Project

General

Profile

Download (18.6 KB) Statistics
| Branch: | Tag: | Revision:
module Katello
class Api::V2::ActivationKeysController < Api::V2::ApiController
include Katello::Concerns::FilteredAutoCompleteSearch
include Katello::Concerns::Api::V2::ContentOverridesController
before_action :verify_presence_of_organization_or_environment, :only => [:index]
before_action :find_environment, :only => [:index, :create, :update]
before_action :find_optional_organization, :only => [:index, :create, :show]
before_action :find_content_view, :only => [:index]
before_action :find_authorized_katello_resource, :only => [:show, :update, :destroy, :available_releases,
:available_host_collections, :add_host_collections, :remove_host_collections,
: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))

api :GET, "/activation_keys", N_("List activation keys")
api :GET, "/environments/:environment_id/activation_keys"
api :GET, "/organizations/:organization_id/activation_keys"
param :organization_id, :number, :desc => N_("organization identifier"), :required => true
param :environment_id, :number, :desc => N_("environment identifier")
param :content_view_id, :number, :desc => N_("content view identifier")
param :name, String, :desc => N_("activation key name to filter by")
param_group :search, Api::V2::ApiController
add_scoped_search_description_for(ActivationKey)
def index
activation_key_includes = [:content_view, :environment, :host_collections, :organization]
respond(:collection => scoped_search(index_relation.distinct, :name, :asc, :includes => activation_key_includes))
end

api :POST, "/activation_keys", N_("Create an activation key")
param :organization_id, :number, :desc => N_("organization identifier"), :required => true
param :name, String, :desc => N_("name"), :required => true
param :description, String, :desc => N_("description")
param :environment, Hash, :desc => N_("environment")
param :environment_id, :number, :desc => N_("environment id")
param :content_view_id, :number, :desc => N_("content view id")
param :max_hosts, :number, :desc => N_("maximum number of registered content hosts")
param :unlimited_hosts, :bool, :desc => N_("can the activation key have unlimited hosts")
param :release_version, String, :desc => N_("content release version")
param :service_level, String, :desc => N_("service level")
param :auto_attach, :bool, :desc => N_("auto attach subscriptions upon registration"), deprecated: true
param :purpose_usage, String, :desc => N_("Sets the system purpose usage")
param :purpose_role, String, :desc => N_("Sets the system purpose usage")
param :purpose_addons, Array, :desc => N_("Sets the system add-ons")
def create
@activation_key = ActivationKey.new(activation_key_params) do |activation_key|
activation_key.environment = @environment if @environment
activation_key.organization = @organization
activation_key.user = current_user
end
sync_task(::Actions::Katello::ActivationKey::Create, @activation_key, service_level: activation_key_params['service_level'])
@activation_key.reload

respond_for_create(:resource => @activation_key)
end

api :PUT, "/activation_keys/:id", N_("Update an activation key")
param :id, :number, :desc => N_("ID of the activation key"), :required => true
param :organization_id, :number, :desc => N_("organization identifier"), :required => true
param :name, String, :desc => N_("name"), :required => false
param :description, String, :desc => N_("description")
param :environment_id, :number, :desc => N_("environment id")
param :content_view_id, :number, :desc => N_("content view id")
param :max_hosts, :number, :desc => N_("maximum number of registered content hosts")
param :unlimited_hosts, :bool, :desc => N_("can the activation key have unlimited hosts")
param :release_version, String, :desc => N_("content release version")
param :service_level, String, :desc => N_("service level")
param :auto_attach, :bool, :desc => N_("auto attach subscriptions upon registration")
param :purpose_usage, String, :desc => N_("Sets the system purpose usage")
param :purpose_role, String, :desc => N_("Sets the system purpose usage")
param :purpose_addons, Array, :desc => N_("Sets the system add-ons")
def update
sync_task(::Actions::Katello::ActivationKey::Update, @activation_key, activation_key_params)
respond_for_show(:resource => @activation_key)
end

api :DELETE, "/activation_keys/:id", N_("Destroy an activation key")
param :id, :number, :desc => N_("ID of the activation key"), :required => true
def destroy
task = sync_task(::Actions::Katello::ActivationKey::Destroy,
@activation_key)
respond_for_async(:resource => task)
end

api :GET, "/activation_keys/:id", N_("Show an activation key")
param :id, :number, :desc => N_("ID of the activation key"), :required => true
param :organization_id, :number, :desc => N_("organization identifier"), :required => false
param :show_hosts, :bool, :desc => N_("Show hosts associated to an activation key"), :required => false
def show
respond(:resource => @activation_key)
end

api :POST, "/activation_keys/:id/copy", N_("Copy an activation key")
param :new_name, String, :desc => N_("Name of new activation key"), :required => true
param :id, :number, :desc => N_("ID of the activation key"), :required => true
param :organization_id, :number, :desc => N_("organization identifier"), :required => false
def copy
@activation_key = Katello::ActivationKey.readable.find_by(:id => params[:id])
throw_resource_not_found(name: 'activation_key', id: params[:id]) if @activation_key.nil?

fail HttpErrors::BadRequest, _("New name cannot be blank") unless params[:new_name]
@new_activation_key = @activation_key.copy(params[:new_name])
@new_activation_key.user = current_user
sync_task(::Actions::Katello::ActivationKey::Create, @new_activation_key)
@new_activation_key.reload
sync_task(::Actions::Katello::ActivationKey::Update, @new_activation_key,
:service_level => @activation_key.service_level,
:release_version => @activation_key.release_version,
:auto_attach => @activation_key.auto_attach
)
@activation_key.pools.each do |pool|
@new_activation_key.subscribe(pool[:id])
end
@new_activation_key.set_content_overrides(@activation_key.content_overrides) unless @activation_key.content_overrides.blank?
respond_for_create(:resource => @new_activation_key)
end

api :GET, "/activation_keys/:id/host_collections/available", N_("List host collections the activation key does not belong to")
param_group :search, Api::V2::ApiController
param :name, String, :desc => N_("host collection name to filter by")
def available_host_collections
table_name = HostCollection.table_name
host_collection_ids = @activation_key.host_collections.pluck("#{table_name}.id")

scoped = HostCollection.readable
scoped = scoped.where("#{table_name}.id NOT IN (?)", host_collection_ids) if host_collection_ids.present?
scoped = scoped.where(:organization_id => @activation_key.organization)
scoped = scoped.where(:name => params[:name]) if params[:name]

respond_for_index(:collection => scoped_search(scoped, :name, :asc, :resource_class => HostCollection))
end

api :GET, "/activation_keys/:id/releases", N_("Show release versions available for an activation key")
param :id, String, :desc => N_("ID of the activation key"), :required => true
def available_releases
response = {
:results => @activation_key.available_releases,
:total => @activation_key.available_releases.size,
:subtotal => @activation_key.available_releases.size
}
respond_for_index :collection => response
end

api :POST, "/activation_keys/:id/host_collections"
param :id, :number, :desc => N_("ID of the activation key"), :required => true
param :host_collection_ids, Array, :required => true, :desc => N_("List of host collection IDs to associate with activation key")
def add_host_collections
ids = activation_key_params[:host_collection_ids]
@activation_key.host_collection_ids = (@activation_key.host_collection_ids + ids).uniq
@activation_key.save!
respond_for_show(:resource => @activation_key)
end

api :PUT, "/activation_keys/:id/host_collections"
param :id, :number, :desc => N_("ID of the activation key"), :required => true
param :host_collection_ids, Array, :required => true, :desc => N_("List of host collection IDs to disassociate from the activation key")
def remove_host_collections
ids = activation_key_params[:host_collection_ids]
@activation_key.host_collection_ids = (@activation_key.host_collection_ids - ids).uniq
@activation_key.save!
respond_for_show(:resource => @activation_key)
end

def deprecate_entitlement_mode_endpoint
::Foreman::Deprecation.api_deprecation_warning(N_("This endpoint is deprecated and will be removed in an upcoming release. Simple Content Access is the only supported content access mode."))
end

api :PUT, "/activation_keys/:id/add_subscriptions", N_("Attach a subscription"), deprecated: true
param :id, :number, :desc => N_("ID of the activation key"), :required => true
param :subscription_id, :number, :desc => N_("Subscription identifier"), :required => false
param :quantity, :number, :desc => N_("Quantity of this subscription to add"), :required => false
param :subscriptions, Array, :desc => N_("Array of subscriptions to add"), :required => false do
param :id, String, :desc => N_("Subscription Pool uuid"), :required => false
param :quantity, :number, :desc => N_("Quantity of this subscriptions to add"), :required => false
end
def add_subscriptions
deprecate_entitlement_mode_endpoint
if params[:subscriptions]
params[:subscriptions].each { |subscription| @activation_key.subscribe(subscription[:id], subscription[:quantity]) }
elsif params[:subscription_id]
@activation_key.subscribe(params[:subscription_id], params[:quantity])
end

respond_for_index(:collection => subscription_index, :template => 'subscriptions')
end

api :PUT, "/activation_keys/:id/remove_subscriptions", N_("Unattach a subscription"), deprecated: true
param :id, :number, :desc => N_("ID of the activation key"), :required => true
param :subscription_id, String, :desc => N_("Subscription ID"), :required => false
param :subscriptions, Array, :desc => N_("Array of subscriptions to add"), :required => false do
param :id, String, :desc => N_("Subscription Pool uuid"), :required => false
end
def remove_subscriptions
deprecate_entitlement_mode_endpoint
if params[:subscriptions]
params[:subscriptions].each { |subscription| @activation_key.unsubscribe(subscription[:id]) }
elsif params[:subscription_id]
@activation_key.unsubscribe(params[:subscription_id])
end

respond_for_index(:collection => subscription_index, :template => 'subscriptions')
end

api :PUT, "/activation_keys/:id/content_override", N_("Override content for activation_key")
param :id, :number, :desc => N_("ID of the activation key"), :required => true
param :content_overrides, Array, :desc => N_("Array of Content override parameters to be added in bulk") do
param :content_label, String, :desc => N_("Label of the content"), :required => true
param :value, String, :desc => N_("Override value. Provide a boolean value if name is 'enabled'"), :required => false
param :name, String, :desc => N_("Override parameter key or name. Note if name is not provided the default name will be 'enabled'"), :required => false
param :remove, :bool, :desc => N_("Set true to remove an override and reset it to 'default'"), :required => false
end
def content_override
if params[:content_overrides]
organization = @activation_key.organization
specified_labels = []
content_override_values = params[:content_overrides].map do |override|
specified_labels << override[:content_label]
validate_content_overrides_enabled(override)
end
specified_labels.uniq!
existing_labels = organization.contents.where(label: specified_labels).uniq

unless specified_labels.size == existing_labels.size
missing_labels = specified_labels - existing_labels.pluck(:label)
msg = "Content label(s) \"#{missing_labels.join(", ")}\" were not found in the Organization \"#{organization}\""
fail HttpErrors::BadRequest, _(msg)
end

@activation_key.set_content_overrides(content_override_values)
end
respond_for_show(:resource => @activation_key)
end

api :GET, "/activation_keys/:id/product_content", N_("Show content available for an activation key")
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"), deprecated: true, default: true
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
end

def index_relation
activation_keys = ActivationKey.readable
activation_keys = activation_keys.where(:name => params[:name]) if params[:name]
activation_keys = activation_keys.where(:organization_id => @organization) if @organization
activation_keys = activation_keys.where(:environment_id => @environment) if @environment
activation_keys = activation_keys.where(:content_view_id => @content_view) if @content_view
activation_keys
end

private

def subscription_index
subs = @activation_key.subscriptions
subscriptions = {
:results => subs,
:subtotal => subs.count,
:total => subs.count,
:page => 1,
:per_page => subs.count
}
subscriptions
end

def find_environment
environment_id = params[:environment_id]
environment_id = params[:environment][:id] if !environment_id && params[:environment]
return unless environment_id

@environment = KTEnvironment.readable.find_by(id: environment_id)
fail HttpErrors::NotFound, _("Couldn't find environment '%s'") % params[:environment_id] if @environment.nil?
@organization = @environment.organization
@environment
end

def find_host_collections
ids = params[:activation_key][:host_collection_ids] if params[:activation_key]
@host_collections = []

ids&.each do |host_collection_id|
host_collection = HostCollection.readable.find(host_collection_id)
fail HttpErrors::NotFound, _("Couldn't find host collection '%s'") % host_collection_id if host_collection.nil?
@host_collections << host_collection
end
end

def verify_presence_of_organization_or_environment
return if params.key?(:organization_id) || params.key?(:environment_id)
fail HttpErrors::BadRequest, _("Either organization ID or environment ID needs to be specified")
end

def find_content_view
if params.include?(:content_view_id)
cv_id = params[:content_view_id]
@content_view = ContentView.readable.find_by(:id => cv_id)
fail HttpErrors::NotFound, _("Couldn't find content view '%s'") % cv_id if @content_view.nil?
end
end

def permitted_params
params.require(:activation_key).permit(:name,
:description,
:environment_id,
:organization_id,
:content_view_id,
:release_version,
:service_level,
:auto_attach,
:max_hosts,
:unlimited_hosts,
:purpose_role,
:purpose_usage,
:purpose_addon_ids,
:content_overrides => [],
:host_collection_ids => []).to_h
end

def activation_key_params
key_params = permitted_params

key_params[:environment_id] = params[:environment][:id] if params[:environment].try(:[], :id)
key_params[:content_view_id] = params[:content_view][:id] if params[:content_view].try(:[], :id)
unless params[:purpose_addons].nil?
key_params[:purpose_addon_ids] = params[:purpose_addons].map { |addon| ::Katello::PurposeAddon.find_or_create_by(name: addon).id }
end
unlimited = params[:activation_key].try(:[], :unlimited_hosts)
max_hosts = params[:activation_key].try(:[], :max_hosts)

if unlimited && max_hosts
key_params[:unlimited_hosts] = true
key_params[:max_hosts] = nil
else
key_params[:unlimited_hosts] = false if max_hosts
key_params[:max_hosts] = nil if unlimited
end

key_params
end

def verify_simple_content_access_disabled
if @activation_key.organization.simple_content_access?
fail HttpErrors::BadRequest, _("The specified organization is in Simple Content Access mode. Attaching subscriptions is disabled")
end
end

def validate_release_version
@organization ||= find_organization
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
(1-1/55)