foreman_rh_cloud 4.0.21.1 → 4.0.24.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) 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 +6 -3
  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/models/insights_client_report_status.rb +11 -22
  12. data/app/services/foreman_rh_cloud/cloud_auth.rb +12 -0
  13. data/app/services/foreman_rh_cloud/cloud_request.rb +14 -0
  14. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +1 -14
  15. data/app/services/foreman_rh_cloud/insights_status_cleaner.rb +17 -0
  16. data/app/services/foreman_rh_cloud/remediations_retriever.rb +1 -4
  17. data/config/package-lock.json.plugin +30931 -0
  18. data/config/routes.rb +19 -0
  19. data/db/migrate/20210720000001_remove_old_insights_statuses.foreman_rh_cloud.rb +6 -0
  20. data/lib/foreman_inventory_upload.rb +9 -1
  21. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +19 -0
  22. data/lib/foreman_inventory_upload/generators/queries.rb +1 -0
  23. data/lib/foreman_inventory_upload/generators/slice.rb +6 -5
  24. data/lib/foreman_rh_cloud/engine.rb +17 -10
  25. data/lib/foreman_rh_cloud/version.rb +1 -1
  26. data/lib/insights_cloud/async/insights_client_status_aging.rb +23 -0
  27. data/lib/insights_cloud/async/insights_full_sync.rb +4 -14
  28. data/lib/insights_cloud/async/insights_resolutions_sync.rb +1 -4
  29. data/lib/insights_cloud/async/insights_rules_sync.rb +2 -7
  30. data/lib/inventory_sync/async/host_result.rb +4 -0
  31. data/lib/inventory_sync/async/inventory_full_sync.rb +2 -1
  32. data/lib/inventory_sync/async/inventory_hosts_sync.rb +16 -2
  33. data/lib/inventory_sync/async/inventory_scheduled_sync.rb +12 -0
  34. data/lib/inventory_sync/async/inventory_self_host_sync.rb +30 -0
  35. data/lib/inventory_sync/async/query_inventory_job.rb +6 -5
  36. data/lib/tasks/insights.rake +15 -0
  37. data/lib/tasks/rh_cloud_inventory.rake +8 -1
  38. data/package.json +1 -1
  39. data/test/controllers/insights_cloud/api/machine_telemetries_controller_test.rb +41 -0
  40. data/test/controllers/inventory_upload/api/inventory_controller_test.rb +53 -0
  41. data/test/factories/inventory_upload_factories.rb +1 -1
  42. data/test/jobs/insights_client_status_aging_test.rb +33 -0
  43. data/test/jobs/inventory_hosts_sync_test.rb +267 -0
  44. data/test/jobs/inventory_scheduled_sync_test.rb +22 -0
  45. data/test/jobs/inventory_self_host_sync_test.rb +103 -0
  46. data/test/models/insights_client_report_status_test.rb +70 -72
  47. data/test/test_plugin_helper.rb +2 -1
  48. data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +3 -3
  49. data/test/unit/services/foreman_rh_cloud/insights_status_cleaner_test.rb +31 -0
  50. data/test/unit/slice_generator_test.rb +70 -27
  51. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +11 -0
  52. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/__tests__/__snapshots__/PageDescription.test.js.snap +11 -0
  53. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButtonActions.js +28 -63
  54. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/integrations.test.js.snap +2 -3
  55. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableActions.js +19 -19
  56. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +0 -2
  57. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableActions.test.js.snap +14 -14
  58. data/webpack/InsightsCloudSync/InsightsCloudSync.js +4 -1
  59. data/webpack/InsightsCloudSync/InsightsCloudSyncActions.js +44 -20
  60. data/webpack/InsightsCloudSync/InsightsCloudSyncConstants.js +2 -0
  61. data/webpack/InsightsCloudSync/__tests__/__snapshots__/InsightsCloudSyncActions.test.js.snap +11 -7
  62. data/webpack/common/ForemanTasks/ForemanTasksActions.js +64 -0
  63. data/webpack/common/ForemanTasks/ForemanTasksHelpers.js +7 -0
  64. data/webpack/common/ForemanTasks/index.js +1 -0
  65. metadata +28 -4
  66. data/app/subscribers/foreman_rh_cloud/insights_subscriber.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97882071192995f2da93032050b9ecdfa616dba407c8d032bfd29f6741ea9d56
4
- data.tar.gz: 88bca49cea9ee2abac2d2dc9d608a33329ad9e214d57035424e8e24984691537
3
+ metadata.gz: 5de90e40ec6d14cf5483a2f92e46c61488c01a921a89feaa8194015f09c6fd0d
4
+ data.tar.gz: 3ac8ba217d2356211e25c1f1de144ad72578ba0be29116ce1d611817302fc097
5
5
  SHA512:
6
- metadata.gz: 67dd2ada55ac862b2d57ddf893e7408d002c40c2f89a141e6bf8c115d6eeee32d19b156e7668751f591665f948fa04d628719e5f6f5ab9e4609c02f0a14a93f4
7
- data.tar.gz: 54ded7bb163e4a38cd3fa4a62dfe101484b98e87c016514b985190f77a07c7556e980dd8574dc5fb70cacb3fcc521a37a1f4f2325e5360cdbb2ddd6f38816804
6
+ metadata.gz: 051caa1c8e5d69a8dad5aa77570b79854854d5ae10f810afe2f57dc6d0f2be0a8de1090caab8ceb0a3faea06b2cb42bad3beda18097792b62e191caa6bb3b41d
7
+ data.tar.gz: 5f53fcc4bfdcc134afe56d19ac8a6c46822b2a6aeab832296eb0c7ffbe462d3a0510f2aaf2d0548f4b0f212f2b44e893fb12a04dace6c35fdc039071a7dd70b2
@@ -0,0 +1,50 @@
1
+ module Api
2
+ module V2
3
+ module RhCloud
4
+ class InventoryController < ::Api::V2::BaseController
5
+ include ::Api::Version2
6
+ include InventoryUpload::ReportActions
7
+ include InventoryUpload::TaskActions
8
+
9
+ api :GET, "/organizations/:organization_id/rh_cloud/report", N_("Download latest report")
10
+ def download_file
11
+ filename, file = report_file(params[:organization_id])
12
+
13
+ send_file file, disposition: 'attachment', filename: filename
14
+ rescue InventoryUpload::ReportActions::ReportMissingError => error
15
+ render json: { message: error.message }, status: :not_found
16
+ end
17
+
18
+ api :POST, "/organizations/:organization_id/rh_cloud/report", N_("Start report generation")
19
+ def generate_report
20
+ organization_id = params[:organization_id]
21
+
22
+ start_report_generation(organization_id)
23
+
24
+ render json: {
25
+ action_status: 'success',
26
+ }, status: :ok
27
+ end
28
+
29
+ api :POST, "/organizations/:organization_id/rh_cloud/inventory_sync", N_("Start inventory synchronization")
30
+ def sync_inventory_status
31
+ selected_org = Organization.find(params[:organization_id])
32
+
33
+ task = start_inventory_sync(selected_org)
34
+
35
+ render json: {
36
+ task: task,
37
+ }, status: :ok
38
+ rescue InventoryUpload::TaskActions::NothingToSyncError => error
39
+ render json: { message: error.message }, status: :bad_request
40
+ end
41
+
42
+ api :POST, "rh_cloud/enable_connector", N_("Enable cloud connector")
43
+ def enable_cloud_connector
44
+ cloud_connector = ForemanRhCloud::CloudConnector.new
45
+ render json: cloud_connector.install.to_json
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,26 @@
1
+ module InventoryUpload
2
+ module ReportActions
3
+ extend ActiveSupport::Concern
4
+
5
+ class ReportMissingError < Foreman::Exception
6
+ MESSAGE = N_("The report file %{filename} doesn't exist")
7
+
8
+ def initialize(**params)
9
+ super(self.class::MESSAGE % params, params)
10
+ end
11
+ end
12
+
13
+ def start_report_generation(organization_id)
14
+ ForemanInventoryUpload::Async::GenerateReportJob.perform_later(ForemanInventoryUpload.generated_reports_folder, organization_id)
15
+ end
16
+
17
+ def report_file(organization_id)
18
+ filename = ForemanInventoryUpload.facts_archive_name(organization_id)
19
+ files = Dir["{#{ForemanInventoryUpload.uploads_file_path(filename)},#{ForemanInventoryUpload.done_file_path(filename)}}"]
20
+
21
+ raise ReportMissingError.new(filename: filename) if files.empty?
22
+
23
+ [filename, files.first]
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ module InventoryUpload
2
+ module TaskActions
3
+ extend ActiveSupport::Concern
4
+
5
+ class NothingToSyncError < Foreman::Exception
6
+ MESSAGE = N_('Nothing to sync, there are no hosts with subscription for this organization.')
7
+
8
+ def initialize(**params)
9
+ super(self.class::MESSAGE, params)
10
+ end
11
+ end
12
+
13
+ def start_inventory_sync(selected_org)
14
+ subscribed_hosts = ForemanInventoryUpload::Generators::Queries.for_slice(
15
+ Host.unscoped.where(organization: selected_org)
16
+ )
17
+
18
+ if subscribed_hosts.empty?
19
+ raise NothingToSyncError
20
+ end
21
+
22
+ ForemanTasks.async_task(InventorySync::Async::InventoryFullSync, selected_org)
23
+ end
24
+ end
25
+ end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module ForemanInventoryUpload
4
4
  class ReportsController < ::ApplicationController
5
+ include InventoryUpload::ReportActions
6
+
5
7
  def last
6
8
  label = ForemanInventoryUpload::Async::GenerateReportJob.output_label(params[:organization_id])
7
9
  output = ForemanInventoryUpload::Async::ProgressOutput.get(label)&.full_output
@@ -20,7 +22,7 @@ module ForemanInventoryUpload
20
22
  def generate
21
23
  organization_id = params[:organization_id]
22
24
 
23
- ForemanInventoryUpload::Async::GenerateReportJob.perform_later(ForemanInventoryUpload.generated_reports_folder, organization_id)
25
+ start_report_generation(organization_id)
24
26
 
25
27
  render json: {
26
28
  action_status: 'success',
@@ -1,25 +1,17 @@
1
1
  module ForemanInventoryUpload
2
2
  class TasksController < ::ApplicationController
3
+ include InventoryUpload::TaskActions
4
+
3
5
  def create
4
6
  selected_org = Organization.current
5
- subscribed_hosts_ids = Set.new(
6
- ForemanInventoryUpload::Generators::Queries.for_slice(
7
- Host.unscoped.where(organization: selected_org)
8
- ).pluck(:id)
9
- )
10
7
 
11
- if subscribed_hosts_ids.empty?
12
- return render json: {
13
- message: N_('Nothing to sync, there are no hosts with subscription for this organization.'),
14
- }, status: :method_not_allowed
15
- else
16
- task = ForemanTasks.async_task(InventorySync::Async::InventoryFullSync, selected_org)
17
- end
18
- return render json: { message: N_('there was an issue triggering the task') }, status: :internal_server_error unless task
8
+ task = start_inventory_sync(selected_org)
19
9
 
20
10
  render json: {
21
11
  task: task,
22
12
  }, status: :ok
13
+ rescue InventoryUpload::TaskActions::NothingToSyncError => error
14
+ render json: { message: error.message }, status: :internal_server_error
23
15
  end
24
16
 
25
17
  def show
@@ -1,5 +1,7 @@
1
1
  module ForemanInventoryUpload
2
2
  class UploadsController < ::ApplicationController
3
+ include InventoryUpload::ReportActions
4
+
3
5
  def last
4
6
  label = ForemanInventoryUpload::Async::UploadReportJob.output_label(params[:organization_id])
5
7
  output = ForemanInventoryUpload::Async::ProgressOutput.get(label)&.full_output
@@ -10,11 +12,9 @@ module ForemanInventoryUpload
10
12
  end
11
13
 
12
14
  def download_file
13
- filename = ForemanInventoryUpload.facts_archive_name(params[:organization_id])
14
- files = Dir["{#{ForemanInventoryUpload.uploads_file_path(filename)},#{ForemanInventoryUpload.done_file_path(filename)}}"]
15
+ filename, file = report_file(params[:organization_id])
15
16
 
16
- return send_file files.first, disposition: 'attachment', filename: filename unless files.empty?
17
- raise ::Foreman::Exception.new("The report file doesn't exist")
17
+ send_file file, disposition: 'attachment', filename: filename
18
18
  end
19
19
 
20
20
  def enable_cloud_connector
@@ -5,6 +5,7 @@ module InsightsCloud::Api
5
5
  include ::InsightsCloud::ClientAuthentication
6
6
  include ::InsightsCloud::CandlepinCache
7
7
 
8
+ before_action :set_admin_user, only: [:forward_request]
8
9
  before_action :cert_uuid, :ensure_org, :ensure_branch_id, :only => [:forward_request, :branch_info]
9
10
  before_action :ensure_telemetry_enabled_for_consumer, :only => [:forward_request]
10
11
 
@@ -75,9 +76,11 @@ module InsightsCloud::Api
75
76
  return unless request.path == '/redhat_access/r/insights/platform/ingress/v1/upload' ||
76
77
  request.path.include?('/redhat_access/r/insights/uploads/')
77
78
 
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))
79
+ return unless @cloud_response.code.to_s.start_with?('2')
80
+
81
+ # create insights status if it wasn't there in the first place and refresh its reporting date
82
+ @host.get_status(InsightsClientReportStatus).refresh!
83
+ @host.refresh_global_status!
81
84
  end
82
85
  end
83
86
  end
@@ -3,7 +3,7 @@ module InsightsCloud
3
3
  include Foreman::Controller::AutoCompleteSearch
4
4
 
5
5
  def index
6
- hits = resource_base_search_and_page.where(host: Host.authorized).preload(:host, :rule)
6
+ hits = resource_base_search_and_page.preload(:host, :rule)
7
7
 
8
8
  render json: {
9
9
  hasToken: !Setting[:rh_cloud_token].empty?,
@@ -23,9 +23,9 @@ module InsightsCloud
23
23
 
24
24
  def resolutions
25
25
  if remediation_all_selected_param
26
- hits = InsightsHit.with_playbook.search_for(params[:query])
26
+ hits = resource_base.with_playbook.search_for(params[:query])
27
27
  else
28
- hits = resource_base_search_and_page.where(id: remediation_ids_param)
28
+ hits = resource_base_search_and_page.with_playbook.where(id: remediation_ids_param)
29
29
  end
30
30
 
31
31
  hits.preload(:host, rule: :resolutions)
@@ -74,5 +74,9 @@ module InsightsCloud
74
74
  def remediation_all_selected_param
75
75
  ActiveModel::Type::Boolean.new.cast(params[:isAllSelected])
76
76
  end
77
+
78
+ def resource_base
79
+ super.where(host: Host.authorized)
80
+ end
77
81
  end
78
82
  end
@@ -0,0 +1,19 @@
1
+ module ForemanInsightsHostHelper
2
+ def insights_host_overview_buttons(host)
3
+ search_condition = "hostname=#{host.fqdn}"
4
+ [
5
+ {
6
+ button: link_to_if_authorized(
7
+ _("Recommendations"),
8
+ hash_for_foreman_rh_cloud_insights_cloud_path(
9
+ search: search_condition,
10
+ select_all: true
11
+ ),
12
+ title: _("Host Insights recommendations"),
13
+ class: 'btn btn-default'
14
+ ),
15
+ priority: 1000,
16
+ },
17
+ ]
18
+ end
19
+ end
@@ -1,10 +1,11 @@
1
1
  class InsightsClientReportStatus < HostStatus::Status
2
2
  REPORT_INTERVAL = 48.hours
3
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
4
+ REPORTING = 0
5
+ NO_REPORT = 1
6
+
7
+ scope :stale, -> { where.not(reported_at: (Time.now - REPORT_INTERVAL)..Time.now) }
8
+ scope :reporting, -> { where(status: REPORTING) }
8
9
 
9
10
  def self.status_name
10
11
  N_('Insights')
@@ -16,10 +17,6 @@ class InsightsClientReportStatus < HostStatus::Status
16
17
  N_('Reporting')
17
18
  when NO_REPORT
18
19
  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
20
  end
24
21
  end
25
22
 
@@ -29,20 +26,16 @@ class InsightsClientReportStatus < HostStatus::Status
29
26
  ::HostStatus::Global::OK
30
27
  when NO_REPORT
31
28
  ::HostStatus::Global::ERROR
32
- when NOT_MANAGED
33
- ::HostStatus::Global::OK
34
- when NOT_MANAGED_WITH_DATA
35
- ::HostStatus::Global::WARN
36
29
  end
37
30
  end
38
31
 
39
- def to_status(data: false)
40
- if insights_param
41
- return REPORTING if data
42
- return in_interval? ? REPORTING : NO_REPORT
43
- end
32
+ def to_status
33
+ in_interval? ? REPORTING : NO_REPORT
34
+ end
44
35
 
45
- data ? NOT_MANAGED_WITH_DATA : NOT_MANAGED
36
+ # prevent creation of the status on global refresh, but show it if the record already exists
37
+ def relevant?(_options = {})
38
+ persisted?
46
39
  end
47
40
 
48
41
  private
@@ -51,8 +44,4 @@ class InsightsClientReportStatus < HostStatus::Status
51
44
  return false unless reported_at
52
45
  (Time.now.utc - reported_at).to_i < REPORT_INTERVAL.to_i
53
46
  end
54
-
55
- def insights_param
56
- host.host_params_hash.dig('host_registration_insights', :value)
57
- end
58
47
  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
 
@@ -61,10 +56,6 @@ module ForemanRhCloud
61
56
 
62
57
  def path_params(request_path, certs)
63
58
  case request_path
64
- when metadata_request?
65
- {
66
- url: ForemanRhCloud.base_url + request_path.sub('/redhat_access/r/insights', '/api'),
67
- }
68
59
  when platform_request?
69
60
  {
70
61
  url: ForemanRhCloud.cert_base_url + request_path.sub('/redhat_access/r/insights/platform', '/api'),
@@ -81,10 +72,6 @@ module ForemanRhCloud
81
72
  end
82
73
  end
83
74
 
84
- def metadata_request?
85
- ->(request_path) { request_path.include? '/static' }
86
- end
87
-
88
75
  def platform_request?
89
76
  ->(request_path) { request_path.include? '/platform' }
90
77
  end
@@ -0,0 +1,17 @@
1
+ module ForemanRhCloud
2
+ class InsightsStatusCleaner
3
+ def clean(host_search)
4
+ host_ids = Host.search_for(host_search).pluck(:id)
5
+
6
+ # delete all insights status records for the hosts
7
+ deleted_count = InsightsClientReportStatus.where(host_id: host_ids).delete_all
8
+
9
+ # refresh global status
10
+ Host.where(id: host_ids).preload(:host_statuses).find_in_batches do |hosts|
11
+ hosts.each { |host| host.refresh_global_status! }
12
+ end
13
+
14
+ deleted_count
15
+ end
16
+ end
17
+ end
@@ -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
  )