katello 4.6.2.1 → 4.7.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (333) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/common/vendor.js +0 -1
  3. data/app/controllers/katello/api/v2/activation_keys_controller.rb +1 -0
  4. data/app/controllers/katello/api/v2/alternate_content_sources_controller.rb +4 -4
  5. data/app/controllers/katello/api/v2/capsule_content_controller.rb +5 -0
  6. data/app/controllers/katello/api/v2/content_imports_controller.rb +1 -0
  7. data/app/controllers/katello/api/v2/content_view_components_controller.rb +1 -1
  8. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +2 -1
  9. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +1 -1
  10. data/app/controllers/katello/api/v2/organizations_controller.rb +1 -0
  11. data/app/controllers/katello/api/v2/repositories_controller.rb +78 -12
  12. data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +1 -1
  13. data/app/controllers/katello/concerns/api/v2/registration_controller_extensions.rb +7 -1
  14. data/app/controllers/katello/concerns/api/v2/smart_proxies_controller_extensions.rb +1 -0
  15. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +11 -9
  16. data/app/helpers/katello/content_source_helper.rb +9 -0
  17. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +31 -0
  18. data/app/lib/actions/katello/activation_key/destroy.rb +1 -0
  19. data/app/lib/actions/katello/agent_action.rb +1 -0
  20. data/app/lib/actions/katello/alternate_content_source/create.rb +1 -1
  21. data/app/lib/actions/katello/alternate_content_source/update.rb +2 -2
  22. data/app/lib/actions/katello/capsule_content/sync.rb +10 -2
  23. data/app/lib/actions/katello/cdn_configuration/update.rb +1 -1
  24. data/app/lib/actions/katello/content_view/promote.rb +1 -0
  25. data/app/lib/actions/katello/content_view/publish.rb +5 -2
  26. data/app/lib/actions/katello/content_view_version/auto_create_redhat_repositories.rb +7 -3
  27. data/app/lib/actions/katello/content_view_version/auto_create_repositories.rb +4 -2
  28. data/app/lib/actions/katello/content_view_version/import.rb +22 -10
  29. data/app/lib/actions/katello/product/destroy.rb +1 -1
  30. data/app/lib/actions/katello/repository/destroy.rb +3 -3
  31. data/app/lib/actions/katello/repository/errata_mail.rb +9 -6
  32. data/app/lib/actions/katello/repository/refresh_repository.rb +1 -1
  33. data/app/lib/actions/katello/repository/sync.rb +13 -6
  34. data/app/lib/actions/katello/repository_set/enable_repository.rb +6 -2
  35. data/app/lib/actions/pulp3/alternate_content_source/refresh_remote.rb +16 -0
  36. data/app/lib/actions/pulp3/orchestration/alternate_content_source/refresh.rb +1 -0
  37. data/app/lib/actions/pulp3/orchestration/content_view_version/export_library.rb +1 -1
  38. data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +10 -2
  39. data/app/lib/katello/concerns/renderer_extensions.rb +2 -1
  40. data/app/lib/katello/errors.rb +2 -2
  41. data/app/lib/katello/resources/candlepin.rb +7 -1
  42. data/app/lib/katello/resources/cdn/katello_cdn.rb +3 -13
  43. data/app/lib/katello/resources/cdn.rb +14 -9
  44. data/app/lib/katello/util/candlepin_repository_checker.rb +73 -0
  45. data/app/models/katello/activation_key.rb +12 -1
  46. data/app/models/katello/alternate_content_source.rb +15 -4
  47. data/app/models/katello/alternate_content_source_product.rb +1 -1
  48. data/app/models/katello/authorization/repository.rb +2 -2
  49. data/app/models/katello/cdn_configuration.rb +12 -3
  50. data/app/models/katello/concerns/host_managed_extensions.rb +15 -2
  51. data/app/models/katello/concerns/http_proxy_extensions.rb +5 -10
  52. data/app/models/katello/concerns/smart_proxy_extensions.rb +30 -15
  53. data/app/models/katello/content.rb +15 -0
  54. data/app/models/katello/content_credential.rb +8 -9
  55. data/app/models/katello/content_view.rb +7 -3
  56. data/app/models/katello/content_view_component.rb +4 -0
  57. data/app/models/katello/content_view_version.rb +1 -1
  58. data/app/models/katello/erratum.rb +6 -2
  59. data/app/models/katello/host/content_facet.rb +13 -3
  60. data/app/models/katello/repository.rb +15 -1
  61. data/app/models/katello/root_repository.rb +0 -2
  62. data/app/overrides/add_smart_proxy_form.rb +5 -0
  63. data/app/presenters/katello/content_view_version_compare_presenter.rb +5 -0
  64. data/app/presenters/katello/host_package_presenter.rb +4 -4
  65. data/app/services/katello/pulp3/alternate_content_source.rb +23 -15
  66. data/app/services/katello/pulp3/ansible_collection.rb +7 -10
  67. data/app/services/katello/pulp3/content_view_version/export.rb +19 -6
  68. data/app/services/katello/pulp3/content_view_version/import.rb +2 -0
  69. data/app/services/katello/pulp3/content_view_version/import_validator.rb +21 -5
  70. data/app/services/katello/pulp3/content_view_version/importable_products.rb +11 -1
  71. data/app/services/katello/pulp3/content_view_version/importable_repositories.rb +38 -9
  72. data/app/services/katello/pulp3/content_view_version/metadata_generator.rb +12 -5
  73. data/app/services/katello/pulp3/content_view_version/metadata_map.rb +13 -2
  74. data/app/services/katello/pulp3/content_view_version/syncable_format_export.rb +5 -1
  75. data/app/services/katello/pulp3/pulp_content_unit.rb +3 -0
  76. data/app/services/katello/pulp3/repository.rb +18 -6
  77. data/app/services/katello/pulp3/repository_mirror.rb +0 -1
  78. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +2 -2
  79. data/app/services/katello/pulp3/task_group.rb +18 -1
  80. data/app/services/katello/repository_type.rb +5 -2
  81. data/app/services/katello/repository_type_manager.rb +4 -3
  82. data/app/views/dashboard/_content_views_widget.html.erb +1 -1
  83. data/app/views/foreman/job_templates/change_content_source.erb +6 -0
  84. data/app/views/foreman/job_templates/update_packages_by_search_query.erb +7 -1
  85. data/app/views/katello/api/v2/alternate_content_sources/base.json.rabl +4 -4
  86. data/app/views/katello/api/v2/alternate_content_sources/index.json.rabl +1 -0
  87. data/app/views/katello/api/v2/alternate_content_sources/permissions.rabl +11 -0
  88. data/app/views/katello/api/v2/content_credentials/show.json.rabl +12 -0
  89. data/app/views/katello/api/v2/content_views/permissions.rabl +1 -0
  90. data/app/views/katello/api/v2/host_packages/base.json.rabl +1 -1
  91. data/app/views/katello/api/v2/module_streams/show.json.rabl +7 -0
  92. data/app/views/katello/api/v2/repositories/compare.json.rabl +10 -0
  93. data/app/views/katello/api/v2/smart_proxies/pulp_info.json.rabl +1 -0
  94. data/app/views/katello/hosts/_errata_counts.html.erb +46 -0
  95. data/app/views/overrides/activation_keys/_host_synced_content_select.html.erb +1 -0
  96. data/app/views/overrides/smart_proxies/_acs_http_proxy.html.erb +6 -0
  97. data/config/initializers/monkeys.rb +1 -0
  98. data/config/routes/api/v2.rb +2 -0
  99. data/config/routes.rb +3 -0
  100. data/db/migrate/20220730033504_update_custom_cdn.rb +13 -0
  101. data/db/migrate/20220920173656_add_http_proxy_to_smart_proxy.rb +7 -0
  102. data/db/migrate/20220920180858_remove_http_proxy_from_katello_alternate_content_sources.rb +6 -0
  103. data/engines/bastion/app/assets/javascripts/bastion/components/notification.service.js +1 -1
  104. data/engines/bastion/app/views/bastion/layouts/assets.html.erb +5 -5
  105. data/engines/bastion/vendor/assets/javascripts/bastion/angular/angular.js +1 -1
  106. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credential.factory.js +17 -0
  107. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credentials.routes.js +10 -0
  108. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-acs.controller.js +36 -0
  109. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-details.controller.js +7 -1
  110. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/views/content-credential-acs.html +38 -0
  111. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/views/content-credential-details.html +3 -0
  112. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/views/content-credentials.html +7 -2
  113. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +4 -2
  114. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +1 -1
  115. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +4 -3
  116. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +14 -1392
  117. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/katello-features.run.js +1 -0
  118. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +7 -0
  119. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +1 -1
  120. data/lib/katello/permission_creator.rb +1 -0
  121. data/lib/katello/plugin.rb +34 -11
  122. data/lib/katello/repository_types/deb.rb +1 -1
  123. data/lib/katello/repository_types/docker.rb +1 -1
  124. data/lib/katello/repository_types/python.rb +3 -3
  125. data/lib/katello/tasks/check_candlepin_content.rake +16 -0
  126. data/lib/katello/tasks/reset.rake +1 -1
  127. data/lib/katello/version.rb +1 -1
  128. data/lib/monkeys/try_pulp_container_path.rb +35 -0
  129. data/locale/action_names.rb +7 -7
  130. data/locale/bn/katello.po +395 -63
  131. data/locale/cs/katello.po +396 -64
  132. data/locale/de/katello.po +399 -67
  133. data/locale/en/katello.po +395 -63
  134. data/locale/es/katello.po +399 -67
  135. data/locale/fr/katello.po +400 -68
  136. data/locale/gu/katello.po +395 -63
  137. data/locale/hi/katello.po +395 -63
  138. data/locale/it/katello.po +396 -64
  139. data/locale/ja/katello.po +400 -68
  140. data/locale/katello.pot +1916 -1213
  141. data/locale/kn/katello.po +395 -63
  142. data/locale/ko/katello.po +396 -64
  143. data/locale/mr/katello.po +395 -63
  144. data/locale/or/katello.po +395 -63
  145. data/locale/pa/katello.po +395 -63
  146. data/locale/pt/katello.po +395 -63
  147. data/locale/pt_BR/katello.po +399 -67
  148. data/locale/ru/katello.po +396 -64
  149. data/locale/ta/katello.po +395 -63
  150. data/locale/te/katello.po +395 -63
  151. data/locale/zh_CN/katello.po +400 -68
  152. data/locale/zh_TW/katello.po +396 -64
  153. data/webpack/components/Bookmark/index.js +5 -1
  154. data/webpack/components/Content/Details/ContentDetails.js +1 -1
  155. data/webpack/components/Content/Details/__tests__/__snapshots__/ContentDetails.test.js.snap +6 -0
  156. data/webpack/components/EditableSwitch.js +1 -0
  157. data/webpack/components/EditableTextInput/EditableTextInput.js +3 -3
  158. data/webpack/components/Errata/errataHelpers.js +33 -0
  159. data/webpack/components/Errata/index.js +45 -12
  160. data/webpack/components/Loading.js +18 -8
  161. data/webpack/components/Packages/index.js +8 -24
  162. data/webpack/components/RoutedTabs/index.js +1 -0
  163. data/webpack/components/Search/Search.js +20 -2
  164. data/webpack/components/Search/__tests__/search.test.js +3 -3
  165. data/webpack/components/Table/EmptyStateMessage.js +1 -1
  166. data/webpack/components/Table/PageControls.js +1 -0
  167. data/webpack/components/Table/TableHooks.js +4 -0
  168. data/webpack/components/Table/TableWrapper.js +7 -7
  169. data/webpack/components/TypeAhead/pf4Search/TypeAheadInput.js +1 -0
  170. data/webpack/components/TypeAhead/pf4Search/TypeAheadItems.js +2 -0
  171. data/webpack/components/TypeAhead/pf4Search/TypeAheadSearch.js +1 -1
  172. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ChangeHostCVModal.js +3 -1
  173. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +2 -1
  174. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.js +124 -68
  175. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.scss +5 -0
  176. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.js +30 -4
  177. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.scss +23 -0
  178. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsModal.js +5 -4
  179. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/hostCollectionsCard.test.js +25 -10
  180. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.js +3 -3
  181. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeEditModal.js +6 -0
  182. data/webpack/components/extensions/HostDetails/Cards/__tests__/errataOverviewCard.test.js +145 -32
  183. data/webpack/components/extensions/HostDetails/DetailsTabCards/RegistrationCard.js +3 -1
  184. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/constants.js +2 -1
  185. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/index.js +1 -0
  186. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +78 -26
  187. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +23 -10
  188. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/HostPackagesConstants.js +1 -0
  189. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +9 -4
  190. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +141 -23
  191. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.scss +6 -1
  192. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +9 -8
  193. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +24 -3
  194. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.js +7 -2
  195. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesEnabler.js +2 -1
  196. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js +20 -4
  197. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +56 -38
  198. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packages.fixtures.json +3 -3
  199. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +5 -4
  200. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +3 -3
  201. data/webpack/containers/Application/config.js +2 -2
  202. data/webpack/containers/Application/overrides.scss +12 -0
  203. data/webpack/global_test_setup.js +19 -1
  204. data/webpack/ouia_id_check.js +0 -2
  205. data/webpack/redux/actions/RedHatRepositories/helpers.js +4 -8
  206. data/webpack/scenes/AlternateContentSources/ACSActions.js +37 -6
  207. data/webpack/scenes/AlternateContentSources/ACSConstants.js +2 -0
  208. data/webpack/scenes/AlternateContentSources/ACSIndexPage.js +1 -1
  209. data/webpack/scenes/AlternateContentSources/ACSSelectors.js +6 -6
  210. data/webpack/scenes/AlternateContentSources/Acs.scss +3 -0
  211. data/webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js +24 -3
  212. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js +10 -8
  213. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCredentials.js +25 -4
  214. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSReview.js +22 -11
  215. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSSmartProxies.js +27 -2
  216. data/webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js +49 -17
  217. data/webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js +76 -23
  218. data/webpack/scenes/AlternateContentSources/Create/__tests__/acsCreate.test.js +159 -11
  219. data/webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js +83 -29
  220. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditCredentials.js +9 -8
  221. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditDetails.js +2 -2
  222. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditProducts.js +2 -2
  223. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditSmartProxies.js +39 -7
  224. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditURLPaths.js +27 -11
  225. data/webpack/scenes/AlternateContentSources/Details/__tests__/ACSEdits.test.js +58 -55
  226. data/webpack/scenes/AlternateContentSources/Details/__tests__/ACSExpandableDetails.test.js +35 -32
  227. data/webpack/scenes/AlternateContentSources/MainTable/ACSTable.js +323 -150
  228. data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsIndex.fixtures.json +5 -1
  229. data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsTable.test.js +10 -11
  230. data/webpack/scenes/AlternateContentSources/helpers.js +26 -0
  231. data/webpack/scenes/ContentViews/ContentViewsConstants.js +1 -0
  232. data/webpack/scenes/ContentViews/ContentViewsPage.js +1 -1
  233. data/webpack/scenes/ContentViews/Copy/CopyContentViewForm.js +1 -0
  234. data/webpack/scenes/ContentViews/Copy/CopyContentViewModal.js +1 -0
  235. data/webpack/scenes/ContentViews/Create/ContentViewFormComponents.js +10 -5
  236. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +30 -7
  237. data/webpack/scenes/ContentViews/Create/CreateContentViewModal.js +1 -0
  238. data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +21 -6
  239. data/webpack/scenes/ContentViews/Delete/Steps/CVDeleteEnvironmentsSelection.js +3 -3
  240. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionReassignActivationKeysForm.js +1 -0
  241. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionReassignHostsForm.js +1 -0
  242. data/webpack/scenes/ContentViews/Delete/__tests__/CvData.fixtures.json +2 -0
  243. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +3 -0
  244. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +4 -1
  245. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentVersion.js +1 -1
  246. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +2 -1
  247. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +14 -0
  248. data/webpack/scenes/ContentViews/Details/ContentViewDetailSelectors.js +11 -1
  249. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +1 -1
  250. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +2 -0
  251. data/webpack/scenes/ContentViews/Details/Filters/Add/CVFilterAddModal.js +5 -0
  252. data/webpack/scenes/ContentViews/Details/Filters/AffectedRepositories/AffectedRepositorySelection.js +1 -0
  253. data/webpack/scenes/ContentViews/Details/Filters/ArtifactsWithNoErrata.js +1 -0
  254. data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +8 -2
  255. data/webpack/scenes/ContentViews/Details/Filters/CVDebFilterContent.js +5 -1
  256. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +22 -6
  257. data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +19 -9
  258. data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +9 -2
  259. data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +9 -2
  260. data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +8 -2
  261. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilterDetailsHeader.js +1 -1
  262. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilters.js +2 -1
  263. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/CVRpmMatchContentModal.js +3 -2
  264. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/__tests__/CVRpmMatchContentModal.test.js +1 -1
  265. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVContainerImageFilterContent.test.js +2 -2
  266. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js +1 -1
  267. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilterDetails.test.js +1 -1
  268. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilters.test.js +1 -1
  269. data/webpack/scenes/ContentViews/Details/Histories/ContentViewHistories.js +2 -2
  270. data/webpack/scenes/ContentViews/Details/Promote/ContentViewVersionPromote.js +2 -0
  271. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +2 -1
  272. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/ReviewEnvironments.js +3 -3
  273. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompare.js +9 -1
  274. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareConfig.js +83 -0
  275. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareTable.js +32 -8
  276. data/webpack/scenes/ContentViews/Details/Versions/Compare/__tests__/CVVersionCompare.test.js +56 -3
  277. data/webpack/scenes/ContentViews/Details/Versions/Compare/__tests__/cvCompareRepositories.fixtures.json +175 -0
  278. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +6 -2
  279. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVEnvironmentSelectionForm.js +3 -3
  280. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignActivationKeysForm.js +1 -0
  281. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignHostsForm.js +1 -0
  282. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +2 -2
  283. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +2 -2
  284. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailConfig.js +2 -2
  285. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +1 -0
  286. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js +4 -1
  287. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +5 -4
  288. data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +5 -1
  289. data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +3 -3
  290. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +10 -5
  291. data/webpack/scenes/ContentViews/__tests__/basicContentViews.fixtures.js +2 -0
  292. data/webpack/scenes/ContentViews/__tests__/contentViewList.fixtures.json +1 -0
  293. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +81 -19
  294. data/webpack/scenes/ContentViews/components/CVBreadCrumb.js +1 -1
  295. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.js +1 -0
  296. data/webpack/scenes/ContentViews/components/InactiveText.js +9 -1
  297. data/webpack/scenes/ContentViews/expansions/RelatedCompositeContentViewsModal.js +4 -2
  298. data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +3 -2
  299. data/webpack/scenes/Hosts/ChangeContentSource/actions.js +18 -11
  300. data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceForm.js +15 -8
  301. data/webpack/scenes/Hosts/ChangeContentSource/components/FormField.js +3 -4
  302. data/webpack/scenes/Hosts/ChangeContentSource/components/Hosts.js +55 -0
  303. data/webpack/scenes/Hosts/ChangeContentSource/components/HostsModal.js +59 -0
  304. data/webpack/scenes/Hosts/ChangeContentSource/constants.js +1 -0
  305. data/webpack/scenes/Hosts/ChangeContentSource/helpers.js +2 -5
  306. data/webpack/scenes/Hosts/ChangeContentSource/index.js +46 -41
  307. data/webpack/scenes/Hosts/ChangeContentSource/selectors.js +5 -5
  308. data/webpack/scenes/ModuleStreams/Details/ModuleDetailsSchema.js +10 -1
  309. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +1 -1
  310. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetails.test.js.snap +97 -2
  311. data/webpack/scenes/Organizations/OrganizationSelectors.js +1 -0
  312. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnConfigurationConstants.js +2 -1
  313. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnTypeForm.js +10 -25
  314. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CustomCdnTypeForm.js +154 -0
  315. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/ExportSyncForm.js +4 -4
  316. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/NetworkSyncForm.js +59 -44
  317. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/CdnTypeForm.test.js +3 -28
  318. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/CustomCdnTypeForm.test.js +97 -0
  319. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/ExportSyncForm.test.js +1 -1
  320. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/NetworkSyncForm.test.js +4 -4
  321. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/index.js +23 -10
  322. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +1 -1
  323. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +2 -1
  324. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +5 -5
  325. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +3 -3
  326. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +2 -2
  327. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +3 -3
  328. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +3 -3
  329. data/webpack/scenes/Tasks/helpers.js +14 -7
  330. metadata +54 -35
  331. data/app/lib/actions/pulp3/orchestration/alternate_content_source/refresh_remote.rb +0 -18
  332. data/db/migrate/20221206170122_update_ignore_srpm_to_false_for_mirror_complete.rb +0 -5
  333. data/vendor/assets/javascripts/katello/jquery.trunk8.js +0 -203
@@ -6,7 +6,8 @@ module Katello
6
6
  included do
7
7
  has_many :root_repositories, :class_name => "::Katello::RootRepository", :foreign_key => :http_proxy_id,
8
8
  :inverse_of => :http_proxy, :dependent => :nullify
9
- has_many :alternate_content_sources, :class_name => "::Katello::AlternateContentSource", :foreign_key => :http_proxy_id,
9
+ # A smart proxy's HTTP proxy is used for all related alternate content sources.
10
+ has_many :smart_proxies, :class_name => "::SmartProxy", :foreign_key => :http_proxy_id,
10
11
  :inverse_of => :http_proxy, :dependent => :nullify
11
12
  after_update :update_default_proxy_setting
12
13
  after_commit :update_repository_proxy_details
@@ -31,7 +32,6 @@ module Katello
31
32
 
32
33
  def remove_references_to_proxy
33
34
  root_repos = repositories_with_proxy(nil).uniq.sort
34
- acss = ::Katello::AlternateContentSource.where(http_proxy_id: id)
35
35
 
36
36
  setting = Setting.find_by(name: 'content_default_http_proxy')
37
37
  if setting&.value && setting.value == self.name
@@ -47,14 +47,9 @@ module Katello
47
47
  http_proxy_id: nil)
48
48
  end
49
49
 
50
- unless acss.empty?
51
- acss.each do |acs|
52
- ForemanTasks.async_task(
53
- ::Actions::Katello::AlternateContentSource::Update,
54
- acs,
55
- acs.smart_proxies,
56
- http_proxy_id: nil
57
- )
50
+ unless smart_proxies.empty?
51
+ smart_proxies.each do |smart_proxy|
52
+ smart_proxy.update(http_proxy_id: nil)
58
53
  end
59
54
  end
60
55
  end
@@ -38,24 +38,27 @@ module Katello
38
38
 
39
39
  lazy_accessor :pulp_repositories, :initializer => lambda { |_s| pulp_node.extensions.repository.retrieve_all }
40
40
 
41
+ # A smart proxy's HTTP proxy is used for all related alternate content sources.
42
+ belongs_to :http_proxy, :inverse_of => :smart_proxies, :class_name => '::HttpProxy'
43
+
41
44
  has_many :capsule_lifecycle_environments,
42
- :class_name => "Katello::CapsuleLifecycleEnvironment",
45
+ :class_name => "Katello::CapsuleLifecycleEnvironment",
43
46
  :foreign_key => :capsule_id,
44
- :dependent => :destroy,
47
+ :dependent => :destroy,
45
48
  :inverse_of => :capsule
46
49
 
47
50
  has_many :lifecycle_environments,
48
51
  :class_name => "Katello::KTEnvironment",
49
- :through => :capsule_lifecycle_environments,
50
- :source => :lifecycle_environment
52
+ :through => :capsule_lifecycle_environments,
53
+ :source => :lifecycle_environment
51
54
 
52
55
  has_many :content_facets, :class_name => "::Katello::Host::ContentFacet", :foreign_key => :content_source_id,
53
- :inverse_of => :content_source, :dependent => :nullify
56
+ :inverse_of => :content_source, :dependent => :nullify
54
57
 
55
58
  has_many :smart_proxy_sync_histories, :class_name => "::Katello::SmartProxySyncHistory", :inverse_of => :smart_proxy, dependent: :delete_all
56
59
 
57
60
  has_many :hostgroup_content_facets, :class_name => "::Katello::Hostgroup::ContentFacet", :foreign_key => :content_source_id,
58
- :inverse_of => :content_source, :dependent => :nullify
61
+ :inverse_of => :content_source, :dependent => :nullify
59
62
  has_many :hostgroups, :class_name => "::Hostgroup", :through => :hostgroup_content_facets
60
63
  has_many :smart_proxy_alternate_content_sources, :class_name => "::Katello::SmartProxyAlternateContentSource", :inverse_of => :smart_proxy, :dependent => :delete_all
61
64
 
@@ -67,7 +70,7 @@ module Katello
67
70
 
68
71
  def self.with_repo(repo)
69
72
  joins(:capsule_lifecycle_environments).
70
- where("#{Katello::CapsuleLifecycleEnvironment.table_name}.lifecycle_environment_id" => repo.environment_id)
73
+ where("#{Katello::CapsuleLifecycleEnvironment.table_name}.lifecycle_environment_id" => repo.environment_id)
71
74
  end
72
75
 
73
76
  def self.pulp_primary
@@ -101,12 +104,12 @@ module Katello
101
104
  features << PULP_FEATURE if include_default
102
105
 
103
106
  unscoped.with_features(features).joins(:capsule_lifecycle_environments).
104
- where(katello_capsule_lifecycle_environments: { lifecycle_environment_id: environment.id })
107
+ where(katello_capsule_lifecycle_environments: { lifecycle_environment_id: environment.id })
105
108
  end
106
109
 
107
110
  def self.pulpcore_proxies_with_environment(environment)
108
111
  unscoped.where(id: unscoped.select { |p| p.pulp_mirror? }.pluck(:id)).joins(:capsule_lifecycle_environments).
109
- where(katello_capsule_lifecycle_environments: { lifecycle_environment_id: environment.id })
112
+ where(katello_capsule_lifecycle_environments: { lifecycle_environment_id: environment.id })
110
113
  end
111
114
 
112
115
  def self.sync_needed?(environment)
@@ -114,6 +117,10 @@ module Katello
114
117
  end
115
118
  end
116
119
 
120
+ def alternate_content_sources
121
+ SmartProxy.joins(:smart_proxy_alternate_content_sources).where('katello_smart_proxy_alternate_content_sources.smart_proxy_id' => self.id)
122
+ end
123
+
117
124
  def sync_container_gateway
118
125
  if has_feature?(::SmartProxy::CONTAINER_GATEWAY_FEATURE)
119
126
  update_container_repo_list
@@ -249,7 +256,7 @@ module Katello
249
256
  end
250
257
 
251
258
  def fix_pulp3_capabilities(type)
252
- if type.is_a?(String) || type.is_a?(Symbol)
259
+ if type.is_a?(String) || type.is_a?(Symbol)
253
260
  repository_type_obj = Katello::RepositoryTypeManager.defined_repository_types[type]
254
261
  else
255
262
  repository_type_obj = type
@@ -270,7 +277,7 @@ module Katello
270
277
  repository_type_obj.pulp3_plugin.present? &&
271
278
  pulp3_enabled? &&
272
279
  (self.capabilities(PULP3_FEATURE).try(:include?, repository_type_obj.pulp3_plugin) ||
273
- self.capabilities(PULP3_FEATURE).try(:include?, 'pulp_' + repository_type_obj.pulp3_plugin))
280
+ self.capabilities(PULP3_FEATURE).try(:include?, 'pulp_' + repository_type_obj.pulp3_plugin))
274
281
  end
275
282
 
276
283
  def pulp3_content_support?(content_type)
@@ -344,7 +351,7 @@ module Katello
344
351
  content_type_string = content_type_obj&.label || content_type
345
352
  unless content_type_obj
346
353
  fail _("Content type %{content_type_string} does not belong to an enabled repo type.") %
347
- { content_type_string: content_type_string }
354
+ { content_type_string: content_type_string }
348
355
  end
349
356
  content_type_obj.pulp3_service_class
350
357
  end
@@ -377,7 +384,7 @@ module Katello
377
384
  end
378
385
 
379
386
  def sync_tasks
380
- ForemanTasks::Task.for_resource(self)
387
+ ForemanTasks::Task.for_resource(self).where(:label => 'Actions::Katello::CapsuleContent::Sync')
381
388
  end
382
389
 
383
390
  def active_sync_tasks
@@ -388,10 +395,14 @@ module Katello
388
395
  sync_tasks.where('started_at > ?', last_sync_time).where.not(:result => 'pending')
389
396
  end
390
397
 
398
+ def last_sync_audit
399
+ Audited::Audit.where(:auditable_id => self, :auditable_type => SmartProxy.name, action: "sync capsule").order(:created_at).last
400
+ end
401
+
391
402
  def last_sync_time
392
403
  task = sync_tasks.where.not(:ended_at => nil).where(:result => 'success').order(:ended_at).last
393
404
 
394
- task&.ended_at
405
+ task&.ended_at || last_sync_audit&.created_at&.to_s
395
406
  end
396
407
 
397
408
  def environment_syncable?(env)
@@ -448,7 +459,7 @@ module Katello
448
459
  # Since Foreman 3.1 this setting is set
449
460
  if (rhsm_url = setting(SmartProxy::PULP3_FEATURE, 'rhsm_url'))
450
461
  URI(rhsm_url)
451
- # Compatibility fall back
462
+ # Compatibility fall back
452
463
  elsif pulp_primary?
453
464
  URI("https://#{URI.parse(url).host}/rhsm")
454
465
  elsif pulp_mirror?
@@ -460,6 +471,10 @@ module Katello
460
471
  URI(setting(SmartProxy::PULP3_FEATURE, 'content_app_url'))
461
472
  end
462
473
 
474
+ def audit_capsule_sync
475
+ write_audit(action: "sync capsule", comment: _('Successfully synced capsule.'), audited_changes: {})
476
+ end
477
+
463
478
  class ::SmartProxy::Jail < ::Safemode::Jail
464
479
  allow :rhsm_url, :pulp_content_url
465
480
  end
@@ -63,5 +63,20 @@ module Katello
63
63
  new_url_subs = new_url&.scan(/\$\w+/)&.sort
64
64
  current_subs == new_url_subs
65
65
  end
66
+
67
+ def self.substitute_content_path(arch: nil, releasever: nil, content_path:)
68
+ arch = nil if arch == "noarch"
69
+ substitutions = {
70
+ :releasever => releasever,
71
+ :basearch => arch
72
+ }.compact
73
+ path = substitutions.inject(content_path) do |path_url, (key, value)|
74
+ path_url.gsub("$#{key}", value)
75
+ end
76
+ {
77
+ path: path,
78
+ substitutions: substitutions
79
+ }
80
+ end
66
81
  end
67
82
  end
@@ -9,26 +9,25 @@ module Katello
9
9
  GPG_KEY_TYPE = 'gpg_key'.freeze
10
10
  CERT_TYPE = 'cert'.freeze
11
11
 
12
- has_many :root_repositories, :class_name => "Katello::RootRepository", :inverse_of => :gpg_key, :dependent => :nullify, :foreign_key => 'gpg_key_id'
12
+ has_many :root_repositories, :class_name => "Katello::RootRepository", :inverse_of => :gpg_key, :dependent => :restrict_with_exception, :foreign_key => 'gpg_key_id'
13
13
  has_many :repositories, :through => :root_repositories
14
14
 
15
- has_many :products, :class_name => "Katello::Product", :inverse_of => :gpg_key, :dependent => :nullify, :foreign_key => 'gpg_key_id'
16
-
15
+ has_many :products, :class_name => "Katello::Product", :inverse_of => :gpg_key, :dependent => :restrict_with_exception, :foreign_key => 'gpg_key_id'
17
16
  has_many :ssl_ca_cdn_configurations, :class_name => "Katello::CdnConfiguration", :foreign_key => 'ssl_ca_credential_id',
18
17
  :inverse_of => :ssl_ca_credential, :dependent => :nullify
19
18
 
20
19
  has_many :ssl_ca_products, :class_name => "Katello::Product", :foreign_key => "ssl_ca_cert_id",
21
- :inverse_of => :ssl_ca_cert, :dependent => :nullify
20
+ :inverse_of => :ssl_ca_cert, :dependent => :restrict_with_exception
22
21
  has_many :ssl_client_products, :class_name => "Katello::Product", :foreign_key => "ssl_client_cert_id",
23
- :inverse_of => :ssl_client_cert, :dependent => :nullify
22
+ :inverse_of => :ssl_client_cert, :dependent => :restrict_with_exception
24
23
  has_many :ssl_key_products, :class_name => "Katello::Product", :foreign_key => "ssl_client_key_id",
25
- :inverse_of => :ssl_client_key, :dependent => :nullify
24
+ :inverse_of => :ssl_client_key, :dependent => :restrict_with_exception
26
25
  has_many :ssl_ca_root_repos, :class_name => "Katello::RootRepository", :foreign_key => "ssl_ca_cert_id",
27
- :inverse_of => :ssl_ca_cert, :dependent => :nullify
26
+ :inverse_of => :ssl_ca_cert, :dependent => :restrict_with_exception
28
27
  has_many :ssl_client_root_repos, :class_name => "Katello::RootRepository", :foreign_key => "ssl_client_cert_id",
29
- :inverse_of => :ssl_client_cert, :dependent => :nullify
28
+ :inverse_of => :ssl_client_cert, :dependent => :restrict_with_exception
30
29
  has_many :ssl_key_root_repos, :class_name => "Katello::RootRepository", :foreign_key => "ssl_client_key_id",
31
- :inverse_of => :ssl_client_key, :dependent => :nullify
30
+ :inverse_of => :ssl_client_key, :dependent => :restrict_with_exception
32
31
  has_many :ssl_ca_alternate_content_sources, :class_name => "Katello::AlternateContentSource", :foreign_key => "ssl_ca_cert_id",
33
32
  :inverse_of => :ssl_ca_cert, :dependent => :nullify
34
33
  has_many :ssl_client_alternate_content_sources, :class_name => "Katello::AlternateContentSource", :foreign_key => "ssl_client_cert_id",
@@ -87,7 +87,11 @@ module Katello
87
87
  scope :composite, -> { where(:composite => true) }
88
88
  scope :non_composite, -> { where(:composite => [nil, false]) }
89
89
  scope :generated, -> { where.not(:generated_for => :none) }
90
- scope :generated_for_repository, -> { where(:generated_for => [:repository_export, :repository_import]) }
90
+ scope :generated_for_repository, -> {
91
+ where(:generated_for => [:repository_export,
92
+ :repository_import,
93
+ :repository_export_syncable])
94
+ }
91
95
  scope :ignore_generated, -> {
92
96
  where.not(:generated_for => [:repository_export,
93
97
  :repository_import,
@@ -585,14 +589,14 @@ module Katello
585
589
  true
586
590
  end
587
591
 
588
- def check_ready_to_publish!(importing: false)
592
+ def check_ready_to_publish!(importing: false, syncable: false)
589
593
  fail _("User must be logged in.") if ::User.current.nil?
590
594
  fail _("Cannot publish default content view") if default?
591
595
 
592
596
  if importing
593
597
  check_ready_to_import!
594
598
  else
595
- fail _("Import-only content views can not be published directly") if import_only?
599
+ fail _("Import-only content views can not be published directly") if import_only? && !syncable
596
600
  check_composite_action_allowed!(organization.library)
597
601
  check_docker_repository_names!([organization.library])
598
602
  end
@@ -56,6 +56,10 @@ module Katello
56
56
  if attached_content_view_ids.include?(view.id)
57
57
  errors.add(:base, _("Another component already includes content view with ID %s" % view.id))
58
58
  end
59
+
60
+ unless view.generated_for_none?
61
+ errors.add(:base, _("Cannot add generated content view versions to composite content view"))
62
+ end
59
63
  end
60
64
 
61
65
  def ensure_valid_attributes
@@ -56,7 +56,7 @@ module Katello
56
56
  scope :with_organization_id, ->(organization_id) do
57
57
  joins(:content_view).where("#{Katello::ContentView.table_name}.organization_id" => organization_id)
58
58
  end
59
-
59
+ scope :not_ignorable, -> { where(content_view_id: Katello::ContentView.ignore_generated) }
60
60
  scope :triggered_by, ->(content_view_version_id) do
61
61
  sql = Katello::ContentViewHistory.where(:triggered_by_id => content_view_version_id).select(:katello_content_view_version_id).to_sql
62
62
  where("#{Katello::ContentViewVersion.table_name}.id in (#{sql})")
@@ -127,10 +127,14 @@ module Katello
127
127
  statement = query_clauses.join(" AND ")
128
128
  ModuleStream.where(:id => ModuleStreamErratumPackage.joins(:erratum_package => {:erratum => :repository_errata}).
129
129
  where("#{RepositoryErratum.table_name}.repository_id" => repo.id).
130
- where(statement).select("#{ModuleStreamErratumPackage.table_name}.module_stream_id")) -
130
+ where(statement).select("#{ModuleStreamErratumPackage.table_name}.module_stream_id")).
131
+ joins(:repository_module_streams).
132
+ where("#{RepositoryModuleStream.table_name}.repository_id" => repo.id) -
131
133
  ModuleStream.where(:id => ModuleStreamErratumPackage.joins(:erratum_package => {:erratum => :repository_errata}).
132
134
  where("#{RepositoryErratum.table_name}.repository_id" => repo.id).
133
- where(statement).where("#{Erratum.table_name}.errata_id" => additional_included_errata.pluck(:errata_id)).select("#{ModuleStreamErratumPackage.table_name}.module_stream_id"))
135
+ where(statement).where("#{Erratum.table_name}.errata_id" => additional_included_errata.pluck(:errata_id)).select("#{ModuleStreamErratumPackage.table_name}.module_stream_id")).
136
+ joins(:repository_module_streams).
137
+ where("#{RepositoryModuleStream.table_name}.repository_id" => repo.id)
134
138
  end
135
139
 
136
140
  def module_streams
@@ -83,13 +83,23 @@ module Katello
83
83
  end
84
84
 
85
85
  def errata_counts
86
- hash = {
86
+ installable_hash = {
87
87
  :security => installable_security_errata_count,
88
88
  :bugfix => installable_bugfix_errata_count,
89
89
  :enhancement => installable_enhancement_errata_count
90
90
  }
91
- hash[:total] = hash.values.inject(:+)
92
- hash
91
+ installable_hash[:total] = installable_hash.values.inject(:+)
92
+ # same for applicable, but we need to get the counts from the db
93
+ applicable_hash = {
94
+ :security => applicable_errata.security.count,
95
+ :bugfix => applicable_errata.bugfix.count,
96
+ :enhancement => applicable_errata.enhancement.count
97
+ }
98
+ applicable_hash[:total] = applicable_hash.values.inject(:+)
99
+ # keeping installable at the top level for backward compatibility
100
+ installable_hash.merge({
101
+ :applicable => applicable_hash
102
+ })
93
103
  end
94
104
 
95
105
  def self.trigger_applicability_generation(host_ids)
@@ -140,7 +140,6 @@ module Katello
140
140
  scope :order_by_root, ->(attr) { joins(:root).order("#{Katello::RootRepository.table_name}.#{attr}") }
141
141
  scope :with_content, ->(content) { joins(Katello::RepositoryTypeManager.find_content_type(content).model_class.repository_association_class.name.demodulize.underscore.pluralize.to_sym).distinct }
142
142
  scope :by_rpm_count, -> { left_joins(:repository_rpms).group(:id).order("count(katello_repository_rpms.id) ASC") } # smallest count first
143
- scope :exportable, -> { with_type(EXPORTABLE_TYPES) }
144
143
  scope :immediate_or_none, -> do
145
144
  immediate.or(where("#{RootRepository.table_name}.download_policy" => nil)).
146
145
  or(where("#{RootRepository.table_name}.download_policy" => ""))
@@ -186,6 +185,12 @@ module Katello
186
185
  delegate :content_id, to: :root, allow_nil: true
187
186
  delegate :repository_type, to: :root
188
187
 
188
+ def self.exportable(format: ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE)
189
+ types = EXPORTABLE_TYPES
190
+ types = [YUM_TYPE, FILE_TYPE] if format == ::Katello::Pulp3::ContentViewVersion::Export::SYNCABLE
191
+ with_type(types)
192
+ end
193
+
189
194
  def self.with_type(content_type)
190
195
  joins(:root).where("#{RootRepository.table_name}.content_type" => content_type)
191
196
  end
@@ -755,6 +760,15 @@ module Katello
755
760
  return true
756
761
  end
757
762
 
763
+ def content_views_all(include_composite: false)
764
+ if include_composite
765
+ cv_ids = library_instances_inverse&.joins(:content_view_version)&.map { |cvv| cvv&.content_view&.id }
766
+ return ContentView.where(id: cv_ids.uniq)
767
+ else
768
+ return self.content_views
769
+ end
770
+ end
771
+
758
772
  def sync_hook
759
773
  run_callbacks :sync do
760
774
  logger.debug "custom hook after_sync on #{name} will be executed if defined."
@@ -225,8 +225,6 @@ module Katello
225
225
  errors.add(:ignorable_content, N_("Invalid value specified for ignorable content."))
226
226
  elsif ignorable_content.any? { |item| !IGNORABLE_CONTENT_UNIT_TYPES.include?(item) }
227
227
  errors.add(:ignorable_content, N_("Invalid value specified for ignorable content. Permissible values %s") % IGNORABLE_CONTENT_UNIT_TYPES.join(","))
228
- elsif self.mirroring_policy == MIRRORING_POLICY_COMPLETE
229
- errors.add(:ignorable_content, N_("Ignore %s can not be set in combination with 'Complete Mirroring' mirroring policy.") % IGNORABLE_CONTENT_UNIT_TYPES.join(","))
230
228
  end
231
229
  end
232
230
 
@@ -12,3 +12,8 @@ Deface::Override.new(:virtual_path => "smart_proxies/_form",
12
12
  :name => "add_smart_proxies_download_policy",
13
13
  :insert_bottom => '#primary',
14
14
  :partial => 'overrides/smart_proxies/download_policy')
15
+
16
+ Deface::Override.new(:virtual_path => "smart_proxies/_form",
17
+ :name => "add_smart_proxies_acs_http_proxy",
18
+ :insert_bottom => '#primary',
19
+ :partial => 'overrides/smart_proxies/acs_http_proxy')
@@ -13,6 +13,11 @@ module Katello
13
13
  item_repos.map(&:content_view_version_id) & @versions.map(&:id)
14
14
  end
15
15
 
16
+ def comparison_repositories
17
+ repo = @item
18
+ @versions.map(&:id) & repo&.published_in_versions&.pluck(:id)
19
+ end
20
+
16
21
  def respond_to?(method)
17
22
  return method.to_s == 'comparison' || @item.respond_to?(method)
18
23
  end
@@ -1,10 +1,10 @@
1
1
  module Katello
2
2
  class HostPackagePresenter < SimpleDelegator
3
- attr_accessor :installed_package, :upgradable_version, :rpm_id
3
+ attr_accessor :installed_package, :upgradable_versions, :rpm_id
4
4
 
5
- def initialize(installed_package, upgradable_version, rpm_id)
5
+ def initialize(installed_package, upgradable_versions, rpm_id)
6
6
  @installed_package = installed_package
7
- @upgradable_version = upgradable_version
7
+ @upgradable_versions = upgradable_versions
8
8
  @rpm_id = rpm_id
9
9
  super(@installed_package)
10
10
  end
@@ -14,7 +14,7 @@ module Katello
14
14
  installed_packages_map = ::Katello::Rpm.where(nvra: packages.map(&:nvra)).select(:id, :name).group_by(&:name)
15
15
 
16
16
  packages.map do |p|
17
- HostPackagePresenter.new(p, upgradable_packages_map[p.name]&.first&.nvra, installed_packages_map[p.name]&.first&.id)
17
+ HostPackagePresenter.new(p, upgradable_packages_map[p.name]&.pluck(:nvra), installed_packages_map[p.name]&.first&.id)
18
18
  end
19
19
  end
20
20
  end
@@ -22,31 +22,40 @@ module Katello
22
22
  end
23
23
 
24
24
  def smart_proxy_acs
25
- if acs.alternate_content_source_type == 'custom'
25
+ if %w[custom rhui].include?(acs.alternate_content_source_type)
26
26
  ::Katello::SmartProxyAlternateContentSource.find_by(alternate_content_source_id: acs.id, smart_proxy_id: smart_proxy.id)
27
27
  else
28
28
  ::Katello::SmartProxyAlternateContentSource.find_by(alternate_content_source_id: acs.id, smart_proxy_id: smart_proxy.id, repository_id: repository.id)
29
29
  end
30
30
  end
31
31
 
32
- def remote_options
33
- if repository.present?
34
- options = repository.backend_service(smart_proxy).remote_options
35
- options[:policy] = 'on_demand'
36
- options[:proxy_url] = acs.http_proxy&.url
37
- options[:proxy_username] = acs.http_proxy&.username
38
- options[:proxy_password] = acs.http_proxy&.password
39
- return options
32
+ def simplified_acs_remote_options
33
+ options = repository.backend_service(smart_proxy).remote_options
34
+ options[:policy] = 'on_demand'
35
+ # Potential RFE: allow inheriting of default smart proxy repo's HTTP proxies for simplified ACSs
36
+ if acs.use_http_proxies
37
+ options[:proxy_url] = smart_proxy.http_proxy&.url
38
+ options[:proxy_username] = smart_proxy.http_proxy&.username
39
+ options[:proxy_password] = smart_proxy.http_proxy&.password
40
+ else
41
+ options[:proxy_url] = nil
42
+ options[:proxy_username] = nil
43
+ options[:proxy_password] = nil
40
44
  end
45
+ options
46
+ end
47
+
48
+ def remote_options
49
+ return simplified_acs_remote_options if repository.present?
41
50
 
42
51
  remote_options = {
43
52
  tls_validation: acs.verify_ssl,
44
53
  name: generate_backend_object_name,
45
54
  url: acs.base_url,
46
55
  policy: 'on_demand',
47
- proxy_url: acs.http_proxy&.url,
48
- proxy_username: acs.http_proxy&.username,
49
- proxy_password: acs.http_proxy&.password,
56
+ proxy_url: smart_proxy.http_proxy&.url,
57
+ proxy_username: smart_proxy.http_proxy&.username,
58
+ proxy_password: smart_proxy.http_proxy&.password,
50
59
  total_timeout: Setting[:sync_connect_timeout]
51
60
  }
52
61
  if acs.content_type == ::Katello::Repository::FILE_TYPE && acs.subpaths.empty? && !remote_options[:url].end_with?('/PULP_MANIFEST')
@@ -57,7 +66,7 @@ module Katello
57
66
  end
58
67
 
59
68
  def ssl_remote_options
60
- if acs.custom?
69
+ if acs.custom? || acs.rhui?
61
70
  {
62
71
  client_cert: acs.ssl_client_cert&.content,
63
72
  client_key: acs.ssl_client_key&.content,
@@ -121,8 +130,7 @@ module Katello
121
130
 
122
131
  def refresh
123
132
  href = smart_proxy_acs.alternate_content_source_href
124
- # https://github.com/pulp/pulp_rpm/issues/2504
125
- api.alternate_content_source_api.refresh(href, 'placeholder')
133
+ api.alternate_content_source_api.refresh(href)
126
134
  end
127
135
 
128
136
  private
@@ -30,24 +30,21 @@ module Katello
30
30
  end
31
31
 
32
32
  def self.insert_child_associations(units, pulp_id_to_id)
33
- insert_tags units
33
+ tag_names = units.map { |unit| unit['tags'].map { |tag| tag[:name] } }.flatten
34
+ tag_rows = tag_names.map { |name| {name: name } }
35
+ Katello::AnsibleTag.insert_all(tag_rows, unique_by: [:name]) if tag_rows.any?
36
+
34
37
  collection_tag_rows = []
35
38
  units.each do |unit|
36
39
  katello_id = pulp_id_to_id[unit['pulp_href']]
37
40
  #delete old tags
38
- unit_tags = unit['tags']&.map { |tag| tag[:name] }
41
+ unit_tags = unit['tags'].map { |tag| tag[:name] }
39
42
  Katello::AnsibleCollectionTag.where(:ansible_collection_id => katello_id).where.not(:ansible_tag_id => Katello::AnsibleTag.where(:name => unit_tags)).delete_all
40
- collection_tag_rows += Katello::AnsibleTag.where(:name => unit_tags)&.pluck(:id)&.map { |tag_id| {ansible_collection_id: katello_id, ansible_tag_id: tag_id} }
43
+ collection_tag_rows += Katello::AnsibleTag.where(:name => unit_tags).pluck(:id).map { |tag_id| {ansible_collection_id: katello_id, ansible_tag_id: tag_id} }
41
44
  end
42
45
 
43
46
  collection_tag_rows.flatten!
44
- Katello::AnsibleCollectionTag.insert_all(collection_tag_rows, unique_by: [:ansible_collection_id, :ansible_tag_id])
45
- end
46
-
47
- def self.insert_tags(units)
48
- tag_names = units.map { |unit| unit['tags']&.map { |tag| tag[:name] } }&.flatten
49
- tag_rows = tag_names&.compact&.map { |name| {name: name } }
50
- Katello::AnsibleTag.insert_all(tag_rows, unique_by: [:name]) if tag_rows.any?
47
+ Katello::AnsibleCollectionTag.insert_all(collection_tag_rows, unique_by: [:ansible_collection_id, :ansible_tag_id]) unless collection_tag_rows.empty?
51
48
  end
52
49
  end
53
50
  end
@@ -40,9 +40,9 @@ module Katello
40
40
 
41
41
  def repositories(fetch_all: false)
42
42
  repos = if content_view_version.default?
43
- content_view_version.repositories.exportable
43
+ content_view_version.repositories.exportable(format: format)
44
44
  else
45
- content_view_version.archived_repos.exportable
45
+ content_view_version.archived_repos.exportable(format: format)
46
46
  end
47
47
  if fetch_all
48
48
  repos
@@ -53,9 +53,9 @@ module Katello
53
53
 
54
54
  def generate_exporter_path
55
55
  return base_path if base_path
56
- export_path = "#{content_view_version.content_view}/#{content_view_version.version}/"
57
- export_path += "#{destination_server}/" unless destination_server.blank?
58
- export_path += "#{date_dir}".gsub(/\s/, '_')
56
+ export_path = "#{content_view_version.content_view.label}/#{content_view_version.version}/"
57
+ export_path += "#{destination_server}/".gsub(/\s/, '_') unless destination_server.blank?
58
+ export_path += "#{date_dir}"
59
59
  @base_path = "#{Setting['pulpcore_export_destination']}/#{content_view_version.organization.label}/#{export_path}"
60
60
  end
61
61
 
@@ -126,10 +126,23 @@ module Katello
126
126
  validate_repositories_immediate! if fail_on_missing_content
127
127
  validate_incremental_export! if validate_incremental && !from_content_view_version.blank?
128
128
  validate_chunk_size(chunk_size)
129
+ validate_export_types! if fail_on_missing_content
130
+ end
131
+
132
+ def validate_export_types!
133
+ repos = repositories(fetch_all: true).where.not(id: ::Katello::Repository.exportable(format: format))
134
+ if repos.any?
135
+ fail _("NOTE: Unable to fully export Content View Version '%{content_view} %{current}'"\
136
+ " it contains repositories with un-exportable content types. \n %{repos}" %
137
+ { content_view: content_view_version.content_view.name,
138
+ current: content_view_version.version,
139
+ repos: self.class.generate_product_repo_strings(repositories: repos)})
140
+
141
+ end
129
142
  end
130
143
 
131
144
  def validate_repositories_immediate!
132
- non_immediate_repos = repositories(fetch_all: true).non_immediate
145
+ non_immediate_repos = repositories(fetch_all: true).yum_type.non_immediate
133
146
  if non_immediate_repos.any?
134
147
  fail _("NOTE: Unable to fully export Content View Version '%{content_view} %{current}'"\
135
148
  " it contains repositories without the 'immediate' download policy."\
@@ -156,6 +156,8 @@ module Katello
156
156
  fail _("Content View label not provided.") if metadata_map.content_view.label.blank?
157
157
 
158
158
  params = import_content_view_params
159
+ return if @metadata_map.syncable_format? && params[:generated_for] != :none
160
+
159
161
  cv = ::Katello::ContentView.find_by(label: params[:label],
160
162
  organization: organization)
161
163
  if cv.blank?
@@ -13,10 +13,14 @@ module Katello
13
13
  end
14
14
 
15
15
  def check!
16
- fail _("Content view not provided in the metadata") if @metadata_map.content_view.blank?
16
+ if @metadata_map.content_view.blank? && !metadata_map.syncable_format?
17
+ fail _("Content view not provided in the metadata")
18
+ end
17
19
 
20
+ ensure_non_syncable_path_valid! unless @metadata_map.syncable_format?
18
21
  ensure_pulp_importable!
19
- unless @content_view.default?
22
+ if @content_view && !@content_view.default?
23
+ ensure_non_composite!
20
24
  ensure_importing_cvv_does_not_exist!
21
25
  ensure_from_cvv_exists!
22
26
  end
@@ -25,7 +29,20 @@ module Katello
25
29
  ensure_redhat_products_metadata_are_in_the_library!
26
30
  end
27
31
 
32
+ def ensure_non_syncable_path_valid!
33
+ uri = URI(@path)
34
+ unless uri.scheme.blank? || uri.scheme == "file"
35
+ fail _("Invalid path provided. Content can be only imported from file system. ")
36
+ end
37
+ end
38
+
39
+ def ensure_non_composite!
40
+ return if @content_view.blank?
41
+ fail _("Content cannot be imported into a Composite Content View. ") if @content_view.composite?
42
+ end
43
+
28
44
  def ensure_pulp_importable!
45
+ return if @metadata_map.syncable_format?
29
46
  api = ::Katello::Pulp3::Api::Core.new(@smart_proxy).importer_check_api
30
47
  response = api.pulp_import_check_post(toc: "#{@path}/#{@metadata_map.toc}")
31
48
  unless response.toc.is_valid
@@ -80,8 +97,7 @@ module Katello
80
97
  if bad_repos.any?
81
98
  fail _("The following repositories provided in the import metadata have an incorrect content type or provider type. "\
82
99
  "Make sure the export and import repositories are of the same type before importing\n "\
83
- "%{repos}" % { content_view: @content_view.name,
84
- repos: generate_product_repo_i18n_string(bad_repos).join("")}
100
+ "%{repos}" % { repos: generate_product_repo_i18n_string(bad_repos).join("")}
85
101
  )
86
102
  end
87
103
  end
@@ -94,7 +110,7 @@ module Katello
94
110
  if missing.any?
95
111
  repos_in_import = generate_product_repo_i18n_string(missing)
96
112
  fail _("The organization's manifest does not contain the subscriptions required to enable the following repositories.\n "\
97
- "%{repos}" % { content_view: @content_view.name, repos: repos_in_import.join("")}
113
+ "%{repos}" % { repos: repos_in_import.join("")}
98
114
  )
99
115
  end
100
116
  end