ruby-puppetdb 1.5.3 → 1.6.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 +6 -0
- data/lib/hiera/backend/puppetdb_backend.rb +1 -1
- data/lib/puppet/face/query.rb +7 -2
- data/lib/puppet/parser/functions/query_resources.rb +12 -6
- data/lib/puppetdb.rb +1 -1
- data/lib/puppetdb/astnode.rb +7 -1
- data/lib/puppetdb/connection.rb +19 -6
- data/spec/unit/puppetdb/connection_spec.rb +4 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZDI4NDc5MGUxNTllOWNlZGE2OGM1MWNhN2E4MmZjZjgwNTdmY2NkYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YjE0ODI1ZWVlMjE2MTUxNjczYWM1MTFjYzg0ZTNjMzM5ZTZlYzc4Yg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MWVhNDlhODY5ZTg4MGViMDZmMDRjNDA3ZmJlNjJlYjg3MmM2ZWQ0ODNiMmNm
|
10
|
+
ZDE1NzhkYmNjNTY3MzM3ODMyY2U1MmU0ZDQ3YTdjMTAxYTFkZDg0YWU4Nzcz
|
11
|
+
NGFlM2E1ZDY4MDQ5ODgwYjI1MTE5ZjNiZWE5ZjM2N2FjNGExYjg=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OTA3ZmI0NjEzYWE0Yzc1MzkxMDljODFkZjM4NWJhYzA4N2VlOTNmNTk0NjA5
|
14
|
+
MTk0MjUzNGY3NjhkY2U1YzE4MDM4MjJjYzk2MzBlNzllMmU0OTUxMzRjNmZh
|
15
|
+
N2E3YjI4MjcwNDIyNjZiZGU3YjVkOTMzN2I1YzI4ODI2YzM4YWY=
|
data/bin/find-nodes
CHANGED
@@ -29,6 +29,10 @@ opt.on("--facts [FACT]", "-f", "Comma separated list of facts") do |v|
|
|
29
29
|
options[:facts] = v.split ','
|
30
30
|
end
|
31
31
|
|
32
|
+
opt.on("--timeout [SECONDS]", "-t", "PuppetDB read timeout") do |v|
|
33
|
+
options[:timeout] = v.to_i
|
34
|
+
end
|
35
|
+
|
32
36
|
opt.parse!
|
33
37
|
|
34
38
|
options[:query] ||= ARGV[0]
|
@@ -39,6 +43,8 @@ puppetdb = PuppetDB::Connection.new(options[:puppetdb_host], options[:puppetdb_p
|
|
39
43
|
http = Net::HTTP.new(options[:puppetdb_host], options[:puppetdb_port])
|
40
44
|
http.use_ssl = true
|
41
45
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
46
|
+
http.read_timeout = options[:timeout] if options[:timeout]
|
47
|
+
|
42
48
|
if options[:facts]
|
43
49
|
query = puppetdb.parse_query(options[:query], :facts)
|
44
50
|
facts = puppetdb.facts(options[:facts], query, http)
|
@@ -40,7 +40,7 @@ class Hiera
|
|
40
40
|
|
41
41
|
if fact then
|
42
42
|
query = @puppetdb.parse_query query, :facts if query.is_a? String
|
43
|
-
@puppetdb.facts([fact], query).each_value.collect { |facts| facts[fact] }
|
43
|
+
@puppetdb.facts([fact], query).each_value.collect { |facts| facts[fact] }.sort
|
44
44
|
else
|
45
45
|
query = @puppetdb.parse_query query, :nodes if query.is_a? String
|
46
46
|
@puppetdb.query(:nodes, query).collect { |n| n['name'] }
|
data/lib/puppet/face/query.rb
CHANGED
@@ -110,7 +110,12 @@ Puppet::Face.define(:query, '1.0.0') do
|
|
110
110
|
end
|
111
111
|
|
112
112
|
when_invoked do |query, options|
|
113
|
-
|
113
|
+
begin
|
114
|
+
require 'chronic'
|
115
|
+
rescue LoadError
|
116
|
+
Puppet.err "Failed to load 'chronic' dependency. Install using `gem install chronic`"
|
117
|
+
raise $!
|
118
|
+
end
|
114
119
|
|
115
120
|
puppetdb = PuppetDB::Connection.new options[:puppetdb_host], options[:puppetdb_port]
|
116
121
|
nodes = puppetdb.query(:nodes, puppetdb.parse_query(query, :nodes)).collect { |n| n['name']}
|
@@ -123,7 +128,7 @@ Puppet::Face.define(:query, '1.0.0') do
|
|
123
128
|
nodes.each_slice(20) do |nodeslice|
|
124
129
|
eventquery = ['and', ['>', 'timestamp', starttime], ['<', 'timestamp', endtime], ['or', *nodeslice.collect { |n| ['=', 'certname', n]}]]
|
125
130
|
eventquery << ['=', 'status', options[:status]] if options[:status] != 'all'
|
126
|
-
events.concat puppetdb.query(:events, eventquery, nil, :
|
131
|
+
events.concat puppetdb.query(:events, eventquery, nil, :v3)
|
127
132
|
end
|
128
133
|
|
129
134
|
events.sort_by do |e|
|
@@ -1,13 +1,15 @@
|
|
1
|
-
Puppet::Parser::Functions.newfunction(:query_resources, :type => :rvalue, :arity =>
|
1
|
+
Puppet::Parser::Functions.newfunction(:query_resources, :type => :rvalue, :arity => -3, :doc => <<-EOT
|
2
2
|
|
3
|
-
Accepts two arguments: a query used to discover nodes,
|
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
|
5
|
-
those hosts.
|
5
|
+
those hosts, and optionally a boolean for whether or not to group the results by host.
|
6
6
|
|
7
|
-
The result is a hash that maps the name of the nodes to a list of
|
7
|
+
The result is a hash (by default) that maps the name of the nodes to a list of
|
8
8
|
resource entries. This is a list because there's no single
|
9
9
|
reliable key for resource operations that's of any use to the end user.
|
10
10
|
|
11
|
+
If the third parameters is false the result will be a an array of all resources found.
|
12
|
+
|
11
13
|
Examples:
|
12
14
|
|
13
15
|
Returns the parameters and such for the ntp class for all CentOS nodes:
|
@@ -22,9 +24,13 @@ Puppet::Parser::Functions.newfunction(:query_resources, :type => :rvalue, :arity
|
|
22
24
|
|
23
25
|
query_resources(false, 'Class["apache"]')
|
24
26
|
|
27
|
+
Returns the parameters for the apache class for all nodes in a flat array:
|
28
|
+
|
29
|
+
query_resources(false, 'Class["apache"]', false)
|
30
|
+
|
25
31
|
EOT
|
26
32
|
) do |args|
|
27
|
-
nodequery, resquery = args
|
33
|
+
nodequery, resquery, grouphosts = args
|
28
34
|
|
29
35
|
require 'puppet/util/puppetdb'
|
30
36
|
# This is needed if the puppetdb library isn't pluginsynced to the master
|
@@ -38,5 +44,5 @@ EOT
|
|
38
44
|
puppetdb = PuppetDB::Connection.new(Puppet::Util::Puppetdb.server, Puppet::Util::Puppetdb.port)
|
39
45
|
nodequery = puppetdb.parse_query nodequery, :facts if nodequery and nodequery.is_a? String and ! nodequery.empty?
|
40
46
|
resquery = puppetdb.parse_query resquery, :none if resquery and resquery.is_a? String and ! resquery.empty?
|
41
|
-
return puppetdb.resources(nodequery, resquery)
|
47
|
+
return puppetdb.resources(nodequery, resquery, nil, grouphosts)
|
42
48
|
end
|
data/lib/puppetdb.rb
CHANGED
data/lib/puppetdb/astnode.rb
CHANGED
@@ -72,7 +72,13 @@ class PuppetDB::ASTNode
|
|
72
72
|
when :nodes,:facts # Do a subquery to match nodes matching the facts
|
73
73
|
return subquery(mode, :facts, ['and', ['=', 'name', @children[0].evaluate(mode)], [op, 'value', @children[1].evaluate(mode)]])
|
74
74
|
when :resources
|
75
|
-
|
75
|
+
paramname = @children[0].evaluate(mode)
|
76
|
+
case paramname
|
77
|
+
when "tag"
|
78
|
+
return [op, paramname, @children[1].evaluate(mode)]
|
79
|
+
else
|
80
|
+
return [op, ['parameter', paramname], @children[1].evaluate(mode)]
|
81
|
+
end
|
76
82
|
end
|
77
83
|
when :string
|
78
84
|
return @value.to_s
|
data/lib/puppetdb/connection.rb
CHANGED
@@ -4,6 +4,9 @@ class PuppetDB::Connection
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'puppetdb/parser'
|
6
6
|
require 'uri'
|
7
|
+
require 'puppet/util/logging'
|
8
|
+
|
9
|
+
include Puppet::Util::Logging
|
7
10
|
|
8
11
|
def initialize(host='puppetdb', port=443, use_ssl=true)
|
9
12
|
@host = host
|
@@ -51,8 +54,9 @@ class PuppetDB::Connection
|
|
51
54
|
#
|
52
55
|
# @param resquery [Array] a resources query for what resources to fetch
|
53
56
|
# @param nodequery [Array] the query to find the nodes to fetch resources for, optionally empty
|
54
|
-
# @
|
55
|
-
|
57
|
+
# @param grouphosts [Boolean] whether or not to group the results by the host they belong to
|
58
|
+
# @return [Hash|Array] a hash of hashes with resources for each node mathing query or array if grouphosts was false
|
59
|
+
def resources(nodequery, resquery, http=nil, grouphosts=true)
|
56
60
|
if resquery and ! resquery.empty?
|
57
61
|
if nodequery and ! nodequery.empty?
|
58
62
|
q = ['and', resquery, nodequery]
|
@@ -63,12 +67,19 @@ class PuppetDB::Connection
|
|
63
67
|
raise RuntimeError, "PuppetDB resources query error: at least one argument must be non empty; arguments were: nodequery: #{nodequery.inspect} and requery: #{resquery.inspect}"
|
64
68
|
end
|
65
69
|
resources = {}
|
66
|
-
query(:resources, q, http)
|
67
|
-
|
68
|
-
|
70
|
+
results = query(:resources, q, http)
|
71
|
+
|
72
|
+
if grouphosts
|
73
|
+
results.each do |resource|
|
74
|
+
unless resources.has_key? resource['certname']
|
75
|
+
resources[resource['certname']] = []
|
76
|
+
end
|
77
|
+
resources[resource['certname']] << resource
|
69
78
|
end
|
70
|
-
|
79
|
+
else
|
80
|
+
resources = results
|
71
81
|
end
|
82
|
+
|
72
83
|
return resources
|
73
84
|
end
|
74
85
|
|
@@ -89,6 +100,8 @@ class PuppetDB::Connection
|
|
89
100
|
uri = "/#{version}/#{endpoint}"
|
90
101
|
uri += URI.escape "?query=#{query.to_json}" unless query.nil? || query.empty?
|
91
102
|
|
103
|
+
debug("PuppetDB query: #{query.to_json}")
|
104
|
+
|
92
105
|
resp = http.get(uri, headers)
|
93
106
|
raise "PuppetDB query error: [#{resp.code}] #{resp.msg}, query: #{query.to_json}" unless resp.kind_of?(Net::HTTPSuccess)
|
94
107
|
JSON.parse(resp.body)
|
@@ -43,6 +43,10 @@ describe PuppetDB::Connection do
|
|
43
43
|
connection.parse_query('file[foo]{bar=baz}').should eq ["in", "name", ["extract", "certname", ["select-resources", ["and", ["=", "exported", false], ["=", "type", "File"], ["=", "title", "foo"], ["=", ["parameter", "bar"], "baz"]]]]]
|
44
44
|
end
|
45
45
|
|
46
|
+
it "should parse resource queries with tags" do
|
47
|
+
connection.parse_query('file[foo]{tag=baz}').should eq ["in", "name", ["extract", "certname", ["select-resources", ["and", ["=", "exported", false], ["=", "type", "File"], ["=", "title", "foo"], ["=", "tag", "baz"]]]]]
|
48
|
+
end
|
49
|
+
|
46
50
|
it "should handle precedence within resource parameter queries" do
|
47
51
|
connection.parse_query('{foo=1 or bar=2 and baz=3}').should eq ["in", "name", ["extract", "certname", ["select-resources", ["and", ["=", "exported", false], ["or", ["=", ["parameter", "foo"], 1], ["and", ["=", ["parameter", "bar"], 2], ["=", ["parameter", "baz"], 3]]]]]]]
|
48
52
|
connection.parse_query('{(foo=1 or bar=2) and baz=3}').should eq ["in", "name", ["extract", "certname", ["select-resources", ["and", ["=", "exported", false], ["or", ["=", ["parameter", "foo"], 1], ["=", ["parameter", "bar"], 2]], ["=", ["parameter", "baz"], 3]]]]]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-puppetdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Bode
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-07-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
@@ -143,6 +143,20 @@ dependencies:
|
|
143
143
|
- - ! '>='
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
|
+
- !ruby/object:Gem::Dependency
|
147
|
+
name: puppet-blacksmith
|
148
|
+
requirement: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ~>
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '3.0'
|
153
|
+
type: :development
|
154
|
+
prerelease: false
|
155
|
+
version_requirements: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ~>
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '3.0'
|
146
160
|
description: A higher level query language for PuppetDB.
|
147
161
|
email:
|
148
162
|
- dan@puppetlabs.com
|
@@ -208,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
208
222
|
version: '0'
|
209
223
|
requirements: []
|
210
224
|
rubyforge_project:
|
211
|
-
rubygems_version: 2.4.
|
225
|
+
rubygems_version: 2.4.5
|
212
226
|
signing_key:
|
213
227
|
specification_version: 4
|
214
228
|
summary: Query functions for PuppetDB
|