katello 4.10.0 → 4.11.0.rc2

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 (498) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/locale/bn/katello.js +254 -215
  3. data/app/assets/javascripts/katello/locale/bn_IN/katello.js +254 -215
  4. data/app/assets/javascripts/katello/locale/ca/katello.js +254 -215
  5. data/app/assets/javascripts/katello/locale/cs/katello.js +254 -215
  6. data/app/assets/javascripts/katello/locale/cs_CZ/katello.js +254 -215
  7. data/app/assets/javascripts/katello/locale/de/katello.js +260 -245
  8. data/app/assets/javascripts/katello/locale/de_AT/katello.js +254 -215
  9. data/app/assets/javascripts/katello/locale/de_DE/katello.js +254 -215
  10. data/app/assets/javascripts/katello/locale/el/katello.js +254 -215
  11. data/app/assets/javascripts/katello/locale/en/katello.js +254 -215
  12. data/app/assets/javascripts/katello/locale/en_GB/katello.js +254 -215
  13. data/app/assets/javascripts/katello/locale/en_US/katello.js +254 -215
  14. data/app/assets/javascripts/katello/locale/es/katello.js +257 -233
  15. data/app/assets/javascripts/katello/locale/et_EE/katello.js +254 -215
  16. data/app/assets/javascripts/katello/locale/fr/katello.js +268 -268
  17. data/app/assets/javascripts/katello/locale/gl/katello.js +254 -215
  18. data/app/assets/javascripts/katello/locale/gu/katello.js +254 -215
  19. data/app/assets/javascripts/katello/locale/he_IL/katello.js +254 -215
  20. data/app/assets/javascripts/katello/locale/hi/katello.js +254 -215
  21. data/app/assets/javascripts/katello/locale/id/katello.js +254 -215
  22. data/app/assets/javascripts/katello/locale/it/katello.js +254 -221
  23. data/app/assets/javascripts/katello/locale/ja/katello.js +268 -268
  24. data/app/assets/javascripts/katello/locale/ka/katello.js +261 -231
  25. data/app/assets/javascripts/katello/locale/kn/katello.js +254 -215
  26. data/app/assets/javascripts/katello/locale/ko/katello.js +255 -222
  27. data/app/assets/javascripts/katello/locale/locale/katello.js +1049 -1012
  28. data/app/assets/javascripts/katello/locale/ml_IN/katello.js +254 -215
  29. data/app/assets/javascripts/katello/locale/mr/katello.js +254 -215
  30. data/app/assets/javascripts/katello/locale/nl_NL/katello.js +254 -215
  31. data/app/assets/javascripts/katello/locale/or/katello.js +254 -215
  32. data/app/assets/javascripts/katello/locale/pa/katello.js +254 -215
  33. data/app/assets/javascripts/katello/locale/pl/katello.js +254 -215
  34. data/app/assets/javascripts/katello/locale/pl_PL/katello.js +254 -215
  35. data/app/assets/javascripts/katello/locale/pt/katello.js +254 -215
  36. data/app/assets/javascripts/katello/locale/pt_BR/katello.js +257 -233
  37. data/app/assets/javascripts/katello/locale/ro/katello.js +254 -215
  38. data/app/assets/javascripts/katello/locale/ro_RO/katello.js +254 -215
  39. data/app/assets/javascripts/katello/locale/ru/katello.js +255 -222
  40. data/app/assets/javascripts/katello/locale/sl/katello.js +254 -215
  41. data/app/assets/javascripts/katello/locale/sv_SE/katello.js +254 -215
  42. data/app/assets/javascripts/katello/locale/ta/katello.js +254 -215
  43. data/app/assets/javascripts/katello/locale/ta_IN/katello.js +254 -215
  44. data/app/assets/javascripts/katello/locale/te/katello.js +254 -215
  45. data/app/assets/javascripts/katello/locale/tr/katello.js +254 -215
  46. data/app/assets/javascripts/katello/locale/vi/katello.js +254 -215
  47. data/app/assets/javascripts/katello/locale/vi_VN/katello.js +254 -215
  48. data/app/assets/javascripts/katello/locale/zh/katello.js +254 -215
  49. data/app/assets/javascripts/katello/locale/zh_CN/katello.js +268 -268
  50. data/app/assets/javascripts/katello/locale/zh_TW/katello.js +255 -222
  51. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +15 -2
  52. data/app/controllers/katello/api/v2/capsule_content_controller.rb +21 -4
  53. data/app/controllers/katello/api/v2/capsules_controller.rb +11 -1
  54. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +1 -1
  55. data/app/controllers/katello/api/v2/docker_tags_controller.rb +2 -0
  56. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +2 -1
  57. data/app/controllers/katello/api/v2/organizations_controller.rb +2 -2
  58. data/app/controllers/katello/api/v2/repositories_controller.rb +1 -0
  59. data/app/controllers/katello/api/v2/simple_content_access_controller.rb +5 -5
  60. data/app/controllers/katello/api/v2/sync_plans_controller.rb +11 -3
  61. data/app/controllers/katello/concerns/api/api_controller.rb +6 -0
  62. data/app/controllers/katello/concerns/api/v2/hosts_bulk_actions_controller_extensions.rb +23 -0
  63. data/app/controllers/katello/concerns/filtered_auto_complete_search.rb +1 -1
  64. data/app/controllers/katello/concerns/organizations_controller_extensions.rb +2 -0
  65. data/app/controllers/katello/remote_execution_controller.rb +1 -1
  66. data/app/jobs/create_host_lifecycle_expire_soon_notifications.rb +11 -0
  67. data/app/lib/actions/katello/applicability/hosts/bulk_generate.rb +10 -0
  68. data/app/lib/actions/katello/capsule_content/refresh_repos.rb +8 -2
  69. data/app/lib/actions/katello/capsule_content/sync.rb +30 -10
  70. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +13 -0
  71. data/app/lib/actions/katello/capsule_content/update_content_counts.rb +24 -0
  72. data/app/lib/actions/katello/content_view/promote.rb +9 -0
  73. data/app/lib/actions/katello/content_view/publish.rb +9 -0
  74. data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +8 -0
  75. data/app/lib/actions/katello/repository/sync.rb +11 -0
  76. data/app/lib/actions/pulp3/capsule_content/reclaim_space.rb +5 -0
  77. data/app/lib/actions/pulp3/content_view_version/create_export_history.rb +6 -1
  78. data/app/lib/actions/pulp3/content_view_version/export.rb +8 -0
  79. data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +1 -1
  80. data/app/lib/katello/concerns/base_template_scope_extensions.rb +14 -1
  81. data/app/lib/katello/errors.rb +1 -0
  82. data/app/lib/katello/repo_discovery.rb +2 -2
  83. data/app/lib/katello/validators/content_view_environment_coherent_default_validator.rb +22 -0
  84. data/app/lib/katello/validators/content_view_environment_validator.rb +1 -0
  85. data/app/mailers/katello/task_mailer.rb +54 -0
  86. data/app/models/katello/concerns/host_managed_extensions.rb +41 -1
  87. data/app/models/katello/concerns/organization_extensions.rb +1 -1
  88. data/app/models/katello/concerns/smart_proxy_extensions.rb +75 -3
  89. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +6 -0
  90. data/app/models/katello/content_view.rb +21 -0
  91. data/app/models/katello/content_view_environment.rb +6 -1
  92. data/app/models/katello/docker_meta_tag.rb +1 -1
  93. data/app/models/katello/docker_tag.rb +1 -1
  94. data/app/models/katello/erratum.rb +1 -1
  95. data/app/models/katello/host/content_facet.rb +10 -7
  96. data/app/models/katello/product.rb +8 -0
  97. data/app/models/katello/repository.rb +31 -6
  98. data/app/models/katello/rhel_lifecycle_status.rb +214 -0
  99. data/app/models/katello/sync_plan.rb +19 -1
  100. data/app/models/katello/yum_metadata_file.rb +1 -1
  101. data/app/services/katello/applicability/applicable_content_helper.rb +1 -1
  102. data/app/services/katello/event_queue.rb +10 -2
  103. data/app/services/katello/host_status_manager.rb +1 -0
  104. data/app/services/katello/product_content_importer.rb +45 -3
  105. data/app/services/katello/pulp3/ansible_collection.rb +1 -0
  106. data/app/services/katello/pulp3/api/core.rb +1 -1
  107. data/app/services/katello/pulp3/deb.rb +1 -0
  108. data/app/services/katello/pulp3/docker_manifest.rb +1 -0
  109. data/app/services/katello/pulp3/docker_manifest_list.rb +9 -4
  110. data/app/services/katello/pulp3/docker_tag.rb +1 -0
  111. data/app/services/katello/pulp3/erratum.rb +1 -0
  112. data/app/services/katello/pulp3/file_unit.rb +1 -0
  113. data/app/services/katello/pulp3/module_stream.rb +1 -0
  114. data/app/services/katello/pulp3/package_group.rb +1 -0
  115. data/app/services/katello/pulp3/pulp_content_unit.rb +39 -0
  116. data/app/services/katello/pulp3/repository_mirror.rb +21 -2
  117. data/app/services/katello/pulp3/rpm.rb +1 -0
  118. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +1 -1
  119. data/app/services/katello/pulp3/srpm.rb +3 -2
  120. data/app/services/katello/registration_manager.rb +6 -3
  121. data/app/services/katello/repository_type.rb +2 -1
  122. data/app/services/katello/ui_notifications/hosts/lifecycle_expire_soon.rb +58 -0
  123. data/app/views/foreman/job_templates/resolve_traces.erb +1 -1
  124. data/app/views/foreman/smart_proxies/_content_tab.html.erb +1 -3
  125. data/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +39 -1
  126. data/app/views/katello/api/v2/content_export_incrementals/repository.json.rabl +13 -0
  127. data/app/views/katello/api/v2/content_facet/show.json.rabl +4 -0
  128. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -1
  129. data/app/views/katello/api/v2/docker_tags/_base.json.rabl +28 -6
  130. data/app/views/katello/hosts/_errata_counts.html.erb +2 -2
  131. data/app/views/katello/task_mailer/cv_promote_failure.html.erb +31 -0
  132. data/app/views/katello/task_mailer/cv_promote_failure.text.erb +13 -0
  133. data/app/views/katello/task_mailer/cv_publish_failure.html.erb +31 -0
  134. data/app/views/katello/task_mailer/cv_publish_failure.text.erb +13 -0
  135. data/app/views/katello/task_mailer/proxy_sync_failure.html.erb +45 -0
  136. data/app/views/katello/task_mailer/proxy_sync_failure.text.erb +25 -0
  137. data/app/views/katello/task_mailer/repo_sync_failure.html.erb +35 -0
  138. data/app/views/katello/task_mailer/repo_sync_failure.text.erb +15 -0
  139. data/app/views/overrides/organizations/_edit_override.html.erb +4 -0
  140. data/config/routes/api/v2.rb +2 -0
  141. data/db/migrate/20230825180856_add_content_counts_to_smart_proxy.rb +7 -0
  142. data/db/migrate/20231020153017_create_indexes_for_nvra_and_epoch.rb +6 -0
  143. data/db/seeds.d/106-mail_notifications.rb +32 -0
  144. data/db/seeds.d/109-katello-notification-blueprints.rb +6 -0
  145. data/engines/bastion/app/assets/javascripts/bastion/components/views/bst-alert.html +1 -1
  146. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/activation-keys.controller.js +4 -0
  147. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-add-host-collections.controller.js +3 -0
  148. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-add-subscriptions.controller.js +3 -0
  149. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-associations.controller.js +4 -0
  150. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-copy.controller.js +7 -2
  151. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-host-collections.controller.js +3 -0
  152. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-repository-sets.controller.js +3 -0
  153. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-subscriptions.controller.js +3 -0
  154. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/new/new-activation-key.controller.js +6 -2
  155. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.controller.js +16 -1
  156. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/rhel-lifecycle-notice.html +5 -0
  157. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credentials.controller.js +7 -2
  158. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-acs.controller.js +7 -2
  159. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-products.controller.js +7 -2
  160. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-repositories.controller.js +7 -2
  161. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/new/new-content-credential.controller.js +3 -0
  162. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-errata-modal.controller.js +5 -1
  163. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-debs-actions.controller.js +5 -1
  164. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-debs-applicable.controller.js +3 -0
  165. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-debs-installed.controller.js +3 -0
  166. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-errata.controller.js +4 -0
  167. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-module-streams.controller.js +3 -0
  168. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages-applicable.controller.js +3 -0
  169. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages-installed.controller.js +3 -0
  170. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages.controller.js +3 -0
  171. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-traces.controller.js +4 -0
  172. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-debs-actions.html +1 -1
  173. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-debs-applicable.html +1 -1
  174. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-debs-installed.html +1 -1
  175. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-errata.html +3 -3
  176. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-module-streams.html +1 -1
  177. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-actions.html +1 -1
  178. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-applicable.html +1 -1
  179. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-installed.html +1 -1
  180. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-traces.html +3 -3
  181. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +5 -0
  182. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.routes.js +1 -1
  183. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-add-host-collections.controller.js +4 -1
  184. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-add-subscriptions.controller.js +3 -0
  185. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-host-collections.controller.js +4 -1
  186. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-repository-sets.controller.js +3 -0
  187. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-subscriptions.controller.js +3 -0
  188. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-add-subscriptions.html +1 -1
  189. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-details.html +4 -3
  190. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-host-collections.html +1 -1
  191. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +3 -3
  192. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-provisioning-info.html +2 -2
  193. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-subscriptions-list.html +1 -1
  194. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-subscriptions.html +1 -1
  195. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +3 -3
  196. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/debs.controller.js +7 -0
  197. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/details/deb-content-views.controller.js +8 -1
  198. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/details/deb-repositories.controller.js +10 -2
  199. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/details/docker-tag-environments.controller.js +5 -2
  200. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/details/docker-tag-repositories.controller.js +6 -2
  201. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/docker-tags.controller.js +6 -3
  202. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/environment-content.controller.js +13 -0
  203. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/environment.controller.js +6 -0
  204. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/new-environment.controller.js +8 -2
  205. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/apply-errata.controller.js +4 -0
  206. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum-content-hosts.controller.js +7 -2
  207. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum-repositories.controller.js +7 -2
  208. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum.controller.js +6 -2
  209. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-info.html +2 -2
  210. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/errata.controller.js +5 -0
  211. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/views/errata.html +1 -1
  212. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/files/details/file-content-views.controller.js +10 -2
  213. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/files/details/file-repositories.controller.js +8 -1
  214. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/files/files.controller.js +9 -2
  215. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-add-hosts.controller.js +3 -0
  216. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-copy.controller.js +7 -2
  217. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-hosts.controller.js +3 -0
  218. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/host-collections.controller.js +4 -0
  219. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/new/new-host-collection.controller.js +6 -2
  220. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host.factory.js +4 -0
  221. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +166 -43
  222. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/fr.po +4 -0
  223. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/translations.js +1 -1
  224. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/packages.controller.js +7 -0
  225. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/product-repositories.controller.js +5 -0
  226. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-advanced-sync.controller.js +6 -2
  227. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-manage-content.controller.js +11 -0
  228. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +3 -0
  229. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/views/product-repositories.html +2 -2
  230. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery-create.controller.js +3 -0
  231. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery.controller.js +3 -0
  232. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/new/product-form.controller.js +6 -2
  233. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +4 -0
  234. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/content-access-mode-banner.html +1 -1
  235. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/sync-plan-add-products.controller.js +5 -1
  236. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/sync-plan-products.controller.js +4 -0
  237. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/new/new-sync-plan.controller.js +3 -0
  238. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/sync-plans.controller.js +4 -0
  239. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/task-details.controller.js +6 -2
  240. data/lib/katello/engine.rb +2 -3
  241. data/lib/katello/permission_creator.rb +2 -2
  242. data/lib/katello/plugin.rb +4 -0
  243. data/lib/katello/repository_types/ostree.rb +1 -0
  244. data/lib/katello/repository_types/python.rb +1 -0
  245. data/lib/katello/scheduled_jobs.rb +1 -1
  246. data/lib/katello/version.rb +1 -1
  247. data/locale/action_names.rb +1 -3
  248. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  249. data/locale/bn/katello.po +236 -197
  250. data/locale/bn/katello.po.time_stamp +0 -0
  251. data/locale/bn_IN/LC_MESSAGES/katello.mo +0 -0
  252. data/locale/bn_IN/katello.po +236 -197
  253. data/locale/bn_IN/katello.po.time_stamp +0 -0
  254. data/locale/ca/LC_MESSAGES/katello.mo +0 -0
  255. data/locale/ca/katello.po +236 -197
  256. data/locale/ca/katello.po.time_stamp +0 -0
  257. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  258. data/locale/cs/katello.po +236 -206
  259. data/locale/cs/katello.po.time_stamp +0 -0
  260. data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
  261. data/locale/cs_CZ/katello.po +236 -197
  262. data/locale/cs_CZ/katello.po.time_stamp +0 -0
  263. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  264. data/locale/de/katello.po +241 -202
  265. data/locale/de/katello.po.time_stamp +0 -0
  266. data/locale/de_AT/LC_MESSAGES/katello.mo +0 -0
  267. data/locale/de_AT/katello.po +236 -197
  268. data/locale/de_AT/katello.po.time_stamp +0 -0
  269. data/locale/de_DE/LC_MESSAGES/katello.mo +0 -0
  270. data/locale/de_DE/katello.po +236 -197
  271. data/locale/de_DE/katello.po.time_stamp +0 -0
  272. data/locale/el/LC_MESSAGES/katello.mo +0 -0
  273. data/locale/el/katello.po +236 -197
  274. data/locale/el/katello.po.time_stamp +0 -0
  275. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  276. data/locale/en/katello.po +236 -197
  277. data/locale/en/katello.po.time_stamp +0 -0
  278. data/locale/en_GB/LC_MESSAGES/katello.mo +0 -0
  279. data/locale/en_GB/katello.po +236 -197
  280. data/locale/en_GB/katello.po.time_stamp +0 -0
  281. data/locale/en_US/LC_MESSAGES/katello.mo +0 -0
  282. data/locale/en_US/katello.po +236 -197
  283. data/locale/en_US/katello.po.time_stamp +0 -0
  284. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  285. data/locale/es/katello.po +238 -199
  286. data/locale/es/katello.po.time_stamp +0 -0
  287. data/locale/et_EE/LC_MESSAGES/katello.mo +0 -0
  288. data/locale/et_EE/katello.po +236 -197
  289. data/locale/et_EE/katello.po.time_stamp +0 -0
  290. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  291. data/locale/fr/katello.po +247 -208
  292. data/locale/fr/katello.po.time_stamp +0 -0
  293. data/locale/gl/LC_MESSAGES/katello.mo +0 -0
  294. data/locale/gl/katello.po +236 -197
  295. data/locale/gl/katello.po.time_stamp +0 -0
  296. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  297. data/locale/gu/katello.po +236 -197
  298. data/locale/gu/katello.po.time_stamp +0 -0
  299. data/locale/he_IL/LC_MESSAGES/katello.mo +0 -0
  300. data/locale/he_IL/katello.po +236 -197
  301. data/locale/he_IL/katello.po.time_stamp +0 -0
  302. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  303. data/locale/hi/katello.po +236 -197
  304. data/locale/hi/katello.po.time_stamp +0 -0
  305. data/locale/id/LC_MESSAGES/katello.mo +0 -0
  306. data/locale/id/katello.po +236 -197
  307. data/locale/id/katello.po.time_stamp +0 -0
  308. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  309. data/locale/it/katello.po +236 -197
  310. data/locale/it/katello.po.time_stamp +0 -0
  311. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  312. data/locale/ja/katello.po +247 -208
  313. data/locale/ja/katello.po.time_stamp +0 -0
  314. data/locale/ka/LC_MESSAGES/katello.mo +0 -0
  315. data/locale/ka/katello.po +241 -202
  316. data/locale/ka/katello.po.time_stamp +0 -0
  317. data/locale/katello.pot +1427 -1296
  318. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  319. data/locale/kn/katello.po +236 -197
  320. data/locale/kn/katello.po.time_stamp +0 -0
  321. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  322. data/locale/ko/katello.po +236 -197
  323. data/locale/ko/katello.po.time_stamp +0 -0
  324. data/locale/ml_IN/LC_MESSAGES/katello.mo +0 -0
  325. data/locale/ml_IN/katello.po +236 -197
  326. data/locale/ml_IN/katello.po.time_stamp +0 -0
  327. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  328. data/locale/mr/katello.po +236 -197
  329. data/locale/mr/katello.po.time_stamp +0 -0
  330. data/locale/nl_NL/LC_MESSAGES/katello.mo +0 -0
  331. data/locale/nl_NL/katello.po +236 -197
  332. data/locale/nl_NL/katello.po.time_stamp +0 -0
  333. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  334. data/locale/or/katello.po +236 -197
  335. data/locale/or/katello.po.time_stamp +0 -0
  336. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  337. data/locale/pa/katello.po +236 -197
  338. data/locale/pa/katello.po.time_stamp +0 -0
  339. data/locale/pl/LC_MESSAGES/katello.mo +0 -0
  340. data/locale/pl/katello.po +236 -197
  341. data/locale/pl/katello.po.time_stamp +0 -0
  342. data/locale/pl_PL/LC_MESSAGES/katello.mo +0 -0
  343. data/locale/pl_PL/katello.po +236 -197
  344. data/locale/pl_PL/katello.po.time_stamp +0 -0
  345. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  346. data/locale/pt/katello.po +236 -197
  347. data/locale/pt/katello.po.time_stamp +0 -0
  348. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  349. data/locale/pt_BR/katello.po +238 -199
  350. data/locale/pt_BR/katello.po.time_stamp +0 -0
  351. data/locale/ro/LC_MESSAGES/katello.mo +0 -0
  352. data/locale/ro/katello.po +236 -197
  353. data/locale/ro/katello.po.time_stamp +0 -0
  354. data/locale/ro_RO/LC_MESSAGES/katello.mo +0 -0
  355. data/locale/ro_RO/katello.po +236 -197
  356. data/locale/ro_RO/katello.po.time_stamp +0 -0
  357. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  358. data/locale/ru/katello.po +236 -197
  359. data/locale/ru/katello.po.time_stamp +0 -0
  360. data/locale/sl/LC_MESSAGES/katello.mo +0 -0
  361. data/locale/sl/katello.po +236 -197
  362. data/locale/sl/katello.po.time_stamp +0 -0
  363. data/locale/sv_SE/LC_MESSAGES/katello.mo +0 -0
  364. data/locale/sv_SE/katello.po +236 -197
  365. data/locale/sv_SE/katello.po.time_stamp +0 -0
  366. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  367. data/locale/ta/katello.po +236 -197
  368. data/locale/ta/katello.po.time_stamp +0 -0
  369. data/locale/ta_IN/LC_MESSAGES/katello.mo +0 -0
  370. data/locale/ta_IN/katello.po +236 -197
  371. data/locale/ta_IN/katello.po.time_stamp +0 -0
  372. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  373. data/locale/te/katello.po +236 -197
  374. data/locale/te/katello.po.time_stamp +0 -0
  375. data/locale/tr/LC_MESSAGES/katello.mo +0 -0
  376. data/locale/tr/katello.po +236 -197
  377. data/locale/tr/katello.po.time_stamp +0 -0
  378. data/locale/vi/LC_MESSAGES/katello.mo +0 -0
  379. data/locale/vi/katello.po +236 -197
  380. data/locale/vi/katello.po.time_stamp +0 -0
  381. data/locale/vi_VN/LC_MESSAGES/katello.mo +0 -0
  382. data/locale/vi_VN/katello.po +236 -197
  383. data/locale/vi_VN/katello.po.time_stamp +0 -0
  384. data/locale/zh/LC_MESSAGES/katello.mo +0 -0
  385. data/locale/zh/katello.po +236 -197
  386. data/locale/zh/katello.po.time_stamp +0 -0
  387. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  388. data/locale/zh_CN/katello.po +247 -208
  389. data/locale/zh_CN/katello.po.time_stamp +0 -0
  390. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  391. data/locale/zh_TW/katello.po +236 -197
  392. data/locale/zh_TW/katello.po.time_stamp +0 -0
  393. data/webpack/components/Table/EmptyStateMessage.js +7 -4
  394. data/webpack/components/Table/MainTable.scss +18 -17
  395. data/webpack/components/Table/TableWrapper.js +4 -1
  396. data/webpack/components/extensions/HostDetails/ActionsBar/index.js +45 -4
  397. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.scss +9 -7
  398. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.js +1 -1
  399. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsModal.js +1 -1
  400. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeActions.js +29 -7
  401. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.js +106 -66
  402. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.scss +6 -0
  403. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeConstants.js +2 -0
  404. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeEditModal.js +53 -29
  405. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeSelectors.js +7 -6
  406. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeCard.test.js +24 -5
  407. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeEditModal.test.js +137 -7
  408. data/webpack/components/extensions/HostDetails/DetailsTabCards/HwPropertiesCard.js +11 -10
  409. data/webpack/components/extensions/HostDetails/DetailsTabCards/RegistrationCard.js +8 -2
  410. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +27 -10
  411. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/HostErrataActions.js +3 -22
  412. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/HostErrataConstants.js +0 -1
  413. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +3 -2
  414. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +2 -2
  415. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +48 -12
  416. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +22 -10
  417. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionHooks.js +1 -1
  418. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +2 -2
  419. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.js +71 -5
  420. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.scss +16 -0
  421. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesEnabler.js +4 -1
  422. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js +6 -2
  423. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +2 -1
  424. data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +25 -0
  425. data/webpack/components/extensions/Hosts/ActionsBar/index.js +36 -0
  426. data/webpack/components/extensions/Hosts/constants.js +2 -0
  427. data/webpack/components/extensions/RegistrationCommands/RegistrationCommandsPageHelpers.js +13 -7
  428. data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/ActivationKeys.test.js.snap +9 -1
  429. data/webpack/components/extensions/RegistrationCommands/fields/ActivationKeys.js +87 -22
  430. data/webpack/components/extensions/RegistrationCommands/index.js +17 -41
  431. data/webpack/global_index.js +11 -2
  432. data/webpack/redux/reducers/RedHatRepositories/enabled.fixtures.js +4 -0
  433. data/webpack/redux/reducers/RedHatRepositories/enabled.js +1 -0
  434. data/webpack/scenes/ActivationKeys/Details/ActivationKeyDetails.js +10 -1
  435. data/webpack/scenes/ActivationKeys/Details/ActivationKeyDetails.scss +33 -31
  436. data/webpack/scenes/AlternateContentSources/MainTable/ACSTable.js +3 -1
  437. data/webpack/scenes/Content/ContentConfig.js +3 -0
  438. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +6 -4
  439. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.scss +8 -6
  440. data/webpack/scenes/ContentViews/Delete/ContentViewDeleteWizard.js +1 -0
  441. data/webpack/scenes/ContentViews/Delete/Steps/CVEnvironmentSelectionForm.scss +4 -2
  442. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +3 -4
  443. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +2 -2
  444. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +5 -5
  445. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/compositeCVDetails.fixtures.json +393 -0
  446. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.test.js +30 -4
  447. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +3 -1
  448. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +3 -3
  449. data/webpack/scenes/ContentViews/Details/Repositories/RepoIcon.js +2 -1
  450. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareTable.js +1 -1
  451. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +1 -1
  452. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveCVVersionWizard.js +1 -1
  453. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +1 -1
  454. data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +24 -1
  455. data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +1 -0
  456. data/webpack/scenes/ContentViews/Publish/__tests__/publishContentView.test.js +42 -0
  457. data/webpack/scenes/ContentViews/Publish/cvPublishForm.scss +13 -11
  458. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +2 -1
  459. data/webpack/scenes/ContentViews/__tests__/mockDetails.fixtures.json +2 -1
  460. data/webpack/scenes/Hosts/ChangeContentSource/index.js +4 -3
  461. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +1 -2
  462. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetails.test.js.snap +1 -1
  463. data/webpack/scenes/RedHatRepositories/RedHatRepositoriesPage.js +2 -1
  464. data/webpack/scenes/RedHatRepositories/__tests__/__snapshots__/RedHatRepositoriesPage.test.js.snap +6 -0
  465. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepository.js +4 -1
  466. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepositoryContent.js +13 -4
  467. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/EnabledRepositoryContent.test.js +1 -0
  468. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/__snapshots__/EnabledRepository.test.js.snap +1 -0
  469. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/__snapshots__/EnabledRepositoryContent.test.js.snap +3 -2
  470. data/webpack/scenes/SmartProxy/AdditionalCapsuleContent.js +93 -0
  471. data/webpack/scenes/SmartProxy/Content.js +12 -4
  472. data/webpack/scenes/SmartProxy/ExpandableCvDetails.js +107 -0
  473. data/webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js +139 -0
  474. data/webpack/scenes/SmartProxy/SmartProxyContentActions.js +17 -4
  475. data/webpack/scenes/SmartProxy/SmartProxyContentConstants.js +1 -0
  476. data/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js +150 -0
  477. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.fixtures.json +799 -0
  478. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js +29 -17
  479. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +16 -19
  480. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.scss +12 -8
  481. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +21 -18
  482. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnConfigurationForm.scss +4 -2
  483. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.scss +38 -19
  484. data/webpack/scenes/Subscriptions/Manifest/index.js +0 -2
  485. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +38 -12
  486. data/webpack/scenes/Subscriptions/SubscriptionsPage.scss +38 -36
  487. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +16 -13
  488. data/webpack/utils/helpers.js +0 -1
  489. metadata +148 -33
  490. data/app/controllers/katello/concerns/api/v2/bulk_hosts_extensions.rb +0 -47
  491. data/webpack/components/Table/TableHooks.js +0 -315
  492. data/webpack/components/Table/__test__/useBulkSelect.test.js +0 -99
  493. data/webpack/components/extensions/RegistrationCommands/__tests__/LifeCycleEnvironment.test.js +0 -11
  494. data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/LifeCycleEnvironment.test.js.snap +0 -29
  495. data/webpack/components/extensions/RegistrationCommands/fields/LifecycleEnvironment.js +0 -57
  496. data/webpack/scenes/SmartProxy/SmartProxyContentTable.js +0 -164
  497. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentResult.fixtures.json +0 -140
  498. data/webpack/scenes/Subscriptions/Manifest/Manifest.scss +0 -16
@@ -1,5 +1,4 @@
1
1
  export const HOST_ERRATA_KEY = 'HOST_ERRATUM';
2
- export const HOST_ERRATA_APPLICABILITY_KEY = 'HOST_ERRATA_APPLICABILITY';
3
2
  export const HOST_ERRATA_APPLY_KEY = 'HOST_ERRATUM_APPLY';
4
3
 
5
4
  export const ERRATA_TYPES = {
@@ -24,8 +24,9 @@ import {
24
24
  LongArrowAltUpIcon,
25
25
  CheckIcon,
26
26
  } from '@patternfly/react-icons';
27
+ import { useBulkSelect, useUrlParams } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
28
+ import { useTableSort } from 'foremanReact/components/PF4/Helpers/useTableSort';
27
29
  import { selectModuleStreamStatus, selectModuleStream } from './ModuleStreamsSelectors';
28
- import { useBulkSelect, useTableSort, useUrlParams } from '../../../../Table/TableHooks';
29
30
  import { getHostModuleStreams } from './ModuleStreamsActions';
30
31
  import InactiveText from '../../../../../scenes/ContentViews/components/InactiveText';
31
32
  import TableWrapper from '../../../../../components/Table/TableWrapper';
@@ -47,7 +48,7 @@ import {
47
48
  } from '../../hostDetailsHelpers';
48
49
 
49
50
  const moduleStreamSupported = ({ os, version }) =>
50
- os.match(/RedHat|RHEL|CentOS|Rocky|AlmaLinux|OracleLinux/i) && Number(version) > 7;
51
+ os.match(/RedHat|RHEL|CentOS|Rocky|AlmaLinux|Oracle Linux/i) && Number(version) > 7;
51
52
  export const hideModuleStreamsTab = ({ hostDetails }) => {
52
53
  const osMatch = hostDetails?.operatingsystem_name?.match(/(\D+) (\d+)/);
53
54
  if (!osMatch) return false;
@@ -8,9 +8,9 @@ import { noop } from 'foremanReact/common/helpers';
8
8
  import { translate as __ } from 'foremanReact/common/I18n';
9
9
  import { urlBuilder } from 'foremanReact/common/urlHelpers';
10
10
  import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
11
+ import { useBulkSelect } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
11
12
  import PropTypes from 'prop-types';
12
13
  import TableWrapper from '../../../../Table/TableWrapper';
13
- import { useBulkSelect } from '../../../../Table/TableHooks';
14
14
  import { HOST_YUM_INSTALLABLE_PACKAGES_KEY } from './YumInstallablePackagesConstants';
15
15
  import { selectHostYumInstallablePackagesStatus } from './YumInstallablePackagesSelectors';
16
16
  import { getHostYumInstallablePackages } from './YumInstallablePackagesActions';
@@ -124,7 +124,7 @@ const PackageInstallModal = ({
124
124
  const selectedPackageNames = () => selectedResults.map(({ name }) => name);
125
125
 
126
126
  const installViaRex = () => {
127
- triggerPackageInstall(fetchBulkParams());
127
+ triggerPackageInstall(fetchBulkParams(), selectedPackageNames().join(', '));
128
128
  selectNone();
129
129
  closeModal();
130
130
  };
@@ -1,5 +1,5 @@
1
1
  import React, { useCallback, useState, useRef } from 'react';
2
- import { useSelector } from 'react-redux';
2
+ import { useSelector, useDispatch } from 'react-redux';
3
3
  import {
4
4
  ActionList,
5
5
  ActionListItem,
@@ -19,12 +19,14 @@ import {
19
19
  import { TableVariant, Thead, Tbody, Tr, Th, Td, TableText } from '@patternfly/react-table';
20
20
  import PropTypes from 'prop-types';
21
21
  import { translate as __ } from 'foremanReact/common/I18n';
22
+ import { HOST_DETAILS_KEY } from 'foremanReact/components/HostDetails/consts';
22
23
  import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
23
-
24
+ import { useSet, useBulkSelect, useUrlParams } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
25
+ import { useTableSort } from 'foremanReact/components/PF4/Helpers/useTableSort';
24
26
  import { urlBuilder } from 'foremanReact/common/urlHelpers';
25
27
  import SelectableDropdown from '../../../../SelectableDropdown';
26
28
  import TableWrapper from '../../../../../components/Table/TableWrapper';
27
- import { useBulkSelect, useTableSort, useUrlParams, useSet } from '../../../../../components/Table/TableHooks';
29
+
28
30
  import PackagesStatus from '../../../../../components/Packages';
29
31
  import {
30
32
  getInstalledPackagesWithLatest,
@@ -43,6 +45,7 @@ import { hasRequiredPermissions as can,
43
45
  userPermissionsFromHostDetails } from '../../hostDetailsHelpers';
44
46
  import SortableColumnHeaders from '../../../../Table/components/SortableColumnHeaders';
45
47
  import { useRexJobPolling } from '../RemoteExecutionHooks';
48
+ import { runSubmanRepos } from '../../Cards/ContentViewDetailsCard/HostContentViewActions';
46
49
 
47
50
  const invokeRexJobs = ['create_job_invocations'];
48
51
  const createBookmarks = ['create_bookmarks'];
@@ -199,6 +202,7 @@ export const PackagesTab = () => {
199
202
  const { results, ...metadata } = response;
200
203
  const { error: errorSearchBody } = metadata;
201
204
  const status = useSelector(state => selectHostPackagesStatus(state));
205
+ const dispatch = useDispatch();
202
206
  const {
203
207
  selectOne,
204
208
  isSelected,
@@ -228,9 +232,10 @@ export const PackagesTab = () => {
228
232
  isPolling: isRemoveInProgress,
229
233
  } = useRexJobPolling(packageRemoveAction);
230
234
 
231
- const packageBulkRemoveAction = bulkParams => removePackages({
235
+ const packageBulkRemoveAction = (bulkParams, packageNames) => removePackages({
232
236
  hostname,
233
237
  search: bulkParams,
238
+ descriptionFormat: `Remove package(s) ${packageNames}`,
234
239
  });
235
240
 
236
241
  const {
@@ -250,10 +255,11 @@ export const PackagesTab = () => {
250
255
  isPolling: isUpgradeInProgress,
251
256
  } = useRexJobPolling(packageUpgradeAction, getHostDetails({ hostname }));
252
257
 
253
- const packageBulkUpgradeAction = bulkParams => updatePackages({
258
+ const packageBulkUpgradeAction = (bulkParams, descriptionFormat) => updatePackages({
254
259
  hostname,
255
260
  search: bulkParams,
256
261
  versions: JSON.stringify(selectedNVRAVersions || []),
262
+ descriptionFormat,
257
263
  });
258
264
 
259
265
  const {
@@ -263,7 +269,7 @@ export const PackagesTab = () => {
263
269
  } = useRexJobPolling(packageBulkUpgradeAction, getHostDetails({ hostname }));
264
270
 
265
271
  const packageInstallAction
266
- = bulkParams => installPackageBySearch({ hostname, search: bulkParams });
272
+ = (bulkParams, packageNames) => installPackageBySearch({ hostname, search: bulkParams, descriptionFormat: `Install package(s) ${packageNames}` });
267
273
 
268
274
  const {
269
275
  triggerJobStart: triggerPackageInstall,
@@ -271,6 +277,23 @@ export const PackagesTab = () => {
271
277
  isPolling: isInstallInProgress,
272
278
  } = useRexJobPolling(packageInstallAction, getHostDetails({ hostname }));
273
279
 
280
+ const refreshHostDetails = () => dispatch({
281
+ type: 'API_GET',
282
+ payload: {
283
+ key: HOST_DETAILS_KEY,
284
+ url: `/api/hosts/${hostname}`,
285
+ },
286
+ });
287
+
288
+ const {
289
+ triggerJobStart: triggerRecalculate, lastCompletedJob: lastCompletedRecalculate,
290
+ } = useRexJobPolling(() => runSubmanRepos(hostname, refreshHostDetails));
291
+
292
+ const handleRefreshApplicabilityClick = () => {
293
+ setIsBulkActionOpen(false);
294
+ triggerRecalculate();
295
+ };
296
+
274
297
  const actionInProgress = (isRemoveInProgress || isUpgradeInProgress
275
298
  || isBulkRemoveInProgress || isBulkUpgradeInProgress || isInstallInProgress);
276
299
  const disabledReason = __('A remote execution job is in progress.');
@@ -286,9 +309,10 @@ export const PackagesTab = () => {
286
309
 
287
310
  const removePackagesViaRemoteExecution = () => {
288
311
  const selected = fetchBulkParams();
312
+ const packageNames = selectedResults.map(({ name }) => name);
289
313
  setIsBulkActionOpen(false);
290
314
  selectNone();
291
- triggerBulkPackageRemove(selected);
315
+ triggerBulkPackageRemove(selected, packageNames.join(', '));
292
316
  };
293
317
 
294
318
  const removeBulk = () => removePackagesViaRemoteExecution();
@@ -301,9 +325,13 @@ export const PackagesTab = () => {
301
325
 
302
326
  const upgradeBulkViaRemoteExecution = () => {
303
327
  const selected = fetchBulkParams();
328
+ const packageNames = selectedResults.map(({ name }) => name);
329
+ const allRowsSelected = areAllRowsSelected();
330
+ let descriptionFormatText = allRowsSelected ? 'Upgrade all packages' : `Upgrade package(s) ${packageNames.join(', ')}`;
331
+ if (selectAllMode && !allRowsSelected) descriptionFormatText = 'Upgrade lots of packages'; // we don't know the package names in the exclusion set
304
332
  setIsBulkActionOpen(false);
305
333
  selectNone();
306
- triggerBulkPackageUpgrade(selected);
334
+ triggerBulkPackageUpgrade(selected, descriptionFormatText);
307
335
  };
308
336
 
309
337
  const upgradeBulk = () => upgradeBulkViaRemoteExecution();
@@ -347,7 +375,7 @@ export const PackagesTab = () => {
347
375
  </DropdownItem>,
348
376
  ];
349
377
 
350
- const dropdownRemoveItems = [
378
+ const kebabItems = [
351
379
  <DropdownItem
352
380
  aria-label="bulk_remove"
353
381
  ouiaId="bulk_remove"
@@ -368,6 +396,15 @@ export const PackagesTab = () => {
368
396
  >
369
397
  {__('Install packages')}
370
398
  </DropdownItem>,
399
+ <DropdownItem
400
+ aria-label="refresh_applicability"
401
+ ouiaId="refresh_applicability"
402
+ key="refresh_applicability"
403
+ component="button"
404
+ onClick={handleRefreshApplicabilityClick}
405
+ >
406
+ {__('Refresh package applicability')}
407
+ </DropdownItem>,
371
408
  ];
372
409
 
373
410
  const handlePackageStatusSelected = newStatus => setPackageStatusSelected((prevStatus) => {
@@ -408,7 +445,7 @@ export const PackagesTab = () => {
408
445
  toggle={<KebabToggle aria-label="bulk_actions" onToggle={toggleBulkAction} />}
409
446
  isOpen={isBulkActionOpen}
410
447
  isPlain
411
- dropdownItems={dropdownRemoveItems}
448
+ dropdownItems={kebabItems}
412
449
  ouiaId="bulk_actions_dropdown"
413
450
  />
414
451
  </ActionListItem>
@@ -433,7 +470,6 @@ export const PackagesTab = () => {
433
470
  );
434
471
 
435
472
  const resetFilters = () => setPackageStatusSelected(PACKAGE_STATUS);
436
-
437
473
  return (
438
474
  <div>
439
475
  <div id="packages-tab">
@@ -463,7 +499,7 @@ export const PackagesTab = () => {
463
499
  additionalListeners={[hostId, packageStatusSelected,
464
500
  activeSortDirection, activeSortColumn, lastCompletedPackageUpgrade,
465
501
  lastCompletedPackageRemove, lastCompletedBulkPackageRemove,
466
- lastCompletedBulkPackageUpgrade, lastCompletedPackageInstall]}
502
+ lastCompletedBulkPackageUpgrade, lastCompletedPackageInstall, lastCompletedRecalculate]}
467
503
  fetchItems={fetchItems}
468
504
  bookmarkController="katello_host_installed_packages"
469
505
  readOnlyBookmarks={readOnlyBookmarks}
@@ -9,10 +9,13 @@ import { PACKAGE_SEARCH_QUERY } from './PackagesTab/YumInstallablePackagesConsta
9
9
  import { PACKAGES_SEARCH_QUERY, SELECTED_UPDATE_VERSIONS } from './PackagesTab/HostPackagesConstants';
10
10
 
11
11
  // PARAM BUILDING
12
- const baseParams = ({ feature, hostname, inputs = {} }) => ({
12
+ const baseParams = ({
13
+ feature, hostname, descriptionFormat, inputs = {},
14
+ }) => ({
13
15
  job_invocation: {
14
16
  feature,
15
17
  inputs,
18
+ descriptionFormat,
16
19
  search_query: `name ^ (${hostname})`,
17
20
  },
18
21
  });
@@ -33,11 +36,12 @@ const katelloPackageInstallParams = ({ hostname, packageName }) =>
33
36
  });
34
37
 
35
38
  // used when we know package Id(s)
36
- const katelloPackageInstallBySearchParams = ({ hostname, search }) =>
39
+ const katelloPackageInstallBySearchParams = ({ hostname, search, descriptionFormat }) =>
37
40
  baseParams({
38
41
  hostname,
39
42
  inputs: { [PACKAGE_SEARCH_QUERY]: search },
40
43
  feature: REX_FEATURES.KATELLO_PACKAGE_INSTALL_BY_SEARCH,
44
+ description_format: descriptionFormat,
41
45
  });
42
46
 
43
47
  const katelloPackageRemoveParams = ({ hostname, packageName }) =>
@@ -47,11 +51,12 @@ const katelloPackageRemoveParams = ({ hostname, packageName }) =>
47
51
  feature: REX_FEATURES.KATELLO_PACKAGE_REMOVE,
48
52
  });
49
53
 
50
- const katelloPackagesRemoveParams = ({ hostname, search }) =>
54
+ const katelloPackagesRemoveParams = ({ hostname, search, descriptionFormat }) =>
51
55
  baseParams({
52
56
  hostname,
53
57
  inputs: { [PACKAGES_SEARCH_QUERY]: search },
54
58
  feature: REX_FEATURES.KATELLO_PACKAGES_REMOVE_BY_SEARCH,
59
+ description_format: descriptionFormat,
55
60
  });
56
61
 
57
62
  const katelloPackageUpdateParams = ({ hostname, packageName }) =>
@@ -61,11 +66,14 @@ const katelloPackageUpdateParams = ({ hostname, packageName }) =>
61
66
  feature: REX_FEATURES.KATELLO_PACKAGE_UPDATE,
62
67
  });
63
68
 
64
- const katelloPackagesUpdateParams = ({ hostname, search, versions }) => ({
69
+ const katelloPackagesUpdateParams = ({
70
+ hostname, search, versions, descriptionFormat,
71
+ }) => ({
65
72
  job_invocation: {
66
73
  feature: REX_FEATURES.KATELLO_PACKAGES_UPDATE_BY_SEARCH,
67
74
  inputs: { [PACKAGES_SEARCH_QUERY]: search, [SELECTED_UPDATE_VERSIONS]: versions },
68
75
  search_query: `name ^ (${hostname})`,
76
+ description_format: descriptionFormat,
69
77
  },
70
78
  });
71
79
 
@@ -134,11 +142,11 @@ export const installPackage = ({ hostname, packageName, handleSuccess }) => post
134
142
  errorToast,
135
143
  });
136
144
 
137
- export const installPackageBySearch = ({ hostname, search }) => post({
145
+ export const installPackageBySearch = ({ hostname, search, descriptionFormat }) => post({
138
146
  type: API_OPERATIONS.POST,
139
147
  key: REX_JOB_INVOCATIONS_KEY,
140
148
  url: foremanApi.getApiUrl('/job_invocations'),
141
- params: katelloPackageInstallBySearchParams({ hostname, search }),
149
+ params: katelloPackageInstallBySearchParams({ hostname, search, descriptionFormat }),
142
150
  handleSuccess: showRexToast,
143
151
  errorToast,
144
152
  });
@@ -152,11 +160,11 @@ export const removePackage = ({ hostname, packageName }) => post({
152
160
  errorToast,
153
161
  });
154
162
 
155
- export const removePackages = ({ hostname, search }) => post({
163
+ export const removePackages = ({ hostname, search, descriptionFormat }) => post({
156
164
  type: API_OPERATIONS.POST,
157
165
  key: REX_JOB_INVOCATIONS_KEY,
158
166
  url: foremanApi.getApiUrl('/job_invocations'),
159
- params: katelloPackagesRemoveParams({ hostname, search }),
167
+ params: katelloPackagesRemoveParams({ hostname, search, descriptionFormat }),
160
168
  handleSuccess: showRexToast,
161
169
  errorToast,
162
170
  });
@@ -170,11 +178,15 @@ export const updatePackage = ({ hostname, packageName }) => post({
170
178
  errorToast,
171
179
  });
172
180
 
173
- export const updatePackages = ({ hostname, search, versions }) => post({
181
+ export const updatePackages = ({
182
+ hostname, search, versions, descriptionFormat,
183
+ }) => post({
174
184
  type: API_OPERATIONS.POST,
175
185
  key: REX_JOB_INVOCATIONS_KEY,
176
186
  url: foremanApi.getApiUrl('/job_invocations'),
177
- params: katelloPackagesUpdateParams({ hostname, search, versions }),
187
+ params: katelloPackagesUpdateParams({
188
+ hostname, search, versions, descriptionFormat,
189
+ }),
178
190
  handleSuccess: showRexToast,
179
191
  errorToast,
180
192
  });
@@ -29,7 +29,7 @@ export const useRexJobPolling = (initialAction, successAction = null, failureAct
29
29
  const tick = (resp) => {
30
30
  const { data } = resp;
31
31
  const { statusLabel, id, description } = propsToCamelCase(data);
32
- setRexJobId(id);
32
+ if (!id) setRexJobId(id);
33
33
  if (statusLabel && statusLabel !== 'running') {
34
34
  stopRexJobPolling({ jobId: id, statusLabel });
35
35
  if (statusLabel === 'succeeded') {
@@ -42,12 +42,12 @@ import {
42
42
  Thead,
43
43
  Tr,
44
44
  } from '@patternfly/react-table';
45
+ import { useTableSort } from 'foremanReact/components/PF4/Helpers/useTableSort';
45
46
 
46
47
  import {
47
48
  useBulkSelect,
48
- useTableSort,
49
49
  useUrlParams,
50
- } from '../../../../../components/Table/TableHooks';
50
+ } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
51
51
  import TableWrapper from '../../../../../components/Table/TableWrapper';
52
52
  import hostIdNotReady from '../../HostDetailsActions';
53
53
  import { selectHostDetailsStatus } from '../../HostDetailsSelectors.js';
@@ -9,17 +9,24 @@ import {
9
9
  Dropdown,
10
10
  DropdownItem,
11
11
  DropdownToggle,
12
+ Text,
13
+ TextContent,
14
+ TextList,
15
+ TextListItem,
16
+ Alert,
12
17
  } from '@patternfly/react-core';
13
- import { CaretDownIcon } from '@patternfly/react-icons';
18
+ import { CaretDownIcon, ArrowRightIcon } from '@patternfly/react-icons';
14
19
  import { translate as __ } from 'foremanReact/common/I18n';
15
20
  import { useSelector } from 'react-redux';
16
21
  import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
17
22
  import { katelloPackageInstallUrl } from '../customizedRexUrlHelpers';
18
23
  import { KATELLO_TRACER_PACKAGE } from './HostTracesConstants';
24
+ import './EnableTracerModal.scss';
19
25
 
20
- const EnableTracerModal = ({ isOpen, setIsOpen, triggerJobStart }) => {
26
+ const EnableTracerModal = ({
27
+ isOpen, setIsOpen, triggerJobStart, tracerRpmAvailable,
28
+ }) => {
21
29
  const title = __('Enable Tracer');
22
- const body = __('Enabling will install the katello-host-tools-tracer package on the host.');
23
30
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
24
31
  const [buttonLoading, setButtonLoading] = useState(false);
25
32
  const toggleDropdownOpen = () => setIsDropdownOpen(prev => !prev);
@@ -42,6 +49,57 @@ const EnableTracerModal = ({ isOpen, setIsOpen, triggerJobStart }) => {
42
49
  handleClose();
43
50
  };
44
51
 
52
+ const body = (
53
+ <TextContent>
54
+ <Text ouiaId="enable-tracer-modal-text" id="enable-tracer-modal-p">
55
+ {__('Enabling Tracer requires installing the katello-host-tools-tracer package on the host.')}
56
+ </Text>
57
+ {!tracerRpmAvailable && (
58
+ <>
59
+ <Alert
60
+ ouiaId="enable-tracer-modal-prereq-text"
61
+ variant="warning"
62
+ isInline
63
+ title={__('Before continuing, ensure that all of the following prerequisites are met:')}
64
+ />
65
+ <TextList className="enable-tracer-modal-prereq-list">
66
+ <TextListItem>
67
+ {__('The Foreman Client repository is enabled. ')}
68
+ <a onClick={() => setButtonLoading(true)} href="/redhat_repositories" id="enable-tracer-enable-red-hat-repos-link">
69
+ {__('Enable Red Hat repositories')}
70
+ </a>
71
+ <ArrowRightIcon />
72
+ </TextListItem>
73
+ <TextListItem>
74
+ {__('The Foreman Client repository is synced. ')}
75
+ <a onClick={() => setButtonLoading(true)} href="/katello/sync_management" id="enable-tracer-sync-status-link">
76
+ {__('View sync status')}
77
+ </a>
78
+ <ArrowRightIcon />
79
+ </TextListItem>
80
+ <TextListItem>
81
+ {__('The Foreman Client repository is available in the host\'s content view environment(s). ')}
82
+ <a onClick={() => setButtonLoading(true)} href="/content_views" id="enable-tracer-cv-link">
83
+ {__('View content views')}
84
+ </a>
85
+ <ArrowRightIcon />
86
+ </TextListItem>
87
+ <TextListItem id="enable-repo-sets-p">
88
+ {__('The Foreman Client repository set is enabled for the host. ')}
89
+ <a onClick={() => setButtonLoading(true)} href="#/Content/Repository%20sets" id="enable-tracer-reposets-link">
90
+ {__('Enable repository sets')}
91
+ </a>
92
+ <ArrowRightIcon />
93
+ </TextListItem>
94
+ <TextListItem>
95
+ {__('Remote execution is enabled.')}
96
+ </TextListItem>
97
+ </TextList>
98
+ </>
99
+ )}
100
+ </TextContent>
101
+ );
102
+
45
103
  const dropdownItems = dropdownOptions.map(text => (
46
104
  <DropdownItem key={`option_${text}`} ouiaId={`option_${text}`} onClick={() => setSelectedOption(text)}>{text}</DropdownItem>
47
105
  ));
@@ -86,7 +144,7 @@ const EnableTracerModal = ({ isOpen, setIsOpen, triggerJobStart }) => {
86
144
  variant={ModalVariant.small}
87
145
  title={title}
88
146
  ouiaId="enable-tracer-modal"
89
- width="28em"
147
+ width="46em"
90
148
  isOpen={isOpen}
91
149
  onClose={handleClose}
92
150
  actions={[
@@ -96,7 +154,14 @@ const EnableTracerModal = ({ isOpen, setIsOpen, triggerJobStart }) => {
96
154
  >
97
155
  <Flex direction={{ default: 'column' }}>
98
156
  <FlexItem>{body}</FlexItem>
99
- <FlexItem><div>{__('Select a provider to install katello-host-tools-tracer')}</div></FlexItem>
157
+ <FlexItem>
158
+ <TextContent>
159
+ <Text ouiaId="enable-tracer-modal-provider-text">
160
+ {tracerRpmAvailable ? __('Select a provider to install katello-host-tools-tracer') :
161
+ __('Once the prerequisites are met, select a provider to install katello-host-tools-tracer')}
162
+ </Text>
163
+ </TextContent>
164
+ </FlexItem>
100
165
  <FlexItem>
101
166
  <Dropdown
102
167
  ouiaId="enable-tracer-modal-dropdown"
@@ -126,6 +191,7 @@ EnableTracerModal.propTypes = {
126
191
  isOpen: PropTypes.bool.isRequired,
127
192
  setIsOpen: PropTypes.func.isRequired,
128
193
  triggerJobStart: PropTypes.func.isRequired,
194
+ tracerRpmAvailable: PropTypes.bool.isRequired,
129
195
  };
130
196
 
131
197
  export default EnableTracerModal;
@@ -0,0 +1,16 @@
1
+ .pf-c-content {
2
+ ul {
3
+ margin-top: 1rem;
4
+ li svg {
5
+ margin-right: 0.3rem;
6
+ margin-left: 0.3rem;
7
+ }
8
+ }
9
+ #enable-tracer-modal-p {
10
+ width: 32rem;
11
+ }
12
+ }
13
+
14
+ #enable-repo-sets-p {
15
+ width: 28rem;
16
+ }
@@ -53,7 +53,7 @@ EnableTracerButton.propTypes = {
53
53
  pollingStarted: PropTypes.bool.isRequired,
54
54
  };
55
55
 
56
- const TracesEnabler = ({ hostname }) => {
56
+ const TracesEnabler = ({ hostname, tracerRpmAvailable }) => {
57
57
  const title = __('Traces are not enabled');
58
58
  const enablingTitle = __('Traces are being enabled');
59
59
  const body = __('Traces help administrators identify applications that need to be restarted after a system is patched.');
@@ -91,9 +91,11 @@ const TracesEnabler = ({ hostname }) => {
91
91
  </Flex>
92
92
  </EmptyStateBody>
93
93
  <EnableTracerModal
94
+ key={hostname}
94
95
  isOpen={enableTracerModalOpen}
95
96
  setIsOpen={setEnableTracerModalOpen}
96
97
  triggerJobStart={triggerJobStart}
98
+ tracerRpmAvailable={tracerRpmAvailable}
97
99
  />
98
100
  </EmptyState>
99
101
  );
@@ -101,6 +103,7 @@ const TracesEnabler = ({ hostname }) => {
101
103
 
102
104
  TracesEnabler.propTypes = {
103
105
  hostname: PropTypes.string.isRequired,
106
+ tracerRpmAvailable: PropTypes.bool.isRequired,
104
107
  };
105
108
 
106
109
  export default TracesEnabler;
@@ -8,9 +8,10 @@ import { translate as __ } from 'foremanReact/common/I18n';
8
8
  import { TableVariant, Thead, Tbody, Tr, Th, Td } from '@patternfly/react-table';
9
9
  import { useSelector } from 'react-redux';
10
10
  import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
11
+ import { useBulkSelect, useUrlParams } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
12
+ import { useTableSort } from 'foremanReact/components/PF4/Helpers/useTableSort';
11
13
  import TracesEnabler from './TracesEnabler';
12
14
  import TableWrapper from '../../../../Table/TableWrapper';
13
- import { useBulkSelect, useTableSort, useUrlParams } from '../../../../Table/TableHooks';
14
15
  import { getHostTraces } from './HostTracesActions';
15
16
  import { resolveTraces } from '../RemoteExecutionActions';
16
17
  import { selectHostTracesStatus } from './HostTracesSelectors';
@@ -36,6 +37,7 @@ const TracesTab = () => {
36
37
  } = hostDetails;
37
38
  const showActions = can(invokeRexJobs, userPermissionsFromHostDetails({ hostDetails }));
38
39
  const showEnableTracer = (contentFacetAttributes?.katello_tracer_installed === false);
40
+ const tracerRpmAvailable = contentFacetAttributes?.katello_tracer_rpm_available;
39
41
  const emptyContentTitle = showActions ? __('No applications to restart') : __('Traces not available');
40
42
  const tracesNotAvailBody = showEnableTracer ? __('Traces may be enabled by a user with the appropriate permissions.') :
41
43
  __('Traces will be shown here to a user with the appropriate permissions.');
@@ -180,7 +182,9 @@ const TracesTab = () => {
180
182
 
181
183
  ) : null;
182
184
  const status = useSelector(state => selectHostTracesStatus(state));
183
- if (showEnableTracer && showActions) return <TracesEnabler hostname={hostname} />;
185
+ if (showEnableTracer && showActions) {
186
+ return <TracesEnabler hostname={hostname} tracerRpmAvailable={tracerRpmAvailable} />;
187
+ }
184
188
 
185
189
  if (!hostId) return <Skeleton />;
186
190
 
@@ -1,12 +1,12 @@
1
1
  import React from 'react';
2
2
  import { renderWithRedux, patientlyWaitFor, fireEvent } from 'react-testing-lib-wrapper';
3
+ import * as hooks from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
3
4
  import { nockInstance, assertNockRequest, mockForemanAutocomplete } from '../../../../../test-utils/nockWrapper';
4
5
  import { foremanApi } from '../../../../../services/api';
5
6
  import { HOST_PACKAGES_KEY, PACKAGES_SEARCH_QUERY, SELECTED_UPDATE_VERSIONS } from '../PackagesTab/HostPackagesConstants';
6
7
  import { PackagesTab } from '../PackagesTab/PackagesTab.js';
7
8
  import mockPackagesData from './packages.fixtures.json';
8
9
  import { REX_FEATURES } from '../RemoteExecutionConstants';
9
- import * as hooks from '../../../../Table/TableHooks';
10
10
 
11
11
  jest.mock('../../hostDetailsHelpers', () => ({
12
12
  ...jest.requireActual('../../hostDetailsHelpers'),
@@ -271,6 +271,7 @@ test('Can bulk upgrade via remote execution', async (done) => {
271
271
  },
272
272
  search_query: `name ^ (${hostname})`,
273
273
  feature: REX_FEATURES.KATELLO_PACKAGES_UPDATE_BY_SEARCH,
274
+ description_format: 'Upgrade package(s) chrony, coreutils',
274
275
  },
275
276
  })
276
277
  .reply(201);
@@ -31,6 +31,7 @@ const tracerNotInstalledResponse = {
31
31
  ...tracerInstalledResponse,
32
32
  content_facet_attributes: {
33
33
  katello_tracer_installed: false,
34
+ katello_tracer_rpm_available: false,
34
35
  },
35
36
  };
36
37
 
@@ -395,6 +396,30 @@ describe('Without tracer installed', () => {
395
396
  assertNockRequest(jobInvocationScope, done);
396
397
  });
397
398
 
399
+ test('Detects if tracer package is not available to install', async () => {
400
+ const { getByText, queryByText }
401
+ = renderWithRedux(<TracesTab />, renderOptions(false));
402
+
403
+ await patientlyWaitFor(() => expect(queryByText('Traces are not enabled')).toBeInTheDocument());
404
+ const enableTracesButton = getByText('Enable Traces');
405
+ enableTracesButton.click();
406
+
407
+ expect(getByText('Before continuing, ensure that all of the following prerequisites are met:')).toBeInTheDocument();
408
+ });
409
+
410
+ test('Detects when tracer package is available to install', async () => {
411
+ tracerNotInstalledResponse.content_facet_attributes.katello_tracer_rpm_available = true;
412
+
413
+ const { getByText, queryByText }
414
+ = renderWithRedux(<TracesTab />, renderOptions(false));
415
+
416
+ await patientlyWaitFor(() => expect(queryByText('Traces are not enabled')).toBeInTheDocument());
417
+ const enableTracesButton = getByText('Enable Traces');
418
+ enableTracesButton.click();
419
+
420
+ expect(queryByText('Before continuing, ensure that all of the following prerequisites are met:')).not.toBeInTheDocument();
421
+ });
422
+
398
423
  test('Can enable tracer via customized remote execution', async () => {
399
424
  const feature = REX_FEATURES.KATELLO_PACKAGE_INSTALL;
400
425
  const { getByText, getByRole, queryByText }
@@ -0,0 +1,36 @@
1
+ import React, { useContext } from 'react';
2
+ import { DropdownItem } from '@patternfly/react-core';
3
+ import { translate as __ } from 'foremanReact/common/I18n';
4
+ import { foremanUrl } from 'foremanReact/common/helpers';
5
+ import { ForemanHostsIndexActionsBarContext } from 'foremanReact/components/HostsIndex';
6
+
7
+ const HostActionsBar = () => {
8
+ const {
9
+ fetchBulkParams,
10
+ selectedCount,
11
+ selectAllMode,
12
+ } = useContext(ForemanHostsIndexActionsBarContext);
13
+
14
+ let href = '';
15
+ if (selectAllMode) {
16
+ const query = fetchBulkParams({ selectAllQuery: 'created_at < "1 second ago"' });
17
+ href = foremanUrl(`/change_host_content_source?search=${query}`);
18
+ } else if (selectedCount > 0) {
19
+ href = foremanUrl(`/change_host_content_source?search=${fetchBulkParams()}`);
20
+ }
21
+
22
+ return (
23
+ <>
24
+ <DropdownItem
25
+ ouiaId="change-content-s-dropdown-item"
26
+ key="change-content-source-dropdown-item"
27
+ href={href}
28
+ isDisabled={selectedCount === 0}
29
+ >
30
+ {__('Change content source')}
31
+ </DropdownItem>
32
+ </>
33
+ );
34
+ };
35
+
36
+ export default HostActionsBar;
@@ -0,0 +1,2 @@
1
+ const HOSTS_INDEX = 'HOSTS';
2
+ export default HOSTS_INDEX;