katello 4.17.0 → 4.18.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of katello might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/assets/javascripts/katello/locale/bn/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/bn_IN/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/ca/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/cs/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/cs_CZ/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/de/katello.js +147 -3
- data/app/assets/javascripts/katello/locale/de_AT/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/de_DE/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/el/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/en/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/en_GB/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/en_US/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/es/katello.js +147 -3
- data/app/assets/javascripts/katello/locale/et_EE/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/fr/katello.js +147 -3
- data/app/assets/javascripts/katello/locale/gl/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/gu/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/he_IL/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/hi/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/id/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/it/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/ja/katello.js +147 -3
- data/app/assets/javascripts/katello/locale/ka/katello.js +147 -3
- data/app/assets/javascripts/katello/locale/kn/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/ko/katello.js +147 -3
- data/app/assets/javascripts/katello/locale/ml_IN/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/mr/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/nl_NL/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/or/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/pa/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/pl/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/pl_PL/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/pt/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/pt_BR/katello.js +147 -3
- data/app/assets/javascripts/katello/locale/ro/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/ro_RO/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/ru/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/sl/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/sv_SE/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/ta/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/ta_IN/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/te/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/tr/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/vi/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/vi_VN/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/zh/katello.js +148 -4
- data/app/assets/javascripts/katello/locale/zh_CN/katello.js +147 -3
- data/app/assets/javascripts/katello/locale/zh_TW/katello.js +148 -4
- data/app/controllers/katello/api/registry/registry_proxies_controller.rb +14 -14
- data/app/controllers/katello/api/v2/content_uploads_controller.rb +2 -1
- data/app/controllers/katello/api/v2/errata_controller.rb +16 -0
- data/app/controllers/katello/api/v2/flatpak_remote_repositories_controller.rb +20 -3
- data/app/controllers/katello/api/v2/flatpak_remotes_controller.rb +7 -3
- data/app/controllers/katello/api/v2/generic_content_units_controller.rb +1 -2
- data/app/controllers/katello/api/v2/products_controller.rb +18 -0
- data/app/controllers/katello/api/v2/repositories_controller.rb +5 -3
- data/app/controllers/katello/concerns/api/v2/hosts_bulk_actions_controller_extensions.rb +10 -0
- data/app/controllers/katello/concerns/api/v2/registration_commands_controller_extensions.rb +1 -0
- data/app/controllers/katello/concerns/filtered_auto_complete_search.rb +17 -0
- data/app/lib/actions/helpers/smart_proxy_sync_helper.rb +12 -0
- data/app/lib/actions/katello/content_view/add_rolling_repo_clone.rb +4 -4
- data/app/lib/actions/katello/content_view/capsule_sync.rb +8 -3
- data/app/lib/actions/katello/content_view/publish.rb +39 -12
- data/app/lib/actions/katello/flatpak/mirror_remote_repository.rb +2 -1
- data/app/lib/actions/katello/repository/capsule_sync.rb +11 -1
- data/app/lib/actions/katello/repository/destroy.rb +3 -0
- data/app/lib/actions/katello/repository/import_upload.rb +2 -3
- data/app/lib/actions/katello/repository/sync.rb +2 -1
- data/app/lib/actions/katello/repository/upload_files.rb +2 -1
- data/app/lib/katello/concerns/bookmark_controller_validator_extensions.rb +1 -1
- data/app/lib/katello/resources/cdn.rb +1 -1
- data/app/models/katello/concerns/smart_proxy_extensions.rb +46 -8
- data/app/models/katello/content_view_environment.rb +1 -1
- data/app/models/katello/erratum.rb +26 -1
- data/app/models/katello/flatpak_remote.rb +0 -1
- data/app/models/katello/flatpak_remote_repository.rb +24 -0
- data/app/models/katello/glue/pulp/repos.rb +1 -1
- data/app/models/katello/root_repository.rb +1 -0
- data/app/presenters/katello/flatpak_remote_mirror_status_presenter.rb +41 -0
- data/app/services/katello/repository_type_manager.rb +2 -0
- data/app/views/foreman/job_templates/flatpak_install.erb +17 -2
- data/app/views/foreman/job_templates/flatpak_login_action.erb +17 -3
- data/app/views/foreman/job_templates/install_errata_by_search_query.erb +1 -1
- data/app/views/foreman/job_templates/install_errata_by_search_query_-_katello_ansible_default.erb +1 -1
- data/app/views/foreman/job_templates/install_packages_by_search_query_-_katello_ansible_default.erb +6 -14
- data/app/views/foreman/job_templates/remove_packages_by_search_query_-_katello_ansible_default.erb +2 -15
- data/app/views/foreman/job_templates/update_packages_by_search_query_-_katello_ansible_default.erb +5 -13
- data/app/views/katello/api/v2/flatpak_remote_repositories/base.json.rabl +3 -1
- data/app/views/katello/api/v2/flatpak_remotes/base.json.rabl +5 -0
- data/app/views/katello/api/v2/flatpak_remotes/permissions.json.rabl +1 -0
- data/config/routes/api/v2.rb +1 -1
- data/config/routes.rb +3 -0
- data/db/migrate/20240924161240_katello_recreate_evr_constructs.rb +20 -0
- data/db/migrate/20250613210050_use_big_int_for_erratum_packages_id.rb +11 -0
- data/db/migrate/20250714190050_add_missing_rpms_evr_index.rb +14 -0
- data/db/seeds.d/108-subcription-bookmarks.rb +2 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/views/errata.html +5 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +4 -5
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/bn.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/bn_IN.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ca.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/cs_CZ.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de_AT.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de_DE.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/el.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/en_GB.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/en_US.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/es.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/et_EE.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/fr.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/gl.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/gu.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/he_IL.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/hi.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/id.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/it.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ja.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ka.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/kn.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ko.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ml_IN.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/mr.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/nl_NL.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/or.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pa.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pl.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pl_PL.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pt.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pt_BR.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ro.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ro_RO.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ru.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/sl.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/sv_SE.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ta.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ta_IN.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/te.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/tr.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/vi.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/vi_VN.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_CN.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_TW.po +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +13 -3
- data/engines/bastion_katello/lib/bastion_katello/engine.rb +2 -0
- data/lib/katello/engine.rb +0 -1
- data/lib/katello/permission_creator.rb +1 -1
- data/lib/katello/plugin.rb +26 -2
- data/lib/katello/version.rb +1 -1
- data/lib/katello.rb +0 -1
- data/lib/proxy_api/container_gateway.rb +24 -0
- data/locale/bn/LC_MESSAGES/katello.mo +0 -0
- data/locale/bn/katello.po +148 -4
- data/locale/bn_IN/LC_MESSAGES/katello.mo +0 -0
- data/locale/bn_IN/katello.po +148 -4
- data/locale/ca/LC_MESSAGES/katello.mo +0 -0
- data/locale/ca/katello.po +148 -4
- data/locale/cs/LC_MESSAGES/katello.mo +0 -0
- data/locale/cs/katello.po +148 -4
- data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
- data/locale/cs_CZ/katello.po +148 -4
- data/locale/de/katello.po +147 -3
- data/locale/de_AT/LC_MESSAGES/katello.mo +0 -0
- data/locale/de_AT/katello.po +148 -4
- data/locale/de_DE/LC_MESSAGES/katello.mo +0 -0
- data/locale/de_DE/katello.po +148 -4
- data/locale/el/LC_MESSAGES/katello.mo +0 -0
- data/locale/el/katello.po +148 -4
- data/locale/en/LC_MESSAGES/katello.mo +0 -0
- data/locale/en/katello.po +148 -4
- data/locale/en_GB/LC_MESSAGES/katello.mo +0 -0
- data/locale/en_GB/katello.po +148 -4
- data/locale/en_US/LC_MESSAGES/katello.mo +0 -0
- data/locale/en_US/katello.po +148 -4
- data/locale/es/katello.po +147 -3
- data/locale/et_EE/LC_MESSAGES/katello.mo +0 -0
- data/locale/et_EE/katello.po +148 -4
- data/locale/fr/katello.po +147 -3
- data/locale/gl/LC_MESSAGES/katello.mo +0 -0
- data/locale/gl/katello.po +148 -4
- data/locale/gu/LC_MESSAGES/katello.mo +0 -0
- data/locale/gu/katello.po +148 -4
- data/locale/he_IL/LC_MESSAGES/katello.mo +0 -0
- data/locale/he_IL/katello.po +148 -4
- data/locale/hi/LC_MESSAGES/katello.mo +0 -0
- data/locale/hi/katello.po +148 -4
- data/locale/id/LC_MESSAGES/katello.mo +0 -0
- data/locale/id/katello.po +148 -4
- data/locale/it/LC_MESSAGES/katello.mo +0 -0
- data/locale/it/katello.po +148 -4
- data/locale/ja/katello.po +147 -3
- data/locale/ka/katello.po +147 -3
- data/locale/katello.pot +703 -428
- data/locale/kn/LC_MESSAGES/katello.mo +0 -0
- data/locale/kn/katello.po +148 -4
- data/locale/ko/katello.po +147 -3
- data/locale/ml_IN/LC_MESSAGES/katello.mo +0 -0
- data/locale/ml_IN/katello.po +148 -4
- data/locale/mr/LC_MESSAGES/katello.mo +0 -0
- data/locale/mr/katello.po +148 -4
- data/locale/nl_NL/LC_MESSAGES/katello.mo +0 -0
- data/locale/nl_NL/katello.po +148 -4
- data/locale/or/LC_MESSAGES/katello.mo +0 -0
- data/locale/or/katello.po +148 -4
- data/locale/pa/LC_MESSAGES/katello.mo +0 -0
- data/locale/pa/katello.po +148 -4
- data/locale/pl/LC_MESSAGES/katello.mo +0 -0
- data/locale/pl/katello.po +148 -4
- data/locale/pl_PL/LC_MESSAGES/katello.mo +0 -0
- data/locale/pl_PL/katello.po +148 -4
- data/locale/pt/LC_MESSAGES/katello.mo +0 -0
- data/locale/pt/katello.po +148 -4
- data/locale/pt_BR/katello.po +147 -3
- data/locale/ro/LC_MESSAGES/katello.mo +0 -0
- data/locale/ro/katello.po +148 -4
- data/locale/ro_RO/LC_MESSAGES/katello.mo +0 -0
- data/locale/ro_RO/katello.po +148 -4
- data/locale/ru/LC_MESSAGES/katello.mo +0 -0
- data/locale/ru/katello.po +148 -4
- data/locale/sl/LC_MESSAGES/katello.mo +0 -0
- data/locale/sl/katello.po +148 -4
- data/locale/sv_SE/LC_MESSAGES/katello.mo +0 -0
- data/locale/sv_SE/katello.po +148 -4
- data/locale/ta/LC_MESSAGES/katello.mo +0 -0
- data/locale/ta/katello.po +148 -4
- data/locale/ta_IN/LC_MESSAGES/katello.mo +0 -0
- data/locale/ta_IN/katello.po +148 -4
- data/locale/te/LC_MESSAGES/katello.mo +0 -0
- data/locale/te/katello.po +148 -4
- data/locale/tr/LC_MESSAGES/katello.mo +0 -0
- data/locale/tr/katello.po +148 -4
- data/locale/vi/LC_MESSAGES/katello.mo +0 -0
- data/locale/vi/katello.po +148 -4
- data/locale/vi_VN/LC_MESSAGES/katello.mo +0 -0
- data/locale/vi_VN/katello.po +148 -4
- data/locale/zh/LC_MESSAGES/katello.mo +0 -0
- data/locale/zh/katello.po +148 -4
- data/locale/zh_CN/katello.po +147 -3
- data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
- data/locale/zh_TW/katello.po +148 -4
- data/package.json +0 -1
- data/webpack/components/Content/Details/__tests__/__snapshots__/ContentDetails.test.js.snap +2 -2
- data/webpack/components/OptionTooltip/OptionTooltip.scss +1 -1
- data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +6 -1
- data/webpack/components/extensions/Hosts/ActionsBar/index.js +11 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/BulkChangeHostCVModal.js +1 -1
- data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/actions.js +1 -2
- data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/04_ReviewFooter.js +1 -1
- data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/04_ReviewFooter.js +1 -1
- data/webpack/components/extensions/Hosts/BulkActions/BulkRepositorySetsWizard/01_BulkRepositorySetsTable.js +371 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkRepositorySetsWizard/03_Review.js +79 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkRepositorySetsWizard/03_ReviewFooter.js +73 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkRepositorySetsWizard/BulkRepositorySetsWizard.js +170 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkRepositorySetsWizard/actions.js +23 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkRepositorySetsWizard/helpers.js +28 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkRepositorySetsWizard/index.js +23 -0
- data/webpack/components/extensions/RegistrationCommands/fields/SetupContainerRegistryCerts.js +39 -0
- data/webpack/components/extensions/RegistrationCommands/index.js +7 -0
- data/webpack/components/pf3Table/formatters/ellipsisCellFormatter.js +3 -2
- data/webpack/containers/Application/config.js +11 -0
- data/webpack/global_index.js +3 -1
- data/webpack/scenes/FlatpakRemotes/CreateEdit/CreateFlatpakRemoteModal.js +30 -0
- data/webpack/scenes/FlatpakRemotes/CreateEdit/EditFlatpakRemotesModal.js +38 -0
- data/webpack/scenes/FlatpakRemotes/CreateEdit/FlatpakRemoteform.js +218 -0
- data/webpack/scenes/FlatpakRemotes/CreateEdit/__tests__/flatpakRemoteform.test.js +117 -0
- data/webpack/scenes/FlatpakRemotes/Delete/DeleteFlatpakModal.js +59 -0
- data/webpack/scenes/FlatpakRemotes/Details/FlatpakRemoteDetailActions.js +87 -0
- data/webpack/scenes/FlatpakRemotes/Details/FlatpakRemoteDetailReducers.js +23 -0
- data/webpack/scenes/FlatpakRemotes/Details/FlatpakRemoteDetailSelectors.js +16 -0
- data/webpack/scenes/FlatpakRemotes/Details/FlatpakRemoteDetails.js +167 -0
- data/webpack/scenes/FlatpakRemotes/Details/Mirror/MirrorRepositoryModal.js +135 -0
- data/webpack/scenes/FlatpakRemotes/Details/Mirror/__tests__/mirrorRepositoryModal.test.js +167 -0
- data/webpack/scenes/FlatpakRemotes/Details/RemoteRepositories/RemoteRepositoriesTable.js +171 -0
- data/webpack/scenes/FlatpakRemotes/Details/__tests__/flatpakRemoteDetails.fixtures.json +58 -0
- data/webpack/scenes/FlatpakRemotes/Details/__tests__/flatpakRemoteDetails.test.js +90 -0
- data/webpack/scenes/FlatpakRemotes/Details/index.js +4 -0
- data/webpack/scenes/FlatpakRemotes/FlatpakRemotesActions.js +26 -0
- data/webpack/scenes/FlatpakRemotes/FlatpakRemotesConstants.js +15 -0
- data/webpack/scenes/FlatpakRemotes/FlatpakRemotesPage.js +202 -0
- data/webpack/scenes/FlatpakRemotes/FlatpakRemotesSelectors.js +24 -0
- data/webpack/scenes/FlatpakRemotes/__tests__/flatpakRemotesList.fixtures.json +55 -0
- data/webpack/scenes/FlatpakRemotes/__tests__/flatpakRemotesPage.test.js +74 -0
- data/webpack/scenes/FlatpakRemotes/index.js +4 -0
- data/webpack/scenes/Hosts/ChangeContentSource/components/Hosts.js +2 -2
- data/webpack/scenes/RedHatRepositories/components/RecommendedRepositorySetsToggler.scss +1 -1
- data/webpack/scenes/RedHatRepositories/index.scss +1 -1
- data/webpack/scenes/Settings/SettingsSelectors.js +3 -3
- data/webpack/scenes/Settings/index.js +1 -3
- data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +2 -2
- data/webpack/scenes/Subscriptions/SubscriptionsPage.scss +1 -1
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionsReducer.test.js +0 -21
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsReducer.test.js.snap +0 -44
- data/webpack/scenes/Subscriptions/index.js +1 -3
- metadata +39 -21
- data/webpack/scenes/Settings/SettingsConstants.js +0 -2
- data/webpack/scenes/Settings/SettingsReducer.js +0 -19
@@ -0,0 +1,23 @@
|
|
1
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
2
|
+
import { API_OPERATIONS, put } from 'foremanReact/redux/API';
|
3
|
+
import { errorToast, renderTaskStartedToast } from '../../../../../scenes/Tasks/helpers';
|
4
|
+
import { foremanApi } from '../../../../../services/api';
|
5
|
+
|
6
|
+
const BULK_HOST_CONTENT_OVERRIDES_KEY = 'BULK_HOST_CONTENT_OVERRIDES';
|
7
|
+
|
8
|
+
export const bulkUpdateHostContentOverrides =
|
9
|
+
(params, handleSuccess, handleError) => put({
|
10
|
+
type: API_OPERATIONS.PUT,
|
11
|
+
key: BULK_HOST_CONTENT_OVERRIDES_KEY,
|
12
|
+
url: foremanApi.getApiUrl('/hosts/bulk/content_overrides'),
|
13
|
+
successToast: () => __('Content overrides updating.'),
|
14
|
+
handleSuccess: (response) => {
|
15
|
+
if (handleSuccess) handleSuccess(response);
|
16
|
+
return renderTaskStartedToast(response.data);
|
17
|
+
},
|
18
|
+
handleError,
|
19
|
+
errorToast,
|
20
|
+
params,
|
21
|
+
});
|
22
|
+
|
23
|
+
export default bulkUpdateHostContentOverrides;
|
@@ -0,0 +1,28 @@
|
|
1
|
+
export const pendingOverrideToApiParamItem = ({ repoLabel, value }) => {
|
2
|
+
switch (Number(value)) {
|
3
|
+
case 0: // No change
|
4
|
+
return null;
|
5
|
+
case 1: // Override to enabled
|
6
|
+
return {
|
7
|
+
content_label: repoLabel,
|
8
|
+
name: 'enabled',
|
9
|
+
value: true,
|
10
|
+
};
|
11
|
+
case 2: // Override to disabled
|
12
|
+
return {
|
13
|
+
content_label: repoLabel,
|
14
|
+
name: 'enabled',
|
15
|
+
value: false,
|
16
|
+
};
|
17
|
+
case 3: // Reset to default
|
18
|
+
return {
|
19
|
+
content_label: repoLabel,
|
20
|
+
name: 'enabled',
|
21
|
+
remove: true,
|
22
|
+
};
|
23
|
+
default:
|
24
|
+
return null;
|
25
|
+
}
|
26
|
+
};
|
27
|
+
|
28
|
+
export default pendingOverrideToApiParamItem;
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { Modal, ModalVariant } from '@patternfly/react-core';
|
3
|
+
import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
|
4
|
+
import BulkRepositorySetsWizard from './BulkRepositorySetsWizard';
|
5
|
+
|
6
|
+
const BulkRepositorySetsWizardModal = () => {
|
7
|
+
const { modalOpen: isOpen } = useForemanModal({ id: 'bulk-repo-sets-wizard' });
|
8
|
+
|
9
|
+
return (
|
10
|
+
<Modal
|
11
|
+
ouiaId="bulk-repo-sets-wizard-modal"
|
12
|
+
isOpen={isOpen}
|
13
|
+
showClose={false}
|
14
|
+
aria-label="Wizard modal"
|
15
|
+
hasNoBodyWrapper
|
16
|
+
variant={ModalVariant.large}
|
17
|
+
>
|
18
|
+
<BulkRepositorySetsWizard />
|
19
|
+
</Modal>
|
20
|
+
);
|
21
|
+
};
|
22
|
+
|
23
|
+
export default BulkRepositorySetsWizardModal;
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { noop } from 'foremanReact/common/helpers';
|
4
|
+
|
5
|
+
import { FormGroup, Checkbox } from '@patternfly/react-core';
|
6
|
+
import LabelIcon from 'foremanReact/components/common/LabelIcon';
|
7
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
8
|
+
|
9
|
+
const SetupContainerRegistryCerts = ({ value, onChange, isLoading }) => (
|
10
|
+
<FormGroup fieldId="reg_container_certs">
|
11
|
+
<Checkbox
|
12
|
+
ouiaId="reg-container-certs"
|
13
|
+
label={
|
14
|
+
<span>
|
15
|
+
{__('Set up container registry certs')}{' '}
|
16
|
+
<LabelIcon text={__('Place symlinks to entitlement certificates on the host, enabling container/flatpak registry access without a username or password.')} />
|
17
|
+
</span>
|
18
|
+
}
|
19
|
+
id="reg_container_certs"
|
20
|
+
onChange={() => onChange({ setupContainerRegistryCerts: !value })}
|
21
|
+
isDisabled={isLoading}
|
22
|
+
isChecked={value}
|
23
|
+
/>
|
24
|
+
</FormGroup>
|
25
|
+
);
|
26
|
+
|
27
|
+
SetupContainerRegistryCerts.propTypes = {
|
28
|
+
value: PropTypes.bool,
|
29
|
+
onChange: PropTypes.func,
|
30
|
+
isLoading: PropTypes.bool,
|
31
|
+
};
|
32
|
+
|
33
|
+
SetupContainerRegistryCerts.defaultProps = {
|
34
|
+
value: false,
|
35
|
+
onChange: noop,
|
36
|
+
isLoading: false,
|
37
|
+
};
|
38
|
+
|
39
|
+
export default SetupContainerRegistryCerts;
|
@@ -7,6 +7,7 @@ import { determineInitialAKSelection } from './helpers';
|
|
7
7
|
import ActivationKeys from './fields/ActivationKeys';
|
8
8
|
import IgnoreSubmanErrors from './fields/IgnoreSubmanErrors';
|
9
9
|
import Force from './fields/Force';
|
10
|
+
import SetupContainerRegistryCerts from './fields/SetupContainerRegistryCerts';
|
10
11
|
|
11
12
|
export const RegistrationCommands = ({
|
12
13
|
pluginValues,
|
@@ -26,6 +27,12 @@ export const RegistrationCommands = ({
|
|
26
27
|
onChange={onChange}
|
27
28
|
isLoading={isLoading}
|
28
29
|
/>
|
30
|
+
<SetupContainerRegistryCerts
|
31
|
+
value={pluginValues?.setupContainerRegistryCerts}
|
32
|
+
pluginValues={pluginValues}
|
33
|
+
onChange={onChange}
|
34
|
+
isLoading={isLoading}
|
35
|
+
/>
|
29
36
|
</>
|
30
37
|
);
|
31
38
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import
|
2
|
+
import { Truncate } from '@patternfly/react-core';
|
3
|
+
|
3
4
|
import cellFormatter from './cellFormatter';
|
4
5
|
|
5
|
-
export default value => cellFormatter(<
|
6
|
+
export default value => cellFormatter(<Truncate content={value} />);
|
@@ -16,6 +16,8 @@ import withHeader from './withHeaders';
|
|
16
16
|
import ChangeContentSource from '../../scenes/Hosts/ChangeContentSource';
|
17
17
|
import AlternateContentSource from '../../scenes/AlternateContentSources';
|
18
18
|
import BootedContainerImages from '../../scenes/BootedContainerImages';
|
19
|
+
import FlatpakRemotes from '../../scenes/FlatpakRemotes';
|
20
|
+
import FlatpakRemoteDetails from '../../scenes/FlatpakRemotes/Details';
|
19
21
|
|
20
22
|
// eslint-disable-next-line import/prefer-default-export
|
21
23
|
export const links = [
|
@@ -90,4 +92,13 @@ export const links = [
|
|
90
92
|
path: 'booted_container_images',
|
91
93
|
component: WithOrganization(withHeader(BootedContainerImages, { title: __('Booted container images') })),
|
92
94
|
},
|
95
|
+
{
|
96
|
+
path: 'flatpak_remotes',
|
97
|
+
component: WithOrganization(withHeader(FlatpakRemotes, { title: __('Flatpak Remotes') })),
|
98
|
+
},
|
99
|
+
{
|
100
|
+
path: 'flatpak_remotes/:id([0-9]+)',
|
101
|
+
component: WithOrganization(withHeader(FlatpakRemoteDetails, { title: __('Flatpak Remote Details') })),
|
102
|
+
exact: false,
|
103
|
+
},
|
93
104
|
];
|
data/webpack/global_index.js
CHANGED
@@ -38,6 +38,7 @@ import SystemPurposeCard from './components/extensions/HostDetails/Cards/SystemP
|
|
38
38
|
import BulkChangeHostCVModal from './components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/index.js';
|
39
39
|
import BulkPackagesWizardModal from './components/extensions/Hosts/BulkActions/BulkPackagesWizard/index.js';
|
40
40
|
import BulkErrataWizardModal from './components/extensions/Hosts/BulkActions/BulkErrataWizard/index.js';
|
41
|
+
import BulkRepositorySetsWizardModal from './components/extensions/Hosts/BulkActions/BulkRepositorySetsWizard/index.js';
|
41
42
|
import ActivationKeysSearch from './components/ActivationKeysSearch';
|
42
43
|
import { CVEDetailsCard } from './scenes/ActivationKeys/Details/components/CVEDetailsCard.js';
|
43
44
|
|
@@ -96,7 +97,8 @@ addGlobalFill(
|
|
96
97
|
// Hosts Index page extensions
|
97
98
|
addGlobalFill('_all-hosts-modals', 'BulkChangeHostCVModal', <BulkChangeHostCVModal key="bulk-change-host-cv-modal" />, 100);
|
98
99
|
addGlobalFill('_all-hosts-modals', 'BulkPackagesWizardModal', <BulkPackagesWizardModal key="bulk-packages-wizard-modal" />, 200);
|
99
|
-
addGlobalFill('_all-hosts-modals', 'BulkErrataWizardModal', <BulkErrataWizardModal key="bulk-errata-wizard-modal" />,
|
100
|
+
addGlobalFill('_all-hosts-modals', 'BulkErrataWizardModal', <BulkErrataWizardModal key="bulk-errata-wizard-modal" />, 300);
|
101
|
+
addGlobalFill('_all-hosts-modals', 'BulkRepositorySetsWizardModal', <BulkRepositorySetsWizardModal key="bulk-repo-sets-wizard-modal" />, 400);
|
100
102
|
|
101
103
|
registerColumns(hostsIndexColumnExtensions);
|
102
104
|
registerGetActions({
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
4
|
+
import { Modal, ModalVariant } from '@patternfly/react-core';
|
5
|
+
import FlatpakRemotesForm from './FlatpakRemoteform';
|
6
|
+
|
7
|
+
const CreateFlatpakModal = ({ show, setIsOpen }) => (
|
8
|
+
<Modal
|
9
|
+
ouiaId="create-flatpak-modal"
|
10
|
+
title={__('Create Flatpak Remote')}
|
11
|
+
variant={ModalVariant.small}
|
12
|
+
isOpen={show}
|
13
|
+
onClose={() => { setIsOpen(false); }}
|
14
|
+
appendTo={document.body}
|
15
|
+
>
|
16
|
+
<FlatpakRemotesForm setModalOpen={setIsOpen} />
|
17
|
+
</Modal>
|
18
|
+
);
|
19
|
+
|
20
|
+
CreateFlatpakModal.propTypes = {
|
21
|
+
show: PropTypes.bool,
|
22
|
+
setIsOpen: PropTypes.func,
|
23
|
+
};
|
24
|
+
|
25
|
+
CreateFlatpakModal.defaultProps = {
|
26
|
+
show: false,
|
27
|
+
setIsOpen: null,
|
28
|
+
};
|
29
|
+
|
30
|
+
export default CreateFlatpakModal;
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
4
|
+
import { Modal, ModalVariant } from '@patternfly/react-core';
|
5
|
+
import FlatpakRemotesForm from './FlatpakRemoteform';
|
6
|
+
|
7
|
+
const EditFlatpakModal = ({ show, setIsOpen, remoteData }) => (
|
8
|
+
<Modal
|
9
|
+
ouiaId="edit-flatpak-modal"
|
10
|
+
title={__('Edit Flatpak Remote')}
|
11
|
+
variant={ModalVariant.small}
|
12
|
+
isOpen={show}
|
13
|
+
onClose={() => { setIsOpen(false); }}
|
14
|
+
appendTo={document.body}
|
15
|
+
>
|
16
|
+
<FlatpakRemotesForm setModalOpen={setIsOpen} remoteData={remoteData} />
|
17
|
+
</Modal>
|
18
|
+
);
|
19
|
+
|
20
|
+
EditFlatpakModal.propTypes = {
|
21
|
+
show: PropTypes.bool,
|
22
|
+
setIsOpen: PropTypes.func,
|
23
|
+
remoteData: PropTypes.shape({
|
24
|
+
id: PropTypes.number,
|
25
|
+
name: PropTypes.string,
|
26
|
+
url: PropTypes.string,
|
27
|
+
username: PropTypes.string,
|
28
|
+
password: PropTypes.string,
|
29
|
+
}),
|
30
|
+
};
|
31
|
+
|
32
|
+
EditFlatpakModal.defaultProps = {
|
33
|
+
show: false,
|
34
|
+
setIsOpen: null,
|
35
|
+
remoteData: null,
|
36
|
+
};
|
37
|
+
|
38
|
+
export default EditFlatpakModal;
|
@@ -0,0 +1,218 @@
|
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import useDeepCompareEffect from 'use-deep-compare-effect';
|
3
|
+
import { STATUS } from 'foremanReact/constants';
|
4
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
5
|
+
import PropTypes from 'prop-types';
|
6
|
+
import { useDispatch, useSelector } from 'react-redux';
|
7
|
+
import {
|
8
|
+
Form,
|
9
|
+
FormGroup,
|
10
|
+
TextInput,
|
11
|
+
ActionGroup,
|
12
|
+
Button,
|
13
|
+
FormHelperText,
|
14
|
+
HelperText,
|
15
|
+
HelperTextItem,
|
16
|
+
|
17
|
+
} from '@patternfly/react-core';
|
18
|
+
import { createFlatpakRemote } from '../FlatpakRemotesActions';
|
19
|
+
import {
|
20
|
+
selectCreateFlatpakRemotes,
|
21
|
+
selectCreateFlatpakRemotesStatus,
|
22
|
+
selectCreateFlatpakRemotesError,
|
23
|
+
} from '../FlatpakRemotesSelectors';
|
24
|
+
import { updateFlatpakRemote } from '../Details/FlatpakRemoteDetailActions';
|
25
|
+
|
26
|
+
// eslint-disable-next-line react/prop-types
|
27
|
+
const FlatpakRemotesForm = ({ setModalOpen, remoteData }) => {
|
28
|
+
const {
|
29
|
+
id: editingId,
|
30
|
+
name: editingName,
|
31
|
+
url: editingUrl,
|
32
|
+
username: editingUsername,
|
33
|
+
upstream_password_exists: passwordExists,
|
34
|
+
} = remoteData || {};
|
35
|
+
|
36
|
+
const isEditing = !!editingName;
|
37
|
+
const dispatch = useDispatch();
|
38
|
+
const [name, setName] = useState(editingName || '');
|
39
|
+
const [url, setUrl] = useState(editingUrl || '');
|
40
|
+
const [username, setUsername] = useState(editingUsername || '');
|
41
|
+
const [password, setPassword] = useState(passwordExists ? '*****' : '');
|
42
|
+
const [redirect, setRedirect] = useState(false);
|
43
|
+
const [saving, setSaving] = useState(false);
|
44
|
+
|
45
|
+
const [urlValidated, setUrlValidated] = useState('default');
|
46
|
+
const handleUrlChange = (newurl, _event) => {
|
47
|
+
setUrl(newurl);
|
48
|
+
if (newurl === '') {
|
49
|
+
setUrlValidated('default');
|
50
|
+
} else if (/^(http(s)?:\/\/)[-a-zA-Z0-9@:%._~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_.~#?&//=]*)$/g.test(newurl)) {
|
51
|
+
setUrlValidated('success');
|
52
|
+
} else {
|
53
|
+
setUrlValidated('error');
|
54
|
+
}
|
55
|
+
};
|
56
|
+
|
57
|
+
const response = useSelector(selectCreateFlatpakRemotes);
|
58
|
+
const status = useSelector(selectCreateFlatpakRemotesStatus);
|
59
|
+
const error = useSelector(selectCreateFlatpakRemotesError);
|
60
|
+
|
61
|
+
useDeepCompareEffect(() => {
|
62
|
+
const { id } = response;
|
63
|
+
if (id && status === STATUS.RESOLVED && saving) {
|
64
|
+
setSaving(false);
|
65
|
+
setRedirect(true);
|
66
|
+
} else if (status === STATUS.ERROR) {
|
67
|
+
setSaving(false);
|
68
|
+
}
|
69
|
+
}, [response, status, error, saving]);
|
70
|
+
|
71
|
+
const onSave = () => {
|
72
|
+
setSaving(true);
|
73
|
+
let editingParams = {};
|
74
|
+
if (isEditing && password === '*****') {
|
75
|
+
editingParams = {
|
76
|
+
name,
|
77
|
+
url,
|
78
|
+
username,
|
79
|
+
};
|
80
|
+
} else {
|
81
|
+
editingParams = {
|
82
|
+
name,
|
83
|
+
url,
|
84
|
+
username,
|
85
|
+
token: password,
|
86
|
+
};
|
87
|
+
}
|
88
|
+
dispatch(isEditing ?
|
89
|
+
updateFlatpakRemote(
|
90
|
+
editingId, editingParams, () => window.location.assign(`/flatpak_remotes/${editingId}`),
|
91
|
+
() => setModalOpen(false),
|
92
|
+
) :
|
93
|
+
createFlatpakRemote({
|
94
|
+
name,
|
95
|
+
url,
|
96
|
+
username,
|
97
|
+
token: password,
|
98
|
+
}));
|
99
|
+
};
|
100
|
+
|
101
|
+
if (redirect) {
|
102
|
+
const { id } = response;
|
103
|
+
window.location.assign(`/flatpak_remotes/${id}`);
|
104
|
+
}
|
105
|
+
|
106
|
+
const submitDisabled =
|
107
|
+
!name?.length || !url?.length || saving || redirect || urlValidated === 'error';
|
108
|
+
|
109
|
+
return (
|
110
|
+
<Form
|
111
|
+
onSubmit={(e) => {
|
112
|
+
e.preventDefault();
|
113
|
+
onSave();
|
114
|
+
}}
|
115
|
+
id="create-flatpak-form"
|
116
|
+
>
|
117
|
+
<FormGroup
|
118
|
+
label={__('Name')}
|
119
|
+
isRequired
|
120
|
+
fieldId="name"
|
121
|
+
>
|
122
|
+
<TextInput
|
123
|
+
isRequired
|
124
|
+
type="text"
|
125
|
+
id="name"
|
126
|
+
aria-label="input_name"
|
127
|
+
ouiaId="input_name"
|
128
|
+
name="name"
|
129
|
+
value={name}
|
130
|
+
onChange={(_event, value) => setName(value)}
|
131
|
+
/>
|
132
|
+
</FormGroup>
|
133
|
+
<FormGroup
|
134
|
+
label={__('URL')}
|
135
|
+
isRequired
|
136
|
+
fieldId="url"
|
137
|
+
>
|
138
|
+
<TextInput
|
139
|
+
isRequired
|
140
|
+
type="url"
|
141
|
+
id="url"
|
142
|
+
aria-label="input_url"
|
143
|
+
ouiaId="input_url"
|
144
|
+
name="url"
|
145
|
+
value={url}
|
146
|
+
validated={urlValidated}
|
147
|
+
onChange={(_event, newurl) => handleUrlChange(newurl, _event)}
|
148
|
+
/>
|
149
|
+
{urlValidated === 'error' && (
|
150
|
+
<FormHelperText>
|
151
|
+
<HelperText>
|
152
|
+
<HelperTextItem variant="error">
|
153
|
+
{__('Must be a vaild URL')}
|
154
|
+
</HelperTextItem>
|
155
|
+
</HelperText>
|
156
|
+
</FormHelperText>
|
157
|
+
)}
|
158
|
+
</FormGroup>
|
159
|
+
<FormGroup label={__('Username')} fieldId="username">
|
160
|
+
<TextInput
|
161
|
+
type="text"
|
162
|
+
id="username"
|
163
|
+
ouiaId="input_username"
|
164
|
+
name="username"
|
165
|
+
aria-label="input_username"
|
166
|
+
value={username}
|
167
|
+
onChange={(_event, value) => setUsername(value)}
|
168
|
+
/>
|
169
|
+
<FormHelperText>
|
170
|
+
<HelperText>
|
171
|
+
<HelperTextItem>Authentication for registry</HelperTextItem>
|
172
|
+
</HelperText>
|
173
|
+
</FormHelperText>
|
174
|
+
</FormGroup>
|
175
|
+
<FormGroup label={__('Password')} fieldId="password">
|
176
|
+
<TextInput
|
177
|
+
type="password"
|
178
|
+
id="password"
|
179
|
+
ouiaId="input_password"
|
180
|
+
name="password"
|
181
|
+
aria-label="input_password"
|
182
|
+
value={password}
|
183
|
+
onChange={(_event, value) => setPassword(value)}
|
184
|
+
/>
|
185
|
+
</FormGroup>
|
186
|
+
|
187
|
+
<ActionGroup>
|
188
|
+
<Button
|
189
|
+
ouiaId="create-flatpak-form-submit"
|
190
|
+
aria-label="create_flatpak"
|
191
|
+
variant="primary"
|
192
|
+
isDisabled={submitDisabled}
|
193
|
+
isLoading={saving || redirect}
|
194
|
+
type="submit"
|
195
|
+
>
|
196
|
+
{isEditing ? __('Update') : __('Create')}
|
197
|
+
</Button>
|
198
|
+
<Button
|
199
|
+
ouiaId="create-flatpakcancel"
|
200
|
+
variant="link"
|
201
|
+
onClick={() => setModalOpen(false)}
|
202
|
+
>
|
203
|
+
{__('Cancel')}
|
204
|
+
</Button>
|
205
|
+
</ActionGroup>
|
206
|
+
</Form>
|
207
|
+
);
|
208
|
+
};
|
209
|
+
|
210
|
+
FlatpakRemotesForm.propTypes = {
|
211
|
+
setModalOpen: PropTypes.func,
|
212
|
+
};
|
213
|
+
|
214
|
+
FlatpakRemotesForm.defaultProps = {
|
215
|
+
setModalOpen: null,
|
216
|
+
};
|
217
|
+
|
218
|
+
export default FlatpakRemotesForm;
|
@@ -0,0 +1,117 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { renderWithRedux, patientlyWaitFor, fireEvent } from 'react-testing-lib-wrapper';
|
3
|
+
import { nockInstance, assertNockRequest } from '../../../../test-utils/nockWrapper';
|
4
|
+
import FlatpakRemotesForm from '../FlatpakRemoteform';
|
5
|
+
import api from '../../../../services/api';
|
6
|
+
|
7
|
+
const mockFn = jest.fn();
|
8
|
+
delete window.location;
|
9
|
+
window.location = { assign: mockFn };
|
10
|
+
|
11
|
+
afterEach(() => {
|
12
|
+
mockFn.mockClear();
|
13
|
+
});
|
14
|
+
|
15
|
+
const createFlatpakPath = api.getApiUrl('/flatpak_remotes');
|
16
|
+
const updateFlatpakPath = id => api.getApiUrl(`/flatpak_remotes/${id}`);
|
17
|
+
|
18
|
+
const mockRemoteData = {
|
19
|
+
id: 1,
|
20
|
+
name: 'Test Remote',
|
21
|
+
url: 'https://example.com',
|
22
|
+
username: 'testuser',
|
23
|
+
upstream_password_exists: true,
|
24
|
+
};
|
25
|
+
|
26
|
+
test('Renders FlatpakRemotesForm fields correctly', () => {
|
27
|
+
const { getByText } = renderWithRedux(<FlatpakRemotesForm setModalOpen={mockFn} />);
|
28
|
+
expect(getByText('Name')).toBeInTheDocument();
|
29
|
+
expect(getByText('URL')).toBeInTheDocument();
|
30
|
+
expect(getByText('Username')).toBeInTheDocument();
|
31
|
+
expect(getByText('Password')).toBeInTheDocument();
|
32
|
+
});
|
33
|
+
|
34
|
+
test('Can save Flatpak remote from form', async (done) => {
|
35
|
+
const createScope = nockInstance
|
36
|
+
.post(createFlatpakPath, {
|
37
|
+
organization_id: 1,
|
38
|
+
name: 'New Remote',
|
39
|
+
url: 'https://example.com',
|
40
|
+
username: 'testuser',
|
41
|
+
token: 'password123',
|
42
|
+
})
|
43
|
+
.reply(201, { id: 2 });
|
44
|
+
|
45
|
+
const { getByLabelText, getByText } = renderWithRedux(<FlatpakRemotesForm
|
46
|
+
setModalOpen={mockFn}
|
47
|
+
/>);
|
48
|
+
fireEvent.change(getByLabelText('input_name'), { target: { value: 'New Remote' } });
|
49
|
+
fireEvent.change(getByLabelText('input_url'), { target: { value: 'https://example.com' } });
|
50
|
+
fireEvent.change(getByLabelText('input_username'), { target: { value: 'testuser' } });
|
51
|
+
fireEvent.change(getByLabelText('input_password'), { target: { value: 'password123' } });
|
52
|
+
|
53
|
+
getByText('Create').click();
|
54
|
+
|
55
|
+
await patientlyWaitFor(() => {
|
56
|
+
expect(window.location.assign).toHaveBeenCalledWith('/flatpak_remotes/2');
|
57
|
+
});
|
58
|
+
|
59
|
+
assertNockRequest(createScope);
|
60
|
+
done();
|
61
|
+
});
|
62
|
+
|
63
|
+
test('Can update Flatpak remote from form', async (done) => {
|
64
|
+
const updateScope = nockInstance
|
65
|
+
.put(updateFlatpakPath(mockRemoteData.id), {
|
66
|
+
name: 'Updated Remote',
|
67
|
+
url: 'https://updated.com',
|
68
|
+
username: 'updateduser',
|
69
|
+
})
|
70
|
+
.reply(200);
|
71
|
+
|
72
|
+
const { getByLabelText, getByText } = renderWithRedux(<FlatpakRemotesForm
|
73
|
+
setModalOpen={mockFn}
|
74
|
+
remoteData={mockRemoteData}
|
75
|
+
/>);
|
76
|
+
|
77
|
+
fireEvent.change(getByLabelText('input_name'), { target: { value: 'Updated Remote' } });
|
78
|
+
fireEvent.change(getByLabelText('input_url'), { target: { value: 'https://updated.com' } });
|
79
|
+
fireEvent.change(getByLabelText('input_username'), { target: { value: 'updateduser' } });
|
80
|
+
|
81
|
+
getByText('Update').click();
|
82
|
+
|
83
|
+
await patientlyWaitFor(() => {
|
84
|
+
expect(window.location.assign).toHaveBeenCalledWith('/flatpak_remotes/1');
|
85
|
+
});
|
86
|
+
|
87
|
+
assertNockRequest(updateScope);
|
88
|
+
done();
|
89
|
+
});
|
90
|
+
|
91
|
+
test('Can update Flatpak remote password from placeholder', async (done) => {
|
92
|
+
const updateScope = nockInstance
|
93
|
+
.put(updateFlatpakPath(mockRemoteData.id), {
|
94
|
+
name: mockRemoteData.name,
|
95
|
+
url: mockRemoteData.url,
|
96
|
+
username: mockRemoteData.username,
|
97
|
+
token: 'newpassword123',
|
98
|
+
})
|
99
|
+
.reply(200);
|
100
|
+
|
101
|
+
const { getByLabelText, getByText } = renderWithRedux(<FlatpakRemotesForm
|
102
|
+
setModalOpen={mockFn}
|
103
|
+
remoteData={mockRemoteData}
|
104
|
+
/>);
|
105
|
+
|
106
|
+
// Simulate changing the password from the placeholder to a new value
|
107
|
+
fireEvent.change(getByLabelText('input_password'), { target: { value: 'newpassword123' } });
|
108
|
+
|
109
|
+
getByText('Update').click();
|
110
|
+
|
111
|
+
await patientlyWaitFor(() => {
|
112
|
+
expect(window.location.assign).toHaveBeenCalledWith('/flatpak_remotes/1');
|
113
|
+
});
|
114
|
+
|
115
|
+
assertNockRequest(updateScope);
|
116
|
+
done();
|
117
|
+
});
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { useDispatch } from 'react-redux';
|
3
|
+
import PropTypes from 'prop-types';
|
4
|
+
import { Modal, ModalVariant, Button, Icon, Title, Flex } from '@patternfly/react-core';
|
5
|
+
import { ExclamationTriangleIcon } from '@patternfly/react-icons';
|
6
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
7
|
+
import { deleteFlatpakRemote } from '../Details/FlatpakRemoteDetailActions';
|
8
|
+
|
9
|
+
const DeleteFlatpakModal = ({ isModalOpen, handleModalToggle, remoteId }) => {
|
10
|
+
const dispatch = useDispatch();
|
11
|
+
|
12
|
+
const handleDelete = () => {
|
13
|
+
dispatch(deleteFlatpakRemote(remoteId, () => window.location.replace('/flatpak_remotes')));
|
14
|
+
handleModalToggle();
|
15
|
+
};
|
16
|
+
|
17
|
+
return (
|
18
|
+
<Modal
|
19
|
+
ouiaId="flatpak-delete-modal"
|
20
|
+
variant={ModalVariant.small}
|
21
|
+
title={[
|
22
|
+
<Flex key="delete-modal-header">
|
23
|
+
<Icon status="warning" key="exclamation-triangle">
|
24
|
+
<ExclamationTriangleIcon />
|
25
|
+
</Icon>
|
26
|
+
<Title ouiaId="flatpak-delete-header" key="delete-flatpak-title" headingLevel="h5" size="2xl">
|
27
|
+
{__('Delete Flatpak remote?')}
|
28
|
+
</Title>
|
29
|
+
</Flex>,
|
30
|
+
]}
|
31
|
+
isOpen={isModalOpen}
|
32
|
+
onClose={handleModalToggle}
|
33
|
+
actions={[
|
34
|
+
<Button ouiaId="delete-button" key="delete" variant="danger" onClick={handleDelete}>
|
35
|
+
{__('Delete')}
|
36
|
+
</Button>,
|
37
|
+
<Button ouiaId="cancel-button" key="cancel" variant="link" onClick={handleModalToggle}>
|
38
|
+
{__('Cancel')}
|
39
|
+
</Button>,
|
40
|
+
]}
|
41
|
+
>
|
42
|
+
{__('This Flatpak remote will be deleted. Repositories mirrored from this remote will remain available and functional for use')}
|
43
|
+
</Modal>
|
44
|
+
);
|
45
|
+
};
|
46
|
+
|
47
|
+
DeleteFlatpakModal.propTypes = {
|
48
|
+
isModalOpen: PropTypes.bool,
|
49
|
+
handleModalToggle: PropTypes.func,
|
50
|
+
remoteId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
51
|
+
};
|
52
|
+
|
53
|
+
DeleteFlatpakModal.defaultProps = {
|
54
|
+
isModalOpen: false,
|
55
|
+
handleModalToggle: () => {},
|
56
|
+
remoteId: undefined,
|
57
|
+
};
|
58
|
+
|
59
|
+
export default DeleteFlatpakModal;
|