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 assigned to multiple content view environments with 'subscription-manager register --environments' or 'subscription-manager environments --set'.") # 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. Also affects the Host Collections dashboard widget.") 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 'validate_host_lce_content_source_coherence', type: :boolean, default: true, full_name: N_('Validate host/lifecycle environment/content source coherence'), description: N_("Validate that a host's assigned lifecycle environment is synced by the smart proxy from which the host will get its content. Applies only to API requests; does not affect web UI checks") 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 'completed_pulp_task_protection_days', type: :integer, default: 30, full_name: N_('Completed pulp task protection days'), description: N_('How many days before a completed Pulp task is purged by Orphan Cleanup.') setting 'remote_execution_prefer_registered_through_proxy', type: :boolean, default: false, full_name: N_('Prefer registered through Smart Proxy for remote execution'), description: N_('Prefer using a Smart 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//content_views//X.Y/...'.") setting 'automatic_content_count_updates', type: :boolean, default: true, full_name: N_('Calculate content counts on smart proxies automatically'), description: N_("If this is enabled, content counts on smart proxies will be updated automatically after content sync.") setting 'hide_reclaim_space_warning', type: :boolean, default: false, full_name: N_('Hide Reclaim Space Warning'), description: N_('If this is enabled, the Smart Proxy page will suppress the warning message about reclaiming space.') end end 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) 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, :create_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