foreman_rh_cloud 5.0.31 → 5.0.34

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) 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/controllers/insights_cloud/api/machine_telemetries_controller.rb +6 -1
  5. data/app/controllers/insights_cloud/hits_controller.rb +8 -1
  6. data/app/helpers/foreman_inventory_upload_host_helper.rb +2 -1
  7. data/app/models/setting/rh_cloud.rb +2 -1
  8. data/app/services/foreman_rh_cloud/cloud_connector.rb +1 -1
  9. data/app/services/foreman_rh_cloud/cloud_ping_service.rb +4 -1
  10. data/app/services/foreman_rh_cloud/cloud_presence.rb +124 -0
  11. data/app/services/foreman_rh_cloud/cloud_request.rb +8 -1
  12. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +16 -5
  13. data/app/services/foreman_rh_cloud/hit_remediations_retriever.rb +67 -0
  14. data/app/services/foreman_rh_cloud/remediations_retriever.rb +16 -45
  15. data/app/services/foreman_rh_cloud/template_renderer_helper.rb +13 -1
  16. data/app/services/foreman_rh_cloud/url_remediations_retriever.rb +37 -0
  17. data/app/views/job_templates/cloud_connector.erb +30 -0
  18. data/app/views/job_templates/rh_cloud_download_playbook.erb +26 -0
  19. data/config/routes.rb +2 -0
  20. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +3 -1
  21. data/lib/foreman_rh_cloud/engine.rb +20 -2
  22. data/lib/foreman_rh_cloud/version.rb +1 -1
  23. data/lib/foreman_rh_cloud.rb +11 -1
  24. data/lib/insights_cloud/async/connector_playbook_execution_reporter_task.rb +193 -0
  25. data/lib/insights_cloud/generators/playbook_progress_generator.rb +49 -0
  26. data/lib/tasks/insights.rake +13 -0
  27. data/package.json +1 -1
  28. data/test/controllers/insights_cloud/api/cloud_request_controller_test.rb +78 -0
  29. data/test/controllers/inventory_upload/cloud_status_controller_test.rb +2 -0
  30. data/test/jobs/connector_playbook_execution_reporter_task_test.rb +207 -0
  31. data/test/unit/fact_helpers_test.rb +2 -2
  32. data/test/unit/foreman_rh_cloud_self_host_test.rb +7 -0
  33. data/test/unit/playbook_progress_generator_test.rb +75 -0
  34. data/test/unit/services/foreman_rh_cloud/cloud_status_service_test.rb +4 -0
  35. data/test/unit/services/foreman_rh_cloud/{remediations_retriever_test.rb → hit_remediations_retriever_test.rb} +3 -3
  36. data/test/unit/services/foreman_rh_cloud/url_remediations_retriever_test.rb +27 -0
  37. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +1 -1
  38. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableActions.js +6 -11
  39. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableHelpers.js +22 -0
  40. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationActions.js +6 -1
  41. data/webpack/InsightsHostDetailsTab/InsightsTotalRiskChart.js +3 -2
  42. metadata +20 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5de242348c67166e20efabc42ca1c4f1db9728fa456f17b2acdd8943df685e88
4
- data.tar.gz: 6077615ad33a58f582e1c0f16e85df6b0c50b58d1956415d90be37bb236b3aee
3
+ metadata.gz: '0389d4bf9e9af791b23a3ea7b271feca1385e2fcf4fc6acc7d954283477c8706'
4
+ data.tar.gz: 839cc45d7b92a308841f995152ae4a68503acd69feb95cd95b19772f99cec6c9
5
5
  SHA512:
6
- metadata.gz: b30c352883db5a9100846d9eb3e0fec08853706129d3ddf7d1faef8e5d825345faa4c11240e3afd61e5d422100a1691fafc7564a43a8e09ecf9849377a0a1a75
7
- data.tar.gz: 1aa622b93f13b5a938ae3ab7680967e9f677f0b421358e5c1f3400e77e3f26f8f45f0bac44b2c312793c72705863afb19c2515e982402a517cdac8acd62e057e
6
+ metadata.gz: 7b37d242c63e0260a76d06a6096ac569423237bf62f6e8685f79d6cf7b3e85246cfa92f35f0907a18b10539deb09f991189ea5914fa519236786aa2456e8aed6
7
+ data.tar.gz: e2baeab2eceeae447276db3ce9c8fa6c7236ff082eab418b835afea4c97ea9172a86eabeeb8ba430012f9662c26bd5a95cc86cc5f45e67a8f6ee4bb2d3a76ac8
@@ -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
@@ -37,8 +37,13 @@ module InsightsCloud::Api
37
37
  return send_data @cloud_response, disposition: @cloud_response.headers[:content_disposition], type: @cloud_response.headers[:content_type]
38
38
  end
39
39
 
40
+ # Append redhat-specific headers
41
+ @cloud_response.headers.each do |key, value|
42
+ assign_header(response, @cloud_response, key, false) if key.to_s.start_with?('x_rh_')
43
+ end
44
+ # Append general headers
40
45
  assign_header(response, @cloud_response, :x_resource_count, true)
41
- assign_header(response, @cloud_response, :x_rh_insights_request_id, false)
46
+ headers[Rack::ETAG] = @cloud_response.headers[:etag]
42
47
 
43
48
  render json: @cloud_response, status: @cloud_response.code
44
49
  end
@@ -14,9 +14,16 @@ module InsightsCloud
14
14
 
15
15
  def show
16
16
  host = Host.where(id: host_id_param).first
17
+ hits = host.insights&.hits
18
+
19
+ unless hits
20
+ return render json: {
21
+ error: 'No recommendations were found for this host',
22
+ }, status: :not_found
23
+ end
17
24
 
18
25
  render json: {
19
- hits: host.insights.hits,
26
+ hits: hits,
20
27
  }, status: :ok
21
28
  end
22
29
 
@@ -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
 
@@ -16,7 +16,7 @@ module ForemanRhCloud
16
16
  composer = ::JobInvocationComposer.for_feature(
17
17
  CLOUD_CONNECTOR_FEATURE,
18
18
  [target_host.id],
19
- {:satellite_user => service_user.login, :satellite_password => token_value}
19
+ {:satellite_cloud_connector_user => service_user.login, :satellite_cloud_connector_password => token_value}
20
20
  )
21
21
  composer.trigger!
22
22
  end
@@ -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
@@ -25,11 +25,12 @@ module ForemanRhCloud
25
25
  base_params = {
26
26
  method: original_request.method,
27
27
  payload: forward_payload,
28
- headers: {
29
- params: forward_params,
30
- user_agent: http_user_agent(original_request),
31
- content_type: original_request.media_type.presence || original_request.format.to_s,
32
- },
28
+ headers: original_headers(original_request).merge(
29
+ {
30
+ params: forward_params,
31
+ user_agent: http_user_agent(original_request),
32
+ content_type: original_request.media_type.presence || original_request.format.to_s,
33
+ }),
33
34
  }
34
35
  base_params.merge(path_params(original_request.path, certs))
35
36
  end
@@ -80,6 +81,16 @@ module ForemanRhCloud
80
81
  end
81
82
  end
82
83
 
84
+ def original_headers(original_request)
85
+ headers = {
86
+ if_none_match: original_request.if_none_match,
87
+ if_modified_since: original_request.if_modified_since,
88
+ }.compact
89
+
90
+ logger.debug("Sending headers: #{headers}")
91
+ headers
92
+ end
93
+
83
94
  def platform_request?
84
95
  ->(request_path) { request_path.include? '/platform' }
85
96
  end
@@ -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,30 @@
1
+ <%#
2
+ name: Configure Cloud Connector
3
+ snippet: false
4
+ template_inputs:
5
+ - name: satellite_cloud_connector_user
6
+ required: true
7
+ input_type: user
8
+ advanced: false
9
+ value_type: plain
10
+ hidden_value: false
11
+ - name: satellite_cloud_connector_password
12
+ required: true
13
+ input_type: user
14
+ advanced: false
15
+ value_type: plain
16
+ hidden_value: true
17
+ model: JobTemplate
18
+ job_category: Maintenance Operations
19
+ description_format: "%{template_name}"
20
+ provider_type: Ansible
21
+ kind: job_template
22
+ feature: ansible_configure_cloud_connector
23
+ %>
24
+
25
+ ---
26
+ - hosts: all
27
+ vars:
28
+ satellite_cloud_connector_url: "<%= foreman_server_url %>"
29
+ roles:
30
+ - redhat.satellite_operations.cloud_connector
@@ -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)