app/controllers/katello/api/v2/repositories_controller.rb in katello-2.4.5 vs app/controllers/katello/api/v2/repositories_controller.rb in katello-3.0.0.rc1

- old
+ new

@@ -4,18 +4,18 @@ before_filter :find_organization, :only => [:index, :auto_complete_search] before_filter :find_product, :only => [:index, :auto_complete_search] before_filter :find_product_for_create, :only => [:create] before_filter :find_organization_from_product, :only => [:create] - before_filter :find_repository, :only => [:show, :update, :destroy, :sync, + before_filter :find_repository, :only => [:show, :update, :destroy, :sync, :export, :remove_content, :upload_content, :import_uploads, :gpg_key_content] before_filter :find_content, :only => :remove_content before_filter :find_organization_from_repo, :only => [:update] before_filter :find_gpg_key, :only => [:create, :update] before_filter :error_on_rh_product, :only => [:create] - before_filter :error_on_rh_repo, :only => [:update, :destroy] + before_filter :error_on_rh_repo, :only => [:destroy] skip_before_filter :authorize, :only => [:sync_complete, :gpg_key_content] skip_before_filter :require_org, :only => [:sync_complete] skip_before_filter :require_user, :only => [:sync_complete] skip_before_filter :check_content_type, :only => [:upload_content] @@ -25,13 +25,15 @@ param :label, String, :required => false param :product_id, :number, :required => true, :desc => N_("Product the repository belongs to") param :url, String, :desc => N_("repository source url") param :gpg_key_id, :number, :desc => N_("id of the gpg key that will be assigned to the new repository") param :unprotected, :bool, :desc => N_("true if this repository can be published via HTTP") - param :content_type, String, :required => true, :desc => N_("type of repo (either 'yum', 'puppet' or 'docker')") + param :content_type, RepositoryTypeManager.creatable_repository_types.keys, :required => true, :desc => N_("type of repo (either 'yum', 'puppet', 'docker', or 'ostree')") param :checksum_type, String, :desc => N_("checksum of the repository, currently 'sha1' & 'sha256' are supported.'") param :docker_upstream_name, String, :desc => N_("name of the upstream docker repository") + param :download_policy, ["immediate", "on_demand", "background"], :desc => N_("download policy for yum repos (either 'immediate', 'on_demand', or 'background')") + param :mirror_on_sync, :bool, :desc => N_("true if this repository when synced has to be mirrored from the source and stale rpms removed.") end api :GET, "/repositories", N_("List of enabled repositories") api :GET, "/content_views/:id/repositories", N_("List of repositories for a content view") param :organization_id, :number, :required => true, :desc => N_("ID of an organization to show repositories in") @@ -40,16 +42,15 @@ param :content_view_id, :number, :desc => N_("ID of a content view to show repositories in") param :content_view_version_id, :number, :desc => N_("ID of a content view version to show repositories in") param :erratum_id, String, :desc => N_("Id of an erratum to find repositories that contain the erratum") param :rpm_id, String, :desc => N_("Id of a package to find repositories that contain the rpm") param :library, :bool, :desc => N_("show repositories in Library and the default content view") - param :content_type, String, :desc => N_("limit to only repositories of this time") + param :content_type, RepositoryTypeManager.repository_types.keys, :desc => (N_("limit to only repositories of this type")) param :name, String, :desc => N_("name of the repository"), :required => false param :available_for, String, :desc => N_("interpret specified object to return only Repositories that can be associated with specified object. Only 'content_view' is supported."), :required => false param_group :search, Api::V2::ApiController - # rubocop:disable Metrics/MethodLength def index options = {:includes => [:gpg_key, :product, :environment]} respond(:collection => scoped_search(index_relation.uniq, :name, :desc, options)) end @@ -111,50 +112,102 @@ api :POST, "/repositories", N_("Create a custom repository") param_group :repo def create repo_params = repository_params + unless RepositoryTypeManager.creatable_by_user?(repo_params[:content_type]) + msg = _("Invalid params provided - content_type must be one of %s") % RepositoryTypeManager.creatable_repository_types.keys.join(",") + fail HttpErrors::UnprocessableEntity, msg + end + gpg_key = @product.gpg_key unless repo_params[:gpg_key_id].blank? gpg_key = @gpg_key end repo_params[:label] = labelize_params(repo_params) repo_params[:url] = nil if repo_params[:url].blank? unprotected = repo_params.key?(:unprotected) ? repo_params[:unprotected] : true repository = @product.add_repo(repo_params[:label], repo_params[:name], repo_params[:url], repo_params[:content_type], unprotected, - gpg_key, repository_params[:checksum_type]) + gpg_key, repository_params[:checksum_type], repo_params[:download_policy]) repository.docker_upstream_name = repo_params[:docker_upstream_name] if repo_params[:docker_upstream_name] + repository.mirror_on_sync = ::Foreman::Cast.to_bool(repo_params[:mirror_on_sync]) if repo_params[:mirror_on_sync] sync_task(::Actions::Katello::Repository::Create, repository, false, true) repository = Repository.find(repository.id) respond_for_show(:resource => repository) end + api :GET, "/repositories/repository_types", N_("Show the available repository types") + param :creatable, :bool, :desc => N_("When set to 'True' repository types that are creatable will be returned") + def repository_types + creatable = ::Foreman::Cast.to_bool(params[:creatable]) + repo_types = creatable ? RepositoryTypeManager.creatable_repository_types : RepositoryTypeManager.repository_types + render :json => repo_types.values + end + api :GET, "/repositories/:id", N_("Show a custom repository") param :id, :identifier, :required => true, :desc => N_("repository ID") def show respond_for_show(:resource => @repository) end api :POST, "/repositories/:id/sync", N_("Sync a repository") param :id, :identifier, :required => true, :desc => N_("repository ID") + param :source_url, String, :desc => N_("temporarily override feed URL for sync"), :required => false + param :incremental, :bool, :desc => N_("perform an incremental import"), :required => false def sync - task = async_task(::Actions::Katello::Repository::Sync, @repository) + if params[:source_url].present? && params[:source_url] !~ /\A#{URI.regexp}\z/ + fail HttpErrors::BadRequest, _("source URL is malformed") + end + + if params[:source_url].blank? && @repository.url.blank? + fail HttpErrors::BadRequest, _("attempted to sync without a feed URL") + end + + task = async_task(::Actions::Katello::Repository::Sync, @repository, + nil, params[:source_url], ::Foreman::Cast.to_bool(params[:incremental])) respond_for_async :resource => task end + api :POST, "/repositories/:id/export", N_("Export a repository") + param :id, :identifier, :desc => N_("Repository identifier"), :required => true + param :export_to_iso, :bool, :desc => N_("Export to ISO format"), :required => false + param :iso_mb_size, :number, :desc => N_("maximum size of each ISO in MB"), :required => false + param :since, Date, :desc => N_("Optional date of last export (ex: 2010-01-01T12:00:00Z)"), :required => false + def export + if !params[:export_to_iso].present? && params[:iso_mb_size].present? + fail HttpErrors::BadRequest, _("ISO export must be enabled when specifying ISO size") + end + + if params[:since].present? + begin + params[:since].to_datetime + rescue + raise HttpErrors::BadRequest, _("Invalid date provided.") + end + end + + task = async_task(::Actions::Katello::Repository::Export, [@repository], + ::Foreman::Cast.to_bool(params[:export_to_iso]), + params[:since].try(:to_datetime), + params[:iso_mb_size], + @repository.pulp_id) + respond_for_async :resource => task + end + api :PUT, "/repositories/:id", N_("Update a custom repository") param :name, String, :desc => N_("New name for the repository") param :id, :identifier, :required => true, :desc => N_("repository ID") param :gpg_key_id, :number, :desc => N_("ID of a gpg key that will be assigned to this repository") param :unprotected, :bool, :desc => N_("true if this repository can be published via HTTP") param :checksum_type, String, :desc => N_("checksum of the repository, currently 'sha1' & 'sha256' are supported.'") param :url, String, :desc => N_("the feed url of the original repository ") param :docker_upstream_name, String, :desc => N_("name of the upstream docker repository") + param :download_policy, ["immediate", "on_demand", "background"], :desc => N_("download policy for yum repos (either 'immediate', 'on_demand', or 'background')") + param :mirror_on_sync, :bool, :desc => N_("true if this repository when synced has to be mirrored from the source and stale rpms removed.") def update repo_params = repository_params - repo_params[:url] = nil if repository_params[:url].blank? sync_task(::Actions::Katello::Repository::Update, @repository, repo_params) respond_for_show(:resource => @repository) end api :DELETE, "/repositories/:id", N_("Destroy a custom repository") @@ -191,28 +244,31 @@ end render :json => {} end api :PUT, "/repositories/:id/remove_packages" - api :PUT, "/repositories/:id/remove_docker_images" + api :PUT, "/repositories/:id/remove_docker_manifests" api :PUT, "/repositories/:id/remove_puppet_modules" api :PUT, "/repositories/:id/remove_content" desc "Remove content from a repository" param :id, :identifier, :required => true, :desc => "repository ID" - param 'uuids', Array, :required => true, :deprecated => true, :desc => "Array of content uuids to remove" param 'ids', Array, :required => true, :desc => "Array of content ids to remove" def remove_content fail _("No content ids provided") if @content.blank? respond_for_async :resource => sync_task(::Actions::Katello::Repository::RemoveContent, @repository, @content) end api :POST, "/repositories/:id/upload_content", N_("Upload content into the repository") param :id, :identifier, :required => true, :desc => N_("repository ID") param :content, File, :required => true, :desc => N_("Content files to upload. Can be a single file or array of files.") def upload_content - filepaths = Array.wrap(params[:content]).compact.map(&:path) + fail Katello::Errors::InvalidRepositoryContent, _("Cannot upload Docker content.") if @repository.docker? + filepaths = params[:content].collect do |content| + {path: content.path, filename: content.original_filename} + end + if !filepaths.blank? sync_task(::Actions::Katello::Repository::UploadFiles, @repository, filepaths) render :json => {:status => "success"} else fail HttpErrors::BadRequest, _("No file uploaded") @@ -276,12 +332,15 @@ fail HttpErrors::NotFound, _("Couldn't find gpg key '%s'") % params[:gpg_key_id] if @gpg_key.nil? end end def repository_params - keys = [:url, :gpg_key_id, :unprotected, :name, :checksum_type, :docker_upstream_name] + keys = [:download_policy, :mirror_on_sync] keys += [:label, :content_type] if params[:action] == "create" + if params[:action] == 'create' || @repository.custom? + keys += [:url, :gpg_key_id, :unprotected, :name, :checksum_type, :docker_upstream_name] + end params.require(:repository).permit(*keys) end def error_on_rh_product fail HttpErrors::BadRequest, _("Red Hat products cannot be manipulated.") if @product.redhat? @@ -298,10 +357,10 @@ def find_organization_from_product @organization = @product.organization end def find_content - @content = @repository.units_for_removal(params[:ids] || params[:uuids]) + @content = @repository.units_for_removal(params[:ids]) end def filter_by_content_view(query, content_view_id, environment_id, is_available_for) if is_available_for params[:library] = true