foreman_rh_cloud 3.0.21.1 → 3.0.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +17 -7
  3. data/app/models/insights_client_report_status.rb +58 -0
  4. data/app/services/foreman_rh_cloud/cloud_auth.rb +12 -0
  5. data/app/services/foreman_rh_cloud/cloud_request.rb +14 -0
  6. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +1 -6
  7. data/app/services/foreman_rh_cloud/remediations_retriever.rb +1 -4
  8. data/app/subscribers/foreman_rh_cloud/insights_subscriber.rb +9 -0
  9. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +19 -0
  10. data/lib/foreman_inventory_upload/generators/slice.rb +6 -6
  11. data/lib/foreman_rh_cloud/engine.rb +4 -1
  12. data/lib/foreman_rh_cloud/version.rb +1 -1
  13. data/lib/insights_cloud/async/insights_full_sync.rb +4 -14
  14. data/lib/insights_cloud/async/insights_resolutions_sync.rb +1 -4
  15. data/lib/insights_cloud/async/insights_rules_sync.rb +2 -7
  16. data/lib/inventory_sync/async/inventory_full_sync.rb +2 -1
  17. data/lib/inventory_sync/async/inventory_scheduled_sync.rb +8 -0
  18. data/lib/inventory_sync/async/query_inventory_job.rb +1 -4
  19. data/lib/tasks/rh_cloud_inventory.rake +6 -0
  20. data/package.json +2 -2
  21. data/test/factories/inventory_upload_factories.rb +1 -1
  22. data/test/jobs/insights_full_sync_test.rb +3 -0
  23. data/test/jobs/insights_resolutions_sync_test.rb +3 -0
  24. data/test/jobs/insights_rules_sync_test.rb +3 -0
  25. data/test/jobs/inventory_full_sync_test.rb +3 -0
  26. data/test/models/insights_client_report_status_test.rb +77 -0
  27. data/test/unit/slice_generator_test.rb +66 -29
  28. data/webpack/ForemanInventoryUpload/Components/FullScreenModal/FullScreenModal.js +1 -1
  29. data/webpack/ForemanInventoryUpload/Components/FullScreenModal/__tests__/__snapshots__/FullScreenModal.test.js.snap +1 -1
  30. data/webpack/ForemanInventoryUpload/Components/FullScreenModal/fullScreenModal.scss +14 -16
  31. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButtonActions.js +28 -63
  32. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/integrations.test.js.snap +2 -3
  33. data/webpack/ForemanInventoryUpload/Components/Terminal/Terminal.js +1 -1
  34. data/webpack/ForemanInventoryUpload/Components/Terminal/__tests__/Terminal.test.js +1 -1
  35. data/webpack/ForemanInventoryUpload/Components/Terminal/__tests__/__snapshots__/Terminal.test.js.snap +2 -2
  36. data/webpack/ForemanInventoryUpload/Components/Terminal/terminal.scss +25 -27
  37. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableActions.js +19 -19
  38. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableActions.test.js.snap +14 -14
  39. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediateButton.js +1 -0
  40. data/webpack/InsightsCloudSync/InsightsCloudSync.js +4 -1
  41. data/webpack/InsightsCloudSync/InsightsCloudSyncActions.js +44 -20
  42. data/webpack/InsightsCloudSync/InsightsCloudSyncConstants.js +2 -0
  43. data/webpack/InsightsCloudSync/__tests__/__snapshots__/InsightsCloudSyncActions.test.js.snap +11 -7
  44. data/webpack/common/ForemanTasks/ForemanTasksActions.js +64 -0
  45. data/webpack/common/ForemanTasks/ForemanTasksHelpers.js +7 -0
  46. data/webpack/common/ForemanTasks/index.js +1 -0
  47. metadata +10 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d87599d8ef67eeeaa3e17e720dc990b58d4085caf7fb6491dab093c54770c8fd
4
- data.tar.gz: 04b52a7412dddf8e6829d61555ec9315c7f3856fde32e976eb8c50638082a3bc
3
+ metadata.gz: 6edd44f8ce4af74d7affca479d84e6012b8a8d363bafcab2ef95fb97eaae5eac
4
+ data.tar.gz: 865870711b1216ea512f5bc5c304f46df1f176b568e4fbb39f6e4686efa68cfb
5
5
  SHA512:
6
- metadata.gz: 4ca381e6bcbf74d21a23ae825ebb6556be1afbe98c193fb33e58ef7fee6027142a809ed79b8cbcb3c8dce95200b0bd4528d497597a1f0411f703172ce1f9c123
7
- data.tar.gz: 945faf0852d9ebce259e4da1bcebd079ef5a4fad87f503fc9ee694f4eae7e3ab36a7dc2390d54879a7da57d176aa22d8030a168d2715fe1f54a521b2258fbb37
6
+ metadata.gz: c0f841e299dd1304590bef74ade8c7b10c9f5392ce7bf164f99243c4cf9d1c68d0061dbb83281bc84123539edca21fdbbcd3bbf1f82e3234a0afd6437cca1c0d
7
+ data.tar.gz: ea5d3651236539899e42085000c4f0aa2401229aff79ef22afaee9eef5c277af38054b0e347fc17d6f119267b1b17410d610b6144883b6b19ec1bdf3ac568d98
@@ -10,27 +10,28 @@ module InsightsCloud::Api
10
10
 
11
11
  skip_after_action :log_response_body, :only => [:forward_request]
12
12
  skip_before_action :check_media_type, :only => [:forward_request]
13
+ after_action :update_host_insights_status, only: [:forward_request]
13
14
 
14
15
  # The method that "proxies" requests over to Cloud
15
16
  def forward_request
16
17
  certs = candlepin_id_cert @organization
17
- cloud_response = ::ForemanRhCloud::CloudRequestForwarder.new.forward_request(request, controller_name, @branch_id, certs)
18
+ @cloud_response = ::ForemanRhCloud::CloudRequestForwarder.new.forward_request(request, controller_name, @branch_id, certs)
18
19
 
19
- if cloud_response.code == 401
20
+ if @cloud_response.code == 401
20
21
  return render json: {
21
22
  :message => 'Authentication to the Insights Service failed.',
22
23
  :headers => {},
23
24
  }, status: :bad_gateway
24
25
  end
25
26
 
26
- if cloud_response.headers[:content_disposition]
27
- return send_data cloud_response, disposition: cloud_response.headers[:content_disposition], type: cloud_response.headers[:content_type]
27
+ if @cloud_response.headers[:content_disposition]
28
+ return send_data @cloud_response, disposition: @cloud_response.headers[:content_disposition], type: @cloud_response.headers[:content_type]
28
29
  end
29
30
 
30
- assign_header(response, cloud_response, :x_resource_count, true)
31
- assign_header(response, cloud_response, :x_rh_insights_request_id, false)
31
+ assign_header(response, @cloud_response, :x_resource_count, true)
32
+ assign_header(response, @cloud_response, :x_rh_insights_request_id, false)
32
33
 
33
- render json: cloud_response, status: cloud_response.code
34
+ render json: @cloud_response, status: @cloud_response.code
34
35
  end
35
36
 
36
37
  def branch_info
@@ -69,5 +70,14 @@ module InsightsCloud::Api
69
70
  @branch_id = cp_owner_id(@organization)
70
71
  return render_message "Branch ID not found for organization #{@organization.title}", :status => 400 unless @branch_id
71
72
  end
73
+
74
+ def update_host_insights_status
75
+ return unless request.path == '/redhat_access/r/insights/platform/ingress/v1/upload' ||
76
+ request.path.include?('/redhat_access/r/insights/uploads/')
77
+
78
+ data = @cloud_response.code.to_s.start_with?('2')
79
+ host_status = @host.get_status(InsightsClientReportStatus)
80
+ host_status.update(reported_at: Time.now.utc, status: host_status.to_status(data: data))
81
+ end
72
82
  end
73
83
  end
@@ -0,0 +1,58 @@
1
+ class InsightsClientReportStatus < HostStatus::Status
2
+ REPORT_INTERVAL = 48.hours
3
+
4
+ REPORTING = 0 # host_registration_insights = true & getting data
5
+ NO_REPORT = 1 # host_registration_insights = true & not getting data
6
+ NOT_MANAGED = 2 # host_registration_insights = false
7
+ NOT_MANAGED_WITH_DATA = 3 # host_registration_insights = false & getting data
8
+
9
+ def self.status_name
10
+ N_('Insights')
11
+ end
12
+
13
+ def to_label(_options = {})
14
+ case status
15
+ when REPORTING
16
+ N_('Reporting')
17
+ when NO_REPORT
18
+ N_('Not reporting')
19
+ when NOT_MANAGED
20
+ N_('Not reporting (not set by registration)')
21
+ when NOT_MANAGED_WITH_DATA
22
+ N_('Reporting (not set by registration)')
23
+ end
24
+ end
25
+
26
+ def to_global(_options = {})
27
+ case status
28
+ when REPORTING
29
+ ::HostStatus::Global::OK
30
+ when NO_REPORT
31
+ ::HostStatus::Global::ERROR
32
+ when NOT_MANAGED
33
+ ::HostStatus::Global::OK
34
+ when NOT_MANAGED_WITH_DATA
35
+ ::HostStatus::Global::WARN
36
+ end
37
+ end
38
+
39
+ def to_status(data: false)
40
+ if insights_param
41
+ return REPORTING if data
42
+ return in_interval? ? REPORTING : NO_REPORT
43
+ end
44
+
45
+ data ? NOT_MANAGED_WITH_DATA : NOT_MANAGED
46
+ end
47
+
48
+ private
49
+
50
+ def in_interval?
51
+ return false unless reported_at
52
+ (Time.now.utc - reported_at).to_i < REPORT_INTERVAL.to_i
53
+ end
54
+
55
+ def insights_param
56
+ host.host_params_hash.dig('host_registration_insights', :value)
57
+ end
58
+ end
@@ -2,6 +2,8 @@ module ForemanRhCloud
2
2
  module CloudAuth
3
3
  extend ActiveSupport::Concern
4
4
 
5
+ include CloudRequest
6
+
5
7
  def rh_credentials
6
8
  @rh_credentials ||= query_refresh_token
7
9
  end
@@ -24,5 +26,15 @@ module ForemanRhCloud
24
26
  Foreman::Logging.exception('Unable to authenticate using rh_cloud_token setting', e)
25
27
  raise ::Foreman::WrappedException.new(e, N_('Unable to authenticate using rh_cloud_token setting'))
26
28
  end
29
+
30
+ def execute_cloud_request(params)
31
+ final_params = {
32
+ headers: {
33
+ Authorization: "Bearer #{rh_credentials}",
34
+ },
35
+ }.deep_merge(params)
36
+
37
+ super(final_params)
38
+ end
27
39
  end
28
40
  end
@@ -0,0 +1,14 @@
1
+ module ForemanRhCloud
2
+ module CloudRequest
3
+ extend ActiveSupport::Concern
4
+
5
+ def execute_cloud_request(params)
6
+ final_params = {
7
+ verify_ssl: ForemanRhCloud.verify_ssl_method,
8
+ proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
9
+ }.deep_merge(params)
10
+
11
+ RestClient::Request.execute(final_params)
12
+ end
13
+ end
14
+ end
@@ -2,7 +2,7 @@ require 'rest-client'
2
2
 
3
3
  module ForemanRhCloud
4
4
  class CloudRequestForwarder
5
- include ::ForemanRhCloud::CloudAuth
5
+ include ForemanRhCloud::CloudRequest
6
6
 
7
7
  def forward_request(original_request, controller_name, branch_id, certs)
8
8
  forward_params = prepare_forward_params(original_request, branch_id)
@@ -22,7 +22,6 @@ module ForemanRhCloud
22
22
  def prepare_request_opts(original_request, forward_payload, forward_params, certs)
23
23
  base_params = {
24
24
  method: original_request.method,
25
- verify_ssl: ForemanRhCloud.verify_ssl_method,
26
25
  payload: forward_payload,
27
26
  headers: {
28
27
  params: forward_params,
@@ -33,10 +32,6 @@ module ForemanRhCloud
33
32
  base_params.merge(path_params(original_request.path, certs))
34
33
  end
35
34
 
36
- def execute_cloud_request(request_opts)
37
- RestClient::Request.execute request_opts
38
- end
39
-
40
35
  def prepare_forward_payload(original_request, controller_name)
41
36
  forward_payload = original_request.request_parameters[controller_name]
42
37
 
@@ -62,14 +62,11 @@ module ForemanRhCloud
62
62
  end
63
63
 
64
64
  def query_playbook
65
- RestClient::Request.execute(
65
+ execute_cloud_request(
66
66
  method: :post,
67
67
  url: InsightsCloud.playbook_url,
68
- verify_ssl: ForemanRhCloud.verify_ssl_method,
69
- proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
70
68
  headers: {
71
69
  content_type: :json,
72
- Authorization: "Bearer #{rh_credentials}",
73
70
  },
74
71
  payload: playbook_request.to_json
75
72
  )
@@ -0,0 +1,9 @@
1
+ module ForemanRhCloud
2
+ class InsightsSubscriber < ::Foreman::BaseSubscriber
3
+ def call(*args)
4
+ host = args.first.payload[:object]
5
+ host_status = host.get_status(InsightsClientReportStatus)
6
+ host_status.update(status: host_status.to_status)
7
+ end
8
+ end
9
+ 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
@@ -78,7 +78,10 @@ module ForemanRhCloud
78
78
 
79
79
  register_global_js_file 'global'
80
80
 
81
- register_custom_status(InventorySync::InventoryStatus)
81
+ register_custom_status InventorySync::InventoryStatus
82
+ register_custom_status InsightsClientReportStatus
83
+
84
+ subscribe 'host_created.event.foreman', ForemanRhCloud::InsightsSubscriber
82
85
 
83
86
  extend_page 'hosts/show' do |context|
84
87
  context.add_pagelet :main_tabs,
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '3.0.21.1'.freeze
2
+ VERSION = '3.0.22'.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
  }
@@ -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
@@ -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,6 +23,12 @@ namespace :rh_cloud_inventory do
23
23
  organizations = [ENV['organization_id']]
24
24
  base_folder = ENV['target'] || Dir.pwd
25
25
 
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
+
26
32
  unless portal_user || organizations.empty?
27
33
  puts "Must specify either portal_user or organization_id"
28
34
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreman_rh_cloud",
3
- "version": "3.0.21.1",
3
+ "version": "3.0.22",
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
+ }