Skip to content

Commit

Permalink
[CP] Katello 4.0.1.2 CP for container gateway fixes (#9411)
Browse files Browse the repository at this point in the history
* Fixes #32233 - Katello should send user-repo info to container gateway (#9267)

(cherry picked from commit 628ee7e)

Conflicts:
	app/controllers/katello/api/registry/registry_proxies_controller.rb
	app/models/katello/authorization/content_view.rb
	app/models/katello/concerns/smart_proxy_extensions.rb

* Bump version to 4.0.1.2

Pins foreman-tasks gem (#4)

Pin foreman-tasks related gems (#5)
  • Loading branch information
ianballou authored Jun 19, 2021
1 parent 0f204f4 commit 1287d02
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def find_readable_repository
return nil unless params[:repository]
repository = Repository.docker_type.find_by(container_repository_name: params[:repository])
if require_user_authorization?(repository)
repository = readable_repositories.docker_type.find_by(container_repository_name: params[:repository])
repository = Repository.readable_docker_catalog.find_by(container_repository_name: params[:repository])
end
repository
end
Expand Down Expand Up @@ -331,7 +331,7 @@ def v1_search
params[:per_page] = params[:n] || 25
params[:search] = params[:q]

search_results = scoped_search(readable_repositories.docker_type.distinct,
search_results = scoped_search(Repository.readable_docker_catalog.distinct,
:container_repository_name, :asc, options)

results = {
Expand All @@ -345,7 +345,7 @@ def v1_search
end

def catalog
repositories = readable_repositories.docker_type.collect do |repository|
repositories = Repository.readable_docker_catalog.collect do |repository|
repository.container_repository_name
end
render json: { repositories: repositories }
Expand Down
1 change: 1 addition & 0 deletions app/controllers/katello/api/v2/repositories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def custom_index_relation(collection)
:required => false
param :with_content, RepositoryTypeManager.enabled_content_types, :desc => N_("only repositories having at least one of the specified content type ex: rpm , erratum")
param :download_policy, ::Runcible::Models::YumImporter::DOWNLOAD_POLICIES, :desc => N_("limit to only repositories with this download policy")
param :username, String, :desc => N_("only show the repositories readable by this user with this username")
param_group :search, Api::V2::ApiController
add_scoped_search_description_for(Repository)
def index
Expand Down
50 changes: 44 additions & 6 deletions app/lib/actions/katello/capsule_content/sync_capsule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,53 @@ def plan(smart_proxy, options = {})
end
end
end
update_unauthenticated_repo_list(smart_proxy) if smart_proxy.has_feature?("Container_Gateway")
sync_container_gateway(smart_proxy)
end

def update_unauthenticated_repo_list(smart_proxy)
unauthenticated_repo_list =
::Katello::SmartProxyHelper.new(smart_proxy).combined_repos_available_to_capsule.select do |repo|
repo.docker? && repo.environment.registry_unauthenticated_pull
def sync_container_gateway(smart_proxy)
if smart_proxy.has_feature?(::SmartProxy::CONTAINER_GATEWAY_FEATURE)
update_container_repo_list(smart_proxy)
users = smart_proxy.container_gateway_users
update_user_container_repo_mapping(smart_proxy, users) if users.any?
end
end

def unauthenticated_container_repositories
::Katello::Repository.joins(:environment).where("#{::Katello::KTEnvironment.table_name}.registry_unauthenticated_pull" => true).select(:id).pluck(:id)
end

def update_container_repo_list(smart_proxy)
# [{ repository: "repoA", auth_required: false }]
repo_list = []
::Katello::SmartProxyHelper.new(smart_proxy).combined_repos_available_to_capsule.each do |repo|
if repo.docker? && !repo.container_repository_name.nil?
repo_list << { repository: repo.container_repository_name,
auth_required: !unauthenticated_container_repositories.include?(repo.id) }
end
smart_proxy.update_unauthenticated_repo_list(unauthenticated_repo_list.map(&:container_repository_name))
end
smart_proxy.update_container_repo_list(repo_list)
end

def update_user_container_repo_mapping(smart_proxy, users)
# Example user-repo mapping:
# { users:
# [
# 'user a' => [{ repository: 'repo 1', auth_required: true }]
# ]
# }

user_repo_map = { users: [] }
users.each do |user|
inner_repo_list = []
repositories = ::Katello::Repository.readable_docker_catalog_as(user)
repositories.each do |repo|
next if repo.container_repository_name.nil?
inner_repo_list << { repository: repo.container_repository_name,
auth_required: !unauthenticated_container_repositories.include?(repo.id) }
end
user_repo_map[:users] << { user.login => inner_repo_list }
end
smart_proxy.update_user_container_repo_mapping(user_repo_map)
end

def repos_to_sync(smart_proxy, environment, content_view, repository, skip_metatadata_check = false)
Expand Down
12 changes: 12 additions & 0 deletions app/models/katello/authorization/content_view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ def readable
authorized(:view_content_views)
end

def creatable
authorized(:view_content_views)
end

def importable?
creatable? && publishable?
end

def readable_as(user)
authorized_as(user, :view_content_views)
end

def readable?
::User.current.can?(:view_content_views)
end
Expand Down
18 changes: 18 additions & 0 deletions app/models/katello/authorization/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,24 @@ def readable
joins(:root).where("#{Repository.table_name}.id in (?) or #{self.table_name}.id in (?) or #{self.table_name}.id in (?) or #{self.table_name}.id in (?)", in_products, in_content_views, in_versions, in_environments)
end

def readable_as(user)
in_products = Repository.in_product(Katello::Product.authorized_as(user, :view_products)).select(:id)
in_environments = Repository.where(:environment_id => Katello::KTEnvironment.authorized_as(user, :view_lifecycle_environments)).select(:id)
in_content_views = Repository.joins(:content_view_repositories).where("#{ContentViewRepository.table_name}.content_view_id" => Katello::ContentView.readable_as(user)).select(:id)
in_versions = Repository.joins(:content_view_version).where("#{Katello::ContentViewVersion.table_name}.content_view_id" => Katello::ContentView.readable_as(user)).select(:id)
joins(:root).where("#{Repository.table_name}.id in (?) or #{self.table_name}.id in (?) or #{self.table_name}.id in (?) or #{self.table_name}.id in (?)", in_products, in_content_views, in_versions, in_environments)
end

def readable_docker_catalog
readable_docker_catalog_as(User.current)
end

def readable_docker_catalog_as(user)
table_name = Repository.table_name
in_unauth_environments = Repository.joins(:environment).where("#{Katello::KTEnvironment.table_name}.registry_unauthenticated_pull" => true).select(:id)
Repository.readable_as(user).or(Repository.joins(:root).where("#{table_name}.id in (?)", in_unauth_environments)).non_archived.docker_type
end

def exportable
in_product(Katello::Product.exportable)
end
Expand Down
14 changes: 14 additions & 0 deletions app/models/katello/concerns/smart_proxy_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def refresh
PULP3_FEATURE = "Pulpcore".freeze
PULP_FEATURE = "Pulp".freeze
PULP_NODE_FEATURE = "Pulp Node".freeze
CONTAINER_GATEWAY_FEATURE = "Container_Gateway".freeze

DOWNLOAD_INHERIT = 'inherit'.freeze
DOWNLOAD_POLICIES = ::Runcible::Models::YumImporter::DOWNLOAD_POLICIES + [DOWNLOAD_INHERIT]
Expand Down Expand Up @@ -119,6 +120,19 @@ def update_puppet_path
path
end

def update_container_repo_list(repo_list)
ProxyAPI::ContainerGateway.new(url: self.url).repository_list({ repositories: repo_list })
end

def update_user_container_repo_mapping(user_repo_map)
ProxyAPI::ContainerGateway.new(url: self.url).user_repository_mapping(user_repo_map)
end

def container_gateway_users
usernames = ProxyAPI::ContainerGateway.new(url: self.url).users
::User.where(login: usernames['users'])
end

def pulp_url
uri = URI.parse(url)
"#{uri.scheme}://#{uri.host}/pulp/api/v2/"
Expand Down
3 changes: 2 additions & 1 deletion katello.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ Gem::Specification.new do |gem|
gem.add_dependency "rest-client"

gem.add_dependency "rabl"
gem.add_dependency "foreman-tasks", ">= 4.0"
gem.add_dependency "foreman-tasks", "~> 4.0"
gem.add_dependency "foreman-tasks-core", "<= 0.3.5"
gem.add_dependency "foreman_remote_execution", ">= 3.0"
gem.add_dependency "dynflow", ">= 1.2.0"
gem.add_dependency "activerecord-import"
Expand Down
2 changes: 1 addition & 1 deletion lib/katello/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Katello
VERSION = "4.0.1.1".freeze
VERSION = "4.0.1.2".freeze
end
33 changes: 22 additions & 11 deletions lib/proxy_api/container_gateway.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
module ProxyAPI
class ContainerGateway < ::ProxyAPI::Resource
def initialize(args)
@url = args[:url] + "/container_gateway/v2"
@url = args[:url] + "/container_gateway"
super args
end

def unauthenticated_repository_list(args = {})
# get '/v2/unauthenticated_repository_list/?'
# put '/v2/unauthenticated_repository_list/?'
@url += "/unauthenticated_repository_list"
if args.empty?
@unauthenticated_repo_list = parse get
else
parse put(args)
end
def repository_list(args)
# put '/v2/repository_list/?'
@url += "/repository_list"
parse put(args)
rescue => e
raise ::ProxyAPI::ProxyException.new(url, e, N_("Unable to perform unauthenticated repository list operation"))
raise ::ProxyAPI::ProxyException.new(url, e, N_("Unable to update the repository list"))
end

def user_repository_mapping(args)
# put '/v2/user_repository_mapping/?'
@url += "/user_repository_mapping"
parse put(args)
rescue => e
raise ::ProxyAPI::ProxyException.new(url, e, N_("Unable to update the user-repository mapping"))
end

def users
# get '/v2/users/?'
@url += "/users"
@users = parse get
rescue => e
raise ::ProxyAPI::ProxyException.new(url, e, N_("Unable to get users"))
end
end
end
23 changes: 23 additions & 0 deletions test/actions/katello/capsule_content_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -316,5 +316,28 @@ class SyncTest < TestBase
action = plan_action_tree(action_class, capsule_content.smart_proxy, :environment_id => staging_environment.id)
refute_empty action.errors
end

it 'correctly generates a container gateway repository list' do
with_pulp3_features(capsule_content.smart_proxy)
capsule_content.smart_proxy.add_lifecycle_environment(environment)
repo = katello_repositories(:pulp3_file_1)
repo.root.update_attribute(:unprotected, true)

repo_list_update_expectation = capsule_content.smart_proxy.expects(:update_container_repo_list).with do |arg|
arg.include?({:repository => "busybox", :auth_required => true}) && arg.include?({:repository => "empty_organization-puppet_product-busybox", :auth_required => true})
end
repo_list_update_expectation.once.returns(true)

repo_mapping_update_expectation = capsule_content.smart_proxy.expects(:update_user_container_repo_mapping).with do |arg|
arg[:users].first["secret_admin"].include?({:repository => "empty_organization-puppet_product-busybox",
:auth_required => true}) &&
arg[:users].first["secret_admin"].include?({:repository => "busybox",
:auth_required => true})
end
repo_mapping_update_expectation.once.returns(true)

capsule_content.smart_proxy.expects(:container_gateway_users).returns(::User.where(login: 'secret_admin'))
plan_action_tree(action_class, capsule_content.smart_proxy, :repository_id => repo.id)
end
end
end
3 changes: 2 additions & 1 deletion test/support/capsule_support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ module CapsuleSupport
def pulp_features
@pulp_node_feature ||= Feature.where(name: SmartProxy::PULP_NODE_FEATURE).first_or_create
@pulp3_feature ||= Feature.where(name: SmartProxy::PULP3_FEATURE).first_or_create
[@pulp_node_feature, @pulp3_feature]
@container_gateway_feature ||= Feature.where(name: SmartProxy::CONTAINER_GATEWAY_FEATURE).first_or_create
[@pulp_node_feature, @pulp3_feature, @container_gateway_feature]
end

def proxy_with_pulp(proxy_resource = nil)
Expand Down

0 comments on commit 1287d02

Please sign in to comment.