module Katello class Api::V2::CapsuleContentController < Api::V2::ApiController resource_description do api_base_url "/katello/api" end 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 param :id, Integer, :desc => N_('Id of the smart proxy'), :required => true param :organization_id, Integer, :desc => N_('Id of the organization to limit environments on') end def_param_group :update_lifecycle_environments do param :id, Integer, :desc => N_('Id of the smart proxy'), :required => true param :environment_id, Integer, :desc => N_('Id of the lifecycle environment'), :required => true end api :GET, '/capsules/:id/content/counts', N_('List content counts for the smart proxy') param :id, Integer, :desc => N_('Id of the smart proxy'), :required => true def counts render json: @capsule.content_counts.to_json end api :GET, '/capsules/:id/content/lifecycle_environments', N_('List the lifecycle environments attached to the smart proxy') param_group :lifecycle_environments def lifecycle_environments environments = @capsule.lifecycle_environments environment_org_scope = params[:organization_id] ? environments.where(organization_id: params[:organization_id]) : environments respond_for_lifecycle_environments_index(environment_org_scope) end api :GET, '/capsules/:id/content/available_lifecycle_environments', N_('List the lifecycle environments not attached to the smart proxy') param_group :lifecycle_environments def available_lifecycle_environments environments = @capsule.available_lifecycle_environments(params[:organization_id]).readable respond_for_lifecycle_environments_index(environments) end api :POST, '/capsules/:id/content/lifecycle_environments', N_('Add lifecycle environments to the smart proxy') param_group :update_lifecycle_environments def add_lifecycle_environment @capsule.add_lifecycle_environment(@environment) respond_for_lifecycle_environments_index(@capsule.lifecycle_environments) end api :DELETE, '/capsules/:id/content/lifecycle_environments/:environment_id', N_('Remove lifecycle environments from the smart proxy') param_group :update_lifecycle_environments def remove_lifecycle_environment @capsule.remove_lifecycle_environment(@environment) respond_for_lifecycle_environments_index(@capsule.lifecycle_environments) end api :POST, '/capsules/:id/content/sync', N_('Synchronize the content to the smart proxy') param :id, Integer, :desc => N_('Id of the smart proxy'), :required => true param :environment_id, Integer, :desc => N_('Id of the environment to limit the synchronization on') param :content_view_id, Integer, :desc => N_('Id of the content view to limit the synchronization on') param :repository_id, Integer, :desc => N_('Id of the repository to limit the synchronization on') param :skip_metadata_check, :bool, :desc => N_('Skip metadata check on each repository on the smart proxy') def sync find_environment if params[:environment_id] find_content_view if params[:content_view_id] find_repository if params[:repository_id] skip_metadata_check = ::Foreman::Cast.to_bool(params[:skip_metadata_check]) sync_options = { :environment_id => @environment.try(:id), :content_view_id => @content_view.try(:id), :repository_id => @repository.try(:id), :skip_metadata_check => skip_metadata_check, } sync_options[:environment_ids] = @capsule.lifecycle_environments&.pluck(:id) unless (@environment || @content_view || @repository) task = async_task(::Actions::Katello::CapsuleContent::Sync, @capsule, sync_options) respond_for_async :resource => task end api :POST, '/capsules/:id/content/update_counts', N_('Update content counts for the smart proxy') param :id, Integer, :desc => N_('Id of the smart proxy'), :required => true param :environment_id, Integer, :desc => N_('Id of the environment to limit the content counting on') param :content_view_id, Integer, :desc => N_('Id of the content view to limit the content counting on') param :repository_id, Integer, :desc => N_('Id of the repository to limit the content counting on') def update_counts find_environment if params[:environment_id] find_content_view if params[:content_view_id] find_repository if params[:repository_id] count_options = { :environment_id => @environment.try(:id), :content_view_id => @content_view.try(:id), :repository_id => @repository.try(:id), } task = async_task(::Actions::Katello::CapsuleContent::UpdateContentCounts, @capsule, count_options) respond_for_async :resource => task end api :GET, '/capsules/:id/content/sync', N_('Get current smart proxy synchronization status') param :id, Integer, :desc => N_('Id of the smart proxy'), :required => true param :organization_id, Integer, :desc => N_('Id of the organization to get the status for'), :required => false def sync_status @lifecycle_environments = @organization ? @capsule.lifecycle_environments.where(organization_id: @organization.id) : @capsule.lifecycle_environments end api :DELETE, '/capsules/:id/content/sync', N_('Cancel running smart proxy synchronization') param :id, Integer, :desc => N_('Id of the smart proxy'), :required => true def cancel_sync tasks = @capsule.cancel_sync if tasks.empty? render_message _('There\'s no running synchronization for this smart proxy.') else render_message _('Trying to cancel the synchronization...') end end api :POST, '/capsules/:id/content/reclaim_space', N_('Reclaim space from all On Demand repositories on a smart proxy') param :id, :number, :required => true, :desc => N_('Id of the smart proxy') def reclaim_space find_capsule(true) task = async_task(::Actions::Pulp3::CapsuleContent::ReclaimSpace, @capsule) respond_for_async :resource => task end api :POST, '/capsules/:id/content/verify_checksum', N_('Check for missing or corrupted artifacts, and attempt to redownload them.') param :id, :number, :required => true, :desc => N_('Id of the smart proxy') param :environment_id, Integer, :desc => N_('Id of the environment to limit verifying checksum on') param :content_view_id, Integer, :desc => N_('Id of the content view to limit verifying checksum on') param :repository_id, Integer, :desc => N_('Id of the repository to limit verifying checksum on') def verify_checksum find_capsule(false) find_environment if params[:environment_id] find_content_view if params[:content_view_id] find_repository if params[:repository_id] repair_options = { :environment_id => @environment.try(:id), :content_view_id => @content_view.try(:id), :repository_id => @repository.try(:id), } repair_options[:environment_ids] = @capsule.lifecycle_environments&.pluck(:id) unless (@environment || @content_view || @repository) task = async_task(::Actions::Katello::CapsuleContent::VerifyChecksum, @capsule, repair_options) respond_for_async :resource => task end protected def respond_for_lifecycle_environments_index(environments) collection = { :results => environments, :total => environments.size, :subtotal => environments.size, } respond_for_index(:collection => collection, :template => :lifecycle_environments) end def find_editable_capsule @capsule = SmartProxy.unscoped.authorized(:manage_capsule_content).find(params[:id]) unless @capsule&.pulp_mirror? fail _("This request may only be performed on a Smart proxy that has the Pulpcore feature with mirror=true.") end end def find_capsule(primary_okay = false) @capsule = SmartProxy.unscoped.authorized(:view_capsule_content).find(params[:id]) unless @capsule&.pulp_mirror? || primary_okay fail _("This request may only be performed on a Smart proxy that has the Pulpcore feature with mirror=true.") end end 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 def find_repository @repository = Katello::Repository.readable.find(params[:repository_id]) end end end