foreman_rh_cloud 5.0.30 → 5.0.33

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/rh_cloud/cloud_request_controller.rb +83 -0
  3. data/app/controllers/foreman_inventory_upload/uploads_controller.rb +7 -0
  4. data/app/helpers/foreman_inventory_upload_host_helper.rb +2 -1
  5. data/app/models/setting/rh_cloud.rb +2 -1
  6. data/app/services/foreman_rh_cloud/cloud_ping_service.rb +4 -1
  7. data/app/services/foreman_rh_cloud/cloud_presence.rb +124 -0
  8. data/app/services/foreman_rh_cloud/cloud_request.rb +8 -1
  9. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +1 -1
  10. data/app/services/foreman_rh_cloud/hit_remediations_retriever.rb +67 -0
  11. data/app/services/foreman_rh_cloud/remediations_retriever.rb +16 -45
  12. data/app/services/foreman_rh_cloud/template_renderer_helper.rb +13 -1
  13. data/app/services/foreman_rh_cloud/url_remediations_retriever.rb +37 -0
  14. data/app/views/job_templates/rh_cloud_download_playbook.erb +26 -0
  15. data/config/routes.rb +2 -0
  16. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +3 -1
  17. data/lib/foreman_rh_cloud/engine.rb +13 -2
  18. data/lib/foreman_rh_cloud/version.rb +1 -1
  19. data/lib/foreman_rh_cloud.rb +11 -1
  20. data/lib/insights_cloud/async/connector_playbook_execution_reporter_task.rb +193 -0
  21. data/lib/insights_cloud/generators/playbook_progress_generator.rb +49 -0
  22. data/lib/tasks/insights.rake +13 -0
  23. data/package.json +1 -1
  24. data/test/controllers/insights_cloud/api/cloud_request_controller_test.rb +78 -0
  25. data/test/controllers/inventory_upload/cloud_status_controller_test.rb +2 -0
  26. data/test/jobs/connector_playbook_execution_reporter_task_test.rb +207 -0
  27. data/test/unit/fact_helpers_test.rb +2 -2
  28. data/test/unit/foreman_rh_cloud_self_host_test.rb +7 -0
  29. data/test/unit/playbook_progress_generator_test.rb +75 -0
  30. data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +19 -0
  31. data/test/unit/services/foreman_rh_cloud/cloud_status_service_test.rb +4 -0
  32. data/test/unit/services/foreman_rh_cloud/{remediations_retriever_test.rb → hit_remediations_retriever_test.rb} +3 -3
  33. data/test/unit/services/foreman_rh_cloud/url_remediations_retriever_test.rb +27 -0
  34. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +1 -1
  35. data/webpack/InsightsHostDetailsTab/InsightsTotalRiskChart.js +1 -1
  36. metadata +19 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 652e5780da34877a7db2beabee9d7853df3e92d56e9336b135c2f5c10e591135
4
- data.tar.gz: 41d79413f8cda24474d233512b75b301277058fec819cd0d8eb19c7ea24465b7
3
+ metadata.gz: bc3c3d4f7552bd3c599539ccb241473e38654c058ad4951e0e668b20d4648c67
4
+ data.tar.gz: 4545a0307c6eb685c2f84543530af13a25c984d605b9fcb01b1e3eb82c3618f2
5
5
  SHA512:
6
- metadata.gz: 5f570c0fce387859fb5cd268452591bf7ab85033600571aa0953173ab2d906bcfc22f5f2dbba5868d88c7af86a4442a4c56b45e719c8f0c0f983a14f039a2b27
7
- data.tar.gz: faa24509c2c3f8ef000c41bbbc0cddbc5352dc50998345883030b904d251cf8ee705a635caaf8ca3e9c84be38f188d529e60d5435dd506b76a7dac0a419e89db
6
+ metadata.gz: a147e2ceb11d2834af97ca954ea8c839bfe663a684fdac16e309ee4f003d3509f38dde84b75e3b06d837de390336541eb7b6c08259dfa9871d681a98cc717363
7
+ data.tar.gz: b176f027e036d865cdf31541af29fc09487407e3f8c95e83bb2c76a3989360e35939762e52de75d0a9df260eb7931ac5b0ca69fa32fe88d496896893103c2a9d
@@ -0,0 +1,83 @@
1
+ module Api::V2::RhCloud
2
+ class CloudRequestController < ::Api::V2::BaseController
3
+ layout false
4
+
5
+ KNOWN_DIRECTIVES = {
6
+ 'playbook-sat' => :handle_run_playbook_request,
7
+ 'foreman_rh_cloud' => :handle_run_playbook_request,
8
+ }
9
+
10
+ def update
11
+ handler = KNOWN_DIRECTIVES[directive]
12
+
13
+ unless handler
14
+ render json: {
15
+ :message => "No valid handler is found for directive: #{directive}",
16
+ }, status: :bad_request
17
+ return
18
+ end
19
+
20
+ send(handler)
21
+
22
+ render json: {
23
+ :message => "Handled #{directive} by #{handler}",
24
+ }
25
+ end
26
+
27
+ private
28
+
29
+ def metadata
30
+ params['metadata']
31
+ end
32
+
33
+ def content
34
+ # the content received as base 64 of the string in double quotes
35
+ Base64.decode64(params['content']).tr('"', '')
36
+ end
37
+
38
+ def directive
39
+ params['directive']
40
+ end
41
+
42
+ def handle_run_playbook_request
43
+ logger.error("API token is not set, unable to fetch data from the cloud") && return if Setting[:rh_cloud_token].empty?
44
+ logger.error("Playbook URL is not valid: #{content}") && return unless valid_url?(content)
45
+ logger.error("Reporting URL is not valid: #{metadata['return_url']}") && return unless valid_url?(metadata['return_url'])
46
+
47
+ hosts = metadata['hosts'].split(',')
48
+ host_ids = host_ids(hosts)
49
+
50
+ logger.warn("Some hosts were not found. Looked for: #{hosts}, found ids: #{host_ids}") unless host_ids.length == hosts.length
51
+
52
+ logger.error("sat_org_id is not present in the metadata") && return unless metadata['sat_org_id']
53
+ org_id = metadata['sat_org_id'].to_i
54
+ organization = Organization.find(org_id)
55
+
56
+ composer = nil
57
+ Organization.as_org(organization) do
58
+ composer = ::JobInvocationComposer.for_feature(
59
+ :rh_cloud_connector_run_playbook,
60
+ host_ids,
61
+ {
62
+ playbook_url: content,
63
+ report_url: metadata['return_url'],
64
+ report_interval: metadata['response_interval'].to_i,
65
+ correlation_id: metadata['correlation_id'],
66
+ }
67
+ )
68
+ composer.trigger!
69
+ end
70
+
71
+ composer.job_invocation
72
+ end
73
+
74
+ def valid_url?(url)
75
+ parsed = URI(url)
76
+ ForemanRhCloud.cloud_url_validator.match(parsed.host)
77
+ end
78
+
79
+ def host_ids(hosts)
80
+ InsightsFacet.where(uuid: hosts).pluck(:host_id)
81
+ end
82
+ end
83
+ end
@@ -18,6 +18,13 @@ module ForemanInventoryUpload
18
18
  end
19
19
 
20
20
  def enable_cloud_connector
21
+ Organization.unscoped.each do |org|
22
+ presence = ForemanRhCloud::CloudPresence.new(org, logger)
23
+ presence.announce_to_sources
24
+ rescue StandardError => ex
25
+ logger.warn(ex)
26
+ end
27
+
21
28
  cloud_connector = ForemanRhCloud::CloudConnector.new
22
29
  render json: cloud_connector.install.to_json
23
30
  end
@@ -5,8 +5,9 @@ module ForemanInventoryUploadHostHelper
5
5
 
6
6
  def hits_counts_cell(host)
7
7
  host_hits = hits_counts[host.id]
8
+ host_link = Setting['host_details_ui'] ? "#{host_details_page_path(host)}#/Insights" : "#{host_path(host)}#insights"
8
9
  tag.td class: ['hidden-xs', 'ellipsis', 'text-center'] do
9
- link_to(host_hits, "#{host_path(host)}#insights") if host_hits
10
+ link_to(host_hits, host_link) if host_hits
10
11
  end
11
12
  end
12
13
  end
@@ -1,5 +1,5 @@
1
1
  class Setting::RhCloud < Setting
2
- ::Setting::BLANK_ATTRS.concat %w{rh_cloud_token}
2
+ ::Setting::BLANK_ATTRS.concat %w{rh_cloud_token rhc_instance_id}
3
3
 
4
4
  def self.load_defaults
5
5
  return false unless table_exists?
@@ -20,6 +20,7 @@ class Setting::RhCloud < Setting
20
20
  set('rh_cloud_token', N_('Authentication token to Red Hat cloud services. Used to authenticate requests to cloud APIs'), nil, N_('Red Hat Cloud token'), nil, encrypted: true),
21
21
  set('exclude_installed_packages', N_('Exclude installed packages from being uploaded to the Red Hat cloud'), false, N_("Exclude installed Packages")),
22
22
  set('include_parameter_tags', N_('Should import include parameter tags from Foreman?'), false, N_('Include parameters in insights-client reports')),
23
+ set('rhc_instance_id', N_('RHC daemon id'), nil, N_('ID of the RHC(Yggdrasil) daemon')),
23
24
  ]
24
25
  end
25
26
 
@@ -39,6 +39,9 @@ module ForemanRhCloud
39
39
  certs = candlepin_id_cert(@org)
40
40
  return StandardError.new('certificate missing') unless certs
41
41
 
42
+ cert_checker = Katello::UpstreamConnectionChecker.new(@org)
43
+ cert_checker.assert_connection
44
+
42
45
  execute_cloud_request(
43
46
  method: :get,
44
47
  url: ForemanRhCloud.cert_base_url + "/api/apicast-tests/ping",
@@ -72,7 +75,7 @@ module ForemanRhCloud
72
75
  org,
73
76
  {
74
77
  success: cert_response.is_a?(RestClient::Response),
75
- error: (cert_response.is_a?(Exception) ? cert_response.inspect : nil),
78
+ error: (cert_response.is_a?(Exception) ? cert_response&.message || cert_response.inspect : nil),
76
79
  },
77
80
  ]
78
81
  end
@@ -0,0 +1,124 @@
1
+ module ForemanRhCloud
2
+ class CloudPresence
3
+ include InsightsCloud::CandlepinCache
4
+ include ForemanRhCloud::CloudRequest
5
+
6
+ attr_reader :organization, :logger
7
+
8
+ def initialize(organization, logger)
9
+ @organization = organization
10
+ @logger = logger
11
+ end
12
+
13
+ def announce_to_sources
14
+ register_rhc_instance
15
+ end
16
+
17
+ def satellite_source_type
18
+ @satellite_source_type ||= begin
19
+ source_type_response = JSON.parse(
20
+ execute_cloud_request(
21
+ method: :get,
22
+ url: source_type_url,
23
+ headers: {
24
+ content_type: :json,
25
+ },
26
+ ssl_client_cert: OpenSSL::X509::Certificate.new(certs[:cert]),
27
+ ssl_client_key: OpenSSL::PKey::RSA.new(certs[:key])
28
+ )
29
+ )
30
+
31
+ source_type_response['data'].first['id']
32
+ end
33
+ end
34
+
35
+ def satellite_instance_source
36
+ @satellite_instance_source ||= begin
37
+ source_response = JSON.parse(
38
+ execute_cloud_request(
39
+ method: :get,
40
+ url: satellite_instance_source_url,
41
+ headers: {
42
+ content_type: :json,
43
+ },
44
+ ssl_client_cert: OpenSSL::X509::Certificate.new(certs[:cert]),
45
+ ssl_client_key: OpenSSL::PKey::RSA.new(certs[:key])
46
+ )
47
+ )
48
+
49
+ result = source_response['data'].first
50
+ result&.dig('id')
51
+ end
52
+ end
53
+
54
+ def create_satellite_instance_source
55
+ create_response = JSON.parse(
56
+ execute_cloud_request(
57
+ method: :post,
58
+ url: create_satellite_instance_source_url,
59
+ headers: {
60
+ content_type: :json,
61
+ },
62
+ ssl_client_cert: OpenSSL::X509::Certificate.new(certs[:cert]),
63
+ ssl_client_key: OpenSSL::PKey::RSA.new(certs[:key]),
64
+ payload: {
65
+ name: "satellite: #{Foreman.instance_id} org: #{@organization.name}",
66
+ source_ref: Foreman.instance_id,
67
+ source_type_id: satellite_source_type,
68
+ }.to_json
69
+ )
70
+ )
71
+
72
+ @satellite_instance_source = create_response['id']
73
+ end
74
+
75
+ def register_rhc_instance
76
+ raise Foreman::Exception.new('rhc_instance_id is empty, cannot register RHC to the cloud') if Setting[:rhc_instance_id].empty?
77
+ source_id = satellite_instance_source || create_satellite_instance_source
78
+
79
+ create_response = JSON.parse(
80
+ execute_cloud_request(
81
+ method: :post,
82
+ url: create_rhc_connections_url,
83
+ headers: {
84
+ content_type: :json,
85
+ },
86
+ ssl_client_cert: OpenSSL::X509::Certificate.new(certs[:cert]),
87
+ ssl_client_key: OpenSSL::PKey::RSA.new(certs[:key]),
88
+ payload: {
89
+ source_id: source_id,
90
+ rhc_id: Setting[:rhc_instance_id],
91
+ }.to_json
92
+ )
93
+ )
94
+
95
+ @satellite_instance_source = create_response['id']
96
+ end
97
+
98
+ private
99
+
100
+ def sources_url(path)
101
+ "#{ForemanRhCloud.cert_base_url}/api/sources/v3.1#{path}"
102
+ end
103
+
104
+ def source_type_url
105
+ sources_url('/source_types?filter[name]=satellite')
106
+ end
107
+
108
+ def satellite_instance_source_url
109
+ sources_url("/sources?filter[source_ref]=#{Foreman.instance_id}")
110
+ end
111
+
112
+ def create_satellite_instance_source_url
113
+ sources_url('/sources')
114
+ end
115
+
116
+ def create_rhc_connections_url
117
+ sources_url('/rhc_connections')
118
+ end
119
+
120
+ def certs
121
+ @certs ||= candlepin_id_cert(@organization)
122
+ end
123
+ end
124
+ end
@@ -8,7 +8,14 @@ module ForemanRhCloud
8
8
  proxy: ForemanRhCloud.transformed_http_proxy_string(logger: logger),
9
9
  }.deep_merge(params)
10
10
 
11
- RestClient::Request.execute(final_params)
11
+ response = RestClient::Request.execute(final_params)
12
+
13
+ logger.debug("Response headers for request url #{final_params[:url]} are: #{response.headers}")
14
+
15
+ response
16
+ rescue RestClient::Exception => ex
17
+ logger.debug("Failed response with code #{ex.http_code} headers for request url #{final_params[:url]} are: #{ex.http_headers} and body: #{ex.http_body}")
18
+ raise ex
12
19
  end
13
20
  end
14
21
  end
@@ -28,7 +28,7 @@ module ForemanRhCloud
28
28
  headers: {
29
29
  params: forward_params,
30
30
  user_agent: http_user_agent(original_request),
31
- content_type: original_request.media_type,
31
+ content_type: original_request.media_type.presence || original_request.format.to_s,
32
32
  },
33
33
  }
34
34
  base_params.merge(path_params(original_request.path, certs))
@@ -0,0 +1,67 @@
1
+ module ForemanRhCloud
2
+ class HitRemediationsRetriever < RemediationsRetriever
3
+ def initialize(hit_remediation_pairs, logger: Logger.new(IO::NULL))
4
+ super(logger: logger)
5
+ @hit_remediation_pairs = hit_remediation_pairs
6
+ logger.debug("Querying playbook for #{hit_remediation_pairs}")
7
+ end
8
+
9
+ private
10
+
11
+ def hit_ids
12
+ @hit_remediation_pairs.map { |pair| pair["hit_id"] }
13
+ end
14
+
15
+ def remediation_ids
16
+ @hit_remediation_pairs.map { |pair| pair["resolution_id"] }
17
+ end
18
+
19
+ def hits
20
+ @hits ||= Hash[
21
+ InsightsHit.joins(:insights_facet).where(id: hit_ids).pluck(:id, 'insights_facets.uuid')
22
+ ]
23
+ end
24
+
25
+ def pairs_by_remediation_id
26
+ @hit_remediation_pairs.group_by { |pair| pair["resolution_id"] }
27
+ end
28
+
29
+ def remediations
30
+ @remediations ||= Hash[
31
+ InsightsResolution.where(id: remediation_ids).pluck(:id, :resolution_type, :rule_id).map do |id, resolution_type, rule_id|
32
+ [id, {resolution_type: resolution_type, rule_id: rule_id}]
33
+ end
34
+ ]
35
+ end
36
+
37
+ def playbook_request
38
+ {
39
+ issues: pairs_by_remediation_id.map do |remediation_id, pairs|
40
+ {
41
+ resolution: remediations[remediation_id][:resolution_type],
42
+ id: InsightsCloud.remediation_rule_id(remediations[remediation_id][:rule_id]),
43
+ systems: pairs.map do |pair|
44
+ hits[pair["hit_id"]]
45
+ end,
46
+ }
47
+ end,
48
+ }
49
+ end
50
+
51
+ def playbook_url
52
+ InsightsCloud.playbook_url
53
+ end
54
+
55
+ def headers
56
+ super
57
+ end
58
+
59
+ def payload
60
+ playbook_request.to_json
61
+ end
62
+
63
+ def method
64
+ :post
65
+ end
66
+ end
67
+ end
@@ -4,11 +4,8 @@ module ForemanRhCloud
4
4
 
5
5
  attr_reader :logger
6
6
 
7
- def initialize(hit_remediation_pairs, logger: Logger.new(IO::NULL))
8
- @hit_remediation_pairs = hit_remediation_pairs
7
+ def initialize(logger: Logger.new(IO::NULL))
9
8
  @logger = logger
10
-
11
- logger.debug("Querying playbook for #{hit_remediation_pairs}")
12
9
  end
13
10
 
14
11
  def create_playbook
@@ -26,55 +23,29 @@ module ForemanRhCloud
26
23
 
27
24
  private
28
25
 
29
- def hit_ids
30
- @hit_remediation_pairs.map { |pair| pair["hit_id"] }
31
- end
32
-
33
- def remediation_ids
34
- @hit_remediation_pairs.map { |pair| pair["resolution_id"] }
35
- end
36
-
37
- def hits
38
- @hits ||= Hash[
39
- InsightsHit.joins(:insights_facet).where(id: hit_ids).pluck(:id, 'insights_facets.uuid')
40
- ]
41
- end
42
-
43
- def pairs_by_remediation_id
44
- @hit_remediation_pairs.group_by { |pair| pair["resolution_id"] }
26
+ def query_playbook
27
+ execute_cloud_request(
28
+ method: method,
29
+ url: playbook_url,
30
+ headers: headers,
31
+ payload: payload
32
+ )
45
33
  end
46
34
 
47
- def remediations
48
- @remediations ||= Hash[
49
- InsightsResolution.where(id: remediation_ids).pluck(:id, :resolution_type, :rule_id).map do |id, resolution_type, rule_id|
50
- [id, {resolution_type: resolution_type, rule_id: rule_id}]
51
- end
52
- ]
35
+ def playbook_url
53
36
  end
54
37
 
55
- def playbook_request
38
+ def headers
56
39
  {
57
- issues: pairs_by_remediation_id.map do |remediation_id, pairs|
58
- {
59
- resolution: remediations[remediation_id][:resolution_type],
60
- id: InsightsCloud.remediation_rule_id(remediations[remediation_id][:rule_id]),
61
- systems: pairs.map do |pair|
62
- hits[pair["hit_id"]]
63
- end,
64
- }
65
- end,
40
+ content_type: :json,
66
41
  }
67
42
  end
68
43
 
69
- def query_playbook
70
- execute_cloud_request(
71
- method: :post,
72
- url: InsightsCloud.playbook_url,
73
- headers: {
74
- content_type: :json,
75
- },
76
- payload: playbook_request.to_json
77
- )
44
+ def payload
45
+ end
46
+
47
+ def method
48
+ :get
78
49
  end
79
50
  end
80
51
  end
@@ -15,8 +15,20 @@ module ForemanRhCloud
15
15
  end
16
16
  def remediations_playbook(hit_remediation_pairs)
17
17
  hit_remediation_pairs = JSON.parse(hit_remediation_pairs)
18
- retriever = ForemanRhCloud::RemediationsRetriever.new(hit_remediation_pairs, logger: template_logger)
18
+ retriever = ForemanRhCloud::HitRemediationsRetriever.new(hit_remediation_pairs, logger: template_logger)
19
19
  retriever.create_playbook
20
20
  end
21
+
22
+ apipie :method, 'Returns a Red Hat remediation playbook compiled on console.redhat.com' do
23
+ required :remediation_path, String, desc: ''
24
+ returns String, desc: 'Playbook downloaded from the cloud'
25
+ end
26
+ def download_rh_playbook(playbook_url)
27
+ retriever = ForemanRhCloud::UrlRemediationsRetriever.new(url: playbook_url, logger: template_logger)
28
+
29
+ cached("rh_playbook_#{playbook_url}") do
30
+ retriever.create_playbook
31
+ end
32
+ end
21
33
  end
22
34
  end
@@ -0,0 +1,37 @@
1
+ module ForemanRhCloud
2
+ class UrlRemediationsRetriever < RemediationsRetriever
3
+ attr_reader :url, :payload, :headers
4
+
5
+ def initialize(url:, payload: '', headers: {}, logger: Logger.new(IO::NULL))
6
+ super(logger: logger)
7
+
8
+ @url = url
9
+ @payload = payload
10
+ @headers = headers
11
+ end
12
+
13
+ private
14
+
15
+ def query_playbook
16
+ logger.debug("Querying playbook at: #{url} with payload: #{payload} and headers: #{headers}")
17
+
18
+ super
19
+ end
20
+
21
+ def playbook_url
22
+ @url
23
+ end
24
+
25
+ def headers
26
+ super.deep_merge(@headers)
27
+ end
28
+
29
+ def payload
30
+ @payload.to_json
31
+ end
32
+
33
+ def method
34
+ :get
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,26 @@
1
+ <%#
2
+ kind: job_template
3
+ name: Run a playbook downloaded from RH cloud
4
+ job_category: Red Hat Insights
5
+ description_format: 'Playbook generated by RH Cloud'
6
+ feature: rh_cloud_connector_run_playbook
7
+ template_inputs:
8
+ - name: playbook_url
9
+ description: URL of the playbook to run
10
+ input_type: user
11
+ required: true
12
+ - name: report_url
13
+ description: URL for calling the report callback
14
+ input_type: user
15
+ required: true
16
+ - name: correlation_id
17
+ description: correlation ID used to identify the original calling message
18
+ input_type: user
19
+ required: true
20
+ - name: report_interval
21
+ description: Reporting interval for the task. A report will be generated every report_interval seconds.
22
+ input_type: user
23
+ required: true
24
+ provider_type: Ansible
25
+ %>
26
+ <%= download_rh_playbook(input('playbook_url')) %>
data/config/routes.rb CHANGED
@@ -58,6 +58,8 @@ Rails.application.routes.draw do
58
58
 
59
59
  namespace 'rh_cloud' do
60
60
  post 'enable_connector', to: 'inventory#enable_cloud_connector'
61
+
62
+ post 'cloud_request', to: 'cloud_request#update'
61
63
  end
62
64
  end
63
65
  end
@@ -104,7 +104,9 @@ module ForemanInventoryUpload
104
104
  end
105
105
 
106
106
  def obfuscate_ip(ip, ips_dict)
107
- "10.230.230.#{ips_dict.count + 1}"
107
+ max_obfuscated = ips_dict.values.map { |v| IPAddr.new(v).to_i }.max || IPAddr.new('10.230.230.0').to_i
108
+
109
+ IPAddr.new(max_obfuscated + 1, Socket::AF_INET).to_s
108
110
  end
109
111
 
110
112
  def bios_uuid(host)
@@ -76,9 +76,13 @@ module ForemanRhCloud
76
76
  },
77
77
  :resource_type => ::InsightsHit.name
78
78
  )
79
+ permission(
80
+ :dispatch_cloud_requests,
81
+ 'api/v2/rh_cloud/cloud_request': [:update]
82
+ )
79
83
  end
80
84
 
81
- plugin_permissions = [:view_foreman_rh_cloud, :generate_foreman_rh_cloud, :view_insights_hits]
85
+ plugin_permissions = [:view_foreman_rh_cloud, :generate_foreman_rh_cloud, :view_insights_hits, :dispatch_cloud_requests]
82
86
 
83
87
  role 'ForemanRhCloud', plugin_permissions, 'Role granting permissions to view the hosts inventory,
84
88
  generate a report, upload it to the cloud and download it locally'
@@ -116,7 +120,7 @@ module ForemanRhCloud
116
120
  end
117
121
 
118
122
  extend_template_helpers ForemanRhCloud::TemplateRendererHelper
119
- allowed_template_helpers :remediations_playbook
123
+ allowed_template_helpers :remediations_playbook, :download_rh_playbook
120
124
  end
121
125
 
122
126
  ::Katello::UINotifications::Subscriptions::ManifestImportSuccess.include ForemanInventoryUpload::Notifications::ManifestImportSuccessNotificationOverride if defined?(Katello)
@@ -145,6 +149,13 @@ module ForemanRhCloud
145
149
  description: N_('Run remediation playbook generated by Insights'),
146
150
  host_action_button: false
147
151
  )
152
+ RemoteExecutionFeature.register(
153
+ :rh_cloud_connector_run_playbook,
154
+ N_('Run RH Cloud playbook'),
155
+ description: N_('Run playbook genrated by Red Hat remediations app'),
156
+ host_action_button: false,
157
+ provided_inputs: ['playbook_url', 'report_url', 'correlation_id', 'report_interval']
158
+ )
148
159
  # skip object creation when admin user is not present, for example in test DB
149
160
  if User.unscoped.find_by_login(User::ANONYMOUS_ADMIN).present?
150
161
  ::ForemanTasks.dynflow.config.on_init(false) do |world|
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '5.0.30'.freeze
2
+ VERSION = '5.0.33'.freeze
3
3
  end
@@ -109,10 +109,20 @@ module ForemanRhCloud
109
109
  end
110
110
 
111
111
  def self.foreman_host_name
112
- ENV['SATELLITE_RH_CLOUD_FOREMAN_HOST'] || ::SmartProxy.default_capsule.name
112
+ ENV['SATELLITE_RH_CLOUD_FOREMAN_HOST'] || marked_foreman_host&.name || ::SmartProxy.default_capsule.name
113
+ end
114
+
115
+ def self.marked_foreman_host
116
+ ::Host.unscoped.search_for('infrastructure_facet.foreman = true').first
117
+ rescue ScopedSearch::QueryNotSupported
118
+ nil
113
119
  end
114
120
 
115
121
  def self.legacy_insights_ca
116
122
  "#{ForemanRhCloud::Engine.root}/config/rh_cert-api_chain.pem"
117
123
  end
124
+
125
+ def self.cloud_url_validator
126
+ @cloud_url_validator ||= Regexp.new(ENV['SATELLITE_RH_CLOUD_VALIDATOR'] || 'redhat.com$')
127
+ end
118
128
  end