NAME
Puppet::DB - Object for easily getting Puppet DB data (e.g. facts, reports, etc)
VERSION
version 0.001
SYNOPSIS
This module provides methods to make it easy to connect to the Puppet DB and to put the data into a form where it can be manipulated more readily.
It can extract anything from the Puppet DB that is supported by the API. See the Puppet docs for more information on the API: https://puppet.com/docs/puppetdb/latest/api/index.html. Although this module tries to make it easier and more approachable by abstracting away some complexity, it still requires a basic understanding of how the API works. There is a bunch of Perl scripts I have created that consumes this and other Puppet Perl modules I have written. They provide some examples of what can be done. They are distributed in a Puppet module as they are generally only useful in a Puppet environment. Consequently the best way to install them is via the module. The module can be found here: https://github.com/Q-Technologies/puppet-utility_scripts.
Here is an example of how to use Puppet::DB
:
use Puppet::DB;
my $puppet_db = Puppet::DB->new;
$puppet_db->refresh_facts;
my $facts = $puppet_db->allfacts_by_certname;
say $facts->{testhost.example.com}{osfamily};
Would output Suse
if there was a SLES system called testhost.example.com
The AST query system of the Puppet DB is supported: https://puppet.com/docs/puppetdb/latest/api/query/v4/ast.html. Rather than specifying it in JSON, specify it as Perl data structures. This module will convert it to JSON when it communicates with the Puppet DB. Some sample queries:
use Puppet::DB;
use Data::Dumper;
my $mode = "facts";
my $fact = 'osfamily';
my $value = 'RedHat';
my $rule = { 'query' => [ "and", ["=","name", $fact],
["~", "value", $value ] ],
"order_by" => [{"field" => "certname"}] };
my $puppet_db = Puppet::DB->new;
$puppet_db->refresh($mode, $rule);
print Dumper( $puppet_db->results );
my $fact = 'os.family';
$mode = "fact-contents";
$rule = { 'query' => [ "and", ["=","path", [split( /\./, $fact)] ],
["~", "value", $value ] ],
"order_by" => [{"field" => "certname"}] };
$puppet_db->refresh($mode, $rule);
print Dumper( $puppet_db->results );
The second example demonstrates how to search via a complex fact.
This is how to access the reports:
$rule = ['=', 'job_id', $opt_j ];
$puppet_db->refresh( "reports", $rule );
print Dumper( $puppet_db->results );
$node_rule = ['=', 'certname', 'testhost.example.com' ];
$rule = [ 'and', ['=', 'latest_report?', 'true' ],
$node_rule,
];
$puppet_db->refresh( "reports", $rule );
print Dumper( $puppet_db->results );
METHODS
new
Create a new Puppet::DB
object connecting to http://localhost:8080:
my $puppet_db = Puppet::DB->new;
or, Connect to a Puppet DB host called puppet
my $puppet_db = Puppet::DB->new( 'puppet' );
or, connect to a non standard port:
my $puppet_db = Puppet::DB->new( server_name => 'puppet', server_port => '1234');
server_name
If you did not specify the server to connect when the object was created you can set it with this method. The default value is localhost
.
$puppet_db->server_name( 'puppet' );
This can be changed at any time for subsequent queries if you need to connect to another Puppet DB.
server_port
If you did not specify the port to connect when the object was created you can set it with this method. The default value is 8080
.
$puppet_db->server_port( '1234' );
This can be changed at any time for subsequent queries if you need to connect to another Puppet DB.
Data Loading Methods
refresh
This method needs to be called to populate the Puppet::DB
object with data from the Puppet DB. This needs to be called everytime you change the query.
$puppet_db->refresh( 'facts' );
or
my $query = { 'query' => ["~","certname", '.*\.example.com'], "order_by" => [{"field" => "certname"}] };
$puppet_db->refresh( 'facts', $query );
No data will be returned. The data can be accessed through one of the accessor methods.
refresh_facts
This method can to be called to populate the Puppet::DB object with facts data from the Puppet DB. It does the same as $puppet_db->refresh( 'facts' ); $puppet_db->facts( $puppet_db->results );
- i.e. it populates the facts property as well as the results property.
$puppet_db->refresh_facts; # Load all facts from the Puppet DB (will be slow for a large instance)
or
my $query = { 'query' => ["~","certname", '.*\.example.com'], "order_by" => [{"field" => "certname"}] };
$puppet_db->refresh_facts( $query );
No data will be returned. The data can be accessed through one of the accessor methods.
Accessor Methods
results
Return all the results gathered from the last "refresh" (including anything that calls refresh indirectly - i.e. it can only be trusted if used immediately after calling refresh).
my $results = $puppet_db->results;
facts
Return all the facts gathered from the last "refresh_facts"
my $facts = $puppet_db->facts;
This returns the data in the form that the Puppet DB provides it as. The other fact accessor methods manipulate it for easier consumption.
allfacts_by_certname
Get all the facts for the specified certname
.
$puppet_db->allfacts_by_certname( 'testhost.example.com' );
The facts will be returned as complex data (i.e hash ref).
allfacts_by_hostname
Get all the facts for the specified hostname
.
$puppet_db->allfacts_by_hostname( 'testhost.example.com' );
The facts will be returned as complex data (i.e hash ref).
Note that it will match the last hostname
found by looking at the first field in the certname
. Basically, if you have two nodes with a different certname
, but the same hostname, you may not get the intended host. If this is a risk, then always use the certname
.
get_fact
This will return a fact value matching the specified certname
and fact
. It is a shortcut for "get_fact_by_certname".
$puppet_db->get_fact( 'testhost.example.com', 'osfamily' );
The fact value may be a string or complex data (i.e hash or array ref).
get_fact_by_certname
This will return a fact value matching the specified certname
and fact
.
$puppet_db->get_fact_by_certname( 'testhost.example.com', 'osfamily' );
The fact value may be a string or complex data (i.e hash or array ref).
get_fact_by_short_hostname
This will return a fact value matching the specified hostname
and fact
. Note that it will match the first hostname
found by looking at the first field in the certname
.
$puppet_db->get_fact_by_short_hostname( 'testhost', 'osfamily' );
The fact value may be a string or complex data (i.e hash or array).
is_certname_in_puppetdb
This will return true or false based on whether the specified certname can be found in the Puppet DB.
$puppet_db->is_certname_in_puppetdb( 'testhost.example.com' );
is_node_in_puppetdb
This will return true or false based on whether the specified node can be found in the Puppet DB. This is a synonym of "is_certname_in_puppetdb".
$puppet_db->is_node_in_puppetdb( 'testhost.example.com' );
is_hostname_in_puppetdb
This will return the certname if the hostname of a node can be found in the Puppet DB. It will match the first certname where the first field matches the hostname.
$puppet_db->is_hostname_in_puppetdb( 'testhost' );
If a hostname is provided with dots in it, it will be assumed to be a certname and simply returned back if it is found in the PuppetDB.
False (i.e. 0) is returned if it is not found in the PuppetDB.
FUNCTIONS
parse_puppetdb_time
Puppet DB time is always stored and reported as GM time in a text string. This method will convert it into a time(2) value in seconds since the system epoch (Midnight, January 1, 1970 GMT on Unix).
my $time = parse_puppetdb_time( '2016-02-08T02:21:04.417Z' );
BUGS/FEATURES
Please report any bugs or feature requests in the issues section of GitHub: https://github.com/Q-Technologies/perl-Puppet-DB. Ideally, submit a Pull Request.
AUTHOR
Matthew Mallard <mqtech@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2019 by Matthew Mallard.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.