fork YML and update it to work with TOML... also clean up formatting
This commit is contained in:
parent
23e409085b
commit
847b8c2d72
|
@ -4,42 +4,46 @@ use warnings;
|
|||
use ExtUtils::MakeMaker;
|
||||
|
||||
my %WriteMakefileArgs = (
|
||||
NAME => 'Rex::CMDB::TOML',
|
||||
AUTHOR => q{Zane C. Bowers-Hadley <vvelox@vvelox.net>},
|
||||
VERSION_FROM => 'lib/Rex/CMDB/TOML.pm',
|
||||
ABSTRACT_FROM => 'lib/Rex/CMDB/TOML.pm',
|
||||
LICENSE => 'apache_2_0',
|
||||
MIN_PERL_VERSION => '5.006',
|
||||
CONFIGURE_REQUIRES => {
|
||||
'ExtUtils::MakeMaker' => '0',
|
||||
},
|
||||
TEST_REQUIRES => {
|
||||
'Test::More' => '0',
|
||||
},
|
||||
PREREQ_PM => {
|
||||
#'ABC' => '1.6',
|
||||
#'Foo::Bar::Module' => '5.0401',
|
||||
},
|
||||
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
|
||||
clean => { FILES => 'Rex-CMDB-TOML-*' },
|
||||
NAME => 'Rex::CMDB::TOML',
|
||||
AUTHOR => q{Zane C. Bowers-Hadley <vvelox@vvelox.net>},
|
||||
VERSION_FROM => 'lib/Rex/CMDB/TOML.pm',
|
||||
ABSTRACT_FROM => 'lib/Rex/CMDB/TOML.pm',
|
||||
LICENSE => 'apache_2_0',
|
||||
MIN_PERL_VERSION => '5.006',
|
||||
CONFIGURE_REQUIRES => {
|
||||
'ExtUtils::MakeMaker' => '0',
|
||||
},
|
||||
TEST_REQUIRES => {
|
||||
'Test::More' => '0',
|
||||
},
|
||||
PREREQ_PM => {
|
||||
'Rex::Logger' => '0',
|
||||
'Rex::Commands' => '0',
|
||||
'Data::Dumper' => '0',
|
||||
'Hash::Merge' => '0',
|
||||
'Rex::Commands::File' => '0',
|
||||
'TOML' => '0',
|
||||
},
|
||||
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
|
||||
clean => { FILES => 'Rex-CMDB-TOML-*' },
|
||||
);
|
||||
|
||||
# Compatibility with old versions of ExtUtils::MakeMaker
|
||||
unless (eval { ExtUtils::MakeMaker->VERSION('6.64'); 1 }) {
|
||||
my $test_requires = delete $WriteMakefileArgs{TEST_REQUIRES} || {};
|
||||
@{$WriteMakefileArgs{PREREQ_PM}}{keys %$test_requires} = values %$test_requires;
|
||||
unless ( eval { ExtUtils::MakeMaker->VERSION('6.64'); 1 } ) {
|
||||
my $test_requires = delete $WriteMakefileArgs{TEST_REQUIRES} || {};
|
||||
@{ $WriteMakefileArgs{PREREQ_PM} }{ keys %$test_requires } = values %$test_requires;
|
||||
}
|
||||
|
||||
unless (eval { ExtUtils::MakeMaker->VERSION('6.55_03'); 1 }) {
|
||||
my $build_requires = delete $WriteMakefileArgs{BUILD_REQUIRES} || {};
|
||||
@{$WriteMakefileArgs{PREREQ_PM}}{keys %$build_requires} = values %$build_requires;
|
||||
unless ( eval { ExtUtils::MakeMaker->VERSION('6.55_03'); 1 } ) {
|
||||
my $build_requires = delete $WriteMakefileArgs{BUILD_REQUIRES} || {};
|
||||
@{ $WriteMakefileArgs{PREREQ_PM} }{ keys %$build_requires } = values %$build_requires;
|
||||
}
|
||||
|
||||
delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
|
||||
unless eval { ExtUtils::MakeMaker->VERSION('6.52'); 1 };
|
||||
unless eval { ExtUtils::MakeMaker->VERSION('6.52'); 1 };
|
||||
delete $WriteMakefileArgs{MIN_PERL_VERSION}
|
||||
unless eval { ExtUtils::MakeMaker->VERSION('6.48'); 1 };
|
||||
unless eval { ExtUtils::MakeMaker->VERSION('6.48'); 1 };
|
||||
delete $WriteMakefileArgs{LICENSE}
|
||||
unless eval { ExtUtils::MakeMaker->VERSION('6.31'); 1 };
|
||||
unless eval { ExtUtils::MakeMaker->VERSION('6.31'); 1 };
|
||||
|
||||
WriteMakefile(%WriteMakefileArgs);
|
||||
|
|
|
@ -1,16 +1,7 @@
|
|||
Rex-CMDB-TOML
|
||||
|
||||
The README is used to introduce the module and provide instructions on
|
||||
how to install the module, any machine dependencies it may have (for
|
||||
example C compilers and installed libraries) and any other information
|
||||
that should be provided before the module is installed.
|
||||
|
||||
A README file is required for CPAN modules since CPAN extracts the README
|
||||
file from a module distribution so that people browsing the archive
|
||||
can use it to get an idea of the module's uses. It is usually a good idea
|
||||
to provide version information here so that people can decide whether
|
||||
fixes for the module are worth downloading.
|
||||
|
||||
A fork of Rex::CMDB::YAML to add TOML support
|
||||
as well as roles.
|
||||
|
||||
INSTALLATION
|
||||
|
||||
|
|
|
@ -1,105 +1,287 @@
|
|||
#
|
||||
# (c) Jan Gehring <jan.gehring@gmail.com>
|
||||
# (c) Zane C. Bowers-Hadley
|
||||
|
||||
package Rex::CMDB::TOML;
|
||||
|
||||
use 5.006;
|
||||
use 5.010001;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.0.1'; # VERSION
|
||||
|
||||
use base qw(Rex::CMDB::Base);
|
||||
|
||||
use Rex::Commands -no => [qw/get/];
|
||||
use Rex::Logger;
|
||||
use TOML qw(from_toml);
|
||||
use Data::Dumper;
|
||||
use Hash::Merge qw/merge/;
|
||||
|
||||
require Rex::Commands::File;
|
||||
|
||||
sub new {
|
||||
my $that = shift;
|
||||
my $proto = ref($that) || $that;
|
||||
my $self = {@_};
|
||||
|
||||
$self->{merger} = Hash::Merge->new();
|
||||
|
||||
if ( !defined $self->{merge_behavior} ) {
|
||||
$self->{merger}->specify_behavior(
|
||||
{
|
||||
SCALAR => {
|
||||
SCALAR => sub { $_[0] },
|
||||
ARRAY => sub { $_[0] },
|
||||
HASH => sub { $_[0] },
|
||||
},
|
||||
ARRAY => {
|
||||
SCALAR => sub { $_[0] },
|
||||
ARRAY => sub { $_[0] },
|
||||
HASH => sub { $_[0] },
|
||||
},
|
||||
HASH => {
|
||||
SCALAR => sub { $_[0] },
|
||||
ARRAY => sub { $_[0] },
|
||||
HASH => sub { Hash::Merge::_merge_hashes( $_[0], $_[1] ) },
|
||||
},
|
||||
},
|
||||
'REX_DEFAULT',
|
||||
); # first found value always wins
|
||||
|
||||
$self->{merger}->set_behavior('REX_DEFAULT');
|
||||
}
|
||||
else {
|
||||
if ( ref $self->{merge_behavior} eq 'HASH' ) {
|
||||
$self->{merger}->specify_behavior( $self->{merge_behavior}, 'USER_DEFINED' );
|
||||
$self->{merger}->set_behavior('USER_DEFINED');
|
||||
}
|
||||
else {
|
||||
$self->{merger}->set_behavior( $self->{merge_behavior} );
|
||||
}
|
||||
}
|
||||
|
||||
bless( $self, $proto );
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub get {
|
||||
my ( $self, $item, $server ) = @_;
|
||||
|
||||
$server = $self->__get_hostname_for($server);
|
||||
|
||||
my $result = {};
|
||||
|
||||
if ( $self->__cache->valid( $self->__cache_key() ) ) {
|
||||
$result = $self->__cache->get( $self->__cache_key() );
|
||||
}
|
||||
else {
|
||||
|
||||
my @files = $self->_get_cmdb_files( $item, $server );
|
||||
|
||||
Rex::Logger::debug( Dumper( \@files ) );
|
||||
|
||||
# configuration variables
|
||||
my $config_values = Rex::Config->get_all;
|
||||
my %template_vars;
|
||||
for my $key ( keys %{$config_values} ) {
|
||||
if ( !exists $template_vars{$key} ) {
|
||||
$template_vars{$key} = $config_values->{$key};
|
||||
}
|
||||
}
|
||||
$template_vars{environment} = Rex::Commands::environment();
|
||||
|
||||
for my $file (@files) {
|
||||
Rex::Logger::debug("CMDB - Opening $file");
|
||||
if ( -f $file ) {
|
||||
|
||||
my $content = eval { local ( @ARGV, $/ ) = ($file); <>; };
|
||||
my $t = Rex::Config->get_template_function();
|
||||
$content .= "\n"; # for safety
|
||||
$content = $t->( $content, \%template_vars );
|
||||
|
||||
my $ref = from_toml($content);
|
||||
|
||||
$result = $self->{merger}->merge( $result, $ref );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( defined $item ) {
|
||||
return $result->{$item};
|
||||
}
|
||||
else {
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub _get_cmdb_files {
|
||||
my ( $self, $item, $server ) = @_;
|
||||
|
||||
$server = $self->__get_hostname_for($server);
|
||||
|
||||
my @files;
|
||||
|
||||
if ( !ref $self->{path} ) {
|
||||
my $env = Rex::Commands::environment();
|
||||
my $server_file = "$server.toml";
|
||||
my $default_file = 'default.toml';
|
||||
@files = (
|
||||
File::Spec->join( $self->{path}, $env, $server_file ),
|
||||
File::Spec->join( $self->{path}, $env, $default_file ),
|
||||
File::Spec->join( $self->{path}, $server_file ),
|
||||
File::Spec->join( $self->{path}, $default_file ),
|
||||
);
|
||||
}
|
||||
elsif ( ref $self->{path} eq "CODE" ) {
|
||||
@files = $self->{path}->( $self, $item, $server );
|
||||
}
|
||||
elsif ( ref $self->{path} eq "ARRAY" ) {
|
||||
@files = @{ $self->{path} };
|
||||
}
|
||||
|
||||
my $os = Rex::Hardware::Host->get_operating_system();
|
||||
|
||||
@files = map { $self->_parse_path( $_, { hostname => $server, operatingsystem => $os, } ) } @files;
|
||||
|
||||
return @files;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Rex::CMDB::TOML - The great new Rex::CMDB::TOML!
|
||||
Rex::CMDB::TOML - TOML-based CMDB provider for Rex
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
Version 0.01
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = '0.01';
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module collects and merges data from a set of TOML files to provide configuration
|
||||
management database for Rex.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
Quick summary of what the module does.
|
||||
use Rex::CMDB;
|
||||
|
||||
set cmdb => {
|
||||
type => 'TOML',
|
||||
path => [ 'cmdb/{hostname}.toml', 'cmdb/default.toml', ],
|
||||
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' );
|
||||
};
|
||||
|
||||
Perhaps a little code snippet.
|
||||
=head1 CONFIGURATION AND ENVIRONMENT
|
||||
|
||||
use Rex::CMDB::TOML;
|
||||
=head2 path
|
||||
|
||||
my $foo = Rex::CMDB::TOML->new();
|
||||
...
|
||||
|
||||
=head1 EXPORT
|
||||
|
||||
A list of functions that can be exported. You can delete this section
|
||||
if you don't export anything, such as for a purely object-oriented module.
|
||||
|
||||
=head1 SUBROUTINES/METHODS
|
||||
|
||||
=head2 function1
|
||||
|
||||
=cut
|
||||
|
||||
sub function1 {
|
||||
}
|
||||
|
||||
=head2 function2
|
||||
|
||||
=cut
|
||||
|
||||
sub function2 {
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Zane C. Bowers-Hadley, C<< <vvelox at vvelox.net> >>
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Please report any bugs or feature requests to C<bug-rex-cmdb-toml at rt.cpan.org>, or through
|
||||
the web interface at L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Rex-CMDB-TOML>. I will be notified, and then you'll
|
||||
automatically be notified of progress on your bug as I make changes.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SUPPORT
|
||||
|
||||
You can find documentation for this module with the perldoc command.
|
||||
|
||||
perldoc Rex::CMDB::TOML
|
||||
|
||||
|
||||
You can also look for information at:
|
||||
The path used to look for CMDB files. It supports various use cases depending on the
|
||||
type of data passed to it.
|
||||
|
||||
=over 4
|
||||
|
||||
=item * RT: CPAN's request tracker (report bugs here)
|
||||
=item * Scalar
|
||||
|
||||
L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=Rex-CMDB-TOML>
|
||||
set cmdb => {
|
||||
type => 'TOML',
|
||||
path => 'path/to/cmdb',
|
||||
};
|
||||
|
||||
=item * CPAN Ratings
|
||||
If a scalar is used, it tries to look up a few files under the given path:
|
||||
|
||||
L<https://cpanratings.perl.org/d/Rex-CMDB-TOML>
|
||||
path/to/cmdb/{environment}/{hostname}.toml
|
||||
path/to/cmdb/{environment}/default.toml
|
||||
path/to/cmdb/{hostname}.toml
|
||||
path/to/cmdb/default.toml
|
||||
|
||||
=item * Search CPAN
|
||||
=item * Array reference
|
||||
|
||||
L<https://metacpan.org/release/Rex-CMDB-TOML>
|
||||
set cmdb => {
|
||||
type => 'TOML',
|
||||
path => [ 'cmdb/{hostname}.yml', 'cmdb/default.yml', ],
|
||||
};
|
||||
|
||||
If an array reference is used, it tries to look up the mentioned files in the given
|
||||
order.
|
||||
|
||||
=item * Code reference
|
||||
|
||||
set cmdb => {
|
||||
type => 'TOML',
|
||||
path => sub {
|
||||
my ( $provider, $item, $server ) = @_;
|
||||
my @files = ( "$server.yml", "$item.yml" );
|
||||
return @files;
|
||||
},
|
||||
};
|
||||
|
||||
If a code reference is passed, it should return a list of files that would be looked
|
||||
up in the same order. The code reference gets the CMDB provider instance, the item,
|
||||
and the server as parameters.
|
||||
|
||||
=back
|
||||
|
||||
When the L<0.51 feature flag|Rex#0.51> or later is used, the default value of the
|
||||
C<path> option is:
|
||||
|
||||
=head1 ACKNOWLEDGEMENTS
|
||||
[qw(
|
||||
cmdb/{operatingsystem}/{hostname}.toml
|
||||
cmdb/{operatingsystem}/default.toml
|
||||
cmdb/{environment}/{hostname}.toml
|
||||
cmdb/{environment}/default.toml
|
||||
cmdb/{hostname}.toml
|
||||
cmdb/default.toml
|
||||
)]
|
||||
|
||||
The path specification supports macros enclosed within curly braces, which are
|
||||
dynamically expanded during runtime. By default, the valid macros are L<Rex::Hardware>
|
||||
variables, C<{server}> for the server name of the current connection, and C<{environment}>
|
||||
for the current environment.
|
||||
|
||||
=head1 LICENSE AND COPYRIGHT
|
||||
Please note that the default environment is, well, C<default>.
|
||||
|
||||
This software is Copyright (c) 2021 by Zane C. Bowers-Hadley.
|
||||
You can define additional CMDB paths via the C<-O> command line option by using a
|
||||
semicolon-separated list of C<cmdb_path=$path> key-value pairs:
|
||||
|
||||
This is free software, licensed under:
|
||||
rex -O 'cmdb_path=cmdb/{domain}.toml;cmdb_path=cmdb/{domain}/{hostname}.toml;' taskname
|
||||
|
||||
The Apache License, Version 2.0, January 2004
|
||||
Those additional paths will be prepended to the current list of CMDB paths (so the last one
|
||||
specified will get on top, and thus checked first).
|
||||
|
||||
=head2 merge_behavior
|
||||
|
||||
This CMDB provider looks up the specified files in order, and returns the requested data. If
|
||||
multiple files specify the same data for a given item, then the first instance of the data
|
||||
will be returned by default.
|
||||
|
||||
Rex uses L<Hash::Merge> internally to merge the data found on different levels of the CMDB
|
||||
hierarchy. Any merge strategy supported by that module can be specified to override the
|
||||
default one. For example one of the built-in strategies:
|
||||
|
||||
set cmdb => {
|
||||
type => 'TOML',
|
||||
path => 'cmdb',
|
||||
merge_behavior => 'LEFT_PRECEDENT',
|
||||
};
|
||||
|
||||
Or even custom ones:
|
||||
|
||||
set cmdb => {
|
||||
type => 'TOML',
|
||||
path => 'cmdb',
|
||||
merge_behavior => {
|
||||
SCALAR => sub {},
|
||||
ARRAY => sub {},
|
||||
HASH => sub {},
|
||||
};
|
||||
|
||||
For the full list of options, please see the documentation of Hash::Merge.
|
||||
|
||||
=cut
|
||||
|
||||
1; # End of Rex::CMDB::TOML
|
||||
|
|
Loading…
Reference in New Issue