foreman_rh_cloud 12.1.3 → 12.1.5
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/README.md +3 -5
- data/app/controllers/concerns/insights_cloud/package_profile_upload_extensions.rb +33 -0
- data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +1 -2
- data/app/controllers/insights_cloud/ui_requests_controller.rb +99 -0
- data/app/services/foreman_rh_cloud/cert_auth.rb +9 -1
- data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +12 -13
- data/app/services/foreman_rh_cloud/gateway_request.rb +26 -0
- data/app/services/foreman_rh_cloud/insights_api_forwarder.rb +116 -0
- data/app/services/foreman_rh_cloud/tags_auth.rb +55 -0
- data/app/views/api/v2/hosts/insights/base.rabl +6 -0
- data/config/routes.rb +2 -0
- data/lib/foreman_inventory_upload/async/generate_report_job.rb +11 -5
- data/lib/foreman_inventory_upload/async/upload_report_job.rb +15 -4
- data/lib/foreman_inventory_upload/generators/archived_report.rb +2 -2
- data/lib/foreman_inventory_upload/generators/fact_helpers.rb +65 -13
- data/lib/foreman_inventory_upload/generators/queries.rb +7 -5
- data/lib/foreman_inventory_upload/generators/slice.rb +0 -1
- data/lib/foreman_inventory_upload.rb +2 -2
- data/lib/foreman_rh_cloud/engine.rb +5 -3
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/insights_cloud.rb +8 -0
- data/lib/inventory_sync/async/inventory_hosts_sync.rb +2 -0
- data/lib/tasks/rh_cloud_inventory.rake +3 -2
- data/package.json +5 -1
- data/test/controllers/insights_cloud/ui_requests_controller_test.rb +169 -0
- data/test/unit/archived_report_generator_test.rb +1 -1
- data/test/unit/fact_helpers_test.rb +267 -2
- data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +20 -3
- data/test/unit/services/foreman_rh_cloud/insights_api_forwarder_test.rb +176 -0
- data/test/unit/services/foreman_rh_cloud/tags_auth_test.rb +29 -0
- data/test/unit/slice_generator_test.rb +69 -10
- data/webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.js +30 -10
- data/webpack/CVEsHostDetailsTab/__tests__/CVEsHostDetailsTab.test.js +18 -11
- data/webpack/CVEsHostDetailsTab/index.js +2 -2
- data/webpack/ForemanColumnExtensions/index.js +51 -0
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilter.js +1 -0
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilter.test.js.snap +1 -0
- data/webpack/ForemanInventoryUpload/Components/InventorySettings/MinimalInventoryDropdown.js +2 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/PageTitle.js +8 -1
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +4 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorButton.js +3 -3
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/__snapshots__/CloudConnectorButton.test.js.snap +3 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +10 -4
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +6 -6
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/SettingsWarning.js +2 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/__snapshots__/SettingsWarning.test.js.snap +2 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButton.js +1 -0
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButton.test.js.snap +1 -0
- data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/InventoryAutoUpload.js +3 -1
- data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/__snapshots__/InventoryAutoUpload.test.js.snap +3 -0
- data/webpack/ForemanRhCloudFills.js +6 -3
- data/webpack/ForemanRhCloudPages.js +6 -3
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +1 -0
- data/webpack/InsightsCloudSync/Components/InsightsTable/SelectAllAlert.js +2 -0
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +1 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +3 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModalFooter.js +12 -2
- data/webpack/InsightsCloudSync/Components/RemediationModal/Resolutions.js +1 -0
- data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +6 -1
- data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.js +21 -0
- data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.test.js +20 -0
- data/webpack/InsightsVulnerabilityHostIndexExtensions/CVECountCell.js +45 -0
- data/webpack/InsightsVulnerabilityHostIndexExtensions/__tests__/CVECountCell.test.js +28 -0
- data/webpack/common/DropdownToggle.js +1 -0
- data/webpack/common/ScalprumModule/ScalprumContext.js +63 -0
- data/webpack/common/Switcher/SwitcherPF4.js +1 -0
- data/webpack/common/Switcher/__tests__/__snapshots__/SwitcherPF4.test.js.snap +1 -0
- data/webpack/common/Switcher/index.js +1 -0
- data/webpack/global_index.js +3 -0
- metadata +19 -4
- data/webpack/InsightsVulnerability/InsightsVulnerability.js +0 -13
- data/webpack/InsightsVulnerability/InsightsVulnerability.test.js +0 -18
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'test_plugin_helper'
|
2
|
+
require 'digest'
|
2
3
|
|
3
4
|
class FactHelpersTest < ActiveSupport::TestCase
|
4
5
|
class FactsHelpersTestStub
|
@@ -29,7 +30,7 @@ class FactHelpersTest < ActiveSupport::TestCase
|
|
29
30
|
|
30
31
|
test 'obfuscates ips with insights-client data' do
|
31
32
|
host = mock('host')
|
32
|
-
@instance.expects(:fact_value).with(host, 'insights_client::
|
33
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscated_ipv4').returns(
|
33
34
|
'[{"obfuscated": "10.230.230.1", "original": "224.0.0.1"}, {"obfuscated": "10.230.230.255", "original": "224.0.0.251"}]'
|
34
35
|
)
|
35
36
|
|
@@ -41,11 +42,275 @@ class FactHelpersTest < ActiveSupport::TestCase
|
|
41
42
|
|
42
43
|
test 'obfuscates ips without insights-client data' do
|
43
44
|
host = mock('host')
|
44
|
-
@instance.expects(:fact_value).with(host, 'insights_client::
|
45
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscated_ipv4').returns(nil)
|
45
46
|
|
46
47
|
actual = @instance.obfuscated_ips(host)
|
47
48
|
|
48
49
|
assert_equal '10.230.230.1', actual['224.0.0.1']
|
49
50
|
assert_equal '10.230.230.2', actual['224.0.0.2']
|
50
51
|
end
|
52
|
+
|
53
|
+
describe 'obfuscate_hostname?' do
|
54
|
+
test 'returns true when global setting is enabled' do
|
55
|
+
Setting.expects(:[]).with(:obfuscate_inventory_hostnames).returns(true)
|
56
|
+
host = mock('host')
|
57
|
+
|
58
|
+
result = @instance.obfuscate_hostname?(host)
|
59
|
+
|
60
|
+
assert result
|
61
|
+
end
|
62
|
+
|
63
|
+
test 'returns false when global setting is disabled and no host-specific setting' do
|
64
|
+
Setting.expects(:[]).with(:obfuscate_inventory_hostnames).returns(false)
|
65
|
+
host = mock('host')
|
66
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_hostname_enabled').returns(nil)
|
67
|
+
|
68
|
+
result = @instance.obfuscate_hostname?(host)
|
69
|
+
|
70
|
+
refute result
|
71
|
+
end
|
72
|
+
|
73
|
+
test 'returns true when host-specific setting is enabled' do
|
74
|
+
Setting.expects(:[]).with(:obfuscate_inventory_hostnames).returns(false)
|
75
|
+
host = mock('host')
|
76
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_hostname_enabled').returns('true')
|
77
|
+
|
78
|
+
result = @instance.obfuscate_hostname?(host)
|
79
|
+
|
80
|
+
assert result
|
81
|
+
end
|
82
|
+
|
83
|
+
test 'returns false when host-specific setting is disabled' do
|
84
|
+
Setting.expects(:[]).with(:obfuscate_inventory_hostnames).returns(false)
|
85
|
+
host = mock('host')
|
86
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_hostname_enabled').returns('false')
|
87
|
+
|
88
|
+
result = @instance.obfuscate_hostname?(host)
|
89
|
+
|
90
|
+
refute result
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe 'fqdn' do
|
95
|
+
test 'returns original fqdn when obfuscation is disabled' do
|
96
|
+
host = mock('host')
|
97
|
+
host.expects(:fqdn).returns('test.example.com')
|
98
|
+
@instance.expects(:obfuscate_hostname?).with(host).returns(false)
|
99
|
+
|
100
|
+
result = @instance.fqdn(host)
|
101
|
+
|
102
|
+
assert_equal 'test.example.com', result
|
103
|
+
end
|
104
|
+
|
105
|
+
test 'returns obfuscated hostname from insights_client fact when available' do
|
106
|
+
host = mock('host')
|
107
|
+
host.expects(:fqdn).returns('test.example.com').once
|
108
|
+
@instance.expects(:obfuscate_hostname?).with(host).returns(true)
|
109
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscated_hostname').returns(
|
110
|
+
'[{"original": "test.example.com", "obfuscated": "abc123.example.com"}]'
|
111
|
+
)
|
112
|
+
|
113
|
+
result = @instance.fqdn(host)
|
114
|
+
|
115
|
+
assert_equal 'abc123.example.com', result
|
116
|
+
end
|
117
|
+
|
118
|
+
test 'returns dynamically obfuscated hostname when insights_client fact is not available' do
|
119
|
+
host = mock('host')
|
120
|
+
host.stubs(:fqdn).returns('test.example.com')
|
121
|
+
@instance.expects(:obfuscate_hostname?).with(host).returns(true)
|
122
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscated_hostname').returns(nil)
|
123
|
+
|
124
|
+
result = @instance.fqdn(host)
|
125
|
+
|
126
|
+
expected = "#{Digest::SHA1.hexdigest('test.example.com')}.example.com"
|
127
|
+
assert_equal expected, result
|
128
|
+
end
|
129
|
+
|
130
|
+
test 'returns dynamically obfuscated hostname when insights_client fact does not contain matching host' do
|
131
|
+
host = mock('host')
|
132
|
+
host.expects(:fqdn).returns('test.example.com').twice
|
133
|
+
@instance.expects(:obfuscate_hostname?).with(host).returns(true)
|
134
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscated_hostname').returns(
|
135
|
+
'[{"original": "other.example.com", "obfuscated": "abc123.example.com"}]'
|
136
|
+
)
|
137
|
+
@instance.expects(:obfuscate_fqdn).with('test.example.com').returns('dynamically_obfuscated.example.com')
|
138
|
+
|
139
|
+
result = @instance.fqdn(host)
|
140
|
+
|
141
|
+
assert_equal 'dynamically_obfuscated.example.com', result
|
142
|
+
end
|
143
|
+
|
144
|
+
test 'handles invalid JSON in insights_client fact gracefully' do
|
145
|
+
host = mock('host')
|
146
|
+
host.stubs(:fqdn).returns('test.example.com')
|
147
|
+
@instance.expects(:obfuscate_hostname?).with(host).returns(true)
|
148
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscated_hostname').returns('invalid json')
|
149
|
+
|
150
|
+
result = @instance.fqdn(host)
|
151
|
+
|
152
|
+
expected = "#{Digest::SHA1.hexdigest('test.example.com')}.example.com"
|
153
|
+
assert_equal expected, result
|
154
|
+
end
|
155
|
+
|
156
|
+
test 'handles empty insights_client fact' do
|
157
|
+
host = mock('host')
|
158
|
+
host.stubs(:fqdn).returns('test.example.com')
|
159
|
+
@instance.expects(:obfuscate_hostname?).with(host).returns(true)
|
160
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscated_hostname').returns('[]')
|
161
|
+
|
162
|
+
result = @instance.fqdn(host)
|
163
|
+
|
164
|
+
expected = "#{Digest::SHA1.hexdigest('test.example.com')}.example.com"
|
165
|
+
assert_equal expected, result
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe 'obfuscate_ips?' do
|
170
|
+
test 'returns true when global setting is enabled' do
|
171
|
+
Setting.expects(:[]).with(:obfuscate_inventory_ips).returns(true)
|
172
|
+
host = mock('host')
|
173
|
+
|
174
|
+
result = @instance.obfuscate_ips?(host)
|
175
|
+
|
176
|
+
assert result
|
177
|
+
end
|
178
|
+
|
179
|
+
test 'returns false when global setting is disabled and no host-specific settings' do
|
180
|
+
Setting.expects(:[]).with(:obfuscate_inventory_ips).returns(false)
|
181
|
+
host = mock('host')
|
182
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv4_enabled').returns(nil)
|
183
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv6_enabled').returns(nil)
|
184
|
+
|
185
|
+
result = @instance.obfuscate_ips?(host)
|
186
|
+
|
187
|
+
refute result
|
188
|
+
end
|
189
|
+
|
190
|
+
test 'returns true when host-specific IPv4 setting is enabled' do
|
191
|
+
Setting.expects(:[]).with(:obfuscate_inventory_ips).returns(false)
|
192
|
+
host = mock('host')
|
193
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv4_enabled').returns('true')
|
194
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv6_enabled').returns(nil)
|
195
|
+
|
196
|
+
result = @instance.obfuscate_ips?(host)
|
197
|
+
|
198
|
+
assert result
|
199
|
+
end
|
200
|
+
|
201
|
+
test 'returns true when host-specific IPv6 setting is enabled' do
|
202
|
+
Setting.expects(:[]).with(:obfuscate_inventory_ips).returns(false)
|
203
|
+
host = mock('host')
|
204
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv4_enabled').returns(nil)
|
205
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv6_enabled').returns('true')
|
206
|
+
|
207
|
+
result = @instance.obfuscate_ips?(host)
|
208
|
+
|
209
|
+
assert result
|
210
|
+
end
|
211
|
+
|
212
|
+
test 'returns true when both IPv4 and IPv6 settings are enabled' do
|
213
|
+
Setting.expects(:[]).with(:obfuscate_inventory_ips).returns(false)
|
214
|
+
host = mock('host')
|
215
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv4_enabled').returns('true')
|
216
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv6_enabled').returns('true')
|
217
|
+
|
218
|
+
result = @instance.obfuscate_ips?(host)
|
219
|
+
|
220
|
+
assert result
|
221
|
+
end
|
222
|
+
|
223
|
+
test 'returns false when both IPv4 and IPv6 settings are disabled' do
|
224
|
+
Setting.expects(:[]).with(:obfuscate_inventory_ips).returns(false)
|
225
|
+
host = mock('host')
|
226
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv4_enabled').returns('false')
|
227
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv6_enabled').returns('false')
|
228
|
+
|
229
|
+
result = @instance.obfuscate_ips?(host)
|
230
|
+
|
231
|
+
refute result
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe 'obfuscate_ip' do
|
236
|
+
test 'generates first IP when no existing obfuscated IPs' do
|
237
|
+
ips_dict = {}
|
238
|
+
|
239
|
+
result = @instance.obfuscate_ip('192.168.1.1', ips_dict)
|
240
|
+
|
241
|
+
assert_equal '10.230.230.1', result
|
242
|
+
end
|
243
|
+
|
244
|
+
test 'generates next sequential IP when existing obfuscated IPs present' do
|
245
|
+
ips_dict = { '192.168.1.1' => '10.230.230.5', '192.168.1.2' => '10.230.230.10' }
|
246
|
+
|
247
|
+
result = @instance.obfuscate_ip('192.168.1.3', ips_dict)
|
248
|
+
|
249
|
+
assert_equal '10.230.230.11', result
|
250
|
+
end
|
251
|
+
|
252
|
+
test 'handles mixed IP ranges correctly' do
|
253
|
+
ips_dict = { '192.168.1.1' => '10.230.230.255', '192.168.1.2' => '10.230.230.1' }
|
254
|
+
|
255
|
+
result = @instance.obfuscate_ip('192.168.1.3', ips_dict)
|
256
|
+
|
257
|
+
assert_equal '10.230.231.0', result
|
258
|
+
end
|
259
|
+
|
260
|
+
test 'generates valid IP addresses' do
|
261
|
+
ips_dict = {}
|
262
|
+
|
263
|
+
result = @instance.obfuscate_ip('any.ip.address', ips_dict)
|
264
|
+
|
265
|
+
assert_match(/\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\z/, result)
|
266
|
+
assert_nothing_raised { IPAddr.new(result) }
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
describe 'obfuscated_ips' do
|
271
|
+
test 'handles invalid JSON in insights_client fact gracefully' do
|
272
|
+
host = mock('host')
|
273
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscated_ipv4').returns('invalid json')
|
274
|
+
|
275
|
+
result = @instance.obfuscated_ips(host)
|
276
|
+
|
277
|
+
assert_equal '10.230.230.1', result['192.168.1.1']
|
278
|
+
end
|
279
|
+
|
280
|
+
test 'handles empty insights_client fact' do
|
281
|
+
host = mock('host')
|
282
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscated_ipv4').returns('[]')
|
283
|
+
|
284
|
+
result = @instance.obfuscated_ips(host)
|
285
|
+
|
286
|
+
assert_equal '10.230.230.1', result['192.168.1.1']
|
287
|
+
end
|
288
|
+
|
289
|
+
test 'preserves existing obfuscated IPs and generates new ones' do
|
290
|
+
host = mock('host')
|
291
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscated_ipv4').returns(
|
292
|
+
'[{"original": "192.168.1.1", "obfuscated": "10.230.230.5"}]'
|
293
|
+
)
|
294
|
+
|
295
|
+
result = @instance.obfuscated_ips(host)
|
296
|
+
|
297
|
+
assert_equal '10.230.230.5', result['192.168.1.1']
|
298
|
+
assert_equal '10.230.230.6', result['192.168.1.2']
|
299
|
+
end
|
300
|
+
|
301
|
+
test 'default_proc generates unique sequential IPs' do
|
302
|
+
host = mock('host')
|
303
|
+
@instance.expects(:fact_value).with(host, 'insights_client::obfuscated_ipv4').returns(nil)
|
304
|
+
|
305
|
+
result = @instance.obfuscated_ips(host)
|
306
|
+
|
307
|
+
ip1 = result['192.168.1.1']
|
308
|
+
ip2 = result['192.168.1.2']
|
309
|
+
ip3 = result['192.168.1.3']
|
310
|
+
|
311
|
+
assert_equal '10.230.230.1', ip1
|
312
|
+
assert_equal '10.230.230.2', ip2
|
313
|
+
assert_equal '10.230.230.3', ip3
|
314
|
+
end
|
315
|
+
end
|
51
316
|
end
|
@@ -3,6 +3,7 @@ require 'puma/null_io'
|
|
3
3
|
|
4
4
|
class CloudRequestForwarderTest < ActiveSupport::TestCase
|
5
5
|
include MockCerts
|
6
|
+
include KatelloCVEHelper
|
6
7
|
|
7
8
|
setup do
|
8
9
|
@forwarder = ::ForemanRhCloud::CloudRequestForwarder.new
|
@@ -10,6 +11,22 @@ class CloudRequestForwarderTest < ActiveSupport::TestCase
|
|
10
11
|
ForemanRhCloud.stubs(:base_url).returns('https://cloud.example.com')
|
11
12
|
ForemanRhCloud.stubs(:cert_base_url).returns('https://cert.cloud.example.com')
|
12
13
|
ForemanRhCloud.stubs(:legacy_insights_url).returns('https://cert-api.access.example.com')
|
14
|
+
|
15
|
+
UpstreamOnlySettingsTestHelper.set_if_available('allow_multiple_content_views')
|
16
|
+
env = FactoryBot.create(:katello_k_t_environment)
|
17
|
+
env2 = FactoryBot.create(:katello_k_t_environment, organization: env.organization)
|
18
|
+
|
19
|
+
@host = FactoryBot.create(
|
20
|
+
:host,
|
21
|
+
:with_subscription,
|
22
|
+
:with_content,
|
23
|
+
:with_hostgroup,
|
24
|
+
:with_parameter,
|
25
|
+
content_view_environments: [make_cve(lifecycle_environment: env), make_cve(lifecycle_environment: env2)],
|
26
|
+
organization: env.organization
|
27
|
+
)
|
28
|
+
|
29
|
+
@host.subscription_facet.pools << FactoryBot.create(:katello_pool, account_number: '5678', cp_id: 1)
|
13
30
|
end
|
14
31
|
|
15
32
|
test 'should prepare correct cloud url' do
|
@@ -25,7 +42,7 @@ class CloudRequestForwarderTest < ActiveSupport::TestCase
|
|
25
42
|
}
|
26
43
|
|
27
44
|
paths.each do |key, value|
|
28
|
-
actual_params = @forwarder.path_params(key
|
45
|
+
actual_params = @forwarder.path_params(key)
|
29
46
|
assert_equal value, actual_params[:url]
|
30
47
|
end
|
31
48
|
end
|
@@ -150,7 +167,7 @@ class CloudRequestForwarderTest < ActiveSupport::TestCase
|
|
150
167
|
'action_dispatch.request.query_parameters' => params
|
151
168
|
)
|
152
169
|
|
153
|
-
actual = @forwarder.prepare_request_opts(req, 'TEST PAYLOAD', params,
|
170
|
+
actual = @forwarder.prepare_request_opts(req, 'TEST PAYLOAD', params, @host)
|
154
171
|
|
155
172
|
assert_match /foo/, actual[:headers][:user_agent]
|
156
173
|
assert_match /bar/, actual[:headers][:user_agent]
|
@@ -175,7 +192,7 @@ class CloudRequestForwarderTest < ActiveSupport::TestCase
|
|
175
192
|
'action_dispatch.request.query_parameters' => params
|
176
193
|
)
|
177
194
|
|
178
|
-
actual = @forwarder.prepare_request_opts(req, 'TEST PAYLOAD', params,
|
195
|
+
actual = @forwarder.prepare_request_opts(req, 'TEST PAYLOAD', params, @host)
|
179
196
|
|
180
197
|
assert_match /text\/html/, actual[:headers][:content_type]
|
181
198
|
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require 'test_plugin_helper'
|
2
|
+
require 'puma/null_io'
|
3
|
+
|
4
|
+
class UIRequestForwarderTest < ActiveSupport::TestCase
|
5
|
+
include MockCerts
|
6
|
+
|
7
|
+
setup do
|
8
|
+
@forwarder = ::ForemanRhCloud::InsightsApiForwarder.new
|
9
|
+
@user = FactoryBot.build(:user)
|
10
|
+
@organization = FactoryBot.build(:organization)
|
11
|
+
@location = FactoryBot.build(:location)
|
12
|
+
|
13
|
+
setup_certs_expectation do
|
14
|
+
@forwarder.stubs(:foreman_certificates)
|
15
|
+
end
|
16
|
+
|
17
|
+
ForemanRhCloud.stubs(:cert_base_url).returns('https://cert.cloud.example.com')
|
18
|
+
end
|
19
|
+
|
20
|
+
test 'should scope GET requests with proper tags' do
|
21
|
+
user_agent = { :foo => :bar }
|
22
|
+
params = {}
|
23
|
+
|
24
|
+
req = ActionDispatch::Request.new(
|
25
|
+
'REQUEST_URI' => '/api/vulnerability/v1/cves/abc-123/affected_systems',
|
26
|
+
'REQUEST_METHOD' => 'GET',
|
27
|
+
'HTTP_USER_AGENT' => user_agent,
|
28
|
+
'rack.input' => ::Puma::NullIO.new,
|
29
|
+
'action_dispatch.request.query_parameters' => params
|
30
|
+
)
|
31
|
+
|
32
|
+
::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag)
|
33
|
+
@forwarder.expects(:execute_cloud_request).with do |actual_params|
|
34
|
+
actual = actual_params[:headers][:params]
|
35
|
+
assert_equal "U:\"#{@user.login}\"O:\"#{@organization.name}\"L:\"#{@location.name}\"", tag_value(actual.find { |param| param[0] == :tag && tag_name(param[1]) =~ /#{ForemanRhCloud::TagsAuth::TAG_NAME}/ }[1])
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
@forwarder.forward_request(req, '/api/vulnerability/v1/cves/abc-123/affected_systems', 'test_controller', @user, @organization, @location)
|
40
|
+
|
41
|
+
# This test asserts the parameters that are sent to the execute_cloud_request method.
|
42
|
+
# This is done by setting the expectation before the actual call.
|
43
|
+
end
|
44
|
+
|
45
|
+
test 'should not scope GET requests for unknown uris' do
|
46
|
+
user_agent = { :foo => :bar }
|
47
|
+
params = {}
|
48
|
+
|
49
|
+
req = ActionDispatch::Request.new(
|
50
|
+
'REQUEST_URI' => '/api/vulnerability/foo/bar',
|
51
|
+
'REQUEST_METHOD' => 'GET',
|
52
|
+
'HTTP_USER_AGENT' => user_agent,
|
53
|
+
'rack.input' => ::Puma::NullIO.new,
|
54
|
+
'action_dispatch.request.query_parameters' => params
|
55
|
+
)
|
56
|
+
|
57
|
+
::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag).never
|
58
|
+
@forwarder.expects(:execute_cloud_request).with do |actual_params|
|
59
|
+
actual = actual_params[:headers][:params]
|
60
|
+
assert_equal 0, actual.count
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
64
|
+
@forwarder.forward_request(req, '/api/vulnerability/foo/bar', 'test_controller', @user, @organization, @location)
|
65
|
+
|
66
|
+
# This test asserts the parameters that are sent to the execute_cloud_request method.
|
67
|
+
# This is done by setting the expectation before the actual call.
|
68
|
+
end
|
69
|
+
|
70
|
+
test 'should merge URI params in GET requests' do
|
71
|
+
user_agent = { :foo => :bar }
|
72
|
+
params = { :page => 5, :per_page => 42 }
|
73
|
+
|
74
|
+
req = ActionDispatch::Request.new(
|
75
|
+
'REQUEST_URI' => '/api/vulnerability/v1/cves/abc-123/affected_systems',
|
76
|
+
'REQUEST_METHOD' => 'GET',
|
77
|
+
'HTTP_USER_AGENT' => user_agent,
|
78
|
+
'rack.input' => ::Puma::NullIO.new,
|
79
|
+
'action_dispatch.request.query_parameters' => params
|
80
|
+
)
|
81
|
+
|
82
|
+
::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag)
|
83
|
+
@forwarder.expects(:execute_cloud_request).with do |actual_params|
|
84
|
+
actual = actual_params[:headers][:params]
|
85
|
+
assert_equal "U:\"#{@user.login}\"O:\"#{@organization.name}\"L:\"#{@location.name}\"", tag_value(actual.find { |param| param[0] == :tag && tag_name(param[1]) =~ /#{ForemanRhCloud::TagsAuth::TAG_NAME}/ }[1])
|
86
|
+
assert_equal 5, actual.find { |param| param[0] == :page }[1]
|
87
|
+
assert_equal 42, actual.find { |param| param[0] == :per_page }[1]
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
@forwarder.forward_request(req, '/api/vulnerability/v1/cves/abc-123/affected_systems', 'test_controller', @user, @organization, @location)
|
92
|
+
# This test asserts the parameters that are sent to the execute_cloud_request method.
|
93
|
+
# This is done by setting the expectation before the actual call.
|
94
|
+
end
|
95
|
+
|
96
|
+
test 'should not scope POST requests' do
|
97
|
+
post_data = 'Random POST data'
|
98
|
+
req = ActionDispatch::Request.new(
|
99
|
+
'REQUEST_URI' => '/foo/bar',
|
100
|
+
'REQUEST_METHOD' => 'POST',
|
101
|
+
'rack.input' => ::Puma::NullIO.new,
|
102
|
+
'RAW_POST_DATA' => post_data
|
103
|
+
)
|
104
|
+
|
105
|
+
::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag).never
|
106
|
+
@forwarder.expects(:execute_cloud_request).with do |actual_params|
|
107
|
+
actual = actual_params[:headers][:params]
|
108
|
+
assert_equal 0, actual.count
|
109
|
+
true
|
110
|
+
end
|
111
|
+
|
112
|
+
@forwarder.forward_request(req, '/api/vulnerability/v1/cves', 'test_controller', @user, @organization, @location)
|
113
|
+
|
114
|
+
# This test asserts the parameters that are sent to the execute_cloud_request method.
|
115
|
+
# This is done by setting the expectation before the actual call.
|
116
|
+
end
|
117
|
+
|
118
|
+
test 'should not scope PUT requests' do
|
119
|
+
put_data = 'Random PUT data'
|
120
|
+
req = ActionDispatch::Request.new(
|
121
|
+
'REQUEST_URI' => '/foo/bar',
|
122
|
+
'REQUEST_METHOD' => 'PUT',
|
123
|
+
'rack.input' => ::Puma::NullIO.new,
|
124
|
+
'RAW_POST_DATA' => put_data
|
125
|
+
)
|
126
|
+
|
127
|
+
::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag).never
|
128
|
+
@forwarder.expects(:execute_cloud_request).with do |actual_params|
|
129
|
+
actual = actual_params[:headers][:params]
|
130
|
+
assert_equal 0, actual.count
|
131
|
+
true
|
132
|
+
end
|
133
|
+
|
134
|
+
@forwarder.forward_request(req, '/api/vulnerability/v1/cves', 'test_controller', @user, @organization, @location)
|
135
|
+
|
136
|
+
# This test asserts the parameters that are sent to the execute_cloud_request method.
|
137
|
+
# This is done by setting the expectation before the actual call.
|
138
|
+
end
|
139
|
+
|
140
|
+
test 'should not scope PATCH requests' do
|
141
|
+
post_data = 'Random PATCH data'
|
142
|
+
req = ActionDispatch::Request.new(
|
143
|
+
'REQUEST_URI' => '/foo/bar',
|
144
|
+
'REQUEST_METHOD' => 'PATCH',
|
145
|
+
'rack.input' => ::Puma::NullIO.new,
|
146
|
+
'RAW_POST_DATA' => post_data,
|
147
|
+
"action_dispatch.request.path_parameters" => { :format => "json" }
|
148
|
+
)
|
149
|
+
|
150
|
+
::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag).never
|
151
|
+
@forwarder.expects(:execute_cloud_request).with do |actual_params|
|
152
|
+
actual = actual_params[:headers][:params]
|
153
|
+
assert_equal 0, actual.count
|
154
|
+
true
|
155
|
+
end
|
156
|
+
|
157
|
+
@forwarder.forward_request(req, '/api/vulnerability/v1/cves', 'test_controller', @user, @organization, @location)
|
158
|
+
|
159
|
+
# This test asserts the parameters that are sent to the execute_cloud_request method.
|
160
|
+
# This is done by setting the expectation before the actual call.
|
161
|
+
end
|
162
|
+
|
163
|
+
def tag_value(param_value)
|
164
|
+
return param_value unless param_value.is_a?(String)
|
165
|
+
|
166
|
+
tag_string = CGI.unescape(param_value)
|
167
|
+
tag_string.split('=')[1]
|
168
|
+
end
|
169
|
+
|
170
|
+
def tag_name(param_value)
|
171
|
+
return param_value unless param_value.is_a?(String)
|
172
|
+
|
173
|
+
tag_string = CGI.unescape(param_value)
|
174
|
+
tag_string.split('=')[0]
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_plugin_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class TagsAuthTest < ActiveSupport::TestCase
|
5
|
+
setup do
|
6
|
+
@user = FactoryBot.build(:user)
|
7
|
+
@logger = Logger.new(IO::NULL)
|
8
|
+
@org = FactoryBot.build(:organization)
|
9
|
+
@loc = FactoryBot.build(:location)
|
10
|
+
@auth = ::ForemanRhCloud::TagsAuth.new(@user, @org, @loc, @logger)
|
11
|
+
end
|
12
|
+
|
13
|
+
test 'Generates tags update request' do
|
14
|
+
uuid1 = 'test_uuid1'
|
15
|
+
uuid2 = 'test_uuid2'
|
16
|
+
|
17
|
+
@auth.expects(:allowed_hosts).returns([uuid1, uuid2])
|
18
|
+
@auth.expects(:execute_cloud_request).with do |actual_params|
|
19
|
+
actual = JSON.parse(actual_params[:payload])
|
20
|
+
assert_includes actual['host_id_list'], uuid1
|
21
|
+
assert_includes actual['host_id_list'], uuid2
|
22
|
+
assert_equal ForemanRhCloud::TagsAuth::TAG_SHORT_NAME, actual['tags'].first['key']
|
23
|
+
assert_equal ForemanRhCloud::TagsAuth::TAG_NAMESPACE, actual['tags'].first['namespace']
|
24
|
+
assert_equal "U:\"#{@user.login}\"O:\"#{@org.name}\"L:\"#{@loc.name}\"", actual['tags'].first['value']
|
25
|
+
end
|
26
|
+
|
27
|
+
@auth.update_tag
|
28
|
+
end
|
29
|
+
end
|
@@ -64,9 +64,10 @@ class SliceGeneratorTest < ActiveSupport::TestCase
|
|
64
64
|
'dmi::system::product_name',
|
65
65
|
'dmi::chassis::asset_tag',
|
66
66
|
'insights_client::obfuscate_hostname_enabled',
|
67
|
+
'insights_client::obfuscated_hostname',
|
68
|
+
'insights_client::obfuscate_ipv4_enabled',
|
69
|
+
'insights_client::obfuscated_ipv4',
|
67
70
|
'insights_client::hostname',
|
68
|
-
'insights_client::obfuscate_ip_enabled',
|
69
|
-
'insights_client::ips',
|
70
71
|
'insights_id',
|
71
72
|
]
|
72
73
|
end
|
@@ -418,14 +419,38 @@ class SliceGeneratorTest < ActiveSupport::TestCase
|
|
418
419
|
assert_equal 1, generator.hosts_count
|
419
420
|
end
|
420
421
|
|
421
|
-
test '
|
422
|
+
test 'does not obfuscate fqdn when insights_client obfuscate_hostname_enabled fact is missing and obfuscate_inventory_hostnames setting is false' do
|
423
|
+
# Create a host and obfuscated_hostname fact, but do NOT create the obfuscate_hostname_enabled fact
|
424
|
+
obfuscated_hostname_data = [
|
425
|
+
{ 'original' => @host.fqdn, 'obfuscated' => '0dd449d0a027.example.com' },
|
426
|
+
]
|
427
|
+
obfuscated_hostname_value = JSON.generate(obfuscated_hostname_data)
|
428
|
+
FactoryBot.create(:fact_value,
|
429
|
+
fact_name: fact_names['insights_client::obfuscated_hostname'],
|
430
|
+
value: obfuscated_hostname_value,
|
431
|
+
host: @host)
|
432
|
+
# Do NOT create the 'insights_client::obfuscate_hostname_enabled' fact
|
433
|
+
|
434
|
+
batch = Host.where(id: @host.id).in_batches.first
|
435
|
+
generator = create_generator(batch)
|
436
|
+
|
437
|
+
json_str = generator.render
|
438
|
+
actual = JSON.parse(json_str.join("\n"))
|
439
|
+
|
440
|
+
assert_not_nil(actual_host = actual['hosts'].first)
|
441
|
+
assert_equal @host.fqdn, actual_host['fqdn'], "FQDN should not be obfuscated when obfuscate_hostname_enabled is missing and setting is false"
|
442
|
+
assert_not_nil(actual_facts = actual_host['facts'].first['facts'])
|
443
|
+
assert_not_equal true, actual_facts['is_hostname_obfuscated']
|
444
|
+
end
|
445
|
+
|
446
|
+
test 'generates obfuscated ip_address fields when insights-client facts are present' do
|
422
447
|
nic = FactoryBot.build(:nic_managed)
|
423
448
|
@host.interfaces << nic
|
424
449
|
|
425
|
-
FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::
|
450
|
+
FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::obfuscate_ipv4_enabled'], value: 'true', host: @host)
|
426
451
|
FactoryBot.create(
|
427
452
|
:fact_value,
|
428
|
-
fact_name: fact_names['insights_client::
|
453
|
+
fact_name: fact_names['insights_client::obfuscated_ipv4'],
|
429
454
|
value: "[{\"obfuscated\": \"10.230.230.100\", \"original\": \"#{nic.ip}\"}]",
|
430
455
|
host: @host
|
431
456
|
)
|
@@ -448,9 +473,17 @@ class SliceGeneratorTest < ActiveSupport::TestCase
|
|
448
473
|
assert_equal 1, generator.hosts_count
|
449
474
|
end
|
450
475
|
|
451
|
-
test 'obfuscates fqdn when
|
476
|
+
test 'obfuscates fqdn when insights-client facts are present' do
|
477
|
+
obfuscated_hostname_data = [
|
478
|
+
{ 'original' => @host.fqdn, 'obfuscated' => '0dd449d0a027.example.com' },
|
479
|
+
{ 'original' => 'satellite.theforeman.org', 'obfuscated' => 'host2.example.com' },
|
480
|
+
]
|
481
|
+
obfuscated_hostname_value = JSON.generate(obfuscated_hostname_data)
|
482
|
+
FactoryBot.create(:fact_value,
|
483
|
+
fact_name: fact_names['insights_client::obfuscated_hostname'],
|
484
|
+
value: obfuscated_hostname_value,
|
485
|
+
host: @host)
|
452
486
|
FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::obfuscate_hostname_enabled'], value: 'true', host: @host)
|
453
|
-
FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::hostname'], value: 'obfuscated_name', host: @host)
|
454
487
|
|
455
488
|
batch = Host.where(id: @host.id).in_batches.first
|
456
489
|
generator = create_generator(batch)
|
@@ -460,7 +493,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
|
|
460
493
|
|
461
494
|
assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
|
462
495
|
assert_not_nil(actual_host = actual['hosts'].first)
|
463
|
-
assert_equal '
|
496
|
+
assert_equal obfuscated_hostname_data.first['obfuscated'], actual_host['fqdn']
|
464
497
|
assert_equal '1234', actual_host['account']
|
465
498
|
assert_not_nil(actual_facts = actual_host['facts'].first['facts'])
|
466
499
|
assert_equal true, actual_facts['is_hostname_obfuscated']
|
@@ -487,9 +520,35 @@ class SliceGeneratorTest < ActiveSupport::TestCase
|
|
487
520
|
assert_equal 1, generator.hosts_count
|
488
521
|
end
|
489
522
|
|
490
|
-
test '
|
523
|
+
test 'obfuscates host fqdn with insights-client when setting set' do
|
524
|
+
Setting[:obfuscate_inventory_hostnames] = true
|
525
|
+
FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::hostname'], value: @host.fqdn, host: @host)
|
526
|
+
|
527
|
+
batch = Host.where(id: @host.id).in_batches.first
|
528
|
+
generator = create_generator(batch)
|
529
|
+
|
530
|
+
json_str = generator.render
|
531
|
+
actual = JSON.parse(json_str.join("\n"))
|
532
|
+
|
533
|
+
obfuscated_fqdn = Digest::SHA1.hexdigest(@host.fqdn) + '.example.com'
|
534
|
+
|
535
|
+
assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
|
536
|
+
assert_not_nil(actual_host = actual['hosts'].first)
|
537
|
+
assert_equal obfuscated_fqdn, actual_host['fqdn']
|
538
|
+
assert_equal '1234', actual_host['account']
|
539
|
+
assert_not_nil(actual_facts = actual_host['facts'].first['facts'])
|
540
|
+
assert_equal true, actual_facts['is_hostname_obfuscated']
|
541
|
+
assert_equal 1, generator.hosts_count
|
542
|
+
end
|
543
|
+
|
544
|
+
test 'does not obfuscate fqdn when host fact from insights-client has a value of false' do
|
545
|
+
obfuscated_hostname_data = [
|
546
|
+
{ 'original' => @host.fqdn, 'obfuscated' => '0dd449d0a027.example.com' },
|
547
|
+
{ 'original' => 'satellite.theforeman.org', 'obfuscated' => 'host2.example.com' },
|
548
|
+
]
|
549
|
+
obfuscated_hostname_value = JSON.generate(obfuscated_hostname_data)
|
491
550
|
FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::obfuscate_hostname_enabled'], value: 'false', host: @host)
|
492
|
-
FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::
|
551
|
+
FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::obfuscated_hostname'], value: obfuscated_hostname_value, host: @host)
|
493
552
|
|
494
553
|
batch = Host.where(id: @host.id).in_batches.first
|
495
554
|
generator = create_generator(batch)
|