foreman_rh_cloud 11.4.4 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/app/controllers/api/v2/rh_cloud/inventory_controller.rb +2 -2
  4. data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +22 -26
  5. data/app/services/foreman_rh_cloud/cloud_request.rb +2 -12
  6. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +3 -17
  7. data/app/services/foreman_rh_cloud/rules_ingester.rb +1 -12
  8. data/config/routes.rb +0 -4
  9. data/lib/foreman_inventory_upload/async/queue_for_upload_job.rb +3 -3
  10. data/lib/foreman_inventory_upload/async/upload_report_job.rb +4 -4
  11. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +13 -65
  12. data/lib/foreman_inventory_upload/generators/queries.rb +3 -5
  13. data/lib/foreman_inventory_upload/generators/slice.rb +1 -0
  14. data/lib/foreman_rh_cloud/engine.rb +0 -11
  15. data/lib/foreman_rh_cloud/version.rb +1 -1
  16. data/lib/foreman_rh_cloud.rb +0 -2
  17. data/lib/tasks/hybrid_cloud.rake +36 -94
  18. data/package.json +5 -5
  19. data/test/controllers/insights_cloud/api/machine_telemetries_controller_test.rb +2 -14
  20. data/test/controllers/inventory_upload/api/inventory_controller_test.rb +1 -1
  21. data/test/jobs/upload_report_job_test.rb +1 -1
  22. data/test/unit/fact_helpers_test.rb +2 -267
  23. data/test/unit/slice_generator_test.rb +10 -69
  24. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/__tests__/__snapshots__/ListItem.test.js.snap +1 -7
  25. data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/__tests__/__snapshots__/ListItemStatus.test.js.snap +1 -5
  26. data/webpack/ForemanInventoryUpload/Components/AccountList/accountList.scss +3 -3
  27. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilter.js +1 -1
  28. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/inventoryFilter.scss +1 -1
  29. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.scss +5 -5
  30. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageTitle.js +5 -4
  31. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +18 -3
  32. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButton.js +0 -1
  33. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButton.test.js.snap +0 -1
  34. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/__snapshots__/InventoryAutoUpload.test.js.snap +2 -10
  35. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +5 -1
  36. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTableConstants.js +1 -1
  37. data/webpack/InsightsCloudSync/Components/InsightsTable/Pagination.js +7 -7
  38. data/webpack/InsightsCloudSync/Components/InsightsTable/table.scss +1 -1
  39. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +5 -1
  40. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationTableConstants.js +8 -1
  41. data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +8 -2
  42. data/webpack/InsightsCloudSync/InsightsCloudSync.scss +1 -1
  43. data/webpack/InsightsHostDetailsTab/InsightsTotalRiskChart.js +11 -2
  44. data/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js +5 -4
  45. data/webpack/common/DropdownToggle.js +2 -2
  46. data/webpack/common/Switcher/HelpLabel.js +1 -1
  47. data/webpack/common/Switcher/SwitcherPF4.scss +1 -1
  48. data/webpack/common/Switcher/__tests__/__snapshots__/HelpLabel.test.js.snap +2 -6
  49. data/webpack/common/table/EmptyState.js +25 -18
  50. metadata +3 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a69803d7adc37a51cb851a218a60b2150a56503eccece90e30b688f1ec8a1ae6
4
- data.tar.gz: 1d79759ed6f0095579f485ead899d8708f151920f9c33e979797672ab78b1585
3
+ metadata.gz: d3666ab0afa45f6fbf3fbe06ec110cbbf7d7eca432b02686e945afca5b412f31
4
+ data.tar.gz: ce3380aca30486d23d89c3e9b30d17cbc862e51ba55032b1e60565ec63af1cc2
5
5
  SHA512:
6
- metadata.gz: a6b24e9d002cebdbfd00e74d08fbb04cfe8b413648d9e0ec3b60c1eb2222b652dbe14e5379cd5fbf9927b707144d7b4d61204ee490397cae187189012a153d67
7
- data.tar.gz: d63ecaa47ba66a4078b15367092840a44f219f1e99a5cb619bbc7fe7fe3f40569ac8068de89b98c08e2b1f7f4e0ff98502ce8b5a473b635367d80a1f077959e4
6
+ metadata.gz: b853fd7fe75e52c4127984c2644feb55fb455d52d68a86b55ed9d96b84e03d05408fc9ddf5190253d2938965c8583b33903682fabfe137f42ce06f57a2d96a09
7
+ data.tar.gz: fb4777f06aa6d47e0038cc3533b86779a95694c23e4d01b01bc78e10c07196f16df87ead87d4787e8c4dc518813d7ef4e250d8fe955857ebe6811ad5e8b0d3ec
data/README.md CHANGED
@@ -15,7 +15,7 @@ for how to install Foreman plugins
15
15
 
16
16
  #### Inventory upload
17
17
 
18
- In UI: Insights -> Inventory Upload -> select the organization -> Generate and upload report
18
+ In UI: Configure -> Inventory Upload -> Generate and upload report
19
19
 
20
20
  From command-line:
21
21
 
@@ -38,7 +38,7 @@ From command-line:
38
38
 
39
39
  #### Fetch hosts remediation data
40
40
 
41
- In UI: Insights -> Recommendations -> Sync recommendations (under the vertical ellipsis)
41
+ In UI: Configure -> Insights -> Sync now
42
42
 
43
43
  From command-line:
44
44
 
@@ -46,7 +46,7 @@ From command-line:
46
46
 
47
47
  #### Synchronize inventory status
48
48
 
49
- In UI: Insights -> Inventory Upload -> Sync all inventory status
49
+ In UI: Configure -> Inventory Upload -> Sync all inventory status
50
50
 
51
51
  From command-line:
52
52
 
@@ -18,10 +18,10 @@ module Api
18
18
 
19
19
  api :POST, "/organizations/:organization_id/rh_cloud/report", N_("Start report generation")
20
20
  param :organization_id, Integer, required: true, desc: N_("Set the current organization context for the request")
21
- param :disconnected, :bool, required: false, default: false, desc: N_('Generate the report, but do not upload')
21
+ param :no_upload, :bool, required: false, default: false, desc: N_('Generate the report, but do not upload')
22
22
  def generate_report
23
23
  organization_id = params[:organization_id]
24
- disconnected = params[:disconnected] || false
24
+ disconnected = params[:no_upload] || false
25
25
 
26
26
  start_report_generation(organization_id, disconnected)
27
27
 
@@ -18,39 +18,35 @@ module InsightsCloud::Api
18
18
  certs = candlepin_id_cert @organization
19
19
  begin
20
20
  @cloud_response = ::ForemanRhCloud::CloudRequestForwarder.new.forward_request(request, controller_name, @branch_id, certs)
21
- rescue RestClient::Exceptions::Timeout => e
22
- response_obj = e.response.presence || e.exception
23
- return render json: { message: response_obj.to_s, error: response_obj.to_s }, status: :gateway_timeout
24
- rescue RestClient::Unauthorized => e
25
- logger.info("Forwarding request auth error: #{e}")
26
- message = 'Authentication to the Insights Service failed.'
27
- return render json: { message: message, error: message }, status: :unauthorized
28
- rescue RestClient::NotModified => e
29
- logger.info("Forwarding request not modified: #{e}")
30
- message = 'Cloud request not modified'
31
- return render json: { message: message, error: message }, status: :not_modified
32
- rescue RestClient::ExceptionWithResponse => e
33
- response_obj = e.response.presence || e.exception
34
- code = response_obj.try(:code) || response_obj.try(:http_code) || 500
35
- message = 'Cloud request failed'
21
+ rescue RestClient::Exception => e
22
+ logger.info("Forwarding request failed with exception: #{e}")
23
+ return render json: { error: e }, status: :bad_gateway
24
+ rescue RestClient::Timeout => e
25
+ logger.info("Forwarding request failed with timeout: #{e}")
26
+ return render json: { error: e }, status: :gateway_timeout
27
+ end
28
+
29
+ return render json: { message: @cloud_response.to_s }, status: :gateway_timeout if @cloud_response.is_a?(RestClient::Exceptions::OpenTimeout)
36
30
 
31
+ if @cloud_response.code == 401
37
32
  return render json: {
38
- :message => message,
39
- :error => response_obj.to_s,
33
+ :message => 'Authentication to the Insights Service failed.',
40
34
  :headers => {},
41
- :response => response_obj,
42
- }, status: code
43
- rescue StandardError => e
44
- # Catch any other exceptions here, such as Errno::ECONNREFUSED
45
- logger.info("Cloud request failed with exception: #{e}")
46
- return render json: { error: e }, status: :bad_gateway
35
+ }, status: :bad_gateway
36
+ end
37
+
38
+ if @cloud_response.code >= 300
39
+ return render json: {
40
+ :message => 'Cloud request failed',
41
+ :headers => {},
42
+ :response => @cloud_response,
43
+ }, status: @cloud_response.code
47
44
  end
48
45
 
49
46
  # Append redhat-specific headers
50
47
  @cloud_response.headers.each do |key, value|
51
48
  assign_header(response, @cloud_response, key, false) if key.to_s.start_with?('x_rh_')
52
49
  end
53
-
54
50
  # Append general headers
55
51
  assign_header(response, @cloud_response, :x_resource_count, true)
56
52
  headers[Rack::ETAG] = @cloud_response.headers[:etag]
@@ -60,8 +56,8 @@ module InsightsCloud::Api
60
56
  # content type
61
57
  send_data @cloud_response, disposition: @cloud_response.headers[:content_disposition], type: @cloud_response.headers[:content_type]
62
58
  elsif @cloud_response.headers[:content_type] =~ /zip/
63
- # If there is no Content-Disposition, but the content type is binary according to Content-Type, send the raw data
64
- # with proper content type
59
+ # if there is no Content-Disposition, but the content type is binary according the content type,
60
+ # forward the request as binry too
65
61
  send_data @cloud_response, type: @cloud_response.headers[:content_type]
66
62
  else
67
63
  render json: @cloud_response, status: @cloud_response.code
@@ -8,23 +8,13 @@ module ForemanRhCloud
8
8
  proxy: ForemanRhCloud.transformed_http_proxy_string,
9
9
  }.deep_merge(params)
10
10
 
11
- if ForemanRhCloud.with_local_advisor_engine?
12
- final_params[:ssl_ca_file] ||= ForemanRhCloud.ca_cert
13
- end
14
-
15
11
  response = RestClient::Request.execute(final_params)
16
12
 
17
13
  logger.debug("Response headers for request url #{final_params[:url]} are: #{response.headers}")
18
14
 
19
15
  response
20
- rescue RestClient::Exceptions::Timeout => ex
21
- logger.debug("Timeout exception raised for request url #{final_params[:url]}: #{ex}")
22
- raise ex
23
- rescue RestClient::ExceptionWithResponse => ex
24
- logger.debug("Response headers for request url #{final_params[:url]} with status code #{ex.http_code} are: #{ex.http_headers} and body: #{ex.http_body}")
25
- raise ex
26
- rescue StandardError => ex
27
- logger.debug("Exception raised for request url #{final_params[:url]}: #{ex}")
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}")
28
18
  raise ex
29
19
  end
30
20
  end
@@ -17,6 +17,8 @@ module ForemanRhCloud
17
17
  logger.debug("Sending request to: #{request_opts[:url]}")
18
18
 
19
19
  execute_cloud_request(request_opts)
20
+ rescue RestClient::ExceptionWithResponse => error_response
21
+ error_response.response.presence || error_response.exception
20
22
  end
21
23
 
22
24
  def prepare_request_opts(original_request, forward_payload, forward_params, certs)
@@ -32,13 +34,7 @@ module ForemanRhCloud
32
34
  ),
33
35
  }
34
36
  requested_url = original_request.original_fullpath.end_with?('/') ? original_request.path + '/' : original_request.path
35
- params = path_params(requested_url, certs)
36
-
37
- if ForemanRhCloud.with_local_advisor_engine?
38
- params[:ssl_ca_file] = ForemanRhCloud.ca_cert
39
- end
40
-
41
- base_params.merge(params)
37
+ base_params.merge(path_params(requested_url, certs))
42
38
  end
43
39
 
44
40
  def prepare_forward_payload(original_request, controller_name)
@@ -67,12 +63,6 @@ module ForemanRhCloud
67
63
 
68
64
  def path_params(request_path, certs)
69
65
  case request_path
70
- when lightspeed?
71
- {
72
- url: ForemanRhCloud.cert_base_url + request_path,
73
- ssl_client_cert: OpenSSL::X509::Certificate.new(certs[:cert]),
74
- ssl_client_key: OpenSSL::PKey.read(certs[:key]),
75
- }
76
66
  when platform_request?
77
67
  {
78
68
  url: ForemanRhCloud.cert_base_url + request_path.sub('/redhat_access/r/insights/platform', '/api'),
@@ -105,10 +95,6 @@ module ForemanRhCloud
105
95
  headers
106
96
  end
107
97
 
108
- def lightspeed?
109
- ->(request_path) { request_path.include? '/lightspeed' }
110
- end
111
-
112
98
  def platform_request?
113
99
  ->(request_path) { request_path.include? '/platform' }
114
100
  end
@@ -13,18 +13,7 @@ module ForemanRhCloud
13
13
 
14
14
  def fetch_rules_data
15
15
  advisor_url = "#{ForemanRhCloud.on_premise_url}/r/insights/v1/static/release/content.json"
16
- uri = URI.parse(advisor_url)
17
- http = Net::HTTP.new(uri.host, uri.port)
18
- http.use_ssl = true
19
-
20
- # Set CA certificate
21
- http.ca_file = ForemanRhCloud.ca_cert
22
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
23
-
24
- request = Net::HTTP::Get.new(uri.request_uri)
25
-
26
- response = http.request(request)
27
- JSON.parse(response.body, symbolize_names: true)
16
+ JSON.parse(Net::HTTP.get(URI.parse(advisor_url)), symbolize_names: true)
28
17
  end
29
18
 
30
19
  def fetch_rules_and_resolutions
data/config/routes.rb CHANGED
@@ -49,10 +49,6 @@ Rails.application.routes.draw do
49
49
  end
50
50
  end
51
51
 
52
- scope :module => :'insights_cloud/api' do
53
- match '/api/lightspeed/*path', to: 'machine_telemetries#forward_request', via: :all
54
- end
55
-
56
52
  # API routes
57
53
 
58
54
  namespace :api, :defaults => { :format => 'json' } do
@@ -3,7 +3,7 @@ module ForemanInventoryUpload
3
3
  class QueueForUploadJob < ::Actions::EntryAction
4
4
  def plan(base_folder, report_file, organization_id, disconnected)
5
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) unless disconnected
6
+ plan_upload_report(enqueue_task.output[:enqueued_file_name], organization_id, disconnected)
7
7
  end
8
8
 
9
9
  def run
@@ -59,8 +59,8 @@ module ForemanInventoryUpload
59
59
  input[:report_file]
60
60
  end
61
61
 
62
- def plan_upload_report(enqueued_file_name, organization_id)
63
- plan_action(UploadReportJob, enqueued_file_name, organization_id)
62
+ def plan_upload_report(enqueued_file_name, organization_id, disconnected)
63
+ plan_action(UploadReportJob, enqueued_file_name, organization_id, disconnected)
64
64
  end
65
65
  end
66
66
  end
@@ -7,15 +7,15 @@ module ForemanInventoryUpload
7
7
  "upload_for_#{label}"
8
8
  end
9
9
 
10
- def plan(filename, organization_id)
10
+ def plan(filename, organization_id, disconnected = false)
11
11
  label = UploadReportJob.output_label(organization_id)
12
- super(label, filename: filename, organization_id: organization_id)
12
+ super(label, filename: filename, organization_id: organization_id, disconnected: disconnected)
13
13
  end
14
14
 
15
15
  def try_execute
16
16
  if content_disconnected?
17
17
  progress_output do |progress_output|
18
- progress_output.write_line('Upload was stopped since disconnected mode setting is enabled for content on this instance.')
18
+ progress_output.write_line('Upload canceled because connection to Insights is not enabled or the --no-upload option was passed.')
19
19
  progress_output.status = "Task aborted, exit 1"
20
20
  done!
21
21
  end
@@ -78,7 +78,7 @@ module ForemanInventoryUpload
78
78
  end
79
79
 
80
80
  def content_disconnected?
81
- !Setting[:subscription_connection_enabled]
81
+ input[:disconnected] || !Setting[:subscription_connection_enabled]
82
82
  end
83
83
  end
84
84
  end
@@ -57,39 +57,17 @@ module ForemanInventoryUpload
57
57
  end
58
58
 
59
59
  def obfuscate_hostname?(host)
60
- # Returns true if hostname obfuscation should be applied for a given host, based on hierarchy:
61
- # 1. Global setting for hostname obfuscation.
62
- return true if Setting[:obfuscate_inventory_hostnames]
63
-
64
60
  insights_client_setting = fact_value(host, 'insights_client::obfuscate_hostname_enabled')
65
61
  insights_client_setting = ActiveModel::Type::Boolean.new.cast(insights_client_setting)
62
+ return insights_client_setting unless insights_client_setting.nil?
66
63
 
67
- # 2. host fact reported by insights_client
68
- # 3. if neither of the above, don't obfuscate.
69
- insights_client_setting.nil? ? false : insights_client_setting
64
+ Setting[:obfuscate_inventory_hostnames]
70
65
  end
71
66
 
72
67
  def fqdn(host)
73
- if obfuscate_hostname?(host)
74
- # If obfuscation is enabled, attempt to retrieve an already obfuscated hostname
75
- # from the 'insights_client::obfuscated_hostname' fact.
76
- # Example format of `parsed_insights_array`:
77
- # [{"original"=>"host.example.com", "obfuscated"=>"0dd449d0a027.example.com"},
78
- # {"original"=>"satellite.example.com", "obfuscated"=>"host2.example.com"}]
79
- begin
80
- parsed_insights_array = JSON.parse(fact_value(host, 'insights_client::obfuscated_hostname') || '[]')
81
- rescue JSON::ParserError
82
- parsed_insights_array = []
83
- end
84
- # Obfuscate using the following hierarchy:
85
- # 1. the obfuscated_hostname fact sent by insights_client
86
- parsed_insights_item = parsed_insights_array.find { |item| item['original'] == host.fqdn }
87
- # 2. our own helper method
88
- parsed_insights_item&.[]('obfuscated') || obfuscate_fqdn(host.fqdn)
89
- else
90
- # If hostname obfuscation is not enabled for this host, return the host's original FQDN.
91
- host.fqdn
92
- end
68
+ return host.fqdn unless obfuscate_hostname?(host)
69
+
70
+ fact_value(host, 'insights_client::hostname') || obfuscate_fqdn(host.fqdn)
93
71
  end
94
72
 
95
73
  def obfuscate_fqdn(fqdn)
@@ -97,65 +75,35 @@ module ForemanInventoryUpload
97
75
  end
98
76
 
99
77
  def obfuscate_ips?(host)
100
- # Returns true if IP obfuscation should be applied for a given host, based on hierarchy:
101
- # 1. Global setting for IP obfuscation.
102
- return true if Setting[:obfuscate_inventory_ips]
103
-
104
- insights_client_ipv4_setting = fact_value(host, 'insights_client::obfuscate_ipv4_enabled')
105
- insights_client_ipv6_setting = fact_value(host, 'insights_client::obfuscate_ipv6_enabled')
106
-
107
- cast_ipv4_setting = ActiveModel::Type::Boolean.new.cast(insights_client_ipv4_setting)
108
- cast_ipv6_setting = ActiveModel::Type::Boolean.new.cast(insights_client_ipv6_setting)
78
+ insights_client_setting = fact_value(host, 'insights_client::obfuscate_ip_enabled')
79
+ insights_client_setting = ActiveModel::Type::Boolean.new.cast(insights_client_setting)
80
+ return insights_client_setting unless insights_client_setting.nil?
109
81
 
110
- # 2. The host's IPv4 or IPv6 obfuscation fact value is true
111
- # 3. If neither of the above, don't obfuscate.
112
- cast_ipv4_setting || cast_ipv6_setting || false
82
+ Setting[:obfuscate_inventory_ips]
113
83
  end
114
84
 
115
85
  def host_ips(host)
116
- # Determines and returns the IP addresses associated with a host, applying obfuscation if enabled.
117
-
118
- # If IP obfuscation is enabled for the host return a representation of obfuscated IP addresses.
119
86
  return obfuscated_ips(host) if obfuscate_ips?(host)
120
87
 
121
- # If IP obfuscation is NOT needed, return a special kind of Hash.
122
- # where when you try to access a key in it
123
- # if the key doesn't exist, it simply returns the key itself.
124
- # This is useful because it means if you try to get an IP from this hash,
125
- # you'll just get the original IP back. It allows the calling code to
126
- # use the same interface whether obfuscation is applied or not.
88
+ # return a pass through proxy hash in case no obfuscation needed
127
89
  Hash.new { |h, k| k }
128
90
  end
129
91
 
130
92
  def obfuscated_ips(host)
131
- # Example format of `parsed_insights_array`:
132
- # [{"original": "192.168.1.10", "obfuscated": "10.230.230.1"},
133
- # {"original": "192.168.1.11", "obfuscated": "10.230.230.2"}]
134
- begin
135
- parsed_insights_array = JSON.parse(fact_value(host, 'insights_client::obfuscated_ipv4') || '[]')
136
- rescue JSON::ParserError
137
- parsed_insights_array = []
138
- end
93
+ insights_client_ips = JSON.parse(fact_value(host, 'insights_client::ips') || '[]')
139
94
 
140
- # Create a new Hash to store the mapping from original IP addresses to their obfuscated versions.
141
- # where the 'original' IP is the key and the 'obfuscated' IP is the value.
142
95
  obfuscated_ips = Hash[
143
- parsed_insights_array.map { |ip_record| [ip_record['original'], ip_record['obfuscated']] }
96
+ insights_client_ips.map { |ip_record| [ip_record['original'], ip_record['obfuscated']] }
144
97
  ]
145
98
 
146
- # Sets a default proc for the obfuscated_ips hash.
147
- # When a key is accessed that does not exist in the hash, this proc is called.
148
- # It assigns the result of obfuscate_ip(key, hash) to the missing key in the hash.
149
- # This ensures that any missing IP address key will be obfuscated and stored automatically.
150
99
  obfuscated_ips.default_proc = proc do |hash, key|
151
100
  hash[key] = obfuscate_ip(key, hash)
152
101
  end
102
+
153
103
  obfuscated_ips
154
104
  end
155
105
 
156
106
  def obfuscate_ip(ip, ips_dict)
157
- # Produce a new, unique obfuscated IP that is
158
- # numerically one greater than the highest existing obfuscated IP
159
107
  max_obfuscated = ips_dict.values.map { |v| IPAddr.new(v).to_i }.max || IPAddr.new('10.230.230.0').to_i
160
108
 
161
109
  IPAddr.new(max_obfuscated + 1, Socket::AF_INET).to_s
@@ -24,11 +24,9 @@ module ForemanInventoryUpload
24
24
  'dmi::system::product_name',
25
25
  'dmi::chassis::asset_tag',
26
26
  'insights_client::obfuscate_hostname_enabled',
27
- 'insights_client::obfuscate_ipv4_enabled',
28
- 'insights_client::obfuscate_ipv6_enabled',
29
- 'insights_client::obfuscated_ipv4',
30
- 'insights_client::obfuscated_ipv6',
31
- 'insights_client::obfuscated_hostname',
27
+ 'insights_client::obfuscate_ip_enabled',
28
+ 'insights_client::hostname',
29
+ 'insights_client::ips',
32
30
  'insights_id',
33
31
  'conversions::activity',
34
32
  'conversions::packages::0::nevra',
@@ -149,6 +149,7 @@ module ForemanInventoryUpload
149
149
  ) { |v| os_release_value(*v) }
150
150
  @stream.simple_field('os_kernel_version', fact_value(host, 'uname::release'))
151
151
  @stream.simple_field('arch', host.architecture&.name)
152
+ @stream.simple_field('katello_agent_running', false)
152
153
  @stream.simple_field(
153
154
  'infrastructure_type',
154
155
  ActiveModel::Type::Boolean.new.cast(fact_value(host, 'virt::is_guest')) ? 'virtual' : 'physical'
@@ -212,15 +212,4 @@ module ForemanRhCloud
212
212
  def self.with_local_advisor_engine?
213
213
  SETTINGS.dig(:foreman_rh_cloud, :use_local_advisor_engine) || false
214
214
  end
215
-
216
- def self.ca_cert
217
- # The reference to candlepin ca_cert_file can be removed
218
- # once the setting is dropped. Foreman 3.15 introduces
219
- # a single CA file that bundles all CAs.
220
- if ::SETTINGS.dig(:katello, :candlepin, :ca_cert_file)
221
- ::SETTINGS[:katello][:candlepin][:ca_cert_file]
222
- else
223
- ::SETTINGS[:ssl_ca_file]
224
- end
225
- end
226
215
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '11.4.4'.freeze
2
+ VERSION = '12.0.0'.freeze
3
3
  end
@@ -47,8 +47,6 @@ module ForemanRhCloud
47
47
  end
48
48
 
49
49
  def self.proxy_string
50
- return '' if ForemanRhCloud.with_local_advisor_engine?
51
-
52
50
  HttpProxy.default_global_content_proxy&.full_url ||
53
51
  ForemanRhCloud.global_foreman_proxy ||
54
52
  ''
@@ -1,122 +1,64 @@
1
1
  require 'io/console'
2
- require 'uri'
3
2
 
4
- def logger
5
- @logger ||= Logger.new(STDOUT)
6
- end
7
-
8
- namespace :rh_cloud do
9
- desc 'Register Satellite Organization with Hybrid Cloud API.'
10
- # This task registers the Satellite Organization with the Hybrid Cloud API.
11
- # It requires the user to input their organization ID, Insights URL, and token.
12
- # The task will then send a POST request to the Hybrid Cloud API to register the organization.
13
- # The response will be logged, and any errors will be caught and logged as well.
14
- # The task will exit with an error message if the organization does not have a manifest imported or if the token is not entered.
15
- # The task will also log a warning if the custom URL is not set and the default one is used.
3
+ namespace :rh_cloud do |args|
4
+ desc 'Register Satellite Organization with Hybrid Cloud API. \
5
+ Specify org_id=x replace your organization ID with x. \
6
+ Specify SATELLITE_RH_CLOUD_URL=https://x with the Hybrid Cloud endpoint you are connecting to.'
16
7
  task hybridcloud_register: [:environment] do
17
8
  include ::ForemanRhCloud::CertAuth
18
9
  include ::InsightsCloud::CandlepinCache
19
10
 
20
- # Helper method to get the registrations URL, with a warning for default usage
21
- def registrations_url(custom_url)
22
- if custom_url.empty?
23
- logger.warn("Custom url is not set, using the default one: #{ForemanRhCloud.base_url}")
24
- URI.join(ForemanRhCloud.base_url, '/api/identity/certificate/registrations').to_s
25
- else
26
- URI.join(custom_url, '/api/identity/certificate/registrations').to_s
27
- end
11
+ def logger
12
+ @logger ||= Logger.new(STDOUT)
28
13
  end
29
14
 
30
- # --- Input Collection ---
31
- puts "Paste in your organization ID, this can be retrieved with the command: hammer organization list"
32
- loop do
33
- input = STDIN.gets.chomp
34
- if input.match?(/^\d+$/) # Checks if input consists only of digits
35
- @user_org_id = input.to_i
36
- break
37
- else
38
- puts "Invalid input. Please enter a numeric organization ID."
39
- end
15
+ def registrations_url
16
+ logger.warn("Custom url is not set, using the default one: #{ForemanRhCloud.base_url}") if ENV['SATELLITE_RH_CLOUD_URL'].empty?
17
+ ForemanRhCloud.base_url + '/api/identity/certificate/registrations'
40
18
  end
41
19
 
42
- puts "\n" + "-" * 50 + "\n\n"
43
- puts 'Paste in your Custom Insights URL. If nothing is entered, the default will be used.'
44
- insights_user_input = STDIN.gets.chomp
45
-
46
- # --- Data Preparation ---
47
-
48
- organization = Organization.find_by(id: @user_org_id)
49
-
50
- if organization.nil?
51
- logger.error("Organization with ID '#{@user_org_id}' not found.")
20
+ if ENV['org_id'].nil?
21
+ logger.error('ERROR: org_id needs to be specified.')
52
22
  exit(1)
53
23
  end
54
24
 
55
- uid = cp_owner_id(organization)
56
- if uid.nil?
57
- logger.error('Organization provided does not have a manifest imported.')
58
- exit(1)
59
- end
25
+ @organization = Organization.find_by(id: ENV['org_id'].to_i) # saw this coming in as a string, so making sure it gets passed as an integer.
26
+ @uid = cp_owner_id(@organization)
27
+ @hostname = ForemanRhCloud.foreman_host_name
28
+ logger.error('Organization provided does not have a manifest imported.') + exit(1) if @uid.nil?
60
29
 
61
- hostname = ForemanRhCloud.foreman_host_name
62
- insights_url = registrations_url(insights_user_input)
30
+ puts 'Paste your token, output will be hidden.'
31
+ @token = STDIN.noecho(&:gets).chomp
32
+ logger.error('Token was not entered.') + exit(1) if @token.empty?
63
33
 
64
- puts "\n" + "-" * 50 + "\n\n"
65
- puts 'Paste in your Hybrid Cloud API token, output will be hidden.'
66
- puts 'This token can be retrieved from the Hybrid Cloud console.'
67
- token = STDIN.noecho(&:gets).chomp
68
-
69
- if token.empty?
70
- logger.error('Token was not entered.')
71
- exit(1)
34
+ def headers
35
+ {
36
+ Authorization: "Bearer #{@token}",
37
+ }
72
38
  end
73
39
 
74
- # --- API Request Configuration ---
75
-
76
- headers = {
77
- Authorization: "Bearer #{token}",
78
- }
79
-
80
- payload = {
81
- 'uid': uid,
82
- "display_name": "#{hostname}+#{organization.label}",
83
- }
40
+ def payload
41
+ {
42
+ "uid": @uid,
43
+ "display_name": "#{@hostname}+#{@organization.label}",
44
+ }
45
+ end
84
46
 
85
- # --- Execute Request ---
47
+ def method
48
+ :post
49
+ end
86
50
 
87
51
  begin
88
52
  response = execute_cloud_request(
89
- organization: organization,
90
- method: :post,
91
- url: insights_url,
53
+ organization: @organization,
54
+ method: method,
55
+ url: registrations_url,
92
56
  headers: headers,
93
57
  payload: payload.to_json
94
58
  )
95
- logger.debug("Cloud request completed: status=#{response.code}, body_preview=#{response.body&.slice(0, 200)}")
96
- # Add a more specific rescue for 401 Unauthorized errors
97
- rescue RestClient::Unauthorized => _ex
98
- logger.error('Registration failed: Your token is invalid or unauthorized. Please check your token and try again.')
99
- # Optionally, you can still log the full debug info if helpful for advanced troubleshooting
100
- # logger.debug(ex.backtrace.join("\n"))
101
- exit(1)
102
- rescue RestClient::ExceptionWithResponse => ex
103
- # This catches any RestClient exception that has a response (like 400, 403, 404, 500, etc.)
104
- status_code = begin
105
- ex.response.code
106
- rescue StandardError
107
- "unknown"
108
- end
109
- logger.error("Registration failed with HTTP status #{status_code}: #{ex.message}")
110
- logger.debug("Response body (if available): #{ex.response.body}")
111
- # logger.debug(ex.backtrace.join("\n"))
112
- exit(1)
59
+ logger.debug(response)
113
60
  rescue StandardError => ex
114
- # This is the catch-all for any other unexpected errors
115
- logger.error("An unexpected error occurred during registration: #{ex.message}")
116
- # logger.debug(ex.backtrace.join("\n")) # Log backtrace for more info
117
- exit(1)
61
+ logger.error(ex)
118
62
  end
119
-
120
- logger.info("Satellite Organization '#{organization.label}' (ID: #{@user_org_id}) successfully registered.")
121
63
  end
122
64
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreman_rh_cloud",
3
- "version": "11.4.4",
3
+ "version": "12.0.0",
4
4
  "description": "Inventory Upload =============",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -19,13 +19,13 @@
19
19
  "url": "http://projects.theforeman.org/projects/foreman_rh_cloud/issues"
20
20
  },
21
21
  "peerDependencies": {
22
- "@theforeman/vendor": ">= 10.1.1"
22
+ "@theforeman/vendor": ">= 15.0.1"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@babel/core": "^7.7.0",
26
- "@theforeman/builder": ">= 10.1.1",
27
- "@theforeman/test": ">= 10.1.1",
28
- "@theforeman/eslint-plugin-foreman": ">= 10.1.1",
26
+ "@theforeman/builder": ">= 15.0.1",
27
+ "@theforeman/test": ">= 15.0.1",
28
+ "@theforeman/eslint-plugin-foreman": ">= 15.0.1",
29
29
  "babel-eslint": "~10.0.0",
30
30
  "eslint": "~6.7.2",
31
31
  "eslint-plugin-spellcheck": "~0.0.17",