foreman_rh_cloud 3.0.22 → 3.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/rh_cloud/inventory_controller.rb +50 -0
  3. data/app/controllers/concerns/inventory_upload/report_actions.rb +26 -0
  4. data/app/controllers/concerns/inventory_upload/task_actions.rb +25 -0
  5. data/app/controllers/foreman_inventory_upload/reports_controller.rb +3 -1
  6. data/app/controllers/foreman_inventory_upload/tasks_controller.rb +5 -13
  7. data/app/controllers/foreman_inventory_upload/uploads_controller.rb +4 -4
  8. data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +1 -0
  9. data/app/controllers/insights_cloud/hits_controller.rb +7 -3
  10. data/app/helpers/foreman_insights_host_helper.rb +19 -0
  11. data/config/package-lock.json.plugin +32774 -0
  12. data/config/routes.rb +19 -0
  13. data/lib/foreman_rh_cloud/engine.rb +4 -0
  14. data/lib/foreman_rh_cloud/version.rb +1 -1
  15. data/lib/inventory_sync/async/inventory_hosts_sync.rb +6 -2
  16. data/lib/inventory_sync/async/inventory_scheduled_sync.rb +4 -0
  17. data/lib/tasks/rh_cloud_inventory.rake +2 -1
  18. data/package.json +2 -2
  19. data/test/controllers/inventory_upload/api/inventory_controller_test.rb +53 -0
  20. data/test/jobs/inventory_hosts_sync_test.rb +265 -0
  21. data/test/jobs/inventory_scheduled_sync_test.rb +22 -0
  22. data/test/test_plugin_helper.rb +2 -0
  23. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +11 -0
  24. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/__tests__/__snapshots__/PageDescription.test.js.snap +11 -0
  25. data/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/NoTokenEmptyState.test.js.snap +20 -13
  26. data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +2 -2
  27. metadata +14 -3
data/config/routes.rb CHANGED
@@ -40,4 +40,23 @@ Rails.application.routes.draw do
40
40
  match '/*path', :constraints => lambda { |req| !req.path.include?('view/api') }, to: 'machine_telemetries#forward_request', via: [:get, :post, :delete,:put, :patch]
41
41
  end
42
42
  end
43
+
44
+ # API routes
45
+
46
+ namespace :api, :defaults => {:format => 'json'} do
47
+ scope '(:apiv)', :module => :v2, :defaults => {:apiv => 'v2'}, :apiv => /v1|v2/, :constraints => ApiConstraints.new(:version => 2, :default => true) do
48
+ resources :organizations, :only => [:show] do
49
+ namespace 'rh_cloud' do
50
+ get 'report', to: 'inventory#download_file'
51
+ post 'report', to: 'inventory#generate_report'
52
+
53
+ post 'inventory_sync', to: 'inventory#sync_inventory_status'
54
+ end
55
+ end
56
+
57
+ namespace 'rh_cloud' do
58
+ post 'enable_connector', to: 'inventory#enable_cloud_connector'
59
+ end
60
+ end
61
+ end
43
62
  end
@@ -83,6 +83,10 @@ module ForemanRhCloud
83
83
 
84
84
  subscribe 'host_created.event.foreman', ForemanRhCloud::InsightsSubscriber
85
85
 
86
+ describe_host do
87
+ overview_buttons_provider :insights_host_overview_buttons
88
+ end
89
+
86
90
  extend_page 'hosts/show' do |context|
87
91
  context.add_pagelet :main_tabs,
88
92
  partial: 'hosts/insights_tab',
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '3.0.22'.freeze
2
+ VERSION = '3.0.23'.freeze
3
3
  end
@@ -20,14 +20,18 @@ module InventorySync
20
20
  private
21
21
 
22
22
  def add_missing_insights_facets(uuids_hash)
23
- existing_facets = InsightsFacet.where(host_id: uuids_hash.keys).pluck(:host_id)
24
- missing_facets = uuids_hash.except(*existing_facets).map do |host_id, uuid|
23
+ existing_facets = InsightsFacet.where(host_id: uuids_hash.keys).pluck(:host_id, :uuid)
24
+ missing_facets = uuids_hash.except(*existing_facets.map(&:first)).map do |host_id, uuid|
25
25
  {
26
26
  host_id: host_id,
27
27
  uuid: uuid,
28
28
  }
29
29
  end
30
30
  InsightsFacet.create(missing_facets)
31
+
32
+ existing_facets.select { |host_id, uuid| uuid.empty? }.each do |host_id, _uuid|
33
+ InsightsFacet.where(host_id: host_id).update_all(uuid: uuids_hash[host_id])
34
+ end
31
35
  end
32
36
  end
33
37
  end
@@ -20,6 +20,10 @@ module InventorySync
20
20
  def plan_org_sync(org)
21
21
  plan_action InventoryFullSync, org
22
22
  end
23
+
24
+ def logger
25
+ action_logger
26
+ end
23
27
  end
24
28
  end
25
29
  end
@@ -29,8 +29,9 @@ namespace :rh_cloud_inventory do
29
29
  puts "Using #{base_folder} for the output"
30
30
  end
31
31
 
32
- unless portal_user || organizations.empty?
32
+ if portal_user.empty? && organizations.empty?
33
33
  puts "Must specify either portal_user or organization_id"
34
+ return
34
35
  end
35
36
 
36
37
  User.as_anonymous_admin do
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreman_rh_cloud",
3
- "version": "3.0.22",
3
+ "version": "3.0.23",
4
4
  "description": "Inventory Upload =============",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -45,4 +45,4 @@
45
45
  "jed": "~1.1.1",
46
46
  "react-intl": "~2.8.0"
47
47
  }
48
- }
48
+ }
@@ -0,0 +1,53 @@
1
+ require 'test_plugin_helper'
2
+
3
+ module InventoryUpload::Api
4
+ class InventoryControllerTest < ActionController::TestCase
5
+ tests Api::V2::RhCloud::InventoryController
6
+
7
+ setup do
8
+ @test_org = FactoryBot.create(:organization)
9
+ end
10
+
11
+ test 'Starts report generation' do
12
+ Api::V2::RhCloud::InventoryController.any_instance
13
+ .expects(:start_report_generation)
14
+ .with(@test_org.id.to_s)
15
+
16
+ post :generate_report, params: { organization_id: @test_org.id }
17
+
18
+ assert_response :success
19
+ end
20
+
21
+ test 'Starts inventory sync action' do
22
+ test_task = FactoryBot.create(:some_task)
23
+
24
+ Api::V2::RhCloud::InventoryController.any_instance
25
+ .expects(:start_inventory_sync)
26
+ .with() { |actual_org| @test_org.id == actual_org.id }
27
+ .returns(test_task)
28
+
29
+ post :sync_inventory_status, params: { organization_id: @test_org.id }
30
+
31
+ assert_response :success
32
+
33
+ assert_not_nil(actual_task = @response.parsed_body['task'])
34
+ assert_equal test_task.id.to_s, actual_task['id']
35
+ end
36
+
37
+ test 'Starts cloud connector configuration job' do
38
+ test_job = FactoryBot.create(:job_invocation)
39
+
40
+ ForemanRhCloud::CloudConnector.any_instance
41
+ .expects(:install)
42
+ .returns(test_job)
43
+
44
+ post :enable_cloud_connector
45
+
46
+ assert_response :success
47
+
48
+ actual_job = @response.parsed_body
49
+
50
+ assert_equal test_job.id, actual_job['id']
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,265 @@
1
+ require 'test_plugin_helper'
2
+ require 'foreman_tasks/test_helpers'
3
+
4
+ class InventoryHostsSyncTest < ActiveSupport::TestCase
5
+ include ForemanTasks::TestHelpers::WithInThreadExecutor
6
+
7
+ setup do
8
+ User.current = User.find_by(login: 'secret_admin')
9
+
10
+ env = FactoryBot.create(:katello_k_t_environment)
11
+ cv = env.content_views << FactoryBot.create(:katello_content_view, organization: env.organization)
12
+
13
+ # this host would pass our plugin queries, so it could be uploaded to the cloud.
14
+ @host1 = FactoryBot.create(
15
+ :host,
16
+ :with_subscription,
17
+ :with_content,
18
+ content_view: cv.first,
19
+ lifecycle_environment: env,
20
+ organization: env.organization
21
+ )
22
+
23
+ pool = FactoryBot.create(:katello_pool, account_number: '1234', cp_id: 1)
24
+
25
+ @host1.subscription_facet.pools << pool
26
+
27
+ # this host would pass our plugin queries, so it could be uploaded to the cloud.
28
+ @host2 = FactoryBot.create(
29
+ :host,
30
+ :with_subscription,
31
+ :with_content,
32
+ content_view: cv.first,
33
+ lifecycle_environment: env,
34
+ organization: env.organization
35
+ )
36
+
37
+ @host2.subscription_facet.pools << pool
38
+ @host2_inventory_id = '4536bf5c-ff03-4154-a8c9-32ff4b40e40c'
39
+
40
+ ForemanInventoryUpload::Generators::Queries.instance_variable_set(:@fact_names, nil)
41
+
42
+ inventory_json = <<-INVENTORY_JSON
43
+ {
44
+ "total": 3,
45
+ "count": 3,
46
+ "page": 1,
47
+ "per_page": 3,
48
+ "results": [
49
+ {
50
+ "insights_id": "72d29d75-dbbf-4121-9566-2f581ab77f36",
51
+ "rhel_machine_id": null,
52
+ "subscription_manager_id": "#{@host2.subscription_facet.uuid}",
53
+ "satellite_id": "bb72bf95-0a19-4090-8009-f0d8c68aca61",
54
+ "bios_uuid": "b48a7e5f-cb50-4029-a75e-366bf43db641",
55
+ "ip_addresses": [
56
+ "192.168.122.56"
57
+ ],
58
+ "fqdn": "#{@host2.fqdn}",
59
+ "mac_addresses": [
60
+ "52:54:00:aa:12:12",
61
+ "00:00:00:00:00:00"
62
+ ],
63
+ "external_id": null,
64
+ "id": "#{@host2_inventory_id}",
65
+ "account": "1460290",
66
+ "display_name": "insights-rh7.example.com",
67
+ "ansible_host": null,
68
+ "facts": [
69
+ {
70
+ "namespace": "satellite",
71
+ "facts": {
72
+ "virtual_host_name": "virt-who-nobody.home-1",
73
+ "satellite_instance_id": "fc4d0cb0-a0b0-421e-b096-b028319b8e47",
74
+ "is_simple_content_access": false,
75
+ "distribution_version": "7.3",
76
+ "satellite_version": "6.8.4",
77
+ "organization_id": 1,
78
+ "is_hostname_obfuscated": false,
79
+ "virtual_host_uuid": "a90e6294-4766-420a-8dc0-3ec5b96d60ec"
80
+ }
81
+ },
82
+ {
83
+ "namespace": "yupana",
84
+ "facts": {
85
+ "report_platform_id": "d37afa50-08ce-4efb-a0e5-759c2a016661",
86
+ "report_slice_id": "5bf791d7-5e30-4a3c-929a-11dd9fa6eb72",
87
+ "source": "Satellite",
88
+ "yupana_host_id": "e85958b6-58db-4cfd-aeb6-01ee81bc0f43",
89
+ "account": "1460290"
90
+ }
91
+ }
92
+ ],
93
+ "reporter": "puptoo",
94
+ "stale_timestamp": "2021-03-19T07:57:42.466399+00:00",
95
+ "stale_warning_timestamp": "2021-03-26T07:57:42.466399+00:00",
96
+ "culled_timestamp": "2021-04-02T07:57:42.466399+00:00",
97
+ "created": "2021-02-08T14:36:03.613880+00:00",
98
+ "updated": "2021-03-18T02:57:42.535250+00:00"
99
+ },
100
+ {
101
+ "insights_id": "e0dc5144-d78e-43ed-97be-a7a21d1b6946",
102
+ "rhel_machine_id": null,
103
+ "subscription_manager_id": "0f97ee19-6862-4900-aea4-f121c8754776",
104
+ "satellite_id": "0f97ee19-6862-4900-aea4-f121c8754776",
105
+ "bios_uuid": "6a0b199a-8225-4ade-ae44-3b18cfc84a01",
106
+ "ip_addresses": [
107
+ "192.168.122.136"
108
+ ],
109
+ "fqdn": "#{@host1.fqdn}",
110
+ "mac_addresses": [
111
+ "52:54:00:02:d1:2a",
112
+ "00:00:00:00:00:00"
113
+ ],
114
+ "external_id": null,
115
+ "id": "3255d080-e6c1-44e2-8d72-b044b9a38d8f",
116
+ "account": "1460290",
117
+ "display_name": "insights-rh8.example.com",
118
+ "ansible_host": null,
119
+ "facts": [
120
+ {
121
+ "namespace": "satellite",
122
+ "facts": {
123
+ "virtual_host_name": "virt-who-nobody.home-1",
124
+ "satellite_instance_id": "fc4d0cb0-a0b0-421e-b096-b028319b8e47",
125
+ "is_simple_content_access": false,
126
+ "distribution_version": "8.3",
127
+ "satellite_version": "6.8.4",
128
+ "organization_id": 1,
129
+ "is_hostname_obfuscated": false,
130
+ "virtual_host_uuid": "a90e6294-4766-420a-8dc0-3ec5b96d60ec"
131
+ }
132
+ },
133
+ {
134
+ "namespace": "yupana",
135
+ "facts": {
136
+ "report_platform_id": "d37afa50-08ce-4efb-a0e5-759c2a016661",
137
+ "report_slice_id": "5bf791d7-5e30-4a3c-929a-11dd9fa6eb72",
138
+ "source": "Satellite",
139
+ "yupana_host_id": "78c62486-0ac4-406c-a4c0-3a1f81112a2d",
140
+ "account": "1460290"
141
+ }
142
+ }
143
+ ],
144
+ "reporter": "puptoo",
145
+ "stale_timestamp": "2021-03-19T06:05:12.092136+00:00",
146
+ "stale_warning_timestamp": "2021-03-26T06:05:12.092136+00:00",
147
+ "culled_timestamp": "2021-04-02T06:05:12.092136+00:00",
148
+ "created": "2021-02-08T13:22:50.555671+00:00",
149
+ "updated": "2021-03-18T01:05:12.131847+00:00"
150
+ },
151
+ {
152
+ "insights_id": "b533848e-465f-4f1a-9b2b-b71cb2d5239d",
153
+ "rhel_machine_id": null,
154
+ "subscription_manager_id": "d29bde40-348e-437c-8acf-8fa98320fc1b",
155
+ "satellite_id": "d29bde40-348e-437c-8acf-8fa98320fc1b",
156
+ "bios_uuid": "3cd5d972-cfb5-451a-8314-fd2f56629d7c",
157
+ "ip_addresses": [
158
+ "172.16.5.39",
159
+ "fd6e:2298:736e::857",
160
+ "fd6e:2298:736e:0:2c66:6101:9cc6:2b23"
161
+ ],
162
+ "fqdn": "rhel8-demo.oss-lab.net",
163
+ "mac_addresses": [
164
+ "6e:66:a6:fe:fc:07",
165
+ "00:00:00:00:00:00"
166
+ ],
167
+ "external_id": null,
168
+ "id": "59ab38db-c25b-4fc7-bfb2-c8eb01d865a9",
169
+ "account": "1460290",
170
+ "display_name": "rhel8-demo.oss-lab.net",
171
+ "ansible_host": null,
172
+ "facts": [
173
+ {
174
+ "namespace": "satellite",
175
+ "facts": {
176
+ "satellite_instance_id": "fb3643d8-9030-487b-b95c-684783806ffd",
177
+ "system_purpose_sla": "",
178
+ "is_simple_content_access": false,
179
+ "distribution_version": "8.3",
180
+ "satellite_version": "6.8.1",
181
+ "organization_id": 1,
182
+ "system_purpose_role": "",
183
+ "system_purpose_usage": "",
184
+ "is_hostname_obfuscated": false
185
+ }
186
+ },
187
+ {
188
+ "namespace": "yupana",
189
+ "facts": {
190
+ "report_platform_id": "fa8b924c-51ee-479d-97d2-b4623cf1d4aa",
191
+ "report_slice_id": "0b49103f-6471-4ade-ad74-a51537bc5691",
192
+ "source": "Satellite",
193
+ "yupana_host_id": "30e43340-12fb-445d-b23f-faaf5cbc2092",
194
+ "account": "1460290"
195
+ }
196
+ }
197
+ ],
198
+ "reporter": "puptoo",
199
+ "stale_timestamp": "2021-03-19T05:55:23.700781+00:00",
200
+ "stale_warning_timestamp": "2021-03-26T05:55:23.700781+00:00",
201
+ "culled_timestamp": "2021-04-02T05:55:23.700781+00:00",
202
+ "created": "2021-01-13T20:05:51.059012+00:00",
203
+ "updated": "2021-03-18T00:55:23.739162+00:00"
204
+ }
205
+ ]
206
+ }
207
+ INVENTORY_JSON
208
+ @inventory = JSON.parse(inventory_json)
209
+ end
210
+
211
+ def interesting_facts
212
+ [
213
+ 'dmi::system::uuid',
214
+ 'virt::uuid',
215
+ 'cpu::cpu(s)',
216
+ 'cpu::cpu_socket(s)',
217
+ 'cpu::core(s)_per_socket',
218
+ 'memory::memtotal',
219
+ 'dmi::bios::vendor',
220
+ 'dmi::bios::version',
221
+ 'dmi::bios::relase_date',
222
+ 'uname::release',
223
+ 'lscpu::flags',
224
+ 'distribution::name',
225
+ 'distribution::version',
226
+ 'distribution::id',
227
+ 'virt::is_guest',
228
+ 'dmi::system::manufacturer',
229
+ 'dmi::system::product_name',
230
+ 'dmi::chassis::asset_tag',
231
+ 'insights_client::obfuscate_hostname_enabled',
232
+ 'insights_client::hostname',
233
+ ]
234
+ end
235
+
236
+ def fact_names
237
+ @fact_names ||= Hash[
238
+ interesting_facts.map do |fact|
239
+ [fact, FactoryBot.create(:fact_name, name: fact, type: 'Katello::RhsmFactName')]
240
+ end
241
+ ]
242
+ end
243
+
244
+ test 'Inventory should sync UUID for existing Insights Facets' do
245
+ InventorySync::Async::InventoryHostsSync.any_instance.expects(:query_inventory).returns(@inventory)
246
+
247
+ @host2.build_insights.save
248
+
249
+ ForemanTasks.sync_task(InventorySync::Async::InventoryHostsSync)
250
+
251
+ @host2.reload
252
+
253
+ assert_equal @host2_inventory_id, @host2.insights.uuid
254
+ end
255
+
256
+ test 'Inventory should sync UUID for new Insights Facets' do
257
+ InventorySync::Async::InventoryHostsSync.any_instance.expects(:query_inventory).returns(@inventory)
258
+
259
+ ForemanTasks.sync_task(InventorySync::Async::InventoryHostsSync)
260
+
261
+ @host2.reload
262
+
263
+ assert_equal @host2_inventory_id, @host2.insights.uuid
264
+ end
265
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_plugin_helper'
2
+ require 'foreman_tasks/test_helpers'
3
+
4
+ class InventoryScheduledSyncTest < ActiveSupport::TestCase
5
+ include ForemanTasks::TestHelpers::WithInThreadExecutor
6
+
7
+ test 'Schedules an execution if auto upload is enabled' do
8
+ FactoryBot.create(:setting, :name => 'allow_auto_inventory_upload', :settings_type => "boolean", :category => "Setting::RhCloud", :default => false, :value => true)
9
+
10
+ InventorySync::Async::InventoryScheduledSync.any_instance.expects(:plan_org_sync).times(Organization.unscoped.count)
11
+
12
+ ForemanTasks.sync_task(InventorySync::Async::InventoryScheduledSync)
13
+ end
14
+
15
+ test 'Skips execution if auto upload is disabled' do
16
+ FactoryBot.create(:setting, :name => 'allow_auto_inventory_upload', :settings_type => "boolean", :category => "Setting::RhCloud", :default => false, :value => false)
17
+
18
+ InventorySync::Async::InventoryScheduledSync.any_instance.expects(:plan_org_sync).never
19
+
20
+ ForemanTasks.sync_task(InventorySync::Async::InventoryScheduledSync)
21
+ end
22
+ end
@@ -2,6 +2,8 @@
2
2
  require 'test_helper'
3
3
 
4
4
  # Add plugin to FactoryBot's paths
5
+ FactoryBot.definition_file_paths << "#{ForemanTasks::Engine.root}/test/factories"
6
+ FactoryBot.definition_file_paths << "#{ForemanRemoteExecution::Engine.root}/test/factories"
5
7
  FactoryBot.definition_file_paths << File.join(File.dirname(__FILE__), 'factories')
6
8
  # FactoryBot.definition_file_paths << "#{Katello::Engine.root}/test/factories"
7
9
  FactoryBot.reload