katello 3.17.0 → 3.18.0

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 (272) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +38 -21
  3. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +3 -1
  4. data/app/controllers/katello/api/v2/activation_keys_controller.rb +10 -15
  5. data/app/controllers/katello/api/v2/capsule_content_controller.rb +2 -2
  6. data/app/controllers/katello/api/v2/content_credentials_controller.rb +1 -8
  7. data/app/controllers/katello/api/v2/content_export_incrementals_controller.rb +98 -0
  8. data/app/controllers/katello/api/v2/content_exports_controller.rb +84 -0
  9. data/app/controllers/katello/api/v2/content_imports_controller.rb +59 -0
  10. data/app/controllers/katello/api/v2/content_view_components_controller.rb +31 -14
  11. data/app/controllers/katello/api/v2/content_view_filters_controller.rb +17 -8
  12. data/app/controllers/katello/api/v2/content_view_repositories_controller.rb +1 -0
  13. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +65 -71
  14. data/app/controllers/katello/api/v2/content_views_controller.rb +37 -26
  15. data/app/controllers/katello/api/v2/environments_controller.rb +8 -8
  16. data/app/controllers/katello/api/v2/gpg_keys_controller.rb +5 -5
  17. data/app/controllers/katello/api/v2/host_collections_controller.rb +19 -16
  18. data/app/controllers/katello/api/v2/host_debs_controller.rb +1 -0
  19. data/app/controllers/katello/api/v2/host_errata_controller.rb +2 -2
  20. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +35 -6
  21. data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +1 -1
  22. data/app/controllers/katello/api/v2/products_controller.rb +9 -9
  23. data/app/controllers/katello/api/v2/repositories_bulk_actions_controller.rb +1 -1
  24. data/app/controllers/katello/api/v2/repositories_controller.rb +10 -5
  25. data/app/controllers/katello/api/v2/repository_sets_controller.rb +24 -14
  26. data/app/controllers/katello/api/v2/subscriptions_controller.rb +1 -1
  27. data/app/controllers/katello/api/v2/sync_plans_controller.rb +8 -9
  28. data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +9 -2
  29. data/app/controllers/katello/concerns/api/v2/authorization.rb +19 -5
  30. data/app/controllers/katello/concerns/api/v2/bulk_hosts_extensions.rb +22 -18
  31. data/app/controllers/katello/concerns/api/v2/registration_controller_extensions.rb +21 -0
  32. data/app/controllers/katello/concerns/api/v2/repository_content_controller.rb +1 -1
  33. data/app/controllers/katello/concerns/organizations_controller_extensions.rb +2 -1
  34. data/app/controllers/katello/concerns/registration_controller_extensions.rb +16 -0
  35. data/app/helpers/katello/katello_urls_helper.rb +5 -2
  36. data/app/lib/actions/candlepin/product/content_create.rb +2 -0
  37. data/app/lib/actions/candlepin/product/content_update.rb +2 -0
  38. data/app/lib/actions/helpers/smart_proxy_sync_history_helper.rb +24 -0
  39. data/app/lib/actions/katello/applicability/hosts/bulk_generate.rb +6 -2
  40. data/app/lib/actions/katello/capsule_content/sync.rb +1 -1
  41. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +16 -7
  42. data/app/lib/actions/katello/content_view/promote_to_environment.rb +1 -1
  43. data/app/lib/actions/katello/content_view/publish.rb +9 -9
  44. data/app/lib/actions/katello/content_view_version/import.rb +8 -13
  45. data/app/lib/actions/katello/content_view_version/import_library.rb +17 -0
  46. data/app/lib/actions/katello/content_view_version/incremental_update.rb +18 -3
  47. data/app/lib/actions/katello/host/hypervisors_update.rb +18 -0
  48. data/app/lib/actions/katello/host/update_system_purpose.rb +31 -0
  49. data/app/lib/actions/katello/host/upload_package_profile.rb +3 -1
  50. data/app/lib/actions/katello/host/upload_profiles.rb +8 -6
  51. data/app/lib/actions/katello/organization/manifest_delete.rb +0 -1
  52. data/app/lib/actions/katello/organization/manifest_import.rb +0 -1
  53. data/app/lib/actions/katello/organization/manifest_refresh.rb +0 -1
  54. data/app/lib/actions/katello/product/content_create.rb +7 -6
  55. data/app/lib/actions/katello/repository/filtered_index_content.rb +10 -1
  56. data/app/lib/actions/katello/repository/import_upload.rb +4 -1
  57. data/app/lib/actions/katello/repository/remove_content.rb +1 -1
  58. data/app/lib/actions/katello/repository/sync.rb +3 -1
  59. data/app/lib/actions/katello/repository/update.rb +5 -1
  60. data/app/lib/actions/katello/repository/upload_files.rb +1 -0
  61. data/app/lib/actions/middleware/record_smart_proxy_sync_history.rb +15 -0
  62. data/app/lib/actions/pulp/consumer/sync_capsule.rb +4 -2
  63. data/app/lib/actions/pulp/repository/distributor_publish.rb +1 -1
  64. data/app/lib/actions/pulp3/capsule_content/sync.rb +1 -0
  65. data/app/lib/actions/pulp3/content_migration.rb +10 -0
  66. data/app/lib/actions/pulp3/content_migration_presenter.rb +59 -0
  67. data/app/lib/actions/pulp3/content_view/delete_repository_references.rb +1 -1
  68. data/app/lib/actions/pulp3/content_view_version/create_importer.rb +7 -3
  69. data/app/lib/actions/pulp3/content_view_version/export.rb +7 -1
  70. data/app/lib/actions/pulp3/content_view_version/import.rb +7 -3
  71. data/app/lib/actions/pulp3/import_migration.rb +6 -1
  72. data/app/lib/actions/pulp3/orchestration/content_view_version/copy_version_units_to_library.rb +2 -1
  73. data/app/lib/actions/pulp3/orchestration/content_view_version/export.rb +38 -14
  74. data/app/lib/actions/pulp3/orchestration/content_view_version/export_library.rb +60 -0
  75. data/app/lib/actions/pulp3/orchestration/content_view_version/import.rb +16 -10
  76. data/app/lib/actions/pulp3/orchestration/repository/generate_metadata.rb +4 -1
  77. data/app/lib/actions/pulp3/orchestration/repository/import_upload.rb +16 -3
  78. data/app/lib/actions/pulp3/repository/commit_upload.rb +2 -1
  79. data/app/lib/actions/pulp3/repository/copy_content.rb +1 -1
  80. data/app/lib/actions/pulp3/repository/delete.rb +1 -1
  81. data/app/lib/actions/pulp3/repository/save_artifact.rb +1 -1
  82. data/app/lib/actions/pulp3/repository/save_version.rb +1 -1
  83. data/app/lib/actions/pulp3/repository/upload_tag.rb +18 -0
  84. data/app/lib/katello/resources/candlepin/consumer.rb +2 -2
  85. data/app/lib/katello/resources/candlepin/owner.rb +5 -0
  86. data/app/lib/katello/resources/candlepin/upstream_consumer.rb +6 -0
  87. data/app/lib/katello/resources/registry.rb +3 -3
  88. data/app/models/katello/authorization/activation_key.rb +4 -0
  89. data/app/models/katello/authorization/content_view.rb +13 -0
  90. data/app/models/katello/authorization/content_view_component.rb +15 -0
  91. data/app/models/katello/authorization/content_view_filter.rb +15 -0
  92. data/app/models/katello/authorization/content_view_version.rb +25 -2
  93. data/app/models/katello/authorization/content_view_version_export_history.rb +1 -1
  94. data/app/models/katello/authorization/gpg_key.rb +12 -4
  95. data/app/models/katello/authorization/lifecycle_environment.rb +8 -0
  96. data/app/models/katello/authorization/organization.rb +8 -0
  97. data/app/models/katello/authorization/sync_plan.rb +16 -0
  98. data/app/models/katello/concerns/operatingsystem_extensions.rb +2 -0
  99. data/app/models/katello/concerns/organization_extensions.rb +4 -5
  100. data/app/models/katello/concerns/smart_proxy_extensions.rb +6 -4
  101. data/app/models/katello/content_migration_progress.rb +4 -0
  102. data/app/models/katello/content_view.rb +30 -4
  103. data/app/models/katello/content_view_component.rb +2 -0
  104. data/app/models/katello/content_view_filter.rb +5 -0
  105. data/app/models/katello/content_view_history.rb +2 -1
  106. data/app/models/katello/content_view_package_filter.rb +1 -1
  107. data/app/models/katello/content_view_puppet_module.rb +8 -0
  108. data/app/models/katello/content_view_repository.rb +13 -1
  109. data/app/models/katello/content_view_version_export_history.rb +8 -1
  110. data/app/models/katello/glue/candlepin/pool.rb +9 -14
  111. data/app/models/katello/glue/pulp/repo.rb +8 -0
  112. data/app/models/katello/gpg_key.rb +1 -1
  113. data/app/models/katello/ping.rb +8 -3
  114. data/app/models/katello/repository.rb +33 -0
  115. data/app/models/katello/root_repository.rb +26 -1
  116. data/app/models/katello/smart_proxy_sync_history.rb +8 -0
  117. data/app/services/katello/candlepin/event_handler.rb +2 -0
  118. data/app/services/katello/candlepin/message_handler.rb +34 -0
  119. data/app/services/katello/candlepin/upstream_consumer.rb +28 -0
  120. data/app/services/katello/host_status_manager.rb +9 -0
  121. data/app/services/katello/pulp3/api/apt.rb +57 -0
  122. data/app/services/katello/pulp3/api/core.rb +8 -0
  123. data/app/services/katello/pulp3/api/docker.rb +4 -0
  124. data/app/services/katello/pulp3/content_view_version/export.rb +125 -8
  125. data/app/services/katello/pulp3/content_view_version/import.rb +39 -34
  126. data/app/services/katello/pulp3/content_view_version/import_export_common.rb +6 -16
  127. data/app/services/katello/pulp3/content_view_version/import_validator.rb +114 -0
  128. data/app/services/katello/pulp3/deb.rb +38 -0
  129. data/app/services/katello/pulp3/docker_manifest.rb +1 -0
  130. data/app/services/katello/pulp3/docker_tag.rb +1 -0
  131. data/app/services/katello/pulp3/migration.rb +51 -10
  132. data/app/services/katello/pulp3/pulp_content_unit.rb +5 -0
  133. data/app/services/katello/pulp3/repository.rb +10 -4
  134. data/app/services/katello/pulp3/repository/ansible_collection.rb +9 -0
  135. data/app/services/katello/pulp3/repository/apt.rb +63 -0
  136. data/app/services/katello/pulp3/repository/docker.rb +9 -0
  137. data/app/services/katello/pulp3/repository/yum.rb +14 -9
  138. data/app/services/katello/pulp3/repository_mirror.rb +9 -4
  139. data/app/services/katello/pulp3/task.rb +4 -0
  140. data/app/services/katello/pulp3/task_group.rb +4 -0
  141. data/app/services/katello/repository_type.rb +2 -1
  142. data/app/services/katello/smart_proxy_helper.rb +9 -0
  143. data/app/views/dashboard/_subscription_widget.html.erb +0 -5
  144. data/app/views/foreman/hosts/_registration.html.erb +12 -0
  145. data/app/views/katello/api/v2/content_view_version_export_histories/show.json.rabl +1 -1
  146. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -0
  147. data/app/views/katello/api/v2/repositories/base.json.rabl +1 -1
  148. data/app/views/katello/layouts/react.html.erb +3 -2
  149. data/app/views/overrides/activation_keys/_host_tab_pane.html.erb +1 -5
  150. data/app/views/overrides/organizations/_index_row_override.html.erb +1 -1
  151. data/config/routes/api/v2.rb +24 -2
  152. data/config/routes/overrides.rb +1 -0
  153. data/db/migrate/20200929200357_create_katello_smart_proxy_sync_history.rb +13 -0
  154. data/db/migrate/20201008204114_add_os_versions_to_katello_root_repositories.rb +5 -0
  155. data/db/migrate/20201012172713_remove_gpg_key_perms.rb +23 -0
  156. data/db/migrate/20201012192035_add_metadata_to_katello_content_view_version_export_history.rb +5 -0
  157. data/db/migrate/20201021150008_add_import_only_to_katello_content_view.rb +5 -0
  158. data/db/migrate/20201119211133_pulp3_migration_progress.rb +9 -0
  159. data/db/seeds.d/111-upgrade_tasks.rb +2 -1
  160. data/engines/bastion/app/assets/javascripts/bastion/components/notification.service.js +1 -1
  161. data/engines/bastion/app/assets/javascripts/bastion/components/nutupane.factory.js +8 -13
  162. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-system-purpose-modal.controller.js +112 -0
  163. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-system-purpose-modal.html +78 -0
  164. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-host-modal-helper.service.js +11 -0
  165. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +5 -0
  166. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-debs-installed.controller.js +2 -42
  167. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +4 -0
  168. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/content-views.controller.js +6 -2
  169. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-details.controller.js +12 -0
  170. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-details.html +7 -7
  171. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-info.html +7 -1
  172. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/new/content-view-new.controller.js +17 -3
  173. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/new/views/content-view-new.html +16 -2
  174. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/views/content-views.html +5 -0
  175. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-details.controller.js +4 -0
  176. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/views/host-collection-info.html +6 -0
  177. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-bulk-action.factory.js +2 -1
  178. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +92 -19
  179. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de.po +17 -20
  180. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/es.po +17 -24
  181. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/fr.po +1292 -1170
  182. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/it.po +17 -20
  183. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ja.po +858 -807
  184. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ko.po +18 -19
  185. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pt_BR.po +17 -24
  186. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ru.po +17 -18
  187. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_CN.po +986 -971
  188. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_TW.po +19 -20
  189. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/translations.js +9 -9
  190. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/products-bulk-advanced-sync-modal.controller.js +6 -7
  191. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +168 -155
  192. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +17 -2
  193. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +125 -113
  194. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +15 -3
  195. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/os-versions.service.js +46 -0
  196. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository-types.service.js +8 -1
  197. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/content-access-mode-banner.html +1 -1
  198. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/views/sync-plan-details.html +1 -1
  199. data/lib/katello/engine.rb +2 -0
  200. data/lib/katello/permission_creator.rb +98 -69
  201. data/lib/katello/permissions/host_permissions.rb +1 -0
  202. data/lib/katello/plugin.rb +10 -2
  203. data/lib/katello/repository_types/deb.rb +9 -1
  204. data/lib/katello/tasks/pulp3_migration.rake +17 -3
  205. data/lib/katello/tasks/pulp3_migration_abort.rake +22 -0
  206. data/lib/katello/tasks/pulp3_migration_stats.rake +41 -0
  207. data/lib/katello/tasks/receptor/extract_orgs.rake +1 -1
  208. data/lib/katello/tasks/reset.rake +2 -1
  209. data/lib/katello/tasks/upgrades/3.18/add_cvv_export_history_metadata.rb +18 -0
  210. data/lib/katello/version.rb +1 -1
  211. data/locale/action_names.rb +51 -44
  212. data/locale/bn/katello.po +279 -55
  213. data/locale/cs/katello.po +278 -51
  214. data/locale/de/katello.po +279 -52
  215. data/locale/en/katello.po +278 -49
  216. data/locale/es/katello.po +279 -51
  217. data/locale/fr/katello.po +279 -51
  218. data/locale/gu/katello.po +279 -55
  219. data/locale/hi/katello.po +279 -55
  220. data/locale/it/katello.po +279 -51
  221. data/locale/ja/katello.po +279 -52
  222. data/locale/katello.pot +1379 -971
  223. data/locale/kn/katello.po +279 -55
  224. data/locale/ko/katello.po +279 -51
  225. data/locale/mr/katello.po +279 -55
  226. data/locale/or/katello.po +279 -55
  227. data/locale/pa/katello.po +279 -55
  228. data/locale/pt/katello.po +278 -52
  229. data/locale/pt_BR/katello.po +279 -51
  230. data/locale/ru/katello.po +279 -51
  231. data/locale/ta/katello.po +279 -55
  232. data/locale/te/katello.po +279 -55
  233. data/locale/zh_CN/katello.po +279 -51
  234. data/locale/zh_TW/katello.po +279 -52
  235. data/webpack/components/ActionableDetail.js +2 -1
  236. data/webpack/components/Search/Search.js +1 -1
  237. data/webpack/components/Table/MainTable.js +6 -2
  238. data/webpack/components/Table/TableWrapper.js +46 -9
  239. data/webpack/scenes/ContentViews/ContentViewSelectors.js +7 -3
  240. data/webpack/scenes/ContentViews/ContentViewsConstants.js +8 -0
  241. data/webpack/scenes/ContentViews/ContentViewsPage.js +2 -9
  242. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +25 -3
  243. data/webpack/scenes/ContentViews/Details/ContentViewDetailSelectors.js +14 -4
  244. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +2 -1
  245. data/webpack/scenes/ContentViews/Details/Repositories/ContentCounts.js +56 -0
  246. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +169 -0
  247. data/webpack/scenes/ContentViews/Details/Repositories/LastSync.js +47 -0
  248. data/webpack/scenes/ContentViews/Details/Repositories/RepoAddedStatus.js +17 -0
  249. data/webpack/scenes/ContentViews/Details/Repositories/RepoIcon.js +23 -0
  250. data/webpack/scenes/ContentViews/Details/Repositories/SelectableDropdown.js +49 -0
  251. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewDetailRepos.fixtures.json +154 -0
  252. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewDetailRepos.test.js +131 -0
  253. data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetail.test.js +3 -0
  254. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +4 -1
  255. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +2 -2
  256. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +29 -19
  257. data/webpack/scenes/Subscriptions/Manifest/ManifestActions.js +17 -0
  258. data/webpack/scenes/Subscriptions/Manifest/ManifestConstants.js +4 -0
  259. data/webpack/scenes/Subscriptions/Manifest/SimpleContentAccess.js +19 -2
  260. data/webpack/scenes/Subscriptions/Manifest/__tests__/SimpleContentAccess.test.js +9 -1
  261. data/webpack/scenes/Subscriptions/Manifest/index.js +2 -1
  262. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +1 -1
  263. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +3 -0
  264. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +8 -2
  265. data/webpack/scenes/Subscriptions/SubscriptionsSelectors.js +3 -0
  266. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +3 -0
  267. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsSelectors.test.js +6 -0
  268. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsSelectors.test.js.snap +6 -0
  269. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +1 -13
  270. data/webpack/test-utils/react-testing-lib-wrapper.js +3 -0
  271. metadata +74 -13
  272. data/webpack/__mocks__/foremanReact/components/common/Fill/GlobalFill.js +0 -3
@@ -17,6 +17,8 @@ module Katello
17
17
 
18
18
  before_validation :set_attributes
19
19
 
20
+ validate :import_only_content_view
21
+
20
22
  def puppet_module
21
23
  PuppetModule.find_by(:pulp_id => self.uuid)
22
24
  end
@@ -42,6 +44,12 @@ module Katello
42
44
 
43
45
  private
44
46
 
47
+ def import_only_content_view
48
+ if self.content_view.import_only?
49
+ errors.add(:base, "Cannot add puppet modules to an import-only content view.")
50
+ end
51
+ end
52
+
45
53
  def set_attributes
46
54
  if self.uuid.present?
47
55
  puppet_module = PuppetModule.with_identifiers(self.uuid).first
@@ -7,6 +7,10 @@ module Katello
7
7
  Repository::DEB_TYPE
8
8
  ].freeze
9
9
 
10
+ ALLOWED_IMPORT_REPOSITORY_TYPES = [
11
+ Repository::YUM_TYPE
12
+ ].freeze
13
+
10
14
  belongs_to :content_view, :inverse_of => :content_view_repositories,
11
15
  :class_name => "Katello::ContentView"
12
16
  belongs_to :repository, :inverse_of => :content_view_repositories,
@@ -27,7 +31,7 @@ module Katello
27
31
  end
28
32
 
29
33
  def ensure_repository_type
30
- unless ALLOWED_REPOSITORY_TYPES.include?(repository.content_type)
34
+ unless allowed_repository_types.include?(repository.content_type)
31
35
  errors.add(:base, _("Cannot add %s repositories to a content view.") % repository.content_type)
32
36
  end
33
37
  end
@@ -41,5 +45,13 @@ module Katello
41
45
  errors.add(:base, _("Repositories from published Content Views are not allowed."))
42
46
  end
43
47
  end
48
+
49
+ def allowed_repository_types
50
+ if self.content_view.import_only?
51
+ ALLOWED_IMPORT_REPOSITORY_TYPES
52
+ else
53
+ ALLOWED_REPOSITORY_TYPES
54
+ end
55
+ end
44
56
  end
45
57
  end
@@ -5,7 +5,9 @@ module Katello
5
5
  belongs_to :content_view_version, :class_name => "Katello::ContentViewVersion", :inverse_of => :export_histories
6
6
  validates_lengths_from_database
7
7
  validates :content_view_version_id, :presence => true
8
- validates :destination_server, :presence => true, :uniqueness => { :scope => [:content_view_version_id, :destination_server, :path] }
8
+ validates :destination_server, :uniqueness => { :scope => [:content_view_version_id, :destination_server, :path] }
9
+ validates :metadata, :presence => true
10
+ serialize :metadata, Hash
9
11
 
10
12
  scope :with_organization_id, ->(organization_id) do
11
13
  where(:content_view_version_id => ContentViewVersion.with_organization_id(organization_id))
@@ -18,5 +20,10 @@ module Katello
18
20
  scoped_search :on => :content_view_id, :relation => :content_view_version, :validator => ScopedSearch::Validators::INTEGER, :only_explicit => true
19
21
  scoped_search :on => :content_view_version_id, :only_explicit => true, :validator => ScopedSearch::Validators::INTEGER
20
22
  scoped_search :on => :id, :only_explicit => true, :validator => ScopedSearch::Validators::INTEGER
23
+
24
+ def self.latest(content_view, destination_server: nil)
25
+ where(content_view_version: content_view.versions,
26
+ destination_server: destination_server).order(:created_at).last
27
+ end
21
28
  end
22
29
  end
@@ -21,6 +21,8 @@ module Katello
21
21
  lazy_accessor :available, :initializer => lambda { |_s| self.quantity_available }
22
22
 
23
23
  lazy_accessor :backend_data, :initializer => lambda { |_s| self.class.candlepin_data(self.cp_id) }
24
+
25
+ lazy_accessor :consumer_uuids, :initializer => lambda { |_s| Resources::Candlepin::Pool.consumer_uuids(self.cp_id) }
24
26
  end
25
27
  end
26
28
 
@@ -162,27 +164,20 @@ module Katello
162
164
  end
163
165
 
164
166
  def import_hosts
165
- uuids = Resources::Candlepin::Pool.consumer_uuids(self.cp_id)
166
-
167
- sub_facet_ids_from_cp, host_ids_from_cp = Katello::Host::SubscriptionFacet.where('uuid in (?)', uuids).pluck([:id, :host_id]).transpose
167
+ sub_facet_ids_from_cp, host_ids_from_cp = Katello::Host::SubscriptionFacet.where('uuid in (?)', consumer_uuids).pluck(:id, :host_id).transpose
168
168
  sub_facet_ids_from_cp ||= []
169
169
  host_ids_from_cp ||= []
170
170
 
171
- sub_facet_ids_from_pool_table = Katello::SubscriptionFacetPool.where(:pool_id => self.id).select(:subscription_facet_id).pluck(:subscription_facet_id)
172
- host_ids_from_pool_table = Katello::Host::SubscriptionFacet.where(:id => sub_facet_ids_from_pool_table).pluck(:host_id)
171
+ sub_facet_ids_from_pool_table, host_ids_from_pool_table = self.subscription_facets.pluck(:id, :host_id).transpose
172
+ sub_facet_ids_from_pool_table ||= []
173
+ host_ids_from_pool_table ||= []
173
174
 
174
175
  entries_to_add = sub_facet_ids_from_cp - sub_facet_ids_from_pool_table
175
- unless entries_to_add.empty?
176
- ActiveRecord::Base.transaction do
177
- entries_to_add.each do |sub_facet_id|
178
- query = "INSERT INTO #{Katello::SubscriptionFacetPool.table_name} (pool_id, subscription_facet_id) VALUES (#{self.id}, #{sub_facet_id})"
179
- ActiveRecord::Base.connection.execute(query)
180
- end
181
- end
182
- end
176
+ facet_pool_data = entries_to_add.map { |sub_facet_id| { pool_id: self.id, subscription_facet_id: sub_facet_id } }
177
+ Katello::SubscriptionFacetPool.import(facet_pool_data) unless facet_pool_data.empty?
183
178
 
184
179
  entries_to_remove = sub_facet_ids_from_pool_table - sub_facet_ids_from_cp
185
- Katello::SubscriptionFacetPool.where(:pool_id => self.id, :subscription_facet_id => entries_to_remove).delete_all
180
+ self.subscription_facet_pools.where(subscription_facet_id: entries_to_remove).delete_all
186
181
  self.import_audit_record(host_ids_from_pool_table, host_ids_from_cp)
187
182
  end
188
183
 
@@ -240,6 +240,8 @@ module Katello
240
240
  "iso"
241
241
  when Repository::DEB_TYPE
242
242
  "deb"
243
+ when Repository::ANSIBLE_COLLECTION_TYPE
244
+ "ansible_collection"
243
245
  end
244
246
  end
245
247
 
@@ -271,6 +273,10 @@ module Katello
271
273
  self.content_type == Repository::DEB_TYPE
272
274
  end
273
275
 
276
+ def ansible_collection?
277
+ self.content_type == Repository::ANSIBLE_COLLECTION_TYPE
278
+ end
279
+
274
280
  def published?
275
281
  distributors.map { |dist| dist['last_publish'] }.compact.any?
276
282
  end
@@ -378,6 +384,8 @@ module Katello
378
384
  "#{scheme}://#{pulp_uri.host.downcase}/pulp/ostree/web/#{relative_path}"
379
385
  elsif deb?
380
386
  "#{scheme}://#{pulp_uri.host.downcase}/pulp/deb/#{relative_path}/"
387
+ elsif ansible_collection?
388
+ "#{scheme}://#{pulp_uri.host.downcase}/pulp/content/#{relative_path}/"
381
389
  else
382
390
  "#{scheme}://#{pulp_uri.host.downcase}/pulp/repos/#{relative_path}/"
383
391
  end
@@ -46,7 +46,7 @@ module Katello
46
46
  end
47
47
 
48
48
  def self.humanize_class_name(_name = nil)
49
- _("GPG Keys")
49
+ _("Content Credentials")
50
50
  end
51
51
 
52
52
  def to_label
@@ -5,10 +5,17 @@ module Katello
5
5
  PACKAGES = %w(katello candlepin pulp qpid foreman tfm hammer).freeze
6
6
 
7
7
  class << self
8
+ def pulpcore_enabled # for downstream 6.9, remove in 6.10
9
+ SETTINGS[:katello][:use_pulp_2_for_content_type].nil? || (!SETTINGS[:katello][:use_pulp_2_for_content_type][:yum] &&
10
+ !SETTINGS[:katello][:use_pulp_2_for_content_type][:docker] &&
11
+ !SETTINGS[:katello][:use_pulp_2_for_content_type][:file]) ||
12
+ system('systemctl is-enabled pulpcore-api.service')
13
+ end
14
+
8
15
  def services(capsule_id = nil)
9
16
  proxy = fetch_proxy(capsule_id)
10
17
  services = [:candlepin, :candlepin_auth, :foreman_tasks, :katello_events, :candlepin_events]
11
- services += [:pulp3] if proxy&.pulp3_enabled?
18
+ services += [:pulp3] if proxy&.pulp3_enabled? && pulpcore_enabled
12
19
  if proxy.nil? || proxy.has_feature?(SmartProxy::PULP_NODE_FEATURE) || proxy.has_feature?(SmartProxy::PULP_FEATURE)
13
20
  services += [:pulp, :pulp_auth]
14
21
  end
@@ -16,9 +23,7 @@ module Katello
16
23
  services
17
24
  end
18
25
 
19
- #
20
26
  # Calls "status" services in all backend engines.
21
- #
22
27
  def ping(services: nil, capsule_id: nil)
23
28
  services ||= self.services(capsule_id)
24
29
  result = {}
@@ -109,6 +109,8 @@ module Katello
109
109
  has_many :distribution_references, :class_name => 'Katello::Pulp3::DistributionReference', :foreign_key => :repository_id,
110
110
  :dependent => :destroy, :inverse_of => :repository
111
111
 
112
+ has_many :smart_proxy_sync_histories, :class_name => "::Katello::SmartProxySyncHistory", :inverse_of => :repository, :dependent => :delete_all
113
+
112
114
  validates_with Validators::ContainerImageNameValidator, :attributes => :container_repository_name, :allow_blank => false, :if => :docker?
113
115
  validates :container_repository_name, :if => :docker?, :uniqueness => {message: ->(object, _data) do
114
116
  _("for repository '%{name}' is not unique and cannot be created in '%{env}'. Its Container Repository Name (%{container_name}) conflicts with an existing repository. Consider changing the Lifecycle Environment's Registry Name Pattern to something more specific.") %
@@ -120,6 +122,8 @@ module Katello
120
122
 
121
123
  scope :has_url, -> { joins(:root).where.not("#{RootRepository.table_name}.url" => nil) }
122
124
  scope :on_demand, -> { joins(:root).where("#{RootRepository.table_name}.download_policy" => ::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND) }
125
+ scope :immediate, -> { joins(:root).where("#{RootRepository.table_name}.download_policy" => ::Runcible::Models::YumImporter::DOWNLOAD_IMMEDIATE) }
126
+ scope :non_immediate, -> { joins(:root).where.not("#{RootRepository.table_name}.download_policy" => ::Runcible::Models::YumImporter::DOWNLOAD_IMMEDIATE) }
123
127
  scope :in_default_view, -> { joins(:content_view_version => :content_view).where("#{Katello::ContentView.table_name}.default" => true) }
124
128
  scope :in_non_default_view, -> { joins(:content_view_version => :content_view).where("#{Katello::ContentView.table_name}.default" => false) }
125
129
  scope :deb_type, -> { with_type(DEB_TYPE) }
@@ -152,6 +156,7 @@ module Katello
152
156
  scoped_search :on => :redhat, :complete_value => { :true => true, :false => false }, :ext_method => :search_by_redhat
153
157
  scoped_search :on => :container_repository_name, :complete_value => true
154
158
  scoped_search :on => :description, :relation => :root, :only_explicit => true
159
+ scoped_search :on => :download_policy, :relation => :root, :only_explicit => true
155
160
  scoped_search :on => :name, :relation => :product, :rename => :product_name
156
161
  scoped_search :on => :id, :relation => :product, :rename => :product_id, :only_explicit => true
157
162
  scoped_search :on => :label, :relation => :root, :complete_value => true, :only_explicit => true
@@ -285,6 +290,10 @@ module Katello
285
290
  root.download_policy == Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND
286
291
  end
287
292
 
293
+ def immediate?
294
+ root.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_IMMEDIATE
295
+ end
296
+
288
297
  def yum_gpg_key_url
289
298
  # if the repo has a gpg key return a url to access it
290
299
  if self.root.gpg_key.try(:content).present?
@@ -531,6 +540,30 @@ module Katello
531
540
  clone
532
541
  end
533
542
 
543
+ def self.synced_on_capsule(smart_proxy)
544
+ smart_proxy.smart_proxy_sync_histories.map { |sph| sph.repository unless sph.finished_at.nil? }
545
+ end
546
+
547
+ def clear_smart_proxy_sync_histories(smart_proxy = nil)
548
+ if smart_proxy
549
+ self.smart_proxy_sync_histories.where(:smart_proxy_id => smart_proxy.id).try(:delete_all)
550
+ else
551
+ self.smart_proxy_sync_histories.delete_all
552
+ end
553
+ end
554
+
555
+ def create_smart_proxy_sync_history(smart_proxy)
556
+ clear_smart_proxy_sync_histories(smart_proxy)
557
+ sp_history_args = {
558
+ :smart_proxy_id => smart_proxy.id,
559
+ :repository_id => self.id,
560
+ :started_at => Time.now
561
+ }
562
+ sp_history = ::Katello::SmartProxySyncHistory.create sp_history_args
563
+ sp_history.save!
564
+ sp_history.id
565
+ end
566
+
534
567
  def latest_sync_audit
535
568
  self.audits.where(:action => AUDIT_SYNC_ACTION).order(:created_at).last
536
569
  end
@@ -3,6 +3,7 @@ module Katello
3
3
  audited :except => [:content_id]
4
4
  serialize :ignorable_content
5
5
  serialize :docker_tags_whitelist
6
+ serialize :os_versions
6
7
 
7
8
  include Ext::LabelFromName
8
9
  include Encryptable
@@ -34,6 +35,11 @@ module Katello
34
35
  NO_DEFAULT_HTTP_PROXY,
35
36
  USE_SELECTED_HTTP_PROXY].freeze
36
37
 
38
+ RHEL6 = 'rhel-6'.freeze
39
+ RHEL7 = 'rhel-7'.freeze
40
+ RHEL8 = 'rhel-8'.freeze
41
+ ALLOWED_OS_VERSIONS = [RHEL6, RHEL7, RHEL8].freeze
42
+
37
43
  belongs_to :product, :inverse_of => :root_repositories, :class_name => "Katello::Product"
38
44
  belongs_to :gpg_key, :inverse_of => :root_repositories, :class_name => "Katello::GpgKey"
39
45
  belongs_to :ssl_ca_cert, :class_name => "Katello::GpgKey", :inverse_of => :ssl_ca_root_repos
@@ -63,6 +69,7 @@ module Katello
63
69
  validate :ensure_compatible_download_policy, :if => :yum?
64
70
  validate :ensure_valid_ignorable_content
65
71
  validate :ensure_valid_docker_tags_whitelist
72
+ validate :ensure_valid_os_versions
66
73
  validate :ensure_content_attribute_restrictions
67
74
  validate :ensure_valid_upstream_authorization
68
75
  validate :ensure_no_checksum_on_demand
@@ -214,6 +221,24 @@ module Katello
214
221
  end
215
222
  end
216
223
 
224
+ def ensure_valid_os_versions
225
+ return if os_versions.empty?
226
+ # os_versions here translate to candlepin as 'required tags'.
227
+ # A host must provide ALL required tags in order for the repo to be enabled.
228
+ # So os_versions such as ['rhel-7', 'rhel-8'] is not allowed, since the repo would always be disabled.
229
+ unless yum?
230
+ errors.add(:os_versions, N_("are only allowed for Yum repositories."))
231
+ end
232
+ if os_versions.length > 1
233
+ errors.add(:os_versions, N_("invalid: Repositories can only require one OS version."))
234
+ end
235
+ os_versions.each do |tag|
236
+ unless ALLOWED_OS_VERSIONS.include?(tag)
237
+ errors.add(:os_versions, N_("must be one of: %s" % ALLOWED_OS_VERSIONS.join(', ')))
238
+ end
239
+ end
240
+ end
241
+
217
242
  def ensure_valid_upstream_authorization
218
243
  return if (self.upstream_username.blank? && self.upstream_password.blank?)
219
244
  if redhat?
@@ -340,7 +365,7 @@ module Katello
340
365
  property :url, String, desc: 'Returns repository source URL'
341
366
  end
342
367
  class Jail < ::Safemode::Jail
343
- allow :name, :label, :docker_upstream_name, :url
368
+ allow :name, :label, :docker_upstream_name, :url, :os_versions
344
369
  end
345
370
  end
346
371
  end
@@ -0,0 +1,8 @@
1
+ module Katello
2
+ class SmartProxySyncHistory < Katello::Model
3
+ self.table_name = 'katello_smart_proxy_sync_history'
4
+
5
+ belongs_to :smart_proxy, :class_name => "::SmartProxy", :inverse_of => :smart_proxy_sync_histories
6
+ belongs_to :repository, :class_name => "Katello::Repository", :inverse_of => :smart_proxy_sync_histories
7
+ end
8
+ end
@@ -30,6 +30,8 @@ module Katello
30
30
  reindex_subscription_status
31
31
  when /system_purpose_compliance\.created/
32
32
  reindex_purpose_status
33
+ when /owner_content_access_mode\.modified/
34
+ message_handler.handle_content_access_mode_modified
33
35
  end
34
36
  end
35
37
 
@@ -20,6 +20,10 @@ module Katello
20
20
  @event_data ||= (data = content['eventData']) ? JSON.parse(data) : {}
21
21
  end
22
22
 
23
+ def target_name
24
+ content['targetName']
25
+ end
26
+
23
27
  def status
24
28
  event_data['status']
25
29
  end
@@ -85,6 +89,36 @@ module Katello
85
89
  Rails.logger.info "deleted pool #{pool_id} from Katello"
86
90
  end
87
91
  end
92
+
93
+ def handle_content_access_mode_modified
94
+ # Ideally the target_name would be the Candlepin Owner key
95
+ # Since it's the displayName, and we don't update that after org creation, there could be a mismatch
96
+ # For now, find the Candlepin Owner displayName from this event, and tie it back to a Katello org based on owner key
97
+ owners = Katello::Resources::Candlepin::Owner.all
98
+ owner = owners.find { |o| o['displayName'] == target_name }
99
+
100
+ unless owner
101
+ fail("Candlepin Owner %s could not be found" % target_name)
102
+ end
103
+
104
+ org = ::Organization.find_by!(label: owner['key'])
105
+ hosts = org.hosts
106
+
107
+ if event_data['contentAccessMode'] == 'org_environment'
108
+ Katello::HostStatusManager.clear_syspurpose_status(hosts)
109
+ Katello::HostStatusManager.update_subscription_status_to_sca(hosts)
110
+ elsif event_data['contentAccessMode'] == 'entitlement'
111
+ cp_consumer_uuids = hosts.joins(:subscription_facet).pluck("#{Katello::Host::SubscriptionFacet.table_name}.uuid")
112
+ cp_consumer_uuids.each do |uuid|
113
+ Katello::Resources::Candlepin::Consumer.compliance(uuid)
114
+ Katello::Resources::Candlepin::Consumer.purpose_compliance(uuid)
115
+ rescue => e
116
+ Rails.logger.error("Error encountered while fetching compliance for consumer #{uuid}: #{e.message}")
117
+ end
118
+ end
119
+
120
+ org.simple_content_access?(cached: false)
121
+ end
88
122
  end
89
123
  end
90
124
  end
@@ -0,0 +1,28 @@
1
+ module Katello
2
+ module Candlepin
3
+ class UpstreamConsumer
4
+ def initialize(organization)
5
+ @organization = organization
6
+ end
7
+
8
+ def simple_content_access_eligible?
9
+ eligible = true
10
+ ::Organization.as_org(@organization) do
11
+ content_modes = resource_class.content_access
12
+
13
+ if content_modes.key?(:contentAccessModeList)
14
+ eligible = content_modes[:contentAccessModeList].include?('org_environment')
15
+ end
16
+ end
17
+
18
+ eligible
19
+ end
20
+
21
+ private
22
+
23
+ def resource_class
24
+ Katello::Resources::Candlepin::UpstreamConsumer
25
+ end
26
+ end
27
+ end
28
+ end
@@ -16,5 +16,14 @@ module Katello
16
16
  Katello::PurposeRoleStatus,
17
17
  Katello::PurposeSlaStatus,
18
18
  Katello::PurposeUsageStatus].freeze
19
+
20
+ def self.update_subscription_status_to_sca(hosts)
21
+ HostStatus::Status.where(host: hosts, type: Katello::SubscriptionStatus.to_s).update(status: Katello::SubscriptionStatus::DISABLED)
22
+ end
23
+
24
+ def self.clear_syspurpose_status(hosts)
25
+ host_purpose = HostStatus::Status.where(type: ::Katello::HostStatusManager::PURPOSE_STATUS.map(&:to_s)).where('host_id in (?)', hosts.pluck(:id))
26
+ host_purpose.destroy_all
27
+ end
19
28
  end
20
29
  end
@@ -0,0 +1,57 @@
1
+ require "pulpcore_client"
2
+
3
+ module Katello
4
+ module Pulp3
5
+ module Api
6
+ class Apt < Core
7
+ def self.api_exception_class
8
+ PulpDebClient::ApiError
9
+ end
10
+
11
+ def self.client_module
12
+ PulpDebClient
13
+ end
14
+
15
+ def self.remote_class
16
+ PulpDebClient::DebAptRemote
17
+ end
18
+
19
+ def self.distribution_class
20
+ PulpDebClient::DebAptDistribution
21
+ end
22
+
23
+ def self.publication_class
24
+ PulpDebClient::DebAptPublication
25
+ end
26
+
27
+ def self.repository_sync_url_class
28
+ PulpDebClient::RepositorySyncURL
29
+ end
30
+
31
+ def api_client
32
+ PulpDebClient::ApiClient.new(smart_proxy.pulp3_configuration(PulpDebClient::Configuration))
33
+ end
34
+
35
+ def repositories_api
36
+ PulpDebClient::RepositoriesAptApi.new(api_client)
37
+ end
38
+
39
+ def repository_versions_api
40
+ PulpDebClient::RepositoriesDebVersionsApi.new(api_client)
41
+ end
42
+
43
+ def remotes_api
44
+ PulpDebClient::RemotesAptApi.new(api_client)
45
+ end
46
+
47
+ def publications_api
48
+ PulpDebClient::PublicationsAptApi.new(api_client)
49
+ end
50
+
51
+ def distributions_api
52
+ PulpDebClient::DistributionsAptApi.new(api_client)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end