chef-zero 15.0.11 → 15.0.21

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.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +36 -29
  3. data/LICENSE +201 -201
  4. data/Rakefile +73 -68
  5. data/bin/chef-zero +111 -111
  6. data/chef-zero.gemspec +34 -28
  7. data/lib/chef_zero/chef_data/acl_path.rb +140 -140
  8. data/lib/chef_zero/chef_data/cookbook_data.rb +237 -237
  9. data/lib/chef_zero/chef_data/data_normalizer.rb +276 -276
  10. data/lib/chef_zero/chef_data/default_creator.rb +476 -476
  11. data/lib/chef_zero/data_store/data_already_exists_error.rb +29 -29
  12. data/lib/chef_zero/data_store/data_error.rb +32 -32
  13. data/lib/chef_zero/data_store/data_not_found_error.rb +29 -29
  14. data/lib/chef_zero/data_store/default_facade.rb +143 -147
  15. data/lib/chef_zero/data_store/interface_v1.rb +67 -67
  16. data/lib/chef_zero/data_store/interface_v2.rb +18 -18
  17. data/lib/chef_zero/data_store/memory_store.rb +33 -33
  18. data/lib/chef_zero/data_store/memory_store_v2.rb +159 -159
  19. data/lib/chef_zero/data_store/raw_file_store.rb +143 -143
  20. data/lib/chef_zero/data_store/v1_to_v2_adapter.rb +150 -150
  21. data/lib/chef_zero/data_store/v2_to_v1_adapter.rb +105 -105
  22. data/lib/chef_zero/dist.rb +9 -9
  23. data/lib/chef_zero/endpoints/acl_endpoint.rb +39 -39
  24. data/lib/chef_zero/endpoints/acls_endpoint.rb +41 -41
  25. data/lib/chef_zero/endpoints/actor_default_key_endpoint.rb +78 -78
  26. data/lib/chef_zero/endpoints/actor_endpoint.rb +184 -184
  27. data/lib/chef_zero/endpoints/actor_key_endpoint.rb +62 -62
  28. data/lib/chef_zero/endpoints/actor_keys_endpoint.rb +129 -129
  29. data/lib/chef_zero/endpoints/actors_endpoint.rb +104 -104
  30. data/lib/chef_zero/endpoints/authenticate_user_endpoint.rb +32 -32
  31. data/lib/chef_zero/endpoints/container_endpoint.rb +22 -22
  32. data/lib/chef_zero/endpoints/containers_endpoint.rb +25 -25
  33. data/lib/chef_zero/endpoints/controls_endpoint.rb +16 -16
  34. data/lib/chef_zero/endpoints/cookbook_artifact_endpoint.rb +24 -24
  35. data/lib/chef_zero/endpoints/cookbook_artifact_identifier_endpoint.rb +68 -68
  36. data/lib/chef_zero/endpoints/cookbook_artifacts_endpoint.rb +34 -34
  37. data/lib/chef_zero/endpoints/cookbook_endpoint.rb +39 -39
  38. data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +136 -136
  39. data/lib/chef_zero/endpoints/cookbooks_base.rb +80 -80
  40. data/lib/chef_zero/endpoints/cookbooks_endpoint.rb +19 -19
  41. data/lib/chef_zero/endpoints/data_bag_endpoint.rb +45 -45
  42. data/lib/chef_zero/endpoints/data_bag_item_endpoint.rb +25 -25
  43. data/lib/chef_zero/endpoints/data_bags_endpoint.rb +23 -23
  44. data/lib/chef_zero/endpoints/dummy_endpoint.rb +29 -29
  45. data/lib/chef_zero/endpoints/environment_cookbook_endpoint.rb +24 -24
  46. data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +126 -126
  47. data/lib/chef_zero/endpoints/environment_cookbooks_endpoint.rb +22 -22
  48. data/lib/chef_zero/endpoints/environment_endpoint.rb +33 -33
  49. data/lib/chef_zero/endpoints/environment_nodes_endpoint.rb +23 -23
  50. data/lib/chef_zero/endpoints/environment_recipes_endpoint.rb +22 -22
  51. data/lib/chef_zero/endpoints/environment_role_endpoint.rb +36 -36
  52. data/lib/chef_zero/endpoints/file_store_file_endpoint.rb +22 -22
  53. data/lib/chef_zero/endpoints/group_endpoint.rb +20 -20
  54. data/lib/chef_zero/endpoints/groups_endpoint.rb +13 -13
  55. data/lib/chef_zero/endpoints/license_endpoint.rb +25 -25
  56. data/lib/chef_zero/endpoints/node_endpoint.rb +34 -34
  57. data/lib/chef_zero/endpoints/node_identifiers_endpoint.rb +22 -22
  58. data/lib/chef_zero/endpoints/nodes_endpoint.rb +34 -34
  59. data/lib/chef_zero/endpoints/not_found_endpoint.rb +11 -11
  60. data/lib/chef_zero/endpoints/organization_association_request_endpoint.rb +22 -22
  61. data/lib/chef_zero/endpoints/organization_association_requests_endpoint.rb +30 -30
  62. data/lib/chef_zero/endpoints/organization_authenticate_user_endpoint.rb +26 -26
  63. data/lib/chef_zero/endpoints/organization_endpoint.rb +47 -47
  64. data/lib/chef_zero/endpoints/organization_user_base.rb +15 -15
  65. data/lib/chef_zero/endpoints/organization_user_default_key_endpoint.rb +16 -16
  66. data/lib/chef_zero/endpoints/organization_user_endpoint.rb +26 -26
  67. data/lib/chef_zero/endpoints/organization_user_key_endpoint.rb +17 -17
  68. data/lib/chef_zero/endpoints/organization_user_keys_endpoint.rb +17 -17
  69. data/lib/chef_zero/endpoints/organization_users_endpoint.rb +43 -43
  70. data/lib/chef_zero/endpoints/organization_validator_key_endpoint.rb +20 -20
  71. data/lib/chef_zero/endpoints/organizations_endpoint.rb +61 -61
  72. data/lib/chef_zero/endpoints/policies_endpoint.rb +26 -26
  73. data/lib/chef_zero/endpoints/policy_endpoint.rb +24 -24
  74. data/lib/chef_zero/endpoints/policy_group_endpoint.rb +46 -46
  75. data/lib/chef_zero/endpoints/policy_group_policy_endpoint.rb +83 -83
  76. data/lib/chef_zero/endpoints/policy_groups_endpoint.rb +38 -38
  77. data/lib/chef_zero/endpoints/policy_revision_endpoint.rb +66 -66
  78. data/lib/chef_zero/endpoints/policy_revisions_endpoint.rb +15 -15
  79. data/lib/chef_zero/endpoints/principal_endpoint.rb +55 -55
  80. data/lib/chef_zero/endpoints/rest_list_endpoint.rb +42 -42
  81. data/lib/chef_zero/endpoints/rest_object_endpoint.rb +78 -78
  82. data/lib/chef_zero/endpoints/role_endpoint.rb +16 -16
  83. data/lib/chef_zero/endpoints/role_environments_endpoint.rb +14 -14
  84. data/lib/chef_zero/endpoints/sandbox_endpoint.rb +27 -27
  85. data/lib/chef_zero/endpoints/sandboxes_endpoint.rb +51 -50
  86. data/lib/chef_zero/endpoints/search_endpoint.rb +208 -208
  87. data/lib/chef_zero/endpoints/searches_endpoint.rb +18 -18
  88. data/lib/chef_zero/endpoints/server_api_version_endpoint.rb +14 -14
  89. data/lib/chef_zero/endpoints/system_recovery_endpoint.rb +30 -30
  90. data/lib/chef_zero/endpoints/universe_endpoint.rb +15 -15
  91. data/lib/chef_zero/endpoints/user_association_request_endpoint.rb +41 -41
  92. data/lib/chef_zero/endpoints/user_association_requests_count_endpoint.rb +19 -19
  93. data/lib/chef_zero/endpoints/user_association_requests_endpoint.rb +19 -19
  94. data/lib/chef_zero/endpoints/user_organizations_endpoint.rb +22 -22
  95. data/lib/chef_zero/endpoints/version_endpoint.rb +13 -13
  96. data/lib/chef_zero/log.rb +7 -7
  97. data/lib/chef_zero/rest_base.rb +332 -332
  98. data/lib/chef_zero/rest_error_response.rb +11 -11
  99. data/lib/chef_zero/rest_request.rb +84 -88
  100. data/lib/chef_zero/rest_router.rb +72 -72
  101. data/lib/chef_zero/rspec.rb +355 -355
  102. data/lib/chef_zero/server.rb +730 -729
  103. data/lib/chef_zero/socketless_server_map.rb +92 -93
  104. data/lib/chef_zero/solr/query/binary_operator.rb +52 -52
  105. data/lib/chef_zero/solr/query/phrase.rb +23 -23
  106. data/lib/chef_zero/solr/query/range_query.rb +46 -46
  107. data/lib/chef_zero/solr/query/regexpable_query.rb +30 -30
  108. data/lib/chef_zero/solr/query/subquery.rb +37 -37
  109. data/lib/chef_zero/solr/query/term.rb +45 -45
  110. data/lib/chef_zero/solr/query/unary_operator.rb +41 -41
  111. data/lib/chef_zero/solr/solr_doc.rb +53 -53
  112. data/lib/chef_zero/solr/solr_parser.rb +208 -208
  113. data/lib/chef_zero/version.rb +3 -3
  114. data/lib/chef_zero.rb +10 -10
  115. data/spec/run_oc_pedant.rb +226 -226
  116. data/spec/search_spec.rb +36 -36
  117. data/spec/server_spec.rb +96 -96
  118. data/spec/socketless_server_map_spec.rb +74 -74
  119. data/spec/support/oc_pedant.rb +149 -149
  120. data/spec/support/secrets.json +6 -6
  121. data/spec/support/stickywicket.pem +27 -27
  122. metadata +72 -15
@@ -1,41 +1,41 @@
1
- module ChefZero
2
- module Solr
3
- module Query
4
- class UnaryOperator
5
- def initialize(operator, operand)
6
- @operator = operator
7
- @operand = operand
8
- end
9
-
10
- def to_s
11
- "#{operator} #{operand}"
12
- end
13
-
14
- attr_reader :operator
15
- attr_reader :operand
16
-
17
- def matches_doc?(doc)
18
- case @operator
19
- when "-", "NOT", "!"
20
- !operand.matches_doc?(doc)
21
- when "+"
22
- # TODO This operator uses relevance to eliminate other, unrelated
23
- # expressions. +a OR b means "if it has b but not a, don't return it"
24
- raise "+ not supported yet, because it is hard."
25
- end
26
- end
27
-
28
- def matches_values?(values)
29
- case @operator
30
- when "-", "NOT", "!"
31
- !operand.matches_values?(values)
32
- when "+"
33
- # TODO This operator uses relevance to eliminate other, unrelated
34
- # expressions. +a OR b means "if it has b but not a, don't return it"
35
- raise "+ not supported yet, because it is hard."
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end
1
+ module ChefZero
2
+ module Solr
3
+ module Query
4
+ class UnaryOperator
5
+ def initialize(operator, operand)
6
+ @operator = operator
7
+ @operand = operand
8
+ end
9
+
10
+ def to_s
11
+ "#{operator} #{operand}"
12
+ end
13
+
14
+ attr_reader :operator
15
+ attr_reader :operand
16
+
17
+ def matches_doc?(doc)
18
+ case @operator
19
+ when "-", "NOT", "!"
20
+ !operand.matches_doc?(doc)
21
+ when "+"
22
+ # TODO This operator uses relevance to eliminate other, unrelated
23
+ # expressions. +a OR b means "if it has b but not a, don't return it"
24
+ raise "+ not supported yet, because it is hard."
25
+ end
26
+ end
27
+
28
+ def matches_values?(values)
29
+ case @operator
30
+ when "-", "NOT", "!"
31
+ !operand.matches_values?(values)
32
+ when "+"
33
+ # TODO This operator uses relevance to eliminate other, unrelated
34
+ # expressions. +a OR b means "if it has b but not a, don't return it"
35
+ raise "+ not supported yet, because it is hard."
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,53 +1,53 @@
1
- module ChefZero
2
- module Solr
3
- # This does what expander does, flattening the json doc into keys and values
4
- # so that solr can search them.
5
- class SolrDoc
6
- def initialize(json, id)
7
- @json = json
8
- @id = id
9
- end
10
-
11
- def [](key)
12
- matching_values { |match_key| match_key == key }
13
- end
14
-
15
- def matching_values(&block)
16
- result = []
17
- key_values(nil, @json) do |key, value|
18
- if yield(key)
19
- result << value.to_s
20
- end
21
- end
22
- # Handle manufactured value(s)
23
- if yield("X_CHEF_id_CHEF_X")
24
- result << @id.to_s
25
- end
26
-
27
- result.uniq
28
- end
29
-
30
- private
31
-
32
- def key_values(key_so_far, value, &block)
33
- if value.is_a?(Hash)
34
- value.each_pair do |child_key, child_value|
35
- yield(child_key, child_value.to_s)
36
- if key_so_far
37
- new_key = "#{key_so_far}_#{child_key}"
38
- key_values(new_key, child_value, &block)
39
- else
40
- key_values(child_key, child_value, &block) if child_value.is_a?(Hash) || child_value.is_a?(Array)
41
- end
42
- end
43
- elsif value.is_a?(Array)
44
- value.each do |child_value|
45
- key_values(key_so_far, child_value, &block)
46
- end
47
- else
48
- yield(key_so_far || "text", value.to_s)
49
- end
50
- end
51
- end
52
- end
53
- end
1
+ module ChefZero
2
+ module Solr
3
+ # This does what expander does, flattening the json doc into keys and values
4
+ # so that solr can search them.
5
+ class SolrDoc
6
+ def initialize(json, id)
7
+ @json = json
8
+ @id = id
9
+ end
10
+
11
+ def [](key)
12
+ matching_values { |match_key| match_key == key }
13
+ end
14
+
15
+ def matching_values(&block)
16
+ result = []
17
+ key_values(nil, @json) do |key, value|
18
+ if yield(key)
19
+ result << value.to_s
20
+ end
21
+ end
22
+ # Handle manufactured value(s)
23
+ if yield("X_CHEF_id_CHEF_X")
24
+ result << @id.to_s
25
+ end
26
+
27
+ result.uniq
28
+ end
29
+
30
+ private
31
+
32
+ def key_values(key_so_far, value, &block)
33
+ if value.is_a?(Hash)
34
+ value.each_pair do |child_key, child_value|
35
+ yield(child_key, child_value.to_s)
36
+ if key_so_far
37
+ new_key = "#{key_so_far}_#{child_key}"
38
+ key_values(new_key, child_value, &block)
39
+ else
40
+ key_values(child_key, child_value, &block) if child_value.is_a?(Hash) || child_value.is_a?(Array)
41
+ end
42
+ end
43
+ elsif value.is_a?(Array)
44
+ value.each do |child_value|
45
+ key_values(key_so_far, child_value, &block)
46
+ end
47
+ else
48
+ yield(key_so_far || "text", value.to_s)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,208 +1,208 @@
1
- require_relative "query/binary_operator"
2
- require_relative "query/unary_operator"
3
- require_relative "query/term"
4
- require_relative "query/phrase"
5
- require_relative "query/range_query"
6
- require_relative "query/subquery"
7
-
8
- module ChefZero
9
- module Solr
10
- class ParseError < RuntimeError; end
11
-
12
- class SolrParser
13
- def initialize(query_string)
14
- @query_string = query_string
15
- @index = 0
16
- end
17
-
18
- def parse
19
- read_expression
20
- end
21
-
22
- #
23
- # Tokenization
24
- #
25
- def peek_token
26
- @next_token ||= parse_token
27
- end
28
-
29
- def next_token
30
- result = peek_token
31
- @next_token = nil
32
- result
33
- end
34
-
35
- def parse_token
36
- # Skip whitespace
37
- skip_whitespace
38
- return nil if eof?
39
-
40
- # Operators
41
- operator = peek_operator_token
42
- if operator
43
- @index += operator.length
44
- operator
45
- else
46
- # Everything that isn't whitespace or an operator, is part of a term
47
- # (characters plus backslashed escaped characters)
48
- start_index = @index
49
- loop do
50
- if @query_string[@index] == '\\'
51
- @index += 1
52
- end
53
- @index += 1 unless eof?
54
- break if eof? || !peek_term_token
55
- end
56
- @query_string[start_index..@index - 1]
57
- end
58
- end
59
-
60
- def skip_whitespace
61
- if @query_string[@index] =~ /\s/
62
- whitespace = /\s+/.match(@query_string, @index) || peek
63
- @index += whitespace[0].length
64
- end
65
- end
66
-
67
- def peek_term_token
68
- return nil if @query_string[@index] =~ /\s/
69
-
70
- op = peek_operator_token
71
- !op || op == "-"
72
- end
73
-
74
- def peek_operator_token
75
- if ['"', "+", "-", "!", "(", ")", "{", "}", "[", "]", "^", ":"].include?(@query_string[@index])
76
- return @query_string[@index]
77
- else
78
- result = @query_string[@index..@index + 1]
79
- if ["&&", "||"].include?(result)
80
- return result
81
- end
82
- end
83
-
84
- nil
85
- end
86
-
87
- def eof?
88
- !@next_token && @index >= @query_string.length
89
- end
90
-
91
- # Parse tree creation
92
- def read_expression
93
- result = read_single_expression
94
- # Expression is over when we hit a close paren or eof
95
- # (peek_token has the side effect of skipping whitespace for us, so we
96
- # really know if we're at eof or not)
97
- until peek_token == ")" || eof?
98
- operator = peek_token
99
- if binary_operator?(operator)
100
- next_token
101
- else
102
- # If 2 terms are next to each other, the default operator is OR
103
- operator = "OR"
104
- end
105
- next_expression = read_single_expression
106
-
107
- # Build the operator, taking precedence into account
108
- if result.is_a?(Query::BinaryOperator) &&
109
- binary_operator_precedence(operator) > binary_operator_precedence(result.operator)
110
- # a+b*c -> a+(b*c)
111
- new_right = Query::BinaryOperator.new(result.right, operator, next_expression)
112
- result = Query::BinaryOperator.new(result.left, result.operator, new_right)
113
- else
114
- # a*b+c -> (a*b)+c
115
- result = Query::BinaryOperator.new(result, operator, next_expression)
116
- end
117
- end
118
- result
119
- end
120
-
121
- def parse_error(token, str)
122
- raise ChefZero::Solr::ParseError, "Error on token '#{token}' at #{@index} of '#{@query_string}': #{str}"
123
- end
124
-
125
- def read_single_expression
126
- token = next_token
127
- # If EOF, we have a problem Houston
128
- if !token
129
- parse_error(nil, "Expected expression!")
130
-
131
- # If it's an unary operand, build that
132
- elsif unary_operator?(token)
133
- operand = read_single_expression
134
- # TODO We rely on all unary operators having higher precedence than all
135
- # binary operators. Check if this is the case.
136
- Query::UnaryOperator.new(token, operand)
137
-
138
- # If it's the start of a phrase, read the terms in the phrase
139
- elsif token == '"'
140
- # Read terms until close "
141
- phrase_terms = []
142
- until (term = next_token) == '"'
143
- phrase_terms << Query::Term.new(term)
144
- end
145
- Query::Phrase.new(phrase_terms)
146
-
147
- # If it's the start of a range query, build that
148
- elsif token == "{" || token == "["
149
- left = next_token
150
- parse_error(left, "Expected left term in range query") unless left
151
- to = next_token
152
- parse_error(left, "Expected TO in range query") if to != "TO"
153
- right = next_token
154
- parse_error(right, "Expected left term in range query") unless right
155
- end_range = next_token
156
- parse_error(right, "Expected end range '#{end_range}") unless ["}", "]"].include?(end_range)
157
- Query::RangeQuery.new(left, right, token == "[", end_range == "]")
158
-
159
- elsif token == "("
160
- subquery = read_expression
161
- close_paren = next_token
162
- parse_error(close_paren, "Expected ')'") if close_paren != ")"
163
- Query::Subquery.new(subquery)
164
-
165
- # If it's the end of a closure, raise an exception
166
- elsif ["}", "]", ")"].include?(token)
167
- parse_error(token, "Unexpected end paren")
168
-
169
- # If it's a binary operator, raise an exception
170
- elsif binary_operator?(token)
171
- parse_error(token, "Unexpected binary operator")
172
-
173
- # Otherwise it's a term.
174
- else
175
- term = Query::Term.new(token)
176
- if peek_token == ":"
177
- Query::BinaryOperator.new(term, next_token, read_single_expression)
178
- else
179
- term
180
- end
181
- end
182
- end
183
-
184
- def unary_operator?(token)
185
- [ "NOT", "+", "-", "!" ].include?(token)
186
- end
187
-
188
- def binary_operator?(token)
189
- [ "AND", "OR", "^", ":"].include?(token)
190
- end
191
-
192
- def binary_operator_precedence(token)
193
- case token
194
- when "^"
195
- 4
196
- when ":"
197
- 3
198
- when "AND"
199
- 2
200
- when "OR"
201
- 1
202
- end
203
- end
204
-
205
- DEFAULT_FIELD = "text".freeze
206
- end
207
- end
208
- end
1
+ require_relative "query/binary_operator"
2
+ require_relative "query/unary_operator"
3
+ require_relative "query/term"
4
+ require_relative "query/phrase"
5
+ require_relative "query/range_query"
6
+ require_relative "query/subquery"
7
+
8
+ module ChefZero
9
+ module Solr
10
+ class ParseError < RuntimeError; end
11
+
12
+ class SolrParser
13
+ def initialize(query_string)
14
+ @query_string = query_string
15
+ @index = 0
16
+ end
17
+
18
+ def parse
19
+ read_expression
20
+ end
21
+
22
+ #
23
+ # Tokenization
24
+ #
25
+ def peek_token
26
+ @next_token ||= parse_token
27
+ end
28
+
29
+ def next_token
30
+ result = peek_token
31
+ @next_token = nil
32
+ result
33
+ end
34
+
35
+ def parse_token
36
+ # Skip whitespace
37
+ skip_whitespace
38
+ return nil if eof?
39
+
40
+ # Operators
41
+ operator = peek_operator_token
42
+ if operator
43
+ @index += operator.length
44
+ operator
45
+ else
46
+ # Everything that isn't whitespace or an operator, is part of a term
47
+ # (characters plus backslashed escaped characters)
48
+ start_index = @index
49
+ loop do
50
+ if @query_string[@index] == "\\"
51
+ @index += 1
52
+ end
53
+ @index += 1 unless eof?
54
+ break if eof? || !peek_term_token
55
+ end
56
+ @query_string[start_index..@index - 1]
57
+ end
58
+ end
59
+
60
+ def skip_whitespace
61
+ if @query_string[@index] =~ /\s/
62
+ whitespace = /\s+/.match(@query_string, @index) || peek
63
+ @index += whitespace[0].length
64
+ end
65
+ end
66
+
67
+ def peek_term_token
68
+ return nil if @query_string[@index] =~ /\s/
69
+
70
+ op = peek_operator_token
71
+ !op || op == "-"
72
+ end
73
+
74
+ def peek_operator_token
75
+ if ['"', "+", "-", "!", "(", ")", "{", "}", "[", "]", "^", ":"].include?(@query_string[@index])
76
+ return @query_string[@index]
77
+ else
78
+ result = @query_string[@index..@index + 1]
79
+ if ["&&", "||"].include?(result)
80
+ return result
81
+ end
82
+ end
83
+
84
+ nil
85
+ end
86
+
87
+ def eof?
88
+ !@next_token && @index >= @query_string.length
89
+ end
90
+
91
+ # Parse tree creation
92
+ def read_expression
93
+ result = read_single_expression
94
+ # Expression is over when we hit a close paren or eof
95
+ # (peek_token has the side effect of skipping whitespace for us, so we
96
+ # really know if we're at eof or not)
97
+ until peek_token == ")" || eof?
98
+ operator = peek_token
99
+ if binary_operator?(operator)
100
+ next_token
101
+ else
102
+ # If 2 terms are next to each other, the default operator is OR
103
+ operator = "OR"
104
+ end
105
+ next_expression = read_single_expression
106
+
107
+ # Build the operator, taking precedence into account
108
+ if result.is_a?(Query::BinaryOperator) &&
109
+ binary_operator_precedence(operator) > binary_operator_precedence(result.operator)
110
+ # a+b*c -> a+(b*c)
111
+ new_right = Query::BinaryOperator.new(result.right, operator, next_expression)
112
+ result = Query::BinaryOperator.new(result.left, result.operator, new_right)
113
+ else
114
+ # a*b+c -> (a*b)+c
115
+ result = Query::BinaryOperator.new(result, operator, next_expression)
116
+ end
117
+ end
118
+ result
119
+ end
120
+
121
+ def parse_error(token, str)
122
+ raise ChefZero::Solr::ParseError, "Error on token '#{token}' at #{@index} of '#{@query_string}': #{str}"
123
+ end
124
+
125
+ def read_single_expression
126
+ token = next_token
127
+ # If EOF, we have a problem Houston
128
+ if !token
129
+ parse_error(nil, "Expected expression!")
130
+
131
+ # If it's an unary operand, build that
132
+ elsif unary_operator?(token)
133
+ operand = read_single_expression
134
+ # TODO We rely on all unary operators having higher precedence than all
135
+ # binary operators. Check if this is the case.
136
+ Query::UnaryOperator.new(token, operand)
137
+
138
+ # If it's the start of a phrase, read the terms in the phrase
139
+ elsif token == '"'
140
+ # Read terms until close "
141
+ phrase_terms = []
142
+ until (term = next_token) == '"'
143
+ phrase_terms << Query::Term.new(term)
144
+ end
145
+ Query::Phrase.new(phrase_terms)
146
+
147
+ # If it's the start of a range query, build that
148
+ elsif token == "{" || token == "["
149
+ left = next_token
150
+ parse_error(left, "Expected left term in range query") unless left
151
+ to = next_token
152
+ parse_error(left, "Expected TO in range query") if to != "TO"
153
+ right = next_token
154
+ parse_error(right, "Expected left term in range query") unless right
155
+ end_range = next_token
156
+ parse_error(right, "Expected end range '#{end_range}") unless ["}", "]"].include?(end_range)
157
+ Query::RangeQuery.new(left, right, token == "[", end_range == "]")
158
+
159
+ elsif token == "("
160
+ subquery = read_expression
161
+ close_paren = next_token
162
+ parse_error(close_paren, "Expected ')'") if close_paren != ")"
163
+ Query::Subquery.new(subquery)
164
+
165
+ # If it's the end of a closure, raise an exception
166
+ elsif ["}", "]", ")"].include?(token)
167
+ parse_error(token, "Unexpected end paren")
168
+
169
+ # If it's a binary operator, raise an exception
170
+ elsif binary_operator?(token)
171
+ parse_error(token, "Unexpected binary operator")
172
+
173
+ # Otherwise it's a term.
174
+ else
175
+ term = Query::Term.new(token)
176
+ if peek_token == ":"
177
+ Query::BinaryOperator.new(term, next_token, read_single_expression)
178
+ else
179
+ term
180
+ end
181
+ end
182
+ end
183
+
184
+ def unary_operator?(token)
185
+ [ "NOT", "+", "-", "!" ].include?(token)
186
+ end
187
+
188
+ def binary_operator?(token)
189
+ [ "AND", "OR", "^", ":"].include?(token)
190
+ end
191
+
192
+ def binary_operator_precedence(token)
193
+ case token
194
+ when "^"
195
+ 4
196
+ when ":"
197
+ 3
198
+ when "AND"
199
+ 2
200
+ when "OR"
201
+ 1
202
+ end
203
+ end
204
+
205
+ DEFAULT_FIELD = "text".freeze
206
+ end
207
+ end
208
+ end
@@ -1,3 +1,3 @@
1
- module ChefZero
2
- VERSION = "15.0.11".freeze
3
- end
1
+ module ChefZero
2
+ VERSION = "15.0.21".freeze
3
+ end
data/lib/chef_zero.rb CHANGED
@@ -1,10 +1,10 @@
1
- module ChefZero
2
- require_relative "chef_zero/log"
3
-
4
- MIN_API_VERSION = 0
5
- MAX_API_VERSION = 2
6
-
7
- CERTIFICATE = "-----BEGIN CERTIFICATE-----\nMIIDMzCCApygAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEyMTEyMTAwMzQyMVoXDTIyMTExOTAwMzQyMVowgZsxEDAOBgNVBAcTB1Nl\nYXR0bGUxEzARBgNVBAgTCldhc2hpbmd0b24xCzAJBgNVBAYTAlVTMRwwGgYDVQQL\nExNDZXJ0aWZpY2F0ZSBTZXJ2aWNlMRYwFAYDVQQKEw1PcHNjb2RlLCBJbmMuMS8w\nLQYDVQQDFCZVUkk6aHR0cDovL29wc2NvZGUuY29tL0dVSURTL3VzZXJfZ3VpZDCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANLDmPbR71bS2esZlZh/HfC6\n0azXFjl2677wq2ovk9xrUb0Ui4ZLC66TqQ9C/RBzOjXU4TRf3hgPTqvlCgHusl0d\nIcLCrsSl6kPEhJpYWWfRoroIAwf82A9yLQekhqXZEXu5EKkwoUMqyF6m0ZCasaE1\ny8niQxdLAsk3ady/CGQlFqHTPKFfU5UASR2LRtYC1MCIvJHDFRKAp9kPJbQo9P37\nZ8IU7cDudkZFgNLmDixlWsh7C0ghX8fgAlj1P6FgsFufygam973k79GhIP54dELB\nc0S6E8ekkRSOXU9jX/IoiXuFglBvFihAdhvED58bMXzj2AwXUyeAlxItnvs+NVUC\nAwEAATANBgkqhkiG9w0BAQUFAAOBgQBkFZRbMoywK3hb0/X7MXmPYa7nlfnd5UXq\nr2n32ettzZNmEPaI2d1j+//nL5qqhOlrWPS88eKEPnBOX/jZpUWOuAAddnrvFzgw\nrp/C2H7oMT+29F+5ezeViLKbzoFYb4yECHBoi66IFXNae13yj7taMboBeUmE664G\nTB/MZpRr8g==\n-----END CERTIFICATE-----\n".freeze
8
- PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0sOY9tHvVtLZ6xmVmH8d\n8LrRrNcWOXbrvvCrai+T3GtRvRSLhksLrpOpD0L9EHM6NdThNF/eGA9Oq+UKAe6y\nXR0hwsKuxKXqQ8SEmlhZZ9GiuggDB/zYD3ItB6SGpdkRe7kQqTChQyrIXqbRkJqx\noTXLyeJDF0sCyTdp3L8IZCUWodM8oV9TlQBJHYtG1gLUwIi8kcMVEoCn2Q8ltCj0\n/ftnwhTtwO52RkWA0uYOLGVayHsLSCFfx+ACWPU/oWCwW5/KBqb3veTv0aEg/nh0\nQsFzRLoTx6SRFI5dT2Nf8iiJe4WCUG8WKEB2G8QPnxsxfOPYDBdTJ4CXEi2e+z41\nVQIDAQAB\n-----END PUBLIC KEY-----\n".freeze
9
- PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA0sOY9tHvVtLZ6xmVmH8d8LrRrNcWOXbrvvCrai+T3GtRvRSL\nhksLrpOpD0L9EHM6NdThNF/eGA9Oq+UKAe6yXR0hwsKuxKXqQ8SEmlhZZ9GiuggD\nB/zYD3ItB6SGpdkRe7kQqTChQyrIXqbRkJqxoTXLyeJDF0sCyTdp3L8IZCUWodM8\noV9TlQBJHYtG1gLUwIi8kcMVEoCn2Q8ltCj0/ftnwhTtwO52RkWA0uYOLGVayHsL\nSCFfx+ACWPU/oWCwW5/KBqb3veTv0aEg/nh0QsFzRLoTx6SRFI5dT2Nf8iiJe4WC\nUG8WKEB2G8QPnxsxfOPYDBdTJ4CXEi2e+z41VQIDAQABAoIBAALhqbW2KQ+G0nPk\nZacwFbi01SkHx8YBWjfCEpXhEKRy0ytCnKW5YO+CFU2gHNWcva7+uhV9OgwaKXkw\nKHLeUJH1VADVqI4Htqw2g5mYm6BPvWnNsjzpuAp+BR+VoEGkNhj67r9hatMAQr0I\nitTvSH5rvd2EumYXIHKfz1K1SegUk1u1EL1RcMzRmZe4gDb6eNBs9Sg4im4ybTG6\npPIytA8vBQVWhjuAR2Tm+wZHiy0Az6Vu7c2mS07FSX6FO4E8SxWf8idaK9ijMGSq\nFvIS04mrY6XCPUPUC4qm1qNnhDPpOr7CpI2OO98SqGanStS5NFlSFXeXPpM280/u\nfZUA0AECgYEA+x7QUnffDrt7LK2cX6wbvn4mRnFxet7bJjrfWIHf+Rm0URikaNma\nh0/wNKpKBwIH+eHK/LslgzcplrqPytGGHLOG97Gyo5tGAzyLHUWBmsNkRksY2sPL\nuHq6pYWJNkqhnWGnIbmqCr0EWih82x/y4qxbJYpYqXMrit0wVf7yAgkCgYEA1twI\ngFaXqesetTPoEHSQSgC8S4D5/NkdriUXCYb06REcvo9IpFMuiOkVUYNN5d3MDNTP\nIdBicfmvfNELvBtXDomEUD8ls1UuoTIXRNGZ0VsZXu7OErXCK0JKNNyqRmOwcvYL\nJRqLfnlei5Ndo1lu286yL74c5rdTLs/nI2p4e+0CgYB079ZmcLeILrmfBoFI8+Y/\ngJLmPrFvXBOE6+lRV7kqUFPtZ6I3yQzyccETZTDvrnx0WjaiFavUPH27WMjY01S2\nTMtO0Iq1MPsbSrglO1as8MvjB9ldFcvp7gy4Q0Sv6XT0yqJ/S+vo8Df0m+H4UBpU\nf5o6EwBSd/UQxwtZIE0lsQKBgQCswfjX8Eg8KL/lJNpIOOE3j4XXE9ptksmJl2sB\njxDnQYoiMqVO808saHVquC/vTrpd6tKtNpehWwjeTFuqITWLi8jmmQ+gNTKsC9Gn\n1Pxf2Gb67PqnEpwQGln+TRtgQ5HBrdHiQIi+5am+gnw89pDrjjO5rZwhanAo6KPJ\n1zcPNQKBgQDxFu8v4frDmRNCVaZS4f1B6wTrcMrnibIDlnzrK9GG6Hz1U7dDv8s8\nNf4UmeMzDXjlPWZVOvS5+9HKJPdPj7/onv8B2m18+lcgTTDJBkza7R1mjL1Cje/Z\nKcVGsryKN6cjE7yCDasnA7R2rVBV/7NWeJV77bmzT5O//rW4yIfUIg==\n-----END RSA PRIVATE KEY-----\n".freeze
10
- end
1
+ module ChefZero
2
+ require_relative "chef_zero/log"
3
+
4
+ MIN_API_VERSION = 0
5
+ MAX_API_VERSION = 2
6
+
7
+ CERTIFICATE = "-----BEGIN CERTIFICATE-----\nMIIDMzCCApygAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEyMTEyMTAwMzQyMVoXDTIyMTExOTAwMzQyMVowgZsxEDAOBgNVBAcTB1Nl\nYXR0bGUxEzARBgNVBAgTCldhc2hpbmd0b24xCzAJBgNVBAYTAlVTMRwwGgYDVQQL\nExNDZXJ0aWZpY2F0ZSBTZXJ2aWNlMRYwFAYDVQQKEw1PcHNjb2RlLCBJbmMuMS8w\nLQYDVQQDFCZVUkk6aHR0cDovL29wc2NvZGUuY29tL0dVSURTL3VzZXJfZ3VpZDCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANLDmPbR71bS2esZlZh/HfC6\n0azXFjl2677wq2ovk9xrUb0Ui4ZLC66TqQ9C/RBzOjXU4TRf3hgPTqvlCgHusl0d\nIcLCrsSl6kPEhJpYWWfRoroIAwf82A9yLQekhqXZEXu5EKkwoUMqyF6m0ZCasaE1\ny8niQxdLAsk3ady/CGQlFqHTPKFfU5UASR2LRtYC1MCIvJHDFRKAp9kPJbQo9P37\nZ8IU7cDudkZFgNLmDixlWsh7C0ghX8fgAlj1P6FgsFufygam973k79GhIP54dELB\nc0S6E8ekkRSOXU9jX/IoiXuFglBvFihAdhvED58bMXzj2AwXUyeAlxItnvs+NVUC\nAwEAATANBgkqhkiG9w0BAQUFAAOBgQBkFZRbMoywK3hb0/X7MXmPYa7nlfnd5UXq\nr2n32ettzZNmEPaI2d1j+//nL5qqhOlrWPS88eKEPnBOX/jZpUWOuAAddnrvFzgw\nrp/C2H7oMT+29F+5ezeViLKbzoFYb4yECHBoi66IFXNae13yj7taMboBeUmE664G\nTB/MZpRr8g==\n-----END CERTIFICATE-----\n".freeze
8
+ PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0sOY9tHvVtLZ6xmVmH8d\n8LrRrNcWOXbrvvCrai+T3GtRvRSLhksLrpOpD0L9EHM6NdThNF/eGA9Oq+UKAe6y\nXR0hwsKuxKXqQ8SEmlhZZ9GiuggDB/zYD3ItB6SGpdkRe7kQqTChQyrIXqbRkJqx\noTXLyeJDF0sCyTdp3L8IZCUWodM8oV9TlQBJHYtG1gLUwIi8kcMVEoCn2Q8ltCj0\n/ftnwhTtwO52RkWA0uYOLGVayHsLSCFfx+ACWPU/oWCwW5/KBqb3veTv0aEg/nh0\nQsFzRLoTx6SRFI5dT2Nf8iiJe4WCUG8WKEB2G8QPnxsxfOPYDBdTJ4CXEi2e+z41\nVQIDAQAB\n-----END PUBLIC KEY-----\n".freeze
9
+ PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA0sOY9tHvVtLZ6xmVmH8d8LrRrNcWOXbrvvCrai+T3GtRvRSL\nhksLrpOpD0L9EHM6NdThNF/eGA9Oq+UKAe6yXR0hwsKuxKXqQ8SEmlhZZ9GiuggD\nB/zYD3ItB6SGpdkRe7kQqTChQyrIXqbRkJqxoTXLyeJDF0sCyTdp3L8IZCUWodM8\noV9TlQBJHYtG1gLUwIi8kcMVEoCn2Q8ltCj0/ftnwhTtwO52RkWA0uYOLGVayHsL\nSCFfx+ACWPU/oWCwW5/KBqb3veTv0aEg/nh0QsFzRLoTx6SRFI5dT2Nf8iiJe4WC\nUG8WKEB2G8QPnxsxfOPYDBdTJ4CXEi2e+z41VQIDAQABAoIBAALhqbW2KQ+G0nPk\nZacwFbi01SkHx8YBWjfCEpXhEKRy0ytCnKW5YO+CFU2gHNWcva7+uhV9OgwaKXkw\nKHLeUJH1VADVqI4Htqw2g5mYm6BPvWnNsjzpuAp+BR+VoEGkNhj67r9hatMAQr0I\nitTvSH5rvd2EumYXIHKfz1K1SegUk1u1EL1RcMzRmZe4gDb6eNBs9Sg4im4ybTG6\npPIytA8vBQVWhjuAR2Tm+wZHiy0Az6Vu7c2mS07FSX6FO4E8SxWf8idaK9ijMGSq\nFvIS04mrY6XCPUPUC4qm1qNnhDPpOr7CpI2OO98SqGanStS5NFlSFXeXPpM280/u\nfZUA0AECgYEA+x7QUnffDrt7LK2cX6wbvn4mRnFxet7bJjrfWIHf+Rm0URikaNma\nh0/wNKpKBwIH+eHK/LslgzcplrqPytGGHLOG97Gyo5tGAzyLHUWBmsNkRksY2sPL\nuHq6pYWJNkqhnWGnIbmqCr0EWih82x/y4qxbJYpYqXMrit0wVf7yAgkCgYEA1twI\ngFaXqesetTPoEHSQSgC8S4D5/NkdriUXCYb06REcvo9IpFMuiOkVUYNN5d3MDNTP\nIdBicfmvfNELvBtXDomEUD8ls1UuoTIXRNGZ0VsZXu7OErXCK0JKNNyqRmOwcvYL\nJRqLfnlei5Ndo1lu286yL74c5rdTLs/nI2p4e+0CgYB079ZmcLeILrmfBoFI8+Y/\ngJLmPrFvXBOE6+lRV7kqUFPtZ6I3yQzyccETZTDvrnx0WjaiFavUPH27WMjY01S2\nTMtO0Iq1MPsbSrglO1as8MvjB9ldFcvp7gy4Q0Sv6XT0yqJ/S+vo8Df0m+H4UBpU\nf5o6EwBSd/UQxwtZIE0lsQKBgQCswfjX8Eg8KL/lJNpIOOE3j4XXE9ptksmJl2sB\njxDnQYoiMqVO808saHVquC/vTrpd6tKtNpehWwjeTFuqITWLi8jmmQ+gNTKsC9Gn\n1Pxf2Gb67PqnEpwQGln+TRtgQ5HBrdHiQIi+5am+gnw89pDrjjO5rZwhanAo6KPJ\n1zcPNQKBgQDxFu8v4frDmRNCVaZS4f1B6wTrcMrnibIDlnzrK9GG6Hz1U7dDv8s8\nNf4UmeMzDXjlPWZVOvS5+9HKJPdPj7/onv8B2m18+lcgTTDJBkza7R1mjL1Cje/Z\nKcVGsryKN6cjE7yCDasnA7R2rVBV/7NWeJV77bmzT5O//rW4yIfUIg==\n-----END RSA PRIVATE KEY-----\n".freeze
10
+ end