foreman_rh_cloud 3.0.21 → 4.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 (61) 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/app/services/foreman_rh_cloud/cloud_auth.rb +12 -0
  12. data/app/services/foreman_rh_cloud/cloud_request.rb +14 -0
  13. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +1 -6
  14. data/app/services/foreman_rh_cloud/remediations_retriever.rb +1 -4
  15. data/config/package-lock.json.plugin +30931 -0
  16. data/config/routes.rb +19 -0
  17. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +19 -0
  18. data/lib/foreman_inventory_upload/generators/slice.rb +6 -6
  19. data/lib/foreman_rh_cloud/engine.rb +13 -7
  20. data/lib/foreman_rh_cloud/version.rb +1 -1
  21. data/lib/insights_cloud/async/insights_full_sync.rb +4 -14
  22. data/lib/insights_cloud/async/insights_resolutions_sync.rb +1 -4
  23. data/lib/insights_cloud/async/insights_rules_sync.rb +2 -7
  24. data/lib/inventory_sync/async/inventory_full_sync.rb +2 -1
  25. data/lib/inventory_sync/async/inventory_hosts_sync.rb +6 -2
  26. data/lib/inventory_sync/async/inventory_scheduled_sync.rb +12 -0
  27. data/lib/inventory_sync/async/query_inventory_job.rb +1 -4
  28. data/lib/tasks/rh_cloud_inventory.rake +8 -1
  29. data/package.json +1 -1
  30. data/test/controllers/inventory_upload/api/inventory_controller_test.rb +53 -0
  31. data/test/factories/inventory_upload_factories.rb +1 -1
  32. data/test/jobs/insights_full_sync_test.rb +3 -0
  33. data/test/jobs/insights_resolutions_sync_test.rb +3 -0
  34. data/test/jobs/insights_rules_sync_test.rb +3 -0
  35. data/test/jobs/inventory_full_sync_test.rb +3 -0
  36. data/test/jobs/inventory_hosts_sync_test.rb +265 -0
  37. data/test/jobs/inventory_scheduled_sync_test.rb +22 -0
  38. data/test/test_plugin_helper.rb +2 -1
  39. data/test/unit/slice_generator_test.rb +66 -29
  40. data/webpack/ForemanInventoryUpload/Components/FullScreenModal/FullScreenModal.js +1 -1
  41. data/webpack/ForemanInventoryUpload/Components/FullScreenModal/__tests__/__snapshots__/FullScreenModal.test.js.snap +1 -1
  42. data/webpack/ForemanInventoryUpload/Components/FullScreenModal/fullScreenModal.scss +14 -16
  43. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +11 -0
  44. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/__tests__/__snapshots__/PageDescription.test.js.snap +11 -0
  45. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButtonActions.js +28 -63
  46. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/integrations.test.js.snap +2 -3
  47. data/webpack/ForemanInventoryUpload/Components/Terminal/Terminal.js +1 -1
  48. data/webpack/ForemanInventoryUpload/Components/Terminal/__tests__/Terminal.test.js +1 -1
  49. data/webpack/ForemanInventoryUpload/Components/Terminal/__tests__/__snapshots__/Terminal.test.js.snap +2 -2
  50. data/webpack/ForemanInventoryUpload/Components/Terminal/terminal.scss +25 -27
  51. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableActions.js +19 -19
  52. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +0 -2
  53. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableActions.test.js.snap +14 -14
  54. data/webpack/InsightsCloudSync/InsightsCloudSync.js +4 -1
  55. data/webpack/InsightsCloudSync/InsightsCloudSyncActions.js +44 -20
  56. data/webpack/InsightsCloudSync/InsightsCloudSyncConstants.js +2 -0
  57. data/webpack/InsightsCloudSync/__tests__/__snapshots__/InsightsCloudSyncActions.test.js.snap +11 -7
  58. data/webpack/common/ForemanTasks/ForemanTasksActions.js +64 -0
  59. data/webpack/common/ForemanTasks/ForemanTasksHelpers.js +7 -0
  60. data/webpack/common/ForemanTasks/index.js +1 -0
  61. metadata +17 -2
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
@@ -10,6 +10,8 @@ module ForemanInventoryUpload
10
10
  CLOUD_AZURE = 'azure'
11
11
  CLOUD_ALIBABA = 'alibaba'
12
12
 
13
+ UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
14
+
13
15
  def fact_value(host, fact_name)
14
16
  value_record = host.fact_values.find do |fact_value|
15
17
  fact_value.fact_name_id == ForemanInventoryUpload::Generators::Queries.fact_names[fact_name]
@@ -104,6 +106,23 @@ module ForemanInventoryUpload
104
106
  def obfuscate_ip(ip, ips_dict)
105
107
  "10.230.230.#{ips_dict.count + 1}"
106
108
  end
109
+
110
+ def bios_uuid(host)
111
+ value = fact_value(host, 'dmi::system::uuid') || ''
112
+ uuid_value(value)
113
+ end
114
+
115
+ def uuid_value(value)
116
+ uuid_match = UUID_REGEX.match(value)
117
+ uuid_match&.to_s
118
+ end
119
+
120
+ def uuid_value!(value)
121
+ uuid = uuid_value(value)
122
+ raise Foreman::Exception.new(N_('Value %{value} is not a valid UUID') % {value: value}) if value && uuid.empty?
123
+
124
+ uuid
125
+ end
107
126
  end
108
127
  end
109
128
  end
@@ -25,7 +25,7 @@ module ForemanInventoryUpload
25
25
 
26
26
  def report_slice(hosts_batch)
27
27
  @stream.object do
28
- @stream.simple_field('report_slice_id', @slice_id)
28
+ @stream.simple_field('report_slice_id', uuid_value!(@slice_id))
29
29
  @stream.array_field('hosts', :last) do
30
30
  first = true
31
31
  hosts_batch.each do |host|
@@ -45,10 +45,10 @@ module ForemanInventoryUpload
45
45
  @stream.object do
46
46
  @stream.simple_field('fqdn', fqdn(host))
47
47
  @stream.simple_field('account', account_id(host.organization).to_s)
48
- @stream.simple_field('subscription_manager_id', host.subscription_facet&.uuid)
49
- @stream.simple_field('satellite_id', host.subscription_facet&.uuid)
50
- @stream.simple_field('bios_uuid', fact_value(host, 'dmi::system::uuid'))
51
- @stream.simple_field('vm_uuid', fact_value(host, 'virt::uuid'))
48
+ @stream.simple_field('subscription_manager_id', uuid_value!(host.subscription_facet&.uuid))
49
+ @stream.simple_field('satellite_id', uuid_value!(host.subscription_facet&.uuid))
50
+ @stream.simple_field('bios_uuid', bios_uuid(host))
51
+ @stream.simple_field('vm_uuid', uuid_value(fact_value(host, 'virt::uuid')))
52
52
  report_ip_addresses(host, host_ips_cache)
53
53
  report_mac_addresses(host)
54
54
  @stream.object_field('system_profile') do
@@ -85,7 +85,7 @@ module ForemanInventoryUpload
85
85
  @stream.object do
86
86
  @stream.simple_field('namespace', namespace)
87
87
  @stream.simple_field('key', key)
88
- @stream.simple_field('value', value, :last)
88
+ @stream.simple_field('value', value.to_s, :last)
89
89
  end
90
90
  @stream.comma unless last
91
91
  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',
@@ -133,13 +137,15 @@ module ForemanRhCloud
133
137
  )
134
138
  # skip object creation when admin user is not present, for example in test DB
135
139
  if User.unscoped.find_by_login(User::ANONYMOUS_ADMIN).present?
136
- unless ForemanTasks::RecurringLogic.joins(:tasks).merge(
137
- ForemanTasks::Task.where(label: 'InventorySync::Async::InventoryScheduledSync')
138
- ).exists?
139
- User.as_anonymous_admin do
140
- recurring_logic = ForemanTasks::RecurringLogic.new_from_cronline("0 0 * * *")
141
- recurring_logic.save!
142
- recurring_logic.start(InventorySync::Async::InventoryScheduledSync)
140
+ ::ForemanTasks.dynflow.config.on_init(false) do |world|
141
+ unless ForemanTasks::RecurringLogic.joins(:tasks).merge(
142
+ ForemanTasks::Task.where(label: 'InventorySync::Async::InventoryScheduledSync')
143
+ ).exists?
144
+ User.as_anonymous_admin do
145
+ recurring_logic = ForemanTasks::RecurringLogic.new_from_cronline("0 0 * * *")
146
+ recurring_logic.save!
147
+ recurring_logic.start(InventorySync::Async::InventoryScheduledSync)
148
+ end
143
149
  end
144
150
  end
145
151
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '3.0.21'.freeze
2
+ VERSION = '4.0.23'.freeze
3
3
  end
@@ -50,28 +50,18 @@ module InsightsCloud
50
50
  end
51
51
 
52
52
  def query_insights_hits
53
- hits_response = RestClient::Request.execute(
53
+ hits_response = execute_cloud_request(
54
54
  method: :get,
55
- url: InsightsCloud.hits_export_url,
56
- verify_ssl: ForemanRhCloud.verify_ssl_method,
57
- proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
58
- headers: {
59
- Authorization: "Bearer #{rh_credentials}",
60
- }
55
+ url: InsightsCloud.hits_export_url
61
56
  )
62
57
 
63
58
  JSON.parse(hits_response)
64
59
  end
65
60
 
66
61
  def query_insights_rules
67
- rules_response = RestClient::Request.execute(
62
+ rules_response = execute_cloud_request(
68
63
  method: :get,
69
- url: InsightsCloud.rules_url,
70
- verify_ssl: ForemanRhCloud.verify_ssl_method,
71
- proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
72
- headers: {
73
- Authorization: "Bearer #{rh_credentials}",
74
- }
64
+ url: InsightsCloud.rules_url
75
65
  )
76
66
 
77
67
  JSON.parse(rules_response)
@@ -22,14 +22,11 @@ module InsightsCloud
22
22
  private
23
23
 
24
24
  def query_insights_resolutions(rule_ids)
25
- resolutions_response = RestClient::Request.execute(
25
+ resolutions_response = execute_cloud_request(
26
26
  method: :post,
27
27
  url: InsightsCloud.resolutions_url,
28
- verify_ssl: ForemanRhCloud.verify_ssl_method,
29
- proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
30
28
  headers: {
31
29
  content_type: :json,
32
- Authorization: "Bearer #{rh_credentials}",
33
30
  },
34
31
  payload: {
35
32
  issues: rule_ids,
@@ -37,14 +37,9 @@ module InsightsCloud
37
37
  private
38
38
 
39
39
  def query_insights_rules(offset)
40
- rules_response = RestClient::Request.execute(
40
+ rules_response = execute_cloud_request(
41
41
  method: :get,
42
- url: InsightsCloud.rules_url(offset: offset),
43
- verify_ssl: ForemanRhCloud.verify_ssl_method,
44
- proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
45
- headers: {
46
- Authorization: "Bearer #{rh_credentials}",
47
- }
42
+ url: InsightsCloud.rules_url(offset: offset)
48
43
  )
49
44
 
50
45
  JSON.parse(rules_response)
@@ -24,6 +24,7 @@ module InventorySync
24
24
 
25
25
  logger.debug("Synced hosts amount: #{host_statuses[:sync]}")
26
26
  logger.debug("Disconnected hosts amount: #{host_statuses[:disconnect]}")
27
+ output[:host_statuses] = host_statuses
27
28
  end
28
29
 
29
30
  def update_statuses_batch
@@ -53,7 +54,7 @@ module InventorySync
53
54
  end
54
55
 
55
56
  def host_statuses
56
- output[:host_statuses] ||= {
57
+ @host_statuses ||= {
57
58
  sync: 0,
58
59
  disconnect: 0,
59
60
  }
@@ -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
@@ -4,6 +4,14 @@ module InventorySync
4
4
  include ::Actions::RecurringAction
5
5
 
6
6
  def plan
7
+ unless Setting[:allow_auto_inventory_upload]
8
+ logger.debug(
9
+ 'The scheduled process is disabled due to the "allow_auto_inventory_upload"
10
+ setting being set to false.'
11
+ )
12
+ return
13
+ end
14
+
7
15
  Organization.unscoped.each do |org|
8
16
  plan_org_sync(org)
9
17
  end
@@ -12,6 +20,10 @@ module InventorySync
12
20
  def plan_org_sync(org)
13
21
  plan_action InventoryFullSync, org
14
22
  end
23
+
24
+ def logger
25
+ action_logger
26
+ end
15
27
  end
16
28
  end
17
29
  end
@@ -29,13 +29,10 @@ module InventorySync
29
29
  private
30
30
 
31
31
  def query_inventory(page = 1)
32
- hosts_inventory_response = RestClient::Request.execute(
32
+ hosts_inventory_response = execute_cloud_request(
33
33
  method: :get,
34
34
  url: ForemanInventoryUpload.inventory_export_url,
35
- verify_ssl: ForemanRhCloud.verify_ssl_method,
36
- proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
37
35
  headers: {
38
- Authorization: "Bearer #{rh_credentials}",
39
36
  params: {
40
37
  per_page: 100,
41
38
  page: page,
@@ -23,8 +23,15 @@ namespace :rh_cloud_inventory do
23
23
  organizations = [ENV['organization_id']]
24
24
  base_folder = ENV['target'] || Dir.pwd
25
25
 
26
- unless portal_user || organizations.empty?
26
+ unless File.writable?(base_folder)
27
+ puts "#{base_folder} is not writable by the current process"
28
+ base_folder = Dir.mktmpdir
29
+ puts "Using #{base_folder} for the output"
30
+ end
31
+
32
+ if portal_user.empty? && organizations.empty?
27
33
  puts "Must specify either portal_user or organization_id"
34
+ return
28
35
  end
29
36
 
30
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.21",
3
+ "version": "4.0.23",
4
4
  "description": "Inventory Upload =============",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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
@@ -49,7 +49,7 @@ end
49
49
 
50
50
  FactoryBot.define do
51
51
  factory :katello_subscription_facets, :aliases => [:subscription_facet], :class => ::Katello::Host::SubscriptionFacet do
52
- sequence(:uuid) { |n| "uuid-#{n}-#{rand(500)}" }
52
+ sequence(:uuid) { |n| "00000000-%<n>04d-%<r>04d-0000-000000000000" % {n: n, r: rand(500)} }
53
53
  facts { { 'memory.memtotal' => "12 GB" } }
54
54
  end
55
55
  end
@@ -1,6 +1,9 @@
1
1
  require 'test_helper'
2
+ require 'foreman_tasks/test_helpers'
2
3
 
3
4
  class InsightsFullSyncTest < ActiveSupport::TestCase
5
+ include ForemanTasks::TestHelpers::WithInThreadExecutor
6
+
4
7
  setup do
5
8
  InsightsCloud::Async::InsightsFullSync.any_instance.stubs(:plan_rules_sync)
6
9
  InsightsCloud::Async::InsightsFullSync.any_instance.stubs(:plan_notifications)
@@ -1,6 +1,9 @@
1
1
  require 'test_helper'
2
+ require 'foreman_tasks/test_helpers'
2
3
 
3
4
  class InsightsResolutionsSyncTest < ActiveSupport::TestCase
5
+ include ForemanTasks::TestHelpers::WithInThreadExecutor
6
+
4
7
  setup do
5
8
  @resolutions = {
6
9
  "advisor:ansible_deprecated_repo|ANSIBLE_DEPRECATED_REPO" => {
@@ -1,6 +1,9 @@
1
1
  require 'test_helper'
2
+ require 'foreman_tasks/test_helpers'
2
3
 
3
4
  class InsightsRulesSyncTest < ActiveSupport::TestCase
5
+ include ForemanTasks::TestHelpers::WithInThreadExecutor
6
+
4
7
  setup do
5
8
  rules_json = <<-'RULES_JSON'
6
9
  {
@@ -1,6 +1,9 @@
1
1
  require 'test_plugin_helper'
2
+ require 'foreman_tasks/test_helpers'
2
3
 
3
4
  class InventoryFullSyncTest < ActiveSupport::TestCase
5
+ include ForemanTasks::TestHelpers::WithInThreadExecutor
6
+
4
7
  setup do
5
8
  User.current = User.find_by(login: 'secret_admin')
6
9
 
@@ -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