foreman_rh_cloud 12.1.2 → 12.1.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca9c35b5c31e2f8d00889ae5c4f57a3245e038f2ff106e708c9f45909e1340d2
4
- data.tar.gz: 7b151bcccb350ff1cb748aeca126656d8e7e2712e7878ea0522b7db719c6594f
3
+ metadata.gz: 6bc60ead37485cf4bb034dd6ccbd416ca9ad957c37123553c1cf529a2a948d48
4
+ data.tar.gz: 7490a0bf69893145965f99d692735dca1ad3786439efb306e99423f555c83ad0
5
5
  SHA512:
6
- metadata.gz: ec35e323ea4ff1e5af20ee9a6185c83f5cf43e011a1f4879d696050381265c474cbf2b1435f72f53e43c785c797f5de013513f7efbf49e19fd87b9d2c58fe279
7
- data.tar.gz: 109928813b8f2e70ee7107d44470e04fff2fad1e9fd356f2b15f7f57092bb06c003277de931c5d5dfa84a4a379de36e4e14fd7ea2898b3070d310c4c7311e5c0
6
+ metadata.gz: 68a8fcbff3c147991ee6c05699a9a0be941552dd97bcd94fb8230635120c40302a06b1ed4d2428a16ad71b353da2a56696e045eca29a3beda0b3df2877bd2206
7
+ data.tar.gz: 00ae0a4cafbad304e4da6ff962c8214c67aecc0e7af37a8c2dbd1be1f889dbca095cf93f4c6222441cef08298d333758ff8c2f942358736aca8473cc813fee34
@@ -0,0 +1,4 @@
1
+ ForemanRhCloud.on_prem_smart_proxy_features.each do |feature_name|
2
+ f = Feature.where(:name => feature_name).first_or_create
3
+ raise "Unable to create proxy feature: #{SeedHelper.format_errors f}" if f.nil? || f.errors.any?
4
+ end
@@ -41,7 +41,10 @@ module ForemanInventoryUpload
41
41
  end
42
42
 
43
43
  def organizations
44
- [['organization', @host.organization.name]]
44
+ [
45
+ ['organization', @host.organization.name],
46
+ ['organization_label', @host.organization.label],
47
+ ]
45
48
  end
46
49
 
47
50
  def content_data
@@ -210,6 +210,30 @@ module ForemanRhCloud
210
210
  )
211
211
  end
212
212
 
213
+ # Ideally this code belongs to an initializer. The problem is that Katello controllers are not initialized completely until after the end of the to_prepare blocks
214
+ # This means I can patch the controller only in the after_initialize block that is promised to run after the to_prepare
215
+ # initializer 'foreman_rh_cloud.allow_smart_proxy_actions', :before => :finisher_hook, :after => 'katello.register_plugin' do |_app|
216
+ # end
217
+ config.after_initialize do
218
+ # skip overrides in migrations, since the controller initialization depends on tables existense
219
+ if defined?(Katello) && !Foreman.in_setup_db_rake?
220
+ Katello::Api::V2::OrganizationsController.include Foreman::Controller::SmartProxyAuth
221
+ # patch the callbacks order for :download_debug_certificate, since local_find_taxonomy has to run after the user is already initialized
222
+ Katello::Api::V2::OrganizationsController.skip_before_action(:local_find_taxonomy, only: :download_debug_certificate)
223
+ Katello::Api::V2::OrganizationsController.add_smart_proxy_filters(
224
+ [:index, :download_debug_certificate],
225
+ features: ForemanRhCloud.on_prem_smart_proxy_features
226
+ )
227
+ Katello::Api::V2::OrganizationsController.before_action(:local_find_taxonomy, only: :download_debug_certificate)
228
+
229
+ Katello::Api::V2::RepositoriesController.include Foreman::Controller::SmartProxyAuth
230
+ Katello::Api::V2::RepositoriesController.add_smart_proxy_filters(
231
+ :index,
232
+ features: ForemanRhCloud.on_prem_smart_proxy_features
233
+ )
234
+ end
235
+ end
236
+
213
237
  rake_tasks do
214
238
  Rake::Task['db:seed'].enhance do
215
239
  ForemanRhCloud::Engine.load_seed
@@ -231,4 +255,8 @@ module ForemanRhCloud
231
255
  ::SETTINGS[:ssl_ca_file]
232
256
  end
233
257
  end
258
+
259
+ def self.on_prem_smart_proxy_features
260
+ ['Insights']
261
+ end
234
262
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '12.1.2'.freeze
2
+ VERSION = '12.1.3'.freeze
3
3
  end
@@ -1,64 +1,132 @@
1
1
  require 'io/console'
2
+ require 'uri'
2
3
 
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.'
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.
7
16
  task hybridcloud_register: [:environment] do
8
17
  include ::ForemanRhCloud::CertAuth
9
18
  include ::InsightsCloud::CandlepinCache
10
19
 
11
- def logger
12
- @logger ||= Logger.new(STDOUT)
20
+ def default_registrations_url
21
+ URI.join(ForemanRhCloud.base_url, '/api/identity/certificate/registrations').to_s
13
22
  end
14
23
 
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'
24
+ # Helper method to get the registrations URL, with a warning for default usage
25
+ def registrations_url(custom_url)
26
+ if custom_url.empty?
27
+ logger.warn("Custom url is not set, using the default one: #{default_registrations_url}")
28
+ default_registrations_url
29
+ else
30
+ if URI(custom_url).scheme.nil?
31
+ logger.warn("Custom URL lacks a scheme; prepending https:// prefix.")
32
+ custom_url = "https://" + custom_url
33
+ end
34
+ custom_url
35
+ end
18
36
  end
19
37
 
20
- if ENV['org_id'].nil?
21
- logger.error('ERROR: org_id needs to be specified.')
22
- exit(1)
38
+ def get_organization(user_org_id)
39
+ maybe_organization = Organization.find_by(id: user_org_id)
40
+ if maybe_organization.nil?
41
+ logger.error("Organization with ID '#{user_org_id}' not found.")
42
+ exit(1)
43
+ end
44
+ maybe_organization
23
45
  end
24
46
 
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?
29
-
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?
33
-
34
- def headers
35
- {
36
- Authorization: "Bearer #{@token}",
37
- }
47
+ def get_uid(organization)
48
+ maybe_uid = cp_owner_id(organization)
49
+ if maybe_uid.nil?
50
+ logger.error("Organization '#{organization}' does not have a manifest imported.")
51
+ exit(1)
52
+ end
53
+ maybe_uid
38
54
  end
39
55
 
40
- def payload
41
- {
42
- "uid": @uid,
43
- "display_name": "#{@hostname}+#{@organization.label}",
44
- }
56
+ # --- Input Collection ---
57
+ puts "Paste in your organization ID, this can be retrieved with the command: hammer organization list"
58
+ loop do
59
+ input = STDIN.gets.chomp
60
+ if input.match?(/^\d+$/) # Checks if input consists only of digits
61
+ @user_org_id = input.to_i
62
+ break
63
+ else
64
+ puts "Invalid input. Please enter a numeric organization ID."
65
+ end
45
66
  end
46
67
 
47
- def method
48
- :post
68
+ puts "\n" + "-" * 50 + "\n\n"
69
+ puts "Paste in your custom Insights URL. If nothing is entered, the default will be used (#{default_registrations_url})."
70
+ insights_user_input = STDIN.gets.chomp
71
+
72
+ puts "\n" + "-" * 50 + "\n\n"
73
+ puts 'Paste in your Hybrid Cloud API token, output will be hidden.'
74
+ puts 'This token can be retrieved from the Hybrid Cloud console.'
75
+ token = STDIN.noecho(&:gets).chomp
76
+ if token.empty?
77
+ logger.error('Token was not entered.')
78
+ exit(1)
49
79
  end
50
80
 
81
+ # --- Data Preparation ---
82
+
83
+ organization = get_organization(@user_org_id)
84
+ uid = get_uid(organization)
85
+ hostname = ForemanRhCloud.foreman_host_name
86
+ insights_url = registrations_url(insights_user_input)
87
+
88
+ # --- API Request ---
89
+
90
+ headers = {
91
+ Authorization: "Bearer #{token}",
92
+ }
93
+
94
+ payload = {
95
+ 'uid': uid,
96
+ "display_name": "#{hostname}+#{organization.label}",
97
+ }
98
+
51
99
  begin
52
100
  response = execute_cloud_request(
53
- organization: @organization,
54
- method: method,
55
- url: registrations_url,
101
+ organization: organization,
102
+ method: :post,
103
+ url: insights_url,
56
104
  headers: headers,
57
105
  payload: payload.to_json
58
106
  )
59
- logger.debug(response)
107
+ logger.debug("Cloud request completed: status=#{response.code}, body_preview=#{response.body&.slice(0, 200)}")
108
+ rescue RestClient::Unauthorized => _ex
109
+ # Add a more specific rescue for 401 Unauthorized errors
110
+ logger.error('Registration failed: Your token is invalid or unauthorized. Please check your token and try again.')
111
+ # Optionally, you can still log the full debug info if helpful for advanced troubleshooting
112
+ # logger.debug(ex.backtrace.join("\n"))
113
+ exit(1)
114
+ rescue RestClient::ExceptionWithResponse => ex
115
+ # This catches any RestClient exception that has a response (like 400, 403, 404, 500, etc.)
116
+ status_code = begin
117
+ ex.response.code
118
+ rescue StandardError
119
+ "unknown"
120
+ end
121
+ logger.error("Registration failed with HTTP status #{status_code}: #{ex.message}")
122
+ logger.debug("Response body (if available): #{ex.response.body}")
123
+ exit(1)
60
124
  rescue StandardError => ex
61
- logger.error(ex)
125
+ # This is the catch-all for any other unexpected errors
126
+ logger.error("An unexpected error occurred during registration: #{ex.message}")
127
+ exit(1)
62
128
  end
129
+
130
+ logger.info("Satellite Organization '#{organization.label}' (ID: #{@user_org_id}) successfully registered.")
63
131
  end
64
132
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreman_rh_cloud",
3
- "version": "12.1.2",
3
+ "version": "12.1.3",
4
4
  "description": "Inventory Upload =============",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -51,8 +51,7 @@ module InsightsCloud::Api
51
51
  mock_composer = mock('composer')
52
52
  ::JobInvocationComposer.expects(:for_feature).with do |feature, host_ids, params|
53
53
  feature == :rh_cloud_connector_run_playbook &&
54
- host_ids.first == host1.id &&
55
- host_ids.last == host2.id
54
+ host_ids.sort == [host1.id, host2.id].sort
56
55
  end.returns(mock_composer)
57
56
  mock_composer.expects(:trigger!)
58
57
  mock_composer.expects(:job_invocation)
@@ -4,6 +4,7 @@ class RhCloudHttpProxyTest < ActiveSupport::TestCase
4
4
  setup do
5
5
  @global_content_proxy_mock = 'http://global:content@localhost:80'
6
6
  @global_foreman_proxy_mock = 'http://global:foreman@localhost:80'
7
+ ForemanRhCloud.stubs(:with_local_advisor_engine?).returns(false)
7
8
  end
8
9
 
9
10
  test 'selects global content proxy' do
@@ -18,6 +19,13 @@ class RhCloudHttpProxyTest < ActiveSupport::TestCase
18
19
  assert_equal @global_foreman_proxy_mock, ForemanRhCloud.proxy_setting
19
20
  end
20
21
 
22
+ test 'returns empty string in on-prem setup' do
23
+ ForemanRhCloud.unstub(:with_local_advisor_engine?)
24
+ ForemanRhCloud.stubs(:with_local_advisor_engine?).returns(true)
25
+
26
+ assert_empty ForemanRhCloud.proxy_setting
27
+ end
28
+
21
29
  def setup_global_content_proxy
22
30
  http_proxy = FactoryBot.create(:http_proxy, url: @global_content_proxy_mock)
23
31
  HttpProxy.stubs(:default_global_content_proxy).returns(http_proxy)
@@ -61,6 +61,7 @@ class TagsGeneratorTest < ActiveSupport::TestCase
61
61
  assert_equal @host.content_views.pluck(:name).max, actual['content_view'].map(&:second).max
62
62
  assert_equal Foreman.instance_id, actual['satellite_instance_id'].first.last
63
63
  assert_equal @host.organization_id.to_s, actual['organization_id'].first.last
64
+ assert_equal @host.organization.label, actual['organization_label'].first.last
64
65
  end
65
66
 
66
67
  test 'filters tags with empty values' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_rh_cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.1.2
4
+ version: 12.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Foreman Red Hat Cloud team
@@ -173,6 +173,7 @@ files:
173
173
  - db/migrate/20241220184900_change_sync_insights_recommendations_to_true.rb
174
174
  - db/seeds.d/179_ui_notifications.rb
175
175
  - db/seeds.d/189_add_host_inventory_param.rb
176
+ - db/seeds.d/200_features.rb
176
177
  - db/seeds.d/50_job_templates.rb
177
178
  - lib/foreman_inventory_upload.rb
178
179
  - lib/foreman_inventory_upload/async/async_helpers.rb