Skip to content

Commit

Permalink
Fixes #36928 - (sorta) handle load balanced smart proxies when regist…
Browse files Browse the repository at this point in the history
…ering hosts (#10804)

* Fixes #36928 - (sorta) handle load balanced smart proxies when registering hosts
  • Loading branch information
jeremylenz authored Dec 11, 2023
1 parent 6d8d3ca commit 27e9e68
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 5 deletions.
15 changes: 14 additions & 1 deletion app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,20 @@ def client_authorized?
def update_host_registered_through(host, headers)
parent_host = get_parent_host(headers)
host.subscription_facet.update_attribute(:registered_through, parent_host)
content_source_id = get_content_source_id(parent_host)
set_host_content_source(host, parent_host)
end

def registering_thru_load_balancer?(hostname)
::SmartProxy.behind_load_balancer(hostname).present?
end

def set_host_content_source(host, content_source_hostname)
content_source_id = get_content_source_id(content_source_hostname)
if registering_thru_load_balancer?(content_source_hostname)
Rails.logger.info "Host %s registered through load balancer %s" % [host.name, content_source_hostname]
content_source_id = ::SmartProxy.behind_load_balancer(content_source_hostname)&.first&.id
end
Rails.logger.warn "Host %s registered through unknown proxy %s" % [host.name, content_source_hostname] if content_source_id.nil?
host.content_facet.update_attribute(:content_source_id, content_source_id)
end

Expand Down
13 changes: 9 additions & 4 deletions app/models/katello/concerns/host_managed_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,17 @@ def update_os_from_facts

def remote_execution_proxies(provider, *_rest)
proxies = super
if (name = subscription_facet&.registered_through)
registered_through = SmartProxy.with_features(provider)
name = subscription_facet&.registered_through
result = []
if name.present?
result = SmartProxy.with_features(provider)
.authorized
.where(name: name)
if result.blank?
result = SmartProxy.authorized.behind_load_balancer(name)
end
end
proxies[:registered_through] = registered_through || []
proxies[:registered_through] = result
proxies
end
end
Expand Down Expand Up @@ -193,7 +198,7 @@ def self.find_with_expiring_pools(_key, _operator, days_from_now)
property :content_views, 'ContentView', desc: 'Returns content views associated with the host'
property :installed_packages, array_of: 'InstalledPackage', desc: 'Returns a list of packages installed on the host'
end
end
end # of included block

def check_host_registration
if subscription_facet
Expand Down
21 changes: 21 additions & 0 deletions app/models/katello/concerns/smart_proxy_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ def refresh
}
scope :with_content, -> { with_features(PULP_FEATURE, PULP_NODE_FEATURE, PULP3_FEATURE) }

def self.load_balanced
proxies = self.with_content # load balancing is only supported for pulp proxies
ids = proxies.select { |proxy| proxy.load_balanced? }.map(&:id)
proxies.where(id: ids)
end

def self.behind_load_balancer(load_balancer_hostname)
proxies = self.with_content
ids = proxies.select { |proxy| proxy.load_balanced? && proxy.registration_host == load_balancer_hostname }.map(&:id)
proxies.where(id: ids)
end

def self.with_repo(repo)
joins(:capsule_lifecycle_environments).
where("#{Katello::CapsuleLifecycleEnvironment.table_name}.lifecycle_environment_id" => repo.environment_id)
Expand Down Expand Up @@ -121,6 +133,15 @@ def alternate_content_sources
SmartProxy.joins(:smart_proxy_alternate_content_sources).where('katello_smart_proxy_alternate_content_sources.smart_proxy_id' => self.id)
end

def registration_host
url = self.setting('Registration', 'registration_url').presence || self.url
URI.parse(url).host
end

def load_balanced?
URI.parse(self.url).host != self.registration_host
end

def update_content_counts!
# {:content_view_versions=>{87=>{:repositories=>{1=>{:metadata=>{},:counts=>{:rpms=>98, :module_streams=>9898}}}}}
new_content_counts = { content_view_versions: {} }
Expand Down
1 change: 1 addition & 0 deletions lib/katello.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require "oauth"
require "gettext_i18n_rails"
require "foreman-tasks"
require "foreman_remote_execution"
require "rest_client"
require "anemone"
require "securerandom"
Expand Down
17 changes: 17 additions & 0 deletions test/models/concerns/host_managed_extensions_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,23 @@ def test_check_cve_attributes
refute host_attrs.key?(:content_view_id)
refute host_attrs.key?(:lifecycle_environment_id)
end

def test_remote_execution_proxies_registered_through
host = FactoryBot.create(:host, :with_content, :with_subscription, :content_view => @library_view, :lifecycle_environment => @library)
host.subscription_facet.expects(:registered_through).returns('test-proxy.example.com')
rex_feature = Feature.where(:name => "Remote Execution").first_or_create
test_proxy = FactoryBot.create(:smart_proxy, :features => [rex_feature], :url => 'http://test-proxy.example.com:9090', :name => 'test-proxy.example.com')
assert_equal host.remote_execution_proxies(rex_feature.name)[:registered_through], [test_proxy]
end

def test_remote_execution_proxies_registered_through_load_balancer
host = FactoryBot.create(:host, :with_content, :with_subscription, :content_view => @library_view, :lifecycle_environment => @library)
host.subscription_facet.expects(:registered_through).returns('unknown-proxy.example.com')
rex_feature = Feature.where(:name => "Remote Execution").first_or_create
proxy_behind_lb = FactoryBot.create(:smart_proxy, :features => [rex_feature], :url => 'http://test-proxy.example.com:9090', :name => 'test-proxy.example.com')
::SmartProxy.expects(:behind_load_balancer).with('unknown-proxy.example.com').returns([proxy_behind_lb])
assert_equal host.remote_execution_proxies(rex_feature.name)[:registered_through], [proxy_behind_lb]
end
end

class HostManagedExtensionsUpdateTest < HostManagedExtensionsTestBase
Expand Down

0 comments on commit 27e9e68

Please sign in to comment.