ruby-puppetdb 1.6.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/bin/find-nodes +34 -21
- data/lib/hiera/backend/puppetdb_backend.rb +15 -12
- data/lib/puppet/application/query.rb +10 -4
- data/lib/puppet/face/query.rb +37 -31
- data/lib/puppet/parser/functions/query_facts.rb +9 -4
- data/lib/puppet/parser/functions/query_nodes.rb +13 -8
- data/lib/puppet/parser/functions/query_resources.rb +35 -6
- data/lib/puppetdb.rb +1 -1
- data/lib/puppetdb/astnode.rb +92 -44
- data/lib/puppetdb/connection.rb +14 -69
- data/lib/puppetdb/grammar.racc +75 -40
- data/lib/puppetdb/lexer.rb +23 -4
- data/lib/puppetdb/lexer.rex +30 -24
- data/lib/puppetdb/parser.rb +245 -223
- data/lib/puppetdb/parser_helper.rb +48 -0
- data/spec/unit/puppetdb/parser_spec.rb +129 -0
- metadata +7 -28
- data/lib/puppet/parser/functions/pdbfactquery.rb +0 -31
- data/lib/puppet/parser/functions/pdbnodequery.rb +0 -38
- data/lib/puppet/parser/functions/pdbnodequery_all.rb +0 -40
- data/lib/puppet/parser/functions/pdbquery.rb +0 -41
- data/lib/puppet/parser/functions/pdbresourcequery.rb +0 -39
- data/lib/puppet/parser/functions/pdbresourcequery_all.rb +0 -37
- data/lib/puppet/parser/functions/pdbstatusquery.rb +0 -31
- data/lib/puppetdb/util.rb +0 -18
- data/spec/unit/puppet/parser/functions/pdbfactquery_spec.rb +0 -19
- data/spec/unit/puppet/parser/functions/pdbnodequery_all_spec.rb +0 -19
- data/spec/unit/puppet/parser/functions/pdbnodequery_spec.rb +0 -19
- data/spec/unit/puppet/parser/functions/pdbquery_spec.rb +0 -19
- data/spec/unit/puppet/parser/functions/pdbresourcequery_all_spec.rb +0 -19
- data/spec/unit/puppet/parser/functions/pdbresourcequery_spec.rb +0 -19
- data/spec/unit/puppet/parser/functions/pdbstatusquery_spec.rb +0 -19
- data/spec/unit/puppetdb/connection_spec.rb +0 -67
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NjdkNGNlZjVmMjE3Mzc2YjJmM2ViMWEzZjdkNDllMzNiNWNlMTY3MA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZmJiM2NjYTljMTAwNDc3MzEyNDM5YjJmNmNhYzc1YTA4MzA5Yzk1NQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MjZiNjBmZmJlMDc3N2M2YTY4YWQ1MjJlOTNlNmIwNjNiNDI1YjRlMWM4NjI4
|
10
|
+
MzA5ZmY1YjBjYTAzOGVhOTBmZjg1MDY2NzFlZjU2ZjJiN2YxYmRhOTM3ZmZm
|
11
|
+
ZjFjNzIyNTM4YTM0ZDQ0Zjk0ZmUzZDNlNGVhMThiYzFlN2M0MmU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTdhMmE3NTQ4NmYyN2QxZjAzYjA5NmNhMjUzODU4M2JhMDdjOTczYWUyYjA1
|
14
|
+
ZDU4M2FkMjRhMzliZjYwYzM4NWQ5MmMxNDhmNGU5NDZlZjZkYWQ1ZGJhY2Zk
|
15
|
+
YzA2YzRlYTQzZWQzYzg2NTZiZmVmYTkxYTg1NzdkN2U2MTIwZDQ=
|
data/bin/find-nodes
CHANGED
@@ -6,54 +6,67 @@ require 'optparse'
|
|
6
6
|
require 'net/http'
|
7
7
|
require 'net/https'
|
8
8
|
|
9
|
-
options = {:
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
options = { host: 'puppetdb',
|
10
|
+
port: 443,
|
11
|
+
fact: nil,
|
12
|
+
query: nil,
|
13
|
+
ssl: true,
|
14
|
+
print: false }
|
13
15
|
|
14
16
|
opt = OptionParser.new
|
15
17
|
|
16
|
-
opt.on(
|
17
|
-
options[:
|
18
|
+
opt.on('--host [PUPPETDB]', '-H', "Host running PuppetDB (#{options[:host]})") do |v|
|
19
|
+
options[:host] = v
|
18
20
|
end
|
19
21
|
|
20
|
-
opt.on(
|
21
|
-
options[:
|
22
|
+
opt.on('--port [PORT]', '-p', Integer, "Port PuppetDB is running on (#{options[:port]})") do |v|
|
23
|
+
options[:port] = v
|
22
24
|
end
|
23
25
|
|
24
|
-
opt.on(
|
26
|
+
opt.on('--query [QUERY]', '-q', 'Query String') do |v|
|
25
27
|
options[:query] = v
|
26
28
|
end
|
27
29
|
|
28
|
-
opt.on(
|
30
|
+
opt.on('--facts [FACT]', '-f', 'Comma separated list of facts') do |v|
|
29
31
|
options[:facts] = v.split ','
|
30
32
|
end
|
31
33
|
|
32
|
-
opt.on(
|
34
|
+
opt.on('--timeout [SECONDS]', '-t', 'PuppetDB read timeout') do |v|
|
33
35
|
options[:timeout] = v.to_i
|
34
36
|
end
|
35
37
|
|
38
|
+
opt.on('--nossl', 'Disable SSL') do |v|
|
39
|
+
options[:ssl] = false
|
40
|
+
end
|
41
|
+
|
42
|
+
opt.on('--print', 'Only print query') do |v|
|
43
|
+
options[:print] = true
|
44
|
+
end
|
45
|
+
|
36
46
|
opt.parse!
|
37
47
|
|
38
48
|
options[:query] ||= ARGV[0]
|
39
49
|
|
40
|
-
abort
|
50
|
+
abort 'Please specify a query' unless options[:query]
|
41
51
|
|
42
|
-
puppetdb = PuppetDB::Connection.new(options[:
|
43
|
-
|
44
|
-
http
|
52
|
+
puppetdb = PuppetDB::Connection.new(options[:host], options[:port])
|
53
|
+
parser = PuppetDB::Parser.new
|
54
|
+
http = Net::HTTP.new(options[:host], options[:port])
|
55
|
+
http.use_ssl = options[:ssl]
|
45
56
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
46
57
|
http.read_timeout = options[:timeout] if options[:timeout]
|
47
58
|
|
48
|
-
if options[:
|
49
|
-
query =
|
50
|
-
|
51
|
-
|
59
|
+
if options[:print]
|
60
|
+
query = parser.parse(options[:query])
|
61
|
+
puts query.to_json
|
62
|
+
elsif options[:facts]
|
63
|
+
query = parser.facts_query(options[:query], options[:facts])
|
64
|
+
parser.facts_hash(puppetdb.query(:facts, query, http)).each_value do |host|
|
52
65
|
print options[:facts].collect { |f| host[f] if host.include? f }.join(',') + "\n"
|
53
66
|
end
|
54
67
|
else
|
55
|
-
query =
|
68
|
+
query = parser.parse(options[:query])
|
56
69
|
results = puppetdb.query(:nodes, query, http)
|
57
|
-
hosts = results.collect { |host| host['
|
70
|
+
hosts = results.collect { |host| host['certname'] }
|
58
71
|
hosts.each { |host| print host + "\n" }
|
59
72
|
end
|
@@ -8,24 +8,27 @@ class Hiera
|
|
8
8
|
# This is needed when we run from hiera cli
|
9
9
|
Puppet.initialize_settings unless Puppet[:confdir]
|
10
10
|
require 'puppet/util/puppetdb'
|
11
|
-
|
12
|
-
|
11
|
+
PuppetDB::Connection.check_version
|
12
|
+
uri = URI(Puppet::Util::Puppetdb.config.server_urls.first)
|
13
|
+
host = uri.host
|
14
|
+
port = uri.port
|
13
15
|
rescue
|
14
|
-
|
16
|
+
host = 'puppetdb'
|
15
17
|
port = 443
|
16
18
|
end
|
17
19
|
|
18
|
-
Hiera.debug(
|
20
|
+
Hiera.debug('Hiera PuppetDB backend starting')
|
19
21
|
|
20
|
-
@puppetdb = PuppetDB::Connection.new(
|
22
|
+
@puppetdb = PuppetDB::Connection.new(host, port)
|
23
|
+
@parser = PuppetDB::Parser.new
|
21
24
|
end
|
22
25
|
|
23
|
-
def lookup(key, scope, order_override,
|
24
|
-
return nil if key.end_with?
|
26
|
+
def lookup(key, scope, order_override, _resolution_type)
|
27
|
+
return nil if key.end_with? '::_nodequery'
|
25
28
|
|
26
29
|
Hiera.debug("Looking up #{key} in PuppetDB backend")
|
27
30
|
|
28
|
-
if nodequery = Backend.lookup(key +
|
31
|
+
if nodequery = Backend.lookup(key + '::_nodequery', nil, scope, order_override, :priority)
|
29
32
|
Hiera.debug("Found nodequery #{nodequery.inspect}")
|
30
33
|
|
31
34
|
# Support specifying the query in a few different ways
|
@@ -38,11 +41,11 @@ class Hiera
|
|
38
41
|
query = nodequery.to_s
|
39
42
|
end
|
40
43
|
|
41
|
-
if fact
|
42
|
-
query = @
|
43
|
-
@puppetdb.facts
|
44
|
+
if fact
|
45
|
+
query = @parser.facts_query query, [fact]
|
46
|
+
@puppetdb.query(:facts, query).collect { |f| f['value'] }.sort
|
44
47
|
else
|
45
|
-
query = @
|
48
|
+
query = @parser.parse query, :nodes if query.is_a? String
|
46
49
|
@puppetdb.query(:nodes, query).collect { |n| n['name'] }
|
47
50
|
end
|
48
51
|
end
|
@@ -2,11 +2,14 @@ require 'puppet/application/face_base'
|
|
2
2
|
|
3
3
|
class Puppet::Application::Query < Puppet::Application::FaceBase
|
4
4
|
def self.setting
|
5
|
+
use_ssl = true
|
5
6
|
begin
|
6
7
|
require 'puppet'
|
7
8
|
require 'puppet/util/puppetdb'
|
8
|
-
|
9
|
-
|
9
|
+
PuppetDB::Connection.check_version
|
10
|
+
uri = URI(Puppet::Util::Puppetdb.config.server_urls.first)
|
11
|
+
host = uri.host
|
12
|
+
port = uri.port
|
10
13
|
rescue Exception => e
|
11
14
|
Puppet.debug(e.message)
|
12
15
|
host = 'puppetdb'
|
@@ -15,8 +18,11 @@ class Puppet::Application::Query < Puppet::Application::FaceBase
|
|
15
18
|
|
16
19
|
Puppet.debug(host)
|
17
20
|
Puppet.debug(port)
|
21
|
+
Puppet.debug("use_ssl=#{use_ssl}")
|
18
22
|
|
19
|
-
{ :
|
20
|
-
:
|
23
|
+
{ host: host,
|
24
|
+
port: port,
|
25
|
+
use_ssl: use_ssl
|
26
|
+
}
|
21
27
|
end
|
22
28
|
end
|
data/lib/puppet/face/query.rb
CHANGED
@@ -4,23 +4,28 @@ require 'puppet/util/colors'
|
|
4
4
|
|
5
5
|
Puppet::Face.define(:query, '1.0.0') do
|
6
6
|
require 'puppetdb/connection'
|
7
|
+
PuppetDB::Connection.check_version
|
7
8
|
|
8
9
|
extend Puppet::Util::Colors
|
9
10
|
|
10
|
-
copyright
|
11
|
-
license
|
11
|
+
copyright 'Erik Dalen & Puppet Labs', 2012..2015
|
12
|
+
license 'Apache 2 license; see COPYING'
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
summary "Host running PuppetDB. "
|
14
|
+
option '--host PUPPETDB' do
|
15
|
+
summary 'Host running PuppetDB. '
|
16
16
|
default_to { Puppet::Application::Query.setting[:host] }
|
17
17
|
end
|
18
18
|
|
19
|
-
option '--
|
19
|
+
option '--port PORT' do
|
20
20
|
summary 'Port PuppetDB is running on'
|
21
21
|
default_to { Puppet::Application::Query.setting[:port] }
|
22
22
|
end
|
23
23
|
|
24
|
+
option '--no_ssl' do
|
25
|
+
summary 'Talk plain HTTP instead of HTTPS'
|
26
|
+
default_to { !Puppet::Application::Query.setting[:use_ssl] }
|
27
|
+
end
|
28
|
+
|
24
29
|
action :facts do
|
25
30
|
summary 'Serves as an interface to puppetdb allowing a user to query for a list of nodes'
|
26
31
|
|
@@ -28,7 +33,7 @@ Puppet::Face.define(:query, '1.0.0') do
|
|
28
33
|
Here is a ton of more useful information :)
|
29
34
|
EOT
|
30
35
|
|
31
|
-
arguments
|
36
|
+
arguments '<query>'
|
32
37
|
|
33
38
|
option '--facts FACTS' do
|
34
39
|
summary 'facts to return that represent each host'
|
@@ -40,20 +45,20 @@ Puppet::Face.define(:query, '1.0.0') do
|
|
40
45
|
end
|
41
46
|
|
42
47
|
when_invoked do |query, options|
|
43
|
-
puppetdb = PuppetDB::Connection.new options[:
|
44
|
-
|
48
|
+
puppetdb = PuppetDB::Connection.new options[:host], options[:port], !options[:no_ssl]
|
49
|
+
parser = PuppetDB::Parser.new
|
50
|
+
factquery = parser.facts_query(query, options[:facts].split(','))
|
51
|
+
parser.facts_hash(puppetdb.query(factquery))
|
45
52
|
end
|
46
|
-
|
47
53
|
end
|
48
54
|
|
49
55
|
action :nodes do
|
50
|
-
|
51
56
|
summary 'Perform complex queries for nodes from PuppetDB'
|
52
57
|
description <<-EOT
|
53
58
|
Here is a ton of more useful information :)
|
54
59
|
EOT
|
55
60
|
|
56
|
-
arguments
|
61
|
+
arguments '<query>'
|
57
62
|
|
58
63
|
option '--node_info BOOLEAN' do
|
59
64
|
summary 'return full info about each node or just name'
|
@@ -64,16 +69,16 @@ Puppet::Face.define(:query, '1.0.0') do
|
|
64
69
|
end
|
65
70
|
|
66
71
|
when_invoked do |query, options|
|
67
|
-
puppetdb = PuppetDB::Connection.new options[:
|
68
|
-
|
72
|
+
puppetdb = PuppetDB::Connection.new options[:host], options[:port], !options[:no_ssl]
|
73
|
+
parser = PuppetDB::Parser.new
|
74
|
+
nodes = puppetdb.query(:nodes, parser.parse(query, :nodes))
|
69
75
|
|
70
76
|
if options[:node_info]
|
71
|
-
Hash[nodes.collect { |node| [node['
|
77
|
+
Hash[nodes.collect { |node| [node['certname'], node.reject { |k, _v| k == 'certname' }] }]
|
72
78
|
else
|
73
|
-
nodes.collect { |node| node['
|
79
|
+
nodes.collect { |node| node['certname'] }
|
74
80
|
end
|
75
81
|
end
|
76
|
-
|
77
82
|
end
|
78
83
|
|
79
84
|
action :events do
|
@@ -83,7 +88,7 @@ Puppet::Face.define(:query, '1.0.0') do
|
|
83
88
|
Get all avents for nodes matching the query specified.
|
84
89
|
EOT
|
85
90
|
|
86
|
-
arguments
|
91
|
+
arguments '<query>'
|
87
92
|
|
88
93
|
option '--since SINCE' do
|
89
94
|
summary 'Get events since this time'
|
@@ -114,30 +119,31 @@ Puppet::Face.define(:query, '1.0.0') do
|
|
114
119
|
require 'chronic'
|
115
120
|
rescue LoadError
|
116
121
|
Puppet.err "Failed to load 'chronic' dependency. Install using `gem install chronic`"
|
117
|
-
raise
|
122
|
+
raise
|
118
123
|
end
|
119
124
|
|
120
|
-
puppetdb = PuppetDB::Connection.new options[:
|
121
|
-
|
122
|
-
|
123
|
-
|
125
|
+
puppetdb = PuppetDB::Connection.new options[:host], options[:port], !options[:no_ssl]
|
126
|
+
parser = PuppetDB::Parser.new
|
127
|
+
nodes = puppetdb.query(:nodes, parser.parse(query, :nodes)).collect { |n| n['certname'] }
|
128
|
+
starttime = Chronic.parse(options[:since], context: :past, guess: false).first.getutc.strftime('%FT%T.000Z')
|
129
|
+
endtime = Chronic.parse(options[:until], context: :past, guess: false).last.getutc.strftime('%FT%T.000Z')
|
124
130
|
|
125
131
|
events = []
|
126
132
|
# Event API doesn't support subqueries at the moment and
|
127
133
|
# we can't do too big queries, so fetch events for some nodes at a time
|
128
134
|
nodes.each_slice(20) do |nodeslice|
|
129
|
-
eventquery = ['and', ['>', 'timestamp', starttime], ['<', 'timestamp', endtime], ['or', *nodeslice.collect { |n| ['=', 'certname', n]}]]
|
135
|
+
eventquery = ['and', ['>', 'timestamp', starttime], ['<', 'timestamp', endtime], ['or', *nodeslice.collect { |n| ['=', 'certname', n] }]]
|
130
136
|
eventquery << ['=', 'status', options[:status]] if options[:status] != 'all'
|
131
|
-
events.concat puppetdb.query(:events, eventquery
|
137
|
+
events.concat puppetdb.query(:events, eventquery)
|
132
138
|
end
|
133
139
|
|
134
140
|
events.sort_by do |e|
|
135
|
-
"#{e['timestamp']}+#{e['
|
141
|
+
"#{e['timestamp']}+#{e['resource_type']}+#{e['resource_title']}+#{e['property']}"
|
136
142
|
end.each do |e|
|
137
|
-
out="#{e['certname']}: #{e['timestamp']}: #{e['
|
138
|
-
out+="/#{e['property']}" if e['property']
|
139
|
-
out+=" (#{e['
|
140
|
-
out+=": #{e['message']}" if e['message']
|
143
|
+
out = "#{e['certname']}: #{e['timestamp']}: #{e['resource_type']}[#{e['resource_title']}]"
|
144
|
+
out += "/#{e['property']}" if e['property']
|
145
|
+
out += " (#{e['old_value']} -> #{e['new_value']})" if e['old_value'] && e['new_value']
|
146
|
+
out += ": #{e['message']}" if e['message']
|
141
147
|
out.chomp!
|
142
148
|
case e['status']
|
143
149
|
when 'failure'
|
@@ -145,7 +151,7 @@ Puppet::Face.define(:query, '1.0.0') do
|
|
145
151
|
when 'success'
|
146
152
|
puts colorize(:green, out)
|
147
153
|
when 'skipped'
|
148
|
-
puts colorize(:hyellow, out) unless e['
|
154
|
+
puts colorize(:hyellow, out) unless e['resource_type'] == 'Schedule'
|
149
155
|
when 'noop'
|
150
156
|
puts out
|
151
157
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
Puppet::Parser::Functions.newfunction(:query_facts, :
|
1
|
+
Puppet::Parser::Functions.newfunction(:query_facts, type: :rvalue, arity: 2, doc: <<-EOT
|
2
2
|
|
3
3
|
accepts two arguments, a query used to discover nodes, and a list of facts
|
4
4
|
that should be returned from those hosts.
|
@@ -13,10 +13,11 @@ Puppet::Parser::Functions.newfunction(:query_facts, :type => :rvalue, :arity =>
|
|
13
13
|
contains the facts specified.
|
14
14
|
|
15
15
|
EOT
|
16
|
-
) do |args|
|
16
|
+
) do |args|
|
17
17
|
query, facts = args
|
18
18
|
|
19
19
|
require 'puppet/util/puppetdb'
|
20
|
+
|
20
21
|
# This is needed if the puppetdb library isn't pluginsynced to the master
|
21
22
|
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..'))
|
22
23
|
begin
|
@@ -25,7 +26,11 @@ EOT
|
|
25
26
|
$LOAD_PATH.shift
|
26
27
|
end
|
27
28
|
|
28
|
-
|
29
|
-
|
29
|
+
PuppetDB::Connection.check_version
|
30
|
+
|
31
|
+
uri = URI(Puppet::Util::Puppetdb.config.server_urls.first)
|
32
|
+
puppetdb = PuppetDB::Connection.new(uri.host, uri.port)
|
33
|
+
parser = PuppetDB::Parser.new
|
34
|
+
query = parser.parse query, :facts if query.is_a? String
|
30
35
|
puppetdb.facts(facts, query)
|
31
36
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
Puppet::Parser::Functions.newfunction(:query_nodes, :
|
1
|
+
Puppet::Parser::Functions.newfunction(:query_nodes, type: :rvalue, arity: -2, doc: <<-EOT
|
2
2
|
|
3
3
|
accepts two arguments, a query used to discover nodes, and a optional
|
4
4
|
fact that should be returned.
|
@@ -10,10 +10,11 @@ Puppet::Parser::Functions.newfunction(:query_nodes, :type => :rvalue, :arity =>
|
|
10
10
|
The second argument should be single fact (this argument is optional)
|
11
11
|
|
12
12
|
EOT
|
13
|
-
) do |args|
|
13
|
+
) do |args|
|
14
14
|
query, fact = args
|
15
15
|
|
16
16
|
require 'puppet/util/puppetdb'
|
17
|
+
|
17
18
|
# This is needed if the puppetdb library isn't pluginsynced to the master
|
18
19
|
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..'))
|
19
20
|
begin
|
@@ -22,12 +23,16 @@ EOT
|
|
22
23
|
$LOAD_PATH.shift
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
PuppetDB::Connection.check_version
|
27
|
+
|
28
|
+
uri = URI(Puppet::Util::Puppetdb.config.server_urls.first)
|
29
|
+
puppetdb = PuppetDB::Connection.new(uri.host, uri.port)
|
30
|
+
parser = PuppetDB::Parser.new
|
31
|
+
if fact
|
32
|
+
query = parser.facts_query query, [fact]
|
33
|
+
puppetdb.query(:facts, query).collect { |f| f['value'] }
|
29
34
|
else
|
30
|
-
query =
|
31
|
-
puppetdb.query(:nodes, query).collect { |n| n['
|
35
|
+
query = parser.parse query, :nodes if query.is_a? String
|
36
|
+
puppetdb.query(:nodes, query).collect { |n| n['certname'] }
|
32
37
|
end
|
33
38
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
Puppet::Parser::Functions.newfunction(:query_resources, :
|
1
|
+
Puppet::Parser::Functions.newfunction(:query_resources, type: :rvalue, arity: -3, doc: <<-EOT
|
2
2
|
|
3
3
|
Accepts two or three arguments: a query used to discover nodes, a
|
4
4
|
resource query for the resources that should be returned from
|
@@ -29,7 +29,7 @@ Puppet::Parser::Functions.newfunction(:query_resources, :type => :rvalue, :arity
|
|
29
29
|
query_resources(false, 'Class["apache"]', false)
|
30
30
|
|
31
31
|
EOT
|
32
|
-
) do |args|
|
32
|
+
) do |args|
|
33
33
|
nodequery, resquery, grouphosts = args
|
34
34
|
|
35
35
|
require 'puppet/util/puppetdb'
|
@@ -41,8 +41,37 @@ EOT
|
|
41
41
|
$LOAD_PATH.shift
|
42
42
|
end
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
PuppetDB::Connection.check_version
|
45
|
+
|
46
|
+
uri = URI(Puppet::Util::Puppetdb.config.server_urls.first)
|
47
|
+
puppetdb = PuppetDB::Connection.new(uri.host, uri.port)
|
48
|
+
parser = PuppetDB::Parser.new
|
49
|
+
nodequery = parser.parse nodequery, :facts if nodequery and nodequery.is_a? String
|
50
|
+
resquery = parser.parse resquery, :none if resquery and resquery.is_a? String
|
51
|
+
|
52
|
+
# Construct query
|
53
|
+
if resquery && !resquery.empty?
|
54
|
+
if nodequery && !nodequery.empty?
|
55
|
+
q = ['and', resquery, nodequery]
|
56
|
+
else
|
57
|
+
q = resquery
|
58
|
+
end
|
59
|
+
else
|
60
|
+
fail "PuppetDB resources query error: at least one argument must be non empty; arguments were: nodequery: #{nodequery.inspect} and requery: #{resquery.inspect}"
|
61
|
+
end
|
62
|
+
|
63
|
+
# Fetch the results
|
64
|
+
results = puppetdb.query(:resources, q)
|
65
|
+
|
66
|
+
# If grouphosts is true create a nested hash with nodes and resources
|
67
|
+
if grouphosts
|
68
|
+
results.reduce({}) do |ret, resource|
|
69
|
+
unless ret.key? resource['certname']
|
70
|
+
ret[resource['certname']] = []
|
71
|
+
end
|
72
|
+
ret[resource['certname']] << resource
|
73
|
+
end
|
74
|
+
else
|
75
|
+
results
|
76
|
+
end
|
48
77
|
end
|