foreman_rh_cloud 13.0.11 → 13.0.12
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/controllers/concerns/foreman_rh_cloud/registration_manager_extensions.rb +2 -2
- data/app/controllers/concerns/insights_cloud/package_profile_upload_extensions.rb +3 -0
- data/app/models/concerns/rh_cloud_host.rb +14 -0
- data/app/models/foreman_rh_cloud/ping.rb +2 -1
- data/app/views/api/v2/advisor_engine/host_details.json.rabl +1 -3
- data/app/views/api/v2/hosts/insights/base.rabl +3 -2
- data/lib/foreman_rh_cloud/plugin.rb +8 -5
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/foreman_rh_cloud.rb +3 -3
- data/lib/insights_cloud/async/connector_playbook_execution_reporter_task.rb +3 -3
- data/package.json +1 -1
- data/test/controllers/insights_cloud/api/advisor_engine_controller_test.rb +28 -1
- data/test/factories/insights_factories.rb +29 -0
- data/test/unit/foreman_rh_cloud_iop_metadata_test.rb +200 -0
- data/test/unit/lib/foreman_rh_cloud/registration_manager_extensions_test.rb +4 -42
- data/test/unit/rh_cloud_host_test.rb +191 -0
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 972f28c475749451f2833bc918cfe95601eec5db19e024aec0d550a6f8844ad8
|
|
4
|
+
data.tar.gz: cf12bf0072e5596db8b10fd7901e8c600482bfd0799426da0d7193a7ddd8d1bb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fe0c825977e36641a874663dc97ba5efcb80ba3dd130123e445739e8ae72c5aff3b2e40859f9e73f3b82ae2be863307d190adf80cc544c4eef52171959bdbd73
|
|
7
|
+
data.tar.gz: d1f9c3d4ef5dd131b9e28a3725ebd6f6bb3bab01e5e30e1970954085264bdaa632449bc4e4ff32ccfbeb5aaa126a4f854d57d2b11fbddc272a89526185fd3811
|
|
@@ -13,13 +13,13 @@ module ForemanRhCloud
|
|
|
13
13
|
host.reload
|
|
14
14
|
|
|
15
15
|
# Only delete from HBI in IoP mode (hosted mode uses async job for cleanup)
|
|
16
|
-
hbi_host_destroy(host) if ForemanRhCloud.with_iop_smart_proxy? && !organization_destroy && host.
|
|
16
|
+
hbi_host_destroy(host) if ForemanRhCloud.with_iop_smart_proxy? && !organization_destroy && host.insights_uuid.presence
|
|
17
17
|
host.insights&.destroy!
|
|
18
18
|
super(host, options)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def hbi_host_destroy(host)
|
|
22
|
-
uuid = host.
|
|
22
|
+
uuid = host.insights_uuid
|
|
23
23
|
logger.debug "Unregistering host #{uuid} from HBI"
|
|
24
24
|
execute_cloud_request(
|
|
25
25
|
organization: host.organization,
|
|
@@ -21,6 +21,9 @@ module InsightsCloud
|
|
|
21
21
|
@host.id
|
|
22
22
|
)
|
|
23
23
|
|
|
24
|
+
# Ensure insights UUID matches subscription UUID (only runs in IoP mode per method guard above)
|
|
25
|
+
@host.ensure_iop_insights_uuid
|
|
26
|
+
|
|
24
27
|
# in IoP case, the hosts are identified by the sub-man ID, and we can assume they already
|
|
25
28
|
# exist in the local inventory. This will also handle facet creation for new hosts.
|
|
26
29
|
return if @host.insights
|
|
@@ -26,5 +26,19 @@ module RhCloudHost
|
|
|
26
26
|
def insights_facet
|
|
27
27
|
insights
|
|
28
28
|
end
|
|
29
|
+
|
|
30
|
+
# In IoP, read directly from the subscription facet to avoid stale data (see comment on ensure_iop_insights_uuid)
|
|
31
|
+
def insights_uuid
|
|
32
|
+
ForemanRhCloud.with_iop_smart_proxy? ? subscription_facet&.uuid : insights_facet&.uuid
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# In non-IoP, insights_facet uuids are assigned by Hosted.
|
|
36
|
+
# In IoP, insights_facet uuids must match Katello subscription_facet uuids.
|
|
37
|
+
# If the host was previously registered to hosted Insights,
|
|
38
|
+
# we need to correct its uuid.
|
|
39
|
+
def ensure_iop_insights_uuid
|
|
40
|
+
return unless insights_facet.present? && subscription_facet.present? && insights_facet.uuid != subscription_facet.uuid
|
|
41
|
+
insights_facet.update!(uuid: subscription_facet.uuid)
|
|
42
|
+
end
|
|
29
43
|
end
|
|
30
44
|
end
|
|
@@ -7,7 +7,7 @@ module ForemanRhCloud
|
|
|
7
7
|
include ForemanRhCloud::CertAuth
|
|
8
8
|
|
|
9
9
|
def iop_smart_proxy_url
|
|
10
|
-
|
|
10
|
+
ForemanRhCloud.iop_smart_proxy&.url
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def service_urls
|
|
@@ -33,6 +33,7 @@ module ForemanRhCloud
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def ping
|
|
36
|
+
return {} unless ForemanRhCloud.with_iop_smart_proxy?
|
|
36
37
|
ping_services
|
|
37
38
|
end
|
|
38
39
|
|
|
@@ -118,14 +118,17 @@ module ForemanRhCloud
|
|
|
118
118
|
end
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
+
# Preload insights facet to avoid N+1 queries when rendering host list with facets
|
|
122
|
+
add_controller_action_scope('Api::V2::HostsController', :index) do |base_scope|
|
|
123
|
+
base_scope.preload(:insights)
|
|
124
|
+
end
|
|
125
|
+
|
|
121
126
|
register_global_js_file 'global'
|
|
122
127
|
|
|
123
128
|
register_custom_status InventorySync::InventoryStatus
|
|
124
129
|
register_custom_status InsightsClientReportStatus
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
register_status_extension { ForemanRhCloud::Ping.status }
|
|
128
|
-
end
|
|
130
|
+
register_ping_extension { ForemanRhCloud::Ping.ping }
|
|
131
|
+
register_status_extension { ForemanRhCloud::Ping.status }
|
|
129
132
|
|
|
130
133
|
describe_host do
|
|
131
134
|
overview_buttons_provider :insights_host_overview_buttons
|
|
@@ -148,7 +151,7 @@ module ForemanRhCloud
|
|
|
148
151
|
end
|
|
149
152
|
|
|
150
153
|
::Foreman::Plugin.app_metadata_registry.register(:foreman_rh_cloud, {
|
|
151
|
-
iop: ForemanRhCloud.with_iop_smart_proxy
|
|
154
|
+
iop: -> { ForemanRhCloud.with_iop_smart_proxy? },
|
|
152
155
|
})
|
|
153
156
|
|
|
154
157
|
extend_template_helpers ForemanRhCloud::TemplateRendererHelper
|
data/lib/foreman_rh_cloud.rb
CHANGED
|
@@ -14,15 +14,15 @@ module ForemanRhCloud
|
|
|
14
14
|
|
|
15
15
|
def self.base_url
|
|
16
16
|
# for testing set ENV to 'https://ci.cloud.redhat.com'
|
|
17
|
-
|
|
17
|
+
env_or_on_premise_url('SATELLITE_RH_CLOUD_URL') || 'https://cloud.redhat.com'
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def self.cert_base_url
|
|
21
|
-
|
|
21
|
+
env_or_on_premise_url('SATELLITE_CERT_RH_CLOUD_URL') || 'https://cert.cloud.redhat.com'
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def self.legacy_insights_url
|
|
25
|
-
|
|
25
|
+
env_or_on_premise_url('SATELLITE_LEGACY_INSIGHTS_URL') || 'https://cert-api.access.redhat.com'
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def self.verify_ssl_method
|
|
@@ -126,10 +126,10 @@ module InsightsCloud
|
|
|
126
126
|
|
|
127
127
|
def invocation_status
|
|
128
128
|
hosts_state = Hash[job_invocation.targeting.hosts.map do |host|
|
|
129
|
-
next unless host.
|
|
129
|
+
next unless host.insights_uuid
|
|
130
130
|
[
|
|
131
|
-
host.
|
|
132
|
-
task_status(job_invocation.sub_task_for_host(host), host.
|
|
131
|
+
host.insights_uuid,
|
|
132
|
+
task_status(job_invocation.sub_task_for_host(host), host.insights_uuid),
|
|
133
133
|
]
|
|
134
134
|
end.compact]
|
|
135
135
|
|
data/package.json
CHANGED
|
@@ -13,7 +13,7 @@ module InsightsCloud
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
test 'shows hosts with uuids' do
|
|
16
|
-
uuids = [@host1.
|
|
16
|
+
uuids = [@host1.insights_uuid, @host2.insights_uuid]
|
|
17
17
|
get :host_details, params: { organization_id: @test_org.id, host_uuids: uuids }
|
|
18
18
|
assert_response :success
|
|
19
19
|
assert_template 'api/v2/advisor_engine/host_details'
|
|
@@ -21,6 +21,33 @@ module InsightsCloud
|
|
|
21
21
|
refute_equal @test_org.hosts.count, assigns(:hosts).count
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
test 'in IoP mode host_details uses subscription uuid when insights uuid is stale' do
|
|
25
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
26
|
+
|
|
27
|
+
stale_insights_uuid = 'stale-insights-uuid-123'
|
|
28
|
+
subscription_uuid = 'subscription-uuid-456'
|
|
29
|
+
|
|
30
|
+
# Create host with diverging facet UUIDs
|
|
31
|
+
host = FactoryBot.create(:host, :with_subscription, organization: @test_org)
|
|
32
|
+
host.subscription_facet.update!(uuid: subscription_uuid)
|
|
33
|
+
host.insights = FactoryBot.create(:insights_facet, host_id: host.id, uuid: stale_insights_uuid)
|
|
34
|
+
host.save!
|
|
35
|
+
|
|
36
|
+
# Query using the stale insights UUID
|
|
37
|
+
get :host_details, params: {
|
|
38
|
+
organization_id: @test_org.id,
|
|
39
|
+
host_uuids: [stale_insights_uuid],
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
assert_response :success
|
|
43
|
+
body = JSON.parse(response.body)
|
|
44
|
+
|
|
45
|
+
# Should return the subscription UUID, not the stale insights UUID
|
|
46
|
+
insights_uuids = body.map { |h| h['insights_uuid'] }
|
|
47
|
+
assert_includes insights_uuids, subscription_uuid, "Should use subscription UUID in IoP mode"
|
|
48
|
+
refute_includes insights_uuids, stale_insights_uuid, "Should not use stale insights UUID"
|
|
49
|
+
end
|
|
50
|
+
|
|
24
51
|
test 'shows error when no hosts found' do
|
|
25
52
|
get :host_details, params: { organization_id: @test_org.id, host_uuids: ['nonexistentuuid'] }
|
|
26
53
|
assert_response :not_found
|
|
@@ -58,5 +58,34 @@ FactoryBot.modify do
|
|
|
58
58
|
host.insights = FactoryBot.create(:insights_facet, :with_hits, host_id: host.id)
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
|
+
|
|
62
|
+
trait :with_mismatched_insights_uuid do
|
|
63
|
+
# Simulates host previously registered to cloud with stale UUID
|
|
64
|
+
# Requires :with_subscription trait to be used together
|
|
65
|
+
after(:create) do |host, _evaluator|
|
|
66
|
+
raise "subscription_facet required for :with_mismatched_insights_uuid trait" unless host.subscription_facet&.uuid
|
|
67
|
+
|
|
68
|
+
host.insights = FactoryBot.create(
|
|
69
|
+
:insights_facet,
|
|
70
|
+
host_id: host.id,
|
|
71
|
+
uuid: 'stale-cloud-uuid' # Different from subscription_facet
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
trait :with_synced_insights_uuid do
|
|
77
|
+
# Ideal state: insights_facet UUID matches subscription_facet UUID
|
|
78
|
+
# Requires :with_subscription trait to be used together
|
|
79
|
+
after(:create) do |host, _evaluator|
|
|
80
|
+
raise "subscription_facet required for :with_synced_insights_uuid trait" unless host.subscription_facet&.uuid
|
|
81
|
+
|
|
82
|
+
subscription_uuid = host.subscription_facet.uuid
|
|
83
|
+
host.insights = FactoryBot.create(
|
|
84
|
+
:insights_facet,
|
|
85
|
+
host_id: host.id,
|
|
86
|
+
uuid: subscription_uuid # Same as subscription_facet
|
|
87
|
+
)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
61
90
|
end
|
|
62
91
|
end
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
require 'test_plugin_helper'
|
|
2
|
+
|
|
3
|
+
class ForemanRhCloudIopMetadataTest < ActiveSupport::TestCase
|
|
4
|
+
setup do
|
|
5
|
+
# Clean up any existing IoP smart proxies
|
|
6
|
+
SmartProxy.unscoped.with_features('iop').destroy_all
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
teardown do
|
|
10
|
+
# Clean up
|
|
11
|
+
SmartProxy.unscoped.with_features('iop').destroy_all
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create_iop_proxy(url: 'https://iop.example.com')
|
|
15
|
+
feature = Feature.find_or_create_by(name: 'iop')
|
|
16
|
+
proxy = FactoryBot.create(:smart_proxy, :url => url)
|
|
17
|
+
# Clear any existing associations for this feature
|
|
18
|
+
feature.reload
|
|
19
|
+
feature.smart_proxies.clear
|
|
20
|
+
proxy.features << feature
|
|
21
|
+
proxy
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe 'plugin metadata' do
|
|
25
|
+
test 'iop metadata is false when no IoP smart proxy exists' do
|
|
26
|
+
# Ensure no IoP proxy exists
|
|
27
|
+
refute ForemanRhCloud.with_iop_smart_proxy?
|
|
28
|
+
|
|
29
|
+
# Plugin metadata should reflect this
|
|
30
|
+
metadata = ::Foreman::Plugin.app_metadata_registry.all_plugin_metadata[:foreman_rh_cloud]
|
|
31
|
+
|
|
32
|
+
# The value is a lambda, so we need to call it
|
|
33
|
+
assert_kind_of Proc, metadata[:iop]
|
|
34
|
+
refute metadata[:iop].call
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
test 'iop metadata is true when IoP smart proxy exists' do
|
|
38
|
+
# Create an IoP smart proxy
|
|
39
|
+
create_iop_proxy
|
|
40
|
+
|
|
41
|
+
# Verify proxy exists
|
|
42
|
+
assert ForemanRhCloud.with_iop_smart_proxy?
|
|
43
|
+
|
|
44
|
+
# Plugin metadata should reflect this
|
|
45
|
+
metadata = ::Foreman::Plugin.app_metadata_registry.all_plugin_metadata[:foreman_rh_cloud]
|
|
46
|
+
|
|
47
|
+
# The value is a lambda, so we need to call it
|
|
48
|
+
assert_kind_of Proc, metadata[:iop]
|
|
49
|
+
assert metadata[:iop].call
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
test 'iop metadata updates when IoP smart proxy is created' do
|
|
53
|
+
# Initially no IoP proxy
|
|
54
|
+
metadata = ::Foreman::Plugin.app_metadata_registry.all_plugin_metadata[:foreman_rh_cloud]
|
|
55
|
+
refute metadata[:iop].call
|
|
56
|
+
|
|
57
|
+
# Create an IoP smart proxy
|
|
58
|
+
create_iop_proxy
|
|
59
|
+
|
|
60
|
+
# Metadata should now return true
|
|
61
|
+
assert metadata[:iop].call
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
test 'iop metadata updates when IoP smart proxy is destroyed' do
|
|
65
|
+
# Create an IoP smart proxy
|
|
66
|
+
proxy = create_iop_proxy
|
|
67
|
+
|
|
68
|
+
metadata = ::Foreman::Plugin.app_metadata_registry.all_plugin_metadata[:foreman_rh_cloud]
|
|
69
|
+
assert metadata[:iop].call
|
|
70
|
+
|
|
71
|
+
# Destroy the proxy
|
|
72
|
+
proxy.destroy
|
|
73
|
+
|
|
74
|
+
# Metadata should now return false
|
|
75
|
+
refute metadata[:iop].call
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe 'URL methods' do
|
|
80
|
+
test 'base_url returns cloud URL when no IoP smart proxy exists' do
|
|
81
|
+
assert_equal 'https://cloud.redhat.com', ForemanRhCloud.base_url
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
test 'cert_base_url returns cloud URL when no IoP smart proxy exists' do
|
|
85
|
+
assert_equal 'https://cert.cloud.redhat.com', ForemanRhCloud.cert_base_url
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
test 'legacy_insights_url returns cloud URL when no IoP smart proxy exists' do
|
|
89
|
+
assert_equal 'https://cert-api.access.redhat.com', ForemanRhCloud.legacy_insights_url
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
test 'base_url returns IoP URL when IoP smart proxy exists' do
|
|
93
|
+
create_iop_proxy
|
|
94
|
+
|
|
95
|
+
assert_equal 'https://iop.example.com', ForemanRhCloud.base_url
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
test 'cert_base_url returns IoP URL when IoP smart proxy exists' do
|
|
99
|
+
create_iop_proxy
|
|
100
|
+
|
|
101
|
+
assert_equal 'https://iop.example.com', ForemanRhCloud.cert_base_url
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
test 'legacy_insights_url returns IoP URL when IoP smart proxy exists' do
|
|
105
|
+
create_iop_proxy
|
|
106
|
+
|
|
107
|
+
assert_equal 'https://iop.example.com', ForemanRhCloud.legacy_insights_url
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
test 'base_url returns ENV var when set' do
|
|
111
|
+
ENV['SATELLITE_RH_CLOUD_URL'] = 'https://custom.example.com'
|
|
112
|
+
|
|
113
|
+
assert_equal 'https://custom.example.com', ForemanRhCloud.base_url
|
|
114
|
+
ensure
|
|
115
|
+
ENV.delete('SATELLITE_RH_CLOUD_URL')
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
test 'cert_base_url returns ENV var when set' do
|
|
119
|
+
ENV['SATELLITE_CERT_RH_CLOUD_URL'] = 'https://env-cert.cloud.test'
|
|
120
|
+
|
|
121
|
+
assert_equal 'https://env-cert.cloud.test', ForemanRhCloud.cert_base_url
|
|
122
|
+
ensure
|
|
123
|
+
ENV.delete('SATELLITE_CERT_RH_CLOUD_URL')
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
test 'legacy_insights_url returns ENV var when set' do
|
|
127
|
+
ENV['SATELLITE_LEGACY_INSIGHTS_URL'] = 'https://env-legacy.insights.test'
|
|
128
|
+
|
|
129
|
+
assert_equal 'https://env-legacy.insights.test', ForemanRhCloud.legacy_insights_url
|
|
130
|
+
ensure
|
|
131
|
+
ENV.delete('SATELLITE_LEGACY_INSIGHTS_URL')
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
test 'base_url prefers IoP URL over ENV var' do
|
|
135
|
+
ENV['SATELLITE_RH_CLOUD_URL'] = 'https://custom.example.com'
|
|
136
|
+
|
|
137
|
+
create_iop_proxy
|
|
138
|
+
|
|
139
|
+
# IoP URL should take precedence
|
|
140
|
+
assert_equal 'https://iop.example.com', ForemanRhCloud.base_url
|
|
141
|
+
ensure
|
|
142
|
+
ENV.delete('SATELLITE_RH_CLOUD_URL')
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
test 'cert_base_url prefers IoP URL over ENV var' do
|
|
146
|
+
ENV['SATELLITE_CERT_RH_CLOUD_URL'] = 'https://env-cert.cloud.test'
|
|
147
|
+
|
|
148
|
+
create_iop_proxy
|
|
149
|
+
|
|
150
|
+
# IoP URL should take precedence
|
|
151
|
+
assert_equal 'https://iop.example.com', ForemanRhCloud.cert_base_url
|
|
152
|
+
ensure
|
|
153
|
+
ENV.delete('SATELLITE_CERT_RH_CLOUD_URL')
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
test 'legacy_insights_url prefers IoP URL over ENV var' do
|
|
157
|
+
ENV['SATELLITE_LEGACY_INSIGHTS_URL'] = 'https://env-legacy.insights.test'
|
|
158
|
+
|
|
159
|
+
create_iop_proxy
|
|
160
|
+
|
|
161
|
+
# IoP URL should take precedence
|
|
162
|
+
assert_equal 'https://iop.example.com', ForemanRhCloud.legacy_insights_url
|
|
163
|
+
ensure
|
|
164
|
+
ENV.delete('SATELLITE_LEGACY_INSIGHTS_URL')
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
test 'URL methods update when IoP smart proxy is created' do
|
|
168
|
+
# Initially returns cloud URLs
|
|
169
|
+
assert_equal 'https://cloud.redhat.com', ForemanRhCloud.base_url
|
|
170
|
+
assert_equal 'https://cert.cloud.redhat.com', ForemanRhCloud.cert_base_url
|
|
171
|
+
assert_equal 'https://cert-api.access.redhat.com', ForemanRhCloud.legacy_insights_url
|
|
172
|
+
|
|
173
|
+
# Create an IoP smart proxy
|
|
174
|
+
create_iop_proxy
|
|
175
|
+
|
|
176
|
+
# Should now return IoP URL for all helpers
|
|
177
|
+
assert_equal 'https://iop.example.com', ForemanRhCloud.base_url
|
|
178
|
+
assert_equal 'https://iop.example.com', ForemanRhCloud.cert_base_url
|
|
179
|
+
assert_equal 'https://iop.example.com', ForemanRhCloud.legacy_insights_url
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
test 'URL methods update when IoP smart proxy is destroyed' do
|
|
183
|
+
# Create an IoP smart proxy
|
|
184
|
+
proxy = create_iop_proxy
|
|
185
|
+
|
|
186
|
+
# Initially returns IoP URL for all helpers
|
|
187
|
+
assert_equal 'https://iop.example.com', ForemanRhCloud.base_url
|
|
188
|
+
assert_equal 'https://iop.example.com', ForemanRhCloud.cert_base_url
|
|
189
|
+
assert_equal 'https://iop.example.com', ForemanRhCloud.legacy_insights_url
|
|
190
|
+
|
|
191
|
+
# Destroy the proxy
|
|
192
|
+
proxy.destroy
|
|
193
|
+
|
|
194
|
+
# Should now return cloud URLs again
|
|
195
|
+
assert_equal 'https://cloud.redhat.com', ForemanRhCloud.base_url
|
|
196
|
+
assert_equal 'https://cert.cloud.redhat.com', ForemanRhCloud.cert_base_url
|
|
197
|
+
assert_equal 'https://cert-api.access.redhat.com', ForemanRhCloud.legacy_insights_url
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
@@ -4,8 +4,8 @@ module ForemanRhCloud
|
|
|
4
4
|
class RegistrationManagerExtensionsTest < ActiveSupport::TestCase
|
|
5
5
|
setup do
|
|
6
6
|
@org = FactoryBot.create(:organization)
|
|
7
|
-
@host = FactoryBot.create(:host, :managed, organization: @org)
|
|
8
|
-
@insights_facet = ::InsightsFacet.create!(host: @host, uuid:
|
|
7
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
8
|
+
@insights_facet = ::InsightsFacet.create!(host: @host, uuid: @host.subscription_facet.uuid)
|
|
9
9
|
|
|
10
10
|
# Stub Candlepin interaction (from Katello)
|
|
11
11
|
::Katello::Resources::Candlepin::Consumer.stubs(:destroy)
|
|
@@ -15,9 +15,9 @@ module ForemanRhCloud
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
context 'unregister_host' do
|
|
18
|
-
test 'should call HBI delete in IoP mode when host has insights
|
|
18
|
+
test 'should call HBI delete in IoP mode when host has insights UUID' do
|
|
19
19
|
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
20
|
-
expected_url = ForemanInventoryUpload.host_by_id_url(
|
|
20
|
+
expected_url = ForemanInventoryUpload.host_by_id_url(@host.subscription_facet.uuid)
|
|
21
21
|
|
|
22
22
|
# Expect the cloud request to be made
|
|
23
23
|
Katello::RegistrationManager.expects(:execute_cloud_request).with do |params|
|
|
@@ -45,44 +45,6 @@ module ForemanRhCloud
|
|
|
45
45
|
assert_nil InsightsFacet.find_by(id: @insights_facet.id)
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
test 'should NOT call HBI delete when host has no insights_facet' do
|
|
49
|
-
host_without_facet = FactoryBot.create(:host, :managed, organization: @org)
|
|
50
|
-
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
51
|
-
|
|
52
|
-
Katello::RegistrationManager.expects(:execute_cloud_request).never
|
|
53
|
-
|
|
54
|
-
assert_nothing_raised do
|
|
55
|
-
Katello::RegistrationManager.unregister_host(host_without_facet, unregistering: true)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
test 'should NOT call HBI delete when host has insights_facet with empty UUID' do
|
|
60
|
-
host_with_empty_uuid_facet = FactoryBot.create(:host, :managed, organization: @org)
|
|
61
|
-
empty_uuid_facet = InsightsFacet.create!(host: host_with_empty_uuid_facet, uuid: '')
|
|
62
|
-
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
63
|
-
|
|
64
|
-
Katello::RegistrationManager.expects(:execute_cloud_request).never
|
|
65
|
-
|
|
66
|
-
assert_nothing_raised do
|
|
67
|
-
Katello::RegistrationManager.unregister_host(host_with_empty_uuid_facet, unregistering: true)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
assert_nil InsightsFacet.find_by(id: empty_uuid_facet.id)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
test 'should NOT call HBI delete when insights_facet has no UUID' do
|
|
74
|
-
facet_id = @insights_facet.id
|
|
75
|
-
@insights_facet.update(uuid: nil)
|
|
76
|
-
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
77
|
-
|
|
78
|
-
Katello::RegistrationManager.expects(:execute_cloud_request).never
|
|
79
|
-
|
|
80
|
-
Katello::RegistrationManager.unregister_host(@host, unregistering: true)
|
|
81
|
-
|
|
82
|
-
# Verify facet was still destroyed
|
|
83
|
-
assert_nil InsightsFacet.find_by(id: facet_id)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
48
|
test 'should always destroy insights_facet regardless of IoP mode' do
|
|
87
49
|
facet_id = @insights_facet.id
|
|
88
50
|
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
require 'test_plugin_helper'
|
|
2
|
+
|
|
3
|
+
class RhCloudHostTest < ActiveSupport::TestCase
|
|
4
|
+
setup do
|
|
5
|
+
@org = FactoryBot.create(:organization)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
teardown do
|
|
9
|
+
ForemanRhCloud.unstub(:with_iop_smart_proxy?)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
context 'insights_uuid method' do
|
|
13
|
+
test 'returns insights_facet uuid in non-IoP mode' do
|
|
14
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
15
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
16
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'insights-123')
|
|
17
|
+
|
|
18
|
+
assert_equal 'insights-123', @host.insights_uuid
|
|
19
|
+
assert_not_equal @host.subscription_facet.uuid, @host.insights_uuid
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
test 'returns subscription_facet uuid in IoP mode' do
|
|
23
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
24
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
25
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'insights-456')
|
|
26
|
+
|
|
27
|
+
assert_equal @host.subscription_facet.uuid, @host.insights_uuid
|
|
28
|
+
assert_not_equal 'insights-456', @host.insights_uuid
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test 'returns nil when insights_facet missing in non-IoP mode' do
|
|
32
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
33
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
34
|
+
|
|
35
|
+
assert_nil @host.insights_uuid
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test 'returns nil when subscription_facet missing in IoP mode' do
|
|
39
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
40
|
+
@host = FactoryBot.create(:host, :managed, organization: @org)
|
|
41
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'insights-789')
|
|
42
|
+
|
|
43
|
+
assert_nil @host.insights_uuid
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
test 'returns nil when both facets missing' do
|
|
47
|
+
@host = FactoryBot.create(:host, :managed, organization: @org)
|
|
48
|
+
|
|
49
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
50
|
+
assert_nil @host.insights_uuid
|
|
51
|
+
|
|
52
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
53
|
+
assert_nil @host.insights_uuid
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
test 'never returns stale insights_facet uuid in IoP mode' do
|
|
57
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
58
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
59
|
+
current_uuid = @host.subscription_facet.uuid
|
|
60
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'stale-456')
|
|
61
|
+
|
|
62
|
+
# Should return subscription_facet UUID, never the stale insights_facet UUID
|
|
63
|
+
assert_equal current_uuid, @host.insights_uuid
|
|
64
|
+
assert_not_equal 'stale-456', @host.insights_uuid
|
|
65
|
+
|
|
66
|
+
# Verify multiple calls always return subscription_facet UUID
|
|
67
|
+
3.times do
|
|
68
|
+
assert_equal current_uuid, @host.insights_uuid
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
test 'dynamically responds to IoP mode changes' do
|
|
73
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
74
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'insights-123')
|
|
75
|
+
subscription_uuid = @host.subscription_facet.uuid
|
|
76
|
+
|
|
77
|
+
# Non-IoP mode: should return insights_facet UUID
|
|
78
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
79
|
+
assert_equal 'insights-123', @host.insights_uuid
|
|
80
|
+
|
|
81
|
+
# IoP mode: should return subscription_facet UUID
|
|
82
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
83
|
+
assert_equal subscription_uuid, @host.insights_uuid
|
|
84
|
+
|
|
85
|
+
# Toggle back to non-IoP mode
|
|
86
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
87
|
+
assert_equal 'insights-123', @host.insights_uuid
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context 'ensure_iop_insights_uuid method' do
|
|
92
|
+
test 'updates insights_facet uuid when different from subscription_facet' do
|
|
93
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
94
|
+
correct_uuid = @host.subscription_facet.uuid
|
|
95
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'wrong-456')
|
|
96
|
+
|
|
97
|
+
assert_equal 'wrong-456', @host.insights_facet.uuid
|
|
98
|
+
|
|
99
|
+
@host.ensure_iop_insights_uuid
|
|
100
|
+
|
|
101
|
+
assert_equal correct_uuid, @host.insights_facet.reload.uuid
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
test 'does nothing when uuids already match' do
|
|
105
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
106
|
+
matching_uuid = @host.subscription_facet.uuid
|
|
107
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: matching_uuid)
|
|
108
|
+
|
|
109
|
+
# Expect no update call since UUIDs already match
|
|
110
|
+
@host.insights_facet.expects(:update!).never
|
|
111
|
+
|
|
112
|
+
@host.ensure_iop_insights_uuid
|
|
113
|
+
|
|
114
|
+
assert_equal matching_uuid, @host.insights_facet.uuid
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
test 'does nothing when insights_facet missing' do
|
|
118
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
119
|
+
|
|
120
|
+
assert_nothing_raised do
|
|
121
|
+
@host.ensure_iop_insights_uuid
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
test 'does nothing when subscription_facet missing' do
|
|
126
|
+
@host = FactoryBot.create(:host, :managed, organization: @org)
|
|
127
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'insights-999')
|
|
128
|
+
original_uuid = @host.insights_facet.uuid
|
|
129
|
+
|
|
130
|
+
assert_nothing_raised do
|
|
131
|
+
@host.ensure_iop_insights_uuid
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
assert_equal original_uuid, @host.insights_facet.uuid
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
test 'does nothing when both facets missing' do
|
|
138
|
+
@host = FactoryBot.create(:host, :managed, organization: @org)
|
|
139
|
+
|
|
140
|
+
assert_nothing_raised do
|
|
141
|
+
@host.ensure_iop_insights_uuid
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
test 'handles nil uuids gracefully' do
|
|
146
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
147
|
+
|
|
148
|
+
# Scenario 1: subscription_facet uuid is nil (shouldn't happen but test gracefully)
|
|
149
|
+
@host.subscription_facet.update(uuid: nil)
|
|
150
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'some-uuid')
|
|
151
|
+
|
|
152
|
+
assert_nothing_raised do
|
|
153
|
+
@host.ensure_iop_insights_uuid
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Scenario 2: insights_facet uuid is nil
|
|
157
|
+
@host.subscription_facet.update(uuid: 'valid-uuid')
|
|
158
|
+
@host.insights_facet.update(uuid: nil)
|
|
159
|
+
|
|
160
|
+
assert_nothing_raised do
|
|
161
|
+
@host.ensure_iop_insights_uuid
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Should update to match subscription_facet
|
|
165
|
+
assert_equal 'valid-uuid', @host.insights_facet.reload.uuid
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
test 'corrects stale uuid after cloud registration' do
|
|
169
|
+
# Simulate a host that was previously registered to cloud with cloud-assigned UUID
|
|
170
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
171
|
+
local_uuid = @host.subscription_facet.uuid
|
|
172
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'cloud-456')
|
|
173
|
+
|
|
174
|
+
# Before sync: insights_facet has stale cloud UUID
|
|
175
|
+
assert_equal 'cloud-456', @host.insights_facet.uuid
|
|
176
|
+
|
|
177
|
+
# In IoP mode, insights_uuid should return subscription_facet UUID (not stale)
|
|
178
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
179
|
+
assert_equal local_uuid, @host.insights_uuid
|
|
180
|
+
|
|
181
|
+
# Call sync to correct the stale UUID
|
|
182
|
+
@host.ensure_iop_insights_uuid
|
|
183
|
+
|
|
184
|
+
# After sync: insights_facet UUID should match subscription_facet UUID
|
|
185
|
+
assert_equal local_uuid, @host.insights_facet.reload.uuid
|
|
186
|
+
|
|
187
|
+
# Verify insights_uuid still returns correct value
|
|
188
|
+
assert_equal local_uuid, @host.insights_uuid
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foreman_rh_cloud
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 13.0.
|
|
4
|
+
version: 13.0.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Foreman Red Hat Cloud team
|
|
@@ -277,12 +277,14 @@ files:
|
|
|
277
277
|
- test/test_plugin_helper.rb
|
|
278
278
|
- test/unit/archived_report_generator_test.rb
|
|
279
279
|
- test/unit/fact_helpers_test.rb
|
|
280
|
+
- test/unit/foreman_rh_cloud_iop_metadata_test.rb
|
|
280
281
|
- test/unit/foreman_rh_cloud_self_host_test.rb
|
|
281
282
|
- test/unit/insights_facet_test.rb
|
|
282
283
|
- test/unit/lib/foreman_rh_cloud/registration_manager_extensions_test.rb
|
|
283
284
|
- test/unit/lib/insights_cloud/async/vmaas_reposcan_sync_test.rb
|
|
284
285
|
- test/unit/metadata_generator_test.rb
|
|
285
286
|
- test/unit/playbook_progress_generator_test.rb
|
|
287
|
+
- test/unit/rh_cloud_host_test.rb
|
|
286
288
|
- test/unit/rh_cloud_http_proxy_test.rb
|
|
287
289
|
- test/unit/rh_cloud_permissions_test.rb
|
|
288
290
|
- test/unit/services/foreman_rh_cloud/branch_info_test.rb
|
|
@@ -691,12 +693,14 @@ test_files:
|
|
|
691
693
|
- test/test_plugin_helper.rb
|
|
692
694
|
- test/unit/archived_report_generator_test.rb
|
|
693
695
|
- test/unit/fact_helpers_test.rb
|
|
696
|
+
- test/unit/foreman_rh_cloud_iop_metadata_test.rb
|
|
694
697
|
- test/unit/foreman_rh_cloud_self_host_test.rb
|
|
695
698
|
- test/unit/insights_facet_test.rb
|
|
696
699
|
- test/unit/lib/foreman_rh_cloud/registration_manager_extensions_test.rb
|
|
697
700
|
- test/unit/lib/insights_cloud/async/vmaas_reposcan_sync_test.rb
|
|
698
701
|
- test/unit/metadata_generator_test.rb
|
|
699
702
|
- test/unit/playbook_progress_generator_test.rb
|
|
703
|
+
- test/unit/rh_cloud_host_test.rb
|
|
700
704
|
- test/unit/rh_cloud_http_proxy_test.rb
|
|
701
705
|
- test/unit/rh_cloud_permissions_test.rb
|
|
702
706
|
- test/unit/services/foreman_rh_cloud/branch_info_test.rb
|