katello 3.8.1 → 3.9.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 (472) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -7
  3. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +16 -9
  4. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +1 -1
  5. data/app/controllers/katello/api/v2/api_controller.rb +20 -22
  6. data/app/controllers/katello/api/v2/capsule_content_controller.rb +1 -1
  7. data/app/controllers/katello/api/v2/content_view_filter_rules_controller.rb +5 -1
  8. data/app/controllers/katello/api/v2/content_view_histories_controller.rb +1 -1
  9. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +12 -12
  10. data/app/controllers/katello/api/v2/content_views_controller.rb +15 -1
  11. data/app/controllers/katello/api/v2/host_errata_controller.rb +1 -1
  12. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +12 -4
  13. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +12 -0
  14. data/app/controllers/katello/api/v2/module_streams_controller.rb +49 -0
  15. data/app/controllers/katello/api/v2/organizations_controller.rb +3 -1
  16. data/app/controllers/katello/api/v2/package_groups_controller.rb +1 -1
  17. data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +5 -4
  18. data/app/controllers/katello/api/v2/products_controller.rb +1 -1
  19. data/app/controllers/katello/api/v2/puppet_modules_controller.rb +5 -0
  20. data/app/controllers/katello/api/v2/repositories_controller.rb +80 -84
  21. data/app/controllers/katello/api/v2/repository_sets_controller.rb +18 -7
  22. data/app/controllers/katello/api/v2/subscriptions_controller.rb +2 -6
  23. data/app/controllers/katello/api/v2/sync_plans_controller.rb +13 -24
  24. data/app/controllers/katello/concerns/api/v2/repository_content_controller.rb +12 -5
  25. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +2 -5
  26. data/app/controllers/katello/react_controller.rb +2 -0
  27. data/app/controllers/katello/remote_execution_controller.rb +16 -5
  28. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +0 -2
  29. data/app/lib/actions/candlepin/import_pool_handler.rb +40 -15
  30. data/app/lib/actions/katello/capsule_content/create_repos.rb +1 -0
  31. data/app/lib/actions/katello/content_view/publish.rb +21 -2
  32. data/app/lib/actions/katello/content_view_version/incremental_update.rb +1 -1
  33. data/app/lib/actions/katello/environment/destroy.rb +2 -3
  34. data/app/lib/actions/katello/environment/publish_repositories.rb +1 -1
  35. data/app/lib/actions/katello/event_queue/monitor.rb +9 -15
  36. data/app/lib/actions/katello/event_queue/poller_thread.rb +24 -1
  37. data/app/lib/actions/katello/event_queue/suspended_action.rb +2 -2
  38. data/app/lib/actions/katello/host/hypervisors_update.rb +82 -22
  39. data/app/lib/actions/katello/organization/manifest_refresh.rb +1 -1
  40. data/app/lib/actions/katello/product/content_create.rb +30 -38
  41. data/app/lib/actions/katello/product/content_destroy.rb +11 -12
  42. data/app/lib/actions/katello/product/create.rb +0 -1
  43. data/app/lib/actions/katello/product/update.rb +0 -2
  44. data/app/lib/actions/katello/repository/clear.rb +2 -0
  45. data/app/lib/actions/katello/repository/clone_to_environment.rb +0 -2
  46. data/app/lib/actions/katello/repository/clone_to_version.rb +15 -3
  47. data/app/lib/actions/katello/repository/clone_yum_content.rb +21 -2
  48. data/app/lib/actions/katello/repository/clone_yum_metadata.rb +1 -1
  49. data/app/lib/actions/katello/repository/correct_checksum.rb +5 -5
  50. data/app/lib/actions/katello/repository/create.rb +7 -7
  51. data/app/lib/actions/katello/repository/create_root.rb +22 -0
  52. data/app/lib/actions/katello/repository/destroy.rb +11 -6
  53. data/app/lib/actions/katello/repository/discover.rb +5 -3
  54. data/app/lib/actions/katello/repository/export.rb +1 -1
  55. data/app/lib/actions/katello/repository/fetch_pxe_files.rb +13 -27
  56. data/app/lib/actions/katello/repository/index_module_streams.rb +16 -0
  57. data/app/lib/actions/katello/repository/metadata_generate.rb +1 -1
  58. data/app/lib/actions/katello/repository/sync.rb +0 -2
  59. data/app/lib/actions/katello/repository/update.rb +15 -28
  60. data/app/lib/actions/katello/repository_set/disable_repository.rb +5 -13
  61. data/app/lib/actions/katello/repository_set/enable_repository.rb +3 -16
  62. data/app/lib/actions/katello/repository_set/scan_cdn.rb +4 -32
  63. data/app/lib/actions/katello/sync_plan/run.rb +37 -0
  64. data/app/lib/actions/pulp/abstract.rb +7 -2
  65. data/app/lib/actions/pulp/abstract_async_task.rb +1 -0
  66. data/app/lib/actions/pulp/consumer/generate_applicability.rb +1 -0
  67. data/app/lib/actions/pulp/repository/copy_module_default.rb +11 -0
  68. data/app/lib/actions/pulp/repository/copy_module_stream.rb +11 -0
  69. data/app/lib/actions/pulp/repository/create.rb +2 -0
  70. data/app/lib/actions/pulp/repository/distributor_publish.rb +3 -2
  71. data/app/lib/actions/pulp/repository/remove_module_default.rb +11 -0
  72. data/app/lib/actions/pulp/repository/remove_module_stream.rb +11 -0
  73. data/app/lib/actions/pulp/repository/sync.rb +6 -19
  74. data/app/lib/actions/pulp/repository/update_importer.rb +9 -7
  75. data/app/lib/katello/concerns/base_template_scope_extensions.rb +42 -0
  76. data/app/lib/katello/concerns/renderer_extensions.rb +6 -4
  77. data/app/lib/katello/http_resource.rb +5 -1
  78. data/app/lib/katello/repo_discovery.rb +6 -2
  79. data/app/lib/katello/resources/candlepin/consumer.rb +18 -1
  80. data/app/lib/katello/resources/candlepin/owner.rb +9 -0
  81. data/app/lib/katello/resources/candlepin/pool.rb +2 -2
  82. data/app/lib/katello/validators/root_repository_unique_attribute_validator.rb +13 -0
  83. data/app/models/katello/authorization/product.rb +3 -4
  84. data/app/models/katello/authorization/repository.rb +4 -4
  85. data/app/models/katello/candlepin/repository_mapper.rb +12 -26
  86. data/app/models/katello/concerns/audit_search.rb +13 -0
  87. data/app/models/katello/concerns/content_facet_host_extensions.rb +1 -1
  88. data/app/models/katello/concerns/content_view_filter_rule_common.rb +1 -0
  89. data/app/models/katello/concerns/host_managed_extensions.rb +68 -2
  90. data/app/models/katello/concerns/hostgroup_extensions.rb +13 -0
  91. data/app/models/katello/concerns/location_extensions.rb +3 -3
  92. data/app/models/katello/concerns/organization_extensions.rb +7 -3
  93. data/app/models/katello/concerns/pulp_database_unit.rb +1 -0
  94. data/app/models/katello/concerns/recurring_logic_extensions.rb +11 -0
  95. data/app/models/katello/concerns/redhat_extensions.rb +0 -25
  96. data/app/models/katello/concerns/search_by_repository_name.rb +21 -0
  97. data/app/models/katello/concerns/setting_extensions.rb +1 -1
  98. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +43 -0
  99. data/app/models/katello/content.rb +7 -3
  100. data/app/models/katello/content_view.rb +4 -4
  101. data/app/models/katello/content_view_component.rb +1 -1
  102. data/app/models/katello/content_view_history.rb +1 -0
  103. data/app/models/katello/content_view_version.rb +14 -2
  104. data/app/models/katello/docker_manifest_list.rb +1 -1
  105. data/app/models/katello/docker_meta_tag.rb +11 -2
  106. data/app/models/katello/docker_tag.rb +1 -1
  107. data/app/models/katello/erratum.rb +6 -0
  108. data/app/models/katello/file_unit.rb +0 -1
  109. data/app/models/katello/glue/candlepin/owner.rb +1 -0
  110. data/app/models/katello/glue/candlepin/pool.rb +1 -2
  111. data/app/models/katello/glue/candlepin/product.rb +0 -4
  112. data/app/models/katello/glue/candlepin/repository.rb +0 -21
  113. data/app/models/katello/glue/provider.rb +4 -2
  114. data/app/models/katello/glue/pulp/repo.rb +10 -173
  115. data/app/models/katello/glue/pulp/repos.rb +2 -112
  116. data/app/models/katello/gpg_key.rb +6 -14
  117. data/app/models/katello/host/content_facet.rb +1 -1
  118. data/app/models/katello/host/subscription_facet.rb +32 -8
  119. data/app/models/katello/kt_environment.rb +9 -29
  120. data/app/models/katello/module_profile.rb +6 -0
  121. data/app/models/katello/module_profile_rpm.rb +5 -0
  122. data/app/models/katello/module_stream.rb +112 -0
  123. data/app/models/katello/module_stream_artifact.rb +5 -0
  124. data/app/models/katello/ostree_branch.rb +0 -1
  125. data/app/models/katello/package_group.rb +1 -1
  126. data/app/models/katello/pool.rb +4 -0
  127. data/app/models/katello/product.rb +18 -21
  128. data/app/models/katello/product_content.rb +2 -2
  129. data/app/models/katello/puppet_module.rb +1 -0
  130. data/app/models/katello/purpose_addons_status.rb +50 -0
  131. data/app/models/katello/purpose_role_status.rb +50 -0
  132. data/app/models/katello/purpose_sla_status.rb +48 -0
  133. data/app/models/katello/purpose_status.rb +56 -0
  134. data/app/models/katello/purpose_usage_status.rb +50 -0
  135. data/app/models/katello/repository.rb +116 -280
  136. data/app/models/katello/repository_module_stream.rb +7 -0
  137. data/app/models/katello/root_repository.rb +262 -0
  138. data/app/models/katello/subscription_status.rb +1 -1
  139. data/app/models/katello/sync_plan.rb +93 -40
  140. data/app/presenters/katello/content_view_version_compare_presenter.rb +7 -2
  141. data/app/services/katello/candlepin/consumer.rb +25 -0
  142. data/app/services/katello/candlepin/message_handler.rb +18 -2
  143. data/app/services/katello/managed_content_medium_provider.rb +27 -0
  144. data/app/services/katello/product_content_finder.rb +3 -3
  145. data/app/services/katello/pulp/module_stream.rb +9 -0
  146. data/app/services/katello/pulp/repository.rb +22 -0
  147. data/app/services/katello/pulp/srpm.rb +1 -1
  148. data/app/services/katello/pxe_files_downloader.rb +41 -0
  149. data/app/services/katello/registration_manager.rb +5 -0
  150. data/app/views/katello/api/v2/content_facet/show.json.rabl +0 -4
  151. data/app/views/katello/api/v2/content_view_versions/base.json.rabl +12 -2
  152. data/app/views/katello/api/v2/debs/compare.json.rabl +10 -0
  153. data/app/views/katello/api/v2/docker_manifest_lists/compare.json.rabl +10 -0
  154. data/app/views/katello/api/v2/environments/show.json.rabl +1 -0
  155. data/app/views/katello/api/v2/hosts/host_collections.json.rabl +3 -0
  156. data/app/views/katello/api/v2/module_streams/base.json.rabl +4 -0
  157. data/app/views/katello/api/v2/module_streams/index.json.rabl +7 -0
  158. data/app/views/katello/api/v2/module_streams/name_stream.json.rabl +3 -0
  159. data/app/views/katello/api/v2/module_streams/name_streams.json.rabl +7 -0
  160. data/app/views/katello/api/v2/module_streams/show.json.rabl +21 -0
  161. data/app/views/katello/api/v2/organizations/show.json.rabl +4 -1
  162. data/app/views/katello/api/v2/products/base.json.rabl +1 -1
  163. data/app/views/katello/api/v2/repositories/base.json.rabl +23 -10
  164. data/app/views/katello/api/v2/repositories/show.json.rabl +47 -38
  165. data/app/views/katello/api/v2/smart_proxies/download_policy.json.rabl +1 -0
  166. data/app/views/katello/api/v2/subscription_facet/base.json.rabl +1 -1
  167. data/app/views/katello/api/v2/sync_plans/show.json.rabl +2 -1
  168. data/app/views/katello/layouts/react.html.erb +1 -0
  169. data/config/katello.yaml.example +1 -2
  170. data/config/routes.rb +5 -0
  171. data/config/routes/api/v2.rb +12 -1
  172. data/config/routes/overrides.rb +1 -0
  173. data/db/migrate/20150114225023_add_upstream_name_to_repository.rb +7 -2
  174. data/db/migrate/20170208215148_add_docker_repo_name.rb +10 -1
  175. data/db/migrate/20180326190408_move_subscription_products.rb +2 -0
  176. data/db/migrate/20180622105300_add_docker_tags_whitelist_to_repository.rb +9 -0
  177. data/db/migrate/20180725083800_change_repository_password_length.rb +5 -0
  178. data/db/migrate/20180806205420_add_index_to_content_view_version.rb +5 -0
  179. data/db/migrate/20180807145652_create_katello_module_streams.rb +88 -0
  180. data/db/migrate/20180807164405_remove_repository_cp_label.rb +5 -0
  181. data/db/migrate/20180808013432_add_system_purpose_attrs.rb +39 -0
  182. data/db/migrate/20180814202747_add_recurring_logic_to_sync_plan.rb +12 -0
  183. data/db/migrate/20180816142044_add_description_to_katello_module_streams.rb +6 -0
  184. data/db/migrate/20180821144248_add_cron_logic_to_sync_plans.rb +5 -0
  185. data/db/migrate/20180828161400_remove_join_table_for_role_and_usage.rb +20 -0
  186. data/db/migrate/20180917173645_add_source_repo_checksum_type_to_katello_repositories.rb +1 -1
  187. data/db/migrate/20180920123913_drop_repo_module_streams_timestamp_not_null.rb +7 -0
  188. data/db/migrate/20180920171008_change_repository_password_to_text.rb +17 -0
  189. data/db/migrate/20180920214134_create_repository_root.rb +142 -0
  190. data/db/seeds.d/111-container-image-bookmarks.rb +19 -0
  191. data/db/seeds.d/111-upgrade_tasks.rb +9 -0
  192. data/db/seeds.d/150-module_job_templates.rb +12 -0
  193. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/bastion-katello-bootstrap.js +1 -0
  194. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/bastion_katello.js +3 -0
  195. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/module-stream-actions.service.js +26 -0
  196. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/subscription-add-or-remove.html +1 -1
  197. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-module-streams-modal.controller.js +60 -0
  198. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-repository-sets-modal.controller.js +2 -1
  199. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-host-bulk-module-streams-modal.html +70 -0
  200. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-packages-modal.html +16 -14
  201. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-repository-sets-modal.html +1 -7
  202. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-host-modal-helper.service.js +11 -0
  203. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts-helper.service.js +8 -4
  204. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +5 -0
  205. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.routes.js +14 -0
  206. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-module-streams.controller.js +48 -0
  207. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-module-streams.html +68 -0
  208. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details-info.controller.js +15 -0
  209. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details.controller.js +59 -2
  210. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-details.html +6 -0
  211. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +81 -27
  212. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-provisioning-info.html +1 -1
  213. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-subscriptions.html +2 -2
  214. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +4 -0
  215. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/content-views.routes.js +10 -0
  216. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-repositories.service.js +0 -1
  217. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-repositories.html +5 -0
  218. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-versions.html +3 -0
  219. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/new/content-view-new.controller.js +7 -0
  220. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/new/views/content-view-new.html +1 -2
  221. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/content-view-version-content.controller.js +38 -13
  222. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/content-view-versions.module.js +1 -0
  223. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version-module-streams.html +8 -0
  224. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version-ostree-branches.html +1 -1
  225. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version-package-groups.html +1 -1
  226. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version-packages.html +1 -1
  227. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version-yum.html +5 -0
  228. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version.html +7 -0
  229. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/docker-tags.controller.js +1 -0
  230. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/content.service.js +5 -0
  231. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-module-streams.html +38 -0
  232. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment.html +1 -1
  233. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/environments.routes.js +11 -0
  234. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/views/environments.html +3 -0
  235. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum-repositories.controller.js +6 -22
  236. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-repositories.html +7 -1
  237. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-details.controller.js +4 -0
  238. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/views/host-collection-info.html +6 -0
  239. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-bulk-action.factory.js +2 -1
  240. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/module-streams/module-stream.factory.js +27 -0
  241. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/module-streams/module-streams.module.js +15 -0
  242. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/module-streams/views/partials/module-streams-table.html +25 -0
  243. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/details/package-repositories.controller.js +6 -22
  244. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/details/views/package-repositories.html +7 -1
  245. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/repositories-filters.service.js +89 -0
  246. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/product-repositories.controller.js +4 -5
  247. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +15 -2
  248. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.filter.js +2 -2
  249. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-manage-content.controller.js +15 -11
  250. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +5 -0
  251. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +36 -20
  252. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-manage-module-streams.html +17 -0
  253. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +6 -6
  254. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repositories.routes.js +9 -0
  255. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/views/product-repositories.html +5 -0
  256. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery.controller.js +2 -1
  257. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/views/discovery.html +10 -0
  258. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/new/new-sync-plan-modal.controller.js +6 -2
  259. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/repository-sets/repository-set.factory.js +1 -1
  260. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/sync-plan-details-info.controller.js +20 -3
  261. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/sync-plan-details.controller.js +2 -1
  262. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/views/sync-plan-info.html +23 -4
  263. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/new/new-sync-plan.controller.js +10 -6
  264. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/new/views/new-sync-plan-form.html +11 -3
  265. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/sync-plan-helper.service.js +3 -3
  266. data/engines/bastion_katello/app/assets/stylesheets/bastion_katello/bastion_katello.scss +5 -1
  267. data/engines/bastion_katello/lib/bastion_katello/engine.rb +2 -2
  268. data/lib/katello/engine.rb +7 -12
  269. data/lib/katello/permission_creator.rb +5 -1
  270. data/lib/katello/permissions/host_permissions.rb +1 -0
  271. data/lib/katello/plugin.rb +38 -14
  272. data/lib/katello/tasks/clean_backend_objects.rake +7 -3
  273. data/lib/katello/tasks/reimport.rake +1 -0
  274. data/lib/katello/tasks/repository.rake +11 -8
  275. data/lib/katello/tasks/upgrades/3.9/migrate_sync_plans.rake +29 -0
  276. data/lib/katello/version.rb +1 -1
  277. data/package.json +11 -7
  278. data/webpack/__mocks__/foremanReact/common/I18n.js +5 -0
  279. data/webpack/components/MultiSelect/index.js +15 -3
  280. data/webpack/components/PaginationRow/index.js +1 -1
  281. data/webpack/components/Search/__snapshots__/Search.test.js.snap +1 -0
  282. data/webpack/components/Search/index.js +5 -1
  283. data/webpack/components/SelectOrg/SetOrganization.js +2 -1
  284. data/webpack/components/WithOrganization/__snapshots__/withOrganization.test.js.snap +41 -0
  285. data/webpack/components/WithOrganization/withOrganization.js +42 -10
  286. data/webpack/components/WithOrganization/withOrganization.test.js +26 -0
  287. data/webpack/containers/Application/Headers.js +11 -0
  288. data/webpack/containers/Application/Routes.js +1 -1
  289. data/webpack/containers/Application/config.js +23 -7
  290. data/webpack/containers/Application/withHeaders.js +15 -0
  291. data/webpack/move_to_foreman/common/helpers.js +72 -8
  292. data/webpack/move_to_foreman/components/common/ConfirmDialog/ConfirmDialog.js +1 -0
  293. data/webpack/move_to_foreman/components/common/Dialog/Dialog.js +1 -0
  294. data/webpack/move_to_foreman/components/common/EmptyState/index.js +1 -0
  295. data/webpack/move_to_foreman/components/common/ModalProgressBar/ModalProgressBar.js +1 -1
  296. data/webpack/move_to_foreman/components/common/table/formatters/selectionCellFormatter.js +1 -0
  297. data/webpack/move_to_pf/OptionTooltip/OptionTooltip.scss +20 -0
  298. data/webpack/move_to_pf/OptionTooltip/__tests__/OptionTooltip.test.js +32 -0
  299. data/webpack/move_to_pf/OptionTooltip/__tests__/__snapshots__/OptionTooltip.test.js.snap +84 -0
  300. data/webpack/move_to_pf/OptionTooltip/index.js +83 -0
  301. data/webpack/move_to_pf/TypeAhead/TypeAhead.js +15 -2
  302. data/webpack/move_to_pf/react-bootstrap-select/index.js +10 -4
  303. data/webpack/move_to_pf/test-utils/testHelpers.js +14 -2
  304. data/webpack/redux/actions/RedHatRepositories/enabled.js +29 -3
  305. data/webpack/redux/actions/RedHatRepositories/helpers.js +1 -1
  306. data/webpack/redux/actions/RedHatRepositories/repositorySetRepositories.js +27 -0
  307. data/webpack/redux/consts.js +8 -0
  308. data/webpack/redux/reducers/RedHatRepositories/__tests__/enabled.test.js +62 -0
  309. data/webpack/redux/reducers/RedHatRepositories/{repositorySetRepositories.test.js → __tests__/repositorySetRepositories.test.js} +31 -3
  310. data/webpack/redux/reducers/RedHatRepositories/{sets.test.js → __tests__/sets.test.js} +3 -3
  311. data/webpack/redux/reducers/RedHatRepositories/enabled.fixtures.js +16 -0
  312. data/webpack/redux/reducers/RedHatRepositories/enabled.js +34 -18
  313. data/webpack/redux/reducers/RedHatRepositories/repositorySetRepositories.fixtures.js +10 -0
  314. data/webpack/redux/reducers/RedHatRepositories/repositorySetRepositories.js +39 -48
  315. data/webpack/redux/reducers/index.js +6 -0
  316. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetailArtifacts.js +19 -0
  317. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetailInfo.js +51 -0
  318. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +147 -0
  319. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetailsActions.js +25 -0
  320. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetailsConstants.js +3 -0
  321. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetailsReducer.js +33 -0
  322. data/webpack/scenes/ModuleStreams/Details/Profiles/ModuleStreamDetailProfiles.js +19 -0
  323. data/webpack/scenes/ModuleStreams/Details/Profiles/ProfileRpmsCellFormatter.js +53 -0
  324. data/webpack/scenes/ModuleStreams/Details/Profiles/ProfileRpmsCellFormatter.scss +4 -0
  325. data/webpack/scenes/ModuleStreams/Details/Profiles/TableSchema.js +35 -0
  326. data/webpack/scenes/ModuleStreams/Details/Profiles/__tests__/ModuleStreamDetailProfiles.test.js +14 -0
  327. data/webpack/scenes/ModuleStreams/Details/Profiles/__tests__/ProfileRpmsCellFormatter.test.js +24 -0
  328. data/webpack/scenes/ModuleStreams/Details/Profiles/__tests__/__snapshots__/ModuleStreamDetailProfiles.test.js.snap +126 -0
  329. data/webpack/scenes/ModuleStreams/Details/Profiles/__tests__/__snapshots__/ProfileRpmsCellFormatter.test.js.snap +14 -0
  330. data/webpack/scenes/ModuleStreams/Details/Repositories/ModuleStreamDetailRepositories.js +19 -0
  331. data/webpack/scenes/ModuleStreams/Details/Repositories/TableSchema.js +39 -0
  332. data/webpack/scenes/ModuleStreams/Details/Repositories/__tests__/ModuleStreamDetailRepositories.test.js +14 -0
  333. data/webpack/scenes/ModuleStreams/Details/Repositories/__tests__/__snapshots__/ModuleStreamDetailRepositories.test.js.snap +70 -0
  334. data/webpack/scenes/ModuleStreams/Details/__tests__/ModuleStreamDetailArtifacts.test.js +14 -0
  335. data/webpack/scenes/ModuleStreams/Details/__tests__/ModuleStreamDetailInfo.test.js +14 -0
  336. data/webpack/scenes/ModuleStreams/Details/__tests__/ModuleStreamDetails.test.js +27 -0
  337. data/webpack/scenes/ModuleStreams/Details/__tests__/ModuleStreamDetailsActions.test.js +42 -0
  338. data/webpack/scenes/ModuleStreams/Details/__tests__/ModuleStreamDetailsReducer.test.js +33 -0
  339. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetailArtifacts.test.js.snap +18 -0
  340. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetailInfo.test.js.snap +111 -0
  341. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetails.test.js.snap +552 -0
  342. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetailsActions.test.js.snap +144 -0
  343. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetailsReducer.test.js.snap +50 -0
  344. data/webpack/scenes/ModuleStreams/Details/__tests__/moduleStreamDetails.fixtures.js +115 -0
  345. data/webpack/scenes/ModuleStreams/Details/index.js +17 -0
  346. data/webpack/scenes/ModuleStreams/ModuleStreamsActions.js +29 -0
  347. data/webpack/scenes/ModuleStreams/ModuleStreamsConstants.js +3 -0
  348. data/webpack/scenes/ModuleStreams/ModuleStreamsPage.js +98 -0
  349. data/webpack/scenes/ModuleStreams/ModuleStreamsReducer.js +43 -0
  350. data/webpack/scenes/ModuleStreams/ModuleStreamsTable.js +38 -0
  351. data/webpack/scenes/ModuleStreams/ModuleStreamsTableSchema.js +69 -0
  352. data/webpack/scenes/ModuleStreams/__tests__/ModuleStreamPage.test.js +27 -0
  353. data/webpack/scenes/ModuleStreams/__tests__/ModuleStreamsActions.test.js +49 -0
  354. data/webpack/scenes/ModuleStreams/__tests__/ModuleStreamsReducer.test.js +46 -0
  355. data/webpack/scenes/ModuleStreams/__tests__/ModuleStreamsTable.test.js +25 -0
  356. data/webpack/scenes/ModuleStreams/__tests__/__snapshots__/ModuleStreamPage.test.js.snap +69 -0
  357. data/webpack/scenes/ModuleStreams/__tests__/__snapshots__/ModuleStreamsTable.test.js.snap +95 -0
  358. data/webpack/scenes/ModuleStreams/__tests__/moduleStreams.fixtures.js +72 -0
  359. data/webpack/scenes/ModuleStreams/index.js +17 -0
  360. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepository.js +120 -0
  361. data/webpack/scenes/RedHatRepositories/components/{EnabledRepository.stories.js → EnabledRepository/EnabledRepository.stories.js} +0 -0
  362. data/webpack/scenes/RedHatRepositories/components/{EnabledRepositoryContent.js → EnabledRepository/EnabledRepositoryContent.js} +0 -0
  363. data/webpack/scenes/RedHatRepositories/components/{__tests__ → EnabledRepository/__tests__}/EnabledRepository.test.js +6 -2
  364. data/webpack/scenes/RedHatRepositories/components/{__tests__ → EnabledRepository/__tests__}/EnabledRepositoryContent.test.js +0 -0
  365. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/__snapshots__/EnabledRepository.test.js.snap +31 -0
  366. data/webpack/scenes/RedHatRepositories/components/{__tests__ → EnabledRepository/__tests__}/__snapshots__/EnabledRepositoryContent.test.js.snap +0 -0
  367. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/index.js +17 -0
  368. data/webpack/scenes/RedHatRepositories/components/RepositorySet.js +1 -1
  369. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepositories.js +43 -5
  370. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepositoriesHelpers.js +3 -0
  371. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository/RepositorySetRepository.js +168 -0
  372. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository/__test__/RepositorySetRepository.test.js +38 -0
  373. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository/__test__/__snapshots__/RepositorySetRepository.test.js.snap +70 -0
  374. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository/index.js +18 -0
  375. data/webpack/scenes/RedHatRepositories/components/SearchBar.js +4 -3
  376. data/webpack/scenes/RedHatRepositories/components/__tests__/RepositorySetRepositories.test.js +44 -0
  377. data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/RepositorySetRepositories.test.js.snap +48 -0
  378. data/webpack/scenes/RedHatRepositories/helpers.js +19 -15
  379. data/webpack/scenes/RedHatRepositories/index.js +1 -3
  380. data/webpack/scenes/RedHatRepositories/index.scss +16 -0
  381. data/webpack/scenes/Settings/Tables/TableActions.js +73 -0
  382. data/webpack/scenes/Settings/Tables/TableConstants.js +11 -0
  383. data/webpack/scenes/Settings/Tables/TableHelpers.js +8 -0
  384. data/webpack/scenes/Settings/Tables/TableReducer.js +46 -0
  385. data/webpack/scenes/Settings/Tables/__tests__/Table.fixtures.js +125 -0
  386. data/webpack/scenes/Settings/Tables/__tests__/TableActions.test.js +84 -0
  387. data/webpack/scenes/Settings/Tables/__tests__/TableReducer.test.js +41 -0
  388. data/webpack/scenes/Settings/Tables/__tests__/__snapshots__/TableReducer.test.js.snap +76 -0
  389. data/webpack/scenes/Settings/index.js +4 -0
  390. data/webpack/scenes/Subscriptions/Details/SubscriptionAttributes.js +2 -0
  391. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailActions.js +1 -1
  392. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailAssociations.js +1 -0
  393. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailInfo.js +1 -0
  394. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProduct.js +20 -13
  395. data/webpack/scenes/Subscriptions/Details/{SubscriptionDetailEnabledProducts.js → SubscriptionDetailProductContent.js} +5 -5
  396. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailReducer.js +3 -3
  397. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +7 -6
  398. data/webpack/scenes/Subscriptions/Details/__tests__/{SubscriptionDetailEnabledProducts.test.js → SubscriptionDetailProductContent.test.js} +4 -4
  399. data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetails.test.js +2 -2
  400. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailProduct.test.js.snap +28 -16
  401. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/{SubscriptionDetailEnabledProducts.test.js.snap → SubscriptionDetailProductContent.test.js.snap} +1 -1
  402. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +16 -16
  403. data/webpack/scenes/Subscriptions/Details/__tests__/subscriptionDetails.fixtures.js +1 -1
  404. data/webpack/scenes/Subscriptions/Manifest/DeleteManifestModalText.js +2 -0
  405. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +38 -61
  406. data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryReducer.js +4 -0
  407. data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryTableSchema.js +1 -0
  408. data/webpack/scenes/Subscriptions/Manifest/__tests__/ManageManifestModal.test.js +3 -3
  409. data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +12 -3
  410. data/webpack/scenes/Subscriptions/SubscriptionActions.js +26 -0
  411. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +56 -0
  412. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +26 -11
  413. data/webpack/scenes/Subscriptions/SubscriptionValidations.js +1 -0
  414. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +144 -39
  415. data/webpack/scenes/Subscriptions/SubscriptionsPage.scss +7 -0
  416. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +10 -16
  417. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsTableSchema.js +1 -0
  418. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsPage.test.js +1 -1
  419. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsActions.test.js +11 -1
  420. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +15 -2
  421. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsReducer.test.js +12 -0
  422. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +19 -0
  423. data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +87 -0
  424. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/EntitlementsInlineEditFormatter.js +1 -1
  425. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionTypeFormatter.js +31 -0
  426. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js +16 -11
  427. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableSchema.js +18 -3
  428. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionTypeFormatter.test.js +33 -0
  429. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +29 -0
  430. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionTypeFormatter.test.js.snap +34 -0
  431. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +24 -43
  432. data/webpack/scenes/Subscriptions/index.js +24 -7
  433. data/webpack/scenes/Tasks/TaskActions.js +43 -19
  434. data/webpack/scenes/Tasks/TaskConstants.js +1 -0
  435. data/webpack/scenes/Tasks/__tests__/TaskActions.test.js +15 -12
  436. data/webpack/scenes/Tasks/helpers.js +17 -27
  437. data/webpack/services/api/index.js +3 -0
  438. metadata +160 -52
  439. data/app/lib/actions/katello/repository/scheduled_sync.rb +0 -15
  440. data/app/lib/actions/katello/sync_plan/add_products.rb +0 -27
  441. data/app/lib/actions/katello/sync_plan/destroy.rb +0 -26
  442. data/app/lib/actions/katello/sync_plan/remove_products.rb +0 -23
  443. data/app/lib/actions/katello/sync_plan/update.rb +0 -20
  444. data/app/lib/actions/pulp/repos/update.rb +0 -24
  445. data/app/lib/actions/pulp/repository/ensure_sync_notification.rb +0 -11
  446. data/app/lib/actions/pulp/repository/remove_schedule.rb +0 -16
  447. data/app/lib/actions/pulp/repository/update_schedule.rb +0 -47
  448. data/app/lib/katello/validators/repository_unique_attribute_validator.rb +0 -13
  449. data/app/models/katello/candlepin/docker_repository_mapper.rb +0 -77
  450. data/app/models/katello/input_template_renderer.rb +0 -7
  451. data/lib/katello/tasks/upgrades/2.4/import_distributions.rake +0 -11
  452. data/lib/katello/tasks/upgrades/2.4/import_package_groups.rake +0 -11
  453. data/lib/katello/tasks/upgrades/2.4/import_puppet_modules.rake +0 -12
  454. data/lib/katello/tasks/upgrades/2.4/import_rpms.rake +0 -12
  455. data/lib/katello/tasks/upgrades/3.0/add_export_distributor.rake +0 -14
  456. data/lib/katello/tasks/upgrades/3.0/delete_docker_v1_content.rake +0 -27
  457. data/lib/katello/tasks/upgrades/3.0/update_puppet_repository_distributors.rake +0 -20
  458. data/lib/katello/tasks/upgrades/3.0/update_subscription_facet_backend_data.rake +0 -9
  459. data/lib/katello/tasks/upgrades/3.3/hypervisors.rake +0 -7
  460. data/lib/katello/tasks/upgrades/3.4/reindex_docker_tags.rake +0 -12
  461. data/lib/katello/tasks/upgrades/3.4/remove_unused_products.rake +0 -28
  462. data/lib/katello/tasks/upgrades/3.6/import_backend_consumer_attributes.rake +0 -32
  463. data/lib/katello/tasks/upgrades/3.6/import_product_content.rake +0 -12
  464. data/lib/katello/tasks/upgrades/3.6/republish_file_repos.rake +0 -16
  465. data/lib/katello/tasks/upgrades/3.7/import_pools.rake +0 -12
  466. data/lib/katello/tasks/upgrades/3.7/make_all_ks_repos_bootable.rake +0 -11
  467. data/webpack/helpers/caret.js +0 -6
  468. data/webpack/redux/reducers/RedHatRepositories/enabled.test.js +0 -36
  469. data/webpack/redux/reducers/RedHatRepositories/filters.fixtures.js +0 -5
  470. data/webpack/scenes/RedHatRepositories/components/EnabledRepository.js +0 -105
  471. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository.js +0 -129
  472. data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/EnabledRepository.test.js.snap +0 -25
@@ -0,0 +1,5 @@
1
+ module Katello
2
+ class ModuleStreamArtifact < Katello::Model
3
+ belongs_to :module_stream, class_name: "Katello::ModuleStream", inverse_of: :artifacts
4
+ end
5
+ end
@@ -10,7 +10,6 @@ module Katello
10
10
  scoped_search :on => :commit, :complete_value => true
11
11
  scoped_search :on => :uuid, :complete_value => true
12
12
  scoped_search :on => :version_date, :complete_value => true, :rename => :created
13
- scoped_search :relation => :repositories, :on => :name, :rename => :repository, :complete_value => true
14
13
 
15
14
  CONTENT_TYPE = Pulp::OstreeBranch::CONTENT_TYPE
16
15
 
@@ -6,10 +6,10 @@ module Katello
6
6
 
7
7
  has_many :repository_package_groups, :class_name => "Katello::RepositoryPackageGroup", :dependent => :destroy, :inverse_of => :package_group
8
8
  has_many :repositories, :through => :repository_package_groups, :class_name => "Katello::Repository"
9
+ has_many :roots, :through => :repositories, :class_name => "Katello::RootRepository"
9
10
 
10
11
  scoped_search :on => :name, :complete_value => true
11
12
  scoped_search :on => :uuid, :rename => :id, :complete_value => true
12
- scoped_search :relation => :repositories, :on => :name, :rename => :repository, :complete_value => true
13
13
 
14
14
  def self.repository_association_class
15
15
  RepositoryPackageGroup
@@ -76,5 +76,9 @@ module Katello
76
76
  def default_sort
77
77
  Pool.joins(:subscription).order("subscription.name")
78
78
  end
79
+
80
+ class Jail < ::Safemode::Jail
81
+ allow :id, :name, :available, :quantity, :product_id, :contract_number
82
+ end
79
83
  end
80
84
  end
@@ -16,11 +16,13 @@ module Katello
16
16
  belongs_to :sync_plan, :inverse_of => :products, :class_name => 'Katello::SyncPlan'
17
17
  belongs_to :gpg_key, :inverse_of => :products, :class_name => "Katello::GpgKey"
18
18
  has_many :product_contents, :foreign_key => 'product_id', :class_name => "Katello::ProductContent", :dependent => :destroy
19
+ has_many :contents, :through => :product_contents
19
20
  has_many :displayable_product_contents, -> { displayable }, :foreign_key => 'product_id', :class_name => "Katello::ProductContent", :dependent => :destroy
20
21
  belongs_to :ssl_ca_cert, :class_name => "Katello::GpgKey", :inverse_of => :ssl_ca_products
21
22
  belongs_to :ssl_client_cert, :class_name => "Katello::GpgKey", :inverse_of => :ssl_client_products
22
23
  belongs_to :ssl_client_key, :class_name => "Katello::GpgKey", :inverse_of => :ssl_key_products
23
- has_many :repositories, :class_name => "Katello::Repository", :dependent => :restrict_with_exception
24
+ has_many :root_repositories, :class_name => "Katello::RootRepository", :dependent => :restrict_with_exception
25
+ has_many :repositories, :through => :root_repositories
24
26
 
25
27
  has_many :pool_products, :class_name => "Katello::PoolProduct", :dependent => :destroy
26
28
  has_many :pools, :through => :pool_products
@@ -59,20 +61,20 @@ module Katello
59
61
  where(:organization_id => organizations)
60
62
  end
61
63
 
62
- scope :syncable_content, -> { distinct.where(Katello::Repository.arel_table[:url].not_eq(nil)).joins(:repositories) }
64
+ scope :syncable_content, -> { distinct.where(Katello::RootRepository.arel_table[:url].not_eq(nil)).joins(:root_repositories) }
63
65
  scope :redhat, -> { joins(:provider).where("#{Provider.table_name}.provider_type" => Provider::REDHAT) }
64
66
  scope :custom, -> { joins(:provider).where("#{Provider.table_name}.provider_type" => [Provider::CUSTOM, Provider::ANONYMOUS]) }
65
67
  scope :with_contents, -> { includes(:product_contents) }
66
68
 
67
69
  def self.subscribable
68
- joins("LEFT OUTER JOIN #{Katello::Repository.table_name} repo ON repo.product_id = #{self.table_name}.id")
69
- .where("repo.content_type IN (?) OR repo IS NULL", Repository::SUBSCRIBABLE_TYPES)
70
+ joins("LEFT OUTER JOIN #{Katello::RootRepository.table_name} repo ON repo.product_id = #{self.table_name}.id")
71
+ .where("repo.content_type IN (?) OR repo IS NULL", RootRepository::SUBSCRIBABLE_TYPES)
70
72
  .group("#{self.table_name}.id, repo.product_id")
71
73
  end
72
74
 
73
75
  def self.enabled
74
76
  self.where("#{Product.table_name}.id in (?) or #{Product.table_name}.id in (?)",
75
- Product.redhat.joins(:repositories).distinct.pluck(:id), Product.custom.pluck(:id))
77
+ Product.redhat.joins(:root_repositories => :repositories).select(:id), Product.custom.select(:id))
76
78
  end
77
79
 
78
80
  before_create :assign_unique_label
@@ -98,6 +100,10 @@ module Katello
98
100
  super
99
101
  end
100
102
 
103
+ def orphaned?
104
+ self.pool_products.empty?
105
+ end
106
+
101
107
  def repos(env, content_view = nil, include_feedless = true)
102
108
  if content_view.nil?
103
109
  if !env.library?
@@ -156,14 +162,14 @@ module Katello
156
162
  end
157
163
 
158
164
  def published_content_views
159
- Katello::ContentView.non_default.joins(:content_view_versions => :repositories).
160
- where("#{Katello::Repository.table_name}.product_id" => self.id)
165
+ Katello::ContentView.non_default.joins(:content_view_versions => {:repositories => :root}).
166
+ where("#{Katello::RootRepository.table_name}.product_id" => self.id)
161
167
  end
162
168
 
163
169
  def published_content_view_versions
164
- Katello::ContentViewVersion.joins(:content_view).joins(:repositories).
170
+ Katello::ContentViewVersion.joins(:content_view).joins(:repositories => :root).
165
171
  where("#{Katello::ContentView.table_name}.default" => false).
166
- where("#{Katello::Repository.table_name}.product_id" => self.id).order(:content_view_id)
172
+ where("#{Katello::RootRepository.table_name}.product_id" => self.id).order(:content_view_id)
167
173
  end
168
174
 
169
175
  def anonymous?
@@ -174,14 +180,6 @@ module Katello
174
180
  self.class.where(["cp_id = ? AND id != ?", cp_id, id]).count > 0
175
181
  end
176
182
 
177
- def gpg_key_name=(name)
178
- if name.blank?
179
- self.gpg_key = nil
180
- else
181
- self.gpg_key = GpgKey.readable.find_by!(:name => name)
182
- end
183
- end
184
-
185
183
  scope :all_in_org, ->(org) { Product.joins(:provider).where("#{Katello::Provider.table_name}.organization_id = ?", org.id) }
186
184
 
187
185
  def assign_unique_label
@@ -225,10 +223,9 @@ module Katello
225
223
  end
226
224
 
227
225
  def available_content(content_view_version_id = nil)
228
- product_contents.select do |product_content|
229
- repos = self.repositories.subscribable.where(content_id: product_content.content.cp_content_id)
230
- repos.exists? && (content_view_version_id.nil? || repos.where(content_view_version_id: content_view_version_id.to_i).count > 0)
231
- end
226
+ root_repos = self.root_repositories.subscribable
227
+ root_repos = root_repos.join(:repositories).where(:content_view_version_id => content_view_version_id) if content_view_version_id
228
+ self.product_contents.joins(:content).where("#{Katello::Content.table_name}.cp_content_id" => root_repos.select(:content_id))
232
229
  end
233
230
 
234
231
  def related_resources
@@ -28,7 +28,7 @@ module Katello
28
28
  end
29
29
 
30
30
  def self.enabled(organization)
31
- joins(:content).where("#{self.content_table_name}.cp_content_id" => Katello::Repository.in_organization(organization).select(:content_id))
31
+ joins(:content).where("#{self.content_table_name}.cp_content_id" => Katello::RootRepository.in_organization(organization).select(:content_id))
32
32
  end
33
33
 
34
34
  def self.with_valid_subscription(organization)
@@ -37,7 +37,7 @@ module Katello
37
37
 
38
38
  # used by Katello::Api::V2::RepositorySetsController#index
39
39
  def repositories
40
- product.repositories.in_default_view.has_url.where(:content_id => content.cp_content_id)
40
+ Katello::Repository.where(:root_id => product.root_repositories.has_url.where(:content_id => content.cp_content_id))
41
41
  end
42
42
  end
43
43
  end
@@ -18,6 +18,7 @@ module Katello
18
18
  :through => :content_view_puppet_environment_puppet_modules,
19
19
  :class_name => "Katello::ContentViewPuppetEnvironment"
20
20
 
21
+ scoped_search :on => :id, :only_explicit => true
21
22
  scoped_search :on => :name, :complete_value => true
22
23
  scoped_search :on => :author, :complete_value => true
23
24
  scoped_search :on => :version, :complete_value => true
@@ -0,0 +1,50 @@
1
+ module Katello
2
+ class PurposeAddonsStatus < HostStatus::Status
3
+ VALID = 0
4
+ INVALID = 1
5
+ UNKNOWN = 2
6
+
7
+ def self.status_name
8
+ N_('Addons')
9
+ end
10
+
11
+ def self.humanized_name
12
+ 'purpose_addons'
13
+ end
14
+
15
+ def to_label(_options = {})
16
+ case status
17
+ when VALID
18
+ N_('Matched')
19
+ when INVALID
20
+ N_('Mismatched')
21
+ else
22
+ N_('Unknown')
23
+ end
24
+ end
25
+
26
+ def to_status(options = {})
27
+ return UNKNOWN unless relevant?
28
+
29
+ status_override = options[:status_override]
30
+
31
+ return INVALID if status_override == false
32
+
33
+ return VALID if status_override || consumer.compliant_addons?
34
+
35
+ INVALID
36
+ end
37
+
38
+ def relevant?(_options = {})
39
+ host.subscription_facet.try(:uuid)
40
+ end
41
+
42
+ def substatus?(_options = {})
43
+ true
44
+ end
45
+
46
+ def consumer
47
+ Katello::Candlepin::Consumer.new(host.subscription_facet.uuid, host.organization.label)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,50 @@
1
+ module Katello
2
+ class PurposeRoleStatus < HostStatus::Status
3
+ VALID = 0
4
+ INVALID = 1
5
+ UNKNOWN = 2
6
+
7
+ def self.status_name
8
+ N_('Role')
9
+ end
10
+
11
+ def self.humanized_name
12
+ 'purpose_role'
13
+ end
14
+
15
+ def to_label(_options = {})
16
+ case status
17
+ when VALID
18
+ N_('Matched')
19
+ when INVALID
20
+ N_('Mismatched')
21
+ else
22
+ N_('Unknown')
23
+ end
24
+ end
25
+
26
+ def to_status(options = {})
27
+ return UNKNOWN unless relevant?
28
+
29
+ status_override = options[:status_override]
30
+
31
+ return INVALID if status_override == false
32
+
33
+ return VALID if status_override || consumer.compliant_role?
34
+
35
+ INVALID
36
+ end
37
+
38
+ def relevant?(_options = {})
39
+ host.subscription_facet.try(:uuid)
40
+ end
41
+
42
+ def substatus?(_options = {})
43
+ true
44
+ end
45
+
46
+ def consumer
47
+ Katello::Candlepin::Consumer.new(host.subscription_facet.uuid, host.organization.label)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,48 @@
1
+ module Katello
2
+ class PurposeSlaStatus < HostStatus::Status
3
+ VALID = 0
4
+ INVALID = 1
5
+ UNKNOWN = 2
6
+
7
+ def self.status_name
8
+ N_('Service Level')
9
+ end
10
+
11
+ def self.humanized_name
12
+ 'purpose_sla'
13
+ end
14
+
15
+ def to_label(_options = {})
16
+ case status
17
+ when VALID
18
+ N_('Matched')
19
+ when INVALID
20
+ N_('Mismatched')
21
+ else
22
+ N_('Unknown')
23
+ end
24
+ end
25
+
26
+ def to_status(options = {})
27
+ return UNKNOWN unless relevant?
28
+
29
+ return INVALID if options[:status_override] == false
30
+
31
+ return VALID if options[:status_override] || consumer.compliant_sla?
32
+
33
+ INVALID
34
+ end
35
+
36
+ def relevant?(_options = {})
37
+ host.subscription_facet.try(:uuid)
38
+ end
39
+
40
+ def substatus?(_options = {})
41
+ true
42
+ end
43
+
44
+ def consumer
45
+ Katello::Candlepin::Consumer.new(host.subscription_facet.uuid, host.organization.label)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,56 @@
1
+ module Katello
2
+ class PurposeStatus < HostStatus::Status
3
+ VALID = 0
4
+ INVALID = 1
5
+ UNKNOWN = 2
6
+
7
+ SUBSTATUSES = [
8
+ Katello::PurposeSlaStatus,
9
+ Katello::PurposeRoleStatus,
10
+ Katello::PurposeUsageStatus,
11
+ Katello::PurposeAddonsStatus
12
+ ].freeze
13
+
14
+ def self.status_name
15
+ N_('System Purpose')
16
+ end
17
+
18
+ def self.humanized_name
19
+ 'purpose'
20
+ end
21
+
22
+ def to_label(_options = {})
23
+ case status
24
+ when VALID
25
+ N_('Matched')
26
+ when INVALID
27
+ N_('Mismatched')
28
+ else
29
+ N_('Unknown')
30
+ end
31
+ end
32
+
33
+ def to_global(_options = {})
34
+ case status
35
+ when VALID
36
+ ::HostStatus::Global::OK
37
+ else
38
+ ::HostStatus::Global::WARN
39
+ end
40
+ end
41
+
42
+ def to_status(_options = {})
43
+ return UNKNOWN unless relevant?
44
+
45
+ SUBSTATUSES.each do |status_class|
46
+ return INVALID if host.get_status(status_class).status != status_class::VALID
47
+ end
48
+
49
+ VALID
50
+ end
51
+
52
+ def relevant?(_options = {})
53
+ host.subscription_facet.try(:uuid)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,50 @@
1
+ module Katello
2
+ class PurposeUsageStatus < HostStatus::Status
3
+ VALID = 0
4
+ INVALID = 1
5
+ UNKNOWN = 2
6
+
7
+ def self.status_name
8
+ N_('Usage')
9
+ end
10
+
11
+ def self.humanized_name
12
+ 'purpose_usage'
13
+ end
14
+
15
+ def to_label(_options = {})
16
+ case status
17
+ when VALID
18
+ N_('Matched')
19
+ when INVALID
20
+ N_('Mismatched')
21
+ else
22
+ N_('Unknown')
23
+ end
24
+ end
25
+
26
+ def to_status(options = {})
27
+ return UNKNOWN unless relevant?
28
+
29
+ status_override = options[:status_override]
30
+
31
+ return INVALID if status_override == false
32
+
33
+ return VALID if status_override || consumer.compliant_usage?
34
+
35
+ INVALID
36
+ end
37
+
38
+ def relevant?(_options = {})
39
+ host.subscription_facet.try(:uuid)
40
+ end
41
+
42
+ def substatus?(_options = {})
43
+ true
44
+ end
45
+
46
+ def consumer
47
+ Katello::Candlepin::Consumer.new(host.subscription_facet.uuid, host.organization.label)
48
+ end
49
+ end
50
+ end
@@ -1,15 +1,12 @@
1
1
  module Katello
2
2
  # rubocop:disable Metrics/ClassLength
3
3
  class Repository < Katello::Model
4
- audited
5
4
  #pulp uses pulp id to sync with 'yum_distributor' on the end
6
5
  PULP_ID_MAX_LENGTH = 220
7
6
 
8
- validates_lengths_from_database :except => [:label]
7
+ validates_lengths_from_database
9
8
  before_destroy :assert_deletable
10
9
  before_create :downcase_pulp_id
11
- before_validation :update_ostree_upstream_sync_policy
12
- serialize :ignorable_content
13
10
 
14
11
  include ForemanTasks::Concerns::ActionSubject
15
12
  include Glue::Candlepin::Repository
@@ -17,8 +14,6 @@ module Katello
17
14
 
18
15
  include Glue if (SETTINGS[:katello][:use_cp] || SETTINGS[:katello][:use_pulp])
19
16
  include Authorization::Repository
20
-
21
- include Ext::LabelFromName
22
17
  include Katello::Engine.routes.url_helpers
23
18
 
24
19
  include ERB::Util
@@ -30,28 +25,18 @@ module Katello
30
25
  DOCKER_TYPE = 'docker'.freeze
31
26
  OSTREE_TYPE = 'ostree'.freeze
32
27
 
33
- IGNORABLE_CONTENT_UNIT_TYPES = %w(rpm drpm srpm distribution erratum).freeze
34
- CHECKSUM_TYPES = %w(sha1 sha256).freeze
35
- SUBSCRIBABLE_TYPES = [YUM_TYPE, OSTREE_TYPE, DEB_TYPE].freeze
36
-
37
- OSTREE_UPSTREAM_SYNC_POLICY_LATEST = "latest".freeze
38
- OSTREE_UPSTREAM_SYNC_POLICY_ALL = "all".freeze
39
- OSTREE_UPSTREAM_SYNC_POLICY_CUSTOM = "custom".freeze
40
- OSTREE_UPSTREAM_SYNC_POLICIES = [OSTREE_UPSTREAM_SYNC_POLICY_LATEST, OSTREE_UPSTREAM_SYNC_POLICY_ALL, OSTREE_UPSTREAM_SYNC_POLICY_CUSTOM].freeze
41
-
42
28
  define_model_callbacks :sync, :only => :after
43
29
 
30
+ belongs_to :root, :inverse_of => :repositories, :class_name => "Katello::RootRepository"
44
31
  belongs_to :environment, :inverse_of => :repositories, :class_name => "Katello::KTEnvironment"
45
- belongs_to :product, :inverse_of => :repositories, :class_name => "Katello::Product"
46
- belongs_to :gpg_key, :inverse_of => :repositories, :class_name => "Katello::GpgKey"
47
- belongs_to :ssl_ca_cert, :class_name => "Katello::GpgKey", :inverse_of => :ssl_ca_repos
48
- belongs_to :ssl_client_cert, :class_name => "Katello::GpgKey", :inverse_of => :ssl_client_repos
49
- belongs_to :ssl_client_key, :class_name => "Katello::GpgKey", :inverse_of => :ssl_key_repos
50
- belongs_to :library_instance, :class_name => "Katello::Repository", :inverse_of => :library_instances_inverse
51
- has_many :library_instances_inverse, # TODO: what is the proper name?
32
+ belongs_to :library_instance, :class_name => "Katello::Repository", :inverse_of => :library_instances_inverse, :foreign_key => :library_instance_id
33
+ has_many :library_instances_inverse,
52
34
  :class_name => 'Katello::Repository',
53
35
  :dependent => :restrict_with_exception,
54
36
  :foreign_key => :library_instance_id
37
+
38
+ has_one :product, :through => :root
39
+
55
40
  has_many :content_view_repositories, :class_name => "Katello::ContentViewRepository",
56
41
  :dependent => :destroy, :inverse_of => :repository
57
42
  has_many :content_views, :through => :content_view_repositories
@@ -99,6 +84,9 @@ module Katello
99
84
  has_many :kickstart_hostgroups, :class_name => "::Hostgroup", :foreign_key => :kickstart_repository_id,
100
85
  :inverse_of => :kickstart_repository, :dependent => :nullify
101
86
 
87
+ has_many :repository_module_streams, class_name: "Katello::RepositoryModuleStream", dependent: :delete_all
88
+ has_many :module_streams, through: :repository_module_streams
89
+
102
90
  # rubocop:disable HasAndBelongsToMany
103
91
  # TODO: change this into has_many :through association
104
92
  has_and_belongs_to_many :filters, :class_name => "Katello::ContentViewFilter",
@@ -106,64 +94,33 @@ module Katello
106
94
  :foreign_key => :content_view_filter_id
107
95
  belongs_to :content_view_version, :inverse_of => :repositories, :class_name => "Katello::ContentViewVersion"
108
96
 
109
- validates :product_id, :presence => true
110
- validates :pulp_id, :presence => true, :uniqueness => true, :if => proc { |r| r.name.present? }
111
- validates :checksum_type, :inclusion => {:in => CHECKSUM_TYPES}, :allow_blank => true
112
-
113
- validates_with Validators::ContainerImageNameValidator, :attributes => :docker_upstream_name, :allow_blank => true, :if => :docker?
114
97
  validates_with Validators::ContainerImageNameValidator, :attributes => :container_repository_name, :allow_blank => false, :if => :docker?
98
+ validates :pulp_id, :presence => true, :uniqueness => true, :if => proc { |r| r.name.present? }
115
99
  validates :container_repository_name, :uniqueness => true, :if => :docker?
116
100
 
117
- validates :ostree_upstream_sync_policy, :inclusion => {:in => OSTREE_UPSTREAM_SYNC_POLICIES, :allow_blank => true}, :if => :ostree?
118
- validates :ostree_upstream_sync_depth, :presence => true, :numericality => { :only_integer => true },
119
- :if => proc { |r| r.ostree? && r.ostree_upstream_sync_policy == OSTREE_UPSTREAM_SYNC_POLICY_CUSTOM }
120
- #validates :content_id, :presence => true #add back after fixing add_repo orchestration
121
- validates_with Validators::KatelloLabelFormatValidator, :attributes => :label
122
- validates_with Validators::KatelloNameFormatValidator, :attributes => :name
123
- validates_with Validators::RepositoryUniqueAttributeValidator, :attributes => :label
124
- validates_with Validators::RepositoryUniqueAttributeValidator, :attributes => :name
125
- validates_with Validators::KatelloUrlFormatValidator,
126
- :attributes => :url, :nil_allowed => proc { |repo| repo.custom? }, :field_name => :url,
127
- :if => proc { |repo| repo.in_default_view? }
128
- validates :content_type, :inclusion => {
129
- :in => ->(_) { Katello::RepositoryTypeManager.repository_types.keys },
130
- :allow_blank => false,
131
- :message => ->(_, _) { _("must be one of the following: %s") % Katello::RepositoryTypeManager.repository_types.keys.join(', ') }
132
- }
133
- validates :download_policy, inclusion: {
134
- :in => ::Runcible::Models::YumImporter::DOWNLOAD_POLICIES,
135
- :message => _("must be one of the following: %s") % ::Runcible::Models::YumImporter::DOWNLOAD_POLICIES.join(', ')
136
- }, if: :yum?
137
- validate :ensure_no_download_policy, if: ->(repo) { !repo.yum? }
138
- validate :ensure_no_ostree_upstream_sync_policy, if: ->(repo) { !repo.ostree? }
139
- validate :ensure_valid_docker_attributes, :if => :docker?
140
- validate :ensure_docker_repo_unprotected, :if => :docker?
141
- validate :ensure_has_url_for_ostree, :if => :ostree?
142
- validate :ensure_ostree_repo_protected, :if => :ostree?
143
- validate :ensure_compatible_download_policy, :if => :yum?
144
- validate :ensure_valid_ignorable_content
145
-
146
101
  before_validation :set_pulp_id
147
102
  before_validation :set_container_repository_name, :if => :docker?
148
103
 
149
- scope :has_url, -> { where('url IS NOT NULL') }
104
+ scope :has_url, -> { joins(:root).where.not("#{RootRepository.table_name}.url" => nil) }
105
+ scope :on_demand, -> { joins(:root).where("#{RootRepository.table_name}.download_policy" => ::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND) }
150
106
  scope :in_default_view, -> { joins(:content_view_version => :content_view).where("#{Katello::ContentView.table_name}.default" => true) }
151
107
  scope :in_non_default_view, -> { joins(:content_view_version => :content_view).where("#{Katello::ContentView.table_name}.default" => false) }
152
- scope :deb_type, -> { where(:content_type => DEB_TYPE) }
153
- scope :yum_type, -> { where(:content_type => YUM_TYPE) }
154
- scope :file_type, -> { where(:content_type => FILE_TYPE) }
155
- scope :puppet_type, -> { where(:content_type => PUPPET_TYPE) }
156
- scope :docker_type, -> { where(:content_type => DOCKER_TYPE) }
157
- scope :ostree_type, -> { where(:content_type => OSTREE_TYPE) }
158
- scope :non_puppet, -> { where("content_type != ?", PUPPET_TYPE) }
108
+ scope :deb_type, -> { with_type(DEB_TYPE) }
109
+ scope :yum_type, -> { with_type(YUM_TYPE) }
110
+ scope :file_type, -> { with_type(FILE_TYPE) }
111
+ scope :puppet_type, -> { with_type(PUPPET_TYPE) }
112
+ scope :docker_type, -> { with_type(DOCKER_TYPE) }
113
+ scope :ostree_type, -> { with_type(OSTREE_TYPE) }
114
+ scope :non_puppet, -> { with_type(RepositoryTypeManager.repository_types.keys - [PUPPET_TYPE]) }
159
115
  scope :non_archived, -> { where('environment_id is not NULL') }
160
116
  scope :archived, -> { where('environment_id is NULL') }
161
- scope :subscribable, -> { where(content_type: SUBSCRIBABLE_TYPES) }
162
117
  scope :in_published_environments, -> { in_content_views(Katello::ContentView.non_default).where.not(:environment_id => nil) }
118
+ scope :order_by_root, ->(attr) { joins(:root).order("#{Katello::RootRepository.table_name}.#{attr}") }
163
119
 
164
- scoped_search :on => :name, :complete_value => true
120
+ scoped_search :on => :name, :relation => :root, :complete_value => true
165
121
  scoped_search :rename => :product, :on => :name, :relation => :product, :complete_value => true
166
- scoped_search :on => :content_type, :complete_value => -> do
122
+ scoped_search :rename => :product_id, :on => :id, :relation => :product
123
+ scoped_search :on => :content_type, :relation => :root, :complete_value => -> do
167
124
  Katello::RepositoryTypeManager.repository_types.keys.each_with_object({}) { |value, hash| hash[value.to_sym] = value }
168
125
  end
169
126
  scoped_search :on => :content_view_id, :relation => :content_view_repositories, :validator => ScopedSearch::Validators::INTEGER, :only_explicit => true
@@ -173,10 +130,25 @@ module Katello
173
130
  scoped_search :on => :distribution_variant, :complete_value => true
174
131
  scoped_search :on => :distribution_bootable, :complete_value => true
175
132
  scoped_search :on => :distribution_uuid, :complete_value => true
176
- scoped_search :on => :ignore_global_proxy, :complete_value => true
133
+ scoped_search :on => :ignore_global_proxy, :relation => :root, :complete_value => true
177
134
  scoped_search :on => :redhat, :complete_value => { :true => true, :false => false }, :ext_method => :search_by_redhat
178
135
  scoped_search :on => :container_repository_name, :complete_value => true
179
- scoped_search :on => :description, :only_explicit => true
136
+ scoped_search :on => :description, :relation => :root, :only_explicit => true
137
+
138
+ delegate :product, :redhat?, :custom?, :to => :root
139
+ delegate :yum?, :docker?, :puppet?, :deb?, :file?, :ostree?, :to => :root
140
+ delegate :name, :label, :docker_upstream_name, :url, :to => :root
141
+
142
+ delegate :name, :created_at, :updated_at, :major, :minor, :gpg_key_id, :content_id, :arch, :label, :url, :unprotected,
143
+ :content_type, :product_id, :checksum_type, :docker_upstream_name, :mirror_on_sync, :"mirror_on_sync?",
144
+ :download_policy, :verify_ssl_on_sync, :"verify_ssl_on_sync?", :upstream_username, :upstream_password,
145
+ :ostree_upstream_sync_policy, :ostree_upstream_sync_depth, :deb_releases, :deb_components, :deb_architectures,
146
+ :ignore_global_proxy, :ssl_ca_cert_id, :ssl_ca_cert, :ssl_client_cert, :ssl_client_cert_id, :ssl_client_key_id,
147
+ :ssl_client_key, :ignorable_content, :description, :docker_tags_whitelist, :to => :root
148
+
149
+ def self.with_type(content_type)
150
+ joins(:root).where("#{RootRepository.table_name}.content_type" => content_type)
151
+ end
180
152
 
181
153
  def organization
182
154
  if self.environment
@@ -209,6 +181,10 @@ module Katello
209
181
  self.content_view_version.content_view
210
182
  end
211
183
 
184
+ def library_instance?
185
+ self.content_view.default?
186
+ end
187
+
212
188
  def self.undisplayable_types
213
189
  ret = [::Katello::Repository::CANDLEPIN_DOCKER_TYPE]
214
190
 
@@ -228,7 +204,7 @@ module Katello
228
204
  end
229
205
 
230
206
  def self.in_product(prod)
231
- where(product_id: prod)
207
+ where(:root_id => RootRepository.where(product_id: prod))
232
208
  end
233
209
 
234
210
  def self.in_content_views(views)
@@ -254,25 +230,12 @@ module Katello
254
230
  end
255
231
 
256
232
  def on_demand?
257
- download_policy == Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND
258
- end
259
-
260
- def self.in_environments_products(env_ids, product_ids)
261
- in_environment(env_ids).in_product(product_ids)
262
- end
263
-
264
- def other_repos_with_same_product_and_content
265
- Repository.in_product(Product.find(self.product.id)).where(:content_id => self.content_id)
266
- .where("#{self.class.table_name}.id != #{self.id}")
267
- end
268
-
269
- def other_repos_with_same_content
270
- Repository.where(:content_id => self.content_id).where("#{self.class.table_name}.id != #{self.id}")
233
+ root.download_policy == Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND
271
234
  end
272
235
 
273
236
  def yum_gpg_key_url
274
237
  # if the repo has a gpg key return a url to access it
275
- if (self.gpg_key && self.gpg_key.content.present?)
238
+ if self.root.gpg_key.try(:content).present?
276
239
  "../..#{gpg_key_content_api_repository_url(self, :only_path => true)}"
277
240
  end
278
241
  end
@@ -281,12 +244,6 @@ module Katello
281
244
  redhat? ? "redhat" : "custom"
282
245
  end
283
246
 
284
- delegate :redhat?, to: :product
285
-
286
- def custom?
287
- !redhat?
288
- end
289
-
290
247
  def empty_errata
291
248
  repository_rpm = Katello::RepositoryRpm.table_name
292
249
  repository_errata = Katello::RepositoryErratum.table_name
@@ -309,18 +266,16 @@ module Katello
309
266
  end
310
267
  end
311
268
 
312
- def library_instance?
313
- library_instance.nil?
269
+ def clones
270
+ self.root.repositories.where.not(:id => library_instance_id || id)
314
271
  end
315
272
 
316
- def clones
317
- lib_id = self.library_instance_id || self.id
318
- Repository.where(:library_instance_id => lib_id)
273
+ def all_instances
274
+ self.root.repositories
319
275
  end
320
276
 
321
277
  def group
322
- library_repo = library_instance? ? self : library_instance
323
- clones.to_a << library_repo
278
+ all_instances
324
279
  end
325
280
 
326
281
  #is the repo cloned in the specified environment
@@ -329,8 +284,8 @@ module Katello
329
284
  end
330
285
 
331
286
  def promoted?
332
- if environment && environment.library? && Repository.where(:library_instance_id => self.id).any?
333
- true
287
+ if environment && environment.library?
288
+ self.clones.any?
334
289
  else
335
290
  false
336
291
  end
@@ -339,8 +294,7 @@ module Katello
339
294
  def get_clone(env)
340
295
  if self.content_view.default
341
296
  # this repo is part of a default content view
342
- lib_id = self.library_instance_id || self.id
343
- Repository.in_environment(env).where(:library_instance_id => lib_id).
297
+ Repository.in_environment(env).clones.
344
298
  joins(:content_view_version => :content_view).where("#{Katello::ContentView.table_name}.default" => true).first
345
299
  else
346
300
  # this repo is part of a content view that was published from a user created view
@@ -348,19 +302,6 @@ module Katello
348
302
  end
349
303
  end
350
304
 
351
- def gpg_key_name=(name)
352
- if name.blank?
353
- self.gpg_key = nil
354
- else
355
- self.gpg_key = GpgKey.readable.find_by!(:name => name)
356
- end
357
- end
358
-
359
- def copy_library_instance_attributes
360
- self.unprotected = library_instance.unprotected
361
- self.checksum_type = library_instance.checksum_type
362
- end
363
-
364
305
  # Returns true if the pulp_task_id was triggered by the last synchronization
365
306
  # action for the repository. Dynflow action handles the synchronization
366
307
  # by it's own so no need to synchronize it again in this callback. Since the
@@ -372,41 +313,29 @@ module Katello
372
313
  return task && task.main_action.pulp_task_id == pulp_task_id
373
314
  end
374
315
 
375
- def as_json(*args)
376
- ret = super
377
- ret["gpg_key_name"] = gpg_key ? gpg_key.name : ""
378
- ret["package_count"] = package_count rescue nil
379
- ret["last_sync"] = last_sync rescue nil
380
- ret["puppet_module_count"] = self.puppet_modules.count rescue nil
381
- ret
382
- end
316
+ def generate_repo_path
317
+ _org, _content, content_path = (self.library_instance || self).relative_path.split("/", 3)
383
318
 
384
- def self.clone_repo_path(options)
385
- repo = options[:repository]
386
- repo_lib = repo.library_instance ? repo.library_instance : repo
387
- org, _, content_path = repo_lib.relative_path.split("/", 3)
388
- if options[:environment]
389
- cve = ContentViewEnvironment.where(:environment_id => options[:environment],
390
- :content_view_id => options[:content_view]).first
391
- "#{org}/#{cve.label}/#{content_path}"
319
+ if self.environment
320
+ cve = ContentViewEnvironment.where(:environment_id => self.environment,
321
+ :content_view_id => self.content_view).first
322
+ "#{organization.label}/#{cve.label}/#{content_path}"
392
323
  else
393
- "#{org}/#{ContentView::CONTENT_DIR}/#{options[:content_view].label}/#{options[:version].version}/#{content_path}"
324
+ "#{organization.label}/#{ContentView::CONTENT_DIR}/#{self.content_view.label}/#{self.content_view_version.version}/#{content_path}"
394
325
  end
395
326
  end
396
327
 
397
- def self.clone_docker_repo_path(options)
398
- repo = options[:repository]
399
- org = repo.organization.label.downcase
400
- if options[:environment]
401
- cve = ContentViewEnvironment.where(:environment_id => options[:environment],
402
- :content_view_id => options[:content_view]).first
403
- view = repo.content_view.label
404
- product = repo.product.label
328
+ def generate_docker_repo_path
329
+ org = self.organization.label.downcase
330
+ if self.environment
331
+ cve = ContentViewEnvironment.where(:environment_id => self.environment,
332
+ :content_view_id => self.content_view).first
333
+ view = self.content_view.label
334
+ product = self.product.label
405
335
  env = cve.label.split('/').first
406
- "#{org}-#{env.downcase}-#{view}-#{product}-#{repo.label}"
336
+ "#{org}-#{env.downcase}-#{view}-#{product}-#{self.root.label}"
407
337
  else
408
- content_path = repo.relative_path.gsub("#{org}-", '')
409
- "#{org}-#{options[:content_view].label}-#{options[:version].version}-#{content_path}"
338
+ "#{org}-#{self.content_view.label}-#{self.content_view_version.version}-#{self.root.product.label}-#{self.root.label}"
410
339
  end
411
340
  end
412
341
 
@@ -428,13 +357,13 @@ module Katello
428
357
  end
429
358
 
430
359
  # TODO: break up method
431
- # rubocop:disable MethodLength
432
360
  def build_clone(options)
433
361
  to_env = options[:environment]
434
362
  version = options[:version]
435
363
  content_view = options[:content_view] || to_env.default_content_view
436
364
  to_version = version || content_view.version(to_env)
437
- library = self.library_instance ? self.library_instance : self
365
+
366
+ fail _("Cannot clone into the Default Content View") if content_view.default?
438
367
 
439
368
  if to_env && version
440
369
  fail "Cannot clone into both an environment and a content view version archive"
@@ -445,52 +374,26 @@ module Katello
445
374
  {:view => content_view.name, :env => to_env.name}
446
375
  end
447
376
 
448
- if content_view.default?
449
- if to_env.prior != self.environment
450
- fail _("Cannot clone repository from %{from_env} to %{to_env}. They are not sequential.") %
451
- {:from_env => self.environment.name, :to_env => to_env.name}
452
- end
453
- if self.cloned_in?(to_env)
454
- fail _("Repository has already been promoted to %{to_env}") %
455
- {:to_env => to_env}
456
- end
457
- else
458
- if to_env &&
459
- content_view.repos(to_env).where(:library_instance_id => library.id).count > 0
460
- fail _("Repository has already been cloned to %{cv_name} in environment %{to_env}") %
461
- {:to_env => to_env, :cv_name => content_view.name}
462
- end
377
+ if to_env && self.clones.in_content_views([content_view]).in_environment(to_env).any?
378
+ fail _("Repository has already been cloned to %{cv_name} in environment %{to_env}") %
379
+ {:to_env => to_env, :cv_name => content_view.name}
463
380
  end
464
381
 
465
- Repository.new(:environment => to_env,
466
- :product => self.product,
467
- :cp_label => self.cp_label,
468
- :library_instance => library,
469
- :label => self.label,
470
- :name => self.name,
471
- :arch => self.arch,
472
- :major => self.major,
473
- :minor => self.minor,
474
- :content_id => self.content_id,
475
- :content_view_version => to_version,
476
- :content_type => self.content_type,
477
- :checksum_type => checksum_type || source_repo_checksum_type,
478
- :docker_upstream_name => self.docker_upstream_name,
479
- :download_policy => download_policy,
480
- :unprotected => self.unprotected) do |clone|
481
- options = {
482
- :repository => self,
483
- :environment => to_env,
484
- :content_view => content_view,
485
- :version => version
486
- }
487
-
488
- clone.relative_path = if clone.docker?
489
- Repository.clone_docker_repo_path(options)
490
- else
491
- Repository.clone_repo_path(options)
492
- end
382
+ if self.yum?
383
+ if self.library_instance?
384
+ checksum_type = root.checksum_type || pulp_scratchpad_checksum_type
385
+ else
386
+ checksum_type = self.saved_checksum_type
387
+ end
493
388
  end
389
+ clone = Repository.new(:environment => to_env,
390
+ :library_instance => self.library_instance || self,
391
+ :root => self.root,
392
+ :content_view_version => to_version,
393
+ :saved_checksum_type => checksum_type)
394
+
395
+ clone.relative_path = clone.docker? ? clone.generate_docker_repo_path : clone.generate_repo_path
396
+ clone
494
397
  end
495
398
 
496
399
  def cancel_dynflow_sync
@@ -506,29 +409,21 @@ module Katello
506
409
  end
507
410
 
508
411
  def latest_dynflow_sync
509
- @latest_dynflow_sync ||= ForemanTasks::Task::DynflowTask.where(:label => [::Actions::Katello::Repository::Sync.name, ::Actions::Katello::Repository::ScheduledSync.name]).
412
+ @latest_dynflow_sync ||= ForemanTasks::Task::DynflowTask.where(:label => ::Actions::Katello::Repository::Sync.name).
510
413
  for_resource(self).order(:started_at).last
511
414
  end
512
415
 
513
- def create_clone(options)
514
- clone = build_clone(options)
515
- clone.save!
516
- return clone
517
- end
518
-
519
416
  # returns other instances of this repo with the same library
520
417
  # equivalent of repo
521
418
  def environmental_instances(view)
522
- repo = self.library_instance || self
523
- search = Repository.non_archived.where("library_instance_id=%s or #{Katello::Repository.table_name}.id=%s" % [repo.id, repo.id])
524
- search.in_content_views([view])
419
+ self.all_instances.non_archived.in_content_views([view])
525
420
  end
526
421
 
527
422
  def archived_instance
528
423
  if self.environment_id.nil? || self.library_instance_id.nil?
529
424
  self
530
425
  else
531
- self.content_view_version.archived_repos.where(:library_instance_id => self.library_instance_id).first
426
+ self.content_view_version.archived_repos.where(:root_id => self.root_id).first
532
427
  end
533
428
  end
534
429
 
@@ -537,7 +432,7 @@ module Katello
537
432
  end
538
433
 
539
434
  def url?
540
- url.present?
435
+ root.url.present?
541
436
  end
542
437
 
543
438
  def name_conflicts
@@ -586,16 +481,6 @@ module Katello
586
481
  self.ostree_branches.map(&:name)
587
482
  end
588
483
 
589
- def compute_ostree_upstream_sync_depth
590
- if ostree_upstream_sync_policy == OSTREE_UPSTREAM_SYNC_POLICY_CUSTOM
591
- ostree_upstream_sync_depth
592
- elsif ostree_upstream_sync_policy == OSTREE_UPSTREAM_SYNC_POLICY_ALL
593
- -1
594
- else
595
- 0
596
- end
597
- end
598
-
599
484
  def ostree_capsule_sync_depth
600
485
  -1
601
486
  end
@@ -750,7 +635,7 @@ module Katello
750
635
  def component_source_repositories
751
636
  #find other copies of this repositories, in the CV version's components, that are in the 'archive'
752
637
  Katello::Repository.where(:content_view_version_id => self.content_view_version.components, :environment_id => nil,
753
- :library_instance_id => self.library_instance_id)
638
+ :root_id => self.root_id)
754
639
  end
755
640
 
756
641
  def self.linked_repositories
@@ -765,12 +650,13 @@ module Katello
765
650
  value = value == 'true'
766
651
  value = !value if operator == '<>'
767
652
 
768
- product_ids = Katello::Product.redhat.pluck(:id)
653
+ product_ids = Katello::Product.redhat.select(:id)
654
+ root_ids = Katello::RootRepository.where(:product_id => product_ids).pluck(:id)
769
655
  if product_ids.empty?
770
656
  {:conditions => "1=0"}
771
657
  else
772
658
  operator = value ? 'IN' : 'NOT IN'
773
- {:conditions => "#{Katello::Repository.table_name}.product_id #{operator} (#{product_ids.join(',')})"}
659
+ {:conditions => "#{Katello::Repository.table_name}.root_id #{operator} (#{root_ids.join(',')})"}
774
660
  end
775
661
  end
776
662
 
@@ -799,6 +685,23 @@ module Katello
799
685
  name.gsub(/[^-\/\w]/, "_").gsub(/_{3,}/, "_").gsub(/-_|^_+|_+$/, "").downcase.strip
800
686
  end
801
687
 
688
+ def custom_repo_path
689
+ return custom_docker_repo_path if docker?
690
+ if [environment, product, root.label].any?(&:nil?)
691
+ return nil # can't generate valid path
692
+ end
693
+ prefix = [environment.organization.label, environment.label].map { |x| x.gsub(/[^-\w]/, "_") }.join("/")
694
+ prefix + root.custom_content_path
695
+ end
696
+
697
+ def custom_docker_repo_path
698
+ if [environment, product, root.label].any?(&:nil?)
699
+ return nil # can't generate valid path
700
+ end
701
+ parts = [environment.organization.label, product.label, root.label]
702
+ parts.map { |x| x.gsub(/[^-\w]/, "_") }.join("-").downcase
703
+ end
704
+
802
705
  protected
803
706
 
804
707
  def removable_unit_association
@@ -827,44 +730,6 @@ module Katello
827
730
  end
828
731
  end
829
732
 
830
- def ensure_compatible_download_policy
831
- if library_instance? && !url.blank? && URI(url).scheme == 'file' &&
832
- [::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND, ::Runcible::Models::YumImporter::DOWNLOAD_BACKGROUND].include?(download_policy)
833
- errors.add(:download_policy, N_("Cannot sync file:// repositories with On Demand or Background Download Policies"))
834
- end
835
- end
836
-
837
- def ensure_valid_docker_attributes
838
- if library_instance? && (!url.blank? && docker_upstream_name.blank?)
839
- errors.add(:docker_upstream_name, N_("cannot be blank when Repository URL is provided."))
840
- errors.add(:base, N_("Upstream Name cannot be blank when Repository URL is provided."))
841
- end
842
- end
843
-
844
- def ensure_docker_repo_unprotected
845
- unless unprotected
846
- errors.add(:base, N_("Container Image Repositories are not protected at this time. " \
847
- "They need to be published via http to be available to containers."))
848
- end
849
- end
850
-
851
- def ensure_no_download_policy
852
- if !yum? && download_policy.present?
853
- errors.add(:download_policy, N_("cannot be set for non-yum repositories."))
854
- end
855
- end
856
-
857
- def ensure_has_url_for_ostree
858
- return true if url.present? || library_instance_id
859
- errors.add(:url, N_("cannot be blank. RPM OSTree Repository URL required for syncing from the upstream."))
860
- end
861
-
862
- def ensure_ostree_repo_protected
863
- if unprotected
864
- errors.add(:base, N_("OSTree Repositories cannot be unprotected."))
865
- end
866
- end
867
-
868
733
  def remove_docker_content(manifests)
869
734
  destroyable_manifests = manifests.select do |manifest|
870
735
  manifest.repositories.empty? || manifest.docker_manifest_lists.empty?
@@ -877,35 +742,6 @@ module Katello
877
742
  DockerMetaTag.cleanup_tags
878
743
  end
879
744
 
880
- def update_ostree_upstream_sync_policy
881
- return unless ostree?
882
- if self.ostree_upstream_sync_policy.blank?
883
- self.ostree_upstream_sync_policy = OSTREE_UPSTREAM_SYNC_POLICY_LATEST
884
- end
885
-
886
- if self.ostree_upstream_sync_policy_changed? &&
887
- previous_changes[:ostree_upstream_sync_policy].present?
888
- self.ostree_upstream_sync_depth = nil unless self.ostree_upstream_sync_policy == OSTREE_UPSTREAM_SYNC_POLICY_CUSTOM
889
- end
890
- end
891
-
892
- def ensure_no_ostree_upstream_sync_policy
893
- if !ostree? && ostree_upstream_sync_policy.present?
894
- errors.add(:ostree_upstream_sync_policy, N_("cannot be set for non-ostree repositories."))
895
- end
896
- end
897
-
898
- def ensure_valid_ignorable_content
899
- return if ignorable_content.blank?
900
- if !yum?
901
- errors.add(:ignorable_content, N_("Ignorable content can be only set for Yum repositories."))
902
- elsif !ignorable_content.is_a?(Array)
903
- errors.add(:ignorable_content, N_("Invalid value specified for ignorable content."))
904
- elsif ignorable_content.any? { |item| !IGNORABLE_CONTENT_UNIT_TYPES.include?(item) }
905
- errors.add(:ignorable_content, N_("Invalid value specified for ignorable content. Permissible values %s") % IGNORABLE_CONTENT_UNIT_TYPES.join(","))
906
- end
907
- end
908
-
909
745
  class Jail < ::Safemode::Jail
910
746
  allow :name, :label, :docker_upstream_name, :url
911
747
  end