puppetdb-model 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []