Permalink
Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
Cannot retrieve contributors at this time.
Cannot retrieve contributors at this time
| module Katello | |
| class Api::V2::ContentViewVersionsController < Api::V2::ApiController | |
| include Concerns::Api::V2::BulkHostsExtensions | |
| include Katello::Concerns::FilteredAutoCompleteSearch | |
| before_action :find_content_view_version, :only => [:show, :update, :promote, :destroy, :export, :republish_repositories] | |
| before_action :find_content_view, :except => [:incremental_update] | |
| before_action :find_environment, :only => [:index] | |
| before_action :find_environments, :only => [:promote] | |
| before_action :validate_promotable, :only => [:promote] | |
| before_action :authorize_destroy, :only => [:destroy] | |
| before_action :find_version_environments, :only => [:incremental_update] | |
| before_action :find_puppet_module, :only => [:index] | |
| api :GET, "/content_view_versions", N_("List content view versions") | |
| api :GET, "/content_views/:content_view_id/content_view_versions", N_("List content view versions") | |
| param :content_view_id, :number, :desc => N_("Content view identifier"), :required => false | |
| param :environment_id, :number, :desc => N_("Filter versions by environment"), :required => false | |
| param :puppet_module_id, :number, :desc => N_("Filter versions by puppet module"), :required => false | |
| param :version, String, :desc => N_("Filter versions by version number"), :required => false | |
| param :composite_version_id, :number, :desc => N_("Filter versions that are components in the specified composite version"), :required => false | |
| param :organization_id, :number, :desc => N_("Organization identifier") | |
| param :triggered_by_id, :number, :desc => N_("Filter composite versions whose publish was triggered by the specified component version"), :required => false | |
| param_group :search, Api::V2::ApiController | |
| def index | |
| options = { | |
| :includes => [:content_view, :environments, :composite_content_views, :history => :task], | |
| :custom_sort => lambda { |query| query.order("#{ContentViewVersion.table_name}.major desc, #{ContentViewVersion.table_name}.minor desc") } | |
| } | |
| respond(:collection => scoped_search(index_relation.distinct, nil, nil, options)) | |
| end | |
| def index_relation | |
| version_number = params.permit(:version)[:version] | |
| versions = ContentViewVersion.readable | |
| versions = versions.triggered_by(params[:triggered_by_id]) if params[:triggered_by_id] | |
| versions = versions.with_organization_id(params[:organization_id]) if params[:organization_id] | |
| versions = versions.where(:content_view_id => @view.id) if @view | |
| versions = versions.for_version(version_number) if version_number | |
| versions = versions.in_environment(@environment) if @environment | |
| versions = versions.with_puppet_module(@puppet_module) if @puppet_module | |
| versions = versions.component_of(params[:composite_version_id]) if params[:composite_version_id] | |
| versions | |
| end | |
| api :GET, "/content_view_versions/:id", N_("Show content view version") | |
| param :id, :number, :desc => N_("Content view version identifier"), :required => true | |
| def show | |
| respond :resource => @version | |
| end | |
| api :POST, "/content_view_versions/:id/promote", N_("Promote a content view version") | |
| param :id, :number, :desc => N_("Content view version identifier"), :required => true | |
| param :force, :bool, :desc => N_("force content view promotion and bypass lifecycle environment restriction") | |
| param :environment_id, :number, :deprecated => true, :desc => N_("LifeCycle Environment identifier") | |
| param :environment_ids, Array, :desc => N_("Identifiers for Lifecycle Environment") | |
| param :description, String, :desc => N_("The description for the content view version promotion") | |
| param :force_yum_metadata_regeneration, :bool, :desc => N_("Force metadata regeneration on the repositories " \ | |
| "in the content view version") | |
| def promote | |
| is_force = ::Foreman::Cast.to_bool(params[:force]) | |
| task = async_task(::Actions::Katello::ContentView::Promote, | |
| @version, @environments, is_force, params[:description], | |
| :force_yum_metadata_regeneration => params[:force_yum_metadata_regeneration]) | |
| respond_for_async :resource => task | |
| end | |
| api :PUT, "/content_view_versions/:id", N_("Update a content view version") | |
| param :id, :number, :desc => N_("Content view version identifier"), :required => true | |
| param :description, String, :desc => N_("The description for the content view version"), :required => true | |
| def update | |
| history = @version.history.publish.successful.first | |
| if history.blank? | |
| fail HttpErrors::BadRequest, _("This content view version doesn't have a history.") | |
| else | |
| history.notes = params[:description] | |
| history.save! | |
| respond_for_show(:resource => @version) | |
| end | |
| end | |
| api :PUT, "/content_view_versions/:id/republish_repositories", N_("Forces a republish of the version's repositories' metadata") | |
| param :id, :number, :desc => N_("Content view version identifier"), :required => true | |
| def republish_repositories | |
| task = async_task(::Actions::Katello::ContentViewVersion::RepublishRepositories, @version) | |
| respond_for_async :resource => task | |
| end | |
| api :POST, "/content_view_versions/:id/export", N_("Export a content view version") | |
| param :id, :number, :desc => N_("Content view version 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].blank? && params[:iso_mb_size].present? | |
| fail HttpErrors::BadRequest, _("ISO export must be enabled when specifying ISO size") | |
| end | |
| if (repos = @version.content_view.on_demand_repositories).any? | |
| fail HttpErrors::BadRequest, _("This content view has on demand repositories that cannot be exported: %{repos}" % {repos: repos.pluck(:label).join(", ")}) | |
| end | |
| if params[:since].present? | |
| begin | |
| params[:since].to_datetime | |
| rescue | |
| raise HttpErrors::BadRequest, _("Invalid date provided.") | |
| end | |
| end | |
| task = async_task(::Actions::Katello::ContentViewVersion::Export, @version, | |
| ::Foreman::Cast.to_bool(params[:export_to_iso]), | |
| params[:since].try(:to_datetime), | |
| params[:iso_mb_size]) | |
| respond_for_async :resource => task | |
| end | |
| api :DELETE, "/content_view_versions/:id", N_("Remove content view version") | |
| param :id, :number, :desc => N_("Content view version identifier"), :required => true | |
| def destroy | |
| task = async_task(::Actions::Katello::ContentViewVersion::Destroy, @version) | |
| respond_for_async :resource => task | |
| end | |
| api :POST, "/content_view_versions/incremental_update", N_("Perform an Incremental Update on one or more Content View Versions") | |
| param :content_view_version_environments, Array do | |
| param :content_view_version_id, :number, :desc => N_("Content View Version Ids to perform an incremental update on. May contain composites as well as one or more components to update.") | |
| param :environment_ids, Array, :desc => N_("The list of environments to promote the specified Content View Version to (replacing the older version)") | |
| end | |
| param :description, String, :desc => N_("The description for the new generated Content View Versions") | |
| param :resolve_dependencies, :bool, :desc => N_("If true, when adding the specified errata or packages, any needed dependencies will be copied as well") | |
| param :propagate_all_composites, :bool, :desc => N_("If true, will publish a new composite version using any specified content_view_version_id that has been promoted to a lifecycle environment") | |
| param :add_content, Hash do | |
| param :errata_ids, Array, :desc => "Errata ids or uuids to copy into the new versions" | |
| param :package_ids, Array, :desc => "Package ids or uuids to copy into the new versions" | |
| param :puppet_module_ids, Array, :desc => "Puppet Module ids or uuids to copy into the new versions" | |
| end | |
| param :update_hosts, Hash, :desc => N_("After generating the incremental update, apply the changes to the specified hosts. Only Errata are supported currently.") do | |
| param :included, Hash, :required => true, :action_aware => true do | |
| param :search, String, :required => false, :desc => N_("Search string for host to perform an action on") | |
| param :ids, Array, :required => false, :desc => N_("List of host ids to perform an action on") | |
| end | |
| param :excluded, Hash, :required => false, :action_aware => true do | |
| param :ids, Array, :required => false, :desc => N_("List of host ids to exclude and not run an action on") | |
| end | |
| end | |
| def incremental_update | |
| any_environments = params[:content_view_version_environments].any? { |cvve| cvve[:environment_ids].try(:any?) } | |
| if params[:add_content] && params[:add_content].key?(:errata_ids) && params[:update_hosts] && any_environments | |
| hosts = calculate_hosts_for_incremental(params[:update_hosts], params[:propagate_to_composites]) | |
| else | |
| hosts = [] | |
| end | |
| validate_content(params[:add_content]) | |
| task = async_task(::Actions::Katello::ContentView::IncrementalUpdates, @version_environments, @composite_version_environments, params[:add_content], | |
| params[:resolve_dependencies], hosts, params[:description]) | |
| respond_for_async :resource => task | |
| end | |
| private | |
| def calculate_hosts_for_incremental(bulk_params, use_composites) | |
| if bulk_params[:included].try(:[], :search) | |
| version_environments = find_version_environments_for_hosts(use_composites) | |
| restrict_hosts = lambda do |relation| | |
| if version_environments.any? | |
| errata = Erratum.with_identifiers(params[:add_content][:errata_ids]) | |
| content_facets = Host::ContentFacet.in_content_view_version_environments(version_environments).with_applicable_errata(errata) | |
| relation.where(:id => content_facets.pluck(:host_id)) | |
| else | |
| relation.where("1=0") | |
| end | |
| end | |
| else | |
| restrict_hosts = nil | |
| end | |
| find_bulk_hosts(:edit_hosts, params[:update_hosts], restrict_hosts) | |
| end | |
| def find_content_view_version | |
| @version = ContentViewVersion.find(params[:id]) | |
| end | |
| def find_content_view | |
| @view = @version ? @version.content_view : ContentView.where(:id => params[:content_view_id]).first | |
| if @view && @view.default? && params[:action] == "promote" | |
| fail HttpErrors::BadRequest, _("The default content view cannot be promoted") | |
| end | |
| end | |
| def find_version_environments | |
| #Generates a data structure for incremental update: | |
| # [{:content_view_version => ContentViewVersion, :environments => [KTEnvironment]}] | |
| list = params[:content_view_version_environments] | |
| fail _("At least one Content View Version must be specified") if list.empty? | |
| @version_environments = [] | |
| @composite_version_environments = [] | |
| list.each do |combination| | |
| version_environment = { | |
| :content_view_version => ContentViewVersion.find(combination[:content_view_version_id]), | |
| :environments => KTEnvironment.where(:id => combination[:environment_ids]) | |
| } | |
| view = version_environment[:content_view_version].content_view | |
| return deny_access(_("You are not allowed to publish Content View %s") % view.name) unless view.publishable? && view.promotable_or_removable? | |
| not_promotable = version_environment[:environments].select { |env| !env.promotable_or_removable? } | |
| unless not_promotable.empty? | |
| return deny_access(_("You are not allowed to promote to Environments %s") % un_promotable.map(&:name).join(', ')) | |
| end | |
| unless combination[:environment_ids].blank? | |
| not_found = combination[:environment_ids].map(&:to_s) - version_environment[:environments].map { |env| env.id.to_s } | |
| fail _("Could not find Environment with ids: %s") % not_found.join(', ') unless not_found.empty? | |
| end | |
| if view.composite? | |
| @composite_version_environments << version_environment | |
| else | |
| @version_environments << version_environment | |
| @composite_version_environments += lookup_all_composites(version_environment[:content_view_version]) if params[:propagate_all_composites] | |
| end | |
| end | |
| @composite_version_environments.uniq! { |cve| cve[:content_view_version] } | |
| end | |
| def lookup_all_composites(component) | |
| component.composites.select { |c| c.environments.any? }.map do |composite| | |
| { | |
| :content_view_version => composite, | |
| :environments => composite.environments | |
| } | |
| end | |
| end | |
| def find_version_environments_for_hosts(include_composites) | |
| if include_composites | |
| version_environments_for_systems_map = {} | |
| @version_environments.each do |version_environment| | |
| version_environment[:content_view_version].composites.each do |composite_version| | |
| version_environments_for_systems_map[composite_version.id] ||= {:content_view_version => composite_version, | |
| :environments => composite_version.environments} | |
| end | |
| end | |
| version_environments_for_systems_map.values | |
| else | |
| @version_environments.select { |ve| !ve[:environments].blank? } | |
| end | |
| end | |
| def find_environment | |
| return unless params.key?(:environment_id) | |
| @environment = KTEnvironment.find(params[:environment_id]) | |
| end | |
| def find_puppet_module | |
| return unless params.key?(:puppet_module_id) | |
| @puppet_module = PuppetModule.with_identifiers([params[:puppet_module_id]]).first | |
| end | |
| def validate_content(content) | |
| if content[:errata_ids] | |
| errata = Erratum.with_identifiers(content[:errata_ids]) | |
| not_found_count = content[:errata_ids].length - errata.length | |
| if not_found_count > 0 | |
| fail _("Could not find %{count} errata. Only found: %{found}") % | |
| { :count => not_found_count, :found => errata.pluck(:errata_id).join(',') } | |
| end | |
| end | |
| if content[:package_ids] | |
| fail _("package_ids is not an array") unless content[:package_ids].is_a?(Array) | |
| end | |
| if content[:puppet_module_ids] | |
| fail _("puppet_module_ids is not an array") unless content[:puppet_module_ids].is_a?(Array) | |
| end | |
| end | |
| def find_environments | |
| @environments = if params[:environment_id] | |
| ::Foreman::Deprecation.api_deprecation_warning("The parameter environment_id will be removed in Katello 3.4. Please update to use the environment_ids parameter.") | |
| KTEnvironment.where(:id => params[:environment_id]) | |
| else | |
| KTEnvironment.where(:id => params[:environment_ids]) | |
| end | |
| end | |
| def validate_promotable | |
| fail HttpErrors::BadRequest, _("Could not find environments for promotion") if @environments.blank? | |
| return deny_access unless @environments.all?(&:promotable_or_removable?) && @version.content_view.promotable_or_removable? | |
| true | |
| end | |
| def authorize_destroy | |
| return deny_access unless @version.content_view.deletable? | |
| true | |
| end | |
| end | |
| end |