insights-api-common 3.8.0 → 3.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +58 -25
- data/lib/insights/api/common/application_controller_mixins/api_doc.rb +8 -0
- data/lib/insights/api/common/application_controller_mixins/parameters.rb +5 -1
- data/lib/insights/api/common/filter.rb +102 -23
- data/lib/insights/api/common/graphql/templates/query_type.erb +4 -1
- data/lib/insights/api/common/rbac/validate_groups.rb +1 -1
- data/lib/insights/api/common/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 484591366a853923b1456ad224f13ea7462cf54c7e2e50091307ab3f6e70dffd
|
4
|
+
data.tar.gz: 0cfbc0b28162bcf862173cd1a4941a6cd406e9ca301316be1adb4856dcd834d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3632e7ccbe7eea9360829aef22960d5605235d95a01b725e7113392787836adb73272ac5280853ea78d610b0bd3b731a507845fd4aecf9dfa2e68d1f5830c72f
|
7
|
+
data.tar.gz: 18460ede94fc0d761284dd1b497e31dd9a0993caa17cc949a982098a6faca24b54d1efb3daf78f776a0f0e2ef79f63eeaeb46940fbf1892de99472cba0d06f6a
|
data/README.md
CHANGED
@@ -49,43 +49,76 @@ Or install it yourself as:
|
|
49
49
|
|
50
50
|
After implementing filtering in your application, this is the way to filter via parameters on index functions:
|
51
51
|
|
52
|
-
| Query Parameter | Ruby Client Parameter
|
53
|
-
| --------------- |
|
54
|
-
|"?filter[name]=reviews"
|
55
|
-
|"?filter[name][eq]=reviews"
|
56
|
-
|"?filter[name][starts_with]=a"
|
57
|
-
|"?filter[name][ends_with]=manager"
|
58
|
-
|"?filter[name][contains]=openshift"
|
59
|
-
|"?filter[id]=5"
|
60
|
-
|"?filter[id][eq]=5"
|
61
|
-
|"?filter[id][gt]=180"
|
62
|
-
|"?filter[id][gte]=190"
|
63
|
-
|"?filter[id][lt]=5"
|
64
|
-
|"?filter[id][lte]=5"
|
65
|
-
|"?filter[id][]=5&filter[id][]=10&filter[id][]=15&filter[id][]=20"
|
66
|
-
|"?filter[id][eq][]=5&filter[id][eq][]=10&filter[id][eq][]=15&filter[id][eq][]=20"
|
52
|
+
| Query Parameter | Ruby Client Parameter | GraphQL Parameter |
|
53
|
+
| --------------- | --------------------- | ----------------- |
|
54
|
+
| "?filter[name]=reviews" | { :filter => { :name => "reviews" } } | filter: { name: "reviews" } |
|
55
|
+
| "?filter[name][eq]=reviews" | { :filter => { :name => { :eq => "reviews" } } } | filter: { name: { eq: "reviews" } } |
|
56
|
+
| "?filter[name][starts_with]=a" | { :filter => { :name => { :starts_with => "a" } } } | filter: { name: { starts_with: "a" } } |
|
57
|
+
| "?filter[name][ends_with]=manager" | { :filter => { :name => { :ends_with => "manager" } } } | filter: { name: { ends_with: "manager" } } |
|
58
|
+
| "?filter[name][contains]=openshift" | { :filter => { :name => { :contains => "openshift" } } } | filter: { name: { contains: "openshift" } } |
|
59
|
+
| "?filter[id]=5" | { :filter => { :id => "5" } } | filter: { id: "5" } |
|
60
|
+
| "?filter[id][eq]=5" | { :filter => { :id => { :eq => "5" } } } | filter: { id: { eq: "5" } } |
|
61
|
+
| "?filter[id][gt]=180" | { :filter => { :id => { :gt => "180" } } } | filter: { id: { gt: "180" } } |
|
62
|
+
| "?filter[id][gte]=190" | { :filter => { :id => { :gte => "190" } } } | filter: { id: { gte: "190" } } |
|
63
|
+
| "?filter[id][lt]=5" | { :filter => { :id => { :lt => "5" } } } | filter: { id: { lt: "5" } } |
|
64
|
+
| "?filter[id][lte]=5" | { :filter => { :id => { :lte => "5" } } } | filter: { id: { lte: "5" } } |
|
65
|
+
| "?filter[id][]=5&filter[id][]=10&filter[id][]=15&filter[id][]=20" | { :filter => { :id => ["5", "10", "15", "20"] } } | filter: { id: ["5", "10", "15", "20"] } |
|
66
|
+
| "?filter[id][eq][]=5&filter[id][eq][]=10&filter[id][eq][]=15&filter[id][eq][]=20" | { :filter => { :id => { :eq => ["5", "10", "15", "20"] } } } | filter: { id: { eq: ["5", "10", "15", "20"] } |
|
67
67
|
|
68
68
|
#### Sorting Results
|
69
69
|
|
70
70
|
Sorting query results is controlled via the _sort_by_ query parameter. The _sort_by_ parameter is available for both REST API and GraphQL requests.
|
71
71
|
|
72
|
-
The
|
72
|
+
The _sort_by_ parameter specifies which attribute name to sort the results by, and may include a sort order of ascending _asc_ or descending _desc_. The default behavior when no sorting order is specified is to sort by ascending order.
|
73
|
+
|
74
|
+
The syntax for the _sort_by_ parameter is as follows:
|
73
75
|
|
74
|
-
-
|
75
|
-
|
76
|
-
- **attribute
|
77
|
-
- **attribute
|
78
|
-
-
|
76
|
+
- One or more object keys representing the attribute name(s) to sort by which may be assigned the **asc** or **desc** value for the sort order.
|
77
|
+
|
78
|
+
- [**attribute**] (_default order is ascending_)
|
79
|
+
- [**attribute**]=**asc** (_ascending order_)
|
80
|
+
- [**attribute**]=**desc** (_descending order_)
|
79
81
|
|
80
82
|
##### Sort_by Examples:
|
81
83
|
|
82
|
-
- GET /api/
|
83
|
-
- GET /api/
|
84
|
+
- GET /api/v2.0/sources?sort_by[name]
|
85
|
+
- GET /api/v2.0/vms?sort_by[power_state]&sort_by[memory]=desc
|
86
|
+
|
87
|
+
| Query Parameter | Ruby Client Parameter | GraphQL Parameter |
|
88
|
+
| --------------- | --------------------- | ----------------- |
|
89
|
+
| "?sort_by[name]" | { :sort_by => { :name => nil } } | sort_by: { name: null } |
|
90
|
+
| "?sort_by[name]=asc" | { :sort_by => { :name => "asc" } } | sort_by: { name: "asc" } |
|
91
|
+
| "?sort_by[power_state]&sort_by[memory]=desc" | { :sort_by => { :power_state => nil, :memory => "desc" } } | sort_by: { power_state: null, memory: "desc" } |
|
92
|
+
|
93
|
+
#### Filtering and Sorting by Association attribute
|
94
|
+
|
95
|
+
Requests can also be filtered by assocation attribute and sorted by association attribute and count in addition to the direct attribute specified as in the above examples.
|
96
|
+
|
97
|
+
Single level association can be specified as follows:
|
98
|
+
|
99
|
+
##### Filter by association attribute:
|
100
|
+
|
101
|
+
| Query Parameter | Ruby Client Parameter | GraphQL Parameter |
|
102
|
+
| --------------- | --------------------- | ----------------- |
|
103
|
+
| "?filter[association][name]=reviews" | { :filter => { :association => { :name => "reviews" } } } | filter: { association: { name: "reviews" } } |
|
104
|
+
| "?filter[association][name][eq]=reviews" | { :filter => { :association => { :name => { :eq => "reviews" } } } } | filter: { association: { name: { eq: "reviews" } } } |
|
105
|
+
|
106
|
+
##### Sort by association attributes and count:
|
107
|
+
|
108
|
+
The _sort_by_ parameter can also be used to choose to sort by attributes of association objects as well as sorting by
|
109
|
+
the count of association records by specifying the **__count** special attribute as follows:
|
110
|
+
|
111
|
+
| Query Parameter | Ruby Client Parameter | GraphQL Parameter |
|
112
|
+
| --------------- | --------------------- | ----------------- |
|
113
|
+
| "?sort_by[association][name]" | { :sort_by => { :association => { :name => nil } } } | sort_by: { association: { name: null } } |
|
114
|
+
| "?sort_by[association][name]=desc" | { :sort_by => { :association => { :name => "desc" } } } | sort_by: { association: { name: "desc" } } |
|
115
|
+
| "?sort_by[association][__count]=asc" | { :sort_by => { :association => { :__count => "asc" } } } | sort_by: { association: { __count: "asc" } } |
|
116
|
+
|
117
|
+
##### Combined Filtering and Sorting example:
|
84
118
|
|
85
119
|
| Query Parameter | Ruby Client Parameter | GraphQL Parameter |
|
86
120
|
| --------------- | --------------------- | ----------------- |
|
87
|
-
| "?sort_by=name" | { :sort_by => "name" } | sort_by: "name" |
|
88
|
-
| "?sort_by[]=power_state\&sort_by[]=memory:desc" | { :sort_by => ["power_state", "memory:desc"] } | sort_by: ["power_state, "memory:desc"] |
|
121
|
+
| "?filter[name][starts_with]=sample_&sort_by[application_types][__count]=desc&sort_by[name]=asc" | { :filter => { :name => { :starts_with => "sample_" } }, :sort_by => { :application_types => { :__count => "desc" }, :name => "asc" } } | filter: { name: { starts_with: "sample_" } }, sort_by: { application_types: { __count: "desc" }, name: "asc" } |
|
89
122
|
|
90
123
|
## Development
|
91
124
|
|
@@ -17,6 +17,10 @@ module Insights
|
|
17
17
|
self.class.send(:api_doc_definition)
|
18
18
|
end
|
19
19
|
|
20
|
+
def api_doc_definitions
|
21
|
+
self.class.send(:api_doc_definitions)
|
22
|
+
end
|
23
|
+
|
20
24
|
module ClassMethods
|
21
25
|
private
|
22
26
|
|
@@ -28,6 +32,10 @@ module Insights
|
|
28
32
|
@api_doc_definition ||= api_doc.definitions[name.split("::").last[0..-11].singularize]
|
29
33
|
end
|
30
34
|
|
35
|
+
def api_doc_definitions
|
36
|
+
@api_doc_definitions ||= api_doc.definitions
|
37
|
+
end
|
38
|
+
|
31
39
|
def api_version
|
32
40
|
@api_version ||= name.split("::")[1].downcase
|
33
41
|
end
|
@@ -90,7 +90,11 @@ module Insights
|
|
90
90
|
|
91
91
|
def filtered
|
92
92
|
check_if_openapi_enabled
|
93
|
-
|
93
|
+
association_attribute_properties =
|
94
|
+
Insights::API::Common::Filter.association_attribute_properties(api_doc_definitions, safe_params_for_list[:filter])
|
95
|
+
extra_attribute_properties = extra_attributes_for_filtering.merge(association_attribute_properties)
|
96
|
+
|
97
|
+
Insights::API::Common::Filter.new(model, safe_params_for_list[:filter], api_doc_definition, extra_attribute_properties).apply
|
94
98
|
end
|
95
99
|
|
96
100
|
def extra_attributes_for_filtering
|
@@ -4,6 +4,7 @@ module Insights
|
|
4
4
|
class Filter
|
5
5
|
INTEGER_COMPARISON_KEYWORDS = ["eq", "gt", "gte", "lt", "lte", "nil", "not_nil"].freeze
|
6
6
|
STRING_COMPARISON_KEYWORDS = ["contains", "contains_i", "eq", "eq_i", "starts_with", "starts_with_i", "ends_with", "ends_with_i", "nil", "not_nil"].freeze
|
7
|
+
ALL_COMPARISON_KEYWORDS = (INTEGER_COMPARISON_KEYWORDS + STRING_COMPARISON_KEYWORDS).uniq.freeze
|
7
8
|
|
8
9
|
attr_reader :apply, :arel_table, :api_doc_definition, :extra_filterable_attributes, :model
|
9
10
|
|
@@ -23,18 +24,23 @@ module Insights
|
|
23
24
|
# A new Filter object, call #apply to get the filtered set of results.
|
24
25
|
#
|
25
26
|
def initialize(model, raw_filter, api_doc_definition, extra_filterable_attributes = {})
|
26
|
-
|
27
|
+
@raw_filter = raw_filter
|
27
28
|
@api_doc_definition = api_doc_definition
|
28
29
|
@arel_table = model.arel_table
|
29
30
|
@extra_filterable_attributes = extra_filterable_attributes
|
30
31
|
@model = model
|
31
|
-
@raw_filter = raw_filter
|
32
32
|
end
|
33
33
|
|
34
|
+
def query
|
35
|
+
@query ||= filter_associations.present? ? model.left_outer_joins(filter_associations) : model
|
36
|
+
end
|
37
|
+
attr_writer :query
|
38
|
+
|
34
39
|
def apply
|
35
40
|
return query if @raw_filter.blank?
|
36
|
-
|
37
|
-
|
41
|
+
|
42
|
+
self.class.compact_filter(@raw_filter).each do |k, v|
|
43
|
+
next unless (attribute = attribute_for_key(k))
|
38
44
|
|
39
45
|
if attribute["type"] == "string"
|
40
46
|
type = determine_string_attribute_type(attribute)
|
@@ -48,13 +54,86 @@ module Insights
|
|
48
54
|
query
|
49
55
|
end
|
50
56
|
|
57
|
+
# Compact filters to support association filtering
|
58
|
+
#
|
59
|
+
# Input: {"source_type"=>{"name"=>{"eq"=>"rhev"}}}
|
60
|
+
# Output: {"source_type.name"=>{"eq"=>"rhev"}}
|
61
|
+
#
|
62
|
+
# Input: {"source_type"=>{"name"=>{"eq"=>["openstack", "openshift"]}}}
|
63
|
+
# Output: {"source_type.name"=>{"eq"=>["openstack", "openshift"]}}
|
64
|
+
#
|
65
|
+
def self.compact_filter(filter)
|
66
|
+
result = {}
|
67
|
+
return result if filter.blank?
|
68
|
+
return filter unless filter.kind_of?(Hash) || filter.kind_of?(ActionController::Parameters)
|
69
|
+
|
70
|
+
filter = Hash(filter.permit!) if filter.kind_of?(ActionController::Parameters)
|
71
|
+
|
72
|
+
filter.each do |ak, av|
|
73
|
+
if av.kind_of?(Hash)
|
74
|
+
av.each do |atk, atv|
|
75
|
+
if !ALL_COMPARISON_KEYWORDS.include?(atk)
|
76
|
+
result["#{ak}.#{atk}"] = atv
|
77
|
+
else
|
78
|
+
result[ak] = av
|
79
|
+
end
|
80
|
+
end
|
81
|
+
else
|
82
|
+
result[ak] = av
|
83
|
+
end
|
84
|
+
end
|
85
|
+
result
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.association_attribute_properties(api_doc_definitions, raw_filter)
|
89
|
+
return {} if raw_filter.blank?
|
90
|
+
|
91
|
+
association_attributes = compact_filter(raw_filter).keys.select { |key| key.include?('.') }.compact.uniq
|
92
|
+
return {} if association_attributes.blank?
|
93
|
+
|
94
|
+
association_attributes.each_with_object({}) do |key, hash|
|
95
|
+
association, attr = key.split('.')
|
96
|
+
hash[key] = api_doc_definitions[association.singularize.classify].properties[attr.to_s]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
51
100
|
private
|
52
101
|
|
53
|
-
attr_accessor :query
|
54
102
|
delegate(:arel_attribute, :to => :model)
|
55
103
|
|
56
104
|
class Error < ArgumentError; end
|
57
105
|
|
106
|
+
def key_model_attribute(key)
|
107
|
+
if key.include?('.')
|
108
|
+
association, attr = key.split('.')
|
109
|
+
[association.classify.constantize, attr]
|
110
|
+
else
|
111
|
+
[model, key]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def model_arel_attribute(key)
|
116
|
+
key_model, attr = key_model_attribute(key)
|
117
|
+
key_model.arel_attribute(attr)
|
118
|
+
end
|
119
|
+
|
120
|
+
def model_arel_table(key)
|
121
|
+
key_model, attr = key_model_attribute(key)
|
122
|
+
key_model.arel_table
|
123
|
+
end
|
124
|
+
|
125
|
+
def filter_associations
|
126
|
+
return nil if @raw_filter.blank?
|
127
|
+
|
128
|
+
@filter_associations ||= begin
|
129
|
+
self.class.compact_filter(@raw_filter).keys.collect do |key|
|
130
|
+
next unless key.include?('.')
|
131
|
+
|
132
|
+
key.split('.').first.to_sym
|
133
|
+
end.compact.uniq
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
58
137
|
def attribute_for_key(key)
|
59
138
|
attribute = api_doc_definition.properties[key.to_s]
|
60
139
|
attribute ||= extra_filterable_attributes[key.to_s]
|
@@ -74,7 +153,7 @@ module Insights
|
|
74
153
|
end
|
75
154
|
|
76
155
|
def string(k, val)
|
77
|
-
if val.kind_of?(
|
156
|
+
if val.kind_of?(Hash)
|
78
157
|
val.each do |comparator, value|
|
79
158
|
add_filter(comparator, STRING_COMPARISON_KEYWORDS, k, value)
|
80
159
|
end
|
@@ -99,7 +178,7 @@ module Insights
|
|
99
178
|
end
|
100
179
|
|
101
180
|
def timestamp(k, val)
|
102
|
-
if val.kind_of?(
|
181
|
+
if val.kind_of?(Hash)
|
103
182
|
val.each do |comparator, value|
|
104
183
|
add_filter(comparator, INTEGER_COMPARISON_KEYWORDS, k, value)
|
105
184
|
end
|
@@ -118,7 +197,7 @@ module Insights
|
|
118
197
|
end
|
119
198
|
|
120
199
|
def integer(k, val)
|
121
|
-
if val.kind_of?(
|
200
|
+
if val.kind_of?(Hash)
|
122
201
|
val.each do |comparator, value|
|
123
202
|
add_filter(comparator, INTEGER_COMPARISON_KEYWORDS, k, value)
|
124
203
|
end
|
@@ -128,69 +207,69 @@ module Insights
|
|
128
207
|
end
|
129
208
|
|
130
209
|
def arel_lower(key)
|
131
|
-
Arel::Nodes::NamedFunction.new("LOWER", [
|
210
|
+
Arel::Nodes::NamedFunction.new("LOWER", [model_arel_attribute(key)])
|
132
211
|
end
|
133
212
|
|
134
213
|
def comparator_contains(key, value)
|
135
214
|
return value.each { |v| comparator_contains(key, v) } if value.kind_of?(Array)
|
136
215
|
|
137
|
-
self.query = query.where(
|
216
|
+
self.query = query.where(model_arel_attribute(key).matches("%#{query.sanitize_sql_like(value)}%", nil, true))
|
138
217
|
end
|
139
218
|
|
140
219
|
def comparator_contains_i(key, value)
|
141
220
|
return value.each { |v| comparator_contains_i(key, v) } if value.kind_of?(Array)
|
142
221
|
|
143
|
-
self.query = query.where(
|
222
|
+
self.query = query.where(model_arel_table(key).grouping(arel_lower(key).matches("%#{query.sanitize_sql_like(value.downcase)}%", nil, true)))
|
144
223
|
end
|
145
224
|
|
146
225
|
def comparator_starts_with(key, value)
|
147
|
-
self.query = query.where(
|
226
|
+
self.query = query.where(model_arel_attribute(key).matches("#{query.sanitize_sql_like(value)}%", nil, true))
|
148
227
|
end
|
149
228
|
|
150
229
|
def comparator_starts_with_i(key, value)
|
151
|
-
self.query = query.where(
|
230
|
+
self.query = query.where(model_arel_table(key).grouping(arel_lower(key).matches("#{query.sanitize_sql_like(value.downcase)}%", nil, true)))
|
152
231
|
end
|
153
232
|
|
154
233
|
def comparator_ends_with(key, value)
|
155
|
-
self.query = query.where(
|
234
|
+
self.query = query.where(model_arel_attribute(key).matches("%#{query.sanitize_sql_like(value)}", nil, true))
|
156
235
|
end
|
157
236
|
|
158
237
|
def comparator_ends_with_i(key, value)
|
159
|
-
self.query = query.where(
|
238
|
+
self.query = query.where(model_arel_table(key).grouping(arel_lower(key).matches("%#{query.sanitize_sql_like(value.downcase)}", nil, true)))
|
160
239
|
end
|
161
240
|
|
162
241
|
def comparator_eq(key, value)
|
163
|
-
self.query = query.where(
|
242
|
+
self.query = query.where(model_arel_attribute(key).eq_any(Array(value)))
|
164
243
|
end
|
165
244
|
|
166
245
|
def comparator_eq_i(key, value)
|
167
246
|
values = Array(value).map { |v| query.sanitize_sql_like(v.downcase) }
|
168
247
|
|
169
|
-
self.query = query.where(
|
248
|
+
self.query = query.where(model_arel_table(key).grouping(arel_lower(key).matches_any(values)))
|
170
249
|
end
|
171
250
|
|
172
251
|
def comparator_gt(key, value)
|
173
|
-
self.query = query.where(
|
252
|
+
self.query = query.where(model_arel_attribute(key).gt(value))
|
174
253
|
end
|
175
254
|
|
176
255
|
def comparator_gte(key, value)
|
177
|
-
self.query = query.where(
|
256
|
+
self.query = query.where(model_arel_attribute(key).gteq(value))
|
178
257
|
end
|
179
258
|
|
180
259
|
def comparator_lt(key, value)
|
181
|
-
self.query = query.where(
|
260
|
+
self.query = query.where(model_arel_attribute(key).lt(value))
|
182
261
|
end
|
183
262
|
|
184
263
|
def comparator_lte(key, value)
|
185
|
-
self.query = query.where(
|
264
|
+
self.query = query.where(model_arel_attribute(key).lteq(value))
|
186
265
|
end
|
187
266
|
|
188
267
|
def comparator_nil(key, _value = nil)
|
189
|
-
self.query = query.where(
|
268
|
+
self.query = query.where(model_arel_attribute(key).eq(nil))
|
190
269
|
end
|
191
270
|
|
192
271
|
def comparator_not_nil(key, _value = nil)
|
193
|
-
self.query = query.where.not(
|
272
|
+
self.query = query.where.not(model_arel_attribute(key).eq(nil))
|
194
273
|
end
|
195
274
|
end
|
196
275
|
end
|
@@ -34,10 +34,13 @@ QueryType = ::GraphQL::ObjectType.define do
|
|
34
34
|
if args[:filter]
|
35
35
|
openapi_doc = ::Insights::API::Common::OpenApi::Docs.instance["<%= api_version %>"]
|
36
36
|
openapi_schema_name, _schema = ::Insights::API::Common::GraphQL::Generator.openapi_schema(openapi_doc, klass_name)
|
37
|
+
association_attribute_properties =
|
38
|
+
Insights::API::Common::Filter.association_attribute_properties(openapi_doc.definitions, ActionController::Parameters.new(args[:filter]))
|
37
39
|
scope = ::Insights::API::Common::Filter.new(
|
38
40
|
scope,
|
39
41
|
ActionController::Parameters.new(args[:filter]),
|
40
|
-
openapi_doc.definitions[openapi_schema_name]
|
42
|
+
openapi_doc.definitions[openapi_schema_name],
|
43
|
+
association_attribute_properties).apply
|
41
44
|
end
|
42
45
|
scope = ::Insights::API::Common::GraphQL.search_options(scope, args)
|
43
46
|
if <%= graphql_options[:use_pagination_v2] %> == true
|
@@ -12,7 +12,7 @@ module Insights
|
|
12
12
|
|
13
13
|
Service.call(RBACApiClient::GroupApi) do |api|
|
14
14
|
uuids = SortedSet.new
|
15
|
-
Service.paginate(api, :list_groups, {}).each { |group| uuids << group.uuid }
|
15
|
+
Service.paginate(api, :list_groups, {:uuid => @group_uuids.to_a}).each { |group| uuids << group.uuid }
|
16
16
|
missing = @group_uuids - uuids
|
17
17
|
raise Insights::API::Common::InvalidParameter, "The following group uuids are missing #{missing.to_a.join(",")}" unless missing.empty?
|
18
18
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: insights-api-common
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Insights Authors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: acts_as_tenant
|
@@ -134,14 +134,14 @@ dependencies:
|
|
134
134
|
requirements:
|
135
135
|
- - "~>"
|
136
136
|
- !ruby/object:Gem::Version
|
137
|
-
version: 0.
|
137
|
+
version: 0.10.0
|
138
138
|
type: :runtime
|
139
139
|
prerelease: false
|
140
140
|
version_requirements: !ruby/object:Gem::Requirement
|
141
141
|
requirements:
|
142
142
|
- - "~>"
|
143
143
|
- !ruby/object:Gem::Version
|
144
|
-
version: 0.
|
144
|
+
version: 0.10.0
|
145
145
|
- !ruby/object:Gem::Dependency
|
146
146
|
name: graphql
|
147
147
|
requirement: !ruby/object:Gem::Requirement
|