foreman_rh_cloud 5.0.32 → 5.0.35
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/api/v2/rh_cloud/cloud_request_controller.rb +83 -0
- data/app/controllers/foreman_inventory_upload/uploads_controller.rb +7 -0
- data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +13 -2
- data/app/controllers/insights_cloud/hits_controller.rb +8 -1
- data/app/models/setting/rh_cloud.rb +2 -1
- data/app/services/foreman_rh_cloud/cloud_connector.rb +1 -1
- data/app/services/foreman_rh_cloud/cloud_presence.rb +124 -0
- data/app/services/foreman_rh_cloud/cloud_request.rb +8 -1
- data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +16 -5
- data/app/services/foreman_rh_cloud/hit_remediations_retriever.rb +67 -0
- data/app/services/foreman_rh_cloud/remediations_retriever.rb +16 -45
- data/app/services/foreman_rh_cloud/template_renderer_helper.rb +13 -1
- data/app/services/foreman_rh_cloud/url_remediations_retriever.rb +37 -0
- data/app/views/job_templates/cloud_connector.erb +30 -0
- data/app/views/job_templates/rh_cloud_download_playbook.erb +26 -0
- data/config/routes.rb +2 -0
- data/lib/foreman_rh_cloud/engine.rb +33 -12
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/foreman_rh_cloud.rb +4 -0
- data/lib/insights_cloud/async/connector_playbook_execution_reporter_task.rb +193 -0
- data/lib/insights_cloud/async/insights_scheduled_sync.rb +4 -0
- data/lib/insights_cloud/generators/playbook_progress_generator.rb +49 -0
- data/lib/tasks/insights.rake +13 -0
- data/package.json +1 -1
- data/test/controllers/insights_cloud/api/cloud_request_controller_test.rb +78 -0
- data/test/controllers/insights_cloud/api/machine_telemetries_controller_test.rb +16 -0
- data/test/jobs/connector_playbook_execution_reporter_task_test.rb +207 -0
- data/test/unit/playbook_progress_generator_test.rb +75 -0
- data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +13 -8
- data/test/unit/services/foreman_rh_cloud/{remediations_retriever_test.rb → hit_remediations_retriever_test.rb} +3 -3
- data/test/unit/services/foreman_rh_cloud/url_remediations_retriever_test.rb +27 -0
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableActions.js +6 -11
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableHelpers.js +22 -0
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationActions.js +6 -1
- data/webpack/InsightsHostDetailsTab/InsightsTotalRiskChart.js +3 -2
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 437d70d98a43e88f7835426bf1a8ae7995a2b759038e3a5908dc41e122544ed1
|
4
|
+
data.tar.gz: a655276cda12b06662db3670019747c518e9204c22ca8ad3591024945dd48fb8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d59ebbe9a845efd88c9d70f1d44ff9ebae7e5faabd947c3ba3d48e5f22435c97052be363839805208b381fea29f643a35ef241f2ff0ae462d1720d6ff5fd538
|
7
|
+
data.tar.gz: f7d94f184cbeba9d50b6e8a83d71db08a3c6417972b6d51b6ca247558a4769a6f17fbfdae37f9e4f5efe2a73a8095885a44e109d2b736fbc1d824f9e68528fe1
|
@@ -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,14 +37,25 @@ 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
|
-
|
46
|
+
headers[Rack::ETAG] = @cloud_response.headers[:etag]
|
42
47
|
|
43
48
|
render json: @cloud_response, status: @cloud_response.code
|
44
49
|
end
|
45
50
|
|
46
51
|
def branch_info
|
47
|
-
|
52
|
+
payload = nil
|
53
|
+
|
54
|
+
User.as_anonymous_admin do
|
55
|
+
payload = ForemanRhCloud::BranchInfo.new.generate(@uuid, @host, @branch_id, request.host).to_json
|
56
|
+
end
|
57
|
+
|
58
|
+
render :json => payload
|
48
59
|
end
|
49
60
|
|
50
61
|
def assign_header(res, cloud_res, header, transform)
|
@@ -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:
|
26
|
+
hits: hits,
|
20
27
|
}, status: :ok
|
21
28
|
end
|
22
29
|
|
@@ -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
|
-
{:
|
19
|
+
{:satellite_cloud_connector_user => service_user.login, :satellite_cloud_connector_password => token_value}
|
20
20
|
)
|
21
21
|
composer.trigger!
|
22
22
|
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
|
-
|
30
|
-
|
31
|
-
|
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(
|
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
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
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
|
38
|
+
def headers
|
56
39
|
{
|
57
|
-
|
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
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
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::
|
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')) %>
|