Project

General

Profile

Download (36.8 KB) Statistics
| Branch: | Tag: | Revision:
require 'katello/permission_creator'
require 'katello/repository_types'
require 'katello/host_status_manager'
# rubocop:disable Metrics/BlockLength

Foreman::Plugin.register :katello do
requires_foreman '>= 3.11'
register_gettext

sub_menu :top_menu, :content_menu, :caption => N_('Content'),
:icon => 'fa fa-book', :after => :monitor_menu do
menu :top_menu,
:red_hat_subscriptions,
:caption => N_('Subscriptions'),
:url => '/subscriptions',
:url_hash => {:controller => 'katello/api/v2/subscriptions',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false

menu :top_menu,
:redhat_provider,
:caption => N_('Red Hat Repositories'),
:url => '/redhat_repositories',
:url_hash => {:controller => 'katello/api/v2/repository_sets',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false

menu :top_menu,
:products,
:caption => N_('Products'),
:url => '/products',
:url_hash => {:controller => 'katello/api/v2/products',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false

menu :top_menu,
:content_credentials,
:caption => N_('Content Credentials'),
:url => '/content_credentials',
:url_hash => {:controller => 'katello/api/v2/content_credentials',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false

menu :top_menu,
:alternate_content_sources,
:url => '/alternate_content_sources',
:url_hash => {:controller => 'katello/api/v2/alternate_content_sources',
:action => 'index'},
:caption => N_('Alternate Content Sources'),
:engine => Katello::Engine,
:turbolinks => false

menu :top_menu,
:sync_plans,
:caption => N_('Sync Plans'),
:url => '/sync_plans',
:url_hash => {:controller => 'katello/api/v2/sync_plans',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false

menu :top_menu,
:sync_status,
:caption => N_('Sync Status'),
:url_hash => {:controller => 'katello/sync_management',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false

divider :top_menu, :caption => N_('Lifecycle'), :parent => :content_menu

menu :top_menu,
:environments,
:caption => N_('Lifecycle Environments'),
:url => '/lifecycle_environments',
:url_hash => {:controller => 'katello/api/v2/environments',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false

menu :top_menu,
:content_views,
:caption => N_('Content Views'),
:url => '/content_views',
:url_hash => {:controller => 'katello/api/v2/content_views',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false

menu :top_menu,
:activation_keys,
:caption => N_('Activation Keys'),
:url => '/activation_keys',
:url_hash => {:controller => 'katello/api/v2/activation_keys',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false

divider :top_menu, :caption => N_('Content Types'), :parent => :content_menu

menu :top_menu,
:debs,
:caption => N_('Deb Packages'),
:url => '/debs',
:url_hash => {:controller => 'katello/api/v2/debs',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false,
:if => lambda { ::Katello::RepositoryTypeManager.enabled?(::Katello::Repository::DEB_TYPE) }

menu :top_menu,
:docker_tags,
:caption => N_('Container Image Tags'),
:url => '/docker_tags',
:url_hash => {:controller => 'katello/api/v2/docker_tags',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false,
:if => lambda { ::Katello::RepositoryTypeManager.enabled?(::Katello::Repository::DOCKER_TYPE) }

menu :top_menu,
:files,
:caption => N_('Files'),
:url => '/files',
:url_hash => {:controller => 'katello/api/v2/file_units',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false,
:if => lambda { ::Katello::RepositoryTypeManager.enabled?(::Katello::Repository::FILE_TYPE) }

menu :top_menu,
:packages,
:caption => N_('Packages'),
:url => '/packages',
:url_hash => {:controller => 'katello/api/v2/packages',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false,
:if => lambda { ::Katello::RepositoryTypeManager.enabled?(::Katello::Repository::YUM_TYPE) }

menu :top_menu,
:errata,
:caption => N_('Errata'),
:url => '/errata',
:url_hash => {:controller => 'katello/api/v2/errata',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false,
:if => lambda { ::Katello::RepositoryTypeManager.enabled?(::Katello::Repository::YUM_TYPE) }

menu :top_menu,
:module_streams,
:caption => N_('Module Streams'),
:url => '/module_streams',
:url_hash => {:controller => 'katello/api/v2/module_streams',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false,
:if => lambda { ::Katello::RepositoryTypeManager.enabled?(::Katello::Repository::YUM_TYPE) }

menu :top_menu,
:ansible_collections,
:caption => N_('Ansible Collections'),
:url => '/content/ansible_collections',
:url_hash => {:controller => 'katello/api/v2/ansible_collections',
:action => 'index'},
:engine => Katello::Engine,
:turbolinks => false,
:if => lambda { ::Katello::RepositoryTypeManager.enabled?(::Katello::Repository::ANSIBLE_COLLECTION_TYPE) }

menu :top_menu,
:other_content_types,
:caption => N_('Other Content Types'),
:url => '/content',
:url_hash => {:controller => '/',
:action => ''},
:engine => Katello::Engine,
:turbolinks => false,
:if => lambda { true }
end

menu :top_menu,
:content_hosts,
:caption => N_('Content Hosts'),
:url => '/content_hosts',
:url_hash => {:controller => 'api/v2/hosts',
:action => 'index'},
:engine => Katello::Engine,
:parent => :hosts_menu,
:after => :newhost,
:turbolinks => false

menu :top_menu,
:host_collections,
:caption => N_('Host Collections'),
:url => '/host_collections',
:url_hash => {:controller => 'katello/api/v2/host_collections',
:action => 'index'},
:engine => Katello::Engine,
:parent => :hosts_menu,
:after => :content_hosts,
:turbolinks => false

extend_template_helpers Katello::KatelloUrlsHelper
extend_template_helpers Katello::Concerns::BaseTemplateScopeExtensions

register_global_js_file 'global'

register_graphql_query_field :host_collection, '::Types::HostCollection', :record_field
register_graphql_query_field :host_collections, '::Types::HostCollection', :collection_field

search_path_override("Katello") do |resource|
"/#{Katello::Util::Model.model_to_controller_path(resource)}/auto_complete_search"
end
apipie_documented_controllers ["#{Katello::Engine.root}/app/controllers/katello/api/v2/*.rb"]
apipie_ignored_controllers %w(::Api::V2::OrganizationsController)
ApipieDSL.configuration.dsl_classes_matchers.concat [
"#{Katello::Engine.root}/app/models/katello/**/*.rb",
"#{Katello::Engine.root}/app/lib/actions/**/*.rb"
]

parameter_filter ::Host::Managed, :host_collection_ids => [],
:content_facet_attributes => [:content_view_id, :lifecycle_environment_id, :content_source_id,
:host, :kickstart_repository_id],
:subscription_facet_attributes => [:release_version, :autoheal, :purpose_usage, :purpose_role, :service_level, :host,
{:installed_products => [:product_id, :product_name, :arch, :version]}, :facts, {:hypervisor_guest_uuids => []}, {:purpose_addon_ids => []}]
parameter_filter ::Hostgroup, :content_view_id, :lifecycle_environment_id, :content_source_id,
:kickstart_repository_id
parameter_filter Organization, :label, :service_level
parameter_filter SmartProxy, :download_policy, :http_proxy_id, :lifecycle_environment_ids => []

logger :glue, :enabled => true
logger :pulp_rest, :enabled => true
logger :cp_rest, :enabled => true
logger :cp_proxy, :enabled => true
logger :action, :enabled => true
logger :manifest_import_logger, :enabled => true
logger :registry_proxy, :enabled => true
logger :katello_events, :enabled => true
logger :candlepin_events, :enabled => true

widget 'errata_widget', :name => 'Latest Errata', :sizey => 1, :sizex => 6
widget 'content_views_widget', :name => 'Content Views', :sizey => 1, :sizex => 6
widget 'sync_widget', :name => 'Sync Overview', :sizey => 1, :sizex => 6
widget 'host_collection_widget', :name => 'Host Collections', :sizey => 1, :sizex => 6

extend_page("smart_proxies/show") do |context|
context.add_pagelet :main_tabs,
:name => _("Content"),
:partial => "foreman/smart_proxies/content_tab",
:onlyif => proc { |proxy| proxy.pulp_mirror? }
context.add_pagelet :details_content,
:name => _("Content Sync"),
:partial => "foreman/smart_proxies/content_sync",
:onlyif => proc { |proxy| proxy.pulp_mirror? }
context.add_pagelet :details_content,
:name => _("Reclaim Space"),
:partial => "foreman/smart_proxies/reclaim_space",
:onlyif => proc { |proxy| proxy.pulp_primary? }
end

extend_page 'hosts/_list' do |context|
context.with_profile :content, _('Content'), default: false do
common_class = 'hidden-tablet hidden-xs ellipsis'
use_pagelet :hosts_table_column_header, :name
use_pagelet :hosts_table_column_content, :name
add_pagelet :hosts_table_column_header, key: :rhel_lifecycle_status, label: _('RHEL Lifecycle status'), sortable: true, class: common_class, width: '10%', export_key: 'rhel_lifecycle_status'
add_pagelet :hosts_table_column_content, key: :rhel_lifecycle_status, class: common_class, callback: ->(host) { host_status_icon(host.rhel_lifecycle_global_status) }

add_pagelet :hosts_table_column_header, key: :installable_updates, label: _('Installable updates'), class: common_class, width: '15%',
export_data: [:security, :bugfix, :enhancement].map { |kind| CsvExporter::ExportDefinition.new("installable_updates.#{kind}", callback: ->(host) { (host.content_facet_attributes&.errata_counts || {})[kind] }) } +
[:rpm, :deb].map { |kind| CsvExporter::ExportDefinition.new("installable_packages.#{kind}", callback: ->(host) { host&.content_facet_attributes&.public_send("upgradable_#{kind}_count".to_sym) || 0 }) }
add_pagelet :hosts_table_column_content, key: :installable_updates, class: common_class, callback: ->(host) { errata_counts(host) }
use_pagelet :hosts_table_column_header, :os_title
use_pagelet :hosts_table_column_content, :os_title
add_pagelet :hosts_table_column_header, key: :lifecycle_environment, label: _('Lifecycle environment'), sortable: true, class: common_class, width: '10%',
export_data: CsvExporter::ExportDefinition.new('single_lifecycle_environment', label: 'Lifecycle Environment')
add_pagelet :hosts_table_column_content, key: :lifecycle_environment, class: common_class, callback: ->(host) { host.content_facet&.single_lifecycle_environment&.name }
add_pagelet :hosts_table_column_header, key: :content_view, label: _('Content view'), sortable: true, class: common_class, width: '10%', export_data: CsvExporter::ExportDefinition.new('single_content_view', label: 'Content View')
add_pagelet :hosts_table_column_content, key: :content_view, class: common_class, callback: ->(host) { host.content_facet&.single_content_view&.name }
add_pagelet :hosts_table_column_header, key: :registered_at, label: _('Registered'), sortable: true, class: common_class, width: '10%', export_data: CsvExporter::ExportDefinition.new('subscription_facet_attributes.registered_at', label: 'Registered')
add_pagelet :hosts_table_column_content, key: :registered_at, class: common_class, callback: ->(host) { host_registered_time(host) }
add_pagelet :hosts_table_column_header, key: :last_checkin, label: _('Last checkin'), sortable: true, class: common_class, width: '10%', export_data: CsvExporter::ExportDefinition.new('subscription_facet_attributes.last_checkin', label: 'Last Checkin')
add_pagelet :hosts_table_column_content, key: :last_checkin, class: common_class, callback: ->(host) { host_checkin_time(host) }
end
end

::Katello::HostStatusManager::STATUSES.each do |status_class|
register_custom_status(status_class)
end

register_ping_extension { Katello::Ping.ping }
register_status_extension { Katello::Ping.status }

extend_rabl_template 'api/v2/smart_proxies/main', 'katello/api/v2/smart_proxies/pulp_info'
extend_rabl_template 'api/v2/hosts/show', 'katello/api/v2/hosts/host_collections'
extend_rabl_template 'api/v2/hosts/show', 'katello/api/v2/hosts/show'

# Katello variables for Host Registration
extend_allowed_registration_vars :activation_keys
extend_allowed_registration_vars :lifecycle_environment_id
extend_allowed_registration_vars :force
extend_allowed_registration_vars :ignore_subman_errors

extend_page "smart_proxies/show" do |cx|
cx.add_pagelet :details_content,
:name => _('Storage'),
:partial => 'smart_proxies/show/storage',
:onlyif => proc { |proxy| proxy.has_feature?(SmartProxy::PULP_FEATURE) || proxy.has_feature?(SmartProxy::PULP_NODE_FEATURE) || proxy.has_feature?(SmartProxy::PULP3_FEATURE) }
end

register_facet Katello::Host::ContentFacet, :content_facet do
configure_host do
api_view :list => 'katello/api/v2/content_facet/base_with_root', :single => 'katello/api/v2/content_facet/show'
api_docs :content_facet_attributes, ::Katello::Api::V2::HostContentsController
template_compatibility_properties :content_source_id, :content_source
extend_model ::Katello::Concerns::ContentFacetHostExtensions
end

configure_hostgroup(::Katello::Hostgroup::ContentFacet) do
set_dependent_action :destroy
end
end

register_facet Katello::Host::SubscriptionFacet, :subscription_facet do
api_view :list => 'katello/api/v2/subscription_facet/base_with_root', :single => 'katello/api/v2/subscription_facet/show'
api_docs :subscription_facet_attributes, ::Katello::Api::V2::HostSubscriptionsController
extend_model ::Katello::Concerns::SubscriptionFacetHostExtensions
end

describe_host do
overview_buttons_provider :content_host_overview_button
multiple_actions_provider :hosts_change_content_source
end

settings do
category :katello, N_('Content') do
http_proxy_select = [{
name: _("HTTP Proxies"),
class: 'HttpProxy',
scope: 'all',
value_method: 'name',
text_method: 'name_and_url'
}]
download_policies = proc { hashify_parameters(::Katello::RootRepository::DOWNLOAD_POLICIES) }
proxy_download_policies = proc { hashify_parameters(::SmartProxy::DOWNLOAD_POLICIES) }
export_formats = proc { hashify_parameters(::Katello::Pulp3::ContentViewVersion::Export::FORMATS) }

def hashify_parameters(parameters)
Hash[parameters.map { |p| [p, p] }]
end

def katello_template_setting_values(name)
templates = ProvisioningTemplate.where(:template_kind => TemplateKind.where(:name => name))
templates.each_with_object({}) { |tmpl, hash| hash[tmpl.name] = tmpl.name }
end

setting 'allow_multiple_content_views',
type: :boolean,
default: false,
full_name: N_('Allow multiple content views'),
description: N_("Allow a host to be registered to multiple content view environments with 'subscription-manager register --environments'.") # TODO: update this description when AKs support this setting as well

setting 'content_default_http_proxy',
type: :string,
default: nil,
full_name: N_('Default HTTP Proxy'),
description: N_("Default HTTP proxy for syncing content"),
collection: proc { http_proxy_select },
include_blank: N_("no global default")

setting 'katello_default_provision',
type: :string,
default: 'Kickstart default',
full_name: N_('Default synced OS provisioning template'),
description: N_("Default provisioning template for Operating Systems created from synced content"),
collection: proc { katello_template_setting_values("provision") }

setting 'katello_default_finish',
type: :string,
default: 'Kickstart default finish',
full_name: N_('Default synced OS finish template'),
description: N_("Default finish template for new Operating Systems created from synced content"),
collection: proc { katello_template_setting_values("finish") }

setting 'katello_default_user_data',
type: :string,
default: 'Kickstart default user data',
full_name: N_('Default synced OS user-data'),
description: N_("Default user data for new Operating Systems created from synced content"),
collection: proc { katello_template_setting_values("user_data") }

setting 'katello_default_PXELinux',
type: :string,
default: 'Kickstart default PXELinux',
full_name: N_('Default synced OS PXELinux template'),
description: N_("Default PXELinux template for new Operating Systems created from synced content"),
collection: proc { katello_template_setting_values("PXELinux") }

setting 'katello_default_PXEGrub',
type: :string,
default: 'Kickstart default PXEGrub',
full_name: N_('Default synced OS PXEGrub template'),
description: N_("Default PXEGrub template for new Operating Systems created from synced content"),
collection: proc { katello_template_setting_values("PXEGrub") }

setting 'katello_default_PXEGrub2',
type: :string,
default: 'Kickstart default PXEGrub2',
full_name: N_('Default synced OS PXEGrub2 template'),
description: N_("Default PXEGrub2 template for new Operating Systems created from synced content"),
collection: proc { katello_template_setting_values("PXEGrub2") }

setting 'katello_default_iPXE',
type: :string,
default: 'Kickstart default iPXE',
full_name: N_('Default synced OS iPXE template'),
description: N_("Default iPXE template for new Operating Systems created from synced content"),
collection: proc { katello_template_setting_values("iPXE") }

setting 'katello_default_ptable',
type: :string,
default: 'Kickstart default',
full_name: N_('Default synced OS partition table'),
description: N_("Default partitioning table for new Operating Systems created from synced content"),
collection: proc { Hash[Template.all.where(:type => "Ptable").map { |tmp| [tmp[:name], tmp[:name]] }] }

setting 'katello_default_kexec',
type: :string,
default: 'Discovery Red Hat kexec',
full_name: N_('Default synced OS kexec template'),
description: N_("Default kexec template for new Operating Systems created from synced content"),
collection: proc { katello_template_setting_values("kexec") }

setting 'katello_default_atomic_provision',
type: :string,
default: 'Atomic Kickstart default',
full_name: N_('Default synced OS Atomic template'),
description: N_("Default provisioning template for new Atomic Operating Systems created from synced content"),
collection: proc { katello_template_setting_values("provision") }

setting 'manifest_refresh_timeout',
type: :integer,
default: 60 * 20,
full_name: N_('Timeout when refreshing a manifest (in seconds)'),
description: N_("Manifest refresh timeout")

setting 'subscription_connection_enabled',
type: :boolean,
default: true,
full_name: N_('Subscription connection enabled'),
description: N_("Can communicate with the Red Hat Portal for subscriptions.")

setting 'errata_status_installable',
type: :boolean,
default: false,
full_name: N_('Generate errata status from directly-installable content'),
description: N_("If true, only errata that can be installed without an incremental update will affect the host's errata status.")

setting 'restrict_composite_view',
type: :boolean,
default: false,
full_name: N_('Restrict composite content view promotion'),
description: N_("If this is enabled, a composite content view may not be published or promoted unless the component content view versions that it includes exist in the target environment.")

setting 'check_services_before_actions',
type: :boolean,
default: true,
full_name: N_('Check services before actions'),
description: N_("Whether or not to check the status of backend services such as pulp and candlepin prior to performing some actions.")

setting 'foreman_proxy_content_batch_size',
type: :integer,
default: 100,
full_name: N_('Batch size to sync repositories in.'),
description: N_("How many repositories should be synced concurrently on the capsule. A smaller number may lead to longer sync times. A larger number will increase dynflow load.")

setting 'foreman_proxy_content_auto_sync',
type: :boolean,
default: true,
full_name: N_('Sync Smart Proxies after content view promotion'),
description: N_("Whether or not to auto sync the Smart Proxies after a content view promotion.")

setting 'download_rate_limit',
type: :integer,
default: 0,
full_name: N_('Download rate limit'),
description: N_("Maximum download rate when syncing a repository (requests per second). Use 0 for no limit.")

setting 'default_download_policy',
type: :string,
default: "immediate",
full_name: N_('Default Custom Repository download policy'),
description: N_("Default download policy for custom repositories (either 'immediate' or 'on_demand')"),
collection: download_policies

setting 'default_redhat_download_policy',
type: :string,
default: "on_demand",
full_name: N_('Default Red Hat Repository download policy'),
description: N_("Default download policy for enabled Red Hat repositories (either 'immediate' or 'on_demand')"),
collection: download_policies

setting 'default_proxy_download_policy',
type: :string,
default: "on_demand",
full_name: N_('Default Smart Proxy download policy'),
description: N_("Default download policy for Smart Proxy syncs (either 'inherit', immediate', or 'on_demand')"),
collection: proxy_download_policies

setting 'pulpcore_export_destination',
type: :string,
default: "/var/lib/pulp/exports",
full_name: N_('Pulp 3 export destination filepath'),
description: N_("On-disk location for pulp 3 exported repositories")

setting 'default_export_format',
type: :string,
default: ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE,
full_name: N_('Default export format'),
description: N_("Default export format for content-exports(either 'syncable' or 'importable')"),
collection: export_formats

setting 'sync_total_timeout',
type: :integer,
default: 3600,
full_name: N_('Sync Total Timeout'),
description: N_("The maximum number of second that Pulp can take to do a single sync operation, e.g., download a single metadata file.")

setting 'sync_connect_timeout_v2',
type: :integer,
default: 60,
full_name: N_('Sync Connect Timeout'),
description: N_("The maximum number of seconds for Pulp to establish a new connection or for waiting for a free connection from a pool if pool connection limits are exceeded.")

setting 'sync_sock_connect_timeout',
type: :integer,
default: 60,
full_name: N_('Sync Sock Connect Timeout'),
description: N_("The maximum number of seconds for Pulp to connect to a peer for a new connection not given from a pool.")

setting 'sync_sock_read_timeout',
type: :integer,
default: 3600,
full_name: N_('Sync Sock Read Timeout'),
description: N_("The maximum number of seconds that Pulp can take to download a file, not counting connection time.")

setting 'unregister_delete_host',
type: :boolean,
default: false,
full_name: N_('Delete Host upon unregister'),
description: N_("When unregistering a host via subscription-manager, also delete the host record. Managed resources linked to host such as virtual machines and DNS records may also be deleted.")

setting 'register_hostname_fact',
type: :string,
default: '',
full_name: N_('Subscription manager name registration fact'),
description: N_("When registering a host via subscription-manager, force use the specified fact (in the form of 'fact.fact')")

setting 'register_hostname_fact_strict_match',
type: :boolean,
default: false,
full_name: N_('Subscription manager name registration fact strict matching'),
description: N_('If this is enabled, and register_hostname_fact is set and provided, registration will look for a new host by name only using that fact, and will skip all hostname matching')

setting 'default_location_subscribed_hosts',
type: :string,
default: nil,
full_name: N_('Default location for subscribed hosts'),
description: N_('Default Location where new subscribed hosts will put upon registration'),
collection: proc { Hash[Location.unscoped.all.map { |loc| [loc[:title], loc[:title]] }] }

setting 'expire_soon_days',
type: :integer,
default: 120,
full_name: N_('Expire soon days'),
description: N_('The number of days remaining in a subscription before you will be reminded about renewing it. Also used for manifest expiration warnings.')

setting 'host_dmi_uuid_duplicates',
type: :array,
default: [],
full_name: N_('Host Duplicate DMI UUIDs'),
description: N_("If hosts fail to register because of duplicate DMI UUIDs, add their comma-separated values here. Subsequent registrations will generate a unique DMI UUID for the affected hosts.")

setting 'host_profile_assume',
type: :boolean,
default: true,
full_name: N_('Host Profile Assume'),
description: N_("Allow new host registrations to assume registered profiles with matching hostname as long as the registering DMI UUID is not used by another host.")

setting 'host_profile_assume_build_can_change',
type: :boolean,
default: false,
full_name: N_('Host Profile Can Change In Build'),
description: N_("Allow host registrations to bypass 'Host Profile Assume' as long as the host is in build mode.")

setting 'host_re_register_build_only',
type: :boolean,
default: false,
full_name: N_('Host Can Re-Register Only In Build'),
description: N_("Allow hosts to re-register themselves only when they are in build mode")

setting 'host_tasks_workers_pool_size',
type: :integer,
default: 5,
full_name: N_('Host Tasks Workers Pool Size'),
description: N_("Amount of workers in the pool to handle the execution of host-related tasks. When set to 0, the default queue will be used instead. Restart of the dynflowd/foreman-tasks service is required.")

setting 'applicability_batch_size',
type: :integer,
default: 50,
full_name: N_('Applicability Batch Size'),
description: N_("Number of host applicability calculations to process per task.")

setting 'bulk_load_size',
type: :integer,
default: 2000,
full_name: N_('Pulp bulk load size'),
description: N_('The number of items fetched from a single paged Pulp API call.')

setting 'orphan_protection_time',
type: :integer,
default: 1440,
full_name: N_('Orphaned Content Protection Time'),
description: N_('Time in minutes before content that is not contained within a repository and has not been accessed is considered orphaned.')

setting 'remote_execution_prefer_registered_through_proxy',
type: :boolean,
default: false,
full_name: N_('Prefer registered through proxy for remote execution'),
description: N_('Prefer using a proxy to which a host is registered when using remote execution')

setting 'delete_repo_across_cv',
type: :boolean,
default: true,
full_name: N_('Allow deleting repositories in published content views'),
description: N_("If this is enabled, repositories can be deleted even when they belong to published content views. The deleted repository will be removed from all content view versions.")

setting 'distribute_archived_cvv',
type: :boolean,
default: true,
full_name: N_('Distribute archived content view versions'),
description: N_("If this is enabled, repositories of content view versions without environments (\"archived\") will be distributed at '/pulp/content/<organization>/content_views/<content view>/X.Y/...'.")
end
end

if Katello.with_remote_execution?
RemoteExecutionFeature.register(:katello_package_install, N_("Katello: Install Package"), :description => N_("Install package via Katello interface"), :provided_inputs => ['package'])
RemoteExecutionFeature.register(:katello_package_install_by_search, N_("Katello: Install packages by search query"), :description => N_("Install packages via Katello interface"), :provided_inputs => ['Package search query'])
RemoteExecutionFeature.register(:katello_package_update, N_("Katello: Update Package"), :description => N_("Update package via Katello interface"), :provided_inputs => ['package'])
RemoteExecutionFeature.register(:katello_packages_update_by_search, N_("Katello: Update Packages by search query"), :description => N_("Update packages via Katello interface"), :provided_inputs => ['Package search query'])
RemoteExecutionFeature.register(:katello_package_remove, N_("Katello: Remove Package"), :description => N_("Remove package via Katello interface"), :provided_inputs => ['package'])
RemoteExecutionFeature.register(:katello_packages_remove_by_search, N_("Katello: Remove Packages by search query"), :description => N_("Remove packages via Katello interface"), :provided_inputs => ['Package search query'])
RemoteExecutionFeature.register(:katello_group_install, N_("Katello: Install Package Group"), :description => N_("Install package group via Katello interface"), :provided_inputs => ['package'])
RemoteExecutionFeature.register(:katello_group_update, N_("Katello: Update Package Group"), :description => N_("Update package group via Katello interface"), :provided_inputs => ['package'])
RemoteExecutionFeature.register(:katello_group_remove, N_("Katello: Remove Package Group"), :description => N_("Remove package group via Katello interface"), :provided_inputs => ['package'])
RemoteExecutionFeature.register(:katello_errata_install, N_("Katello: Install Errata"), :description => N_("Install errata via Katello interface"), :provided_inputs => ['errata'])
RemoteExecutionFeature.register(:katello_errata_install_by_search, N_("Katello: Install errata by search query"), :description => N_("Install errata using scoped search query"), :provided_inputs => ['Errata search query'])
RemoteExecutionFeature.register(:katello_service_restart, N_("Katello: Service Restart"), :description => N_("Restart Services via Katello interface"), :provided_inputs => ['helpers'])
RemoteExecutionFeature.register(:katello_host_tracer_resolve, N_("Katello: Resolve Traces"), :description => N_("Resolve traces via Katello interface"), :provided_inputs => ['ids'])
RemoteExecutionFeature.register(:katello_change_content_source, N_("Katello: Configure host for new content source"), :description => N_("Replace content source on the target machine"), :provided_inputs => [])
RemoteExecutionFeature.register(:katello_upload_profile, N_("Katello: Upload Profile"), :description => N_("Upload package / repos profile"), :provided_inputs => [])
RemoteExecutionFeature.register(:katello_module_stream_action, N_("Katello: Module Stream Actions"),
:description => N_("Perform a module stream action via Katello interface"),
:provided_inputs => ['action', 'module_spec', 'options'])
allowed_template_helpers :errata

RemoteExecutionProvider.singleton_class.prepend(Katello::Concerns::RemoteExecutionProviderExtensions)
end

tests_to_skip("AccessPermissionsTest" => [
'foreman_tasks/api/tasks/callback should have a permission that grants access',
'bastion/bastion/index should have a permission that grants access',
'bastion/bastion/index_ie should have a permission that grants access'
])

add_controller_action_scope('HostsController', :index) do |base_scope|
base_scope
.preload(:subscription_facet)
.preload(content_facet: [:bound_repositories])
end

add_controller_action_scope('Api::V2::HostsController', :index) do |base_scope|
base_scope
.preload(:subscription_facet)
.preload(content_facet: [:bound_repositories])
end

register_info_provider Katello::Host::InfoProvider

medium_providers_registry.register(Katello::ManagedContentMediumProvider)

Katello::PermissionCreator.new(self).define
add_all_permissions_to_default_roles
unless Rails.env.test?
add_permissions_to_default_roles 'System admin' => [:create_lifecycle_environments, :create_content_views]
end
role 'Register hosts', [
:view_hostgroups, :view_activation_keys, :view_hosts,
:create_hosts, :edit_hosts, :destroy_hosts,
:view_content_views, :view_content_credentials, :view_subscriptions,
:attach_subscriptions, :view_host_collections,
:view_organizations, :view_lifecycle_environments, :view_products,
:view_locations, :view_domains, :view_architectures,
:view_operatingsystems, :view_smart_proxies, :view_params
]

role 'Content Importer', [
:import_content, :create_products, :create_content_views,
:edit_products, :edit_content_views, :view_organizations
], 'Role granting permission to import content views in an organization'

role 'Content Exporter', [
:export_content, :view_products, :view_content_views, :view_organizations
], 'Role granting permission to export content views in an organization'

def find_katello_assets(args = {})
type = args.fetch(:type, nil)
vendor = args.fetch(:vendor, false)

if vendor
asset_dir = "#{Katello::Engine.root}/vendor/assets/#{type}/"
else
asset_dir = "#{Katello::Engine.root}/app/assets/#{type}/"
end

asset_paths = Dir[File.join(asset_dir, '**', '*')].reject { |file| File.directory?(file) }
asset_paths.each { |file| file.slice!(asset_dir) }

asset_paths
end

javascripts = find_katello_assets(:type => 'javascripts')
images = find_katello_assets(:type => 'images')
vendor_images = find_katello_assets(:type => 'images', :vendor => true)

bastion_locale_files = Dir.glob("#{Katello::Engine.root}/engines/bastion/vendor/assets/javascripts/#{Bastion.localization_path("*")}")
bastion_locale_files.map do |file|
file.gsub!("#{Katello::Engine.root}/engines/bastion/vendor/assets/javascripts/", "")
end

precompile = [
'katello/katello.css',
'katello/containers/container.css',
'bastion/bastion.css',
'bastion/bastion.js',
'bastion_katello/bastion_katello.css',
'bastion_katello/bastion_katello.js',
'katello/sync_management',
'katello/common'
]

precompile.concat(javascripts)
precompile.concat(images)
precompile.concat(vendor_images)
precompile.concat(bastion_locale_files)

precompile_assets(precompile)

extend_observable_events(::Dynflow::Action.descendants.select { |klass| klass <= ::Actions::ObservableAction }.map(&:namespaced_event_names))
end
(4-4/9)