katello 4.13.0 → 4.14.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of katello might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js +12 -8
- data/app/assets/javascripts/katello/locale/bn/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/bn_IN/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/ca/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/cs/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/cs_CZ/katello.js +275 -23
- data/app/assets/javascripts/katello/locale/de/katello.js +280 -28
- data/app/assets/javascripts/katello/locale/de_AT/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/de_DE/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/el/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/en/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/en_GB/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/en_US/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/es/katello.js +276 -24
- data/app/assets/javascripts/katello/locale/et_EE/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/fr/katello.js +283 -31
- data/app/assets/javascripts/katello/locale/gl/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/gu/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/he_IL/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/hi/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/id/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/it/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/ja/katello.js +283 -31
- data/app/assets/javascripts/katello/locale/ka/katello.js +280 -28
- data/app/assets/javascripts/katello/locale/kn/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/ko/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/ml_IN/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/mr/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/nl_NL/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/or/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/pa/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/pl/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/pl_PL/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/pt/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/pt_BR/katello.js +276 -24
- data/app/assets/javascripts/katello/locale/ro/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/ro_RO/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/ru/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/sl/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/sv_SE/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/ta/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/ta_IN/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/te/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/tr/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/vi/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/vi_VN/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/zh/katello.js +274 -22
- data/app/assets/javascripts/katello/locale/zh_CN/katello.js +283 -31
- data/app/assets/javascripts/katello/locale/zh_TW/katello.js +274 -22
- data/app/controllers/katello/api/registry/registry_proxies_controller.rb +118 -74
- data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +15 -2
- data/app/controllers/katello/api/v2/activation_keys_controller.rb +1 -1
- data/app/controllers/katello/api/v2/api_controller.rb +7 -0
- data/app/controllers/katello/api/v2/content_view_versions_controller.rb +4 -4
- data/app/controllers/katello/api/v2/debs_controller.rb +3 -2
- data/app/controllers/katello/api/v2/environments_controller.rb +2 -4
- data/app/controllers/katello/api/v2/host_contents_controller.rb +8 -3
- data/app/controllers/katello/api/v2/host_errata_controller.rb +4 -4
- data/app/controllers/katello/api/v2/host_packages_controller.rb +2 -2
- data/app/controllers/katello/api/v2/organizations_controller.rb +1 -1
- data/app/controllers/katello/api/v2/packages_controller.rb +13 -3
- data/app/controllers/katello/api/v2/repositories_bulk_actions_controller.rb +6 -2
- data/app/controllers/katello/api/v2/repositories_controller.rb +3 -4
- data/app/controllers/katello/api/v2/repository_sets_controller.rb +13 -14
- data/app/controllers/katello/api/v2/subscriptions_controller.rb +15 -9
- data/app/controllers/katello/api/v2/sync_controller.rb +2 -2
- data/app/controllers/katello/application_controller.rb +1 -1
- data/app/controllers/katello/concerns/api/v2/authorization.rb +3 -2
- data/app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb +28 -0
- data/app/controllers/katello/concerns/api/v2/registration_commands_controller_extensions.rb +1 -1
- data/app/controllers/katello/concerns/api/v2/repository_content_controller.rb +4 -3
- data/app/controllers/katello/concerns/hosts_controller_extensions.rb +2 -4
- data/app/controllers/katello/remote_execution_controller.rb +53 -58
- data/app/helpers/katello/hosts_and_hostgroups_helper.rb +19 -2
- data/app/helpers/katello/katello_urls_helper.rb +1 -1
- data/app/lib/actions/katello/alternate_content_source/alternate_content_source_common.rb +1 -1
- data/app/lib/actions/katello/alternate_content_source/update.rb +2 -1
- data/app/lib/actions/katello/capsule_content/verify_checksum.rb +1 -2
- data/app/lib/actions/katello/content_view/publish.rb +1 -0
- data/app/lib/actions/katello/content_view_version/create_repos.rb +1 -0
- data/app/lib/actions/katello/content_view_version/incremental_update.rb +3 -2
- data/app/lib/actions/katello/environment/{publish_repositories.rb → publish_container_repositories.rb} +10 -8
- data/app/lib/actions/katello/foreman/content_update.rb +4 -6
- data/app/lib/actions/katello/host/hypervisors_update.rb +6 -4
- data/app/lib/actions/katello/repository/create.rb +4 -4
- data/app/lib/actions/katello/repository/discover.rb +11 -4
- data/app/lib/actions/katello/repository/import_upload.rb +4 -6
- data/app/lib/actions/katello/repository/metadata_generate.rb +1 -0
- data/app/lib/actions/katello/repository/update.rb +3 -3
- data/app/lib/actions/katello/repository_set/enable_repository.rb +5 -6
- data/app/lib/actions/middleware/backend_services_check.rb +3 -2
- data/app/lib/actions/pulp3/abstract_async_task.rb +2 -4
- data/app/lib/actions/pulp3/capsule_content/verify_checksum.rb +1 -2
- data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +5 -1
- data/app/lib/actions/pulp3/orchestration/repository/delete.rb +5 -2
- data/app/lib/actions/pulp3/repository/create_publication.rb +4 -0
- data/app/lib/actions/pulp3/repository/save_version.rb +3 -5
- data/app/lib/katello/concerns/base_template_scope_extensions.rb +5 -9
- data/app/lib/katello/errors.rb +1 -0
- data/app/lib/katello/http_resource.rb +1 -0
- data/app/lib/katello/lazy_accessor.rb +1 -1
- data/app/lib/katello/repo_discovery.rb +4 -190
- data/app/lib/katello/resources/candlepin/candlepin_ping.rb +0 -5
- data/app/lib/katello/resources/candlepin/owner.rb +1 -1
- data/app/lib/katello/resources/candlepin/pool.rb +1 -2
- data/app/lib/katello/resources/candlepin/upstream_job.rb +1 -1
- data/app/lib/katello/resources/cdn.rb +3 -2
- data/app/lib/katello/resources/discovery/container.rb +127 -0
- data/app/lib/katello/resources/discovery/yum.rb +95 -0
- data/app/lib/katello/util/cdn_var_substitutor.rb +5 -3
- data/app/lib/katello/util/data.rb +3 -2
- data/app/lib/katello/util/errata.rb +4 -3
- data/app/lib/katello/util/package.rb +3 -3
- data/app/lib/katello/util/path_with_substitutions.rb +1 -1
- data/app/lib/katello/util/report_table.rb +3 -2
- data/app/lib/katello/util/url_matcher.rb +1 -1
- data/app/lib/katello/validators/alternate_content_source_path_validator.rb +4 -3
- data/app/lib/katello/validators/alternate_content_source_products_validator.rb +5 -7
- data/app/lib/katello/validators/container_image_name_validator.rb +1 -1
- data/app/lib/katello/validators/katello_name_format_validator.rb +2 -2
- data/app/lib/katello/validators/no_trailing_space_validator.rb +2 -2
- data/app/lib/katello/validators/prior_validator.rb +2 -2
- data/app/lib/katello/validators/product_unique_attribute_validator.rb +2 -4
- data/app/models/katello/activation_key.rb +4 -6
- data/app/models/katello/alternate_content_source.rb +1 -1
- data/app/models/katello/authorization/host_tracer.rb +1 -2
- data/app/models/katello/candlepin/repository_mapper.rb +2 -2
- data/app/models/katello/concerns/host_managed_extensions.rb +41 -10
- data/app/models/katello/concerns/hostgroup_extensions.rb +2 -4
- data/app/models/katello/concerns/location_extensions.rb +2 -4
- data/app/models/katello/concerns/operatingsystem_extensions.rb +84 -16
- data/app/models/katello/concerns/smart_proxy_extensions.rb +4 -4
- data/app/models/katello/concerns/subscription_facet_host_extensions.rb +2 -0
- data/app/models/katello/content_view.rb +5 -1
- data/app/models/katello/content_view_environment.rb +19 -4
- data/app/models/katello/content_view_environment_content_facet.rb +11 -0
- data/app/models/katello/erratum.rb +1 -1
- data/app/models/katello/event.rb +1 -1
- data/app/models/katello/glue/provider.rb +1 -2
- data/app/models/katello/hash_util.rb +1 -1
- data/app/models/katello/host/content_facet.rb +16 -3
- data/app/models/katello/host/subscription_facet.rb +27 -4
- data/app/models/katello/host_collection.rb +12 -8
- data/app/models/katello/pool.rb +5 -1
- data/app/models/katello/product.rb +7 -4
- data/app/models/katello/provider.rb +1 -2
- data/app/models/katello/repository.rb +18 -4
- data/app/models/katello/root_repository.rb +29 -0
- data/app/models/katello/rpm.rb +2 -2
- data/app/models/katello/subscription_facet_pool.rb +1 -1
- data/app/models/katello/sync_plan.rb +5 -4
- data/app/models/katello/task_status.rb +18 -18
- data/app/presenters/katello/product_host_count_presenter.rb +10 -0
- data/app/services/katello/candlepin/consumer.rb +11 -11
- data/app/services/katello/candlepin/message_handler.rb +3 -2
- data/app/services/katello/content_unit_indexer.rb +6 -0
- data/app/services/katello/pulp3/alternate_content_source.rb +1 -3
- data/app/services/katello/pulp3/api/core.rb +1 -1
- data/app/services/katello/pulp3/api/docker.rb +10 -0
- data/app/services/katello/pulp3/content_view_version/export.rb +1 -0
- data/app/services/katello/pulp3/content_view_version/import.rb +6 -4
- data/app/services/katello/pulp3/content_view_version/importable_products.rb +1 -3
- data/app/services/katello/pulp3/repository/apt.rb +4 -16
- data/app/services/katello/pulp3/repository/yum.rb +9 -5
- data/app/services/katello/pulp3/repository.rb +2 -2
- data/app/services/katello/pulp3/repository_mirror.rb +2 -9
- data/app/services/katello/pulp3/task.rb +4 -2
- data/app/services/katello/registration_manager.rb +13 -3
- data/app/services/katello/repository_type.rb +1 -1
- data/app/services/katello/smart_proxy_helper.rb +1 -0
- data/app/views/dashboard/_host_collection_widget.html.erb +5 -4
- data/app/views/foreman/job_templates/install_errata.erb +2 -0
- data/app/views/foreman/job_templates/install_errata_-_katello_ansible_default.erb +2 -0
- data/app/views/foreman/job_templates/install_errata_by_search_query.erb +2 -0
- data/app/views/foreman/job_templates/install_errata_by_search_query_-_katello_ansible_default.erb +3 -1
- data/app/views/foreman/job_templates/install_packages_by_search_query_-_katello_ansible_default.erb +1 -1
- data/app/views/foreman/job_templates/remove_packages_by_search_query_-_katello_ansible_default.erb +2 -2
- data/app/views/foreman/job_templates/resolve_traces.erb +5 -1
- data/app/views/foreman/job_templates/update_packages_by_search_query_-_katello_ansible_default.erb +1 -1
- data/app/views/foreman/job_templates/upload_profile.erb +2 -0
- data/app/views/foreman/smart_proxies/_reclaim_space.html.erb +7 -5
- data/app/views/katello/api/v2/content_facet/base.json.rabl +18 -2
- data/app/views/katello/api/v2/packages/thindex.json.rabl +6 -0
- data/app/views/katello/api/v2/repositories/show.json.rabl +8 -8
- data/app/views/katello/api/v2/repository_sets/show.json.rabl +1 -1
- data/app/views/katello/api/v2/subscription_facet/base.json.rabl +1 -1
- data/app/views/katello/api/v2/subscriptions/index.json.rabl +1 -0
- data/app/views/katello/api/v2/subscriptions/show.json.rabl +1 -0
- data/app/views/overrides/activation_keys/_host_environment_select.html.erb +14 -11
- data/app/views/overrides/activation_keys/_host_synced_content_select.html.erb +4 -4
- data/config/initializers/monkeys.rb +0 -1
- data/config/routes/api/v2.rb +3 -1
- data/config/routes.rb +1 -3
- data/db/migrate/20160114200145_add_mirror_on_sync_to_repositories.rb +1 -0
- data/db/migrate/20160131182301_add_download_policy_to_katello_repositories.rb +1 -0
- data/db/migrate/20210119162528_delete_puppet_and_ostree_repos.rb +3 -0
- data/db/migrate/20240522165308_add_priority_to_content_view_environment_content_facet.rb +5 -0
- data/db/migrate/20240621121212_katello_repository_debs_id_bigint.rb +6 -0
- data/db/migrate/20240729192228_add_convert2rhel_to_host_facets.rb +9 -0
- data/db/seeds.d/102-organizations.rb +5 -7
- data/db/seeds.d/150-module_job_templates.rb +7 -9
- data/db/seeds.d/75-job_templates.rb +9 -16
- data/engines/bastion_katello/README.md +3 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-errata.controller.js +3 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/details/views/deb-info.html +6 -6
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-content-hosts.html +2 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +4 -4
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/details/views/package-info.html +6 -6
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +31 -27
- data/engines/bastion_katello/lib/bastion_katello/engine.rb +2 -2
- data/lib/katello/engine.rb +1 -8
- data/lib/katello/permission_creator.rb +3 -2
- data/lib/katello/plugin.rb +31 -27
- data/lib/katello/repository_types/docker.rb +1 -0
- data/lib/katello/repository_types/yum.rb +1 -0
- data/lib/katello/tasks/clean_old_file_repos.rake +2 -4
- data/lib/katello/tasks/reset.rake +3 -4
- data/lib/katello/version.rb +1 -1
- data/lib/katello.rb +0 -4
- data/lib/monkeys/ar_postgres_evr_t.rb +2 -0
- data/locale/action_names.rb +1 -1
- data/locale/bn/LC_MESSAGES/katello.mo +0 -0
- data/locale/bn/katello.po +274 -22
- data/locale/bn_IN/katello.po +274 -22
- data/locale/ca/katello.po +274 -22
- data/locale/cs/katello.po +274 -22
- data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
- data/locale/cs_CZ/katello.po +275 -23
- data/locale/de/LC_MESSAGES/katello.mo +0 -0
- data/locale/de/katello.po +280 -28
- data/locale/de_AT/katello.po +274 -22
- data/locale/de_DE/katello.po +274 -22
- data/locale/el/katello.po +274 -22
- data/locale/en/katello.po +274 -22
- data/locale/en_GB/katello.po +274 -22
- data/locale/en_US/katello.po +274 -22
- data/locale/es/LC_MESSAGES/katello.mo +0 -0
- data/locale/es/katello.po +276 -24
- data/locale/et_EE/katello.po +274 -22
- data/locale/fr/LC_MESSAGES/katello.mo +0 -0
- data/locale/fr/katello.po +283 -31
- data/locale/gl/katello.po +274 -22
- data/locale/gu/katello.po +274 -22
- data/locale/he_IL/katello.po +274 -22
- data/locale/hi/katello.po +274 -22
- data/locale/id/katello.po +274 -22
- data/locale/it/LC_MESSAGES/katello.mo +0 -0
- data/locale/it/katello.po +274 -22
- data/locale/ja/LC_MESSAGES/katello.mo +0 -0
- data/locale/ja/katello.po +283 -31
- data/locale/ka/LC_MESSAGES/katello.mo +0 -0
- data/locale/ka/katello.po +280 -28
- data/locale/katello.pot +1001 -527
- data/locale/kn/katello.po +274 -22
- data/locale/ko/LC_MESSAGES/katello.mo +0 -0
- data/locale/ko/katello.po +274 -22
- data/locale/ml_IN/katello.po +274 -22
- data/locale/mr/katello.po +274 -22
- data/locale/nl_NL/katello.po +274 -22
- data/locale/or/katello.po +274 -22
- data/locale/pa/katello.po +274 -22
- data/locale/pl/katello.po +274 -22
- data/locale/pl_PL/katello.po +274 -22
- data/locale/pt/katello.po +274 -22
- data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
- data/locale/pt_BR/katello.po +276 -24
- data/locale/ro/katello.po +274 -22
- data/locale/ro_RO/katello.po +274 -22
- data/locale/ru/LC_MESSAGES/katello.mo +0 -0
- data/locale/ru/katello.po +274 -22
- data/locale/sl/katello.po +274 -22
- data/locale/sv_SE/katello.po +274 -22
- data/locale/ta/LC_MESSAGES/katello.mo +0 -0
- data/locale/ta/katello.po +274 -22
- data/locale/ta_IN/katello.po +274 -22
- data/locale/te/katello.po +274 -22
- data/locale/tr/katello.po +274 -22
- data/locale/vi/katello.po +274 -22
- data/locale/vi_VN/katello.po +274 -22
- data/locale/zh/katello.po +274 -22
- data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
- data/locale/zh_CN/katello.po +283 -31
- data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
- data/locale/zh_TW/katello.po +274 -22
- data/webpack/ForemanColumnExtensions/index.js +44 -1
- data/webpack/components/Table/TableWrapper.js +6 -0
- data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ChangeHostCVModal.js +24 -3
- data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +124 -56
- data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/HostContentViewActions.js +2 -3
- data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/__tests__/contentViewDetailsCard.test.js +44 -10
- data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +75 -31
- data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionConstants.js +1 -0
- data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionHooks.js +1 -1
- data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +22 -7
- data/webpack/components/extensions/Hosts/ActionsBar/ActionsBar.scss +14 -0
- data/webpack/components/extensions/Hosts/ActionsBar/index.js +82 -23
- data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/index.js +5 -2
- data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/02_BulkErrataTable.js +171 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/04_Review.js +160 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/04_ReviewFooter.js +99 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/BulkErrataWizard.js +157 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/index.js +24 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/02_BulkPackagesTable.js +157 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/04_Review.js +168 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/04_ReviewFooter.js +141 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/BulkPackagesWizard.js +252 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/index.js +24 -0
- data/webpack/components/extensions/Hosts/BulkActions/HostReview.js +176 -0
- data/webpack/components/extensions/Hosts/TableRowActions/index.js +17 -0
- data/webpack/global_index.js +11 -3
- data/webpack/redux/actions/RedHatRepositories/repositorySetRepositories.js +5 -6
- data/webpack/redux/reducers/RedHatRepositories/__tests__/repositorySetRepositories.test.js +1 -1
- data/webpack/redux/reducers/RedHatRepositories/repositorySetRepositories.js +1 -1
- data/webpack/scenes/ContentViews/Copy/CopyContentViewModal.js +2 -1
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +2 -1
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +2 -1
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +2 -1
- data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +2 -1
- data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +2 -2
- data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +2 -1
- data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +3 -2
- data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +2 -1
- data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +2 -1
- data/webpack/scenes/ContentViews/components/CVBreadCrumb.js +2 -1
- data/webpack/scenes/ContentViews/components/ContentViewSelect/ContentViewSelectOption.js +2 -2
- data/webpack/scenes/Subscriptions/Details/SubscriptionAttributes.js +1 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailInfo.test.js.snap +10 -0
- data/webpack/scenes/Subscriptions/SubscriptionConstants.js +6 -0
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +2 -0
- data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +14 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableHelpers.js +1 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableSchema.js +10 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.fixtures.js +1 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/__snapshots__/SubscriptionsToolbar.test.js.snap +10 -0
- data/webpack/scenes/Tasks/helpers.js +1 -1
- metadata +49 -29
- data/app/assets/javascripts/katello/containers/container.js +0 -304
- data/db/migrate/20240531193030_remove_sha1_repository_checksum_type.rb +0 -10
- data/lib/monkeys/anemone.rb +0 -33
- data/webpack/utils/useKatelloDocUrl.js +0 -18
@@ -58,8 +58,8 @@ module Actions
|
|
58
58
|
|
59
59
|
def run
|
60
60
|
repository = ::Katello::Repository.find(input[:repository_id])
|
61
|
-
if input[:sync_capsule]
|
62
|
-
ForemanTasks.async_task(Katello::Repository::CapsuleSync, repository)
|
61
|
+
if input[:sync_capsule] && (Setting[:foreman_proxy_content_auto_sync])
|
62
|
+
ForemanTasks.async_task(Katello::Repository::CapsuleSync, repository)
|
63
63
|
end
|
64
64
|
output[:upload_results] = results_to_json(input[:upload_results])
|
65
65
|
rescue ::Katello::Errors::CapsuleCannotBeReached # skip any capsules that cannot be connected to
|
@@ -92,10 +92,8 @@ module Actions
|
|
92
92
|
json_results << {:type => 'file'}
|
93
93
|
end
|
94
94
|
end
|
95
|
-
|
96
|
-
|
97
|
-
json_results << {:type => 'file'}
|
98
|
-
end
|
95
|
+
if !json_results.size && (result[:content_unit_href])
|
96
|
+
json_results << {:type => 'file'}
|
99
97
|
end
|
100
98
|
end
|
101
99
|
json_results
|
@@ -3,6 +3,7 @@ module Actions
|
|
3
3
|
module Repository
|
4
4
|
class MetadataGenerate < Actions::EntryAction
|
5
5
|
def plan(repository, options = {})
|
6
|
+
return if repository.root.is_container_push && repository.library_instance?
|
6
7
|
action_subject(repository)
|
7
8
|
repository.check_ready_to_act!
|
8
9
|
source_repository = options.fetch(:source_repository, nil)
|
@@ -92,7 +92,7 @@ module Actions
|
|
92
92
|
# match the ACS content type and have a non-nil URL
|
93
93
|
product = repository.product
|
94
94
|
repo_content_types = Set.new
|
95
|
-
product.
|
95
|
+
product.acs_compatible_repositories.each do |test_repo|
|
96
96
|
# we need to check id because test_repo will still contain the old, non-nil url
|
97
97
|
repo_content_types.add(test_repo.content_type) if (repository.id != test_repo.id) && test_repo.url.present?
|
98
98
|
end
|
@@ -110,11 +110,11 @@ module Actions
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def create_acs?(old_url, new_url)
|
113
|
-
old_url.nil? && new_url.present?
|
113
|
+
(old_url.nil? || old_url.start_with?('uln')) && new_url.present? && !new_url.start_with?('uln')
|
114
114
|
end
|
115
115
|
|
116
116
|
def delete_acs?(old_url, new_url)
|
117
|
-
old_url.present? && new_url.nil?
|
117
|
+
old_url.present? && (new_url.nil? || new_url.start_with?('uln'))
|
118
118
|
end
|
119
119
|
end
|
120
120
|
end
|
@@ -6,8 +6,7 @@ module Actions
|
|
6
6
|
_("Enable")
|
7
7
|
end
|
8
8
|
|
9
|
-
def plan(product, content, substitutions,
|
10
|
-
override_arch: nil)
|
9
|
+
def plan(product, content, substitutions, opts = {})
|
11
10
|
mapper = ::Katello::Candlepin::RepositoryMapper.new(product,
|
12
11
|
content,
|
13
12
|
substitutions)
|
@@ -16,10 +15,10 @@ module Actions
|
|
16
15
|
fail ::Katello::Errors::ConflictException, _("The repository is already enabled")
|
17
16
|
end
|
18
17
|
repository = mapper.build_repository
|
19
|
-
repository.root.arch = override_arch if override_arch.present?
|
20
|
-
if override_url
|
21
|
-
repository.root.url = override_url
|
22
|
-
repository.root.download_policy = ::Katello::RootRepository::DOWNLOAD_IMMEDIATE if URI(override_url).scheme == 'file'
|
18
|
+
repository.root.arch = opts[:override_arch] if opts[:override_arch].present?
|
19
|
+
if opts[:override_url]
|
20
|
+
repository.root.url = opts[:override_url]
|
21
|
+
repository.root.download_policy = ::Katello::RootRepository::DOWNLOAD_IMMEDIATE if URI(opts[:override_url]).scheme == 'file'
|
23
22
|
end
|
24
23
|
plan_action(Repository::Create, repository, clone: false)
|
25
24
|
action_subject(repository)
|
@@ -28,9 +28,10 @@ module Actions
|
|
28
28
|
def capsule_id(args)
|
29
29
|
capsule_id = nil
|
30
30
|
args.each do |arg|
|
31
|
-
|
31
|
+
case arg
|
32
|
+
when SmartProxy
|
32
33
|
capsule_id = arg.id
|
33
|
-
|
34
|
+
when Hash
|
34
35
|
capsule_id = arg[:capsule_id] || arg[:smart_proxy_id]
|
35
36
|
end
|
36
37
|
break if capsule_id
|
@@ -96,10 +96,9 @@ module Actions
|
|
96
96
|
def transform_task_response(response)
|
97
97
|
response = [] if response.nil?
|
98
98
|
response = [response] unless response.is_a?(Array)
|
99
|
-
response
|
99
|
+
response.map do |task|
|
100
100
|
task.as_json
|
101
101
|
end
|
102
|
-
response
|
103
102
|
end
|
104
103
|
|
105
104
|
def check_for_errors
|
@@ -166,8 +165,7 @@ module Actions
|
|
166
165
|
def get_task_label(name, href)
|
167
166
|
name = name.split('.').last if name
|
168
167
|
href = href.split('-').last[0...-1] if href
|
169
|
-
|
170
|
-
label
|
168
|
+
"%s (ID: %s)" % [name, href]
|
171
169
|
end
|
172
170
|
end
|
173
171
|
end
|
@@ -17,8 +17,7 @@ module Actions
|
|
17
17
|
if repository
|
18
18
|
[repository]
|
19
19
|
else
|
20
|
-
|
21
|
-
repositories
|
20
|
+
smart_proxy_helper.repositories_available_to_capsule(environment, content_view).by_rpm_count
|
22
21
|
end
|
23
22
|
end
|
24
23
|
end
|
@@ -23,7 +23,7 @@ module Actions
|
|
23
23
|
plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo, tasks: action.output[:pulp_tasks])
|
24
24
|
copy_actions = []
|
25
25
|
#since we're creating a new version from the first repo, start copying at the 2nd
|
26
|
-
source_repositories[1
|
26
|
+
source_repositories[1..].each do |source_repo|
|
27
27
|
# TODO: In a future refactor, can :copy_all be utilized? Filters should not be needed in this code segment.
|
28
28
|
copy_actions << plan_action(Actions::Pulp3::Repository::CopyContent, source_repo, smart_proxy, target_repo,
|
29
29
|
filter_ids: filter_ids, solve_dependencies: solve_dependencies,
|
@@ -32,6 +32,10 @@ module Actions
|
|
32
32
|
plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo, tasks: copy_actions.last.output[:pulp_tasks])
|
33
33
|
end
|
34
34
|
end
|
35
|
+
elsif source_repositories.first.root.is_container_push
|
36
|
+
copy_action = plan_action(Actions::Pulp3::Repository::CopyContent, source_repositories.first, smart_proxy, target_repo,
|
37
|
+
copy_all: true)
|
38
|
+
plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo, tasks: copy_action.output[:pulp_tasks])
|
35
39
|
else
|
36
40
|
plan_self(source_version_repo_id: source_repositories.first.id,
|
37
41
|
target_repo_id: target_repo.id)
|
@@ -9,10 +9,13 @@ module Actions
|
|
9
9
|
plan_action(Actions::Pulp3::Repository::DeleteDistributions, repository.id, smart_proxy)
|
10
10
|
|
11
11
|
if repository.content_view.default?
|
12
|
-
#
|
12
|
+
# Container push repositories must be deleted through the distribution
|
13
|
+
return if repository.root.is_container_push
|
14
|
+
|
15
|
+
# We're deleting the library instance, so just delete the whole pulp3 repo
|
13
16
|
plan_action(Actions::Pulp3::Repository::Delete, repository.id, smart_proxy)
|
14
17
|
elsif repository.environment.nil?
|
15
|
-
#
|
18
|
+
# We're deleting the archived instance, so delete the version
|
16
19
|
plan_action(Actions::Pulp3::Repository::DeleteVersion, repository, smart_proxy)
|
17
20
|
end
|
18
21
|
end
|
@@ -14,6 +14,10 @@ module Actions
|
|
14
14
|
def invoke_external_task
|
15
15
|
unless input[:skip_publication_creation]
|
16
16
|
repository = ::Katello::Repository.find(input[:repository_id])
|
17
|
+
if repository.root.sha1_checksum?
|
18
|
+
repository.root.remove_sha1_checksum_type
|
19
|
+
repository.root.save!
|
20
|
+
end
|
17
21
|
output[:response] = repository.backend_service(smart_proxy).with_mirror_adapter.create_publication
|
18
22
|
end
|
19
23
|
end
|
@@ -20,11 +20,9 @@ module Actions
|
|
20
20
|
end
|
21
21
|
|
22
22
|
output[:publication_provided] = false
|
23
|
-
if input[:tasks].present?
|
24
|
-
|
25
|
-
|
26
|
-
output[:publication_provided] = true
|
27
|
-
end
|
23
|
+
if input[:tasks].present? && (publication_href = ::Katello::Pulp3::Task.publication_href(input[:tasks]))
|
24
|
+
repo.update(:publication_href => publication_href)
|
25
|
+
output[:publication_provided] = true
|
28
26
|
end
|
29
27
|
|
30
28
|
if version_href
|
@@ -259,13 +259,9 @@ module Katello
|
|
259
259
|
labels = 'label ^ (Actions::Katello::Host::Erratum::Install, Actions::Katello::Host::Erratum::ApplicableErrataInstall)'
|
260
260
|
select = 'foreman_tasks_tasks.*'
|
261
261
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
select += ',template_invocations.id AS template_invocation_id'
|
266
|
-
else
|
267
|
-
select += ',NULL AS template_invocation_id'
|
268
|
-
end
|
262
|
+
new_labels = 'label = Actions::RemoteExecution::RunHostJob AND remote_execution_feature.label ^ (katello_errata_install, katello_errata_install_by_search)'
|
263
|
+
labels = [labels, new_labels].map { |label| "(#{label})" }.join(' OR ')
|
264
|
+
select += ',template_invocations.id AS template_invocation_id'
|
269
265
|
|
270
266
|
search = [search_up_to, search_since, search_result, "state = stopped", labels].compact.join(' and ')
|
271
267
|
|
@@ -302,8 +298,8 @@ module Katello
|
|
302
298
|
current_erratum_errata_type = current_erratum[1]
|
303
299
|
current_erratum_issued = current_erratum.last
|
304
300
|
|
305
|
-
if filter_errata_type != 'all'
|
306
|
-
next
|
301
|
+
if filter_errata_type != 'all' && !(filter_errata_type == current_erratum_errata_type)
|
302
|
+
next
|
307
303
|
end
|
308
304
|
|
309
305
|
hash = {
|
data/app/lib/katello/errors.rb
CHANGED
@@ -24,7 +24,7 @@ module Katello
|
|
24
24
|
def lazy_accessor(*args)
|
25
25
|
options = args.extract_options!
|
26
26
|
@lazy_attributes = [] if @lazy_attributes.nil?
|
27
|
-
@lazy_attributes
|
27
|
+
@lazy_attributes.concat args
|
28
28
|
@lazy_attributes_options ||= {}
|
29
29
|
fail ArgumentError, "Attribute names must be symbols" if args.any? { |attribute| !attribute.is_a?(Symbol) }
|
30
30
|
redefined_attr = args.find { |attribute| instance_methods.include?(attribute.to_s) }
|
@@ -4,22 +4,11 @@ module Katello
|
|
4
4
|
class RepoDiscovery
|
5
5
|
include Katello::Util::HttpProxy
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
upstream_password = nil, search = '*', crawled = [],
|
12
|
-
found = [], to_follow = [])
|
13
|
-
@uri = uri(url)
|
14
|
-
@content_type = content_type
|
15
|
-
@upstream_username = upstream_username.empty? ? nil : upstream_username
|
16
|
-
@upstream_password = upstream_password.empty? ? nil : upstream_password
|
17
|
-
@search = search
|
18
|
-
@found = found
|
19
|
-
@crawled = crawled
|
20
|
-
@to_follow = to_follow
|
7
|
+
def self.class_for(content_type)
|
8
|
+
repo_discovery_class = RepositoryTypeManager.find_repository_type(content_type)&.repo_discovery_class
|
9
|
+
fail _("Content type does not support repo discovery") unless repo_discovery_class
|
10
|
+
repo_discovery_class
|
21
11
|
end
|
22
|
-
# rubocop:enable Metrics/ParameterLists
|
23
12
|
|
24
13
|
def uri(url)
|
25
14
|
#add a / on the end, as directories require it or else
|
@@ -27,180 +16,5 @@ module Katello
|
|
27
16
|
url += '/' unless url.ends_with?('/')
|
28
17
|
URI(url)
|
29
18
|
end
|
30
|
-
|
31
|
-
def run(resume_point)
|
32
|
-
if @content_type == 'docker'
|
33
|
-
docker_search
|
34
|
-
else
|
35
|
-
if @uri.scheme == 'file'
|
36
|
-
file_crawl(uri(resume_point))
|
37
|
-
elsif %w(http https).include?(@uri.scheme)
|
38
|
-
http_crawl(uri(resume_point))
|
39
|
-
else
|
40
|
-
fail _("Unsupported URL protocol %s.") % @uri.scheme
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def parse_parameter(field_value)
|
48
|
-
field_value.lstrip!
|
49
|
-
i = field_value.index(/[ \t=;,]/) || field_value.length
|
50
|
-
name = field_value.slice!(0, i).downcase(:ascii)
|
51
|
-
field_value.lstrip!
|
52
|
-
if field_value.delete_prefix!('=')
|
53
|
-
field_value.lstrip!
|
54
|
-
if field_value.delete_prefix!('"')
|
55
|
-
value = ''
|
56
|
-
until field_value.empty?
|
57
|
-
break if field_value.delete_prefix!('"')
|
58
|
-
field_value.delete_prefix!("\\")
|
59
|
-
value += field_value.slice!(0, 1) || ''
|
60
|
-
end
|
61
|
-
else
|
62
|
-
i = field_value.index(/[;,]/) || field_value.length
|
63
|
-
value = field_value.slice!(0, i)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
{name: name, value: value || ''}
|
67
|
-
end
|
68
|
-
|
69
|
-
def parse_parameters(field_value)
|
70
|
-
seen_rel = false
|
71
|
-
has_next_rel = false
|
72
|
-
has_anchor = false
|
73
|
-
until field_value.empty?
|
74
|
-
field_value.lstrip!
|
75
|
-
break if field_value.delete_prefix!(';').nil?
|
76
|
-
param = parse_parameter(field_value)
|
77
|
-
case
|
78
|
-
when param[:name] == 'rel' && !seen_rel
|
79
|
-
seen_rel = true
|
80
|
-
has_next_rel = param[:value].downcase(:ascii).split(/[ \t]/).include?('next')
|
81
|
-
when param[:name] == 'anchor'
|
82
|
-
has_anchor = true
|
83
|
-
end
|
84
|
-
end
|
85
|
-
{has_next_rel: has_next_rel, has_anchor: has_anchor}
|
86
|
-
end
|
87
|
-
|
88
|
-
def get_next_link(link_header)
|
89
|
-
# This code mostly follows Appendix B "Algorithms of Parsing Link Header Fields" of RFC 8288
|
90
|
-
# "Web Linking", <https://www.rfc-editor.org/rfc/rfc8288#appendix-B> (that RFC appears to be
|
91
|
-
# silent about multiple "next" links, so just use the first one and ignore any additional
|
92
|
-
# ones, in the general spirit of being lenient):
|
93
|
-
return nil if link_header.nil?
|
94
|
-
field_value = link_header.clone
|
95
|
-
until field_value.empty?
|
96
|
-
# The following ignores any junk preceding the next <...> link URL:
|
97
|
-
m = field_value.match(/<(.*)>/)
|
98
|
-
break unless m
|
99
|
-
target_string = m[1]
|
100
|
-
field_value = m.post_match
|
101
|
-
params = parse_parameters(field_value)
|
102
|
-
if params[:has_next_rel]
|
103
|
-
# To keep it simple, ignore a link with an (unlikely) anchor parameter; but the RFC
|
104
|
-
# mandates that we "MUST NOT process the link without applying the anchor", so just raise
|
105
|
-
# an exception in that (unlikely) case:
|
106
|
-
fail "anchor not supported" if params[:has_anchor]
|
107
|
-
return target_string
|
108
|
-
end
|
109
|
-
end
|
110
|
-
nil
|
111
|
-
end
|
112
|
-
|
113
|
-
def docker_search
|
114
|
-
request_params = {
|
115
|
-
method: :get,
|
116
|
-
headers: { accept: :json },
|
117
|
-
url: "#{@uri}v1/search?q=#{@search}"
|
118
|
-
}
|
119
|
-
|
120
|
-
request_params[:user] = @upstream_username unless @upstream_username.empty?
|
121
|
-
request_params[:password] = @upstream_password unless @upstream_password.empty?
|
122
|
-
request_params[:proxy] = proxy_uri if proxy
|
123
|
-
|
124
|
-
begin
|
125
|
-
results = RestClient::Request.execute(request_params)
|
126
|
-
JSON.parse(results)['results'].each do |result|
|
127
|
-
@found << result['name']
|
128
|
-
end
|
129
|
-
rescue
|
130
|
-
# Note: v2 endpoint does not support search
|
131
|
-
request_params[:url] = "#{@uri}v2/_catalog"
|
132
|
-
loop do
|
133
|
-
results = RestClient::Request.execute(request_params)
|
134
|
-
JSON.parse(results)['repositories'].each do |result|
|
135
|
-
@found << result
|
136
|
-
end
|
137
|
-
next_uri = get_next_link(results.headers[:link])
|
138
|
-
break if next_uri.nil?
|
139
|
-
request_params[:url] = URI(request_params[:url]).merge(next_uri).to_s
|
140
|
-
end
|
141
|
-
end
|
142
|
-
@found.sort!
|
143
|
-
end
|
144
|
-
|
145
|
-
def anemone_proxy_details
|
146
|
-
details = {}
|
147
|
-
|
148
|
-
if proxy
|
149
|
-
details[:proxy_host] = proxy_host
|
150
|
-
details[:proxy_port] = proxy_port
|
151
|
-
details[:proxy_user] = proxy.username
|
152
|
-
details[:proxy_password] = proxy.password
|
153
|
-
end
|
154
|
-
|
155
|
-
details
|
156
|
-
end
|
157
|
-
|
158
|
-
def http_crawl(resume_point)
|
159
|
-
resume_point_uri = URI(resume_point)
|
160
|
-
resume_point_uri.user = @upstream_username if @upstream_username
|
161
|
-
resume_point_uri.password = @upstream_password if @upstream_password
|
162
|
-
|
163
|
-
Anemone.crawl(resume_point_uri, anemone_proxy_details) do |anemone|
|
164
|
-
anemone.focus_crawl do |page|
|
165
|
-
@crawled << page.url.path
|
166
|
-
|
167
|
-
page.links.each do |link|
|
168
|
-
if link.path.ends_with?('/repodata/')
|
169
|
-
page_url = page.url.clone
|
170
|
-
page_url.user = nil
|
171
|
-
page_url.password = nil
|
172
|
-
@found << page_url.to_s
|
173
|
-
else
|
174
|
-
@to_follow << link.to_s if should_follow?(link.path)
|
175
|
-
end
|
176
|
-
end
|
177
|
-
page.discard_doc! #saves memory, doc not needed
|
178
|
-
[]
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
def file_crawl(resume_point)
|
184
|
-
if resume_point.path.ends_with?('/repodata/')
|
185
|
-
found_path = Pathname(resume_point.path).parent.to_s
|
186
|
-
@found << "file://#{found_path}"
|
187
|
-
end
|
188
|
-
if resume_point.path == @uri.path
|
189
|
-
Dir.glob("#{@uri.path}**/").each { |path| @to_follow << path }
|
190
|
-
@to_follow.shift
|
191
|
-
end
|
192
|
-
@crawled << resume_point.path
|
193
|
-
end
|
194
|
-
|
195
|
-
def should_follow?(path)
|
196
|
-
#Verify:
|
197
|
-
# * link's path starts with the base url
|
198
|
-
# * link hasn't already been crawled
|
199
|
-
# * link ends with '/' so it should be a directory
|
200
|
-
# * link doesn't end with '/Packages/', as this increases
|
201
|
-
# processing time and memory usage considerably
|
202
|
-
return path.starts_with?(@uri.path) && !@crawled.include?(path) &&
|
203
|
-
path.ends_with?('/') && !path.ends_with?('/Packages/')
|
204
|
-
end
|
205
19
|
end
|
206
20
|
end
|
@@ -65,7 +65,7 @@ module Katello
|
|
65
65
|
response = JSON.parse(response_json).with_indifferent_access
|
66
66
|
if wait_until_complete && response['state'] == 'CREATED'
|
67
67
|
while !response['state'].nil? && response['state'] != 'FINISHED' && response['state'] != 'ERROR'
|
68
|
-
path = join_path('candlepin', response['statusPath'][1
|
68
|
+
path = join_path('candlepin', response['statusPath'][1..])
|
69
69
|
response_json = self.get(path, self.default_headers)
|
70
70
|
response = JSON.parse(response_json).with_indifferent_access
|
71
71
|
end
|
@@ -13,8 +13,7 @@ module Katello
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def create(owner_key, attrs)
|
16
|
-
|
17
|
-
pool
|
16
|
+
self.post("/candlepin/owners/#{owner_key}/pools", attrs.to_json, self.default_headers).body
|
18
17
|
end
|
19
18
|
|
20
19
|
def find(pool_id)
|
@@ -11,7 +11,7 @@ module Katello
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def get(id, upstream)
|
14
|
-
url = API_URL
|
14
|
+
url = ENV['REDHAT_RHSM_API_URL'] || API_URL
|
15
15
|
response = Resources::Candlepin::UpstreamConsumer.start_upstream_export("#{url}#{path(id)}", upstream['idCert']['cert'],
|
16
16
|
upstream['idCert']['key'], nil)
|
17
17
|
job = JSON.parse(response)
|
@@ -104,9 +104,10 @@ module Katello
|
|
104
104
|
# very old infrastructure for now, but that was considered better than having an insecure default.
|
105
105
|
net.min_version = OpenSSL::SSL::TLS1_2_VERSION
|
106
106
|
|
107
|
-
|
107
|
+
case @options[:verify_ssl]
|
108
|
+
when false, OpenSSL::SSL::VERIFY_NONE
|
108
109
|
net.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
109
|
-
|
110
|
+
when Integer
|
110
111
|
net.verify_mode = @options[:verify_ssl]
|
111
112
|
net.verify_callback = lambda do |preverify_ok, ssl_context|
|
112
113
|
if !preverify_ok || ssl_context.error != 0
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module Katello
|
2
|
+
module Resources
|
3
|
+
module Discovery
|
4
|
+
class Container < RepoDiscovery
|
5
|
+
attr_reader :found, :crawled, :to_follow
|
6
|
+
def initialize(url, crawled = [], found = [], to_follow = [],
|
7
|
+
upstream_credentials_and_search = {
|
8
|
+
upstream_username: nil,
|
9
|
+
upstream_password: nil,
|
10
|
+
search: '*'
|
11
|
+
})
|
12
|
+
@uri = uri(url)
|
13
|
+
@upstream_username = upstream_credentials_and_search[:upstream_username].presence
|
14
|
+
@upstream_password = upstream_credentials_and_search[:upstream_password].presence
|
15
|
+
@search = upstream_credentials_and_search.fetch(:search, '*')
|
16
|
+
@found = found
|
17
|
+
@crawled = crawled
|
18
|
+
@to_follow = to_follow
|
19
|
+
end
|
20
|
+
|
21
|
+
def run(_resume_point)
|
22
|
+
docker_search
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def parse_parameter(field_value)
|
28
|
+
field_value.lstrip!
|
29
|
+
i = field_value.index(/[ \t=;,]/) || field_value.length
|
30
|
+
name = field_value.slice!(0, i).downcase(:ascii)
|
31
|
+
field_value.lstrip!
|
32
|
+
if field_value.delete_prefix!('=')
|
33
|
+
field_value.lstrip!
|
34
|
+
if field_value.delete_prefix!('"')
|
35
|
+
value = ''
|
36
|
+
until field_value.empty?
|
37
|
+
break if field_value.delete_prefix!('"')
|
38
|
+
field_value.delete_prefix!("\\")
|
39
|
+
value += field_value.slice!(0, 1) || ''
|
40
|
+
end
|
41
|
+
else
|
42
|
+
i = field_value.index(/[;,]/) || field_value.length
|
43
|
+
value = field_value.slice!(0, i)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
{name: name, value: value || ''}
|
47
|
+
end
|
48
|
+
|
49
|
+
def parse_parameters(field_value)
|
50
|
+
seen_rel = false
|
51
|
+
has_next_rel = false
|
52
|
+
has_anchor = false
|
53
|
+
until field_value.empty?
|
54
|
+
field_value.lstrip!
|
55
|
+
break if field_value.delete_prefix!(';').nil?
|
56
|
+
param = parse_parameter(field_value)
|
57
|
+
case
|
58
|
+
when param[:name] == 'rel' && !seen_rel
|
59
|
+
seen_rel = true
|
60
|
+
has_next_rel = param[:value].downcase(:ascii).split(/[ \t]/).include?('next')
|
61
|
+
when param[:name] == 'anchor'
|
62
|
+
has_anchor = true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
{has_next_rel: has_next_rel, has_anchor: has_anchor}
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_next_link(link_header)
|
69
|
+
# This code mostly follows Appendix B "Algorithms of Parsing Link Header Fields" of RFC 8288
|
70
|
+
# "Web Linking", <https://www.rfc-editor.org/rfc/rfc8288#appendix-B> (that RFC appears to be
|
71
|
+
# silent about multiple "next" links, so just use the first one and ignore any additional
|
72
|
+
# ones, in the general spirit of being lenient):
|
73
|
+
return nil if link_header.nil?
|
74
|
+
field_value = link_header.clone
|
75
|
+
until field_value.empty?
|
76
|
+
# The following ignores any junk preceding the next <...> link URL:
|
77
|
+
m = field_value.match(/<(.*)>/)
|
78
|
+
break unless m
|
79
|
+
target_string = m[1]
|
80
|
+
field_value = m.post_match
|
81
|
+
params = parse_parameters(field_value)
|
82
|
+
if params[:has_next_rel]
|
83
|
+
# To keep it simple, ignore a link with an (unlikely) anchor parameter; but the RFC
|
84
|
+
# mandates that we "MUST NOT process the link without applying the anchor", so just raise
|
85
|
+
# an exception in that (unlikely) case:
|
86
|
+
fail "anchor not supported" if params[:has_anchor]
|
87
|
+
return target_string
|
88
|
+
end
|
89
|
+
end
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
|
93
|
+
def docker_search
|
94
|
+
request_params = {
|
95
|
+
method: :get,
|
96
|
+
headers: { accept: :json },
|
97
|
+
url: "#{@uri}v1/search?q=#{@search}"
|
98
|
+
}
|
99
|
+
|
100
|
+
request_params[:user] = @upstream_username if @upstream_username
|
101
|
+
request_params[:password] = @upstream_password if @upstream_password
|
102
|
+
request_params[:proxy] = proxy_uri if proxy
|
103
|
+
|
104
|
+
begin
|
105
|
+
results = RestClient::Request.execute(request_params)
|
106
|
+
JSON.parse(results)['results'].each do |result|
|
107
|
+
@found << result['name']
|
108
|
+
end
|
109
|
+
rescue
|
110
|
+
# Note: v2 endpoint does not support search
|
111
|
+
request_params[:url] = "#{@uri}v2/_catalog"
|
112
|
+
loop do
|
113
|
+
results = RestClient::Request.execute(request_params)
|
114
|
+
JSON.parse(results)['repositories'].each do |result|
|
115
|
+
@found << result
|
116
|
+
end
|
117
|
+
next_uri = get_next_link(results.headers[:link])
|
118
|
+
break if next_uri.nil?
|
119
|
+
request_params[:url] = URI(request_params[:url]).merge(next_uri).to_s
|
120
|
+
end
|
121
|
+
end
|
122
|
+
@found.sort!
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|