katello 4.18.1 → 4.19.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of katello might be problematic. Click here for more details.

Files changed (336) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/locale/bn/katello.js +56 -107
  3. data/app/assets/javascripts/katello/locale/bn_IN/katello.js +56 -107
  4. data/app/assets/javascripts/katello/locale/ca/katello.js +56 -107
  5. data/app/assets/javascripts/katello/locale/cs/katello.js +56 -107
  6. data/app/assets/javascripts/katello/locale/cs_CZ/katello.js +57 -108
  7. data/app/assets/javascripts/katello/locale/de/katello.js +58 -109
  8. data/app/assets/javascripts/katello/locale/de_AT/katello.js +56 -107
  9. data/app/assets/javascripts/katello/locale/de_DE/katello.js +56 -107
  10. data/app/assets/javascripts/katello/locale/el/katello.js +57 -108
  11. data/app/assets/javascripts/katello/locale/en/katello.js +56 -107
  12. data/app/assets/javascripts/katello/locale/en_GB/katello.js +56 -107
  13. data/app/assets/javascripts/katello/locale/en_US/katello.js +56 -107
  14. data/app/assets/javascripts/katello/locale/es/katello.js +58 -109
  15. data/app/assets/javascripts/katello/locale/et_EE/katello.js +56 -107
  16. data/app/assets/javascripts/katello/locale/fr/katello.js +59 -110
  17. data/app/assets/javascripts/katello/locale/gl/katello.js +56 -107
  18. data/app/assets/javascripts/katello/locale/gu/katello.js +56 -107
  19. data/app/assets/javascripts/katello/locale/he_IL/katello.js +56 -107
  20. data/app/assets/javascripts/katello/locale/hi/katello.js +56 -107
  21. data/app/assets/javascripts/katello/locale/id/katello.js +56 -107
  22. data/app/assets/javascripts/katello/locale/it/katello.js +56 -107
  23. data/app/assets/javascripts/katello/locale/ja/katello.js +59 -110
  24. data/app/assets/javascripts/katello/locale/ka/katello.js +58 -109
  25. data/app/assets/javascripts/katello/locale/kn/katello.js +56 -107
  26. data/app/assets/javascripts/katello/locale/ko/katello.js +59 -110
  27. data/app/assets/javascripts/katello/locale/ml_IN/katello.js +56 -107
  28. data/app/assets/javascripts/katello/locale/mr/katello.js +56 -107
  29. data/app/assets/javascripts/katello/locale/nl_NL/katello.js +56 -107
  30. data/app/assets/javascripts/katello/locale/or/katello.js +56 -107
  31. data/app/assets/javascripts/katello/locale/pa/katello.js +56 -107
  32. data/app/assets/javascripts/katello/locale/pl/katello.js +56 -107
  33. data/app/assets/javascripts/katello/locale/pl_PL/katello.js +56 -107
  34. data/app/assets/javascripts/katello/locale/pt/katello.js +56 -107
  35. data/app/assets/javascripts/katello/locale/pt_BR/katello.js +58 -109
  36. data/app/assets/javascripts/katello/locale/ro/katello.js +56 -107
  37. data/app/assets/javascripts/katello/locale/ro_RO/katello.js +56 -107
  38. data/app/assets/javascripts/katello/locale/ru/katello.js +57 -108
  39. data/app/assets/javascripts/katello/locale/sl/katello.js +56 -107
  40. data/app/assets/javascripts/katello/locale/sv_SE/katello.js +56 -107
  41. data/app/assets/javascripts/katello/locale/ta/katello.js +56 -107
  42. data/app/assets/javascripts/katello/locale/ta_IN/katello.js +56 -107
  43. data/app/assets/javascripts/katello/locale/te/katello.js +56 -107
  44. data/app/assets/javascripts/katello/locale/tr/katello.js +56 -107
  45. data/app/assets/javascripts/katello/locale/vi/katello.js +56 -107
  46. data/app/assets/javascripts/katello/locale/vi_VN/katello.js +56 -107
  47. data/app/assets/javascripts/katello/locale/zh/katello.js +56 -107
  48. data/app/assets/javascripts/katello/locale/zh_CN/katello.js +59 -110
  49. data/app/assets/javascripts/katello/locale/zh_TW/katello.js +57 -108
  50. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +41 -12
  51. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +1 -1
  52. data/app/controllers/katello/api/v2/activation_keys_controller.rb +3 -65
  53. data/app/controllers/katello/api/v2/content_view_filter_rules_controller.rb +1 -1
  54. data/app/controllers/katello/api/v2/content_views_controller.rb +18 -3
  55. data/app/controllers/katello/api/v2/debs_controller.rb +21 -11
  56. data/app/controllers/katello/api/v2/docker_tags_controller.rb +7 -0
  57. data/app/controllers/katello/api/v2/flatpak_remote_repositories_controller.rb +21 -19
  58. data/app/controllers/katello/api/v2/host_debs_controller.rb +16 -1
  59. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +3 -60
  60. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +10 -53
  61. data/app/controllers/katello/api/v2/repositories_controller.rb +0 -1
  62. data/app/controllers/katello/concerns/organizations_controller_extensions.rb +3 -0
  63. data/app/lib/actions/candlepin/activation_key/create.rb +0 -2
  64. data/app/lib/actions/candlepin/activation_key/update.rb +0 -2
  65. data/app/lib/actions/candlepin/product/content_create.rb +3 -5
  66. data/app/lib/actions/candlepin/product/content_update.rb +2 -3
  67. data/app/lib/actions/helpers/rolling_cv_repos.rb +1 -1
  68. data/app/lib/actions/katello/activation_key/create.rb +0 -1
  69. data/app/lib/actions/katello/activation_key/update.rb +0 -2
  70. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +1 -6
  71. data/app/lib/actions/katello/content_credential/update.rb +1 -1
  72. data/app/lib/actions/katello/content_view/add_rolling_repo_clone.rb +18 -24
  73. data/app/lib/actions/katello/content_view/create.rb +9 -4
  74. data/app/lib/actions/katello/content_view/refresh_rolling_repo.rb +6 -1
  75. data/app/lib/actions/katello/content_view/remove_rolling_repo_clone.rb +16 -11
  76. data/app/lib/actions/katello/content_view/update.rb +34 -7
  77. data/app/lib/actions/katello/product/content_create.rb +2 -2
  78. data/app/lib/actions/katello/product/content_destroy.rb +1 -1
  79. data/app/lib/actions/katello/repository/check_matching_content.rb +1 -1
  80. data/app/lib/actions/katello/repository/clone_contents.rb +1 -1
  81. data/app/lib/actions/katello/repository/create.rb +1 -1
  82. data/app/lib/actions/katello/repository/destroy.rb +4 -4
  83. data/app/lib/actions/katello/repository/finish_upload.rb +1 -1
  84. data/app/lib/actions/katello/repository/sync.rb +1 -1
  85. data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +2 -2
  86. data/app/lib/actions/pulp3/orchestration/repository/generate_metadata.rb +1 -1
  87. data/app/lib/actions/pulp3/orchestration/repository/multi_copy_all_units.rb +1 -1
  88. data/app/lib/actions/pulp3/repository/save_publication.rb +3 -1
  89. data/app/lib/actions/pulp3/repository/save_version.rb +45 -24
  90. data/app/lib/actions/pulp3/repository/save_versions.rb +2 -1
  91. data/app/lib/katello/resources/candlepin/activation_key.rb +3 -4
  92. data/app/lib/katello/resources/candlepin/upstream_job.rb +9 -1
  93. data/app/lib/katello/resources/candlepin.rb +4 -0
  94. data/app/models/katello/authorization/repository.rb +17 -4
  95. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +0 -7
  96. data/app/models/katello/content_view_deb_filter.rb +10 -0
  97. data/app/models/katello/content_view_deb_filter_rule.rb +7 -0
  98. data/app/models/katello/deb.rb +10 -10
  99. data/app/models/katello/erratum.rb +1 -1
  100. data/app/models/katello/glue/provider.rb +14 -3
  101. data/app/models/katello/host/content_facet.rb +1 -1
  102. data/app/models/katello/host/subscription_facet.rb +1 -7
  103. data/app/models/katello/product_content.rb +2 -2
  104. data/app/models/katello/repository.rb +4 -23
  105. data/app/models/katello/root_repository.rb +2 -5
  106. data/app/services/katello/candlepin/event_handler.rb +0 -33
  107. data/app/services/katello/candlepin/message_handler.rb +0 -41
  108. data/app/services/katello/content_unit_indexer.rb +59 -13
  109. data/app/services/katello/product_content_finder.rb +5 -4
  110. data/app/services/katello/pulp3/alternate_content_source.rb +2 -2
  111. data/app/services/katello/pulp3/ansible_collection.rb +1 -0
  112. data/app/services/katello/pulp3/api/content_guard.rb +5 -5
  113. data/app/services/katello/pulp3/api/core.rb +10 -0
  114. data/app/services/katello/pulp3/deb.rb +1 -0
  115. data/app/services/katello/pulp3/docker_manifest.rb +1 -0
  116. data/app/services/katello/pulp3/docker_manifest_list.rb +1 -0
  117. data/app/services/katello/pulp3/docker_tag.rb +1 -0
  118. data/app/services/katello/pulp3/file_unit.rb +1 -0
  119. data/app/services/katello/pulp3/generic_content_unit.rb +1 -0
  120. data/app/services/katello/pulp3/module_stream.rb +1 -0
  121. data/app/services/katello/pulp3/package_group.rb +1 -0
  122. data/app/services/katello/pulp3/repository/apt.rb +30 -13
  123. data/app/services/katello/pulp3/repository.rb +59 -10
  124. data/app/services/katello/pulp3/rpm.rb +3 -2
  125. data/app/services/katello/pulp3/srpm.rb +3 -2
  126. data/app/services/katello/pulp3/task_group.rb +1 -1
  127. data/app/services/katello/registration_manager.rb +19 -17
  128. data/app/services/katello/repository_type_manager.rb +7 -5
  129. data/app/services/katello/smart_proxy_helper.rb +1 -6
  130. data/app/views/foreman/job_templates/upload_profile.erb +5 -0
  131. data/app/views/katello/api/v2/activation_keys/base.json.rabl +1 -1
  132. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -0
  133. data/app/views/katello/api/v2/debs/thindex.json.rabl +6 -0
  134. data/app/views/katello/api/v2/docker_tags/_base.json.rabl +32 -0
  135. data/app/views/katello/api/v2/docker_tags/show.json.rabl +0 -5
  136. data/app/views/katello/api/v2/flatpak_remotes/index.json.rabl +6 -0
  137. data/app/views/katello/api/v2/host_debs/installed_debs.json.rabl +6 -0
  138. data/app/views/katello/api/v2/hosts_bulk_actions/applicable_errata.json.rabl +1 -1
  139. data/app/views/katello/api/v2/hosts_bulk_actions/applicable_erratum.json.rabl +9 -0
  140. data/app/views/katello/api/v2/hosts_bulk_actions/installable_errata.json.rabl +1 -1
  141. data/app/views/katello/api/v2/hosts_bulk_actions/{erratum.json.rabl → installable_erratum.json.rabl} +3 -3
  142. data/app/views/katello/api/v2/subscription_facet/base.json.rabl +1 -1
  143. data/config/initializers/monkeys.rb +1 -0
  144. data/config/routes/api/v2.rb +2 -2
  145. data/config/routes/overrides.rb +2 -7
  146. data/config/routes.rb +2 -0
  147. data/db/migrate/20211019192121_create_cdn_configuration.katello.rb +1 -1
  148. data/db/migrate/20250912000000_add_pulp_prn_fields.rb +73 -0
  149. data/db/migrate/20250912000001_populate_pulp_prn_fields.rb +403 -0
  150. data/db/migrate/20251009142516_remove_auto_attach_from_activation_keys.rb +5 -0
  151. data/db/migrate/20251009142517_remove_autoheal_from_subscription_facets.rb +5 -0
  152. data/db/seeds.d/111-upgrade_tasks.rb +2 -0
  153. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/el.po +2 -2
  154. data/lib/katello/permission_creator.rb +2 -2
  155. data/lib/katello/permissions/host_permissions.rb +0 -6
  156. data/lib/katello/plugin.rb +16 -8
  157. data/lib/katello/tasks/jenkins.rake +1 -1
  158. data/lib/katello/tasks/upgrades/4.19/enable_structured_apt_for_deb.rake +87 -0
  159. data/lib/katello/tasks/upgrades/4.19/populate_repository_version_prns.rake +32 -0
  160. data/lib/katello/version.rb +1 -1
  161. data/lib/monkeys/fix_rpm_repository_gpgcheck.rb +38 -0
  162. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  163. data/locale/bn/katello.po +56 -107
  164. data/locale/bn_IN/LC_MESSAGES/katello.mo +0 -0
  165. data/locale/bn_IN/katello.po +56 -107
  166. data/locale/ca/LC_MESSAGES/katello.mo +0 -0
  167. data/locale/ca/katello.po +56 -107
  168. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  169. data/locale/cs/katello.po +56 -107
  170. data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
  171. data/locale/cs_CZ/katello.po +57 -108
  172. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  173. data/locale/de/katello.po +58 -109
  174. data/locale/de_AT/LC_MESSAGES/katello.mo +0 -0
  175. data/locale/de_AT/katello.po +56 -107
  176. data/locale/de_DE/LC_MESSAGES/katello.mo +0 -0
  177. data/locale/de_DE/katello.po +56 -107
  178. data/locale/el/LC_MESSAGES/katello.mo +0 -0
  179. data/locale/el/katello.po +58 -109
  180. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  181. data/locale/en/katello.po +56 -107
  182. data/locale/en_GB/LC_MESSAGES/katello.mo +0 -0
  183. data/locale/en_GB/katello.po +56 -107
  184. data/locale/en_US/LC_MESSAGES/katello.mo +0 -0
  185. data/locale/en_US/katello.po +56 -107
  186. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  187. data/locale/es/katello.po +58 -109
  188. data/locale/et_EE/LC_MESSAGES/katello.mo +0 -0
  189. data/locale/et_EE/katello.po +56 -107
  190. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  191. data/locale/fr/katello.po +59 -110
  192. data/locale/gl/LC_MESSAGES/katello.mo +0 -0
  193. data/locale/gl/katello.po +56 -107
  194. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  195. data/locale/gu/katello.po +56 -107
  196. data/locale/he_IL/LC_MESSAGES/katello.mo +0 -0
  197. data/locale/he_IL/katello.po +56 -107
  198. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  199. data/locale/hi/katello.po +56 -107
  200. data/locale/id/LC_MESSAGES/katello.mo +0 -0
  201. data/locale/id/katello.po +56 -107
  202. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  203. data/locale/it/katello.po +56 -107
  204. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  205. data/locale/ja/katello.po +59 -110
  206. data/locale/ka/LC_MESSAGES/katello.mo +0 -0
  207. data/locale/ka/katello.po +58 -109
  208. data/locale/katello.pot +676 -749
  209. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  210. data/locale/kn/katello.po +56 -107
  211. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  212. data/locale/ko/katello.po +59 -110
  213. data/locale/ml_IN/LC_MESSAGES/katello.mo +0 -0
  214. data/locale/ml_IN/katello.po +56 -107
  215. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  216. data/locale/mr/katello.po +56 -107
  217. data/locale/nl_NL/LC_MESSAGES/katello.mo +0 -0
  218. data/locale/nl_NL/katello.po +56 -107
  219. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  220. data/locale/or/katello.po +56 -107
  221. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  222. data/locale/pa/katello.po +56 -107
  223. data/locale/pl/LC_MESSAGES/katello.mo +0 -0
  224. data/locale/pl/katello.po +56 -107
  225. data/locale/pl_PL/LC_MESSAGES/katello.mo +0 -0
  226. data/locale/pl_PL/katello.po +56 -107
  227. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  228. data/locale/pt/katello.po +56 -107
  229. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  230. data/locale/pt_BR/katello.po +58 -109
  231. data/locale/ro/LC_MESSAGES/katello.mo +0 -0
  232. data/locale/ro/katello.po +56 -107
  233. data/locale/ro_RO/LC_MESSAGES/katello.mo +0 -0
  234. data/locale/ro_RO/katello.po +56 -107
  235. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  236. data/locale/ru/katello.po +57 -108
  237. data/locale/sl/LC_MESSAGES/katello.mo +0 -0
  238. data/locale/sl/katello.po +56 -107
  239. data/locale/sv_SE/LC_MESSAGES/katello.mo +0 -0
  240. data/locale/sv_SE/katello.po +56 -107
  241. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  242. data/locale/ta/katello.po +56 -107
  243. data/locale/ta_IN/LC_MESSAGES/katello.mo +0 -0
  244. data/locale/ta_IN/katello.po +56 -107
  245. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  246. data/locale/te/katello.po +56 -107
  247. data/locale/tr/LC_MESSAGES/katello.mo +0 -0
  248. data/locale/tr/katello.po +56 -107
  249. data/locale/vi/LC_MESSAGES/katello.mo +0 -0
  250. data/locale/vi/katello.po +56 -107
  251. data/locale/vi_VN/LC_MESSAGES/katello.mo +0 -0
  252. data/locale/vi_VN/katello.po +56 -107
  253. data/locale/zh/LC_MESSAGES/katello.mo +0 -0
  254. data/locale/zh/katello.po +56 -107
  255. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  256. data/locale/zh_CN/katello.po +59 -110
  257. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  258. data/locale/zh_TW/katello.po +57 -108
  259. data/webpack/components/Content/Details/__tests__/__snapshots__/ContentDetails.test.js.snap +2 -2
  260. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeEditModal.js +0 -2
  261. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeEditModal.test.js +0 -2
  262. data/webpack/components/extensions/Hosts/ActionsBar/index.js +1 -0
  263. data/webpack/components/extensions/Hosts/BulkActions/BulkActionsConstants.js +7 -0
  264. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/BulkChangeHostCollectionsModal.js +388 -0
  265. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/__tests__/BulkChangeHostCollectionsModal.test.js +640 -0
  266. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/actions.js +28 -0
  267. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/index.js +71 -0
  268. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/BulkErrataWizard.js +1 -1
  269. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/02_BulkPackagesTable.js +10 -3
  270. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/BulkPackagesWizard.js +51 -24
  271. data/webpack/components/extensions/Hosts/BulkActions/HostReview.js +7 -0
  272. data/webpack/containers/Application/config.js +11 -1
  273. data/webpack/global_index.js +3 -0
  274. data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/BootedContainerImagesConstants.js +1 -1
  275. data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/BootedContainerImagesPage.js +7 -43
  276. data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/__tests__/bootedContainerImagesPage.test.js +1 -1
  277. data/webpack/scenes/ContainerImages/ContainerImagesPage.js +86 -0
  278. data/webpack/scenes/ContainerImages/LabelsAnnotationsModal.js +105 -0
  279. data/webpack/scenes/ContainerImages/Synced/Details/ManifestDetails.js +218 -0
  280. data/webpack/scenes/ContainerImages/Synced/Details/ManifestDetailsActions.js +15 -0
  281. data/webpack/scenes/ContainerImages/Synced/Details/ManifestDetailsSelectors.js +16 -0
  282. data/webpack/scenes/ContainerImages/Synced/Details/__tests__/ManifestDetails.test.js +395 -0
  283. data/webpack/scenes/ContainerImages/Synced/Details/__tests__/manifestDetails.fixtures.json +43 -0
  284. data/webpack/scenes/ContainerImages/Synced/Details/__tests__/manifestList.fixtures.json +58 -0
  285. data/webpack/scenes/ContainerImages/Synced/Details/index.js +4 -0
  286. data/webpack/scenes/ContainerImages/Synced/SyncedContainerImagesPage.js +359 -0
  287. data/webpack/scenes/ContainerImages/Synced/SyncedContainerImagesPage.scss +21 -0
  288. data/webpack/scenes/ContainerImages/Synced/__tests__/LabelsAnnotationsModal.test.js +69 -0
  289. data/webpack/scenes/ContainerImages/Synced/__tests__/SyncedContainerImagesPage.test.js +335 -0
  290. data/webpack/scenes/ContainerImages/Synced/__tests__/syncedContainerImages.fixtures.json +105 -0
  291. data/webpack/scenes/ContainerImages/TableEmptyState.js +67 -0
  292. data/webpack/scenes/ContainerImages/containerImagesHelpers.js +48 -0
  293. data/webpack/scenes/ContainerImages/index.js +4 -0
  294. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +29 -3
  295. data/webpack/scenes/ContentViews/Create/__tests__/contentViewCreateResult.fixtures.json +1 -0
  296. data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +45 -1
  297. data/webpack/scenes/ContentViews/Delete/__tests__/affectedHosts.fixtures.json +0 -1
  298. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +59 -1
  299. data/webpack/scenes/ContentViews/Details/Filters/CVDebFilterContent.js +1 -0
  300. data/webpack/scenes/ContentViews/Details/Filters/Rules/DebPackage/AddEditDebPackageRuleModal.js +164 -24
  301. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVDebFilterContent.test.js +268 -0
  302. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvDebFilterDetail.fixtures.json +95 -0
  303. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvDebFilterRules.fixtures.json +31 -0
  304. data/webpack/scenes/ContentViews/Details/Filters/__tests__/emptyCVDebFilterRules.fixtures.json +10 -0
  305. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/hosts.fixtures.json +0 -1
  306. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvAffectedHosts.fixture.json +0 -1
  307. data/webpack/scenes/ContentViews/Details/__tests__/contentViewRollingDetail.test.js +15 -0
  308. data/webpack/scenes/ContentViews/Details/__tests__/contentViewRollingDetails.fixtures.json +1 -0
  309. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +9 -0
  310. data/webpack/scenes/FlatpakRemotes/CreateEdit/CreateFlatpakRemoteModal.js +5 -3
  311. data/webpack/scenes/FlatpakRemotes/CreateEdit/EditFlatpakRemotesModal.js +1 -1
  312. data/webpack/scenes/FlatpakRemotes/CreateEdit/FlatpakRemoteform.js +35 -3
  313. data/webpack/scenes/FlatpakRemotes/Details/FlatpakRemoteDetails.js +1 -1
  314. data/webpack/scenes/FlatpakRemotes/Details/RemoteRepositories/RemoteRepositoriesTable.css +3 -0
  315. data/webpack/scenes/FlatpakRemotes/Details/RemoteRepositories/RemoteRepositoriesTable.js +63 -132
  316. data/webpack/scenes/FlatpakRemotes/FlatpakRemotesPage.js +67 -143
  317. data/webpack/scenes/SmartProxy/ExpandableCvDetails.js +10 -2
  318. data/webpack/scenes/SmartProxy/SmartProxyContentActions.js +13 -2
  319. data/webpack/scenes/SmartProxy/SmartProxyContentConstants.js +1 -0
  320. data/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js +8 -2
  321. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js +67 -1
  322. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +2 -2
  323. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +0 -2
  324. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap +2 -2
  325. metadata +83 -55
  326. data/app/lib/actions/katello/host/attach_subscriptions.rb +0 -59
  327. data/app/lib/actions/katello/host/auto_attach_subscriptions.rb +0 -22
  328. data/app/lib/actions/katello/host/remove_subscriptions.rb +0 -50
  329. data/app/lib/actions/katello/organization/simple_content_access/disable.rb +0 -25
  330. data/app/lib/actions/katello/organization/simple_content_access/enable.rb +0 -25
  331. data/app/lib/actions/katello/organization/simple_content_access/toggle.rb +0 -42
  332. data/lib/katello/tasks/migrate_structure_content_for_deb.rake +0 -105
  333. data/lib/katello/tasks/upgrades/4.2/remove_checksum_values.rake +0 -17
  334. data/locale/action_names.rb +0 -186
  335. /data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/__tests__/bootedContainerImages.fixtures.js +0 -0
  336. /data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/index.js +0 -0
@@ -0,0 +1,388 @@
1
+ import React, { useState, useCallback } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { useDispatch } from 'react-redux';
4
+ import { FormattedMessage } from 'react-intl';
5
+ import {
6
+ Modal,
7
+ Button,
8
+ Radio,
9
+ TextContent,
10
+ Text,
11
+ ToolbarItem,
12
+ } from '@patternfly/react-core';
13
+ import { ExclamationTriangleIcon } from '@patternfly/react-icons';
14
+ import { addToast } from 'foremanReact/components/ToastsList';
15
+ import { translate as __ } from 'foremanReact/common/I18n';
16
+ import { STATUS } from 'foremanReact/constants';
17
+ import { foremanUrl, noop } from 'foremanReact/common/helpers';
18
+ import { APIActions } from 'foremanReact/redux/API';
19
+ import {
20
+ HOSTS_API_PATH,
21
+ API_REQUEST_KEY,
22
+ } from 'foremanReact/routes/Hosts/constants';
23
+ import { useForemanOrganization } from 'foremanReact/Root/Context/ForemanContext';
24
+ import { useTableIndexAPIResponse, useSetParamsAndApiAndSearch } from 'foremanReact/components/PF4/TableIndexPage/Table/TableIndexHooks';
25
+ import { useBulkSelect } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
26
+ import { getPageStats } from 'foremanReact/components/PF4/TableIndexPage/Table/helpers';
27
+ import TableIndexPage from 'foremanReact/components/PF4/TableIndexPage/TableIndexPage';
28
+ import { Table } from 'foremanReact/components/PF4/TableIndexPage/Table/Table';
29
+ import SelectAllCheckbox from 'foremanReact/components/PF4/TableIndexPage/Table/SelectAllCheckbox';
30
+ import {
31
+ bulkAddHostCollections,
32
+ bulkRemoveHostCollections,
33
+ } from './actions';
34
+ import katelloApi from '../../../../../services/api';
35
+
36
+ const BulkChangeHostCollectionsModal = ({
37
+ isOpen,
38
+ closeModal,
39
+ fetchBulkParams,
40
+ selectedCount: selectedHostsCount,
41
+ }) => {
42
+ const dispatch = useDispatch();
43
+ const [addRadioChecked, setAddRadioChecked] = useState(true);
44
+
45
+ const orgId = useForemanOrganization()?.id;
46
+ const DEFAULT_PER_PAGE = 5;
47
+ const hostCollectionsUrlForOrg =
48
+ katelloApi.getApiUrl(`/host_collections?per_page=${DEFAULT_PER_PAGE}&include_permissions=true&enabled=true&with_custom=true&organization_id=${orgId}`);
49
+ const apiOptions = { key: 'BULK_HOST_COLLECTIONS' };
50
+ const replacementResponse = isOpen ? false : { response: {} };
51
+
52
+ const hostCollectionsResponse = useTableIndexAPIResponse({
53
+ replacementResponse, // don't fetch data if modal is closed
54
+ apiUrl: hostCollectionsUrlForOrg,
55
+ apiOptions,
56
+ defaultParams: { per_page: DEFAULT_PER_PAGE },
57
+ });
58
+
59
+ const {
60
+ response: {
61
+ results: hostCollectionsResults,
62
+ ...hostCollectionsMetadata
63
+ },
64
+ setAPIOptions,
65
+ status: hostCollectionsLoadingStatus,
66
+ } = hostCollectionsResponse;
67
+
68
+ const {
69
+ total, page, subtotal, per_page: perPage,
70
+ } = hostCollectionsMetadata;
71
+
72
+ // Function to determine if a host collection row should be selectable
73
+ const isSelectableRow = useCallback((hc) => {
74
+ // When removing, all collections are selectable
75
+ if (!addRadioChecked) return true;
76
+
77
+ // When adding, check if there's enough space for the selected hosts
78
+ if (hc?.unlimited_hosts) return true; // Unlimited collections always have space
79
+
80
+ const currentHosts = Number(hc?.total_hosts || 0);
81
+ const maxHosts = Number(hc?.max_hosts || 0);
82
+ const availableSpace = maxHosts - currentHosts;
83
+
84
+ // Collection is selectable only if it has enough space for all selected hosts
85
+ return availableSpace >= selectedHostsCount;
86
+ }, [addRadioChecked, selectedHostsCount]);
87
+
88
+ const hostCollectionsBulkSelect = useBulkSelect({
89
+ results: hostCollectionsResults,
90
+ metadata: { total, page, selectable: subtotal },
91
+ isSelectable: isSelectableRow,
92
+ });
93
+
94
+ const {
95
+ setParamsAndAPI: setHostCollectionsParamsAndAPI,
96
+ } = useSetParamsAndApiAndSearch({
97
+ defaultParams: { search: '' },
98
+ apiOptions,
99
+ setAPIOptions,
100
+ updateSearchQuery: hostCollectionsBulkSelect.updateSearchQuery,
101
+ pushToHistory: false,
102
+ });
103
+
104
+ const {
105
+ selectNone,
106
+ selectOne,
107
+ selectPage,
108
+ isSelected,
109
+ selectedCount,
110
+ selectedResults,
111
+ areAllRowsSelected,
112
+ areAllRowsOnPageSelected,
113
+ updateSearchQuery,
114
+ } = hostCollectionsBulkSelect;
115
+
116
+ const pageStats = getPageStats({ total: subtotal, page, perPage });
117
+
118
+ // Handler for switching between Add/Remove modes
119
+ const handleRadioChange = (isAdd) => {
120
+ setAddRadioChecked(isAdd);
121
+
122
+ // If switching to "Add" mode, deselect any collections that don't have enough space
123
+ if (isAdd) {
124
+ selectedResults.forEach((hc) => {
125
+ if (!isSelectableRow(hc)) {
126
+ selectOne(false, hc.id);
127
+ }
128
+ });
129
+ }
130
+ };
131
+
132
+ // Derive selected IDs directly from selectedResults instead of storing in state
133
+ const HCIds = selectedResults.map(result => result.id);
134
+
135
+ const handleModalClose = () => {
136
+ setAddRadioChecked(true);
137
+ selectNone();
138
+ setHostCollectionsParamsAndAPI({ page: 1 });
139
+ closeModal();
140
+ };
141
+
142
+ const handleError = (error) => {
143
+ const message = error?.response?.data?.error?.message || __('An error occurred while updating host collections');
144
+ dispatch(addToast({ type: 'danger', message }));
145
+ };
146
+
147
+ const handleSuccess = (response) => {
148
+ const messages = response?.data?.displayMessages;
149
+ const message = Array.isArray(messages) && messages.length > 0
150
+ ? (
151
+ <>
152
+ {messages.map(msg => (
153
+ <div key={msg}>{msg}</div>
154
+ ))}
155
+ </>
156
+ )
157
+ : __('Host collections updated');
158
+
159
+ dispatch(addToast({ type: 'success', message }));
160
+ dispatch(APIActions.get({
161
+ key: API_REQUEST_KEY,
162
+ url: foremanUrl(HOSTS_API_PATH),
163
+ }));
164
+ handleModalClose();
165
+ };
166
+
167
+ const handleSave = () => {
168
+ const requestBody = {
169
+ included: {
170
+ search: fetchBulkParams(),
171
+ },
172
+ host_collection_ids: HCIds,
173
+ organization_id: orgId,
174
+ };
175
+
176
+ if (addRadioChecked) {
177
+ dispatch(bulkAddHostCollections(requestBody, handleSuccess, handleError));
178
+ } else {
179
+ dispatch(bulkRemoveHostCollections(requestBody, handleSuccess, handleError));
180
+ }
181
+ };
182
+
183
+ const isLoadingHostCollections = hostCollectionsLoadingStatus === STATUS.PENDING;
184
+ const isSaveDisabled = HCIds.length === 0 || isLoadingHostCollections;
185
+
186
+ // Selection toolbar
187
+ const selectionToolbar = (
188
+ <ToolbarItem key="selectAll">
189
+ <SelectAllCheckbox
190
+ {...{
191
+ selectAll: noop,
192
+ selectOne,
193
+ updateSearchQuery,
194
+ selectNone,
195
+ selectPage,
196
+ selectedCount,
197
+ pageRowCount: pageStats.pageRowCount,
198
+ areAllRowsSelected,
199
+ areAllRowsOnPageSelected,
200
+ }}
201
+ totalCount={total}
202
+ areAllRowsOnPageSelected={areAllRowsOnPageSelected()}
203
+ areAllRowsSelected={areAllRowsSelected()}
204
+ />
205
+ </ToolbarItem>
206
+ );
207
+
208
+ const modalActions = [
209
+ <Button
210
+ key="save"
211
+ ouiaId="bulk-change-host-collections-modal-save-button"
212
+ variant="primary"
213
+ onClick={handleSave}
214
+ isDisabled={isSaveDisabled}
215
+ isLoading={isLoadingHostCollections}
216
+ >
217
+ {__('Save')}
218
+ </Button>,
219
+ <Button
220
+ key="cancel"
221
+ ouiaId="bulk-change-host-collections-modal-cancel-button"
222
+ variant="link"
223
+ onClick={handleModalClose}
224
+ >
225
+ {__('Cancel')}
226
+ </Button>,
227
+ ];
228
+
229
+ const columns = {
230
+ name: {
231
+ title: __('Host collection'),
232
+ wrapper: hc => hc?.name || '',
233
+ isSorted: true,
234
+ weight: 50,
235
+ },
236
+ limit: {
237
+ title: __('Limit'),
238
+ wrapper: (hc) => {
239
+ const totalLimit = hc?.unlimited_hosts ? 'unlimited' : (hc?.max_hosts || 0);
240
+ const count = Number(hc?.total_hosts || 0);
241
+ const maxHosts = Number(hc?.max_hosts || 0);
242
+ const availableSpace = maxHosts - count;
243
+
244
+ // Show warning if collection doesn't have enough space for selected hosts (when adding)
245
+ const showWarning = addRadioChecked
246
+ && !hc?.unlimited_hosts
247
+ && availableSpace < selectedHostsCount;
248
+
249
+ return (
250
+ <>
251
+ {showWarning && (
252
+ <ExclamationTriangleIcon
253
+ color="var(--pf-v5-global--warning-color--100)"
254
+ style={{ marginRight: '8px' }}
255
+ aria-label={__('Insufficient space for selected hosts')}
256
+ />
257
+ )}
258
+ {`${count}/${totalLimit}`}
259
+ </>
260
+ );
261
+ },
262
+ isSorted: false,
263
+ weight: 100,
264
+ },
265
+ description: {
266
+ title: __('Description'),
267
+ wrapper: hc => hc?.description || '',
268
+ isSorted: false,
269
+ weight: 150,
270
+ },
271
+ };
272
+
273
+ return (
274
+ <Modal
275
+ isOpen={isOpen}
276
+ onClose={handleModalClose}
277
+ onEscapePress={handleModalClose}
278
+ title={__('Change host collections')}
279
+ width="60%"
280
+ position="top"
281
+ actions={modalActions}
282
+ id="bulk-update-host-collections-modal"
283
+ key="bulk-update-host-collections-modal"
284
+ ouiaId="bulk-update-host-collections-modal"
285
+ >
286
+ <TextContent>
287
+ <Text ouiaId="bulk-update-host-collections-text">
288
+ <FormattedMessage
289
+ defaultMessage={__('Select host collections to change their associations with {selectedHosts}. Changing host collection will affect all your selected hosts. Some hosts may already be in your chosen collections.')}
290
+ values={{
291
+ selectedHosts: (
292
+ <strong>
293
+ <FormattedMessage
294
+ defaultMessage="{count, plural, one {# {singular}} other {# {plural}}}"
295
+ values={{
296
+ count: selectedHostsCount,
297
+ singular: __('selected host'),
298
+ plural: __('selected hosts'),
299
+ }}
300
+ id="bulk-change-host-collections-selected-hosts"
301
+ />
302
+ </strong>
303
+ ),
304
+ }}
305
+ id="bulk-change-host-collections-description"
306
+ />
307
+ </Text>
308
+ </TextContent>
309
+ <h3><strong>{__('Select action')}</strong></h3>
310
+ <div style={{ display: 'flex', alignItems: 'baseline' }}>
311
+ <Radio
312
+ isChecked={addRadioChecked}
313
+ onChange={(_e, checked) => handleRadioChange(checked)}
314
+ name="radio-add"
315
+ label={__('Add to host collections')}
316
+ id="radio-add-action"
317
+ ouiaId="radio-add-action"
318
+ />
319
+ <Radio
320
+ isChecked={!addRadioChecked}
321
+ onChange={(_e, checked) => handleRadioChange(!checked)}
322
+ name="radio-remove"
323
+ label={__('Remove from host collections')}
324
+ id="radio-remove-action"
325
+ ouiaId="radio-remove-action"
326
+ style={{ marginLeft: '50px' }}
327
+ />
328
+ </div>
329
+ <div>
330
+ <TableIndexPage
331
+ selectionToolbar={selectionToolbar}
332
+ results={hostCollectionsResults}
333
+ metadata={hostCollectionsMetadata}
334
+ response={hostCollectionsResponse}
335
+ tableType="host_collections"
336
+ apiUrl={hostCollectionsUrlForOrg}
337
+ apiOptions={apiOptions}
338
+ selectedCount={selectedCount}
339
+ selectPage={selectPage}
340
+ selectNone={selectNone}
341
+ customSearchProps={{
342
+ autocomplete: {
343
+ url: katelloApi.getApiUrl('/host_collections/auto_complete_search'),
344
+ },
345
+ }}
346
+ bulkSelect={hostCollectionsBulkSelect}
347
+ updateParamsByUrl={false}
348
+ isSelectableRow={isSelectableRow}
349
+ >
350
+ <Table
351
+ showCheckboxes
352
+ selectOne={selectOne}
353
+ isSelected={isSelected}
354
+ isSelectable={isSelectableRow}
355
+ isEmbedded
356
+ idColumn="id"
357
+ columns={columns}
358
+ refreshData={noop}
359
+ url=""
360
+ results={hostCollectionsResults}
361
+ isPending={hostCollectionsLoadingStatus === STATUS.PENDING}
362
+ params={{ ...hostCollectionsMetadata, perPage, page }}
363
+ setParams={setHostCollectionsParamsAndAPI}
364
+ page={page}
365
+ perPage={perPage}
366
+ itemCount={subtotal}
367
+ />
368
+ </TableIndexPage>
369
+ </div>
370
+ </Modal>
371
+ );
372
+ };
373
+
374
+ BulkChangeHostCollectionsModal.propTypes = {
375
+ isOpen: PropTypes.bool,
376
+ closeModal: PropTypes.func,
377
+ fetchBulkParams: PropTypes.func,
378
+ selectedCount: PropTypes.number,
379
+ };
380
+
381
+ BulkChangeHostCollectionsModal.defaultProps = {
382
+ isOpen: false,
383
+ closeModal: () => {},
384
+ fetchBulkParams: () => '',
385
+ selectedCount: 0,
386
+ };
387
+
388
+ export default BulkChangeHostCollectionsModal;