foreman_rh_cloud 13.2.7 → 13.2.8
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.
- checksums.yaml +4 -4
- data/app/models/concerns/rh_cloud_host.rb +31 -1
- data/lib/foreman_inventory_upload/async/create_missing_insights_facets.rb +8 -2
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/insights_cloud/async/vmaas_reposcan_sync.rb +23 -8
- data/test/unit/lib/insights_cloud/async/vmaas_reposcan_sync_test.rb +80 -25
- data/test/unit/rh_cloud_host_test.rb +154 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 04c6a1daea1675deb081565cf7d9e83e669a3fd01a577a032c9d7d5ba825cbce
|
|
4
|
+
data.tar.gz: 5172a5c764d0dbcb71cf47e19e423f0eae01db27636be594320dece4c6364719
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 15b24817679825c5e60bc0e0ca0b33c18eadae7277483155c641f3d3d140bd911c0c7ad7dca15c40e3d63f9a8e354acfcd5789048658fd2888a33fa4b9741d0d
|
|
7
|
+
data.tar.gz: 0cfe77f01b645de55c8e3e41ac4411201c5ec4819e5926d3054bac08b551e12dc923dffa6b1503956cb1075c688a5a3d94e5a63a8c4e332414e10f78054d3954
|
|
@@ -21,7 +21,8 @@ module RhCloudHost
|
|
|
21
21
|
scoped_search :relation => :inventory_sync_status_object, :on => :status, :rename => :insights_inventory_sync_status,
|
|
22
22
|
:complete_value => { :disconnect => ::InventorySync::InventoryStatus::DISCONNECT,
|
|
23
23
|
:sync => ::InventorySync::InventoryStatus::SYNC }
|
|
24
|
-
scoped_search :
|
|
24
|
+
scoped_search :on => :id, :rename => :insights_uuid, :only_explicit => true,
|
|
25
|
+
:ext_method => :search_by_insights_uuid, :complete_value => false
|
|
25
26
|
|
|
26
27
|
def insights_facet
|
|
27
28
|
insights
|
|
@@ -41,4 +42,33 @@ module RhCloudHost
|
|
|
41
42
|
insights_facet.update!(uuid: subscription_facet.uuid)
|
|
42
43
|
end
|
|
43
44
|
end
|
|
45
|
+
|
|
46
|
+
module ClassMethods
|
|
47
|
+
def search_by_insights_uuid(_key, operator, value)
|
|
48
|
+
# Determine which facet table to search based on IoP mode
|
|
49
|
+
facet_table = ForemanRhCloud.with_iop_smart_proxy? ? Katello::Host::SubscriptionFacet.table_name : InsightsFacet.table_name
|
|
50
|
+
|
|
51
|
+
# Build SQL condition
|
|
52
|
+
if ['IN', 'NOT IN'].include?(operator)
|
|
53
|
+
# For IN/NOT IN, value may be an array or comma-separated string
|
|
54
|
+
# Convert to array and build placeholders for each value
|
|
55
|
+
values = value.is_a?(Array) ? value : value.to_s.split(',').map(&:strip)
|
|
56
|
+
placeholders = (['?'] * values.size).join(',')
|
|
57
|
+
condition = sanitize_sql_for_conditions(
|
|
58
|
+
["#{facet_table}.uuid #{operator} (#{placeholders})", *values]
|
|
59
|
+
)
|
|
60
|
+
else
|
|
61
|
+
# For other operators (=, !=, LIKE, etc.), use value_to_sql for proper SQL formatting
|
|
62
|
+
condition = sanitize_sql_for_conditions(
|
|
63
|
+
["#{facet_table}.uuid #{operator} ?", value_to_sql(operator, value)]
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Return search parameters with LEFT JOIN to include hosts without facets
|
|
68
|
+
{
|
|
69
|
+
joins: "LEFT JOIN #{facet_table} ON #{facet_table}.host_id = #{Host::Managed.table_name}.id",
|
|
70
|
+
conditions: condition,
|
|
71
|
+
}
|
|
72
|
+
end
|
|
73
|
+
end
|
|
44
74
|
end
|
|
@@ -7,9 +7,15 @@ module ForemanInventoryUpload
|
|
|
7
7
|
|
|
8
8
|
def run
|
|
9
9
|
organization = ::Organization.find(input[:organization_id])
|
|
10
|
-
|
|
10
|
+
# Find hosts with subscription facets but without insights facets
|
|
11
|
+
# Note: We can't use scoped_search 'null? insights_uuid' because the null? operator
|
|
12
|
+
# doesn't work with ext_methods - it would check hosts.id IS NULL instead of the facet
|
|
13
|
+
hosts_without_facets = ::ForemanInventoryUpload::Generators::Queries.for_org(organization, use_batches: false)
|
|
14
|
+
.left_outer_joins(:insights)
|
|
15
|
+
.where(insights_facets: { id: nil })
|
|
16
|
+
|
|
11
17
|
facet_count = 0
|
|
12
|
-
hosts_without_facets.
|
|
18
|
+
hosts_without_facets.in_batches(of: ForemanInventoryUpload.slice_size) do |batch|
|
|
13
19
|
facets = batch.pluck(:id, 'katello_subscription_facets.uuid').map do |host_id, uuid|
|
|
14
20
|
{
|
|
15
21
|
host_id: host_id,
|
|
@@ -6,6 +6,8 @@ module InsightsCloud
|
|
|
6
6
|
class VmaasReposcanSync < ::Actions::EntryAction
|
|
7
7
|
include ::ForemanRhCloud::CertAuth
|
|
8
8
|
|
|
9
|
+
HTTP_TOO_MANY_REQUESTS = 429
|
|
10
|
+
|
|
9
11
|
# Subscribe to Katello repository sync hook action, if available
|
|
10
12
|
def self.subscribe
|
|
11
13
|
'Actions::Katello::Repository::SyncHook'.constantize
|
|
@@ -49,15 +51,9 @@ module InsightsCloud
|
|
|
49
51
|
|
|
50
52
|
response
|
|
51
53
|
rescue RestClient::ExceptionWithResponse => e
|
|
52
|
-
|
|
53
|
-
logger.error(message)
|
|
54
|
-
output[:message] = message
|
|
55
|
-
raise
|
|
54
|
+
handle_rest_client_error(e)
|
|
56
55
|
rescue StandardError => e
|
|
57
|
-
|
|
58
|
-
logger.error(message)
|
|
59
|
-
output[:message] = message
|
|
60
|
-
raise
|
|
56
|
+
handle_standard_error(e)
|
|
61
57
|
end
|
|
62
58
|
|
|
63
59
|
def rescue_strategy_for_self
|
|
@@ -70,6 +66,25 @@ module InsightsCloud
|
|
|
70
66
|
|
|
71
67
|
private
|
|
72
68
|
|
|
69
|
+
def handle_rest_client_error(exception)
|
|
70
|
+
if exception.response&.code == HTTP_TOO_MANY_REQUESTS
|
|
71
|
+
message = "VMaaS reposcan sync skipped: another sync already in progress (#{HTTP_TOO_MANY_REQUESTS})"
|
|
72
|
+
logger.warn(message)
|
|
73
|
+
else
|
|
74
|
+
message = "VMaaS reposcan sync failed: #{exception.response&.code} - #{exception.response&.body}"
|
|
75
|
+
logger.error(message)
|
|
76
|
+
end
|
|
77
|
+
output[:message] = message
|
|
78
|
+
# Do NOT raise - let rescue_strategy_for_self Skip handle this
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def handle_standard_error(exception)
|
|
82
|
+
message = "Error triggering VMaaS reposcan sync: #{exception.message}"
|
|
83
|
+
logger.error(message)
|
|
84
|
+
output[:message] = message
|
|
85
|
+
# Do NOT raise - let rescue_strategy_for_self Skip handle this
|
|
86
|
+
end
|
|
87
|
+
|
|
73
88
|
def logger
|
|
74
89
|
action_logger
|
|
75
90
|
end
|
|
@@ -5,19 +5,17 @@ class VmaasReposcanSyncTest < ActiveSupport::TestCase
|
|
|
5
5
|
include ForemanTasks::TestHelpers::WithInThreadExecutor
|
|
6
6
|
|
|
7
7
|
setup do
|
|
8
|
-
@
|
|
9
|
-
|
|
10
|
-
@repo =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
distribution_version: '7.5',
|
|
15
|
-
root: @root
|
|
16
|
-
)
|
|
8
|
+
@organization = FactoryBot.create(:organization)
|
|
9
|
+
# Create a simple repository - we only need id and organization_id for the action
|
|
10
|
+
@repo = ::Katello::Repository.new(id: 1)
|
|
11
|
+
@repo.stubs(:organization_id).returns(@organization.id)
|
|
12
|
+
::Katello::Repository.stubs(:find).with(1).returns(@repo)
|
|
13
|
+
|
|
17
14
|
@repo_payload = { id: @repo.id }
|
|
18
15
|
@expected_url = 'https://example.com/api/v1/vmaas/reposcan/sync'
|
|
19
16
|
InsightsCloud.stubs(:vmaas_reposcan_sync_url).returns(@expected_url)
|
|
20
17
|
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
18
|
+
Organization.stubs(:find).with(@organization.id).returns(@organization)
|
|
21
19
|
end
|
|
22
20
|
|
|
23
21
|
teardown do
|
|
@@ -83,7 +81,7 @@ class VmaasReposcanSyncTest < ActiveSupport::TestCase
|
|
|
83
81
|
params[:url] == @expected_url &&
|
|
84
82
|
params[:headers].is_a?(Hash) &&
|
|
85
83
|
params[:headers]['Content-Type'] == 'application/json' &&
|
|
86
|
-
params[:organization] == @
|
|
84
|
+
params[:organization] == @organization
|
|
87
85
|
end
|
|
88
86
|
.returns(mock_response)
|
|
89
87
|
|
|
@@ -116,37 +114,94 @@ class VmaasReposcanSyncTest < ActiveSupport::TestCase
|
|
|
116
114
|
.stubs(:execute_cloud_request)
|
|
117
115
|
.raises(exception)
|
|
118
116
|
|
|
119
|
-
|
|
120
|
-
ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
|
|
121
|
-
end
|
|
117
|
+
task = ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
|
|
122
118
|
|
|
123
|
-
assert_equal 'VMaaS reposcan sync failed: 500 - Server Error',
|
|
119
|
+
assert_equal 'VMaaS reposcan sync failed: 500 - Server Error', task.output[:message]
|
|
124
120
|
end
|
|
125
121
|
|
|
126
122
|
test 'run sets error message in task output for StandardError exception' do
|
|
123
|
+
mock_logger = mock('logger')
|
|
124
|
+
mock_logger.expects(:error).with('Error triggering VMaaS reposcan sync: Network timeout')
|
|
125
|
+
InsightsCloud::Async::VmaasReposcanSync.any_instance.stubs(:logger).returns(mock_logger)
|
|
126
|
+
|
|
127
127
|
InsightsCloud::Async::VmaasReposcanSync.any_instance
|
|
128
128
|
.stubs(:execute_cloud_request)
|
|
129
129
|
.raises(StandardError.new('Network timeout'))
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
|
|
133
|
-
end
|
|
131
|
+
task = ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
|
|
134
132
|
|
|
135
|
-
|
|
136
|
-
assert_match(/Error triggering VMaaS reposcan sync: Network timeout, response: /,
|
|
137
|
-
error.task.main_action.output[:message])
|
|
133
|
+
assert_equal 'Error triggering VMaaS reposcan sync: Network timeout', task.output[:message]
|
|
138
134
|
end
|
|
139
135
|
|
|
140
|
-
test 'run logs and
|
|
141
|
-
error_response = mock('error_response'
|
|
136
|
+
test 'run logs and handles error response without raising' do
|
|
137
|
+
error_response = mock('error_response')
|
|
138
|
+
error_response.stubs(:code).returns(500)
|
|
139
|
+
error_response.stubs(:body).returns('error')
|
|
142
140
|
exception = RestClient::ExceptionWithResponse.new(error_response)
|
|
143
141
|
|
|
144
142
|
InsightsCloud::Async::VmaasReposcanSync.any_instance
|
|
145
143
|
.stubs(:execute_cloud_request)
|
|
146
144
|
.raises(exception)
|
|
147
145
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
146
|
+
task = ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
|
|
147
|
+
|
|
148
|
+
assert_equal 'VMaaS reposcan sync failed: 500 - error', task.output[:message]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
test 'run handles 429 error with warning log level' do
|
|
152
|
+
error_response = mock('error_response')
|
|
153
|
+
error_response.stubs(:code).returns(429)
|
|
154
|
+
error_response.stubs(:body).returns('{"msg": "Another task already in progress"}')
|
|
155
|
+
exception = RestClient::ExceptionWithResponse.new(error_response)
|
|
156
|
+
|
|
157
|
+
mock_logger = mock('logger')
|
|
158
|
+
mock_logger.expects(:warn).with('VMaaS reposcan sync skipped: another sync already in progress (429)')
|
|
159
|
+
InsightsCloud::Async::VmaasReposcanSync.any_instance.stubs(:logger).returns(mock_logger)
|
|
160
|
+
|
|
161
|
+
InsightsCloud::Async::VmaasReposcanSync.any_instance
|
|
162
|
+
.stubs(:execute_cloud_request)
|
|
163
|
+
.raises(exception)
|
|
164
|
+
|
|
165
|
+
task = ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
|
|
166
|
+
|
|
167
|
+
assert_equal 'VMaaS reposcan sync skipped: another sync already in progress (429)',
|
|
168
|
+
task.output[:message]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
test 'run handles non-429 errors with error log level' do
|
|
172
|
+
error_response = mock('error_response')
|
|
173
|
+
error_response.stubs(:code).returns(500)
|
|
174
|
+
error_response.stubs(:body).returns('Internal Server Error')
|
|
175
|
+
exception = RestClient::ExceptionWithResponse.new(error_response)
|
|
176
|
+
|
|
177
|
+
mock_logger = mock('logger')
|
|
178
|
+
mock_logger.expects(:error).with('VMaaS reposcan sync failed: 500 - Internal Server Error')
|
|
179
|
+
InsightsCloud::Async::VmaasReposcanSync.any_instance.stubs(:logger).returns(mock_logger)
|
|
180
|
+
|
|
181
|
+
InsightsCloud::Async::VmaasReposcanSync.any_instance
|
|
182
|
+
.stubs(:execute_cloud_request)
|
|
183
|
+
.raises(exception)
|
|
184
|
+
|
|
185
|
+
task = ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
|
|
186
|
+
|
|
187
|
+
assert_equal 'VMaaS reposcan sync failed: 500 - Internal Server Error',
|
|
188
|
+
task.output[:message]
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
test 'run handles RestClient::ExceptionWithResponse with nil response' do
|
|
192
|
+
exception = RestClient::ExceptionWithResponse.new(nil)
|
|
193
|
+
|
|
194
|
+
mock_logger = mock('logger')
|
|
195
|
+
mock_logger.expects(:error).with('VMaaS reposcan sync failed: - ')
|
|
196
|
+
InsightsCloud::Async::VmaasReposcanSync.any_instance.stubs(:logger).returns(mock_logger)
|
|
197
|
+
|
|
198
|
+
InsightsCloud::Async::VmaasReposcanSync.any_instance
|
|
199
|
+
.stubs(:execute_cloud_request)
|
|
200
|
+
.raises(exception)
|
|
201
|
+
|
|
202
|
+
task = ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
|
|
203
|
+
|
|
204
|
+
refute_nil task.output[:message]
|
|
205
|
+
assert_equal 'VMaaS reposcan sync failed: - ', task.output[:message]
|
|
151
206
|
end
|
|
152
207
|
end
|
|
@@ -188,4 +188,158 @@ class RhCloudHostTest < ActiveSupport::TestCase
|
|
|
188
188
|
assert_equal local_uuid, @host.insights_uuid
|
|
189
189
|
end
|
|
190
190
|
end
|
|
191
|
+
|
|
192
|
+
context 'scoped search on insights_uuid' do
|
|
193
|
+
setup do
|
|
194
|
+
@org = FactoryBot.create(:organization)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
teardown do
|
|
198
|
+
ForemanRhCloud.unstub(:with_iop_smart_proxy?)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
test 'searches insights_facet.uuid in non-IoP mode with = operator' do
|
|
202
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
203
|
+
host1 = FactoryBot.create(:host, :managed, organization: @org)
|
|
204
|
+
host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'insights-uuid-123')
|
|
205
|
+
host2 = FactoryBot.create(:host, :managed, organization: @org)
|
|
206
|
+
host2.insights = FactoryBot.create(:insights_facet, host_id: host2.id, uuid: 'insights-uuid-456')
|
|
207
|
+
|
|
208
|
+
results = Host::Managed.search_for('insights_uuid = insights-uuid-123')
|
|
209
|
+
|
|
210
|
+
assert_includes results, host1
|
|
211
|
+
assert_not_includes results, host2
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
test 'searches subscription_facet.uuid in IoP mode with = operator' do
|
|
215
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
216
|
+
host1 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
217
|
+
host2 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
218
|
+
|
|
219
|
+
# Even if insights_facet has different UUID, should use subscription_facet UUID
|
|
220
|
+
host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'stale-123')
|
|
221
|
+
|
|
222
|
+
results = Host::Managed.search_for("insights_uuid = #{host1.subscription_facet.uuid}")
|
|
223
|
+
|
|
224
|
+
assert_includes results, host1
|
|
225
|
+
assert_not_includes results, host2
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
test 'searches with ^ operator (IN) in non-IoP mode' do
|
|
229
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
230
|
+
host1 = FactoryBot.create(:host, :managed, organization: @org)
|
|
231
|
+
host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'uuid-1')
|
|
232
|
+
host2 = FactoryBot.create(:host, :managed, organization: @org)
|
|
233
|
+
host2.insights = FactoryBot.create(:insights_facet, host_id: host2.id, uuid: 'uuid-2')
|
|
234
|
+
host3 = FactoryBot.create(:host, :managed, organization: @org)
|
|
235
|
+
host3.insights = FactoryBot.create(:insights_facet, host_id: host3.id, uuid: 'uuid-3')
|
|
236
|
+
|
|
237
|
+
results = Host::Managed.search_for('insights_uuid ^ (uuid-1,uuid-2)')
|
|
238
|
+
|
|
239
|
+
assert_includes results, host1
|
|
240
|
+
assert_includes results, host2
|
|
241
|
+
assert_not_includes results, host3
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
test 'searches with ^ operator (IN) in IoP mode - THE BUG FIX' do
|
|
245
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
246
|
+
host1 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
247
|
+
host2 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
248
|
+
host3 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
249
|
+
|
|
250
|
+
# Create insights facets with stale UUIDs to verify we're using subscription_facet
|
|
251
|
+
host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'stale-1')
|
|
252
|
+
host2.insights = FactoryBot.create(:insights_facet, host_id: host2.id, uuid: 'stale-2')
|
|
253
|
+
host3.insights = FactoryBot.create(:insights_facet, host_id: host3.id, uuid: 'stale-3')
|
|
254
|
+
|
|
255
|
+
uuid1 = host1.subscription_facet.uuid
|
|
256
|
+
uuid2 = host2.subscription_facet.uuid
|
|
257
|
+
|
|
258
|
+
# This is the search query that remediation modal creates
|
|
259
|
+
results = Host::Managed.search_for("insights_uuid ^ (#{uuid1},#{uuid2})")
|
|
260
|
+
|
|
261
|
+
# Should find hosts by subscription_facet UUID, not insights_facet UUID
|
|
262
|
+
assert_includes results, host1
|
|
263
|
+
assert_includes results, host2
|
|
264
|
+
assert_not_includes results, host3
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
test 'searches with !^ operator (NOT IN) in non-IoP mode' do
|
|
268
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
269
|
+
host1 = FactoryBot.create(:host, :managed, organization: @org)
|
|
270
|
+
host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'uuid-1')
|
|
271
|
+
host2 = FactoryBot.create(:host, :managed, organization: @org)
|
|
272
|
+
host2.insights = FactoryBot.create(:insights_facet, host_id: host2.id, uuid: 'uuid-2')
|
|
273
|
+
host3 = FactoryBot.create(:host, :managed, organization: @org)
|
|
274
|
+
host3.insights = FactoryBot.create(:insights_facet, host_id: host3.id, uuid: 'uuid-3')
|
|
275
|
+
|
|
276
|
+
results = Host::Managed.search_for('insights_uuid !^ (uuid-1,uuid-2)')
|
|
277
|
+
|
|
278
|
+
assert_not_includes results, host1
|
|
279
|
+
assert_not_includes results, host2
|
|
280
|
+
assert_includes results, host3
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
test 'searches with !^ operator (NOT IN) in IoP mode' do
|
|
284
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
285
|
+
host1 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
286
|
+
host2 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
287
|
+
host3 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
288
|
+
|
|
289
|
+
uuid1 = host1.subscription_facet.uuid
|
|
290
|
+
uuid2 = host2.subscription_facet.uuid
|
|
291
|
+
|
|
292
|
+
results = Host::Managed.search_for("insights_uuid !^ (#{uuid1},#{uuid2})")
|
|
293
|
+
|
|
294
|
+
assert_not_includes results, host1
|
|
295
|
+
assert_not_includes results, host2
|
|
296
|
+
assert_includes results, host3
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
test 'handles hosts without facets in non-IoP mode' do
|
|
300
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
301
|
+
host_without_facet = FactoryBot.create(:host, :managed, organization: @org)
|
|
302
|
+
host_with_facet = FactoryBot.create(:host, :managed, organization: @org)
|
|
303
|
+
host_with_facet.insights = FactoryBot.create(:insights_facet, host_id: host_with_facet.id, uuid: 'uuid-1')
|
|
304
|
+
|
|
305
|
+
results = Host::Managed.search_for('insights_uuid = uuid-1')
|
|
306
|
+
|
|
307
|
+
assert_includes results, host_with_facet
|
|
308
|
+
assert_not_includes results, host_without_facet
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
test 'handles hosts without subscription_facet in IoP mode' do
|
|
312
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
313
|
+
host_without_sub = FactoryBot.create(:host, :managed, organization: @org)
|
|
314
|
+
host_with_sub = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
315
|
+
|
|
316
|
+
uuid = host_with_sub.subscription_facet.uuid
|
|
317
|
+
|
|
318
|
+
results = Host::Managed.search_for("insights_uuid = #{uuid}")
|
|
319
|
+
|
|
320
|
+
assert_includes results, host_with_sub
|
|
321
|
+
assert_not_includes results, host_without_sub
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
test 'mode changes are reflected in searches' do
|
|
325
|
+
host1 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
326
|
+
host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'insights-uuid-abc')
|
|
327
|
+
insights_uuid = 'insights-uuid-abc'
|
|
328
|
+
subscription_uuid = host1.subscription_facet.uuid
|
|
329
|
+
|
|
330
|
+
# Non-IoP mode: should find by insights_facet UUID
|
|
331
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
332
|
+
results = Host::Managed.search_for("insights_uuid = #{insights_uuid}")
|
|
333
|
+
assert_includes results, host1
|
|
334
|
+
|
|
335
|
+
# IoP mode: should find by subscription_facet UUID
|
|
336
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
337
|
+
results = Host::Managed.search_for("insights_uuid = #{subscription_uuid}")
|
|
338
|
+
assert_includes results, host1
|
|
339
|
+
|
|
340
|
+
# Should NOT find by old insights_facet UUID in IoP mode
|
|
341
|
+
results = Host::Managed.search_for("insights_uuid = #{insights_uuid}")
|
|
342
|
+
assert_not_includes results, host1
|
|
343
|
+
end
|
|
344
|
+
end
|
|
191
345
|
end
|