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
@@ -46,13 +46,9 @@ import {
46
46
  userPermissionsFromHostDetails,
47
47
  } from '../../hostDetailsHelpers';
48
48
 
49
- const moduleStreamSupported = ({ os, version }) =>
50
- os.match(/RedHat|CentOS|Rocky|AlmaLinux|OracleLinux/i) && Number(version) > 7;
51
49
  export const hideModuleStreamsTab = ({ hostDetails }) => {
52
50
  const osMatch = hostDetails?.operatingsystem_name?.match(/(\w+) (\d+)/);
53
- if (!osMatch) return true;
54
- const [, os, version] = osMatch;
55
- return !(osMatch && moduleStreamSupported({ os, version }));
51
+ return !(osMatch && osMatch[1].match(/RedHat|CentOS/i) && Number(osMatch[2]) > 7);
56
52
  };
57
53
 
58
54
  const EnabledIcon = ({ streamText, streamInstallStatus, upgradable }) => {
@@ -164,6 +160,7 @@ const ModuleActionConfirmationModal = ({
164
160
  variant={ModalVariant.small}
165
161
  isOpen={actionModalOpen}
166
162
  aria-label="Module action confirmation modal"
163
+ ouiaId="Module-action-confirmation-modal"
167
164
  title={title}
168
165
  titleIconVariant="warning"
169
166
  showClose
@@ -171,6 +168,7 @@ const ModuleActionConfirmationModal = ({
171
168
  actions={[
172
169
  <Button
173
170
  aria-label="confirm-module-action"
171
+ ouiaId="confirm-module-action"
174
172
  key="confirm-module-action"
175
173
  onClick={() => {
176
174
  triggerModuleStreamAction({ hostname, action, moduleSpec });
@@ -181,6 +179,7 @@ const ModuleActionConfirmationModal = ({
181
179
  </Button>,
182
180
  <Button
183
181
  aria-label="cancel-module-action"
182
+ ouiaId="cancel-module-action"
184
183
  key="cancel-module-action"
185
184
  variant="link"
186
185
  onClick={() => setActionModalOpen(false)}
@@ -189,7 +188,7 @@ const ModuleActionConfirmationModal = ({
189
188
  </Button>,
190
189
  ]}
191
190
  >
192
- <Text component={TextVariants.p}>
191
+ <Text component={TextVariants.p} ouiaId="text">
193
192
  {body}
194
193
  </Text>
195
194
 
@@ -408,7 +407,7 @@ export const ModuleStreamsTab = () => {
408
407
  }
409
408
  >
410
409
  <Thead>
411
- <Tr>
410
+ <Tr ouiaId="header-tr">
412
411
  <SortableColumnHeaders
413
412
  columnHeaders={columnHeaders}
414
413
  pfSortParams={pfSortParams}
@@ -429,22 +428,24 @@ export const ModuleStreamsTab = () => {
429
428
  }, index) => {
430
429
  /* eslint-disable react/no-array-index-key */
431
430
  const dropdownItems = [
432
- <DropdownItem key={`dropdownItem-checkbox-${id}`}>
431
+ <DropdownItem key={`dropdownItem-checkbox-${id}`} ouiaId={`dropdownItem-checkbox-${id}`}>
433
432
  <Checkbox
434
433
  aria-label={`customize-checkbox-${id}`}
434
+ ouiaId={`customize-checkbox-${id}`}
435
435
  id={`Checkbox${id}`}
436
436
  label={__('Customize with Rex')}
437
437
  isChecked={id === useCustomizedRex}
438
438
  onChange={checked => (checked ? setUseCustomizedRex(id) : setUseCustomizedRex(''))}
439
439
  />
440
440
  </DropdownItem>,
441
- <DropdownSeparator key={`separator-${id}`} />,
441
+ <DropdownSeparator key={`separator-${id}`} ouiaId={`separator-${id}`} />,
442
442
 
443
443
  ];
444
444
  if (id === useCustomizedRex) {
445
445
  dropdownItems.push(
446
446
  <DropdownItem
447
447
  aria-label={`enable-${id}-href`}
448
+ ouiaId={`enable-${id}-href`}
448
449
  key={`dropdownItem-enable-url-${id}`}
449
450
  component="a"
450
451
  href={customizedActionURL('enable', moduleSpec)}
@@ -455,6 +456,7 @@ export const ModuleStreamsTab = () => {
455
456
  </DropdownItem>,
456
457
  <DropdownItem
457
458
  aria-label={`disable-${id}-href`}
459
+ ouiaId={`disable-${id}-href`}
458
460
  key={`dropdownItem-disable-url-${id}`}
459
461
  component="a"
460
462
  href={customizedActionURL('disable', moduleSpec)}
@@ -466,6 +468,7 @@ export const ModuleStreamsTab = () => {
466
468
  </DropdownItem>,
467
469
  <DropdownItem
468
470
  aria-label={`install-${id}-href`}
471
+ ouiaId={`install-${id}-href`}
469
472
  key={`dropdownItem-install-url-${id}`}
470
473
  component="a"
471
474
  href={customizedActionURL('install', moduleSpec)}
@@ -479,6 +482,7 @@ export const ModuleStreamsTab = () => {
479
482
  </DropdownItem>,
480
483
  <DropdownItem
481
484
  aria-label={`update-${id}-href`}
485
+ ouiaId={`update-${id}-href`}
482
486
  key={`dropdownItem-update-${id}`}
483
487
  component="a"
484
488
  href={customizedActionURL('update', moduleSpec)}
@@ -488,6 +492,7 @@ export const ModuleStreamsTab = () => {
488
492
  </DropdownItem>,
489
493
  <DropdownItem
490
494
  aria-label={`reset-${id}-href`}
495
+ ouiaId={`reset-${id}-href`}
491
496
  key={`dropdownItem-reset-${id}`}
492
497
  component="a"
493
498
  href={customizedActionURL('reset', moduleSpec)}
@@ -497,6 +502,7 @@ export const ModuleStreamsTab = () => {
497
502
  </DropdownItem>,
498
503
  <DropdownItem
499
504
  aria-label={`remove-${id}-href`}
505
+ ouiaId={`remove-${id}-href`}
500
506
  key={`dropdownItem-remove-${id}`}
501
507
  component="a"
502
508
  href={customizedActionURL('remove', moduleSpec)}
@@ -509,6 +515,7 @@ export const ModuleStreamsTab = () => {
509
515
  dropdownItems.push(
510
516
  <DropdownItem
511
517
  aria-label={`enable-${id}-button`}
518
+ ouiaId={`enable-${id}-button`}
512
519
  key={`dropdownItem-enable-${id}`}
513
520
  component="button"
514
521
  onClick={() => {
@@ -523,6 +530,7 @@ export const ModuleStreamsTab = () => {
523
530
  </DropdownItem>,
524
531
  <DropdownItem
525
532
  aria-label={`disable-${id}-button`}
533
+ ouiaId={`disable-${id}-button`}
526
534
  key={`dropdownItem-disable-${id}`}
527
535
  component="button"
528
536
  onClick={() => {
@@ -540,6 +548,7 @@ export const ModuleStreamsTab = () => {
540
548
  </DropdownItem>,
541
549
  <DropdownItem
542
550
  aria-label={`install-${id}-button`}
551
+ ouiaId={`install-${id}-button`}
543
552
  key={`dropdownItem-install-${id}`}
544
553
  component="button"
545
554
  onClick={() => {
@@ -557,6 +566,7 @@ export const ModuleStreamsTab = () => {
557
566
  </DropdownItem>,
558
567
  <DropdownItem
559
568
  aria-label={`update-${id}-button`}
569
+ ouiaId={`update-${id}-button`}
560
570
  key={`dropdownItem-update-${id}`}
561
571
  component="button"
562
572
  onClick={() => {
@@ -570,6 +580,7 @@ export const ModuleStreamsTab = () => {
570
580
  </DropdownItem>,
571
581
  <DropdownItem
572
582
  aria-label={`reset-${id}-button`}
583
+ ouiaId={`reset-${id}-button`}
573
584
  key={`dropdownItem-reset-${id}`}
574
585
  component="button"
575
586
  onClick={() => {
@@ -586,6 +597,7 @@ export const ModuleStreamsTab = () => {
586
597
  </DropdownItem>,
587
598
  <DropdownItem
588
599
  aria-label={`remove-${id}-button`}
600
+ ouiaId={`remove-${id}-button`}
589
601
  key={`dropdownItem-remove-${id}`}
590
602
  component="button"
591
603
  onClick={() => {
@@ -603,7 +615,7 @@ export const ModuleStreamsTab = () => {
603
615
  );
604
616
  }
605
617
  return (
606
- <Tr key={`${id} ${index}`}>
618
+ <Tr key={`${id} ${index}`} ouiaId={`tr-${id}-${index}`}>
607
619
  <Td>
608
620
  <a
609
621
  href={`/module_streams?search=module_spec%3D${moduleSpec}+and+host%3D${hostname}`}
@@ -632,6 +644,7 @@ export const ModuleStreamsTab = () => {
632
644
  <Td key={`actions-td-${id}-${dropdownOpen}`}>
633
645
  <Dropdown
634
646
  aria-label={`actions-dropdown-${id}`}
647
+ ouiaId={`actions-dropdown-${id}`}
635
648
  key={`actions-dropdown-${id}-${dropdownOpen}`}
636
649
  isPlain
637
650
  style={{ width: 'inherit' }}
@@ -3,6 +3,7 @@ export const HOST_PACKAGES_INSTALL_KEY = 'HOST_PACKAGES_KATELLO_AGENT_INSTALL';
3
3
  export const HOST_PACKAGES_REMOVE_KEY = 'HOST_PACKAGES_REMOVE';
4
4
  export const HOST_PACKAGES_UPGRADE_KEY = 'HOST_PACKAGES_UPGRADE';
5
5
  export const PACKAGES_SEARCH_QUERY = 'Packages search query';
6
+ export const SELECTED_UPDATE_VERSIONS = 'Selected update versions';
6
7
 
7
8
  export const PACKAGES_VERSION_STATUSES = {
8
9
  UPGRADABLE: 'Upgradable',
@@ -35,17 +35,19 @@ const InstallDropdown = ({
35
35
  const dropdownItems = [
36
36
  <DropdownItem
37
37
  key="install-k-agent"
38
+ ouiaId="install-k-agent"
38
39
  component="button"
39
40
  onClick={installViaKatelloAgent}
40
41
  isDisabled={disableInstallViaKatelloAgent}
41
42
  >
42
43
  {__('Install via katello-agent')}
43
44
  </DropdownItem>,
44
- <DropdownItem key="install-rex" component="button" onClick={installViaRex}>
45
+ <DropdownItem key="install-rex" ouiaId="install-rex" component="button" onClick={installViaRex}>
45
46
  {__('Install via remote execution')}
46
47
  </DropdownItem>,
47
48
  <DropdownItem
48
49
  key="install-customized-rex"
50
+ ouiaId="install-customized-rex"
49
51
  component="a"
50
52
  href={bulkCustomizedRexUrl}
51
53
  onClick={onActionSelect}
@@ -59,10 +61,12 @@ const InstallDropdown = ({
59
61
 
60
62
  return (
61
63
  <Dropdown
64
+ ouiaId="action-dropdown"
62
65
  direction={DropdownDirection.up}
63
66
  onSelect={onActionSelect}
64
67
  toggle={
65
68
  <DropdownToggle
69
+ ouiaId="install-action-toggle"
66
70
  isDisabled={isDisabled}
67
71
  splitButtonItems={[
68
72
  <DropdownToggleAction key="install" onClick={defaultRemoteAction}>
@@ -174,7 +178,7 @@ const PackageInstallModal = ({
174
178
  showKatelloAgent={showKatelloAgent}
175
179
  disableInstallViaKatelloAgent={selectedResults.length === 0}
176
180
  />,
177
- <Button key="cancel" variant="link" onClick={handleModalClose}>
181
+ <Button key="cancel" ouiaId="cancel-button" variant="link" onClick={handleModalClose}>
178
182
  Cancel
179
183
  </Button>,
180
184
  ]);
@@ -187,6 +191,7 @@ const PackageInstallModal = ({
187
191
  width="50%"
188
192
  actions={modalActions}
189
193
  id="package-install-modal"
194
+ ouiaId="package-install-modal"
190
195
  >
191
196
  <FormattedMessage
192
197
  className="pkg-install-modal-blurb"
@@ -221,7 +226,7 @@ const PackageInstallModal = ({
221
226
  displaySelectAllCheckbox
222
227
  >
223
228
  <Thead>
224
- <Tr>
229
+ <Tr ouiaId="row-header">
225
230
  {columnHeaders.map(col =>
226
231
  <Th key={col}>{col}</Th>)}
227
232
  <Th />
@@ -236,7 +241,7 @@ const PackageInstallModal = ({
236
241
  version,
237
242
  } = pkg;
238
243
  return (
239
- <Tr key={id}>
244
+ <Tr key={id} ouiaId={`row-${id}`}>
240
245
  <Td
241
246
  select={{
242
247
  disable: false,
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useState } from 'react';
1
+ import React, { useCallback, useState, useRef } from 'react';
2
2
  import { useSelector, useDispatch } from 'react-redux';
3
3
  import {
4
4
  ActionList,
@@ -9,19 +9,23 @@ import {
9
9
  DropdownToggle,
10
10
  DropdownToggleAction,
11
11
  KebabToggle,
12
+ Select,
13
+ SelectOption,
14
+ SelectVariant,
12
15
  Skeleton,
13
16
  Split,
14
17
  SplitItem,
15
18
  } from '@patternfly/react-core';
16
- import { TableVariant, Thead, Tbody, Tr, Th, Td } from '@patternfly/react-table';
19
+ import { TableVariant, Thead, Tbody, Tr, Th, Td, TableText } from '@patternfly/react-table';
20
+ import PropTypes from 'prop-types';
17
21
  import { translate as __ } from 'foremanReact/common/I18n';
18
22
  import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
19
23
 
20
24
  import { urlBuilder } from 'foremanReact/common/urlHelpers';
21
25
  import SelectableDropdown from '../../../../SelectableDropdown';
22
26
  import TableWrapper from '../../../../../components/Table/TableWrapper';
23
- import { useBulkSelect, useTableSort, useUrlParams } from '../../../../../components/Table/TableHooks';
24
- import { PackagesStatus, PackagesLatestVersion } from '../../../../../components/Packages';
27
+ import { useBulkSelect, useTableSort, useUrlParams, useSet } from '../../../../../components/Table/TableHooks';
28
+ import PackagesStatus from '../../../../../components/Packages';
25
29
  import {
26
30
  getInstalledPackagesWithLatest,
27
31
  removePackageViaKatelloAgent,
@@ -35,7 +39,7 @@ import {
35
39
  import { removePackage, updatePackage, removePackages, updatePackages, installPackageBySearch } from '../RemoteExecutionActions';
36
40
  import { katelloPackageUpdateUrl, packagesUpdateUrl } from '../customizedRexUrlHelpers';
37
41
  import './PackagesTab.scss';
38
- import hostIdNotReady from '../../HostDetailsActions';
42
+ import hostIdNotReady, { getHostDetails } from '../../HostDetailsActions';
39
43
  import PackageInstallModal from './PackageInstallModal';
40
44
  import { defaultRemoteActionMethod,
41
45
  hasRequiredPermissions as can,
@@ -49,6 +53,70 @@ const invokeRexJobs = ['create_job_invocations'];
49
53
  const doKatelloAgentActions = ['edit_hosts'];
50
54
  const createBookmarks = ['create_bookmarks'];
51
55
 
56
+ const UpdateVersionsSelect = ({
57
+ packageName,
58
+ rowIndex,
59
+ selections,
60
+ upgradableVersions,
61
+ toggleUpgradableVersionSelect,
62
+ onUpgradableVersionSelect,
63
+ upgradableVersionSelectOpen,
64
+ }) => {
65
+ if (upgradableVersions === null) {
66
+ return <TableText wrapModifier="nowrap">—</TableText>;
67
+ } else if (upgradableVersions.length === 1) {
68
+ return <TableText wrapModifier="nowrap">{upgradableVersions[0]}</TableText>;
69
+ }
70
+
71
+ return (
72
+ <div>
73
+ <span id="style-select-id">
74
+ <Select
75
+ variant={SelectVariant.single}
76
+ aria-label="upgradable-version-select"
77
+ ouiaId="upgradable-version-select"
78
+ onToggle={isOpen => toggleUpgradableVersionSelect(isOpen, rowIndex)}
79
+ onSelect={(event, selected) => {
80
+ onUpgradableVersionSelect(event, selected, rowIndex, packageName);
81
+ }}
82
+ selections={selections}
83
+ isOpen={upgradableVersionSelectOpen.has(rowIndex)}
84
+ isPlain
85
+ >
86
+ {upgradableVersions.map(version => (
87
+ <SelectOption
88
+ key={version}
89
+ value={version}
90
+ label={`${version}-version-select-option`}
91
+ />
92
+ ))}
93
+ </Select>
94
+ </span>
95
+ </div>
96
+ );
97
+ };
98
+
99
+ UpdateVersionsSelect.propTypes = {
100
+ packageName: PropTypes.string.isRequired,
101
+ rowIndex: PropTypes.number.isRequired,
102
+ selections: PropTypes.string,
103
+ upgradableVersions: PropTypes.arrayOf(PropTypes.string),
104
+ toggleUpgradableVersionSelect: PropTypes.func,
105
+ onUpgradableVersionSelect: PropTypes.func,
106
+ upgradableVersionSelectOpen: PropTypes.shape({
107
+ has: PropTypes.func,
108
+ rowIndex: PropTypes.number,
109
+ }),
110
+ };
111
+
112
+ UpdateVersionsSelect.defaultProps = {
113
+ selections: null,
114
+ upgradableVersions: null,
115
+ toggleUpgradableVersionSelect: undefined,
116
+ onUpgradableVersionSelect: undefined,
117
+ upgradableVersionSelectOpen: null,
118
+ };
119
+
52
120
  export const PackagesTab = () => {
53
121
  const hostDetails = useSelector(state => selectAPIResponse(state, 'HOST_DETAILS'));
54
122
  const {
@@ -79,6 +147,26 @@ export const PackagesTab = () => {
79
147
  setIsActionOpen(prev => !prev);
80
148
  };
81
149
 
150
+ const upgradableVersionSelectOpen = useSet([]);
151
+ const toggleUpgradableVersionSelect = (isOpenState, rowIndex) => {
152
+ if (isOpenState) {
153
+ upgradableVersionSelectOpen.add(rowIndex);
154
+ } else {
155
+ upgradableVersionSelectOpen.delete(rowIndex);
156
+ }
157
+ };
158
+
159
+ const selectedNewVersions = useRef({});
160
+ const onUpgradableVersionSelect = (_event, selected, rowIndex, packageName) => {
161
+ toggleUpgradableVersionSelect(false, rowIndex);
162
+ selectedNewVersions.current[packageName] = selected;
163
+ };
164
+ const selectedPackageUpgradeVersion = ({ packageName, upgradableVersions }) => (
165
+ selectedNewVersions.current[packageName] || upgradableVersions[0]
166
+ );
167
+ const selectedNVRAVersions = Object.keys(selectedNewVersions.current).map(k =>
168
+ selectedNewVersions.current[k]);
169
+
82
170
  const emptyContentTitle = __('This host does not have any packages.');
83
171
  const emptyContentBody = __('Packages will appear here when available.');
84
172
  const emptySearchTitle = __('No matching packages found');
@@ -161,27 +249,28 @@ export const PackagesTab = () => {
161
249
  isPolling: isBulkRemoveInProgress,
162
250
  } = useRexJobPolling(packageBulkRemoveAction);
163
251
 
164
- const packageUpgradeAction = packageName => updatePackage({
252
+ const packageUpgradeAction = ({ packageName, upgradableVersions }) => updatePackage({
165
253
  hostname,
166
- packageName,
254
+ packageName: selectedPackageUpgradeVersion({ packageName, upgradableVersions }),
167
255
  });
168
256
 
169
257
  const {
170
258
  triggerJobStart: triggerPackageUpgrade,
171
259
  lastCompletedJob: lastCompletedPackageUpgrade,
172
260
  isPolling: isUpgradeInProgress,
173
- } = useRexJobPolling(packageUpgradeAction);
261
+ } = useRexJobPolling(packageUpgradeAction, getHostDetails({ hostname }));
174
262
 
175
263
  const packageBulkUpgradeAction = bulkParams => updatePackages({
176
264
  hostname,
177
265
  search: bulkParams,
266
+ versions: JSON.stringify(selectedNVRAVersions || []),
178
267
  });
179
268
 
180
269
  const {
181
270
  triggerJobStart: triggerBulkPackageUpgrade,
182
271
  lastCompletedJob: lastCompletedBulkPackageUpgrade,
183
272
  isPolling: isBulkUpgradeInProgress,
184
- } = useRexJobPolling(packageBulkUpgradeAction);
273
+ } = useRexJobPolling(packageBulkUpgradeAction, getHostDetails({ hostname }));
185
274
 
186
275
  const packageInstallAction
187
276
  = bulkParams => installPackageBySearch({ hostname, search: bulkParams });
@@ -190,7 +279,7 @@ export const PackagesTab = () => {
190
279
  triggerJobStart: triggerPackageInstall,
191
280
  lastCompletedJob: lastCompletedPackageInstall,
192
281
  isPolling: isInstallInProgress,
193
- } = useRexJobPolling(packageInstallAction);
282
+ } = useRexJobPolling(packageInstallAction, getHostDetails({ hostname }));
194
283
 
195
284
  const actionInProgress = (isRemoveInProgress || isUpgradeInProgress
196
285
  || isBulkRemoveInProgress || isBulkUpgradeInProgress || isInstallInProgress);
@@ -218,7 +307,8 @@ export const PackagesTab = () => {
218
307
  };
219
308
 
220
309
  const selectedPackageNames = () => selectedResults.map(({ name }) => name);
221
- const selectedUpgradableVersions = () => selectedResults.map(({ upgradable_version: v }) => v);
310
+ const selectedUpgradableVersions = () => selectedResults.map(({ name, upgradable_versions: v }) =>
311
+ selectedNewVersions.current[name] || v[0]);
222
312
 
223
313
  const removePackagesViaKatelloAgent = () => {
224
314
  dispatch(removePackageViaKatelloAgent(hostId, { packages: selectedPackageNames() }));
@@ -243,7 +333,9 @@ export const PackagesTab = () => {
243
333
  }
244
334
  };
245
335
 
246
- const upgradeViaRemoteExecution = packageName => triggerPackageUpgrade(packageName);
336
+ const upgradeViaRemoteExecution = ({ packageName, upgradableVersions }) => (
337
+ triggerPackageUpgrade({ packageName, upgradableVersions })
338
+ );
247
339
 
248
340
  const upgradeBulkViaRemoteExecution = () => {
249
341
  const selected = fetchBulkParams();
@@ -270,13 +362,16 @@ export const PackagesTab = () => {
270
362
  };
271
363
 
272
364
  const upgradeViaCustomizedRemoteExecution = selectedCount ?
273
- packagesUpdateUrl({ hostname, search: fetchBulkParams() }) :
274
- '#';
365
+ packagesUpdateUrl({
366
+ hostname,
367
+ search: fetchBulkParams(),
368
+ versions: JSON.stringify(selectedNVRAVersions),
369
+ }) : '#';
275
370
 
276
371
  const disableRemove = () => selectedCount === 0 || selectAllMode;
277
372
 
278
373
  const allUpgradable = () => selectedResults.length > 0 &&
279
- selectedResults.every(item => item.upgradable_version);
374
+ selectedResults.every(item => item.upgradable_versions?.length > 0);
280
375
  const disableUpgrade = () => selectedCount === 0 ||
281
376
  (selectAllMode && packageStatusSelected !== 'Upgradable') ||
282
377
  (defaultRemoteAction === KATELLO_AGENT && selectAllMode && !areAllRowsSelected()) ||
@@ -288,6 +383,7 @@ export const PackagesTab = () => {
288
383
  const dropdownUpgradeItems = [
289
384
  <DropdownItem
290
385
  aria-label="bulk_upgrade_rex"
386
+ ouiaId="bulk_upgrade_rex"
291
387
  key="bulk_upgrade_rex"
292
388
  component="button"
293
389
  onClick={upgradeBulkViaRemoteExecution}
@@ -296,6 +392,7 @@ export const PackagesTab = () => {
296
392
  </DropdownItem>,
297
393
  <DropdownItem
298
394
  aria-label="bulk_upgrade_customized_rex"
395
+ ouiaId="bulk_upgrade_customized_rex"
299
396
  key="bulk_upgrade_customized_rex"
300
397
  component="a"
301
398
  href={upgradeViaCustomizedRemoteExecution}
@@ -307,6 +404,7 @@ export const PackagesTab = () => {
307
404
  const dropdownRemoveItems = [
308
405
  <DropdownItem
309
406
  aria-label="bulk_remove"
407
+ ouiaId="bulk_remove"
310
408
  key="bulk_remove"
311
409
  component="button"
312
410
  onClick={removeBulk}
@@ -314,9 +412,10 @@ export const PackagesTab = () => {
314
412
  >
315
413
  {__('Remove')}
316
414
  </DropdownItem>,
317
- <DropdownSeparator key="separator" />,
415
+ <DropdownSeparator key="separator" ouiaId="separator" />,
318
416
  <DropdownItem
319
417
  aria-label="install_pkg_on_host"
418
+ ouiaId="install_pkg_on_host"
320
419
  key="install_pkg_on_host"
321
420
  component="button"
322
421
  onClick={handleInstallPackagesClick}
@@ -338,9 +437,11 @@ export const PackagesTab = () => {
338
437
  <ActionList isIconList>
339
438
  <ActionListItem>
340
439
  <Dropdown
440
+ ouiaId="upgrade_actions_dropdown"
341
441
  onSelect={onActionSelect}
342
442
  toggle={
343
443
  <DropdownToggle
444
+ ouiaId="upgrade_actions_dropdown_toggle"
344
445
  splitButtonItems={[
345
446
  <DropdownToggleAction key="action" aria-label="upgrade_actions" onClick={upgradeBulk}>
346
447
  {__('Upgrade')}
@@ -362,6 +463,7 @@ export const PackagesTab = () => {
362
463
  isOpen={isBulkActionOpen}
363
464
  isPlain
364
465
  dropdownItems={dropdownRemoveItems}
466
+ ouiaId="bulk_actions_dropdown"
365
467
  />
366
468
  </ActionListItem>
367
469
  </ActionList>
@@ -429,7 +531,7 @@ export const PackagesTab = () => {
429
531
  alwaysShowActionButtons={false}
430
532
  >
431
533
  <Thead>
432
- <Tr>
534
+ <Tr ouiaId="row-header">
433
535
  <Th key="select-all" />
434
536
  <SortableColumnHeaders
435
537
  columnHeaders={columnHeaders}
@@ -446,7 +548,7 @@ export const PackagesTab = () => {
446
548
  name: packageName,
447
549
  nvra: installedVersion,
448
550
  rpm_id: rpmId,
449
- upgradable_version: upgradableVersion,
551
+ upgradable_versions: upgradableVersions,
450
552
  } = pkg;
451
553
 
452
554
  const rowActions = [
@@ -457,23 +559,29 @@ export const PackagesTab = () => {
457
559
  },
458
560
  ];
459
561
 
460
- if (upgradableVersion) {
562
+ if (upgradableVersions) {
461
563
  rowActions.unshift(
462
564
  {
463
565
  title: __('Upgrade via remote execution'),
464
- onClick: () => upgradeViaRemoteExecution(upgradableVersion),
566
+ onClick: () => upgradeViaRemoteExecution({ packageName, upgradableVersions }),
465
567
  isDisabled: actionInProgress,
466
568
  },
467
569
  {
468
570
  title: __('Upgrade via customized remote execution'),
469
571
  component: 'a',
470
- href: katelloPackageUpdateUrl({ hostname, packageName: upgradableVersion }),
572
+ href: katelloPackageUpdateUrl({
573
+ hostname,
574
+ packageName: selectedPackageUpgradeVersion({
575
+ packageName,
576
+ upgradableVersions,
577
+ }),
578
+ }),
471
579
  },
472
580
  );
473
581
  }
474
582
 
475
583
  return (
476
- <Tr key={`${id}`}>
584
+ <Tr key={`${id}`} ouiaId={`action-row-${id}`}>
477
585
  {showActions ? (
478
586
  <Td
479
587
  select={{
@@ -494,7 +602,17 @@ export const PackagesTab = () => {
494
602
  </Td>
495
603
  <Td><PackagesStatus {...pkg} /></Td>
496
604
  <Td>{installedVersion.replace(`${packageName}-`, '')}</Td>
497
- <Td><PackagesLatestVersion {...pkg} /></Td>
605
+ <Td>
606
+ <UpdateVersionsSelect
607
+ packageName={packageName}
608
+ rowIndex={rowIndex}
609
+ selections={selectedNewVersions.current[packageName]}
610
+ upgradableVersions={upgradableVersions}
611
+ toggleUpgradableVersionSelect={toggleUpgradableVersionSelect}
612
+ onUpgradableVersionSelect={onUpgradableVersionSelect}
613
+ upgradableVersionSelectOpen={upgradableVersionSelectOpen}
614
+ />
615
+ </Td>
498
616
  {showActions ? (
499
617
  <Td
500
618
  key={`rowActions-${id}`}
@@ -4,4 +4,9 @@
4
4
 
5
5
  #packages-alert {
6
6
  margin: 16px 24px;
7
- }
7
+ }
8
+
9
+ #style-select-id .pf-c-select button.pf-c-select__toggle {
10
+ font-size: 1em;
11
+ margin-left: -0.5rem;
12
+ }
@@ -6,7 +6,7 @@ import { errorToast, renderRexJobStartedToast } from '../../../../scenes/Tasks/h
6
6
  import { ERRATA_SEARCH_QUERY } from './ErrataTab/HostErrataConstants';
7
7
  import { TRACES_SEARCH_QUERY } from './TracesTab/HostTracesConstants';
8
8
  import { PACKAGE_SEARCH_QUERY } from './PackagesTab/YumInstallablePackagesConstants';
9
- import { PACKAGES_SEARCH_QUERY } from './PackagesTab/HostPackagesConstants';
9
+ import { PACKAGES_SEARCH_QUERY, SELECTED_UPDATE_VERSIONS } from './PackagesTab/HostPackagesConstants';
10
10
 
11
11
  // PARAM BUILDING
12
12
  const baseParams = ({ feature, hostname, inputs = {} }) => ({
@@ -54,12 +54,13 @@ const katelloPackageUpdateParams = ({ hostname, packageName }) =>
54
54
  feature: REX_FEATURES.KATELLO_PACKAGE_UPDATE,
55
55
  });
56
56
 
57
- const katelloPackagesUpdateParams = ({ hostname, search }) =>
58
- baseParams({
59
- hostname,
60
- inputs: { [PACKAGES_SEARCH_QUERY]: search },
57
+ const katelloPackagesUpdateParams = ({ hostname, search, versions }) => ({
58
+ job_invocation: {
61
59
  feature: REX_FEATURES.KATELLO_PACKAGES_UPDATE_BY_SEARCH,
62
- });
60
+ inputs: { [PACKAGES_SEARCH_QUERY]: search, [SELECTED_UPDATE_VERSIONS]: versions },
61
+ search_query: `name ^ (${hostname})`,
62
+ },
63
+ });
63
64
 
64
65
  const katelloTracerResolveParams = ({ hostname, search }) =>
65
66
  baseParams({
@@ -150,11 +151,11 @@ export const updatePackage = ({ hostname, packageName }) => post({
150
151
  errorToast,
151
152
  });
152
153
 
153
- export const updatePackages = ({ hostname, search }) => post({
154
+ export const updatePackages = ({ hostname, search, versions }) => post({
154
155
  type: API_OPERATIONS.POST,
155
156
  key: REX_JOB_INVOCATIONS_KEY,
156
157
  url: foremanApi.getApiUrl('/job_invocations'),
157
- params: katelloPackagesUpdateParams({ hostname, search }),
158
+ params: katelloPackagesUpdateParams({ hostname, search, versions }),
158
159
  handleSuccess: showRexToast,
159
160
  errorToast,
160
161
  });