katello 4.6.2.1 → 4.7.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.

Files changed (333) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/common/vendor.js +0 -1
  3. data/app/controllers/katello/api/v2/activation_keys_controller.rb +1 -0
  4. data/app/controllers/katello/api/v2/alternate_content_sources_controller.rb +4 -4
  5. data/app/controllers/katello/api/v2/capsule_content_controller.rb +5 -0
  6. data/app/controllers/katello/api/v2/content_imports_controller.rb +1 -0
  7. data/app/controllers/katello/api/v2/content_view_components_controller.rb +1 -1
  8. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +2 -1
  9. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +1 -1
  10. data/app/controllers/katello/api/v2/organizations_controller.rb +1 -0
  11. data/app/controllers/katello/api/v2/repositories_controller.rb +78 -12
  12. data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +1 -1
  13. data/app/controllers/katello/concerns/api/v2/registration_controller_extensions.rb +7 -1
  14. data/app/controllers/katello/concerns/api/v2/smart_proxies_controller_extensions.rb +1 -0
  15. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +11 -9
  16. data/app/helpers/katello/content_source_helper.rb +9 -0
  17. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +31 -0
  18. data/app/lib/actions/katello/activation_key/destroy.rb +1 -0
  19. data/app/lib/actions/katello/agent_action.rb +1 -0
  20. data/app/lib/actions/katello/alternate_content_source/create.rb +1 -1
  21. data/app/lib/actions/katello/alternate_content_source/update.rb +2 -2
  22. data/app/lib/actions/katello/capsule_content/sync.rb +10 -2
  23. data/app/lib/actions/katello/cdn_configuration/update.rb +1 -1
  24. data/app/lib/actions/katello/content_view/promote.rb +1 -0
  25. data/app/lib/actions/katello/content_view/publish.rb +5 -2
  26. data/app/lib/actions/katello/content_view_version/auto_create_redhat_repositories.rb +7 -3
  27. data/app/lib/actions/katello/content_view_version/auto_create_repositories.rb +4 -2
  28. data/app/lib/actions/katello/content_view_version/import.rb +22 -10
  29. data/app/lib/actions/katello/product/destroy.rb +1 -1
  30. data/app/lib/actions/katello/repository/destroy.rb +3 -3
  31. data/app/lib/actions/katello/repository/errata_mail.rb +9 -6
  32. data/app/lib/actions/katello/repository/refresh_repository.rb +1 -1
  33. data/app/lib/actions/katello/repository/sync.rb +13 -6
  34. data/app/lib/actions/katello/repository_set/enable_repository.rb +6 -2
  35. data/app/lib/actions/pulp3/alternate_content_source/refresh_remote.rb +16 -0
  36. data/app/lib/actions/pulp3/orchestration/alternate_content_source/refresh.rb +1 -0
  37. data/app/lib/actions/pulp3/orchestration/content_view_version/export_library.rb +1 -1
  38. data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +10 -2
  39. data/app/lib/katello/concerns/renderer_extensions.rb +2 -1
  40. data/app/lib/katello/errors.rb +2 -2
  41. data/app/lib/katello/resources/candlepin.rb +7 -1
  42. data/app/lib/katello/resources/cdn/katello_cdn.rb +3 -13
  43. data/app/lib/katello/resources/cdn.rb +14 -9
  44. data/app/lib/katello/util/candlepin_repository_checker.rb +73 -0
  45. data/app/models/katello/activation_key.rb +12 -1
  46. data/app/models/katello/alternate_content_source.rb +15 -4
  47. data/app/models/katello/alternate_content_source_product.rb +1 -1
  48. data/app/models/katello/authorization/repository.rb +2 -2
  49. data/app/models/katello/cdn_configuration.rb +12 -3
  50. data/app/models/katello/concerns/host_managed_extensions.rb +15 -2
  51. data/app/models/katello/concerns/http_proxy_extensions.rb +5 -10
  52. data/app/models/katello/concerns/smart_proxy_extensions.rb +30 -15
  53. data/app/models/katello/content.rb +15 -0
  54. data/app/models/katello/content_credential.rb +8 -9
  55. data/app/models/katello/content_view.rb +7 -3
  56. data/app/models/katello/content_view_component.rb +4 -0
  57. data/app/models/katello/content_view_version.rb +1 -1
  58. data/app/models/katello/erratum.rb +6 -2
  59. data/app/models/katello/host/content_facet.rb +13 -3
  60. data/app/models/katello/repository.rb +15 -1
  61. data/app/models/katello/root_repository.rb +0 -2
  62. data/app/overrides/add_smart_proxy_form.rb +5 -0
  63. data/app/presenters/katello/content_view_version_compare_presenter.rb +5 -0
  64. data/app/presenters/katello/host_package_presenter.rb +4 -4
  65. data/app/services/katello/pulp3/alternate_content_source.rb +23 -15
  66. data/app/services/katello/pulp3/ansible_collection.rb +7 -10
  67. data/app/services/katello/pulp3/content_view_version/export.rb +19 -6
  68. data/app/services/katello/pulp3/content_view_version/import.rb +2 -0
  69. data/app/services/katello/pulp3/content_view_version/import_validator.rb +21 -5
  70. data/app/services/katello/pulp3/content_view_version/importable_products.rb +11 -1
  71. data/app/services/katello/pulp3/content_view_version/importable_repositories.rb +38 -9
  72. data/app/services/katello/pulp3/content_view_version/metadata_generator.rb +12 -5
  73. data/app/services/katello/pulp3/content_view_version/metadata_map.rb +13 -2
  74. data/app/services/katello/pulp3/content_view_version/syncable_format_export.rb +5 -1
  75. data/app/services/katello/pulp3/pulp_content_unit.rb +3 -0
  76. data/app/services/katello/pulp3/repository.rb +18 -6
  77. data/app/services/katello/pulp3/repository_mirror.rb +0 -1
  78. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +2 -2
  79. data/app/services/katello/pulp3/task_group.rb +18 -1
  80. data/app/services/katello/repository_type.rb +5 -2
  81. data/app/services/katello/repository_type_manager.rb +4 -3
  82. data/app/views/dashboard/_content_views_widget.html.erb +1 -1
  83. data/app/views/foreman/job_templates/change_content_source.erb +6 -0
  84. data/app/views/foreman/job_templates/update_packages_by_search_query.erb +7 -1
  85. data/app/views/katello/api/v2/alternate_content_sources/base.json.rabl +4 -4
  86. data/app/views/katello/api/v2/alternate_content_sources/index.json.rabl +1 -0
  87. data/app/views/katello/api/v2/alternate_content_sources/permissions.rabl +11 -0
  88. data/app/views/katello/api/v2/content_credentials/show.json.rabl +12 -0
  89. data/app/views/katello/api/v2/content_views/permissions.rabl +1 -0
  90. data/app/views/katello/api/v2/host_packages/base.json.rabl +1 -1
  91. data/app/views/katello/api/v2/module_streams/show.json.rabl +7 -0
  92. data/app/views/katello/api/v2/repositories/compare.json.rabl +10 -0
  93. data/app/views/katello/api/v2/smart_proxies/pulp_info.json.rabl +1 -0
  94. data/app/views/katello/hosts/_errata_counts.html.erb +46 -0
  95. data/app/views/overrides/activation_keys/_host_synced_content_select.html.erb +1 -0
  96. data/app/views/overrides/smart_proxies/_acs_http_proxy.html.erb +6 -0
  97. data/config/initializers/monkeys.rb +1 -0
  98. data/config/routes/api/v2.rb +2 -0
  99. data/config/routes.rb +3 -0
  100. data/db/migrate/20220730033504_update_custom_cdn.rb +13 -0
  101. data/db/migrate/20220920173656_add_http_proxy_to_smart_proxy.rb +7 -0
  102. data/db/migrate/20220920180858_remove_http_proxy_from_katello_alternate_content_sources.rb +6 -0
  103. data/engines/bastion/app/assets/javascripts/bastion/components/notification.service.js +1 -1
  104. data/engines/bastion/app/views/bastion/layouts/assets.html.erb +5 -5
  105. data/engines/bastion/vendor/assets/javascripts/bastion/angular/angular.js +1 -1
  106. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credential.factory.js +17 -0
  107. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credentials.routes.js +10 -0
  108. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-acs.controller.js +36 -0
  109. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-details.controller.js +7 -1
  110. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/views/content-credential-acs.html +38 -0
  111. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/views/content-credential-details.html +3 -0
  112. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/views/content-credentials.html +7 -2
  113. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +4 -2
  114. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +1 -1
  115. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +4 -3
  116. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +14 -1392
  117. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/katello-features.run.js +1 -0
  118. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +7 -0
  119. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +1 -1
  120. data/lib/katello/permission_creator.rb +1 -0
  121. data/lib/katello/plugin.rb +34 -11
  122. data/lib/katello/repository_types/deb.rb +1 -1
  123. data/lib/katello/repository_types/docker.rb +1 -1
  124. data/lib/katello/repository_types/python.rb +3 -3
  125. data/lib/katello/tasks/check_candlepin_content.rake +16 -0
  126. data/lib/katello/tasks/reset.rake +1 -1
  127. data/lib/katello/version.rb +1 -1
  128. data/lib/monkeys/try_pulp_container_path.rb +35 -0
  129. data/locale/action_names.rb +7 -7
  130. data/locale/bn/katello.po +395 -63
  131. data/locale/cs/katello.po +396 -64
  132. data/locale/de/katello.po +399 -67
  133. data/locale/en/katello.po +395 -63
  134. data/locale/es/katello.po +399 -67
  135. data/locale/fr/katello.po +400 -68
  136. data/locale/gu/katello.po +395 -63
  137. data/locale/hi/katello.po +395 -63
  138. data/locale/it/katello.po +396 -64
  139. data/locale/ja/katello.po +400 -68
  140. data/locale/katello.pot +1916 -1213
  141. data/locale/kn/katello.po +395 -63
  142. data/locale/ko/katello.po +396 -64
  143. data/locale/mr/katello.po +395 -63
  144. data/locale/or/katello.po +395 -63
  145. data/locale/pa/katello.po +395 -63
  146. data/locale/pt/katello.po +395 -63
  147. data/locale/pt_BR/katello.po +399 -67
  148. data/locale/ru/katello.po +396 -64
  149. data/locale/ta/katello.po +395 -63
  150. data/locale/te/katello.po +395 -63
  151. data/locale/zh_CN/katello.po +400 -68
  152. data/locale/zh_TW/katello.po +396 -64
  153. data/webpack/components/Bookmark/index.js +5 -1
  154. data/webpack/components/Content/Details/ContentDetails.js +1 -1
  155. data/webpack/components/Content/Details/__tests__/__snapshots__/ContentDetails.test.js.snap +6 -0
  156. data/webpack/components/EditableSwitch.js +1 -0
  157. data/webpack/components/EditableTextInput/EditableTextInput.js +3 -3
  158. data/webpack/components/Errata/errataHelpers.js +33 -0
  159. data/webpack/components/Errata/index.js +45 -12
  160. data/webpack/components/Loading.js +18 -8
  161. data/webpack/components/Packages/index.js +8 -24
  162. data/webpack/components/RoutedTabs/index.js +1 -0
  163. data/webpack/components/Search/Search.js +20 -2
  164. data/webpack/components/Search/__tests__/search.test.js +3 -3
  165. data/webpack/components/Table/EmptyStateMessage.js +1 -1
  166. data/webpack/components/Table/PageControls.js +1 -0
  167. data/webpack/components/Table/TableHooks.js +4 -0
  168. data/webpack/components/Table/TableWrapper.js +7 -7
  169. data/webpack/components/TypeAhead/pf4Search/TypeAheadInput.js +1 -0
  170. data/webpack/components/TypeAhead/pf4Search/TypeAheadItems.js +2 -0
  171. data/webpack/components/TypeAhead/pf4Search/TypeAheadSearch.js +1 -1
  172. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ChangeHostCVModal.js +3 -1
  173. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +2 -1
  174. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.js +124 -68
  175. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.scss +5 -0
  176. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.js +30 -4
  177. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.scss +23 -0
  178. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsModal.js +5 -4
  179. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/hostCollectionsCard.test.js +25 -10
  180. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.js +3 -3
  181. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeEditModal.js +6 -0
  182. data/webpack/components/extensions/HostDetails/Cards/__tests__/errataOverviewCard.test.js +145 -32
  183. data/webpack/components/extensions/HostDetails/DetailsTabCards/RegistrationCard.js +3 -1
  184. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/constants.js +2 -1
  185. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/index.js +1 -0
  186. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +78 -26
  187. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +23 -10
  188. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/HostPackagesConstants.js +1 -0
  189. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +9 -4
  190. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +141 -23
  191. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.scss +6 -1
  192. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +9 -8
  193. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +24 -3
  194. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.js +7 -2
  195. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesEnabler.js +2 -1
  196. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js +20 -4
  197. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +56 -38
  198. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packages.fixtures.json +3 -3
  199. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +5 -4
  200. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +3 -3
  201. data/webpack/containers/Application/config.js +2 -2
  202. data/webpack/containers/Application/overrides.scss +12 -0
  203. data/webpack/global_test_setup.js +19 -1
  204. data/webpack/ouia_id_check.js +0 -2
  205. data/webpack/redux/actions/RedHatRepositories/helpers.js +4 -8
  206. data/webpack/scenes/AlternateContentSources/ACSActions.js +37 -6
  207. data/webpack/scenes/AlternateContentSources/ACSConstants.js +2 -0
  208. data/webpack/scenes/AlternateContentSources/ACSIndexPage.js +1 -1
  209. data/webpack/scenes/AlternateContentSources/ACSSelectors.js +6 -6
  210. data/webpack/scenes/AlternateContentSources/Acs.scss +3 -0
  211. data/webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js +24 -3
  212. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js +10 -8
  213. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCredentials.js +25 -4
  214. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSReview.js +22 -11
  215. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSSmartProxies.js +27 -2
  216. data/webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js +49 -17
  217. data/webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js +76 -23
  218. data/webpack/scenes/AlternateContentSources/Create/__tests__/acsCreate.test.js +159 -11
  219. data/webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js +83 -29
  220. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditCredentials.js +9 -8
  221. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditDetails.js +2 -2
  222. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditProducts.js +2 -2
  223. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditSmartProxies.js +39 -7
  224. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditURLPaths.js +27 -11
  225. data/webpack/scenes/AlternateContentSources/Details/__tests__/ACSEdits.test.js +58 -55
  226. data/webpack/scenes/AlternateContentSources/Details/__tests__/ACSExpandableDetails.test.js +35 -32
  227. data/webpack/scenes/AlternateContentSources/MainTable/ACSTable.js +323 -150
  228. data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsIndex.fixtures.json +5 -1
  229. data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsTable.test.js +10 -11
  230. data/webpack/scenes/AlternateContentSources/helpers.js +26 -0
  231. data/webpack/scenes/ContentViews/ContentViewsConstants.js +1 -0
  232. data/webpack/scenes/ContentViews/ContentViewsPage.js +1 -1
  233. data/webpack/scenes/ContentViews/Copy/CopyContentViewForm.js +1 -0
  234. data/webpack/scenes/ContentViews/Copy/CopyContentViewModal.js +1 -0
  235. data/webpack/scenes/ContentViews/Create/ContentViewFormComponents.js +10 -5
  236. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +30 -7
  237. data/webpack/scenes/ContentViews/Create/CreateContentViewModal.js +1 -0
  238. data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +21 -6
  239. data/webpack/scenes/ContentViews/Delete/Steps/CVDeleteEnvironmentsSelection.js +3 -3
  240. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionReassignActivationKeysForm.js +1 -0
  241. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionReassignHostsForm.js +1 -0
  242. data/webpack/scenes/ContentViews/Delete/__tests__/CvData.fixtures.json +2 -0
  243. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +3 -0
  244. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +4 -1
  245. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentVersion.js +1 -1
  246. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +2 -1
  247. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +14 -0
  248. data/webpack/scenes/ContentViews/Details/ContentViewDetailSelectors.js +11 -1
  249. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +1 -1
  250. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +2 -0
  251. data/webpack/scenes/ContentViews/Details/Filters/Add/CVFilterAddModal.js +5 -0
  252. data/webpack/scenes/ContentViews/Details/Filters/AffectedRepositories/AffectedRepositorySelection.js +1 -0
  253. data/webpack/scenes/ContentViews/Details/Filters/ArtifactsWithNoErrata.js +1 -0
  254. data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +8 -2
  255. data/webpack/scenes/ContentViews/Details/Filters/CVDebFilterContent.js +5 -1
  256. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +22 -6
  257. data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +19 -9
  258. data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +9 -2
  259. data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +9 -2
  260. data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +8 -2
  261. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilterDetailsHeader.js +1 -1
  262. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilters.js +2 -1
  263. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/CVRpmMatchContentModal.js +3 -2
  264. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/__tests__/CVRpmMatchContentModal.test.js +1 -1
  265. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVContainerImageFilterContent.test.js +2 -2
  266. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js +1 -1
  267. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilterDetails.test.js +1 -1
  268. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilters.test.js +1 -1
  269. data/webpack/scenes/ContentViews/Details/Histories/ContentViewHistories.js +2 -2
  270. data/webpack/scenes/ContentViews/Details/Promote/ContentViewVersionPromote.js +2 -0
  271. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +2 -1
  272. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/ReviewEnvironments.js +3 -3
  273. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompare.js +9 -1
  274. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareConfig.js +83 -0
  275. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareTable.js +32 -8
  276. data/webpack/scenes/ContentViews/Details/Versions/Compare/__tests__/CVVersionCompare.test.js +56 -3
  277. data/webpack/scenes/ContentViews/Details/Versions/Compare/__tests__/cvCompareRepositories.fixtures.json +175 -0
  278. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +6 -2
  279. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVEnvironmentSelectionForm.js +3 -3
  280. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignActivationKeysForm.js +1 -0
  281. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignHostsForm.js +1 -0
  282. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +2 -2
  283. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +2 -2
  284. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailConfig.js +2 -2
  285. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +1 -0
  286. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js +4 -1
  287. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +5 -4
  288. data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +5 -1
  289. data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +3 -3
  290. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +10 -5
  291. data/webpack/scenes/ContentViews/__tests__/basicContentViews.fixtures.js +2 -0
  292. data/webpack/scenes/ContentViews/__tests__/contentViewList.fixtures.json +1 -0
  293. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +81 -19
  294. data/webpack/scenes/ContentViews/components/CVBreadCrumb.js +1 -1
  295. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.js +1 -0
  296. data/webpack/scenes/ContentViews/components/InactiveText.js +9 -1
  297. data/webpack/scenes/ContentViews/expansions/RelatedCompositeContentViewsModal.js +4 -2
  298. data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +3 -2
  299. data/webpack/scenes/Hosts/ChangeContentSource/actions.js +18 -11
  300. data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceForm.js +15 -8
  301. data/webpack/scenes/Hosts/ChangeContentSource/components/FormField.js +3 -4
  302. data/webpack/scenes/Hosts/ChangeContentSource/components/Hosts.js +55 -0
  303. data/webpack/scenes/Hosts/ChangeContentSource/components/HostsModal.js +59 -0
  304. data/webpack/scenes/Hosts/ChangeContentSource/constants.js +1 -0
  305. data/webpack/scenes/Hosts/ChangeContentSource/helpers.js +2 -5
  306. data/webpack/scenes/Hosts/ChangeContentSource/index.js +46 -41
  307. data/webpack/scenes/Hosts/ChangeContentSource/selectors.js +5 -5
  308. data/webpack/scenes/ModuleStreams/Details/ModuleDetailsSchema.js +10 -1
  309. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +1 -1
  310. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetails.test.js.snap +97 -2
  311. data/webpack/scenes/Organizations/OrganizationSelectors.js +1 -0
  312. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnConfigurationConstants.js +2 -1
  313. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnTypeForm.js +10 -25
  314. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CustomCdnTypeForm.js +154 -0
  315. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/ExportSyncForm.js +4 -4
  316. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/NetworkSyncForm.js +59 -44
  317. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/CdnTypeForm.test.js +3 -28
  318. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/CustomCdnTypeForm.test.js +97 -0
  319. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/ExportSyncForm.test.js +1 -1
  320. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/NetworkSyncForm.test.js +4 -4
  321. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/index.js +23 -10
  322. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +1 -1
  323. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +2 -1
  324. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +5 -5
  325. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +3 -3
  326. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +2 -2
  327. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +3 -3
  328. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +3 -3
  329. data/webpack/scenes/Tasks/helpers.js +14 -7
  330. metadata +54 -35
  331. data/app/lib/actions/pulp3/orchestration/alternate_content_source/refresh_remote.rb +0 -18
  332. data/db/migrate/20221206170122_update_ignore_srpm_to_false_for_mirror_complete.rb +0 -5
  333. data/vendor/assets/javascripts/katello/jquery.trunk8.js +0 -203
@@ -8,6 +8,8 @@ import ACS_KEY, {
8
8
  DELETE_ACS_KEY,
9
9
  EDIT_ACS_KEY,
10
10
  PRODUCTS_KEY,
11
+ BULK_ACS_REFRESH_KEY,
12
+ BULK_ACS_DELETE_KEY,
11
13
  } from './ACSConstants';
12
14
  import { getResponseErrorMsgs } from '../../utils/helpers';
13
15
  import { renderTaskStartedToast } from '../Tasks/helpers';
@@ -25,6 +27,7 @@ export const acsErrorToast = (error) => {
25
27
  export const createACSParams = (extraParams) => {
26
28
  const getParams = {
27
29
  organization_id: orgId(),
30
+ include_permissions: true,
28
31
  ...extraParams,
29
32
  };
30
33
  return getParams;
@@ -42,13 +45,15 @@ export const getACSDetails = (acsId, extraParams = {}) => get({
42
45
  key: acsDetailsKey(acsId),
43
46
  params: { organization_id: orgId(), include_permissions: true, ...extraParams },
44
47
  url: api.getApiUrl(`/alternate_content_sources/${acsId}`),
48
+ errorToast: error => acsErrorToast(error),
45
49
  });
46
50
 
47
- export const createACS = params => post({
51
+ export const createACS = (params, name, handleSuccess) => post({
48
52
  type: API_OPERATIONS.POST,
49
- key: CREATE_ACS_KEY,
53
+ key: CREATE_ACS_KEY + name,
50
54
  url: api.getApiUrl('/alternate_content_sources'),
51
55
  params,
56
+ handleSuccess,
52
57
  successToast: response => acsSuccessToast(response),
53
58
  errorToast: error => acsErrorToast(error),
54
59
  });
@@ -59,7 +64,7 @@ export const deleteACS = (acsId, handleSuccess) => APIActions.delete({
59
64
  url: api.getApiUrl(`/alternate_content_sources/${acsId}`),
60
65
  handleSuccess,
61
66
  successToast: () => __('Alternate content source deleted'),
62
- errorToast: error => __(`Something went wrong while deleting this alternate content source! ${getResponseErrorMsgs(error.response)}`),
67
+ errorToast: error => acsErrorToast(error),
63
68
  });
64
69
 
65
70
  export const refreshACS = (acsId, handleSuccess) => post({
@@ -68,10 +73,36 @@ export const refreshACS = (acsId, handleSuccess) => post({
68
73
  url: api.getApiUrl(`/alternate_content_sources/${acsId}/refresh`),
69
74
  params: { id: acsId },
70
75
  handleSuccess: (response) => {
71
- if (handleSuccess) handleSuccess();
76
+ if (handleSuccess) {
77
+ handleSuccess();
78
+ }
72
79
  return renderTaskStartedToast(response.data);
73
80
  },
74
- errorToast: error => __(`Something went wrong while refreshing this alternate content source! ${getResponseErrorMsgs(error.response)}`),
81
+ errorToast: error => acsErrorToast(error),
82
+ });
83
+
84
+ export const bulkRefreshACS = (params, handleSuccess) => post({
85
+ type: API_OPERATIONS.POST,
86
+ key: BULK_ACS_REFRESH_KEY,
87
+ url: api.getApiUrl('/alternate_content_sources/bulk/refresh'),
88
+ params,
89
+ handleSuccess: (response) => {
90
+ renderTaskStartedToast(response?.data, __('Bulk alternate content source refresh has started.'));
91
+ return handleSuccess();
92
+ },
93
+ errorToast: error => __('Something went wrong while refreshing alternate content sources: ') + getResponseErrorMsgs(error.response),
94
+ });
95
+
96
+ export const bulkDeleteACS = (params, handleSuccess) => APIActions.put({
97
+ type: API_OPERATIONS.PUT,
98
+ key: BULK_ACS_DELETE_KEY,
99
+ url: api.getApiUrl('/alternate_content_sources/bulk/destroy'),
100
+ params,
101
+ handleSuccess: (response) => {
102
+ renderTaskStartedToast(response?.data, __('Bulk alternate content source delete has started.'));
103
+ return handleSuccess();
104
+ },
105
+ errorToast: error => __(`Something went wrong while deleting alternate content sources: ${getResponseErrorMsgs(error.response)}`),
75
106
  });
76
107
 
77
108
  export const getProducts = () => get({
@@ -91,7 +122,7 @@ export const editACS = (acsId, params, handleSuccess, handleError) => APIActions
91
122
  handleSuccess,
92
123
  handleError,
93
124
  successToast: () => __('Alternate content source edited'),
94
- errorToast: error => __(`Something went wrong while editing the alternate content source! ${getResponseErrorMsgs(error.response)}`),
125
+ errorToast: error => acsErrorToast(error),
95
126
  });
96
127
 
97
128
  export default getAlternateContentSources;
@@ -7,6 +7,8 @@ export const DELETE_ACS_KEY = 'ACS_DELETE';
7
7
  export const SMART_PROXY_KEY = 'SMART_PROXY';
8
8
  export const PRODUCTS_KEY = 'PRODUCTS';
9
9
  export const SSL_CERTS = 'SSL_CERTS';
10
+ export const BULK_ACS_REFRESH_KEY = 'BULK_ACS_REFRESH';
11
+ export const BULK_ACS_DELETE_KEY = 'BULK_ACS_DELETE';
10
12
  export const acsRefreshKey = acsId => `${ACS_KEY}_REFRESH_${acsId}`;
11
13
  export const acsDetailsKey = acsId => `${ACS_KEY}_DETAILS_${acsId}`;
12
14
 
@@ -8,7 +8,7 @@ const ACSIndexPage = () => (
8
8
  <Grid className="margin-24">
9
9
  <GridItem span={12}>
10
10
  <TextContent>
11
- <Text component={TextVariants.h1}>{__('Alternate content sources')}</Text>
11
+ <Text component={TextVariants.h1}>{__('Alternate Content Sources')}</Text>
12
12
  </TextContent>
13
13
  </GridItem>
14
14
  </Grid>
@@ -10,14 +10,14 @@ export const selectAlternateContentSourcesStatus = (state, index = '') =>
10
10
  export const selectAlternateContentSourcesError = (state, index = '') =>
11
11
  selectAPIError(state, ACS_KEY + index);
12
12
 
13
- export const selectCreateACS = state =>
14
- selectAPIResponse(state, CREATE_ACS_KEY) || {};
13
+ export const selectCreateACS = (state, name) =>
14
+ selectAPIResponse(state, CREATE_ACS_KEY + name) || {};
15
15
 
16
- export const selectCreateACSStatus = state =>
17
- selectAPIStatus(state, CREATE_ACS_KEY) || STATUS.PENDING;
16
+ export const selectCreateACSStatus = (state, name) =>
17
+ selectAPIStatus(state, CREATE_ACS_KEY + name) || STATUS.PENDING;
18
18
 
19
- export const selectCreateACSError = state =>
20
- selectAPIError(state, CREATE_ACS_KEY);
19
+ export const selectCreateACSError = (state, name) =>
20
+ selectAPIError(state, CREATE_ACS_KEY + name);
21
21
 
22
22
  export const selectACSDetails = (state, acsId) =>
23
23
  selectAPIResponse(state, acsDetailsKey(acsId)) || {};
@@ -0,0 +1,3 @@
1
+ .expandable-section-text {
2
+ font-size: 14px;
3
+ }
@@ -16,6 +16,8 @@ import { getSmartProxies } from '../../SmartProxy/SmartProxyContentActions';
16
16
  import { CONTENT_CREDENTIAL_CERT_TYPE } from '../../ContentCredentials/ContentCredentialConstants';
17
17
  import { getProducts } from '../ACSActions';
18
18
  import ACSProducts from './Steps/ACSProducts';
19
+ import { areSubPathsValid, isValidUrl } from '../helpers';
20
+
19
21
 
20
22
  const ACSCreateWizard = ({ show, setIsOpen }) => {
21
23
  const [acsType, setAcsType] = useState(null);
@@ -25,6 +27,7 @@ const ACSCreateWizard = ({ show, setIsOpen }) => {
25
27
  const [smartProxies, setSmartProxies] = useState([]);
26
28
  const [url, setUrl] = useState('');
27
29
  const [subpaths, setSubpaths] = useState('');
30
+ const [useHttpProxies, setUseHttpProxies] = useState(false);
28
31
  const [verifySSL, setVerifySSL] = useState(false);
29
32
  const [authentication, setAuthentication] = useState('');
30
33
  const [sslCert, setSslCert] = useState('');
@@ -49,6 +52,16 @@ const ACSCreateWizard = ({ show, setIsOpen }) => {
49
52
  [dispatch],
50
53
  );
51
54
 
55
+ const credentialsFilled = () => {
56
+ if (authentication === 'manual') {
57
+ return username !== '';
58
+ }
59
+ return true;
60
+ };
61
+
62
+ const subPathValidated = areSubPathsValid(subpaths) ? 'default' : 'error';
63
+ const urlValidated = (url === '' || isValidUrl(url)) ? 'default' : 'error';
64
+
52
65
  const sourceTypeStep = {
53
66
  id: 1,
54
67
  name: __('Select source type'),
@@ -60,6 +73,7 @@ const ACSCreateWizard = ({ show, setIsOpen }) => {
60
73
  id: 2,
61
74
  name: __('Name source'),
62
75
  component: <NameACS />,
76
+ canJumpTo: acsType && contentType,
63
77
  enableNext: name !== '',
64
78
  };
65
79
 
@@ -67,6 +81,7 @@ const ACSCreateWizard = ({ show, setIsOpen }) => {
67
81
  id: 3,
68
82
  name: __('Select smart proxy'),
69
83
  component: <ACSSmartProxies />,
84
+ canJumpTo: name !== '',
70
85
  enableNext: smartProxies.length,
71
86
  };
72
87
 
@@ -74,6 +89,7 @@ const ACSCreateWizard = ({ show, setIsOpen }) => {
74
89
  id: 4,
75
90
  name: __('Select products'),
76
91
  component: <ACSProducts />,
92
+ canJumpTo: smartProxies.length,
77
93
  enableNext: productIds.length,
78
94
  };
79
95
 
@@ -81,14 +97,16 @@ const ACSCreateWizard = ({ show, setIsOpen }) => {
81
97
  id: 5,
82
98
  name: __('URL and paths'),
83
99
  component: <AcsUrlPaths />,
84
- enableNext: url !== '',
100
+ canJumpTo: (acsType === 'custom' || acsType === 'rhui') && (smartProxies.length),
101
+ enableNext: url !== '' && urlValidated !== 'error' && subPathValidated !== 'error',
85
102
  };
86
103
 
87
104
  const credentialsStep = {
88
105
  id: 6,
89
106
  name: __('Credentials'),
90
107
  component: <ACSCredentials />,
91
- enableNext: (url !== '' || productIds.length) && smartProxies.length && name !== '' && acsType && contentType,
108
+ canJumpTo: url !== '' && urlValidated !== 'error' && subPathValidated !== 'error',
109
+ enableNext: (url !== '' || productIds.length) && smartProxies.length && name !== '' && acsType && contentType && credentialsFilled(),
92
110
  };
93
111
 
94
112
  const reviewStep = {
@@ -96,6 +114,7 @@ const ACSCreateWizard = ({ show, setIsOpen }) => {
96
114
  name: __('Review details'),
97
115
  component: <ACSReview />,
98
116
  nextButtonText: __('Add'),
117
+ canJumpTo: (url !== '' || productIds.length) && smartProxies.length && name !== '' && acsType && contentType && credentialsFilled(),
99
118
  enableNext: (url !== '' || productIds.length) && smartProxies.length && name !== '' && acsType && contentType,
100
119
  };
101
120
 
@@ -110,7 +129,7 @@ const ACSCreateWizard = ({ show, setIsOpen }) => {
110
129
  sourceTypeStep,
111
130
  nameStep,
112
131
  smartProxyStep,
113
- ...(acsType === 'custom' ? [urlPathStep, credentialsStep] : []),
132
+ ...((acsType === 'custom' || acsType === 'rhui') ? [urlPathStep, credentialsStep] : []),
114
133
  ...(acsType === 'simplified' ? [productStep] : []),
115
134
  reviewStep,
116
135
  finishStep,
@@ -140,6 +159,8 @@ const ACSCreateWizard = ({ show, setIsOpen }) => {
140
159
  setUrl,
141
160
  subpaths,
142
161
  setSubpaths,
162
+ useHttpProxies,
163
+ setUseHttpProxies,
143
164
  verifySSL,
144
165
  setVerifySSL,
145
166
  authentication,
@@ -6,7 +6,7 @@ import { translate as __ } from 'foremanReact/common/I18n';
6
6
  import { STATUS } from 'foremanReact/constants';
7
7
  import ACSCreateContext from '../ACSCreateContext';
8
8
  import { selectCreateACS, selectCreateACSError, selectCreateACSStatus } from '../../ACSSelectors';
9
- import { createACS } from '../../ACSActions';
9
+ import getAlternateContentSources, { createACS } from '../../ACSActions';
10
10
  import Loading from '../../../../components/Loading';
11
11
 
12
12
  const ACSCreateFinish = () => {
@@ -21,6 +21,7 @@ const ACSCreateFinish = () => {
21
21
  smartProxies,
22
22
  url,
23
23
  subpaths,
24
+ useHttpProxies,
24
25
  verifySSL,
25
26
  authentication,
26
27
  sslCert,
@@ -31,15 +32,15 @@ const ACSCreateFinish = () => {
31
32
  productIds,
32
33
  } = useContext(ACSCreateContext);
33
34
  const dispatch = useDispatch();
34
- const response = useSelector(state => selectCreateACS(state));
35
- const status = useSelector(state => selectCreateACSStatus(state));
36
- const error = useSelector(state => selectCreateACSError(state));
35
+ const response = useSelector(state => selectCreateACS(state, name));
36
+ const status = useSelector(state => selectCreateACSStatus(state, name));
37
+ const error = useSelector(state => selectCreateACSError(state, name));
37
38
  const [createACSDispatched, setCreateACSDispatched] = useState(false);
38
39
  const [saving, setSaving] = useState(true);
39
40
 
40
41
  const acsTypeParams = useCallback((params, type) => {
41
42
  let acsParams = params;
42
- if (type === 'custom') {
43
+ if (type === 'custom' || type === 'rhui') {
43
44
  acsParams = {
44
45
  base_url: url, verify_ssl: verifySSL, ssl_ca_cert_id: caCert, ...acsParams,
45
46
  };
@@ -60,6 +61,7 @@ const ACSCreateFinish = () => {
60
61
  name,
61
62
  description,
62
63
  smart_proxy_names: smartProxies,
64
+ use_http_proxies: useHttpProxies,
63
65
  content_type: contentType,
64
66
  alternate_content_source_type: acsType,
65
67
  };
@@ -70,18 +72,18 @@ const ACSCreateFinish = () => {
70
72
  if (authentication === 'manual') {
71
73
  params = { upstream_username: username, upstream_password: password, ...params };
72
74
  }
73
- dispatch(createACS(params));
75
+ dispatch(createACS(params, name, () => { dispatch(getAlternateContentSources()); }));
74
76
  }
75
77
  }, [dispatch, createACSDispatched, setCreateACSDispatched,
76
78
  acsType, authentication, name, description, url, subpaths,
77
- smartProxies, contentType, verifySSL, caCert, sslCert, sslKey,
79
+ smartProxies, contentType, useHttpProxies, verifySSL, caCert, sslCert, sslKey,
78
80
  username, password, currentStep, acsTypeParams]);
79
81
 
80
82
  useDeepCompareEffect(() => {
81
83
  const { id } = response;
82
84
  if (id && status === STATUS.RESOLVED && saving) {
83
85
  setSaving(false);
84
- push(`/labs/alternate_content_sources/${id}/details`);
86
+ window.location.assign(`/alternate_content_sources/${id}/details`);
85
87
  setIsOpen(false);
86
88
  } else if (status === STATUS.ERROR) {
87
89
  setSaving(false);
@@ -8,6 +8,7 @@ import {
8
8
  FormSelectOption,
9
9
  TextInput,
10
10
  Radio,
11
+ Switch,
11
12
  } from '@patternfly/react-core';
12
13
  import { STATUS } from 'foremanReact/constants';
13
14
  import ACSCreateContext from '../ACSCreateContext';
@@ -17,9 +18,9 @@ import Loading from '../../../../components/Loading';
17
18
 
18
19
  const ACSCredentials = () => {
19
20
  const {
20
- authentication, setAuthentication, username, setUsername, password, setPassword,
21
+ acsType, authentication, setAuthentication, username, setUsername, password, setPassword,
21
22
  sslCert, setSslCert, sslKey, setSslKey, caCert, setCACert,
22
- setSslCertName, setSslKeyName, setCACertName,
23
+ setSslCertName, setSslKeyName, setCACertName, verifySSL, setVerifySSL,
23
24
  } = useContext(ACSCreateContext);
24
25
 
25
26
  const contentCredentials = useSelector(selectContentCredentials);
@@ -31,13 +32,18 @@ const ACSCredentials = () => {
31
32
 
32
33
  const getCertName = id => contentCredentials?.filter(cc => Number(cc.id) === Number(id))[0]?.name;
33
34
 
35
+ const description = acsType === 'rhui' ?
36
+ __('Choose content credentials if required for this RHUI source.') :
37
+ __('Enter basic authentication information or choose content credentials if required for this source.');
38
+
34
39
  return (
35
40
  <>
36
41
  <WizardHeader
37
42
  title={__('Credentials')}
38
- description={__('Enter basic authentication information or choose content credentials if required for this source.')}
43
+ description={description}
39
44
  />
40
45
  <Form>
46
+ {(acsType !== 'rhui') &&
41
47
  <Radio
42
48
  label={__('Manual authentication')}
43
49
  id="manual_auth"
@@ -52,6 +58,7 @@ const ACSCredentials = () => {
52
58
  setSslKeyName('');
53
59
  }}
54
60
  />
61
+ }
55
62
  {(authentication === 'manual') &&
56
63
  <>
57
64
  <FormGroup
@@ -168,12 +175,26 @@ const ACSCredentials = () => {
168
175
  setPassword('');
169
176
  }}
170
177
  />
178
+ <FormGroup label={__('Verify SSL')} fieldId="verify_ssl">
179
+ <Switch
180
+ id="verify-ssl-switch"
181
+ aria-label="verify-ssl-switch"
182
+ isChecked={verifySSL}
183
+ onChange={checked => setVerifySSL(checked)}
184
+ />
185
+ </FormGroup>
171
186
  <FormGroup
172
187
  label={__('SSL CA certificate')}
173
188
  type="string"
174
189
  fieldId="ca_cert"
175
190
  >
176
- <FormSelect isRequired value={caCert} onChange={(value) => { setCACert(value); setCACertName(getCertName(value)); }} aria-label="sslCAcert_select">
191
+ <FormSelect
192
+ isDisabled={!verifySSL}
193
+ isRequired
194
+ value={caCert}
195
+ onChange={(value) => { setCACert(value); setCACertName(getCertName(value)); }}
196
+ aria-label="sslCAcert_select"
197
+ >
177
198
  {
178
199
  [
179
200
  <FormSelectOption
@@ -1,13 +1,15 @@
1
1
  import React, { useContext } from 'react';
2
+ import { capitalize, upperCase } from 'lodash';
2
3
  import { translate as __ } from 'foremanReact/common/I18n';
3
4
  import { TextContent, TextList, TextListItem, TextListItemVariants, TextListVariants } from '@patternfly/react-core';
4
5
  import ACSCreateContext from '../ACSCreateContext';
5
6
  import WizardHeader from '../../../ContentViews/components/WizardHeader';
7
+ import InactiveText from '../../../ContentViews/components/InactiveText';
6
8
 
7
9
  const ACSReview = () => {
8
10
  const {
9
11
  name, description, acsType, contentType,
10
- smartProxies, url, subpaths, verifySSL,
12
+ smartProxies, useHttpProxies, url, subpaths, verifySSL,
11
13
  authentication, sslCertName, sslKeyName, username,
12
14
  password, caCertName, productNames,
13
15
  } = useContext(ACSCreateContext);
@@ -15,9 +17,14 @@ const ACSReview = () => {
15
17
  return (
16
18
  <>
17
19
  <WizardHeader
18
- title={__('Review Details')}
19
- description={__('Review the information below and click Add to add your source. ' +
20
- 'To edit details in previous steps, click Back or any step on the left.')}
20
+ title={__('Review details')}
21
+ description={
22
+ <>
23
+ {__('Review the information below and click ')}<strong>{__('Add')}</strong>{__(' to add your source. ' +
24
+ 'To edit details in previous steps, click ')}<strong>{__('Back')}</strong>{__(' or any step on the left.')
25
+ }
26
+ </>
27
+ }
21
28
  />
22
29
  <TextContent>
23
30
  <TextList component={TextListVariants.dl}>
@@ -27,7 +34,7 @@ const ACSReview = () => {
27
34
  </TextListItem>
28
35
  <TextListItem component={TextListItemVariants.dt}>{__('Source type')}</TextListItem>
29
36
  <TextListItem component={TextListItemVariants.dd}>
30
- {acsType}
37
+ {acsType === 'rhui' ? upperCase(acsType) : capitalize(acsType)}
31
38
  </TextListItem>
32
39
  <TextListItem component={TextListItemVariants.dt}>{__('Description')}</TextListItem>
33
40
  <TextListItem component={TextListItemVariants.dd}>
@@ -35,13 +42,17 @@ const ACSReview = () => {
35
42
  </TextListItem>
36
43
  <TextListItem component={TextListItemVariants.dt}>{__('Content type')}</TextListItem>
37
44
  <TextListItem component={TextListItemVariants.dd}>
38
- {contentType}
45
+ {capitalize(contentType)}
39
46
  </TextListItem>
40
47
  <TextListItem component={TextListItemVariants.dt}>{__('Smart proxies')}</TextListItem>
41
48
  <TextListItem component={TextListItemVariants.dd}>
42
49
  {smartProxies.join(', ')}
43
50
  </TextListItem>
44
- {acsType === 'custom' &&
51
+ <TextListItem component={TextListItemVariants.dt}>{__('Use HTTP Proxies')}</TextListItem>
52
+ <TextListItem component={TextListItemVariants.dd}>
53
+ {useHttpProxies ? __('Yes') : __('No')}
54
+ </TextListItem>
55
+ {(acsType === 'custom' || acsType === 'rhui') &&
45
56
  <>
46
57
  <TextListItem component={TextListItemVariants.dt}>
47
58
  {__('Base URL')}
@@ -57,7 +68,7 @@ const ACSReview = () => {
57
68
  <TextListItem component={TextListItemVariants.dd}>
58
69
  {verifySSL ? __('Yes') : __('No')}
59
70
  </TextListItem>
60
- <TextListItem component={TextListItemVariants.dt}>{__('CA Cert')}</TextListItem>
71
+ <TextListItem component={TextListItemVariants.dt}>{__('SSL CA certificate')}</TextListItem>
61
72
  <TextListItem component={TextListItemVariants.dd}>
62
73
  {caCertName}
63
74
  </TextListItem>
@@ -76,7 +87,7 @@ const ACSReview = () => {
76
87
  </TextListItem>
77
88
  <TextListItem component={TextListItemVariants.dt}>{__('Password')}</TextListItem>
78
89
  <TextListItem component={TextListItemVariants.dd}>
79
- {password}
90
+ {password.length > 0 ? '••••••••' : <InactiveText text={__('N/A')} />}
80
91
  </TextListItem>
81
92
  </>
82
93
  )}
@@ -89,11 +100,11 @@ const ACSReview = () => {
89
100
  <TextListItem component={TextListItemVariants.dd}>
90
101
  {__('Content credential')}
91
102
  </TextListItem>
92
- <TextListItem component={TextListItemVariants.dt}>{__('SSL Cert')}</TextListItem>
103
+ <TextListItem component={TextListItemVariants.dt}>{__('SSL client certificate')}</TextListItem>
93
104
  <TextListItem component={TextListItemVariants.dd}>
94
105
  {sslCertName}
95
106
  </TextListItem>
96
- <TextListItem component={TextListItemVariants.dt}>{__('Client key')}</TextListItem>
107
+ <TextListItem component={TextListItemVariants.dt}>{__('SSL client key')}</TextListItem>
97
108
  <TextListItem component={TextListItemVariants.dd}>
98
109
  {sslKeyName}
99
110
  </TextListItem>
@@ -1,14 +1,21 @@
1
1
  import React, { useContext, useState } from 'react';
2
2
  import { useSelector } from 'react-redux';
3
3
  import { translate as __ } from 'foremanReact/common/I18n';
4
- import { DualListSelector } from '@patternfly/react-core';
4
+ import {
5
+ DualListSelector,
6
+ FormGroup,
7
+ Switch,
8
+ Flex,
9
+ FlexItem,
10
+ } from '@patternfly/react-core';
5
11
  import ACSCreateContext from '../ACSCreateContext';
6
12
  import WizardHeader from '../../../ContentViews/components/WizardHeader';
7
13
  import { selectSmartProxy } from '../../../SmartProxy/SmartProxyContentSelectors';
14
+ import { HelpToolTip } from '../../../ContentViews/Create/ContentViewFormComponents';
8
15
 
9
16
  const ACSSmartProxies = () => {
10
17
  const {
11
- smartProxies, setSmartProxies,
18
+ smartProxies, setSmartProxies, useHttpProxies, setUseHttpProxies,
12
19
  } = useContext(ACSCreateContext);
13
20
  const availableSmartProxies = useSelector(selectSmartProxy);
14
21
  const { results } = availableSmartProxies;
@@ -35,6 +42,24 @@ const ACSSmartProxies = () => {
35
42
  removeSelected={onListChange}
36
43
  id="selector"
37
44
  />
45
+ <FormGroup
46
+ label={
47
+ <Flex spaceItems={{ default: 'spaceItemsNone' }}>
48
+ <FlexItem>{__('Use HTTP proxies')}</FlexItem>
49
+ <FlexItem>
50
+ <HelpToolTip tooltip={__('Alternate content sources use the HTTP proxy of their assigned smart proxy for communication.')} />
51
+ </FlexItem>
52
+ </Flex>
53
+ }
54
+ fieldId="use_http_proxies"
55
+ >
56
+ <Switch
57
+ id="use-http-proxies-switch"
58
+ aria-label="use-http-proxies-switch"
59
+ isChecked={useHttpProxies}
60
+ onChange={checked => setUseHttpProxies(checked)}
61
+ />
62
+ </FormGroup>
38
63
  </>
39
64
  );
40
65
  };
@@ -1,67 +1,99 @@
1
1
  import React, { useContext } from 'react';
2
2
  import { translate as __ } from 'foremanReact/common/I18n';
3
3
  import {
4
+ ClipboardCopy,
4
5
  Form,
5
6
  FormGroup,
6
7
  TextInput,
7
8
  TextArea,
8
- Switch,
9
9
  } from '@patternfly/react-core';
10
10
  import ACSCreateContext from '../ACSCreateContext';
11
11
  import WizardHeader from '../../../ContentViews/components/WizardHeader';
12
+ import { areSubPathsValid, isValidUrl } from '../../helpers';
12
13
 
13
14
  const AcsUrlPaths = () => {
14
15
  const {
15
- url, setUrl, subpaths, setSubpaths, verifySSL, setVerifySSL,
16
+ acsType, url, setUrl, subpaths, setSubpaths,
16
17
  } = useContext(ACSCreateContext);
17
18
 
19
+ const subPathValidated = areSubPathsValid(subpaths) ? 'default' : 'error';
20
+ const [urlValidated, setUrlValidated] = React.useState('default');
21
+ const handleUrlChange = (newUrl, _event) => {
22
+ setUrl(newUrl);
23
+ if (isValidUrl(newUrl, acsType)) {
24
+ setUrlValidated('success');
25
+ } else {
26
+ setUrlValidated('error');
27
+ }
28
+ };
29
+
30
+ const baseURLplaceholder = acsType === 'rhui' ?
31
+ 'https://rhui-server.example.com/pulp/content' :
32
+ 'http:// or https://';
33
+ const helperTextInvalid = acsType === 'rhui' ?
34
+ 'http://rhui-server.example.com/pulp/content or https://rhui-server.example.com/pulp/content' :
35
+ 'http://, https:// or file://';
36
+ let headerDescription =
37
+ __('Enter in the base path and any subpaths that should be searched for alternate content.');
38
+ headerDescription = acsType === 'rhui' ?
39
+ `${headerDescription}${__(' The base path must be a web address pointing to the root RHUI content directory.')}` :
40
+ `${headerDescription}${__(' The base path can be a web address or a filesystem location.')}`;
41
+
18
42
  return (
19
43
  <>
20
44
  <WizardHeader
21
45
  title={__('URL and paths')}
22
- description={__('Enter in the base path and any subpaths that should be searched for alternate content. ' +
23
- 'The base path can be a web address or a filesystem location.')}
46
+ description={headerDescription}
24
47
  />
25
48
  <Form>
26
49
  <FormGroup
27
50
  label={__('Base URL')}
28
- type="string"
29
51
  fieldId="acs_base_url"
52
+ helperTextInvalid={helperTextInvalid}
53
+ validated={urlValidated}
30
54
  isRequired
31
55
  >
32
56
  <TextInput
33
57
  isRequired
34
- type="text"
58
+ type="url"
35
59
  id="acs_base_url_field"
36
60
  name="acs_base_url_field"
37
61
  aria-label="acs_base_url_field"
38
- placeholder="https:// or file://"
62
+ placeholder={baseURLplaceholder}
39
63
  value={url}
40
- onChange={(value) => { setUrl(value); }}
64
+ validated={urlValidated}
65
+ onChange={handleUrlChange}
41
66
  />
42
67
  </FormGroup>
68
+ {acsType === 'rhui' &&
69
+ <>
70
+ {__('On the RHUA Instance, check the available repositories.')}
71
+ <ClipboardCopy hoverTip="Copy" clickTip="Copied" variant="inline-compact" isBlock>
72
+ rhui-manager repo list
73
+ </ClipboardCopy>
74
+ {__('Find the relative path for each RHUI repository and combine them in a comma-separated list.')}
75
+ <ClipboardCopy hoverTip="Copy" clickTip="Copied" variant="inline-compact" isBlock>
76
+ rhui-manager repo info --repo_id your_repo_id
77
+ </ClipboardCopy>
78
+ </>
79
+ }
43
80
  <FormGroup
44
81
  label={__('Subpaths')}
45
82
  type="string"
46
83
  fieldId="acs_subpaths"
84
+ helperTextInvalid={__('Comma-separated list of subpaths. All subpaths must have a slash at the end and none at the front.')}
85
+ validated={subPathValidated}
47
86
  >
48
87
  <TextArea
49
88
  placeholder="test/repo1/, test/repo2/,"
50
89
  value={subpaths}
51
- onChange={(value) => { setSubpaths(value); }}
90
+ validated={subPathValidated}
91
+ onChange={value => setSubpaths(value)}
52
92
  name="acs_subpath_field"
53
93
  id="acs_subpath_field"
54
94
  aria-label="acs_subpath_field"
55
95
  />
56
96
  </FormGroup>
57
- <FormGroup label={__('Verify SSL')} fieldId="verify_ssl">
58
- <Switch
59
- id="verify-ssl-switch"
60
- aria-label="verify-ssl-switch"
61
- isChecked={verifySSL}
62
- onChange={checked => setVerifySSL(checked)}
63
- />
64
- </FormGroup>
65
97
  </Form>
66
98
  </>
67
99
  );