foreman_rh_cloud 4.0.25 → 5.0.28

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/rh_cloud/inventory_controller.rb +4 -1
  3. data/app/controllers/concerns/inventory_upload/report_actions.rb +1 -1
  4. data/app/controllers/foreman_inventory_upload/cloud_status_controller.rb +26 -0
  5. data/app/controllers/foreman_inventory_upload/reports_controller.rb +1 -1
  6. data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +18 -4
  7. data/app/controllers/insights_cloud/hits_controller.rb +0 -1
  8. data/app/models/setting/rh_cloud.rb +0 -1
  9. data/app/models/task_output_line.rb +2 -0
  10. data/app/models/task_output_status.rb +2 -0
  11. data/app/services/foreman_rh_cloud/cloud_ping_service.rb +83 -0
  12. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +15 -3
  13. data/config/Gemfile.lock.gh_test +169 -160
  14. data/config/database.yml.example +2 -2
  15. data/config/package-lock.json.plugin +10551 -7500
  16. data/config/rh_cert-api_chain.pem +74 -0
  17. data/config/routes.rb +3 -1
  18. data/db/migrate/20211027000001_create_task_output.foreman_rh_cloud.rb +18 -0
  19. data/lib/foreman_inventory_upload/async/generate_all_reports_job.rb +11 -7
  20. data/lib/foreman_inventory_upload/async/generate_report_job.rb +24 -12
  21. data/lib/foreman_inventory_upload/async/progress_output.rb +5 -28
  22. data/lib/foreman_inventory_upload/async/queue_for_upload_job.rb +20 -5
  23. data/lib/foreman_inventory_upload/async/shell_process.rb +17 -4
  24. data/lib/foreman_inventory_upload/async/upload_report_job.rb +22 -13
  25. data/lib/foreman_inventory_upload/generators/queries.rb +0 -16
  26. data/lib/foreman_inventory_upload/generators/tags.rb +1 -2
  27. data/lib/foreman_rh_cloud/engine.rb +4 -11
  28. data/lib/foreman_rh_cloud/version.rb +1 -1
  29. data/lib/foreman_rh_cloud.rb +16 -1
  30. data/lib/insights_cloud/async/insights_client_status_aging.rb +4 -0
  31. data/lib/insights_cloud/async/insights_full_sync.rb +4 -0
  32. data/lib/insights_cloud/async/insights_generate_notifications.rb +4 -0
  33. data/lib/insights_cloud/async/insights_resolutions_sync.rb +7 -2
  34. data/lib/insights_cloud/async/insights_rules_sync.rb +10 -2
  35. data/lib/insights_cloud/async/insights_scheduled_sync.rb +11 -7
  36. data/lib/insights_cloud.rb +4 -0
  37. data/lib/inventory_sync/async/inventory_full_sync.rb +4 -0
  38. data/lib/inventory_sync/async/inventory_hosts_sync.rb +4 -0
  39. data/lib/inventory_sync/async/inventory_scheduled_sync.rb +4 -0
  40. data/lib/inventory_sync/async/inventory_self_host_sync.rb +4 -0
  41. data/lib/inventory_sync/async/query_inventory_job.rb +4 -0
  42. data/lib/tasks/rh_cloud_inventory.rake +4 -11
  43. data/package.json +7 -12
  44. data/test/controllers/insights_cloud/api/machine_telemetries_controller_test.rb +20 -39
  45. data/test/controllers/inventory_upload/cloud_status_controller_test.rb +44 -0
  46. data/test/factories/inventory_upload_factories.rb +14 -0
  47. data/test/jobs/insights_resolutions_sync_test.rb +10 -1
  48. data/test/jobs/upload_report_job_test.rb +5 -3
  49. data/test/test_plugin_helper.rb +53 -0
  50. data/test/unit/foreman_rh_cloud_self_host_test.rb +28 -0
  51. data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +29 -34
  52. data/test/unit/services/foreman_rh_cloud/cloud_status_service_test.rb +66 -0
  53. data/test/unit/shell_process_job_test.rb +3 -1
  54. data/test/unit/slice_generator_test.rb +24 -4
  55. data/test/unit/tags_generator_test.rb +16 -16
  56. data/webpack/ForemanInventoryUpload/Components/AccountList/accountList.scss +8 -0
  57. data/webpack/ForemanInventoryUpload/Components/InventorySettings/InventorySettings.scss +0 -4
  58. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.scss +17 -4
  59. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageTitle.js +36 -12
  60. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +58 -37
  61. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +144 -0
  62. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.scss +5 -0
  63. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +12 -10
  64. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/__tests__/__snapshots__/PageDescription.test.js.snap +10 -10
  65. data/webpack/ForemanInventoryUpload/ForemanInventoryConstants.js +2 -0
  66. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/__snapshots__/InventoryAutoUpload.test.js.snap +1 -1
  67. data/webpack/InsightsCloudSync/Components/InsightsHeader/InsightsHeader.scss +5 -1
  68. data/webpack/InsightsCloudSync/Components/InsightsHeader/index.js +6 -6
  69. data/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettings.js +9 -5
  70. data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettings.test.js.snap +6 -6
  71. data/webpack/InsightsCloudSync/Components/InsightsSettings/insightsSettings.scss +1 -14
  72. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +5 -24
  73. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableConstants.js +11 -4
  74. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableSelectors.js +0 -3
  75. data/webpack/InsightsCloudSync/Components/InsightsTable/Pagination.js +51 -0
  76. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +7 -69
  77. data/webpack/InsightsCloudSync/Components/InsightsTable/table.scss +10 -0
  78. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +11 -10
  79. data/webpack/InsightsCloudSync/Components/RemediationModal/index.js +0 -2
  80. data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +32 -0
  81. data/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/InsightsHeader.test.js.snap +5 -5
  82. data/webpack/InsightsCloudSync/Components/__tests__/__snapshots__/NoTokenEmptyState.test.js.snap +24 -13
  83. data/webpack/InsightsCloudSync/InsightsCloudSync.js +19 -13
  84. data/webpack/InsightsCloudSync/InsightsCloudSync.scss +82 -2
  85. data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +16 -6
  86. data/webpack/__mocks__/foremanReact/components/Head.js +11 -0
  87. data/webpack/common/Switcher/HelpLabel.js +1 -1
  88. data/webpack/common/Switcher/SwitcherPF4.js +1 -1
  89. data/webpack/common/Switcher/SwitcherPF4.scss +6 -7
  90. data/webpack/common/Switcher/__tests__/__snapshots__/HelpLabel.test.js.snap +1 -1
  91. data/webpack/common/Switcher/__tests__/__snapshots__/SwitcherPF4.test.js.snap +2 -1
  92. metadata +20 -24
  93. data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/InsightsSyncSwitcher.fixtures.js +0 -1
  94. data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/InsightsSyncSwitcher.js +0 -45
  95. data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/__tests__/InsightsSyncSwitcher.test.js +0 -17
  96. data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/__tests__/__snapshots__/InsightsSyncSwitcher.test.js.snap +0 -38
  97. data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/index.js +0 -1
  98. data/webpack/InsightsCloudSync/Components/InsightsSyncSwitcher/insightsSyncSwitcher.scss +0 -3
  99. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediateButton.js +0 -59
@@ -0,0 +1,74 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
41
+ Kg6Ay0rrsi4nw1JHue2GvdjdfVOaWSWC
42
+ -----END CERTIFICATE-----
43
+ -----BEGIN CERTIFICATE-----
44
+ MIIFfTCCA2WgAwIBAgIJAJGKz8qFAAADMA0GCSqGSIb3DQEBBQUAMIGwMQswCQYD
45
+ VQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExEDAOBgNVBAcMB1JhbGVp
46
+ Z2gxFjAUBgNVBAoMDVJlZCBIYXQsIEluYy4xGDAWBgNVBAsMD1JlZCBIYXQgTmV0
47
+ d29yazEeMBwGA1UEAwwVRW50aXRsZW1lbnQgTWFzdGVyIENBMSQwIgYJKoZIhvcN
48
+ AQkBFhVjYS1zdXBwb3J0QHJlZGhhdC5jb20wHhcNMTUwNTA1MTMwMzQ4WhcNMjUw
49
+ NTAyMTMwMzQ4WjCBiTELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5PUlRIIENBUk9M
50
+ SU5BMRAwDgYDVQQHEwdSYWxlaWdoMRAwDgYDVQQKEwdSZWQgSGF0MRgwFgYDVQQL
51
+ Ew9SZWQgSGF0IE5ldHdvcmsxIzAhBgNVBAMTGmNlcnQtYXBpLmFjY2Vzcy5yZWRo
52
+ YXQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9hTNMtZMa7Kg
53
+ Jlux6pnuUinP0Rv0aiiPFr7qNHFore4loGrPlpzUvQbUByy3xm7lhf4R4qbINCls
54
+ veWg6HDidvQr174RXb5YLMXuBrYAiPWQTrRRLNuvXFHKzREghRWTv48IXTIDEo0G
55
+ fZJUO+myY2RfwqugZKic5dR6ZakHSSpQO70O6H5R0eHlKa13k4eEpG2fVY/xqFto
56
+ WkfZyEmSacZpqxp7gIjZqreLc4MFwpiVjGFrK3Jk+Px1Z6J94LTLx2SxrYzWIeUs
57
+ 5j+lceQOvpV4/pkClnRCW1pkCKTccjFKQkpNPGwdIusRXUGl9IYc20Fa/7g9iUQc
58
+ 5fXu9EAzfwIDAQABo4G+MIG7MAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZA
59
+ MAsGA1UdDwQEAwIF4DATBgNVHSUEDDAKBggrBgEFBQcDATA5BglghkgBhvhCAQ0E
60
+ LBYqTWFuYWdlZCBieSBSZWQgSGF0IChjYS1zdXBwb3J0QHJlZGhhdC5jb20pMB0G
61
+ A1UdDgQWBBRfgCjd8aXf0U4VX8DKTVIn+paGBzAfBgNVHSMEGDAWgBSIS6ZFxEbs
62
+ j9bPpvYazyY8kMx/FzANBgkqhkiG9w0BAQUFAAOCAgEAlC+r6UEEp5BUkI0Rj2T+
63
+ 1PH7oUCaGQeQoyVbGddz/WUcBk/lMMtyCEoxU+3tTwNWmCWWjYXtjoL9MlSAC/q+
64
+ NZfBi1iq0uuSus9JI/Uu8aRhoxTK56qGRed/JNixOHEmFn891cahIPpF0exWwtYD
65
+ ThwXo7Z6PI7t8EMKdSrGTOowp58yho8xYFL/Z7JmjL55Pf85GIrdiniNZd4i178J
66
+ 07R9zsiLvdXq9mT33iJwkm+uhO+FA9d8OE3ji21pBbGUAQSWOdkemvUCsy8zANW9
67
+ fT+dBrMr5Buk7eaBBJ2PxECNiWLCRQJWmyff1O5zMT0daS2lBdEGUNhBZ0hnX13Q
68
+ kabUp0bxRrNRq+WkomP7onZhfZS6SjKm0UmwoV6o3V1ED6y7muQNRmgDpA5PcbvO
69
+ gl7OexNL4zcpyfMdAmTYf5yTRSvB42Yg5hVfuzPEnOIqupwES3mWkEHRlqbMUkHw
70
+ qIQAxIwQqZd5PdPpElQ/6j/ZT9DwW/I6zgndX2rsS0oGYcwFTkSj0/rKKkC13hk7
71
+ LchXMZu5ckdustM79U6OZIBairrJaL2OpR08un2nwIjgEGqhVFYc44UK1VpkE8mr
72
+ qvqJS6OHVlTlKcEDnhVkPS3i5qjuS/PtSq0CwH8bzYKFJayLDY/z36Zv6PdttzmU
73
+ Yb1NSDcJejHJ80pMINutyYQ=
74
+ -----END CERTIFICATE-----
data/config/routes.rb CHANGED
@@ -11,6 +11,8 @@ Rails.application.routes.draw do
11
11
  post 'cloud_connector', to: 'uploads#enable_cloud_connector'
12
12
 
13
13
  resources :tasks, only: [:create, :show]
14
+
15
+ get 'status', to: 'cloud_status#index'
14
16
  end
15
17
 
16
18
  namespace :insights_cloud do
@@ -37,7 +39,7 @@ Rails.application.routes.draw do
37
39
  end
38
40
 
39
41
  scope '/r/insights' do
40
- match '/*path', :constraints => lambda { |req| !req.path.include?('view/api') }, to: 'machine_telemetries#forward_request', via: [:get, :post, :delete,:put, :patch]
42
+ match '(/*path)(/)', :constraints => lambda { |req| !req.path.include?('view/api') }, to: 'machine_telemetries#forward_request', via: [:get, :post, :delete,:put, :patch]
41
43
  end
42
44
  end
43
45
 
@@ -0,0 +1,18 @@
1
+ class CreateTaskOutput < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :task_output_lines do |t|
4
+ t.string :label
5
+ t.string :line
6
+ t.timestamps
7
+
8
+ t.index :label
9
+ end
10
+
11
+ create_table :task_output_statuses do |t|
12
+ t.string :label
13
+ t.string :status
14
+
15
+ t.index :label, unique: true
16
+ end
17
+ end
18
+ end
@@ -1,7 +1,9 @@
1
1
  module ForemanInventoryUpload
2
2
  module Async
3
- class GenerateAllReportsJob < ::ApplicationJob
4
- def perform
3
+ class GenerateAllReportsJob < ::Actions::EntryAction
4
+ include ::Actions::RecurringAction
5
+
6
+ def plan
5
7
  unless Setting[:allow_auto_inventory_upload]
6
8
  logger.debug(
7
9
  'The scheduled process is disabled due to the "allow_auto_inventory_upload"
@@ -16,17 +18,19 @@ module ForemanInventoryUpload
16
18
  total_hosts = ForemanInventoryUpload::Generators::Queries.for_org(organization.id, use_batches: false).count
17
19
 
18
20
  if total_hosts <= ForemanInventoryUpload.max_org_size
19
- GenerateReportJob.perform_later(ForemanInventoryUpload.generated_reports_folder, organization.id)
21
+ plan_generate_report(ForemanInventoryUpload.generated_reports_folder, organization)
20
22
  else
21
23
  logger.info("Skipping automatic uploads for organization #{organization.name}, too many hosts (#{total_hosts}/#{ForemanInventoryUpload.max_org_size})")
22
24
  end
23
25
  end.compact
24
- ensure
25
- self.class.set(:wait => 24.hours).perform_later
26
26
  end
27
27
 
28
- def self.singleton_job_name
29
- name
28
+ def rescue_strategy_for_self
29
+ Dynflow::Action::Rescue::Fail
30
+ end
31
+
32
+ def plan_generate_report(folder, organization)
33
+ plan_action(ForemanInventoryUpload::Async::GenerateReportJob, folder, organization.id)
30
34
  end
31
35
  end
32
36
  end
@@ -5,17 +5,21 @@ module ForemanInventoryUpload
5
5
  "report_for_#{label}"
6
6
  end
7
7
 
8
- def perform(base_folder, organization)
9
- @base_folder = base_folder
10
- @organization = organization
8
+ def plan(base_folder, organization_id)
9
+ sequence do
10
+ super(
11
+ GenerateReportJob.output_label(organization_id),
12
+ organization_id: organization_id,
13
+ base_folder: base_folder
14
+ )
11
15
 
12
- super(GenerateReportJob.output_label(organization))
13
-
14
- QueueForUploadJob.perform_later(
15
- base_folder,
16
- ForemanInventoryUpload.facts_archive_name(organization),
17
- organization
18
- )
16
+ plan_action(
17
+ QueueForUploadJob,
18
+ base_folder,
19
+ ForemanInventoryUpload.facts_archive_name(organization_id),
20
+ organization_id
21
+ )
22
+ end
19
23
  end
20
24
 
21
25
  def rake_prefix
@@ -28,10 +32,18 @@ module ForemanInventoryUpload
28
32
 
29
33
  def env
30
34
  super.merge(
31
- 'target' => @base_folder,
32
- 'organization_id' => @organization
35
+ 'target' => base_folder,
36
+ 'organization_id' => organization_id
33
37
  )
34
38
  end
39
+
40
+ def base_folder
41
+ input[:base_folder]
42
+ end
43
+
44
+ def organization_id
45
+ input[:organization_id]
46
+ end
35
47
  end
36
48
  end
37
49
  end
@@ -6,6 +6,7 @@ module ForemanInventoryUpload
6
6
  end
7
7
 
8
8
  def self.register(label)
9
+ TaskOutputLine.where(label: @label).delete_all
9
10
  ProgressOutput.new(label, :writer)
10
11
  end
11
12
 
@@ -14,47 +15,23 @@ module ForemanInventoryUpload
14
15
  @mode = mode
15
16
  end
16
17
 
17
- def buffer
18
- @buffer ||= begin
19
- File.open(file_name, file_mode)
20
- rescue Errno::ENOENT
21
- StringIO.new
22
- end
23
- end
24
-
25
18
  def full_output
26
- buffer.read
19
+ TaskOutputLine.where(label: @label).order(:created_at).pluck(:line).join("\n")
27
20
  end
28
21
 
29
22
  def write_line(line)
30
- buffer << line
31
- buffer.fsync
23
+ TaskOutputLine.create!(label: @label, line: line)
32
24
  end
33
25
 
34
26
  def close
35
- @buffer&.close
36
27
  end
37
28
 
38
29
  def status
39
- File.read(file_name(:status))
40
- rescue Errno::ENOENT
41
- ''
30
+ TaskOutputStatus.where(label: @label).pluck(:status).first || ''
42
31
  end
43
32
 
44
33
  def status=(status)
45
- File.atomic_write(file_name(:status)) do |status_file|
46
- status_file.write(status)
47
- end
48
- end
49
-
50
- private
51
-
52
- def file_mode
53
- (@mode == :reader) ? 'r' : 'w'
54
- end
55
-
56
- def file_name(type = 'out')
57
- File.join(ForemanInventoryUpload.outputs_folder, "#{@label}.#{type}")
34
+ TaskOutputStatus.upsert({ label: @label, status: status }, unique_by: :label)
58
35
  end
59
36
  end
60
37
  end
@@ -1,9 +1,12 @@
1
1
  module ForemanInventoryUpload
2
2
  module Async
3
- class QueueForUploadJob < ::ApplicationJob
4
- def perform(base_folder, report_file, organization_id)
5
- @base_folder = base_folder
6
- @report_file = report_file
3
+ class QueueForUploadJob < ::Actions::EntryAction
4
+ def plan(base_folder, report_file, organization_id)
5
+ enqueue_task = plan_self(base_folder: base_folder, report_file: report_file)
6
+ plan_upload_report(enqueue_task.output[:enqueued_file_name], organization_id)
7
+ end
8
+
9
+ def run
7
10
  logger.debug('Ensuring objects')
8
11
  ensure_ouput_folder
9
12
  ensure_output_script
@@ -12,7 +15,7 @@ module ForemanInventoryUpload
12
15
  FileUtils.mv(File.join(base_folder, report_file), enqueued_file_name)
13
16
  logger.debug("Done copying #{report_file} to #{enqueued_file_name}")
14
17
 
15
- UploadReportJob.perform_later(enqueued_file_name, organization_id)
18
+ output[:enqueued_file_name] = enqueued_file_name
16
19
  end
17
20
 
18
21
  def uploads_folder
@@ -47,6 +50,18 @@ module ForemanInventoryUpload
47
50
  def logger
48
51
  Foreman::Logging.logger('background')
49
52
  end
53
+
54
+ def base_folder
55
+ input[:base_folder]
56
+ end
57
+
58
+ def report_file
59
+ input[:report_file]
60
+ end
61
+
62
+ def plan_upload_report(enqueued_file_name, organization_id)
63
+ plan_action(UploadReportJob, enqueued_file_name, organization_id)
64
+ end
50
65
  end
51
66
  end
52
67
  end
@@ -2,13 +2,18 @@ require 'open3'
2
2
 
3
3
  module ForemanInventoryUpload
4
4
  module Async
5
- class ShellProcess < ::ApplicationJob
5
+ class ShellProcess < ::Actions::EntryAction
6
6
  include AsyncHelpers
7
7
 
8
- def perform(instance_label)
8
+ def plan(instance_label, more_inputs = {})
9
+ inputs = more_inputs.merge(instance_label: instance_label)
10
+ plan_self(inputs)
11
+ end
12
+
13
+ def run
9
14
  klass_name = self.class.name
10
15
  logger.debug("Starting #{klass_name} with label #{instance_label}")
11
- progress_output_for(instance_label) do |progress_output|
16
+ progress_output do |progress_output|
12
17
  Open3.popen2e(hash_to_s(env), *preprocess_command(command)) do |_stdin, stdout_stderr, wait_thread|
13
18
  progress_output.status = "Running in pid #{wait_thread.pid}"
14
19
 
@@ -25,7 +30,7 @@ module ForemanInventoryUpload
25
30
  def command
26
31
  end
27
32
 
28
- def progress_output_for(instance_label)
33
+ def progress_output
29
34
  progress_output = ProgressOutput.register(instance_label)
30
35
  yield(progress_output)
31
36
  ensure
@@ -40,11 +45,19 @@ module ForemanInventoryUpload
40
45
  Foreman::Logging.logger('background')
41
46
  end
42
47
 
48
+ def rescue_strategy_for_self
49
+ Dynflow::Action::Rescue::Fail
50
+ end
51
+
43
52
  private
44
53
 
45
54
  def preprocess_command(command)
46
55
  command.kind_of?(Array) ? command : [command]
47
56
  end
57
+
58
+ def instance_label
59
+ input[:instance_label]
60
+ end
48
61
  end
49
62
  end
50
63
  end
@@ -7,44 +7,45 @@ module ForemanInventoryUpload
7
7
  "upload_for_#{label}"
8
8
  end
9
9
 
10
- def perform(filename, organization_id)
10
+ def plan(filename, organization_id)
11
11
  label = UploadReportJob.output_label(organization_id)
12
- @filename = filename
13
- @organization = Organization.find(organization_id)
12
+ super(label, filename: filename, organization_id: organization_id)
13
+ end
14
14
 
15
+ def run
15
16
  if Setting[:content_disconnected]
16
- progress_output_for(label) do |progress_output|
17
+ progress_output do |progress_output|
17
18
  progress_output.write_line('Upload was stopped since disconnected mode setting is enabled for content on this instance.')
18
19
  progress_output.status = "Task aborted, exit 1"
19
20
  end
20
21
  return
21
22
  end
22
23
 
23
- unless @organization.owner_details&.fetch('upstreamConsumer')&.fetch('idCert')
24
- logger.info("Skipping organization '#{@organization}', no candlepin certificate defined.")
25
- progress_output_for(label) do |progress_output|
26
- progress_output.write_line("Skipping organization #{@organization}, no candlepin certificate defined.")
24
+ unless organization.owner_details&.fetch('upstreamConsumer')&.fetch('idCert')
25
+ logger.info("Skipping organization '#{organization}', no candlepin certificate defined.")
26
+ progress_output do |progress_output|
27
+ progress_output.write_line("Skipping organization #{organization}, no candlepin certificate defined.")
27
28
  progress_output.status = "Task aborted, exit 1"
28
29
  end
29
30
  return
30
31
  end
31
32
 
32
- Tempfile.create([@organization.name, '.pem']) do |cer_file|
33
+ Tempfile.create([organization.name, '.pem']) do |cer_file|
33
34
  cer_file.write(rh_credentials[:cert])
34
35
  cer_file.write(rh_credentials[:key])
35
36
  cer_file.flush
36
37
  @cer_path = cer_file.path
37
- super(label)
38
+ super
38
39
  end
39
40
  end
40
41
 
41
42
  def command
42
- ['/bin/bash', File.join(File.dirname(@filename), ForemanInventoryUpload.upload_script_file)]
43
+ ['/bin/bash', File.join(File.dirname(filename), ForemanInventoryUpload.upload_script_file)]
43
44
  end
44
45
 
45
46
  def env
46
47
  env_vars = super.merge(
47
- 'FILES' => @filename,
48
+ 'FILES' => filename,
48
49
  'CER_PATH' => @cer_path
49
50
  )
50
51
 
@@ -58,13 +59,21 @@ module ForemanInventoryUpload
58
59
 
59
60
  def rh_credentials
60
61
  @rh_credentials ||= begin
61
- candlepin_id_certificate = @organization.owner_details['upstreamConsumer']['idCert']
62
+ candlepin_id_certificate = organization.owner_details['upstreamConsumer']['idCert']
62
63
  {
63
64
  cert: candlepin_id_certificate['cert'],
64
65
  key: candlepin_id_certificate['key'],
65
66
  }
66
67
  end
67
68
  end
69
+
70
+ def filename
71
+ input[:filename]
72
+ end
73
+
74
+ def organization
75
+ @organization ||= Organization.find(input[:organization_id])
76
+ end
68
77
  end
69
78
  end
70
79
  end
@@ -45,26 +45,10 @@ module ForemanInventoryUpload
45
45
  )
46
46
  end
47
47
 
48
- def self.for_report(portal_user)
49
- org_ids = organizations_for_user(portal_user).pluck(:id)
50
- for_org(org_ids)
51
- end
52
-
53
48
  def self.for_org(organization_id, use_batches: true)
54
49
  base_query = for_slice(Host.unscoped.where(organization_id: organization_id))
55
50
  use_batches ? base_query.in_batches(of: ForemanInventoryUpload.slice_size) : base_query
56
51
  end
57
-
58
- def self.organizations_for_user(portal_user)
59
- Organization
60
- .joins(:telemetry_configuration)
61
- .where(
62
- redhat_access_telemetry_configurations: {
63
- portal_user: portal_user,
64
- enable_telemetry: true,
65
- }
66
- )
67
- end
68
52
  end
69
53
  end
70
54
  end
@@ -19,8 +19,7 @@ module ForemanInventoryUpload
19
19
  def generate_parameters
20
20
  return [] unless Setting[:include_parameter_tags]
21
21
 
22
- (@host.host_inherited_params_objects || [])
23
- .map { |item| [item.name, item.value] }
22
+ (@host.host_params || {})
24
23
  .select { |_name, value| value.present? || value.is_a?(FalseClass) }
25
24
  end
26
25
 
@@ -1,5 +1,4 @@
1
1
  require 'katello'
2
- require 'redhat_access'
3
2
  require 'foreman_ansible'
4
3
 
5
4
  module ForemanRhCloud
@@ -43,6 +42,8 @@ module ForemanRhCloud
43
42
  Foreman::Plugin.register :foreman_rh_cloud do
44
43
  requires_foreman '>= 2.3'
45
44
 
45
+ apipie_documented_controllers ["#{ForemanRhCloud::Engine.root}/app/controllers/api/v2/**/*.rb"]
46
+
46
47
  # Add permissions
47
48
  security_block :foreman_rh_cloud do
48
49
  permission(
@@ -114,15 +115,6 @@ module ForemanRhCloud
114
115
  ::Host::Managed.include RhCloudHost
115
116
  end
116
117
 
117
- initializer "foreman_rh_cloud.set_dynflow.config.on_init", :before => :finisher_hook do |_app|
118
- unless Rails.env.test?
119
- ForemanTasks.dynflow.config.on_init do |world|
120
- ForemanInventoryUpload::Async::GenerateAllReportsJob.spawn_if_missing(world)
121
- InsightsCloud::Async::InsightsScheduledSync.spawn_if_missing(world)
122
- end
123
- end
124
- end
125
-
126
118
  rake_tasks do
127
119
  Rake::Task['db:seed'].enhance do
128
120
  ForemanRhCloud::Engine.load_seed
@@ -138,7 +130,6 @@ module ForemanRhCloud
138
130
  config.to_prepare do
139
131
  # skip database manipulations while tables do not exist, like in migrations
140
132
  if ActiveRecord::Base.connection.data_source_exists?(ForemanTasks::Task.table_name) &&
141
-
142
133
  RemoteExecutionFeature.register(
143
134
  :rh_cloud_remediate_hosts,
144
135
  N_('Apply Insights recommendations'),
@@ -148,7 +139,9 @@ module ForemanRhCloud
148
139
  # skip object creation when admin user is not present, for example in test DB
149
140
  if User.unscoped.find_by_login(User::ANONYMOUS_ADMIN).present?
150
141
  ::ForemanTasks.dynflow.config.on_init(false) do |world|
142
+ ForemanRhCloud::Engine.register_scheduled_task(ForemanInventoryUpload::Async::GenerateAllReportsJob, '0 0 * * *')
151
143
  ForemanRhCloud::Engine.register_scheduled_task(InventorySync::Async::InventoryScheduledSync, '0 0 * * *')
144
+ ForemanRhCloud::Engine.register_scheduled_task(InsightsCloud::Async::InsightsScheduledSync, '0 0 * * *')
152
145
  ForemanRhCloud::Engine.register_scheduled_task(InsightsCloud::Async::InsightsClientStatusAging, '0 0 * * *')
153
146
  end
154
147
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '4.0.25'.freeze
2
+ VERSION = '5.0.28'.freeze
3
3
  end
@@ -98,6 +98,21 @@ module ForemanRhCloud
98
98
 
99
99
  # For testing purposes we can override the default hostname with an environment variable SATELLITE_RH_CLOUD_FOREMAN_HOST
100
100
  def self.foreman_host
101
- @foreman_host ||= ::Host.unscoped.friendly.find(ENV['SATELLITE_RH_CLOUD_FOREMAN_HOST'] || ::SmartProxy.default_capsule.name)
101
+ @foreman_host ||= begin
102
+ fullname = foreman_host_name
103
+ ::Host.unscoped.friendly.find(fullname)
104
+ rescue ActiveRecord::RecordNotFound
105
+ # fullname didn't work. Let's try shortname
106
+ shortname = /(?<shortname>[^\.]*)\.?.*/.match(fullname)[:shortname]
107
+ ::Host.unscoped.friendly.find(shortname)
108
+ end
109
+ end
110
+
111
+ def self.foreman_host_name
112
+ ENV['SATELLITE_RH_CLOUD_FOREMAN_HOST'] || ::SmartProxy.default_capsule.name
113
+ end
114
+
115
+ def self.legacy_insights_ca
116
+ "#{ForemanRhCloud::Engine.root}/config/rh_cert-api_chain.pem"
102
117
  end
103
118
  end
@@ -18,6 +18,10 @@ module InsightsCloud
18
18
  def logger
19
19
  action_logger
20
20
  end
21
+
22
+ def rescue_strategy_for_self
23
+ Dynflow::Action::Rescue::Fail
24
+ end
21
25
  end
22
26
  end
23
27
  end
@@ -118,6 +118,10 @@ module InsightsCloud
118
118
 
119
119
  match || { id: nil }
120
120
  end
121
+
122
+ def rescue_strategy_for_self
123
+ Dynflow::Action::Rescue::Fail
124
+ end
121
125
  end
122
126
  end
123
127
  end
@@ -53,6 +53,10 @@ module InsightsCloud
53
53
  }
54
54
  )
55
55
  end
56
+
57
+ def rescue_strategy_for_self
58
+ Dynflow::Action::Rescue::Fail
59
+ end
56
60
  end
57
61
  end
58
62
  end
@@ -19,8 +19,9 @@ module InsightsCloud
19
19
  def run
20
20
  InsightsResolution.transaction do
21
21
  InsightsResolution.delete_all
22
- api_response = query_insights_resolutions(relevant_rules)
23
- write_resolutions(api_response)
22
+ rule_ids = relevant_rules
23
+ api_response = query_insights_resolutions(rule_ids) unless rule_ids.empty?
24
+ write_resolutions(api_response) if api_response
24
25
  end
25
26
  end
26
27
 
@@ -70,6 +71,10 @@ module InsightsCloud
70
71
  def to_rule_id(resolution_rule_id)
71
72
  RULE_ID_REGEX.match(resolution_rule_id).named_captures.fetch('id', resolution_rule_id)
72
73
  end
74
+
75
+ def rescue_strategy_for_self
76
+ Dynflow::Action::Rescue::Fail
77
+ end
73
78
  end
74
79
  end
75
80
  end
@@ -11,8 +11,12 @@ module InsightsCloud
11
11
  return
12
12
  end
13
13
 
14
- plan_self
15
- plan_resolutions
14
+ # since the tasks are not connected, we need to force sequence execution here
15
+ # to make sure we don't run resolutions until we synced all our rules
16
+ sequence do
17
+ plan_self
18
+ plan_resolutions
19
+ end
16
20
  end
17
21
 
18
22
  def plan_resolutions
@@ -71,6 +75,10 @@ module InsightsCloud
71
75
  rating: rule_hash['rating'],
72
76
  }
73
77
  end
78
+
79
+ def rescue_strategy_for_self
80
+ Dynflow::Action::Rescue::Fail
81
+ end
74
82
  end
75
83
  end
76
84
  end