File Coverage

lib/Rex/CMDB.pm
Criterion Covered Total %
statement 29 29 100.0
branch 6 6 100.0
condition n/a
subroutine 9 9 100.0
pod 1 2 50.0
total 45 46 97.8


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4              
5             =head1 NAME
6              
7             Rex::CMDB - Function to access the CMDB (configuration management database)
8              
9             =head1 DESCRIPTION
10              
11             This module exports a function to access a CMDB via a common interface. When the L<0.51 feature flag|Rex#0.51> or later is used, the CMDB is enabled by default with L as the default provider.
12              
13             =head1 SYNOPSIS
14              
15             use Rex::CMDB;
16              
17             set cmdb => {
18             type => 'YAML',
19             path => [ 'cmdb/{hostname}.yml', 'cmdb/default.yml', ],
20             merge_behavior => 'LEFT_PRECEDENT',
21             };
22              
23             task 'prepare', 'server1', sub {
24             my %all_information = get cmdb;
25             my $specific_item = get cmdb('item');
26             my $specific_item_for_server = get cmdb( 'item', 'server' );
27             };
28              
29             =head1 EXPORTED FUNCTIONS
30              
31             =cut
32              
33             package Rex::CMDB;
34              
35 47     47   132140 use v5.12.5;
  47         363  
36 47     47   756 use warnings;
  47         327  
  47         2376  
37              
38             our $VERSION = '1.14.2.2'; # TRIAL VERSION
39              
40 47     46   2907 use Rex::Commands;
  46         125  
  46         369  
41 46     45   565 use Rex::Value;
  45         121  
  45         515  
42              
43             require Rex::Exporter;
44 45     45   1706 use base qw(Rex::Exporter);
  45         87  
  45         3146  
45 45     45   266 use vars qw(@EXPORT);
  45         98  
  45         21968  
46             @EXPORT = qw(cmdb);
47              
48             my $CMDB_PROVIDER;
49              
50             =head2 set cmdb
51              
52             set cmdb => {
53             type => 'YAML',
54             %provider_options,
55             };
56              
57             Instantiate a specific C of CMDB provider with the given options. Returns the provider instance.
58              
59             Please consult the documentation of the given provider for their supported options.
60              
61             =cut
62              
63             Rex::Config->register_set_handler(
64             "cmdb" => sub {
65             my ($option) = @_;
66              
67             my %args = Rex::Args->getopts;
68              
69             if ( exists $args{O} ) {
70             for my $itm ( split( /;/, $args{O} ) ) {
71             my ( $key, $val ) = split( /=/, $itm );
72             if ( $key eq "cmdb_path" ) {
73             if ( ref $option->{path} eq "ARRAY" ) {
74             unshift @{ $option->{path} }, $val;
75             }
76             else {
77             $option->{path} = [$val];
78             }
79             }
80             }
81             }
82              
83             my $klass = $option->{type};
84              
85             if ( !$klass ) {
86              
87             # no cmdb set
88             return;
89             }
90              
91             if ( $klass !~ m/::/ ) {
92             $klass = "Rex::CMDB::$klass";
93             }
94              
95 5     5   77 eval "use $klass";
  5         21  
  5         62  
96              
97             if ($@) {
98             die("CMDB provider ($klass) not found: $@");
99             }
100              
101             $CMDB_PROVIDER = $klass->new( %{$option} );
102             }
103             );
104              
105             =head2 cmdb([$item, $server])
106              
107             Function to query a CMDB.
108              
109             If called without arguments, it returns the full CMDB data structure for the current connection.
110              
111             If only a defined C<$item> is passed, it returns only the value for the given CMDB item, for the current connection.
112              
113             If only a defined C<$server> is passed, it returns the whole CMDB data structure for the given server.
114              
115             If both C<$item> and C<$server> are defined, it returns the given CMDB item for the given server.
116              
117             The value returned is a L, so you may need to use the C form if you'd like to assign the result to a Perl variable:
118              
119             task 'prepare', 'server1', sub {
120             my %all_information = get cmdb;
121             my $specific_item = get cmdb('item');
122             my $specific_item_for_server = get cmdb( 'item', 'server' );
123             };
124              
125             If caching is enabled, this function caches the full data structure for the given server under the C cache key after the first query.
126              
127             =cut
128              
129             sub cmdb {
130 35     35 1 41981 my ( $item, $server ) = @_;
131              
132 35 100       108 return if !cmdb_active();
133              
134 25         304 $CMDB_PROVIDER->__warm_up_cache_for($server);
135              
136 25         191 my $value = $CMDB_PROVIDER->get( $item, $server );
137              
138 25 100       200 if ( defined $value ) {
139 22         424 return Rex::Value->new( value => $value );
140             }
141             else {
142 3         47 Rex::Logger::debug("CMDB - no item ($item) found");
143 3         72 return;
144             }
145             }
146              
147             sub cmdb_active {
148 54 100   54 0 456 return ( $CMDB_PROVIDER ? 1 : 0 );
149             }
150              
151             1;