puppetdb-model 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3955e9caf235d79e7db2bb101833588a07598ef564a98057e543fe432a0a2d88
4
+ data.tar.gz: f37fc2719124a8b4cc88f998ecb13665e055a4582ab4c8ea3c09caec1cd9a9f8
5
+ SHA512:
6
+ metadata.gz: f50a8f4cffd9eee6363323680857580691f518fa4c9ea148ef8534f7c1a3e9708ce51db901084d4f644a99d37fe51e590b4587294b1894cbd8994671ab7a10dc
7
+ data.tar.gz: aabf6c930f0910a33785e6ce2d0e416154534db19899b22f0063ae1491af5722bbe6bc931992f6a947e1aa870f9438ce527d33cce25c5266aa6acaea4d62903e
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # Model for PuppetDB queries
2
+
3
+ This library provides classes for retreiving objects from the puppet DB
4
+
5
+ ## Example usage
6
+
7
+ ```ruby
8
+ require 'puppetdb/model'
9
+
10
+ PuppetDB::Model::Base.client = PuppetDB::Client.new(server: 'puppetserver.daho.im')
11
+
12
+ # get nodes reporting to production environment
13
+ PuppetDB::Model::Nodes.get(report_environment: 'production').each { |node| puts node.certname }
14
+
15
+ # get Resources exported by a node
16
+ PuppetDB::Model::Resource.get(exported: true, certname: 'dbserver.daho.im').each { |r| puts r.title }
17
+
18
+ # get Resources from node with regular expressions
19
+ PuppetDB::Model::Resource.get(certname: 'db.*daho.im', regexp: true).each { |r| puts r.title }
20
+
21
+ # get all exporte Resources
22
+ PuppetDB::Model::Resource.get(exported: true)
23
+
24
+ ```
@@ -0,0 +1,76 @@
1
+ module PuppetDB
2
+ module Model
3
+ class Base
4
+
5
+ # Parses objects from PuppetDB
6
+ #
7
+ # The parser expects an array of hashes where each item in the array is parsed into a separate object.
8
+ # The keys of the hashes are turned into getters of the resulting object returning the associated values.
9
+ def initialize(attributes)
10
+ attributes.each do |attribute_name, attribute_value|
11
+ # this will create an `attr_reader` for each attribute passed
12
+ self.class.send(:define_method, attribute_name.to_sym) do
13
+ instance_variable_get("@#{attribute_name}")
14
+ end
15
+
16
+ # set an instance variable for each attribute like `@certname`
17
+ instance_variable_set("@#{attribute_name}", attribute_value)
18
+ end
19
+ end
20
+
21
+ # Saves the PuppetDB client into a class variable which is shared among all object created from this class
22
+ #
23
+ # @param client [PuppetDB::Client]
24
+ def self.client=(client)
25
+ # rubocop:disable Style/ClassVars
26
+ @@client = client
27
+ # rubocop:enable Style/ClassVars
28
+ end
29
+
30
+ # Return the PuppetDB Client
31
+ #
32
+ # @return [PuppetDB::Client] instance
33
+ def self.client
34
+ @@client
35
+ end
36
+
37
+ # Query the Puppet DB an build new Objects from the result
38
+ #
39
+ # @param query [String] The PQL query to execute
40
+ def self.query(query)
41
+ request(query).map { |object| new(object) }
42
+ end
43
+
44
+ def self.request(query)
45
+ client.request('', query).data
46
+ end
47
+
48
+ # Get object from Puppet DB
49
+ #
50
+ # Pass a list of key: val arguments as filters for the query.
51
+ #
52
+ # @param regexp [Boolean] Set this to true for regular expression matching
53
+ # @param object [String] The name of the object from The PuppetDB
54
+ #
55
+ # @example Get exported Resources
56
+ # PuppetDB::Model::Base.get(object: 'resources', exported: true)
57
+ # @example Regexp search Resources by title
58
+ # PuppetDB::Model::Resource.get(object: 'resources', title: '^foo.*bar', regexp: true)
59
+ def self.get(object:, regexp: false, **filters)
60
+ # use strict comparator by default, because this is less performance intensive
61
+ comparator = regexp ? '~' : '='
62
+
63
+ filters = filters.map do |key, value|
64
+ # Boolean values doesn't support regexp operator(~) and must not be escaped
65
+ if [TrueClass, FalseClass].include?(value.class)
66
+ "#{key} = #{value}"
67
+ else
68
+ "#{key} #{comparator} #{value.to_s.dump}"
69
+ end
70
+ end
71
+
72
+ query("#{object} {#{filters.join(' and ')}}")
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,35 @@
1
+ module PuppetDB
2
+ module Model
3
+ # Parses fact_contents from PuppetDB
4
+ #
5
+ # All attributes retreived from the puppetdb be added as getter to the object
6
+ class Fact < Base
7
+ attr_reader :name
8
+
9
+ def initialize(attributes)
10
+ super(**attributes)
11
+ self.name = attributes[:name]
12
+ end
13
+
14
+ # set the name of the fact
15
+ #
16
+ # @param name [String] accepts fact name where subfacts can be separated by period(.)
17
+ def name=(name)
18
+ @path ||= name.split('.')
19
+ @name = name
20
+ end
21
+
22
+ # gets the value for the fact and certname combination
23
+ #
24
+ # The value of value is lazy loaded on call and saved in the object
25
+ def value
26
+ pql = "fact_contents[value] { certname = '#{certname}' and path = #{@path}}"
27
+ @value ||= self.class.request(pql).first.values
28
+ end
29
+
30
+ def to_s
31
+ value
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ module PuppetDB
2
+ module Model
3
+ class Inventory < Base
4
+
5
+ # Get object from Puppet DB
6
+ #
7
+ # Pass a list of key: val arguments as filters for the query.
8
+ #
9
+ # @param regexp [Boolean] Set this to true for regular expression matching
10
+ #
11
+ # @example Get by certname
12
+ # PuppetDB::Model::Resource.get(certname: 'daho.im')
13
+ # @example Regexp search in title
14
+ # PuppetDB::Model::Resource.get(title: '^foo.*bar', regexp: true)
15
+ def self.get(**arguments)
16
+ super object: 'inventory', **arguments
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,113 @@
1
+ module PuppetDB
2
+ module Model
3
+ # Parses Nodes from Puppetdb
4
+ #
5
+ # All attributes returned by for the node from the puppetdb will be added as getter to the object
6
+ #
7
+ # @example print uptime for hardware
8
+ # servers = PuppetDB::Model::Node.all_hardware_servers.each do |server|
9
+ # puts server.certname
10
+ # puts server.uptime
11
+ # end
12
+ #
13
+ # @example get nodes by fact
14
+ # PuppetDB::Model::Node.by_fact({'custom_fact' => 'FooBar'}).each do |server|
15
+ # puts server.certname
16
+ # end
17
+ class Node < Base
18
+
19
+ # parses the data returned by a puppetdb query of 'node' objects and parses it
20
+ # @param attributes The data returned by a PuppetDB query
21
+ def initialize(attributes)
22
+ @facts = {}
23
+ attributes[:environment] = attributes[:catalog_environment]
24
+ super(attributes)
25
+ end
26
+
27
+ # Get object from Puppet DB
28
+ #
29
+ # Pass a list of key: val arguments as filters for the query.
30
+ #
31
+ # @param regexp [Boolean] Set this to true for regular expression matching
32
+ #
33
+ # @example Get nodes in environment
34
+ # PuppetDB::Model::Nodes.get(report_environment: production)
35
+ #
36
+ # @example Regexp search in title
37
+ # PuppetDB::Model::Node.get(title: '^foo.*bar', regexp: true)
38
+ def self.get(**arguments)
39
+ super object: 'nodes', **arguments
40
+ end
41
+
42
+ # get nodes by name
43
+ #
44
+ # @param fqdn [String] FQDN to search
45
+ # @param regexp [Boolean] Defines if the matching is done with regexp. Default : False
46
+ def by_name(fqdn, regexp: false)
47
+ # use strict comparator by default, because this is less performance intensive
48
+ comparator = regexp ? '~' : '='
49
+
50
+ query("node { certname #{comparator} #{fqdn.dump}}")
51
+ end
52
+
53
+ # get nodes with a specific class
54
+ #
55
+ # @param classname [String] The name of the Class to search the Nodes
56
+ # @example Nodes with 'Environment' class loaded
57
+ # PuppetDB::Model::Node.by_class('Environment').each do |server|
58
+ # puts server.uptime
59
+ # end
60
+ def self.by_class(classname)
61
+ query("nodes { resources { type = 'Class' and title = #{classname.dump} }}")
62
+ end
63
+
64
+ # get nodes by matching facts
65
+ #
66
+ # @param facts [Hash] name value pair for matching facts. Subfacts can be separated by period(.)
67
+ # @param regexp [Boolean] Defines if the matching is done with regexp. Default : False
68
+ def self.by_fact(facts, regexp: false)
69
+ # use strict comparator by default, because this is less performance intensive
70
+ comparator = regexp ? '~' : '='
71
+
72
+ filters = facts.map do |key, value|
73
+ # Boolean values doesn't support regexp operator(~) and must not be escaped
74
+ if [TrueClass, FalseClass].include?(value.class)
75
+ "facts.#{key} = #{value}"
76
+ else
77
+ "facts.#{key} #{comparator} #{value.to_s.dump}"
78
+ end
79
+ end
80
+
81
+ query("nodes { inventory { #{filters.join(' and ')} }}")
82
+ end
83
+
84
+ # get all hardware servers
85
+ def self.all_hardware_servers
86
+ query("nodes { inventory { facts.virtual = 'physical' and facts.dmi.chassis.type != 'Desktop' }}")
87
+ end
88
+
89
+ # get all nodes
90
+ def self.all
91
+ query('nodes {}')
92
+ end
93
+
94
+ # get a fact associated with this node
95
+ #
96
+ # @example get dmi info from host
97
+ # Bios = PuppetDB::Model::Node.by_name.fact('dmi.bios.).value
98
+ def fact(name)
99
+ @facts[name] ||= Fact.new(certname: certname, name: name)
100
+ end
101
+
102
+ # get the bios version
103
+ def bios_version
104
+ fact('dmi.bios.version').value
105
+ end
106
+
107
+ # get the uptime
108
+ def uptime
109
+ fact('system_uptime.uptime').value
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,20 @@
1
+ module PuppetDB
2
+ module Model
3
+ class Resource < Base
4
+ # Get object from Puppet DB
5
+ #
6
+ # Pass a list of key: val arguments as filters for the query.
7
+ #
8
+ # @param regexp [Boolean] Set this to true for regular expression matching
9
+ #
10
+ # @example Get exported Resources
11
+ # PuppetDB::Model::Resource.get(exported: true)
12
+ #
13
+ # @example Regexp search in title
14
+ # PuppetDB::Model::Resource.get(title: '^foo.*bar', regexp: true)
15
+ def self.get(**arguments)
16
+ super object: 'resources', **arguments
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ module PuppetDB
2
+ module Model
3
+ VERSION = '0.1.0'.freeze
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'puppetdb/model/base'
2
+ require 'puppetdb/model/node'
3
+ require 'puppetdb/model/fact'
4
+ require 'puppetdb/model/inventory'
5
+ require 'puppetdb/model/resource'
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: puppetdb-model
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Moritz Kraus
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-10-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Provides objects for PuppetDB
14
+ email: moritz.kraus@makandra.de
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - README.md
20
+ - lib/puppetdb/model.rb
21
+ - lib/puppetdb/model/base.rb
22
+ - lib/puppetdb/model/fact.rb
23
+ - lib/puppetdb/model/inventory.rb
24
+ - lib/puppetdb/model/node.rb
25
+ - lib/puppetdb/model/resource.rb
26
+ - lib/puppetdb/model/version.rb
27
+ homepage: https://makandra.com
28
+ licenses:
29
+ - MIT
30
+ metadata:
31
+ rubygems_mfa_required: 'true'
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubygems_version: 3.3.7
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: Provides objects for PuppetDB
51
+ test_files: []