ruby-puppetdb 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/puppetdb.rb +1 -1
- data/lib/puppetdb/lexer.rb +5 -5
- data/lib/puppetdb/lexer.rex +2 -2
- data/spec/unit/puppetdb/parser_spec.rb +150 -58
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NjY0NTMwZTM1NjBkOTRjYmU4M2Y5N2VlNzlkZTUwMWEzZmMxYjk5Mg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MjgxMGNiMjdjNjRjZDMyZWE2OTg4MDliODcxMTQyOTY1YWVlZmY5Mw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZThkNjAwMGZhYzZhNzIyOTI2NjJkNjZiMjY0YThiY2EzODIzODAzMWMwZmIz
|
10
|
+
MTJhNGQwN2NkNGExMzI4M2Q5ZmU2Y2I3ZTRhMWE4N2RlZDE4N2RiYjk3NjBk
|
11
|
+
ZTI4MzEwODYzZTI1ZTg3NzlhZThkOTVkMGFkZWNhZTZhOTQ1ODY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NTU4NzI1OTBjMGUxMjVlNGQ2N2ExNGQ5YzZmNTc4NWM5NDZmZTQwODM3Nzli
|
14
|
+
MzBjZDA1ZjU1YjE4Y2E2MWRjNGI3MTAxNjk3YjViZmY1YjgzMWFmZGI1ZjZi
|
15
|
+
Y2I2OGNmNTA3MmVlZjM2MWQ2MTc2ZDYxMmZiNTg4MjVjMzE4NDg=
|
data/lib/puppetdb.rb
CHANGED
data/lib/puppetdb/lexer.rb
CHANGED
@@ -95,18 +95,18 @@ class PuppetDB::Lexer < Racc::Parser
|
|
95
95
|
when (text = @ss.scan(/\!~/))
|
96
96
|
action { [:NOTMATCH, text] }
|
97
97
|
|
98
|
-
when (text = @ss.scan(/</))
|
99
|
-
action { [:LESSTHAN, text] }
|
100
|
-
|
101
98
|
when (text = @ss.scan(/<=/))
|
102
99
|
action { [:LESSTHANEQ, text] }
|
103
100
|
|
104
|
-
when (text = @ss.scan(
|
105
|
-
action { [:
|
101
|
+
when (text = @ss.scan(/</))
|
102
|
+
action { [:LESSTHAN, text] }
|
106
103
|
|
107
104
|
when (text = @ss.scan(/>=/))
|
108
105
|
action { [:GREATERTHANEQ, text] }
|
109
106
|
|
107
|
+
when (text = @ss.scan(/>/))
|
108
|
+
action { [:GREATERTHAN, text] }
|
109
|
+
|
110
110
|
when (text = @ss.scan(/\*/))
|
111
111
|
action { [:ASTERISK, text] }
|
112
112
|
|
data/lib/puppetdb/lexer.rex
CHANGED
@@ -18,10 +18,10 @@ rule
|
|
18
18
|
\!= { [:NOTEQUALS, text] }
|
19
19
|
~ { [:MATCH, text] }
|
20
20
|
\!~ { [:NOTMATCH, text] }
|
21
|
-
< { [:LESSTHAN, text] }
|
22
21
|
<= { [:LESSTHANEQ, text] }
|
23
|
-
|
22
|
+
< { [:LESSTHAN, text] }
|
24
23
|
>= { [:GREATERTHANEQ, text] }
|
24
|
+
> { [:GREATERTHAN, text] }
|
25
25
|
\* { [:ASTERISK, text] }
|
26
26
|
\# { [:HASH, text] }
|
27
27
|
\. { [:DOT, text] }
|
@@ -4,108 +4,200 @@ require 'spec_helper'
|
|
4
4
|
require 'puppetdb/parser'
|
5
5
|
|
6
6
|
describe PuppetDB::Parser do
|
7
|
-
context
|
7
|
+
context 'Query parsing' do
|
8
8
|
let(:parser) { PuppetDB::Parser.new }
|
9
|
-
it
|
9
|
+
it 'should handle empty queries' do
|
10
10
|
parser.parse('').should be_nil
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
14
|
-
parser.parse('foo="bar"').should eq
|
13
|
+
it 'should handle double quoted strings' do
|
14
|
+
parser.parse('foo="bar"').should eq \
|
15
|
+
['in', 'certname',
|
16
|
+
['extract', 'certname',
|
17
|
+
['select_fact_contents',
|
18
|
+
['and',
|
19
|
+
['=', 'path', ['foo']],
|
20
|
+
['=', 'value', 'bar']]]]]
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should handle single quoted strings' do
|
24
|
+
parser.parse('foo=\'bar\'').should eq \
|
25
|
+
['in', 'certname',
|
26
|
+
['extract', 'certname',
|
27
|
+
['select_fact_contents',
|
28
|
+
['and',
|
29
|
+
['=', 'path', ['foo']],
|
30
|
+
['=', 'value', 'bar']]]]]
|
15
31
|
end
|
16
32
|
|
17
|
-
it
|
18
|
-
parser.parse('foo
|
33
|
+
it 'should handle = operator' do
|
34
|
+
parser.parse('foo=bar').should eq \
|
35
|
+
['in', 'certname',
|
36
|
+
['extract', 'certname',
|
37
|
+
['select_fact_contents',
|
38
|
+
['and',
|
39
|
+
['=', 'path', ['foo']],
|
40
|
+
['=', 'value', 'bar']]]]]
|
19
41
|
end
|
20
42
|
|
21
|
-
it
|
22
|
-
parser.parse('foo
|
23
|
-
|
43
|
+
it 'should handle != operator' do
|
44
|
+
parser.parse('foo!=bar').should eq \
|
45
|
+
['in', 'certname',
|
46
|
+
['extract', 'certname',
|
47
|
+
['select_fact_contents',
|
48
|
+
['and',
|
49
|
+
['=', 'path', ['foo']],
|
50
|
+
['not', ['=', 'value', 'bar']]]]]]
|
24
51
|
end
|
25
52
|
|
26
|
-
it
|
27
|
-
parser.parse('
|
53
|
+
it 'should handle ~ operator' do
|
54
|
+
parser.parse('foo~bar').should eq \
|
55
|
+
['in', 'certname',
|
56
|
+
['extract', 'certname',
|
57
|
+
['select_fact_contents',
|
58
|
+
['and',
|
59
|
+
['=', 'path', ['foo']],
|
60
|
+
['~', 'value', 'bar']]]]]
|
28
61
|
end
|
29
62
|
|
30
|
-
it
|
31
|
-
parser.parse('
|
63
|
+
it 'should handle !~ operator' do
|
64
|
+
parser.parse('foo!~bar').should eq \
|
65
|
+
['in', 'certname',
|
66
|
+
['extract', 'certname',
|
67
|
+
['select_fact_contents',
|
68
|
+
['and',
|
69
|
+
['=', 'path', ['foo']],
|
70
|
+
['not', ['~', 'value', 'bar']]]]]]
|
32
71
|
end
|
33
72
|
|
34
|
-
it
|
35
|
-
parser.parse('
|
73
|
+
it 'should handle >= operator' do
|
74
|
+
parser.parse('foo>=1').should eq \
|
75
|
+
['in', 'certname',
|
76
|
+
['extract', 'certname',
|
77
|
+
['select_fact_contents',
|
78
|
+
['and',
|
79
|
+
['=', 'path', ['foo']],
|
80
|
+
['>=', 'value', 1]]]]]
|
36
81
|
end
|
37
82
|
|
38
|
-
it
|
39
|
-
parser.parse('
|
40
|
-
|
83
|
+
it 'should handle <= operator' do
|
84
|
+
parser.parse('foo<=1').should eq \
|
85
|
+
['in', 'certname',
|
86
|
+
['extract', 'certname',
|
87
|
+
['select_fact_contents',
|
88
|
+
['and',
|
89
|
+
['=', 'path', ['foo']],
|
90
|
+
['<=', 'value', 1]]]]]
|
41
91
|
end
|
42
92
|
|
43
|
-
it
|
44
|
-
parser.parse('
|
93
|
+
it 'should handle > operator' do
|
94
|
+
parser.parse('foo>1').should eq \
|
95
|
+
['in', 'certname',
|
96
|
+
['extract', 'certname',
|
97
|
+
['select_fact_contents',
|
98
|
+
['and',
|
99
|
+
['=', 'path', ['foo']],
|
100
|
+
['>', 'value', 1]]]]]
|
45
101
|
end
|
46
102
|
|
47
|
-
it
|
48
|
-
parser.parse('
|
103
|
+
it 'should handle < operator' do
|
104
|
+
parser.parse('foo<1').should eq \
|
105
|
+
['in', 'certname',
|
106
|
+
['extract', 'certname',
|
107
|
+
['select_fact_contents',
|
108
|
+
['and',
|
109
|
+
['=', 'path', ['foo']],
|
110
|
+
['<', 'value', 1]]]]]
|
49
111
|
end
|
50
112
|
|
51
|
-
it
|
52
|
-
parser.parse('
|
113
|
+
it 'should handle precedence' do
|
114
|
+
parser.parse('foo=1 or bar=2 and baz=3').should eq ['or', ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['=', 'path', ['foo']], ['=', 'value', 1]]]]], ['and', ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['=', 'path', ['bar']], ['=', 'value', 2]]]]], ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['=', 'path', ['baz']], ['=', 'value', 3]]]]]]]
|
115
|
+
parser.parse('(foo=1 or bar=2) and baz=3').should eq ['and', ['or', ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['=', 'path', ['foo']], ['=', 'value', 1]]]]], ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['=', 'path', ['bar']], ['=', 'value', 2]]]]]], ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['=', 'path', ['baz']], ['=', 'value', 3]]]]]]
|
53
116
|
end
|
54
117
|
|
55
|
-
it
|
56
|
-
parser.parse('foo
|
118
|
+
it 'should parse resource queries for exported resources' do
|
119
|
+
parser.parse('@@file[foo]').should eq ['in', 'certname', ['extract', 'certname', ['select_resources', ['and', ['=', 'type', 'File'], ['=', 'title', 'foo'], ['=', 'exported', true]]]]]
|
57
120
|
end
|
58
121
|
|
59
|
-
it
|
60
|
-
parser.parse('foo
|
122
|
+
it 'should parse resource queries with type, title and parameters' do
|
123
|
+
parser.parse('file[foo]{bar=baz}').should eq ['in', 'certname', ['extract', 'certname', ['select_resources', ['and', ['=', 'type', 'File'], ['=', 'title', 'foo'], ['=', 'exported', false], ['=', %w(parameter bar), 'baz']]]]]
|
61
124
|
end
|
62
125
|
|
63
|
-
it
|
64
|
-
parser.parse('foo
|
126
|
+
it 'should parse resource queries with tags' do
|
127
|
+
parser.parse('file[foo]{tag=baz}').should eq ['in', 'certname', ['extract', 'certname', ['select_resources', ['and', ['=', 'type', 'File'], ['=', 'title', 'foo'], ['=', 'exported', false], ['=', 'tag', 'baz']]]]]
|
65
128
|
end
|
66
129
|
|
67
|
-
it
|
68
|
-
parser.parse('foo
|
130
|
+
it 'should handle precedence within resource parameter queries' do
|
131
|
+
parser.parse('file[foo]{foo=1 or bar=2 and baz=3}').should eq ['in', 'certname', ['extract', 'certname', ['select_resources', ['and', ['=', 'type', 'File'], ['=', 'title', 'foo'], ['=', 'exported', false], ['or', ['=', %w(parameter foo), 1], ['and', ['=', %w(parameter bar), 2], ['=', %w(parameter baz), 3]]]]]]]
|
132
|
+
parser.parse('file[foo]{(foo=1 or bar=2) and baz=3}').should eq ['in', 'certname', ['extract', 'certname', ['select_resources', ['and', ['=', 'type', 'File'], ['=', 'title', 'foo'], ['=', 'exported', false], ['and', ['or', ['=', %w(parameter foo), 1], ['=', %w(parameter bar), 2]], ['=', %w(parameter baz), 3]]]]]]
|
69
133
|
end
|
70
134
|
|
71
|
-
it
|
72
|
-
parser.parse('foo
|
135
|
+
it 'should capitalize class names' do
|
136
|
+
parser.parse('class[foo::bar]').should eq ['in', 'certname', ['extract', 'certname', ['select_resources', ['and', ['=', 'type', 'Class'], ['=', 'title', 'Foo::Bar'], ['=', 'exported', false]]]]]
|
73
137
|
end
|
74
138
|
|
75
|
-
it
|
76
|
-
parser.parse('
|
139
|
+
it 'should parse resource queries with regeexp title matching' do
|
140
|
+
parser.parse('class[~foo]').should eq ['in', 'certname', ['extract', 'certname', ['select_resources', ['and', ['=', 'type', 'Class'], ['~', 'title', 'foo'], ['=', 'exported', false]]]]]
|
77
141
|
end
|
78
142
|
|
79
|
-
it
|
80
|
-
parser.parse('
|
143
|
+
it 'should be able to negate expressions' do
|
144
|
+
parser.parse('not foo=bar').should eq ['not', ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['=', 'path', ['foo']], ['=', 'value', 'bar']]]]]]
|
81
145
|
end
|
82
146
|
|
83
|
-
it
|
84
|
-
parser.parse('
|
147
|
+
it 'should handle single string expressions' do
|
148
|
+
parser.parse('foo.bar.com').should eq ['~', 'certname', 'foo\\.bar\\.com']
|
85
149
|
end
|
86
150
|
|
87
|
-
it
|
88
|
-
parser.parse('
|
151
|
+
it 'should handle structured facts' do
|
152
|
+
parser.parse('foo.bar=baz').should eq ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['=', 'path', %w(foo bar)], ['=', 'value', 'baz']]]]]
|
89
153
|
end
|
90
154
|
|
91
|
-
it
|
92
|
-
|
93
|
-
|
155
|
+
it 'should handle structured facts with array component' do
|
156
|
+
parser.parse('foo.bar.0=baz').should eq ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['=', 'path', ['foo', 'bar', 0]], ['=', 'value', 'baz']]]]]
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should handle structured facts with match operator' do
|
160
|
+
parser.parse('foo.bar.~".*"=baz').should eq ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['~>', 'path', ['foo', 'bar', '.*']], ['=', 'value', 'baz']]]]]
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should handle structured facts with wildcard operator' do
|
164
|
+
parser.parse('foo.bar.*=baz').should eq ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['~>', 'path', ['foo', 'bar', '.*']], ['=', 'value', 'baz']]]]]
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should handle #node subqueries' do
|
168
|
+
parser.parse('#node.catalog_environment=production').should eq ['in', 'certname', ['extract', 'certname', ['select_nodes', ['=', 'catalog_environment', 'production']]]]
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should handle #node subqueries with block of conditions' do
|
172
|
+
parser.parse('#node { catalog_environment=production }').should eq ['in', 'certname', ['extract', 'certname', ['select_nodes', ['=', 'catalog_environment', 'production']]]]
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should handle #node subquery combined with fact query' do
|
176
|
+
parser.parse('#node.catalog_environment=production and foo=bar').should eq ['and', ['in', 'certname', ['extract', 'certname', ['select_nodes', ['=', 'catalog_environment', 'production']]]], ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['=', 'path', ['foo']], ['=', 'value', 'bar']]]]]]
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'should escape non match parts on structured facts with match operator' do
|
180
|
+
parser.parse('"foo.bar".~".*"=baz').should eq ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['~>', 'path', ['foo\\.bar', '.*']], ['=', 'value', 'baz']]]]]
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'should parse dates in queries' do
|
184
|
+
date = Time.new(2014, 9, 9).iso8601
|
185
|
+
parser.parse('#node.report_timestamp<@"Sep 9, 2014"').should eq ['in', 'certname', ['extract', 'certname', ['select_nodes', ['<', 'report_timestamp', date]]]]
|
94
186
|
end
|
95
187
|
end
|
96
188
|
|
97
|
-
context
|
189
|
+
context 'facts_query' do
|
98
190
|
let(:parser) { PuppetDB::Parser.new }
|
99
191
|
it 'should return a query for all if no facts are specified' do
|
100
|
-
parser.facts_query('kernel=Linux').should eq [
|
192
|
+
parser.facts_query('kernel=Linux').should eq ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['=', 'path', ['kernel']], ['=', 'value', 'Linux']]]]]
|
101
193
|
end
|
102
194
|
|
103
195
|
it 'should return a query for specific facts if they are specified' do
|
104
|
-
parser.facts_query('kernel=Linux', ['ipaddress']). should eq [
|
196
|
+
parser.facts_query('kernel=Linux', ['ipaddress']). should eq ['and', ['in', 'certname', ['extract', 'certname', ['select_fact_contents', ['and', ['=', 'path', ['kernel']], ['=', 'value', 'Linux']]]]], ['or', ['=', 'name', 'ipaddress']]]
|
105
197
|
end
|
106
198
|
|
107
199
|
it 'should return a query for matching facts on all nodes if query is missing' do
|
108
|
-
parser.facts_query('', ['ipaddress']).should eq [
|
200
|
+
parser.facts_query('', ['ipaddress']).should eq ['or', ['=', 'name', 'ipaddress']]
|
109
201
|
end
|
110
202
|
end
|
111
203
|
|
@@ -113,16 +205,16 @@ describe PuppetDB::Parser do
|
|
113
205
|
let(:parser) { PuppetDB::Parser.new }
|
114
206
|
it 'should merge facts into a nested hash' do
|
115
207
|
parser.facts_hash([
|
116
|
-
{
|
117
|
-
{
|
118
|
-
{
|
119
|
-
{
|
120
|
-
{
|
121
|
-
{
|
208
|
+
{ 'certname' => 'ip-172-31-45-32.eu-west-1.compute.internal', 'environment' => 'production', 'name' => 'kernel', 'value' => 'Linux' },
|
209
|
+
{ 'certname' => 'ip-172-31-33-234.eu-west-1.compute.internal', 'environment' => 'production', 'name' => 'kernel', 'value' => 'Linux' },
|
210
|
+
{ 'certname' => 'ip-172-31-5-147.eu-west-1.compute.internal', 'environment' => 'production', 'name' => 'kernel', 'value' => 'Linux' },
|
211
|
+
{ 'certname' => 'ip-172-31-45-32.eu-west-1.compute.internal', 'environment' => 'production', 'name' => 'fqdn', 'value' => 'ip-172-31-45-32.eu-west-1.compute.internal' },
|
212
|
+
{ 'certname' => 'ip-172-31-33-234.eu-west-1.compute.internal', 'environment' => 'production', 'name' => 'fqdn', 'value' => 'ip-172-31-33-234.eu-west-1.compute.internal' },
|
213
|
+
{ 'certname' => 'ip-172-31-5-147.eu-west-1.compute.internal', 'environment' => 'production', 'name' => 'fqdn', 'value' => 'ip-172-31-5-147.eu-west-1.compute.internal' }
|
122
214
|
]).should eq(
|
123
|
-
|
124
|
-
|
125
|
-
|
215
|
+
'ip-172-31-45-32.eu-west-1.compute.internal' => { 'kernel' => 'Linux', 'fqdn' => 'ip-172-31-45-32.eu-west-1.compute.internal' },
|
216
|
+
'ip-172-31-33-234.eu-west-1.compute.internal' => { 'kernel' => 'Linux', 'fqdn' => 'ip-172-31-33-234.eu-west-1.compute.internal' },
|
217
|
+
'ip-172-31-5-147.eu-west-1.compute.internal' => { 'kernel' => 'Linux', 'fqdn' => 'ip-172-31-5-147.eu-west-1.compute.internal' }
|
126
218
|
)
|
127
219
|
end
|
128
220
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-puppetdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Erik Dalen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|