foreman_rh_cloud 4.0.21.1 → 4.0.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/app/services/foreman_rh_cloud/cloud_auth.rb +12 -0
  3. data/app/services/foreman_rh_cloud/cloud_request.rb +14 -0
  4. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +1 -6
  5. data/app/services/foreman_rh_cloud/remediations_retriever.rb +1 -4
  6. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +19 -0
  7. data/lib/foreman_inventory_upload/generators/slice.rb +5 -5
  8. data/lib/foreman_rh_cloud/version.rb +1 -1
  9. data/lib/insights_cloud/async/insights_full_sync.rb +4 -14
  10. data/lib/insights_cloud/async/insights_resolutions_sync.rb +1 -4
  11. data/lib/insights_cloud/async/insights_rules_sync.rb +2 -7
  12. data/lib/inventory_sync/async/inventory_full_sync.rb +2 -1
  13. data/lib/inventory_sync/async/inventory_scheduled_sync.rb +8 -0
  14. data/lib/inventory_sync/async/query_inventory_job.rb +1 -4
  15. data/lib/tasks/rh_cloud_inventory.rake +6 -0
  16. data/package.json +1 -1
  17. data/test/factories/inventory_upload_factories.rb +1 -1
  18. data/test/test_plugin_helper.rb +0 -1
  19. data/test/unit/slice_generator_test.rb +55 -27
  20. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButtonActions.js +28 -63
  21. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/integrations.test.js.snap +2 -3
  22. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableActions.js +19 -19
  23. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableActions.test.js.snap +14 -14
  24. data/webpack/InsightsCloudSync/InsightsCloudSync.js +4 -1
  25. data/webpack/InsightsCloudSync/InsightsCloudSyncActions.js +44 -20
  26. data/webpack/InsightsCloudSync/InsightsCloudSyncConstants.js +2 -0
  27. data/webpack/InsightsCloudSync/__tests__/__snapshots__/InsightsCloudSyncActions.test.js.snap +11 -7
  28. data/webpack/common/ForemanTasks/ForemanTasksActions.js +64 -0
  29. data/webpack/common/ForemanTasks/ForemanTasksHelpers.js +7 -0
  30. data/webpack/common/ForemanTasks/index.js +1 -0
  31. metadata +6 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97882071192995f2da93032050b9ecdfa616dba407c8d032bfd29f6741ea9d56
4
- data.tar.gz: 88bca49cea9ee2abac2d2dc9d608a33329ad9e214d57035424e8e24984691537
3
+ metadata.gz: ea5629e755a80131b35cb1509ff5d44fefccbe70c0362829e7d7c0f1d9f2484d
4
+ data.tar.gz: b1e1ded88509739b56711a97aa81797592d5b4ec8b32cb811ad9d6a280adfb57
5
5
  SHA512:
6
- metadata.gz: 67dd2ada55ac862b2d57ddf893e7408d002c40c2f89a141e6bf8c115d6eeee32d19b156e7668751f591665f948fa04d628719e5f6f5ab9e4609c02f0a14a93f4
7
- data.tar.gz: 54ded7bb163e4a38cd3fa4a62dfe101484b98e87c016514b985190f77a07c7556e980dd8574dc5fb70cacb3fcc521a37a1f4f2325e5360cdbb2ddd6f38816804
6
+ metadata.gz: 1ac6593a54fd506e2a8bb690bc4c6e046f92fea706333c77a54f9472b4977fd88201e2d13852f15418e326cee9961b25f31ef9cfda4703cc88f29c84d63a6459
7
+ data.tar.gz: '02649cb1f8b0e11d6570988f3cafe55e82d14bad6f133f5cf691c396b542156e0e2c2e132d0eb38a11bb421d14e5d31757e630ba463052cd4cbf71c701564fc7'
@@ -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
  )
@@ -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
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '4.0.21.1'.freeze
2
+ VERSION = '4.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": "4.0.21.1",
3
+ "version": "4.0.22",
4
4
  "description": "Inventory Upload =============",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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
@@ -33,7 +33,6 @@ module KatelloLocationFix
33
33
  FactoryBot.create(:setting, name: 'default_location_subscribed_hosts')
34
34
  FactoryBot.create(:setting, name: 'default_location_puppet_content')
35
35
  Setting[:default_location_subscribed_hosts] = Location.first.title
36
- Setting[:default_location_puppet_content] = Location.first.title
37
36
  end
38
37
  end
39
38
  end
@@ -71,7 +71,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
71
71
  json_str = generator.render
72
72
  actual = JSON.parse(json_str.join("\n"))
73
73
 
74
- assert_equal 'slice_123', actual['report_slice_id']
74
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
75
75
  assert_not_nil(actual_host = actual['hosts'].first)
76
76
  assert_nil actual_host['ip_addresses']
77
77
  assert_nil actual_host['mac_addresses']
@@ -102,7 +102,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
102
102
  json_str = generator.render
103
103
  actual = JSON.parse(json_str.join("\n"))
104
104
 
105
- assert_equal 'slice_123', actual['report_slice_id']
105
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
106
106
  assert_not_nil(actual_host = actual['hosts'].first)
107
107
  assert_not_nil(actual_system_profile = actual_host['system_profile'])
108
108
  assert_equal 4, actual_system_profile['number_of_cpus']
@@ -120,7 +120,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
120
120
  json_str = generator.render
121
121
  actual = JSON.parse(json_str.join("\n"))
122
122
 
123
- assert_equal 'slice_123', actual['report_slice_id']
123
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
124
124
  assert_not_nil(actual_host = actual['hosts'].first)
125
125
  assert_equal @host.interfaces.where.not(ip: nil).first.ip, actual_host['ip_addresses'].first
126
126
  assert_equal @host.interfaces.where.not(mac: nil).first.mac, actual_host['mac_addresses'].first
@@ -142,7 +142,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
142
142
  json_str = generator.render
143
143
  actual = JSON.parse(json_str.join("\n"))
144
144
 
145
- assert_equal 'slice_123', actual['report_slice_id']
145
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
146
146
  assert_not_nil(actual_host = actual['hosts'].first)
147
147
  assert_equal @host.interfaces.where.not(ip: nil).first.ip, actual_host['ip_addresses'].first
148
148
  assert_equal @host.interfaces.where.not(mac: nil).first.mac, actual_host['mac_addresses'].first
@@ -172,7 +172,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
172
172
  json_str = generator.render
173
173
  actual = JSON.parse(json_str.join("\n"))
174
174
 
175
- assert_equal 'slice_123', actual['report_slice_id']
175
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
176
176
  assert_not_nil(actual_host = actual['hosts'].first)
177
177
  assert_equal @host.interfaces.where.not(ip: nil).first.ip, actual_host['ip_addresses'].first
178
178
  assert_equal @host.interfaces.where.not(mac: nil).first.mac, actual_host['mac_addresses'].first
@@ -191,7 +191,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
191
191
  json_str = generator.render
192
192
  actual = JSON.parse(json_str.join("\n"))
193
193
 
194
- assert_equal 'slice_123', actual['report_slice_id']
194
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
195
195
  assert_not_nil(actual_host = actual['hosts'].first)
196
196
  assert_equal '10.230.230.1', actual_host['ip_addresses'].first
197
197
  assert_not_nil(actual_system_profile = actual_host['system_profile'])
@@ -221,7 +221,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
221
221
  json_str = generator.render
222
222
  actual = JSON.parse(json_str.join("\n"))
223
223
 
224
- assert_equal 'slice_123', actual['report_slice_id']
224
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
225
225
  assert_not_nil(actual_host = actual['hosts'].first)
226
226
  assert_equal '10.230.230.100', actual_host['ip_addresses'].first
227
227
  assert_not_nil(actual_system_profile = actual_host['system_profile'])
@@ -243,7 +243,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
243
243
  json_str = generator.render
244
244
  actual = JSON.parse(json_str.join("\n"))
245
245
 
246
- assert_equal 'slice_123', actual['report_slice_id']
246
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
247
247
  assert_not_nil(actual_host = actual['hosts'].first)
248
248
  assert_equal 'obfuscated_name', actual_host['fqdn']
249
249
  assert_equal '1234', actual_host['account']
@@ -263,7 +263,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
263
263
 
264
264
  obfuscated_fqdn = Digest::SHA1.hexdigest(@host.fqdn) + '.example.com'
265
265
 
266
- assert_equal 'slice_123', actual['report_slice_id']
266
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
267
267
  assert_not_nil(actual_host = actual['hosts'].first)
268
268
  assert_equal obfuscated_fqdn, actual_host['fqdn']
269
269
  assert_equal '1234', actual_host['account']
@@ -282,7 +282,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
282
282
  json_str = generator.render
283
283
  actual = JSON.parse(json_str.join("\n"))
284
284
 
285
- assert_equal 'slice_123', actual['report_slice_id']
285
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
286
286
  assert_not_nil(actual_host = actual['hosts'].first)
287
287
  assert_equal @host.fqdn, actual_host['fqdn']
288
288
  assert_equal '1234', actual_host['account']
@@ -355,7 +355,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
355
355
  json_str = generator.render
356
356
  actual = JSON.parse(json_str.join("\n"))
357
357
 
358
- assert_equal 'slice_123', actual['report_slice_id']
358
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
359
359
  assert_not_nil(actual_host = actual['hosts'].first)
360
360
  assert_equal @host.fqdn, actual_host['fqdn']
361
361
  assert_not_nil(host_facts = actual_host['facts']&.first)
@@ -377,7 +377,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
377
377
  json_str = generator.render
378
378
  actual = JSON.parse(json_str.join("\n"))
379
379
 
380
- assert_equal 'slice_123', actual['report_slice_id']
380
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
381
381
  assert_not_nil(actual_host = actual['hosts'].first)
382
382
  assert_equal @host.fqdn, actual_host['fqdn']
383
383
  assert_not_nil(host_facts = actual_host['facts']&.first)
@@ -397,7 +397,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
397
397
  json_str = generator.render
398
398
  actual = JSON.parse(json_str.join("\n"))
399
399
 
400
- assert_equal 'slice_123', actual['report_slice_id']
400
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
401
401
  assert_not_nil(actual_host = actual['hosts'].first)
402
402
  assert_equal @host.fqdn, actual_host['fqdn']
403
403
  assert_equal '1234', actual_host['account']
@@ -417,7 +417,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
417
417
  json_str = generator.render
418
418
  actual = JSON.parse(json_str.join("\n"))
419
419
 
420
- assert_equal 'slice_123', actual['report_slice_id']
420
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
421
421
  assert_not_nil(actual_host = actual['hosts'].first)
422
422
  assert_equal @host.fqdn, actual_host['fqdn']
423
423
  assert_equal '1234', actual_host['account']
@@ -436,7 +436,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
436
436
  json_str = generator.render
437
437
  actual = JSON.parse(json_str.join("\n"))
438
438
 
439
- assert_equal 'slice_123', actual['report_slice_id']
439
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
440
440
  assert_equal 1, generator.hosts_count
441
441
  end
442
442
 
@@ -449,7 +449,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
449
449
  json_str = generator.render
450
450
  actual = JSON.parse(json_str.join("\n"))
451
451
 
452
- assert_equal 'slice_123', actual['report_slice_id']
452
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
453
453
  assert_not_nil(actual_host = actual['hosts'].first)
454
454
  assert_not_nil(actual_profile = actual_host['system_profile'])
455
455
  assert_equal 1024, actual_profile['system_memory_bytes']
@@ -475,7 +475,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
475
475
  json_str = generator.render
476
476
  actual = JSON.parse(json_str.join("\n"))
477
477
 
478
- assert_equal 'slice_123', actual['report_slice_id']
478
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
479
479
  assert_not_nil(actual_host = actual['hosts'].first)
480
480
  assert_not_nil(actual_host['account'])
481
481
  assert_not_empty(actual_host['account'])
@@ -492,7 +492,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
492
492
  json_str = generator.render
493
493
  actual = JSON.parse(json_str.join("\n"))
494
494
 
495
- assert_equal 'slice_123', actual['report_slice_id']
495
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
496
496
  assert_not_nil(actual_host = actual['hosts'].first)
497
497
  assert_not_nil(actual_profile = actual_host['system_profile'])
498
498
  assert_equal 'Red Hat Test Linux 7.1 (TestId)', actual_profile['os_release']
@@ -507,7 +507,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
507
507
  json_str = generator.render
508
508
  actual = JSON.parse(json_str.join("\n"))
509
509
 
510
- assert_equal 'slice_123', actual['report_slice_id']
510
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
511
511
  assert_not_nil(actual_host = actual['hosts'].first)
512
512
  assert_not_nil(actual_profile = actual_host['system_profile'])
513
513
  assert_equal 'virtual', actual_profile['infrastructure_type']
@@ -522,7 +522,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
522
522
  json_str = generator.render
523
523
  actual = JSON.parse(json_str.join("\n"))
524
524
 
525
- assert_equal 'slice_123', actual['report_slice_id']
525
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
526
526
  assert_not_nil(actual_host = actual['hosts'].first)
527
527
  assert_not_nil(actual_profile = actual_host['system_profile'])
528
528
  assert_equal 'physical', actual_profile['infrastructure_type']
@@ -537,7 +537,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
537
537
  json_str = generator.render
538
538
  actual = JSON.parse(json_str.join("\n"))
539
539
 
540
- assert_equal 'slice_123', actual['report_slice_id']
540
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
541
541
  assert_not_nil(actual_host = actual['hosts'].first)
542
542
  assert_not_nil(actual_profile = actual_host['system_profile'])
543
543
  assert_equal 'aws', actual_profile['cloud_provider']
@@ -552,7 +552,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
552
552
  json_str = generator.render
553
553
  actual = JSON.parse(json_str.join("\n"))
554
554
 
555
- assert_equal 'slice_123', actual['report_slice_id']
555
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
556
556
  assert_not_nil(actual_host = actual['hosts'].first)
557
557
  assert_not_nil(actual_profile = actual_host['system_profile'])
558
558
  assert_equal 'google', actual_profile['cloud_provider']
@@ -567,7 +567,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
567
567
  json_str = generator.render
568
568
  actual = JSON.parse(json_str.join("\n"))
569
569
 
570
- assert_equal 'slice_123', actual['report_slice_id']
570
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
571
571
  assert_not_nil(actual_host = actual['hosts'].first)
572
572
  assert_not_nil(actual_profile = actual_host['system_profile'])
573
573
  assert_equal 'azure', actual_profile['cloud_provider']
@@ -582,7 +582,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
582
582
  json_str = generator.render
583
583
  actual = JSON.parse(json_str.join("\n"))
584
584
 
585
- assert_equal 'slice_123', actual['report_slice_id']
585
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
586
586
  assert_not_nil(actual_host = actual['hosts'].first)
587
587
  assert_not_nil(actual_profile = actual_host['system_profile'])
588
588
  assert_equal 'alibaba', actual_profile['cloud_provider']
@@ -597,7 +597,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
597
597
  json_str = generator.render
598
598
  actual = JSON.parse(json_str.join("\n"))
599
599
 
600
- assert_equal 'slice_123', actual['report_slice_id']
600
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
601
601
  assert_not_nil(actual_host = actual['hosts'].first)
602
602
  assert_not_nil(actual_profile = actual_host['system_profile'])
603
603
  assert_equal 'alibaba', actual_profile['cloud_provider']
@@ -623,15 +623,43 @@ class SliceGeneratorTest < ActiveSupport::TestCase
623
623
  json_str = generator.render
624
624
  actual = JSON.parse(json_str.join("\n"))
625
625
 
626
- assert_equal 'slice_123', actual['report_slice_id']
626
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
627
627
  assert_not_nil(actual_host = actual['hosts'].first)
628
628
  assert_not_nil(actual_profile = actual_host['system_profile'])
629
629
  assert_not_nil(actual_profile['installed_packages'])
630
630
  end
631
631
 
632
+ test 'omits malformed bios_uuid field' do
633
+ FactoryBot.create(:fact_value, fact_name: fact_names['dmi::system::uuid'], value: 'test value', host: @host)
634
+
635
+ batch = Host.where(id: @host.id).in_batches.first
636
+ generator = create_generator(batch)
637
+
638
+ json_str = generator.render
639
+ actual = JSON.parse(json_str.join("\n"))
640
+
641
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
642
+ assert_not_nil(actual_host = actual['hosts'].first)
643
+ assert_nil actual_host['bios_uuid']
644
+ end
645
+
646
+ test 'passes valid bios_uuid field' do
647
+ FactoryBot.create(:fact_value, fact_name: fact_names['dmi::system::uuid'], value: 'D30B0B42-7824-2635-C62D-491394DE43F7', host: @host)
648
+
649
+ batch = Host.where(id: @host.id).in_batches.first
650
+ generator = create_generator(batch)
651
+
652
+ json_str = generator.render
653
+ actual = JSON.parse(json_str.join("\n"))
654
+
655
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
656
+ assert_not_nil(actual_host = actual['hosts'].first)
657
+ assert_not_nil actual_host['bios_uuid']
658
+ end
659
+
632
660
  private
633
661
 
634
- def create_generator(batch, name = 'slice_123')
662
+ def create_generator(batch, name = '00000000-0000-0000-0000-000000000000')
635
663
  generator = ForemanInventoryUpload::Generators::Slice.new(batch, [], name)
636
664
  if block_given?
637
665
  yield(generator)
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
- import { get, post } from 'foremanReact/redux/API';
3
- import { withInterval } from 'foremanReact/redux/middlewares/IntervalMiddleware';
2
+ import { post } from 'foremanReact/redux/API';
4
3
  import { addToast } from 'foremanReact/redux/actions/toasts';
5
4
  import { translate as __ } from 'foremanReact/common/I18n';
6
5
  import { inventoryUrl } from '../../../../ForemanInventoryHelpers';
@@ -9,7 +8,10 @@ import {
9
8
  INVENTORY_SYNC,
10
9
  INVENTORY_SYNC_TASK_UPDATE,
11
10
  } from './SyncButtonConstants';
12
- import { foremanUrl } from '../../../../../ForemanRhCloudHelpers';
11
+ import {
12
+ setupTaskPolling,
13
+ taskRelatedToast,
14
+ } from '../../../../../common/ForemanTasks';
13
15
 
14
16
  export const handleSync = () => dispatch => {
15
17
  dispatch(
@@ -21,9 +23,9 @@ export const handleSync = () => dispatch => {
21
23
  task: { id },
22
24
  },
23
25
  }) => {
24
- dispatch(getSyncTaskInterval(id));
26
+ dispatch(setupInventorySyncTaskPolling(id, dispatch));
25
27
  return dispatch(
26
- taskPageRefererToast(id, 'info', __('Inventory sync has started:'))
28
+ taskRelatedToast(id, 'info', __('Inventory sync has started:'))
27
29
  );
28
30
  },
29
31
  errorToast: inventorySyncErrorToast,
@@ -31,62 +33,25 @@ export const handleSync = () => dispatch => {
31
33
  );
32
34
  };
33
35
 
34
- export const getSyncTaskInterval = id => dispatch => {
35
- dispatch(
36
- withInterval(
37
- get({
38
- key: INVENTORY_SYNC_TASK_UPDATE,
39
- url: inventoryUrl(`tasks/${id}`),
40
- handleSuccess: ({ data: { result, output } }, stopTaskInterval) => {
41
- if (result === 'success') {
42
- const {
43
- host_statuses: { sync, disconnect },
44
- } = output;
45
- dispatch(
46
- addToast({
47
- sticky: true,
48
- type: 'success',
49
- message: (
50
- <Toast syncHosts={sync} disconnectHosts={disconnect} />
51
- ),
52
- })
53
- );
54
- }
55
- if (result === 'error') {
56
- dispatch(
57
- taskPageRefererToast(
58
- id,
59
- 'error',
60
- __('Inventory sync has failed:'),
61
- true
62
- )
63
- );
64
- }
65
- stopTaskInterval();
66
- },
67
- errorToast: inventorySyncErrorToast,
68
- })
69
- )
70
- );
71
- };
72
-
73
- const inventorySyncErrorToast = ({ message, response }) =>
74
- `${__('Inventory sync has failed: ')} ${response.data?.message || message}`;
75
-
76
- const taskPageRefererToast = (taskID, toastType, prefix, sticky = false) =>
77
- addToast({
78
- sticky,
79
- type: toastType,
80
- message: (
81
- <span>
82
- {prefix}{' '}
83
- <a
84
- target="_blank"
85
- rel="noopener noreferrer"
86
- href={foremanUrl(`/foreman_tasks/tasks/${taskID}`)}
87
- >
88
- {__('view the task page for more details')}
89
- </a>
90
- </span>
91
- ),
36
+ export const setupInventorySyncTaskPolling = (id, dispatch) =>
37
+ setupTaskPolling({
38
+ taskId: id,
39
+ key: INVENTORY_SYNC_TASK_UPDATE,
40
+ onTaskSuccess: ({
41
+ output: {
42
+ host_statuses: { sync, disconnect },
43
+ },
44
+ }) =>
45
+ dispatch(
46
+ addToast({
47
+ sticky: true,
48
+ type: 'success',
49
+ message: <Toast syncHosts={sync} disconnectHosts={disconnect} />,
50
+ })
51
+ ),
52
+ dispatch,
92
53
  });
54
+
55
+ const inventorySyncErrorToast = message =>
56
+ `${__('Inventory sync has failed: ')} ${message.response?.data?.message ||
57
+ message}`;
@@ -22,7 +22,7 @@ Array [
22
22
  "errorToast": [Function],
23
23
  "interval": 3000,
24
24
  "type": "API_GET",
25
- "url": "/foreman_inventory_upload/tasks/1",
25
+ "url": "/foreman_tasks/api/tasks/1/details?include_permissions",
26
26
  },
27
27
  ],
28
28
  Array [
@@ -31,7 +31,7 @@ Array [
31
31
  "message": Object {
32
32
  "message": <span>
33
33
  Inventory sync has started:
34
-
34
+ <br />
35
35
  <a
36
36
  href="/foreman_tasks/tasks/1"
37
37
  rel="noopener noreferrer"
@@ -40,7 +40,6 @@ Array [
40
40
  view the task page for more details
41
41
  </a>
42
42
  </span>,
43
- "sticky": false,
44
43
  "type": "info",
45
44
  },
46
45
  },
@@ -19,25 +19,6 @@ export const fetchInsights = (queryParams = {}) => (dispatch, getState) => {
19
19
  ...queryParams,
20
20
  };
21
21
 
22
- dispatch(
23
- get({
24
- key: INSIGHTS_HITS_API_KEY,
25
- url: INSIGHTS_HITS_PATH,
26
- params: {
27
- page,
28
- per_page: perPage,
29
- search: query,
30
- order: `${sortBy} ${sortOrder}`,
31
- },
32
- handleSuccess: response => {
33
- if (isSelectAll) {
34
- selectAllIds(dispatch, response.data.hits || []);
35
- dispatch(selectAll());
36
- }
37
- },
38
- })
39
- );
40
-
41
22
  const uri = new URI();
42
23
  uri.search({
43
24
  page,
@@ -58,6 +39,25 @@ export const fetchInsights = (queryParams = {}) => (dispatch, getState) => {
58
39
  if (!isSelectAll) {
59
40
  dispatch(setSelectAllAlert(false));
60
41
  }
42
+
43
+ return dispatch(
44
+ get({
45
+ key: INSIGHTS_HITS_API_KEY,
46
+ url: INSIGHTS_HITS_PATH,
47
+ params: {
48
+ page,
49
+ per_page: perPage,
50
+ search: query,
51
+ order: `${sortBy} ${sortOrder}`,
52
+ },
53
+ handleSuccess: response => {
54
+ if (isSelectAll) {
55
+ selectAllIds(dispatch, response.data.hits || []);
56
+ dispatch(selectAll());
57
+ }
58
+ },
59
+ })
60
+ );
61
61
  };
62
62
 
63
63
  const selectAllIds = (dispatch, results, prevSelectedIds = {}) => {
@@ -26,6 +26,20 @@ Array [
26
26
 
27
27
  exports[`insights table actions should fetchInsights 1`] = `
28
28
  Array [
29
+ Array [
30
+ Object {
31
+ "payload": Object {
32
+ "args": Array [
33
+ Object {
34
+ "pathname": "/foreman_rh_cloud/insights_cloud",
35
+ "search": "?page=2&per_page=7&search=&sort_by=&sort_order=&select_all=true",
36
+ },
37
+ ],
38
+ "method": "push",
39
+ },
40
+ "type": "@@router/CALL_HISTORY_METHOD",
41
+ },
42
+ ],
29
43
  Array [
30
44
  Object {
31
45
  "payload": Object {
@@ -61,20 +75,6 @@ Array [
61
75
  "url": "/insights_cloud/hits",
62
76
  },
63
77
  ],
64
- Array [
65
- Object {
66
- "payload": Object {
67
- "args": Array [
68
- Object {
69
- "pathname": "/foreman_rh_cloud/insights_cloud",
70
- "search": "?page=2&per_page=7&search=&sort_by=&sort_order=&select_all=true",
71
- },
72
- ],
73
- "method": "push",
74
- },
75
- "type": "@@router/CALL_HISTORY_METHOD",
76
- },
77
- ],
78
78
  ]
79
79
  `;
80
80
 
@@ -36,7 +36,10 @@ const InsightsCloudSync = ({
36
36
  toolbarButtons={
37
37
  <>
38
38
  <RemediationModal />
39
- <Button variant="secondary" onClick={syncInsights}>
39
+ <Button
40
+ variant="secondary"
41
+ onClick={() => syncInsights(fetchInsights, query)}
42
+ >
40
43
  {__('Start recommendations sync')}
41
44
  </Button>
42
45
  </>
@@ -1,25 +1,49 @@
1
- import React from 'react';
2
1
  import { post } from 'foremanReact/redux/API';
3
2
  import { translate as __ } from 'foremanReact/common/I18n';
4
3
  import { insightsCloudUrl } from './InsightsCloudSyncHelpers';
5
- import { INSIGHTS_CLOUD_SYNC } from './InsightsCloudSyncConstants';
6
- import { foremanUrl } from '../ForemanRhCloudHelpers';
4
+ import {
5
+ INSIGHTS_CLOUD_SYNC,
6
+ INSIGHTS_CLOUD_SYNC_TASK,
7
+ } from './InsightsCloudSyncConstants';
8
+ import { setupTaskPolling, taskRelatedToast } from '../common/ForemanTasks';
7
9
 
8
- export const syncInsights = () =>
9
- post({
10
- key: INSIGHTS_CLOUD_SYNC,
11
- url: insightsCloudUrl('tasks'),
12
- successToast: response => (
13
- <span>
14
- {__('Recommendation sync has started: ')}
15
- <a
16
- target="_blank"
17
- rel="noopener noreferrer"
18
- href={foremanUrl(`/foreman_tasks/tasks/${response.data?.task?.id}`)}
19
- >
20
- {__('view the task in progress')}
21
- </a>
22
- </span>
23
- ),
24
- errorToast: error => `${__('Recommendation sync has failed: ')} ${error}`,
10
+ export const syncInsights = (fetchInsights, query) => dispatch =>
11
+ dispatch(
12
+ post({
13
+ key: INSIGHTS_CLOUD_SYNC,
14
+ url: insightsCloudUrl('tasks'),
15
+ handleSuccess: ({
16
+ data: {
17
+ task: { id },
18
+ },
19
+ }) => {
20
+ dispatch(syncInsightsStartedToast(id));
21
+ dispatch(setupInsightsTaskPolling(id, fetchInsights, query, dispatch));
22
+ },
23
+ errorToast: error => syncInsightsError(error),
24
+ })
25
+ );
26
+
27
+ const syncInsightsError = error =>
28
+ `${__('Recommendation sync has failed: ')} ${error}`;
29
+
30
+ const syncInsightsStartedToast = taskId =>
31
+ taskRelatedToast(taskId, 'info', __('Recommendation sync has started: '));
32
+
33
+ const setupInsightsTaskPolling = (taskId, fetchInsights, query, dispatch) =>
34
+ setupTaskPolling({
35
+ taskId,
36
+ key: INSIGHTS_CLOUD_SYNC_TASK,
37
+ onTaskSuccess: () => {
38
+ fetchInsights({ query, page: 1 });
39
+ dispatch(
40
+ taskRelatedToast(
41
+ taskId,
42
+ 'success',
43
+ __('Recommendations synced successfully')
44
+ )
45
+ );
46
+ },
47
+ taskErrorMessage: data => syncInsightsError(data.humanized.errors),
48
+ dispatch,
25
49
  });
@@ -4,6 +4,8 @@ import { foremanUrl } from '../ForemanRhCloudHelpers';
4
4
 
5
5
  export const INSIGHTS_CLOUD_SYNC = 'INSIGHTS_CLOUD_SYNC';
6
6
 
7
+ export const INSIGHTS_CLOUD_SYNC_TASK = 'INSIGHTS_CLOUD_SYNC_TASK';
8
+
7
9
  export const INSIGHTS_SYNC_PAGE_TITLE = __('Red Hat Insights');
8
10
 
9
11
  export const INSIGHTS_PATH = foremanUrl('/foreman_rh_cloud/insights_cloud');
@@ -1,11 +1,15 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`Insights cloud sync actions should syncInsights 1`] = `
4
- Object {
5
- "errorToast": [Function],
6
- "key": "INSIGHTS_CLOUD_SYNC",
7
- "successToast": [Function],
8
- "type": "post-some-type",
9
- "url": "/insights_cloud/tasks",
10
- }
4
+ Array [
5
+ Array [
6
+ Object {
7
+ "errorToast": [Function],
8
+ "handleSuccess": [Function],
9
+ "key": "INSIGHTS_CLOUD_SYNC",
10
+ "type": "post-some-type",
11
+ "url": "/insights_cloud/tasks",
12
+ },
13
+ ],
14
+ ]
11
15
  `;
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ import { get } from 'foremanReact/redux/API';
3
+ import { withInterval } from 'foremanReact/redux/middlewares/IntervalMiddleware';
4
+ import { addToast } from 'foremanReact/redux/actions/toasts';
5
+ import { translate as __ } from 'foremanReact/common/I18n';
6
+ import { foremanTaskDetailsUrl } from './ForemanTasksHelpers';
7
+ import { foremanUrl } from '../../ForemanRhCloudHelpers';
8
+
9
+ export const setupTaskPolling = ({
10
+ taskId,
11
+ key,
12
+ onTaskSuccess,
13
+ onTaskError,
14
+ taskErrorMessage,
15
+ dispatch,
16
+ }) =>
17
+ withInterval(
18
+ get({
19
+ key,
20
+ url: foremanTaskDetailsUrl(taskId),
21
+ handleSuccess: ({ data }, stopTaskInterval) => {
22
+ if (data.result === 'success') {
23
+ stopTaskInterval();
24
+ onTaskSuccess(data, dispatch);
25
+ }
26
+ if (data.result === 'error') {
27
+ stopTaskInterval();
28
+ if (taskErrorMessage === undefined) {
29
+ taskErrorMessage = errorData =>
30
+ `${__('The task failed with the following error:')} ${
31
+ errorData.humanized.errors
32
+ }`;
33
+ }
34
+ if (onTaskError === undefined) {
35
+ onTaskError = errorData =>
36
+ dispatch(defaultTaskErrorHandler(errorData, taskErrorMessage));
37
+ }
38
+ onTaskError(data, dispatch);
39
+ }
40
+ },
41
+ errorToast: error => `Could not get task details: ${error}`,
42
+ })
43
+ );
44
+
45
+ export const taskRelatedToast = (taskID, type, message) =>
46
+ addToast({
47
+ type,
48
+ message: (
49
+ <span>
50
+ {message}
51
+ <br />
52
+ <a
53
+ target="_blank"
54
+ rel="noopener noreferrer"
55
+ href={foremanUrl(`/foreman_tasks/tasks/${taskID}`)}
56
+ >
57
+ {__('view the task page for more details')}
58
+ </a>
59
+ </span>
60
+ ),
61
+ });
62
+
63
+ const defaultTaskErrorHandler = (data, taskErrorMessage) =>
64
+ taskRelatedToast(data.id, 'error', taskErrorMessage(data));
@@ -0,0 +1,7 @@
1
+ import { foremanUrl } from '../../ForemanRhCloudHelpers';
2
+
3
+ export const foremanTasksApiPath = path =>
4
+ foremanUrl(`/foreman_tasks/api/tasks/${path}`);
5
+
6
+ export const foremanTaskDetailsUrl = id =>
7
+ foremanTasksApiPath(`${id}/details?include_permissions`);
@@ -0,0 +1 @@
1
+ export { setupTaskPolling, taskRelatedToast } from './ForemanTasksActions';
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_rh_cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.21.1
4
+ version: 4.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Foreman Red Hat Cloud team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-06 00:00:00.000000000 Z
11
+ date: 2021-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: katello
@@ -172,6 +172,7 @@ files:
172
172
  - app/services/foreman_rh_cloud/branch_info.rb
173
173
  - app/services/foreman_rh_cloud/cloud_auth.rb
174
174
  - app/services/foreman_rh_cloud/cloud_connector.rb
175
+ - app/services/foreman_rh_cloud/cloud_request.rb
175
176
  - app/services/foreman_rh_cloud/cloud_request_forwarder.rb
176
177
  - app/services/foreman_rh_cloud/remediations_retriever.rb
177
178
  - app/services/foreman_rh_cloud/template_renderer_helper.rb
@@ -620,6 +621,9 @@ files:
620
621
  - webpack/__tests__/__snapshots__/ForemanRhCloudHelpers.test.js.snap
621
622
  - webpack/__tests__/__snapshots__/ForemanRhCloudSelectors.test.js.snap
622
623
  - webpack/__tests__/__snapshots__/ForemanRhCloudTestHelpers.test.js.snap
624
+ - webpack/common/ForemanTasks/ForemanTasksActions.js
625
+ - webpack/common/ForemanTasks/ForemanTasksHelpers.js
626
+ - webpack/common/ForemanTasks/index.js
623
627
  - webpack/common/Switcher/HelpLabel.js
624
628
  - webpack/common/Switcher/SwitcherPF4.js
625
629
  - webpack/common/Switcher/SwitcherPF4.scss