Skip to content

Commit

Permalink
Merge branch 'Katello:master' into push_repos_to_pulp
Browse files Browse the repository at this point in the history
  • Loading branch information
phess authored Jan 5, 2023
2 parents e3ce5f4 + 3ef7613 commit c49755f
Show file tree
Hide file tree
Showing 1,196 changed files with 362,738 additions and 211,935 deletions.
9 changes: 7 additions & 2 deletions .github/workflows/react_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@ jobs:
repository: theforeman/foreman
path: ${{ github.workspace }}/foreman # checkout Foreman and Katello as siblings, same as dev env
ref: develop
- name: Generate Foreman dependencies package-lock
run: npm i --package-lock-only --no-audit
working-directory: ${{ github.workspace }}/foreman
- name: Install Foreman dependencies
run: npm i
run: npm ci --no-audit
working-directory: ${{ github.workspace }}/foreman
- name: Generate Katello dependencies package-lock
run: npm i --package-lock-only --no-audit
- name: Install Katello dependencies
run: npm i
run: npm ci --no-audit
- name: Run Katello linting
run: npm run lint
- name: Run Katello tests
Expand Down
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ AllCops:
- foreman/**/*
- node_modules/**/*
- Gemfile
- locale/action_names.rb
Include:
- '**/*.rb'
- app/views/**/*.rabl
Expand Down
1 change: 0 additions & 1 deletion app/assets/javascripts/katello/common/vendor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@
//= require "jquery-ui/effect"
//= require "jquery-ui/effect.all"
//= require "katello/jquery.periodicalupdater"
//= require "katello/jquery.trunk8"
11 changes: 9 additions & 2 deletions app/assets/javascripts/katello/hosts/activation_key_edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,15 @@ function ktSetParam(name, value) {
var paramContainer = ktFindParamContainer(name);
if(value) {
if(! paramContainer) { // we create the param for kt_activation_keys
$("div#parameters a[target~='#global_parameters_table']").click();
paramContainer = $("div#parameters .fields").last();
var addParameterButton = $('#parameters').find('.btn-primary');
addParameterButton.click();
var directionOfAddedItems = addParameterButton.attr('direction');
var paramContainer = $('#parameters').find('.fields');
if(directionOfAddedItems === 'append'){
paramContainer = paramContainer.last();
} else {
paramContainer = paramContainer.first();
}
paramContainer.find("input[name*='name']").val(name);
}
paramContainer.find("textarea").val(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ def pull_manifest
end
end
response.headers['Content-Type'] = media_type
length = manifest_response.try(:body).try(:size)
length ||= 0
response.header['Content-Length'] = "#{length}"
render json: manifest_response
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ def find_host(uuid = nil)
@host = facet.host
end

rescue_from RestClient::Exception do |e|
Rails.logger.error(pp_exception(e, with_backtrace: false))
Rails.logger.error(e.backtrace.detect { |line| line.match("katello.*controller") })
if request_from_katello_cli?
render :json => { :errors => [e.http_body] }, :status => e.http_code
else
render :plain => e.http_body, :status => e.http_code
end
end

def authorize_client_or_user
client_authorized? || authorize
end
Expand Down
26 changes: 16 additions & 10 deletions app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def enabled_repos

#api :POST, "/environments/:environment_id/consumers", N_("Register a consumer in environment")
def consumer_create
host = Katello::RegistrationManager.process_registration(rhsm_params, find_content_view_environment)
host = Katello::RegistrationManager.process_registration(rhsm_params, find_content_view_environments)

host.reload

Expand Down Expand Up @@ -271,7 +271,7 @@ def serials

def get_parent_host(headers)
hostnames = headers["HTTP_X_FORWARDED_HOST"]
host = hostnames.split(/[\,,:]/)[0].strip if hostnames
host = hostnames.split(/[,,:]/)[0].strip if hostnames
host || URI.parse(Setting[:foreman_url]).host
end

Expand Down Expand Up @@ -308,21 +308,27 @@ def find_host(uuid = nil)
@host = ::Host::Managed.unscoped.find(facet.host_id)
end

def find_content_view_environment
environment = nil
def find_content_view_environments
environments = []

if params.key?(:environment_id)
environment = get_content_view_environment("cp_id", params[:environment_id])
elsif params.key?(:organization_id) && !params.key?(:environment_id)
environments = [get_content_view_environment("cp_id", params[:environment_id])]
elsif params.key?(:environments)
if params['environments'].length > 1 && !Setting['allow_multiple_content_views']
fail HttpErrors::BadRequest, _('Registering to multiple environments is not enabled.')
end
environments = params[:environments].map do |env|
get_content_view_environment("cp_id", env['id'])
end
elsif params.key?(:organization_id) && !params.key?(:environment_id) && !params.key?(:environments)
organization = Organization.current
environment = organization.library.content_view_environment
environments = organization.library.content_view_environment
elsif User.current.default_organization.present?
environment = User.current.default_organization.library.content_view_environment
environments = User.current.default_organization.library.content_view_environment
else
fail HttpErrors::NotFound, _("User '%s' did not specify an organization ID and does not have a default organization.") % current_user.login
end

environment
environments
end

def find_hypervisor_organization
Expand Down
8 changes: 8 additions & 0 deletions app/controllers/katello/api/v2/activation_keys_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Api::V2::ActivationKeysController < Api::V2::ApiController
:content_override, :add_subscriptions, :remove_subscriptions,
:subscriptions]
before_action :verify_simple_content_access_disabled, :only => [:add_subscriptions]
before_action :validate_release_version, :only => [:create, :update]

wrap_parameters :include => (ActivationKey.attribute_names + %w(host_collection_ids service_level auto_attach purpose_role purpose_usage purpose_addons content_view_environment))

Expand Down Expand Up @@ -229,6 +230,7 @@ def content_override
param :id, String, :desc => N_("ID of the activation key"), :required => true
param :content_access_mode_all, :bool, :desc => N_("Get all content available, not just that provided by subscriptions")
param :content_access_mode_env, :bool, :desc => N_("Limit content to just that available in the activation key's content view version")
param_group :search, Api::V2::ApiController
def product_content
# note this is just there as a place holder for apipie.
# The routing would automatically redirect it to repository_sets#index
Expand Down Expand Up @@ -337,5 +339,11 @@ def verify_simple_content_access_disabled
fail HttpErrors::BadRequest, _("The specified organization is in Simple Content Access mode. Attaching subscriptions is disabled")
end
end

def validate_release_version
if params[:release_version].present? && !@organization.library.available_releases.include?(params[:release_version])
fail HttpErrors::BadRequest, _("Invalid release version: [%s]") % params[:release_version]
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
module Katello
class Api::V2::AlternateContentSourcesBulkActionsController < Api::V2::ApiController
before_action :find_alternate_content_sources

api :PUT, '/alternate_content_sources/bulk/destroy', N_('Destroy one or more alternate content sources')
param :ids, Array, desc: N_('List of alternate content source IDs'), required: true
def destroy_alternate_content_sources
deletable_alternate_content_sources = @alternate_content_sources.deletable

if deletable_alternate_content_sources.empty?
msg = _("Unable to delete any alternate content source. You either do not have the permission to"\
" delete, or none of the alternate content sources exist.")
fail HttpErrors::UnprocessableEntity, msg
end
task = async_task(::Actions::BulkAction,
::Actions::Katello::AlternateContentSource::Destroy,
deletable_alternate_content_sources)
respond_for_async :resource => task
end

api :POST, '/alternate_content_sources/bulk/refresh', N_('Refresh alternate content sources')
param :ids, Array, desc: N_('List of alternate content source IDs'), required: true
def refresh_alternate_content_sources
refreshable_alternate_content_sources = @alternate_content_sources.editable
if refreshable_alternate_content_sources.empty?
msg = _("Unable to refresh any alternate content source. You either do not have the permission to"\
" refresh, or none of the alternate content sources exist.")
fail HttpErrors::UnprocessableEntity, msg
else
task = async_task(::Actions::BulkAction,
::Actions::Katello::AlternateContentSource::Refresh,
refreshable_alternate_content_sources)
respond_for_async resource: task
end
end

private

def find_alternate_content_sources
params.require(:ids)
@alternate_content_sources = AlternateContentSource.readable.where(id: params[:ids])
end
end
end
154 changes: 154 additions & 0 deletions app/controllers/katello/api/v2/alternate_content_sources_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
module Katello
class Api::V2::AlternateContentSourcesController < Api::V2::ApiController
include Katello::Concerns::FilteredAutoCompleteSearch

acs_wrap_params = AlternateContentSource.attribute_names + [:smart_proxy_ids, :smart_proxy_names, :product_ids]
wrap_parameters :alternate_content_source, include: acs_wrap_params

before_action :find_authorized_katello_resource, only: [:show, :update, :destroy, :refresh]
before_action :find_smart_proxies, only: :create
before_action :find_products, only: :create

def_param_group :acs do
param :name, String, desc: N_("Name of the alternate content source")
param :description, String, desc: N_("Description for the alternate content source"), required: false
param :base_url, String, desc: N_('Base URL for finding alternate content'), required: false
param :subpaths, Array, desc: N_('Path suffixes for finding alternate content'), required: false
param :smart_proxy_ids, Array, desc: N_("Ids of smart proxies to associate"), required: false
param :smart_proxy_names, Array, desc: N_("Names of smart proxies to associate"), required: false
param :upstream_username, String, desc: N_("Basic authentication username"), required: false
param :upstream_password, String, desc: N_("Basic authentication password"), required: false
param :ssl_ca_cert_id, :number, desc: N_("Identifier of the content credential containing the SSL CA Cert"), required: false
param :ssl_client_cert_id, :number, desc: N_("Identifier of the content credential containing the SSL Client Cert"), required: false
param :ssl_client_key_id, :number, desc: N_("Identifier of the content credential containing the SSL Client Key"), required: false
param :verify_ssl, :bool, desc: N_("If SSL should be verified for the upstream URL"), required: false
param :use_http_proxies, :bool, desc: N_("If the smart proxies' assigned HTTP proxies should be used"), required: false
param :product_ids, Array, desc: N_("IDs of products to copy repository information from into a Simplified Alternate Content Source. Products must include at least one repository of the chosen content type."), required: false
end

api :GET, "/alternate_content_sources", N_("List alternate content sources.")
param :name, String, :desc => N_("Name of the alternate content source"), :required => false
param_group :search, Api::V2::ApiController
add_scoped_search_description_for(AlternateContentSource)
def index
respond_to do |format|
format.csv do
options[:csv] = true
alternate_content_sources = scoped_search(index_relation, :name, :asc)
if @acs.custom? || @acs.rhui?
csv_response(alternate_content_sources,
[:id, :name, :description, :label, :base_url, :subpaths, :content_type, :alternate_content_source_type],
['Id', 'Name', 'Description', 'label', 'Base URL', 'Subpaths', 'Content Type', 'Alternate Content Source Type'])
elsif @acs.simplified?
csv_response(alternate_content_sources,
[:id, :name, :description, :label, :content_type, :alternate_content_source_type, :products],
['Id', 'Name', 'Description', 'label', 'Content Type', 'Alternate Content Source Type', 'Products'])
end
end
format.any do
alternate_content_sources = scoped_search(index_relation, :name, :asc)
respond(collection: alternate_content_sources)
end
end
end

def index_relation
query = AlternateContentSource.readable.distinct
query = query.where(name: params[:name]) if params[:name]
query
end

api :GET, '/alternate_content_sources/:id', N_('Show an alternate content source.')
param :id, :number, :required => true, :desc => N_("Alternate content source ID")
def show
respond_for_show(:resource => @alternate_content_source)
end

api :POST, '/alternate_content_sources', N_('Create an alternate content source to download content from during repository syncing. Note: alternate content sources are global and affect ALL sync actions on their smart proxies regardless of organization.')
param :content_type, RepositoryTypeManager.defined_repository_types.keys & AlternateContentSource::CONTENT_TYPES, desc: N_("The content type for the Alternate Content Source"), required: false
param :alternate_content_source_type, AlternateContentSource::ACS_TYPES, desc: N_("The Alternate Content Source type")
param_group :acs
def create
@alternate_content_source = ::Katello::AlternateContentSource.new(acs_params.except(:smart_proxy_ids, :smart_proxy_names, :product_ids))
@alternate_content_source.verify_ssl = nil if @alternate_content_source.simplified?
sync_task(::Actions::Katello::AlternateContentSource::Create, @alternate_content_source, @smart_proxies, @products)
@alternate_content_source.reload
respond_for_create(resource: @alternate_content_source)
end

api :PUT, '/alternate_content_sources/:id', N_('Update an alternate content source.')
param_group :acs
param :id, :number, :required => true, :desc => N_("Alternate content source ID")
def update
# If a user doesn't include smart proxies or products in the update call, don't accidentally remove all of them.
if params[:smart_proxy_ids].nil? && params[:smart_proxy_names].nil?
@smart_proxies = @alternate_content_source.smart_proxies
elsif params[:smart_proxy_ids] == [] || params[:smart_proxy_names] == []
@smart_proxies = []
else
find_smart_proxies
end

if params[:product_ids].nil?
@products = @alternate_content_source.products
elsif params[:product_ids] == []
@products = []
else
find_products
end
sync_task(::Actions::Katello::AlternateContentSource::Update, @alternate_content_source, @smart_proxies, @products, acs_params.except(:smart_proxy_ids, :smart_proxy_names, :product_ids))
respond_for_show(:resource => @alternate_content_source)
end

api :DELETE, '/alternate_content_sources/:id', N_('Destroy an alternate content source.')
param :id, :number, :required => true, :desc => N_("Alternate content source ID")
def destroy
sync_task(::Actions::Katello::AlternateContentSource::Destroy, @alternate_content_source)
respond_for_destroy
end

api :POST, '/alternate_content_sources/:id/refresh', N_('Refresh an alternate content source. Refreshing, like repository syncing, is required before using an alternate content source.')
param :id, :number, :required => true, :desc => N_("Alternate content source ID")
def refresh
task = async_task(::Actions::Katello::AlternateContentSource::Refresh, @alternate_content_source)
respond_for_async :resource => task
end

protected

def acs_params
keys = [:name, :label, :description, {smart_proxy_ids: []}, {smart_proxy_names: []}, :content_type, :alternate_content_source_type, :use_http_proxies]
keys += [:base_url, {subpaths: []}, :upstream_username, :upstream_password, :ssl_ca_cert_id, :ssl_client_cert_id, :ssl_client_key_id, :verify_ssl] if params[:action] == 'create' || @alternate_content_source&.custom? || @alternate_content_source&.rhui?
keys += [{product_ids: []}] if params[:action] == 'create' || @alternate_content_source&.simplified?
params.require(:alternate_content_source).permit(*keys).to_h.with_indifferent_access
end

def find_smart_proxies
if params[:smart_proxy_ids]
@smart_proxies = ::SmartProxy.where(id: params[:smart_proxy_ids])
elsif params[:smart_proxy_names]
@smart_proxies = ::SmartProxy.where(name: params[:smart_proxy_names])
end
if params[:smart_proxy_ids] && @smart_proxies.length < params[:smart_proxy_ids].length
missing_smart_proxies = params[:smart_proxy_ids] - @smart_proxies.pluck(:id)
fail HttpErrors::NotFound, _("Couldn't find smart proxies with id '%s'") % missing_smart_proxies.to_sentence
elsif params[:smart_proxy_names] && @smart_proxies.length < params[:smart_proxy_names].length
missing_smart_proxies = params[:smart_proxy_names] - @smart_proxies.pluck(:name)
fail HttpErrors::NotFound, _("Couldn't find smart proxies with name '%s'") % missing_smart_proxies.to_sentence
end
end

def find_products
if params[:product_ids]
@products = ::Katello::Product.where(id: params[:product_ids])
else
@products = nil
end

if params[:product_ids] && @products.length < params[:product_ids].length
missing_products = params[:product_ids] - @products.pluck(:id)
fail HttpErrors::NotFound, _("Couldn't find products with id '%s'") % missing_products.to_sentence
end
end
end
end
5 changes: 5 additions & 0 deletions app/controllers/katello/api/v2/capsule_content_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class Api::V2::CapsuleContentController < Api::V2::ApiController
before_action :find_capsule, :except => [:sync, :cancel_sync, :add_lifecycle_environment, :remove_lifecycle_environment, :reclaim_space]
before_action :find_editable_capsule, :only => [:sync, :cancel_sync, :add_lifecycle_environment, :remove_lifecycle_environment]
before_action :find_environment, :only => [:add_lifecycle_environment, :remove_lifecycle_environment]
before_action :find_acs_http_proxy, :only => [:add_acs_http_proxy]
before_action :find_optional_organization, :only => [:sync_status]

def_param_group :lifecycle_environments do
Expand Down Expand Up @@ -123,6 +124,10 @@ def find_environment
@environment = Katello::KTEnvironment.readable.find(params[:environment_id])
end

def find_acs_http_proxy
@acs_http_proxy = ::HttpProxy.readable.find(params[:alternate_content_source_http_proxy_id])
end

def find_content_view
@content_view = Katello::ContentView.readable.find(params[:content_view_id])
end
Expand Down
Loading

0 comments on commit c49755f

Please sign in to comment.