File: CMDB.pm

package info (click to toggle)
rex 1.14.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,012 kB
  • sloc: perl: 35,587; xml: 264; sh: 51; makefile: 13
file content (151 lines) | stat: -rw-r--r-- 3,482 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#
# (c) Jan Gehring <jan.gehring@gmail.com>
#

=head1 NAME

Rex::CMDB - Function to access the CMDB (configuration management database)

=head1 DESCRIPTION

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<Rex::CMDB::YAML> as the default provider.

=head1 SYNOPSIS

 use Rex::CMDB;
 
 set cmdb => {
   type           => 'YAML',
   path           => [ 'cmdb/{hostname}.yml', 'cmdb/default.yml', ],
   merge_behavior => 'LEFT_PRECEDENT',
 };
 
 task 'prepare', 'server1', sub {
   my %all_information          = get cmdb;
   my $specific_item            = get cmdb('item');
   my $specific_item_for_server = get cmdb( 'item', 'server' );
 };

=head1 EXPORTED FUNCTIONS

=cut

package Rex::CMDB;

use v5.12.5;
use warnings;

our $VERSION = '1.14.1'; # VERSION

use Rex::Commands;
use Rex::Value;

require Rex::Exporter;
use base qw(Rex::Exporter);
use vars qw(@EXPORT);
@EXPORT = qw(cmdb);

my $CMDB_PROVIDER;

=head2 set cmdb

 set cmdb => {
   type => 'YAML',
   %provider_options,
 };

Instantiate a specific C<type> of CMDB provider with the given options. Returns the provider instance.

Please consult the documentation of the given provider for their supported options.

=cut

Rex::Config->register_set_handler(
  "cmdb" => sub {
    my ($option) = @_;

    my %args = Rex::Args->getopts;

    if ( exists $args{O} ) {
      for my $itm ( split( /;/, $args{O} ) ) {
        my ( $key, $val ) = split( /=/, $itm );
        if ( $key eq "cmdb_path" ) {
          if ( ref $option->{path} eq "ARRAY" ) {
            unshift @{ $option->{path} }, $val;
          }
          else {
            $option->{path} = [$val];
          }
        }
      }
    }

    my $klass = $option->{type};

    if ( !$klass ) {

      # no cmdb set
      return;
    }

    if ( $klass !~ m/::/ ) {
      $klass = "Rex::CMDB::$klass";
    }

    eval "use $klass";

    if ($@) {
      die("CMDB provider ($klass) not found: $@");
    }

    $CMDB_PROVIDER = $klass->new( %{$option} );
  }
);

=head2 cmdb([$item, $server])

Function to query a CMDB.

If called without arguments, it returns the full CMDB data structure for the current connection.

If only a defined C<$item> is passed, it returns only the value for the given CMDB item, for the current connection.

If only a defined C<$server> is passed, it returns the whole CMDB data structure for the given server.

If both C<$item> and C<$server> are defined, it returns the given CMDB item for the given server.

The value returned is a L<Rex::Value>, so you may need to use the C<get cmdb(...)> form if you'd like to assign the result to a Perl variable:

 task 'prepare', 'server1', sub {
   my %all_information          = get cmdb;
   my $specific_item            = get cmdb('item');
   my $specific_item_for_server = get cmdb( 'item', 'server' );
 };

If caching is enabled, this function caches the full data structure for the given server under the C<cmdb/$CMDB_PROVIDER/$server> cache key after the first query.

=cut

sub cmdb {
  my ( $item, $server ) = @_;

  return if !cmdb_active();

  $CMDB_PROVIDER->__warm_up_cache_for($server);

  my $value = $CMDB_PROVIDER->get( $item, $server );

  if ( defined $value ) {
    return Rex::Value->new( value => $value );
  }
  else {
    Rex::Logger::debug("CMDB - no item ($item) found");
    return;
  }
}

sub cmdb_active {
  return ( $CMDB_PROVIDER ? 1 : 0 );
}

1;