katello 3.6.0.1.rc2 → 3.7.0.rc1

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

Potentially problematic release.


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

Files changed (530) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/hosts/activation_key_edit.js +2 -2
  3. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +6 -4
  4. data/app/controllers/katello/api/v2/activation_keys_controller.rb +1 -3
  5. data/app/controllers/katello/api/v2/api_controller.rb +13 -3
  6. data/app/controllers/katello/api/v2/content_credentials_controller.rb +116 -0
  7. data/app/controllers/katello/api/v2/content_view_filter_rules_controller.rb +1 -1
  8. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +6 -0
  9. data/app/controllers/katello/api/v2/content_views_controller.rb +2 -1
  10. data/app/controllers/katello/api/v2/environments_controller.rb +20 -3
  11. data/app/controllers/katello/api/v2/gpg_keys_controller.rb +5 -0
  12. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +14 -7
  13. data/app/controllers/katello/api/v2/products_controller.rb +31 -1
  14. data/app/controllers/katello/api/v2/repositories_controller.rb +103 -34
  15. data/app/controllers/katello/api/v2/repository_sets_controller.rb +22 -15
  16. data/app/controllers/katello/api/v2/subscriptions_controller.rb +31 -7
  17. data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +93 -0
  18. data/app/controllers/katello/concerns/api/v2/repository_content_controller.rb +2 -2
  19. data/app/helpers/katello/katello_urls_helper.rb +21 -4
  20. data/app/jobs/create_pulp_disk_space_notifications.rb +4 -0
  21. data/app/jobs/send_expire_soon_notifications.rb +13 -0
  22. data/app/lib/actions/candlepin/import_pool_handler.rb +5 -4
  23. data/app/lib/actions/candlepin/owner/import_products.rb +4 -2
  24. data/app/lib/actions/helpers/notifications.rb +35 -0
  25. data/app/lib/actions/katello/capsule_content/sync.rb +12 -1
  26. data/app/lib/actions/katello/content_view/{capsule_generate_and_sync.rb → capsule_sync.rb} +1 -1
  27. data/app/lib/actions/katello/content_view/promote_to_environment.rb +1 -1
  28. data/app/lib/actions/katello/content_view/publish.rb +40 -11
  29. data/app/lib/actions/katello/content_view/remove.rb +2 -2
  30. data/app/lib/actions/katello/environment/publish_repositories.rb +41 -0
  31. data/app/lib/actions/katello/event_queue/poller_thread.rb +10 -8
  32. data/app/lib/actions/katello/host/attach_subscriptions.rb +1 -1
  33. data/app/lib/actions/katello/host/remove_subscriptions.rb +1 -1
  34. data/app/lib/actions/katello/organization/manifest_delete.rb +22 -0
  35. data/app/lib/actions/katello/organization/manifest_import.rb +22 -0
  36. data/app/lib/actions/katello/organization/manifest_refresh.rb +22 -0
  37. data/app/lib/actions/katello/product/create.rb +3 -6
  38. data/app/lib/actions/katello/product/reindex_subscriptions.rb +3 -4
  39. data/app/lib/actions/katello/repository/{capsule_generate_and_sync.rb → capsule_sync.rb} +1 -1
  40. data/app/lib/actions/katello/repository/clone_yum_metadata.rb +2 -1
  41. data/app/lib/actions/katello/repository/create.rb +2 -1
  42. data/app/lib/actions/katello/repository/filtered_index_content.rb +2 -0
  43. data/app/lib/actions/katello/repository/import_upload.rb +38 -6
  44. data/app/lib/actions/katello/repository/remove_content.rb +1 -1
  45. data/app/lib/actions/katello/repository/sync.rb +8 -1
  46. data/app/lib/actions/katello/repository/sync_hook.rb +11 -0
  47. data/app/lib/actions/katello/repository/update.rb +4 -1
  48. data/app/lib/actions/katello/sync_plan/add_products.rb +1 -1
  49. data/app/lib/actions/katello/upstream_subscriptions/bind_entitlement.rb +31 -0
  50. data/app/lib/actions/katello/upstream_subscriptions/bind_entitlements.rb +28 -0
  51. data/app/lib/actions/katello/upstream_subscriptions/remove_entitlement.rb +22 -0
  52. data/app/lib/actions/katello/upstream_subscriptions/remove_entitlements.rb +35 -0
  53. data/app/lib/actions/katello/upstream_subscriptions/update_entitlement.rb +23 -0
  54. data/app/lib/actions/katello/upstream_subscriptions/update_entitlements.rb +37 -0
  55. data/app/lib/actions/middleware/execute_if_contents_changed.rb +1 -1
  56. data/app/lib/actions/pulp/repository/create.rb +3 -0
  57. data/app/lib/actions/pulp/repository/ensure_sync_notification.rb +11 -0
  58. data/app/lib/actions/pulp/repository/import_upload.rb +2 -2
  59. data/app/lib/katello/resources/candlepin.rb +68 -801
  60. data/app/lib/katello/resources/candlepin/activation_key.rb +101 -0
  61. data/app/lib/katello/resources/candlepin/c_p_user.rb +17 -0
  62. data/app/lib/katello/resources/candlepin/candlepin_ping.rb +19 -0
  63. data/app/lib/katello/resources/candlepin/consumer.rb +204 -0
  64. data/app/lib/katello/resources/candlepin/content.rb +36 -0
  65. data/app/lib/katello/resources/candlepin/entitlement.rb +22 -0
  66. data/app/lib/katello/resources/candlepin/environment.rb +44 -0
  67. data/app/lib/katello/resources/candlepin/job.rb +25 -0
  68. data/app/lib/katello/resources/candlepin/owner.rb +130 -0
  69. data/app/lib/katello/resources/candlepin/owner_info.rb +18 -0
  70. data/app/lib/katello/resources/candlepin/pool.rb +39 -0
  71. data/app/lib/katello/resources/candlepin/product.rb +116 -0
  72. data/app/lib/katello/resources/candlepin/proxy.rb +41 -0
  73. data/app/lib/katello/resources/candlepin/subscription.rb +31 -0
  74. data/app/lib/katello/resources/candlepin/upstream_consumer.rb +41 -0
  75. data/app/lib/katello/resources/candlepin/upstream_entitlement.rb +19 -0
  76. data/app/lib/katello/resources/candlepin/upstream_owner.rb +15 -0
  77. data/app/lib/katello/resources/candlepin/upstream_pool.rb +17 -0
  78. data/app/lib/katello/util/data.rb +2 -4
  79. data/app/lib/katello/util/http_proxy.rb +29 -0
  80. data/app/lib/katello/util/model.rb +1 -1
  81. data/app/lib/katello/validators/container_image_name_validator.rb +18 -0
  82. data/app/lib/katello/validators/content_view_environment_org_validator.rb +14 -0
  83. data/app/lib/katello/validators/environment_docker_repositories_validator.rb +71 -0
  84. data/app/lib/katello/validators/gpg_key_content_type_validator.rb +22 -0
  85. data/app/models/katello/activation_key.rb +4 -2
  86. data/app/models/katello/authorization/content_view_history.rb +0 -1
  87. data/app/models/katello/authorization/pool.rb +0 -2
  88. data/app/models/katello/authorization/repository.rb +0 -2
  89. data/app/models/katello/capsule_lifecycle_environment.rb +2 -0
  90. data/app/models/katello/compliance_reason.rb +5 -0
  91. data/app/models/katello/concerns/content_facet_host_extensions.rb +5 -1
  92. data/app/models/katello/concerns/organization_extensions.rb +22 -0
  93. data/app/models/katello/concerns/smart_proxy_extensions.rb +3 -2
  94. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +2 -0
  95. data/app/models/katello/content.rb +5 -0
  96. data/app/models/katello/content_facet_applicable_rpm.rb +1 -0
  97. data/app/models/katello/content_view.rb +50 -82
  98. data/app/models/katello/content_view_component.rb +1 -0
  99. data/app/models/katello/content_view_docker_filter_rule.rb +0 -1
  100. data/app/models/katello/content_view_environment.rb +5 -3
  101. data/app/models/katello/content_view_filter.rb +2 -1
  102. data/app/models/katello/content_view_history.rb +3 -0
  103. data/app/models/katello/content_view_puppet_environment.rb +12 -0
  104. data/app/models/katello/content_view_puppet_module.rb +1 -0
  105. data/app/models/katello/content_view_version.rb +18 -1
  106. data/app/models/katello/docker_manifest.rb +2 -1
  107. data/app/models/katello/docker_manifest_list.rb +2 -1
  108. data/app/models/katello/docker_meta_tag.rb +22 -1
  109. data/app/models/katello/erratum.rb +17 -5
  110. data/app/models/katello/event.rb +2 -0
  111. data/app/models/katello/glue/candlepin/activation_key.rb +2 -2
  112. data/app/models/katello/glue/candlepin/candlepin_object.rb +7 -6
  113. data/app/models/katello/glue/candlepin/owner.rb +4 -3
  114. data/app/models/katello/glue/candlepin/pool.rb +51 -20
  115. data/app/models/katello/glue/candlepin/product.rb +3 -2
  116. data/app/models/katello/glue/candlepin/subscription.rb +16 -35
  117. data/app/models/katello/glue/pulp/repo.rb +26 -6
  118. data/app/models/katello/glue/pulp/repos.rb +6 -3
  119. data/app/models/katello/gpg_key.rb +29 -4
  120. data/app/models/katello/host/content_facet.rb +5 -3
  121. data/app/models/katello/host/subscription_facet.rb +55 -23
  122. data/app/models/katello/host_collection.rb +1 -0
  123. data/app/models/katello/host_collection_hosts.rb +1 -1
  124. data/app/models/katello/installed_package.rb +4 -0
  125. data/app/models/katello/installed_product.rb +33 -0
  126. data/app/models/katello/key_host_collection.rb +2 -2
  127. data/app/models/katello/kt_environment.rb +8 -0
  128. data/app/models/katello/ostree_branch.rb +1 -1
  129. data/app/models/katello/ping.rb +1 -0
  130. data/app/models/katello/pool.rb +13 -7
  131. data/app/models/katello/pool_product.rb +6 -0
  132. data/app/models/katello/product.rb +16 -6
  133. data/app/models/katello/product_content.rb +4 -0
  134. data/app/models/katello/pulp_task_status.rb +0 -46
  135. data/app/models/katello/repository.rb +96 -19
  136. data/app/models/katello/repository_docker_manifest.rb +1 -1
  137. data/app/models/katello/repository_docker_manifest_list.rb +1 -1
  138. data/app/models/katello/repository_ostree_branch.rb +1 -1
  139. data/app/models/katello/rhsm_fact_importer.rb +2 -17
  140. data/app/models/katello/subscription.rb +5 -5
  141. data/app/models/katello/subscription_facet_installed_product.rb +6 -0
  142. data/app/models/katello/subscription_facet_pool.rb +2 -0
  143. data/app/models/katello/sync_plan.rb +1 -0
  144. data/app/models/katello/upstream_pool.rb +112 -0
  145. data/app/models/setting/content.rb +11 -7
  146. data/app/services/katello/candlepin/consumer.rb +9 -2
  147. data/app/services/katello/candlepin/message_handler.rb +18 -35
  148. data/app/services/katello/candlepin/pool_service.rb +17 -0
  149. data/app/services/katello/event_queue.rb +11 -6
  150. data/app/services/katello/pulp/server.rb +3 -1
  151. data/app/services/katello/registration_manager.rb +9 -2
  152. data/app/services/katello/repository_type_manager.rb +2 -1
  153. data/app/services/katello/ui_notifications/abstract_notification.rb +29 -0
  154. data/app/services/katello/ui_notifications/content_view/auto_publish_failure.rb +22 -0
  155. data/app/services/katello/ui_notifications/pulp/proxy_disk_space.rb +3 -4
  156. data/app/services/katello/ui_notifications/subscriptions/expire_soon.rb +65 -0
  157. data/app/services/katello/ui_notifications/subscriptions/manifest_delete_error.rb +13 -0
  158. data/app/services/katello/ui_notifications/subscriptions/manifest_delete_success.rb +13 -0
  159. data/app/services/katello/ui_notifications/subscriptions/manifest_import_error.rb +13 -0
  160. data/app/services/katello/ui_notifications/subscriptions/manifest_import_success.rb +13 -0
  161. data/app/services/katello/ui_notifications/subscriptions/manifest_refresh_error.rb +13 -0
  162. data/app/services/katello/ui_notifications/subscriptions/manifest_refresh_success.rb +13 -0
  163. data/app/services/katello/ui_notifications/task_notification.rb +26 -0
  164. data/app/views/foreman/job_templates/install_errata.erb +7 -2
  165. data/app/views/foreman/job_templates/install_errata_-_katello_ansible_default.erb +18 -0
  166. data/app/views/foreman/job_templates/install_group_-_katello_ansible_default.erb +16 -0
  167. data/app/views/foreman/job_templates/install_package_-_katello_ansible_default.erb +16 -0
  168. data/app/views/foreman/job_templates/remove_group_-_katello_ansible_default.erb +16 -0
  169. data/app/views/foreman/job_templates/remove_package_-_katello_ansible_default.erb +16 -0
  170. data/app/views/foreman/job_templates/restart_services_-_katello_ansible_default.erb +20 -0
  171. data/app/views/foreman/job_templates/update_group_-_katello_ansible_default.erb +16 -0
  172. data/app/views/foreman/job_templates/update_package_-_katello_ansible_default.erb +16 -0
  173. data/app/views/foreman/smart_proxies/_content_tab.html.erb +1 -1
  174. data/app/views/katello/api/v2/content_credentials/index.json.rabl +3 -0
  175. data/app/views/katello/api/v2/content_credentials/show.json.rabl +101 -0
  176. data/app/views/katello/api/v2/content_view_histories/show.json.rabl +13 -1
  177. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -0
  178. data/app/views/katello/api/v2/environments/show.json.rabl +1 -0
  179. data/app/views/katello/api/v2/errata/{available_errata.rabl → available_errata.json.rabl} +0 -0
  180. data/app/views/katello/api/v2/errata/show.json.rabl +4 -0
  181. data/app/views/katello/api/v2/products/_product_content.json.rabl +6 -6
  182. data/app/views/katello/api/v2/products/base.json.rabl +3 -0
  183. data/app/views/katello/api/v2/products/show.json.rabl +12 -0
  184. data/app/views/katello/api/v2/repositories/base.json.rabl +2 -1
  185. data/app/views/katello/api/v2/repositories/show.json.rabl +19 -5
  186. data/app/views/katello/api/v2/subscription_facet/show.json.rabl +10 -14
  187. data/app/views/katello/api/v2/subscriptions/base.json.rabl +2 -1
  188. data/app/views/katello/api/v2/upstream_subscriptions/base.json.rabl +18 -0
  189. data/app/views/katello/api/v2/upstream_subscriptions/index.json.rabl +7 -0
  190. data/app/views/katello/sync_management/_products.html.erb +1 -1
  191. data/config/katello.yaml.example +10 -0
  192. data/config/routes.rb +3 -14
  193. data/config/routes/api/rhsm.rb +1 -0
  194. data/config/routes/api/v2.rb +16 -0
  195. data/db/migrate/20161014133811_move_content_view_version_description_to_histories.rb +2 -1
  196. data/db/migrate/20161214151548_move_content_source_id_to_content_facets.rb +2 -2
  197. data/db/migrate/20171110082124_add_ssl_certs_to_products_and_repos.rb +42 -0
  198. data/db/migrate/20171214050230_add_auto_publish_to_content_views.rb +5 -0
  199. data/db/migrate/20180117202932_sub_facet_add_installed_products.rb +20 -0
  200. data/db/migrate/20180119152210_add_compliance_reasons.rb +11 -0
  201. data/db/migrate/20180207232901_add_triggered_by_to_content_view_history.rb +7 -0
  202. data/db/migrate/20180218191449_add_manifest_refreshed_at_to_organization.rb +9 -0
  203. data/db/migrate/20180227094827_use_uuid_for_task_id.rb +26 -0
  204. data/db/migrate/20180323175122_add_registry_name_pattern_to_environment.rb +11 -0
  205. data/db/migrate/20180326145716_subscription_cp_id_change.rb +10 -0
  206. data/db/migrate/20180326150339_move_stacking_id.rb +25 -0
  207. data/db/migrate/20180326190408_move_subscription_products.rb +75 -0
  208. data/db/migrate/20180402160223_clean_up_force_post_sync_action_setting.rb +5 -0
  209. data/db/migrate/20180410140909_add_organization_id_to_pool.rb +15 -0
  210. data/db/migrate/20180413153126_content_facet_applicable_rpms_index.rb +5 -0
  211. data/db/migrate/20180417031215_add_ignorable_content_to_repository.rb +5 -0
  212. data/db/migrate/20180521200848_drop_repo_rpms_timestamp_not_null.rb +18 -0
  213. data/db/seeds.d/109-katello-notification-blueprints.rb +42 -0
  214. data/db/seeds.d/110-content-view-autopublish.rb +15 -0
  215. data/db/seeds.d/75-job_templates.rb +3 -1
  216. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-add-subscriptions.controller.js +1 -1
  217. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-details-info.controller.js +34 -3
  218. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-subscriptions.controller.js +1 -0
  219. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-info.html +3 -1
  220. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/bastion-katello-bootstrap.js +1 -1
  221. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/bastion_katello.js +2 -2
  222. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/subscription-add-or-remove.html +2 -2
  223. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credential.factory.js +83 -0
  224. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/{gpg-keys/gpg-keys.controller.js → content-credentials/content-credentials.controller.js} +8 -8
  225. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/{gpg-keys/gpg-keys.module.js → content-credentials/content-credentials.module.js} +3 -3
  226. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credentials.routes.js +76 -0
  227. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-type.filter.js +25 -0
  228. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/{gpg-keys/details/gpg-key-details-info.controller.js → content-credentials/details/content-credential-details-info.controller.js} +10 -10
  229. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-details.controller.js +48 -0
  230. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-products.controller.js +36 -0
  231. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-repositories.controller.js +36 -0
  232. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/views/content-credential-details.html +36 -0
  233. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/{gpg-keys/details/views/gpg-key-info.html → content-credentials/details/views/content-credential-info.html} +21 -12
  234. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/{gpg-keys/details/views/gpg-key-products.html → content-credentials/details/views/content-credential-products.html} +6 -2
  235. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/{gpg-keys/details/views/gpg-key-repositories.html → content-credentials/details/views/content-credential-repositories.html} +6 -4
  236. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/new/new-content-credential.controller.js +39 -0
  237. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/new/views/new-content-credential.html +53 -0
  238. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/views/content-credentials.html +55 -0
  239. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-errata-modal.controller.js +31 -19
  240. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-host-collections-modal.controller.js +0 -1
  241. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-packages-modal.controller.js +4 -1
  242. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-environment-modal.html +2 -2
  243. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-errata-modal.html +108 -1
  244. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-host-collections-modal.html +2 -2
  245. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-packages-modal.html +2 -2
  246. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-subscriptions-modal.html +1 -1
  247. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-errata.controller.js +3 -3
  248. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-errata.html +9 -9
  249. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-applicable.html +1 -1
  250. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-installed.html +1 -1
  251. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-add-subscriptions.controller.js +1 -2
  252. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-subscriptions.controller.js +1 -1
  253. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-details.html +1 -1
  254. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +4 -4
  255. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-repository-sets.html +1 -1
  256. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +1 -1
  257. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/register.html +14 -4
  258. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/components/content-view-composite-available-content-views.controller.js +7 -4
  259. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-available-deb-repositories.controller.js +4 -2
  260. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-available-docker-repositories.controller.js +5 -3
  261. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-available-file-repositories.controller.js +4 -2
  262. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-available-ostree-repositories.controller.js +5 -3
  263. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-available-repositories.controller.js +4 -2
  264. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-deb-repositories-list.controller.js +4 -2
  265. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-details.controller.js +4 -2
  266. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-docker-repositories-list.controller.js +4 -2
  267. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-file-repositories-list.controller.js +4 -2
  268. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-ostree-repositories-list.controller.js +4 -2
  269. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-repositories-list.controller.js +4 -2
  270. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-versions.controller.js +5 -3
  271. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/date-type-errata-filter.controller.js +8 -9
  272. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/filter-helper.service.js +1 -1
  273. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/new-filter.controller.js +1 -1
  274. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/views/date-type-errata.html +6 -2
  275. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/views/docker-filter.html +1 -1
  276. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/views/new-filter.html +1 -1
  277. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/histories/content-view-history.controller.js +2 -2
  278. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/puppet-modules/content-view-puppet-modules.controller.js +5 -1
  279. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-details.html +8 -7
  280. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-docker-repositories.html +3 -3
  281. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-info.html +14 -0
  282. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-versions.html +12 -4
  283. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/new/views/content-view-new.html +16 -0
  284. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/content-view-version-content.controller.js +2 -1
  285. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version-errata.html +2 -2
  286. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version.html +2 -2
  287. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/details/views/docker-tag-details.html +1 -1
  288. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/details/views/docker-tag-environments.html +1 -1
  289. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/details/views/docker-tag-info.html +1 -1
  290. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/docker-tags.routes.js +2 -2
  291. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/views/docker-tags.html +4 -4
  292. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/content.service.js +1 -1
  293. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/environment.controller.js +3 -2
  294. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-details.html +8 -0
  295. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-docker.html +9 -5
  296. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-errata.html +2 -2
  297. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment.html +2 -1
  298. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/views/environments.html +18 -6
  299. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum-content-hosts.controller.js +22 -8
  300. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum-repositories.controller.js +18 -2
  301. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-content-hosts.html +3 -3
  302. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-repositories.html +1 -1
  303. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/incremental-update.service.js +3 -2
  304. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/views/apply-errata-confirm.html +17 -6
  305. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/views/errata.html +2 -2
  306. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/README +4 -0
  307. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +3465 -1541
  308. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/translations.js +10 -10
  309. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/katello-features.run.js +5 -5
  310. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/organizations/fenced-pages.service.js +1 -1
  311. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/ostree-branch-repositories.controller.js +18 -2
  312. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/views/ostree-branch-repositories.html +1 -1
  313. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/details/package-repositories.controller.js +18 -2
  314. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/details/views/package-info.html +2 -2
  315. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/details/views/package-repositories.html +1 -1
  316. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/details/views/package.html +2 -2
  317. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/packages.routes.js +1 -1
  318. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/views/packages.html +1 -1
  319. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/product-details-info.controller.js +32 -5
  320. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +34 -13
  321. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.filter.js +16 -0
  322. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-manage-content.controller.js +15 -2
  323. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +42 -4
  324. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-manage-debs.html +2 -2
  325. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-manage-docker-manifest-lists.html +2 -2
  326. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-manage-docker-manifests.html +7 -7
  327. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-manage-docker-tags.html +47 -0
  328. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-manage-files.html +1 -1
  329. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-manage-packages.html +1 -1
  330. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +10 -8
  331. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +43 -5
  332. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repositories.routes.js +11 -2
  333. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository-types.service.js +39 -0
  334. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/views/product-repositories.html +6 -6
  335. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/yum-content-units.service.js +24 -0
  336. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/views/product-info.html +24 -0
  337. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery-create.controller.js +7 -7
  338. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery.controller.js +1 -1
  339. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/views/discovery-create.html +3 -3
  340. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/new/product-form.controller.js +7 -7
  341. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/new/views/product-new-form.html +29 -2
  342. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +9 -3
  343. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.module.js +1 -1
  344. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/views/products.html +2 -1
  345. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/details/subscription-details.controller.js +1 -1
  346. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/manifest/manifest-import.controller.js +12 -3
  347. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/manifest/views/manifest-delete-modal.html +1 -1
  348. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/manifest/views/manifest-import.html +2 -2
  349. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/task.factory.js +4 -7
  350. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/tasks-nutupane.factory.js +6 -1
  351. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/tasks-table.directive.js +6 -3
  352. data/engines/bastion_katello/lib/bastion_katello/engine.rb +1 -1
  353. data/lib/katello/apipie/validators.rb +0 -56
  354. data/lib/katello/engine.rb +6 -43
  355. data/lib/katello/permission_creator.rb +31 -4
  356. data/lib/katello/plugin.rb +124 -73
  357. data/lib/katello/scheduled_jobs.rb +10 -4
  358. data/lib/katello/tasks/job_templates.rake +16 -0
  359. data/lib/katello/tasks/reset.rake +0 -3
  360. data/lib/katello/tasks/upgrades/3.6/import_backend_consumer_attributes.rake +32 -0
  361. data/lib/katello/tasks/upgrades/3.7/make_all_ks_repos_bootable.rake +11 -0
  362. data/lib/katello/version.rb +1 -1
  363. data/locale/action_names.rb +52 -48
  364. data/locale/katello.pot +3136 -1999
  365. data/package.json +83 -0
  366. data/webpack/__mocks__/foremanReact/common/helpers.js +5 -0
  367. data/webpack/__mocks__/foremanReact/components/common/table.js +6 -0
  368. data/webpack/__mocks__/react-bootstrap-tooltip-button.js +6 -0
  369. data/webpack/components/MultiSelect/index.js +35 -0
  370. data/webpack/components/PaginationRow/PaginationRow.test.js +25 -0
  371. data/webpack/components/PaginationRow/__snapshots__/PaginationRow.test.js.snap +35 -0
  372. data/webpack/components/PaginationRow/index.js +90 -0
  373. data/webpack/components/Search/Search.test.js +20 -0
  374. data/webpack/components/Search/__snapshots__/Search.test.js.snap +18 -0
  375. data/webpack/components/Search/helpers.js +6 -0
  376. data/webpack/components/Search/index.js +86 -0
  377. data/webpack/containers/Application/Routes.js +11 -0
  378. data/webpack/containers/Application/config.js +21 -0
  379. data/webpack/containers/Application/index.js +39 -0
  380. data/webpack/containers/Application/overrides.scss +38 -0
  381. data/webpack/index.js +18 -0
  382. data/webpack/mockRequest.js +32 -0
  383. data/webpack/move_to_foreman/Settings/SettingsActions.js +28 -0
  384. data/webpack/move_to_foreman/Settings/SettingsConstants.js +3 -0
  385. data/webpack/move_to_foreman/Settings/__tests__/SettingsActions.test.js +41 -0
  386. data/webpack/move_to_foreman/Settings/__tests__/settings.fixtures.js +34 -0
  387. data/webpack/move_to_foreman/__mocks__/foreman_toast_notifications.js +3 -0
  388. data/webpack/move_to_foreman/common/helpers.js +36 -0
  389. data/webpack/move_to_foreman/components/common/ConfirmDialog/ConfirmDialog.js +50 -0
  390. data/webpack/move_to_foreman/components/common/ConfirmDialog/__tests__/ConfirmDialog.test.js +40 -0
  391. data/webpack/move_to_foreman/components/common/ConfirmDialog/__tests__/__snapshots__/ConfirmDialog.test.js.snap +125 -0
  392. data/webpack/move_to_foreman/components/common/ConfirmDialog/index.js +3 -0
  393. data/webpack/move_to_foreman/components/common/Dialog/Dialog.js +65 -0
  394. data/webpack/move_to_foreman/components/common/Dialog/__tests__/Dialog.test.js +61 -0
  395. data/webpack/move_to_foreman/components/common/Dialog/__tests__/__snapshots__/Dialog.test.js.snap +349 -0
  396. data/webpack/move_to_foreman/components/common/Dialog/index.js +3 -0
  397. data/webpack/move_to_foreman/components/common/ModalProgressBar/ModalProgressBar.js +43 -0
  398. data/webpack/move_to_foreman/components/common/ModalProgressBar/ModalProgressBar.scss +15 -0
  399. data/webpack/move_to_foreman/components/common/ModalProgressBar/__tests__/ModalProgressBar.test.js +22 -0
  400. data/webpack/move_to_foreman/components/common/ModalProgressBar/__tests__/__snapshots__/ModalProgressBar.test.js.snap +60 -0
  401. data/webpack/move_to_foreman/components/common/ModalProgressBar/index.js +4 -0
  402. data/webpack/move_to_foreman/components/common/emptyState/index.js +49 -0
  403. data/webpack/move_to_foreman/components/common/table/index.js +88 -0
  404. data/webpack/move_to_foreman/foreman_toast_notifications.js +22 -0
  405. data/webpack/move_to_pf/TypeAhead/TypeAhead.js +125 -0
  406. data/webpack/move_to_pf/TypeAhead/TypeAhead.scss +7 -0
  407. data/webpack/move_to_pf/TypeAhead/TypeAheadInput.js +47 -0
  408. data/webpack/move_to_pf/TypeAhead/TypeAheadItems.js +60 -0
  409. data/webpack/move_to_pf/TypeAhead/helpers.js +5 -0
  410. data/webpack/move_to_pf/react-bootstrap-select/index.js +65 -0
  411. data/webpack/redux/actions/RedHatRepositories/enabled.js +53 -0
  412. data/webpack/redux/actions/RedHatRepositories/helpers.js +38 -0
  413. data/webpack/redux/actions/RedHatRepositories/repositorySetRepositories.js +50 -0
  414. data/webpack/redux/actions/RedHatRepositories/sets.js +42 -0
  415. data/webpack/redux/consts.js +18 -0
  416. data/webpack/redux/index.js +9 -0
  417. data/webpack/redux/reducers/RedHatRepositories/enabled.fixtures.js +149 -0
  418. data/webpack/redux/reducers/RedHatRepositories/enabled.js +80 -0
  419. data/webpack/redux/reducers/RedHatRepositories/enabled.test.js +36 -0
  420. data/webpack/redux/reducers/RedHatRepositories/filters.fixtures.js +5 -0
  421. data/webpack/redux/reducers/RedHatRepositories/index.js +10 -0
  422. data/webpack/redux/reducers/RedHatRepositories/repositorySetRepositories.fixtures.js +135 -0
  423. data/webpack/redux/reducers/RedHatRepositories/repositorySetRepositories.js +97 -0
  424. data/webpack/redux/reducers/RedHatRepositories/repositorySetRepositories.test.js +66 -0
  425. data/webpack/redux/reducers/RedHatRepositories/sets.fixtures.js +123 -0
  426. data/webpack/redux/reducers/RedHatRepositories/sets.js +41 -0
  427. data/webpack/redux/reducers/RedHatRepositories/sets.test.js +36 -0
  428. data/webpack/redux/reducers/index.js +14 -0
  429. data/webpack/scenes/Organizations/OrganizationActions.js +60 -0
  430. data/webpack/scenes/Organizations/OrganizationConstants.js +7 -0
  431. data/webpack/scenes/Organizations/OrganizationReducer.js +32 -0
  432. data/webpack/scenes/Organizations/__tests__/OrganizationActions.test.js +59 -0
  433. data/webpack/scenes/Organizations/__tests__/OrganizationReducer.test.js +56 -0
  434. data/webpack/scenes/Organizations/__tests__/organizations.fixtures.js +99 -0
  435. data/webpack/scenes/RedHatRepositories/components/EnabledRepository.js +114 -0
  436. data/webpack/scenes/RedHatRepositories/components/EnabledRepository.stories.js +13 -0
  437. data/webpack/scenes/RedHatRepositories/components/RepositorySet.js +35 -0
  438. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepositories.js +64 -0
  439. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository.js +127 -0
  440. data/webpack/scenes/RedHatRepositories/components/RepositoryTypeIcon.js +33 -0
  441. data/webpack/scenes/RedHatRepositories/components/Search.js +91 -0
  442. data/webpack/scenes/RedHatRepositories/components/SearchBar.js +145 -0
  443. data/webpack/scenes/RedHatRepositories/components/__tests__/RepositoryTypeIcon.test.js +28 -0
  444. data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/RepositoryTypeIcon.test.js.snap +143 -0
  445. data/webpack/scenes/RedHatRepositories/helpers.js +72 -0
  446. data/webpack/scenes/RedHatRepositories/index.js +91 -0
  447. data/webpack/scenes/RedHatRepositories/index.scss +63 -0
  448. data/webpack/scenes/Subscriptions/EntitlementsInlineEditFormatter.js +87 -0
  449. data/webpack/scenes/Subscriptions/Manifest/DeleteManifestModalText.js +22 -0
  450. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +243 -0
  451. data/webpack/scenes/Subscriptions/Manifest/Manifest.scss +3 -0
  452. data/webpack/scenes/Subscriptions/Manifest/ManifestActions.js +114 -0
  453. data/webpack/scenes/Subscriptions/Manifest/ManifestConstants.js +15 -0
  454. data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryReducer.js +34 -0
  455. data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryTableSchema.js +46 -0
  456. data/webpack/scenes/Subscriptions/Manifest/__tests__/ManageManifestModal.test.js +26 -0
  457. data/webpack/scenes/Subscriptions/Manifest/__tests__/ManifestActions.test.js +113 -0
  458. data/webpack/scenes/Subscriptions/Manifest/__tests__/ManifestHistoryReducer.test.js +36 -0
  459. data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +363 -0
  460. data/webpack/scenes/Subscriptions/Manifest/__tests__/manifest.fixtures.js +216 -0
  461. data/webpack/scenes/Subscriptions/Manifest/index.js +28 -0
  462. data/webpack/scenes/Subscriptions/SubscriptionActions.js +119 -0
  463. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +27 -0
  464. data/webpack/scenes/Subscriptions/SubscriptionHelpers.js +3 -0
  465. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +123 -0
  466. data/webpack/scenes/Subscriptions/SubscriptionValidations.js +25 -0
  467. data/webpack/scenes/Subscriptions/Subscriptions.scss +14 -0
  468. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +275 -0
  469. data/webpack/scenes/Subscriptions/SubscriptionsTable.js +336 -0
  470. data/webpack/scenes/Subscriptions/SubscriptionsTableSchema.js +117 -0
  471. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsActions.js +61 -0
  472. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsContstants.js +7 -0
  473. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +246 -0
  474. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsReducer.js +59 -0
  475. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsTableSchema.js +120 -0
  476. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsActions.test.js +64 -0
  477. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsPage.test.js +22 -0
  478. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsReducer.test.js +57 -0
  479. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +226 -0
  480. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/upstreamSubscriptions.fixtures.js +162 -0
  481. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/index.js +20 -0
  482. data/webpack/scenes/Subscriptions/__tests__/SubscriptionValidations.test.js +66 -0
  483. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsActions.test.js +126 -0
  484. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +26 -0
  485. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsReducer.test.js +67 -0
  486. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsTable.test.js +47 -0
  487. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +198 -0
  488. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +419 -0
  489. data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +364 -0
  490. data/webpack/scenes/Subscriptions/index.js +27 -0
  491. data/webpack/scenes/Tasks/TaskActions.js +75 -0
  492. data/webpack/scenes/Tasks/TaskConstants.js +7 -0
  493. data/webpack/scenes/Tasks/__tests__/TaskActions.test.js +81 -0
  494. data/webpack/scenes/Tasks/__tests__/task.fixtures.js +123 -0
  495. data/webpack/services/api/fixtures.js +353 -0
  496. data/webpack/services/api/index.js +105 -0
  497. data/webpack/services/api/setupMocks.js +17 -0
  498. data/webpack/services/index.js +59 -0
  499. data/webpack/stories/index.js +12 -0
  500. data/webpack/test_setup.js +9 -0
  501. metadata +265 -61
  502. data/app/assets/javascripts/katello/providers/provider_redhat.js +0 -185
  503. data/app/assets/javascripts/katello/providers/redhat/index.js +0 -3
  504. data/app/controllers/katello/products_controller.rb +0 -106
  505. data/app/controllers/katello/providers_controller.rb +0 -64
  506. data/app/helpers/katello/providers_helper.rb +0 -93
  507. data/app/models/katello/subscription_product.rb +0 -6
  508. data/app/views/foreman/unattended/finish-katello.erb +0 -60
  509. data/app/views/foreman/unattended/kickstart-katello-atomic.erb +0 -51
  510. data/app/views/foreman/unattended/kickstart-katello.erb +0 -139
  511. data/app/views/foreman/unattended/snippets/_subscription_manager_registration.erb +0 -18
  512. data/app/views/foreman/unattended/userdata-katello.erb +0 -92
  513. data/app/views/katello/providers/redhat/_enable_errors.html.erb +0 -12
  514. data/app/views/katello/providers/redhat/_errors.html.erb +0 -19
  515. data/app/views/katello/providers/redhat/_repo_sets.html.erb +0 -56
  516. data/app/views/katello/providers/redhat/_repos.html.erb +0 -60
  517. data/app/views/katello/providers/redhat/_tab.html.erb +0 -9
  518. data/app/views/katello/providers/redhat/show.html.erb +0 -35
  519. data/db/seeds.d/103-provisioning_templates.rb +0 -42
  520. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/errata-content-hosts.html +0 -28
  521. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/errata-details.html +0 -59
  522. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/gpg-keys/details/gpg-key-details.controller.js +0 -48
  523. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/gpg-keys/details/gpg-key-products.controller.js +0 -36
  524. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/gpg-keys/details/gpg-key-repositories.controller.js +0 -36
  525. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/gpg-keys/details/views/gpg-key-details.html +0 -36
  526. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/gpg-keys/gpg-key.factory.js +0 -43
  527. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/gpg-keys/gpg-keys.routes.js +0 -76
  528. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/gpg-keys/new/new-gpg-key.controller.js +0 -39
  529. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/gpg-keys/new/views/new-gpg-key.html +0 -44
  530. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/gpg-keys/views/gpg-keys.html +0 -46
@@ -0,0 +1,37 @@
1
+ module Actions
2
+ module Katello
3
+ module UpstreamSubscriptions
4
+ class UpdateEntitlements < Actions::Base
5
+ middleware.use Actions::Middleware::KeepCurrentTaxonomies
6
+
7
+ def plan(pools = [])
8
+ fail _("No pools were provided.") if pools.blank?
9
+ fail _("Current organization is not set.") unless ::Organization.current
10
+
11
+ sequence do
12
+ concurrence do
13
+ pools.each do |p|
14
+ pool = ::Katello::Pool.find(p[:id])
15
+
16
+ fail _("Provided pool with id %s has no upstream entitlement" % p[:id]) if pool.upstream_entitlement_id.nil?
17
+ plan_action(::Actions::Katello::UpstreamSubscriptions::UpdateEntitlement,
18
+ entitlement_id: pool.upstream_entitlement_id,
19
+ quantity: p[:quantity])
20
+ end
21
+ end
22
+
23
+ plan_action(::Actions::Katello::Organization::ManifestRefresh, ::Organization.current)
24
+ end
25
+ end
26
+
27
+ def humanized_name
28
+ N_("Update Upstream Subscription")
29
+ end
30
+
31
+ def rescue_strategy
32
+ Dynflow::Action::Rescue::Skip
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -12,7 +12,7 @@ module Actions
12
12
  private
13
13
 
14
14
  def execute?
15
- if action.input.keys.include?('contents_changed') && !action.input['contents_changed'] && !Setting[:force_post_sync_actions]
15
+ if action.input.keys.include?('contents_changed') && !action.input['contents_changed']
16
16
  self.action.output[:post_sync_skipped] = true
17
17
  false
18
18
  else
@@ -28,6 +28,7 @@ module Actions
28
28
  param :deb_releases
29
29
  param :deb_architectures
30
30
  param :deb_components
31
+ param :ignorable_content
31
32
  end
32
33
 
33
34
  def run
@@ -75,6 +76,7 @@ module Actions
75
76
  importer.remove_missing = input[:mirror_on_sync] if input[:content_type] == ::Katello::Repository::YUM_TYPE
76
77
  importer.basic_auth_username = input[:upstream_username] if input[:upstream_username].present?
77
78
  importer.basic_auth_password = input[:upstream_password] if input[:upstream_password].present?
79
+ importer.type_skip_list = input[:ignorable_content] if input[:ignorable_content]
78
80
  importer
79
81
  end
80
82
 
@@ -157,6 +159,7 @@ module Actions
157
159
  yum_dist_options = { protected: true,
158
160
  id: input[:pulp_id],
159
161
  auto_publish: true }
162
+ yum_dist_options[:skip] = input[:ignorable_content] if input[:ignorable_content]
160
163
  yum_dist_options[:checksum_type] = input[:checksum_type] if input[:checksum_type]
161
164
  Runcible::Models::YumDistributor.new(input[:path],
162
165
  input[:unprotected] || false,
@@ -0,0 +1,11 @@
1
+ module Actions
2
+ module Pulp
3
+ module Repository
4
+ class EnsureSyncNotification < Pulp::Abstract
5
+ def run
6
+ output[:results] = ::Katello::Repository.ensure_sync_notification
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -11,11 +11,11 @@ module Actions
11
11
  end
12
12
 
13
13
  def invoke_external_task
14
- pulp_resources.content.import_into_repo(input[:pulp_id],
14
+ output[:pulp_tasks] = [pulp_resources.content.import_into_repo(input[:pulp_id],
15
15
  input[:unit_type_id],
16
16
  input[:upload_id],
17
17
  input[:unit_key],
18
- unit_metadata: input[:unit_metadata] || {})
18
+ unit_metadata: input[:unit_metadata] || {})]
19
19
  end
20
20
  end
21
21
  end
@@ -1,51 +1,14 @@
1
- require 'katello/util/data'
2
-
3
1
  module Katello
4
2
  module Resources
5
- require 'rest_client'
6
-
7
3
  module Candlepin
8
- class Proxy
9
- def self.logger
10
- ::Foreman::Logging.logger('katello/cp_proxy')
11
- end
12
-
13
- def self.post(path, body)
14
- logger.debug "Sending POST request to Candlepin: #{path}"
15
- client = CandlepinResource.rest_client(Net::HTTP::Post, :post, path_with_cp_prefix(path))
16
- client.post body, {:accept => :json, :content_type => :json}.merge(User.cp_oauth_header)
17
- end
18
-
19
- def self.delete(path, body = nil)
20
- logger.debug "Sending DELETE request to Candlepin: #{path}"
21
- client = CandlepinResource.rest_client(Net::HTTP::Delete, :delete, path_with_cp_prefix(path))
22
- # Some candlepin calls will set the body in DELETE requests.
23
- client.options[:payload] = body unless body.nil?
24
- client.delete({:accept => :json, :content_type => :json}.merge(User.cp_oauth_header))
25
- end
26
-
27
- def self.get(path)
28
- logger.debug "Sending GET request to Candlepin: #{path}"
29
- client = CandlepinResource.rest_client(Net::HTTP::Get, :get, path_with_cp_prefix(path))
30
- client.get({:accept => :json}.merge(User.cp_oauth_header))
31
- end
32
-
33
- def self.put(path, body)
34
- logger.debug "Sending PUT request to Candlepin: #{path}"
35
- client = CandlepinResource.rest_client(Net::HTTP::Put, :put, path_with_cp_prefix(path))
36
- client.put body, {:accept => :json, :content_type => :json}.merge(User.cp_oauth_header)
37
- end
38
-
39
- def self.path_with_cp_prefix(path)
40
- CandlepinResource.prefix + path
41
- end
42
- end
4
+ TOTAL_COUNT_HEADER = :x_total_count # as parsed by rest_client
43
5
 
44
6
  class CandlepinResource < HttpResource
45
7
  cfg = SETTINGS[:katello][:candlepin]
46
8
  url = cfg[:url]
47
- self.prefix = URI.parse(url).path
48
- self.site = url.gsub(self.prefix, "")
9
+ uri = URI.parse(url)
10
+ self.prefix = uri.path
11
+ self.site = "#{uri.scheme}://#{uri.host}:#{uri.port}"
49
12
  self.consumer_secret = cfg[:oauth_secret]
50
13
  self.consumer_key = cfg[:oauth_key]
51
14
  self.ca_cert_file = cfg[:ca_cert_file]
@@ -107,801 +70,105 @@ module Katello
107
70
  end
108
71
  end
109
72
 
110
- class CandlepinPing < CandlepinResource
111
- class << self
112
- def ping
113
- response = get('/candlepin/status').body
114
- JSON.parse(response).with_indifferent_access
115
- end
73
+ class UpstreamCandlepinResource < CandlepinResource
74
+ extend ::Katello::Util::HttpProxy
116
75
 
117
- def distributor_versions
118
- response = get("/candlepin/distributor_versions").body
119
- JSON.parse(response)
120
- end
121
- end
122
- end
76
+ self.prefix = '/subscription'
123
77
 
124
- class Consumer < CandlepinResource
125
78
  class << self
126
- def path(id = nil)
127
- "/candlepin/consumers/#{id}"
128
- end
79
+ delegate :[], to: :json_resource
129
80
 
130
- def all_uuids
131
- cp_consumers = Organization.all.map do |org|
132
- ::Katello::Resources::Candlepin::Consumer.get('owner' => org.label, :include_only => [:uuid])
133
- end
134
- cp_consumers.flatten!
135
- cp_consumers.map { |consumer| consumer["uuid"] }
81
+ def resource(url = self.site + self.path, client_cert = self.client_cert, client_key = self.client_key, ca_file = nil, options = {})
82
+ RestClient::Resource.new(url,
83
+ :ssl_client_cert => OpenSSL::X509::Certificate.new(client_cert),
84
+ :ssl_client_key => OpenSSL::PKey::RSA.new(client_key),
85
+ :ssl_ca_file => ca_file,
86
+ :verify_ssl => ca_file ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE,
87
+ :open_timeout => Setting[:manifest_refresh_timeout],
88
+ :timeout => Setting[:manifest_refresh_timeout],
89
+ :proxy => self.proxy_uri,
90
+ **options
91
+ )
136
92
  end
137
93
 
138
- def get(params)
139
- if params.is_a?(String)
140
- JSON.parse(super(path(params), self.default_headers).body).with_indifferent_access
141
- else
142
- includes = params.key?(:include_only) ? "&" + included_list(params.delete(:include_only)) : ""
143
- fetch_paged do |page_add|
144
- response = super(path + hash_to_query(params) + includes + "&#{page_add}", self.default_headers).body
145
- JSON.parse(response)
146
- end
147
- end
94
+ def json_resource(url = self.site + self.path, client_cert = self.client_cert, client_key = self.client_key, ca_file = nil, options = {})
95
+ options.deep_merge!(headers: self.default_headers)
96
+ resource(url, client_cert, client_key, ca_file, options)
148
97
  end
149
98
 
150
- def create(env_id, parameters, activation_key_cp_ids)
151
- parameters['installedProducts'] ||= [] #if installed products is nil, candlepin won't attach custom products
152
- url = "/candlepin/environments/#{url_encode(env_id)}/consumers/"
153
- url += "?activation_keys=" + activation_key_cp_ids.join(",") if activation_key_cp_ids.length > 0
99
+ def rest_client(_http_type = nil, method = :get, path = self.path)
100
+ # No oauth upstream
101
+ self.consumer_secret = nil
102
+ self.consumer_key = nil
154
103
 
155
- response = self.post(url, parameters.to_json, self.default_headers).body
156
- JSON.parse(response).with_indifferent_access
104
+ resource(self.site + path, client_cert, client_key, nil, http_method: method)
157
105
  end
158
106
 
159
- def async_hypervisors(owner, raw_json)
160
- url = "/candlepin/hypervisors/#{owner}"
161
- headers = self.default_headers
162
- headers['content-type'] = 'text/plain'
163
- response = self.post(url, raw_json, headers)
164
- JSON.parse(response).with_indifferent_access
107
+ def client_cert
108
+ upstream_id_cert['cert']
165
109
  end
166
110
 
167
- def register_hypervisors(params)
168
- url = "/candlepin/hypervisors"
169
- url << "?owner=#{params[:owner]}&env=#{params[:env]}"
170
- attrs = params.except(:owner, :env)
171
- response = self.post(url, attrs.to_json, self.default_headers).body
172
- JSON.parse(response).with_indifferent_access
111
+ def client_key
112
+ upstream_id_cert['key']
173
113
  end
174
114
 
175
- def update(uuid, params)
176
- if params.empty?
177
- true
178
- else
179
- self.put(path(uuid), params.to_json, self.default_headers).body
180
- end
181
- # consumer update doesn't return any data atm
182
- # JSON.parse(response).with_indifferent_access
183
- end
184
-
185
- def destroy(uuid)
186
- self.delete(path(uuid), User.cp_oauth_header).code.to_i
115
+ def upstream_api_uri
116
+ URI.parse(upstream_consumer['apiUrl'])
187
117
  end
188
118
 
189
- def serials(uuid)
190
- response = Candlepin::CandlepinResource.get(join_path(path(uuid), 'certificates/serials'))
191
- JSON.parse(response.body)
119
+ def site
120
+ "#{upstream_api_uri.scheme}://#{upstream_api_uri.host}"
192
121
  end
193
122
 
194
- def checkin(uuid, checkin_date)
195
- checkin_date ||= Time.now
196
- self.put(path(uuid), {:lastCheckin => checkin_date}.to_json, self.default_headers).body
197
- end
198
-
199
- def available_pools(owner_label, uuid, listall = false)
200
- url = Pool.path(nil, owner_label) + "?consumer=#{uuid}&listall=#{listall}&add_future=true"
201
- response = Candlepin::CandlepinResource.get(url, self.default_headers).body
202
- JSON.parse(response)
203
- end
204
-
205
- def regenerate_identity_certificates(uuid)
206
- response = self.post(path(uuid), {}, self.default_headers).body
207
- JSON.parse(response).with_indifferent_access
208
- end
209
-
210
- def export(uuid)
211
- # Export is a zip file
212
- headers = self.default_headers
213
- headers['accept'] = 'application/zip'
214
- response = Candlepin::CandlepinResource.get(join_path(path(uuid), 'export'), headers)
215
- response
216
- end
217
-
218
- def entitlements(uuid)
219
- response = Candlepin::CandlepinResource.get(join_path(path(uuid), 'entitlements'), self.default_headers).body
220
- ::Katello::Util::Data.array_with_indifferent_access JSON.parse(response)
221
- end
222
-
223
- def refresh_entitlements(uuid)
224
- self.post(join_path(path(uuid), 'entitlements'), "", self.default_headers).body
225
- end
226
-
227
- def consume_entitlement(uuid, pool, quantity = nil)
228
- uri = join_path(path(uuid), 'entitlements') + "?pool=#{pool}"
229
- uri += "&quantity=#{quantity}" if quantity && quantity > 0
230
- response = self.post(uri, "", self.default_headers).body
231
- response.blank? ? [] : JSON.parse(response)
232
- end
233
-
234
- def remove_entitlement(uuid, ent_id)
235
- uri = join_path(path(uuid), 'entitlements') + "/#{ent_id}"
236
- self.delete(uri, self.default_headers).code.to_i
237
- end
238
-
239
- def remove_entitlements(uuid)
240
- uri = join_path(path(uuid), 'entitlements')
241
- self.delete(uri, self.default_headers).code.to_i
242
- end
243
-
244
- def remove_certificate(uuid, serial_id)
245
- uri = join_path(path(uuid), 'certificates') + "/#{serial_id}"
246
- self.delete(uri, self.default_headers).code.to_i
247
- end
248
-
249
- def virtual_guests(uuid)
250
- response = Candlepin::CandlepinResource.get(join_path(path(uuid), 'guests'), self.default_headers).body
251
- ::Katello::Util::Data.array_with_indifferent_access JSON.parse(response)
252
- rescue
253
- return []
254
- end
255
-
256
- def virtual_host(uuid)
257
- response = Candlepin::CandlepinResource.get(join_path(path(uuid), 'host'), self.default_headers).body
258
- if response.present?
259
- JSON.parse(response).with_indifferent_access
260
- else
261
- return nil
262
- end
263
- rescue
264
- return nil
265
- end
266
-
267
- def compliance(uuid)
268
- response = Candlepin::CandlepinResource.get(join_path(path(uuid), 'compliance'), self.default_headers(uuid)).body
269
- if response.present?
270
- json = JSON.parse(response).with_indifferent_access
271
- if json['reasons']
272
- json['reasons'].sort! { |x, y| x['attributes']['name'] <=> y['attributes']['name'] }
273
- else
274
- json['reasons'] = []
275
- end
276
- json
277
- else
278
- return nil
279
- end
280
- end
281
-
282
- def events(uuid)
283
- response = Candlepin::CandlepinResource.get(join_path(path(uuid), 'events'), self.default_headers).body
284
- if response.present?
285
- ::Katello::Util::Data.array_with_indifferent_access JSON.parse(response)
286
- else
287
- return []
123
+ def upstream_id_cert
124
+ unless upstream_consumer && upstream_consumer['idCert'] && upstream_consumer['idCert']['cert'] && upstream_consumer['idCert']['key']
125
+ Rails.logger.error "Upstream identity certificate not available"
126
+ fail _("Upstream identity certificate not available")
288
127
  end
128
+ upstream_consumer['idCert']
289
129
  end
290
130
 
291
- def content_overrides(id)
292
- result = Candlepin::CandlepinResource.get(join_path(path(id), 'content_overrides'), self.default_headers).body
293
- ::Katello::Util::Data.array_with_indifferent_access(JSON.parse(result))
131
+ def upstream_owner_id
132
+ JSON.parse(Katello::Resources::Candlepin::UpstreamConsumer.resource.get.body)['owner']['key']
133
+ rescue RestClient::Exception => e
134
+ Rails.logger.error "Unable to find upstream owner for consumer"
135
+ raise e
294
136
  end
295
137
 
296
- # expected params
297
- # id : UUID of the consumer
298
- # content_overrides => Array of entitlement hashes objects
299
- def update_content_overrides(id, content_overrides)
300
- attrs_to_delete = []
301
- attrs_to_update = []
302
- content_overrides.each do |content_override|
303
- if content_override[:value]
304
- attrs_to_update << content_override
305
- else
306
- attrs_to_delete << content_override
307
- end
308
- end
309
-
310
- if attrs_to_update.present?
311
- result = Candlepin::CandlepinResource.put(join_path(path(id), 'content_overrides'),
312
- attrs_to_update.to_json, self.default_headers)
313
- end
314
- if attrs_to_delete.present?
315
- client = Candlepin::CandlepinResource.rest_client(Net::HTTP::Delete, :delete,
316
- join_path(path(id), 'content_overrides'))
317
- client.options[:payload] = attrs_to_delete.to_json
318
- result = client.delete({:accept => :json, :content_type => :json}.merge(User.cp_oauth_header))
319
- end
320
- ::Katello::Util::Data.array_with_indifferent_access(JSON.parse(result))
138
+ def upstream_consumer_id
139
+ upstream_consumer['uuid']
321
140
  end
322
- end
323
- end
324
141
 
325
- class UpstreamConsumer < HttpResource
326
- def self.logger
327
- ::Foreman::Logging.logger('katello/cp_rest')
328
- end
329
-
330
- def self.resource(url, client_cert, client_key, ca_file)
331
- if SETTINGS[:katello][:cdn_proxy] && SETTINGS[:katello][:cdn_proxy][:host]
332
- proxy_config = SETTINGS[:katello][:cdn_proxy]
333
- uri = URI('')
334
-
335
- uri.scheme = URI.parse(proxy_config[:host]).scheme
336
- uri.host = URI.parse(proxy_config[:host]).host
337
- uri.port = proxy_config[:port].try(:to_s)
338
- uri.user = proxy_config[:user].try(:to_s)
339
- uri.password = proxy_config[:password].try(:to_s)
142
+ def upstream_consumer
143
+ fail _("Current organization not set.") unless Organization.current
144
+ upstream_consumer = Organization.current.owner_details['upstreamConsumer']
145
+ fail _("Current organization has no manifest imported.") unless upstream_consumer
340
146
 
341
- RestClient.proxy = uri.to_s
147
+ upstream_consumer
342
148
  end
149
+ end # class << self
150
+ end # UpstreamCandlepinResource
343
151
 
344
- RestClient::Resource.new(url,
345
- :ssl_client_cert => OpenSSL::X509::Certificate.new(client_cert),
346
- :ssl_client_key => OpenSSL::PKey::RSA.new(client_key),
347
- :ssl_ca_file => ca_file,
348
- :verify_ssl => ca_file ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE,
349
- :open_timeout => Setting[:manifest_refresh_timeout],
350
- :timeout => Setting[:manifest_refresh_timeout]
351
- )
352
- end
353
-
354
- def self.export(url, client_cert, client_key, ca_file)
355
- logger.debug "Sending GET request to upstream Candlepin: #{url}"
356
- return resource(url, client_cert, client_key, ca_file).get
357
- rescue => e
358
- raise e
359
- ensure
360
- RestClient.proxy = ""
361
- end
362
-
363
- def self.update(url, client_cert, client_key, ca_file, attributes)
364
- logger.debug "Sending POST request to upstream Candlepin: #{url} #{attributes.to_json}"
365
-
366
- return resource(url, client_cert, client_key, ca_file).put(attributes.to_json,
367
- 'accept' => 'application/json',
368
- 'accept-language' => I18n.locale,
369
- 'content-type' => 'application/json')
370
- ensure
371
- RestClient.proxy = ""
372
- end
373
- end
374
-
375
- class OwnerInfo < CandlepinResource
376
- class << self
377
- def find(key)
378
- owner_json = self.get(path(key), {'accept' => 'application/json'}.merge(User.cp_oauth_header)).body
379
- JSON.parse(owner_json).with_indifferent_access
380
- end
381
-
382
- def path(id = nil)
383
- "/candlepin/owners/#{id}/info"
384
- end
385
- end
386
- end
387
-
388
- class Owner < CandlepinResource
389
- class << self
390
- # Set the contentPrefix at creation time so that the client will get
391
- # content only for the org it has been subscribed to
392
- def create(key, description)
393
- attrs = {:key => key, :displayName => description, :contentPrefix => "/#{key}/$env"}
394
- owner_json = self.post(path, attrs.to_json, self.default_headers).body
395
- JSON.parse(owner_json).with_indifferent_access
396
- end
397
-
398
- # create the first user for owner
399
- def create_user(_key, username, password)
400
- # create user with superadmin flag (no role, permissions etc)
401
- CPUser.create(:username => name_to_key(username), :password => name_to_key(password), :superAdmin => true)
402
- end
403
-
404
- def destroy(key)
405
- self.delete(path(key), User.cp_oauth_header).code.to_i
406
- end
407
-
408
- def find(key)
409
- owner_json = self.get(path(key), {'accept' => 'application/json'}.merge(User.cp_oauth_header)).body
410
- JSON.parse(owner_json).with_indifferent_access
411
- end
412
-
413
- def update(key, attrs)
414
- owner = find(key)
415
- owner.merge!(attrs)
416
- self.put(path(key), JSON.generate(owner), self.default_headers).body
417
- end
418
-
419
- def import(organization_name, path_to_file, options)
420
- path = join_path(path(organization_name), 'imports')
421
- if options[:force] || SETTINGS[:katello].key?(:force_manifest_import)
422
- path += "?force=#{SETTINGS[:katello][:force_manifest_import]}"
423
- end
424
-
425
- self.post(path, {:import => File.new(path_to_file, 'rb')}, self.default_headers.except('content-type'))
426
- end
427
-
428
- def product_content(organization_name)
429
- Product.all(organization_name, [:id, :productContent])
430
- end
431
-
432
- def destroy_imports(organization_name, wait_until_complete = false)
433
- response_json = self.delete(join_path(path(organization_name), 'imports'), self.default_headers)
434
- response = JSON.parse(response_json).with_indifferent_access
435
- if wait_until_complete && response['state'] == 'CREATED'
436
- while !response['state'].nil? && response['state'] != 'FINISHED' && response['state'] != 'ERROR'
437
- path = join_path('candlepin', response['statusPath'][1..-1])
438
- response_json = self.get(path, self.default_headers)
439
- response = JSON.parse(response_json).with_indifferent_access
440
- end
441
- end
442
-
443
- response
444
- end
445
-
446
- def imports(organization_name)
447
- imports_json = self.get(join_path(path(organization_name), 'imports'), self.default_headers)
448
- ::Katello::Util::Data.array_with_indifferent_access JSON.parse(imports_json)
449
- end
450
-
451
- def pools(owner_label, filter = {})
452
- filter[:add_future] ||= true
453
- params = hash_to_query(filter)
454
- if owner_label
455
- # hash_to_query escapes the ":!" to "%3A%21" which candlepin rejects
456
- params += '&attribute=unmapped_guests_only:!true'
457
- json_str = self.get(join_path(path(owner_label), 'pools') + params, self.default_headers).body
458
- else
459
- json_str = self.get(join_path('candlepin', 'pools') + params, self.default_headers).body
460
- end
461
- ::Katello::Util::Data.array_with_indifferent_access JSON.parse(json_str)
462
- end
463
-
464
- def statistics(key)
465
- json_str = self.get(join_path(path(key), 'statistics'), self.default_headers).body
466
- ::Katello::Util::Data.array_with_indifferent_access JSON.parse(json_str)
467
- end
468
-
469
- def generate_ueber_cert(key)
470
- ueber_cert_json = self.post(join_path(path(key), "uebercert"), {}.to_json, self.default_headers).body
471
- JSON.parse(ueber_cert_json).with_indifferent_access
472
- end
473
-
474
- def get_ueber_cert(key)
475
- ueber_cert_json = self.get(join_path(path(key), "uebercert"), {'accept' => 'application/json'}.merge(User.cp_oauth_header)).body
476
- JSON.parse(ueber_cert_json).with_indifferent_access
477
- end
478
-
479
- def get_ueber_cert_pkcs12(key, name = nil, password = nil)
480
- certs = get_ueber_cert(key)
481
- c = OpenSSL::X509::Certificate.new certs["cert"]
482
- p = OpenSSL::PKey::RSA.new certs["key"]
483
- OpenSSL::PKCS12.create(password, name, p, c, nil, "PBE-SHA1-3DES", "PBE-SHA1-3DES")
484
- end
485
-
486
- def events(key)
487
- response = self.get(join_path(path(key), 'events'), self.default_headers).body
488
- ::Katello::Util::Data.array_with_indifferent_access JSON.parse(response)
489
- end
490
-
491
- def service_levels(uuid)
492
- response = Candlepin::CandlepinResource.get(join_path(path(uuid), 'servicelevels'), self.default_headers).body
493
- if response.empty?
494
- return []
495
- else
496
- JSON.parse(response)
497
- end
498
- end
499
-
500
- def auto_attach(key)
501
- response = self.post(join_path(path(key), 'entitlements'), "", self.default_headers).body
502
- if response.empty?
503
- return nil
504
- else
505
- JSON.parse(response)
506
- end
507
- end
508
-
509
- def path(id = nil)
510
- "/candlepin/owners/#{id}"
511
- end
152
+ module ConsumerResource
153
+ def path(id = nil)
154
+ "#{self.prefix}/consumers/#{id}"
512
155
  end
513
156
  end
514
157
 
515
- class Environment < CandlepinResource
516
- class << self
517
- def find(id)
518
- JSON.parse(self.get(path(id), self.default_headers).body).with_indifferent_access
519
- end
520
-
521
- def all
522
- JSON.parse(self.get(path, self.default_headers).body).collect { |a| a.with_indifferent_access }
523
- end
524
-
525
- def create(owner_id, id, name, description)
526
- attrs = {:id => id, :name => name, :description => description}
527
- path = "/candlepin/owners/#{owner_id}/environments"
528
- environment_json = self.post(path, attrs.to_json, self.default_headers).body
529
- JSON.parse(environment_json).with_indifferent_access
530
- end
531
-
532
- def destroy(id)
533
- self.delete(path(id), User.cp_oauth_header).code.to_i
534
- end
535
-
536
- def path(id = '')
537
- "/candlepin/environments/#{id}"
538
- end
539
-
540
- def add_content(env_id, content_ids)
541
- path = self.path(env_id) + "/content"
542
- params = content_ids.map { |content_id| {:contentId => content_id} }
543
- JSON.parse(self.post(path, params.to_json, self.default_headers).body).with_indifferent_access
544
- end
545
-
546
- def delete_content(env_id, content_ids)
547
- path = self.path(env_id) + "/content"
548
- params = content_ids.map { |content_id| {:content => content_id}.to_param }.join("&")
549
- self.delete("#{path}?#{params}", self.default_headers).code.to_i
550
- end
158
+ module OwnerResource
159
+ def path(id = nil)
160
+ "#{self.prefix}/owners/#{id}"
551
161
  end
552
162
  end
553
163
 
554
- class CPUser < CandlepinResource
555
- class << self
556
- def create(attrs)
557
- JSON.parse(self.post(path, JSON.generate(attrs), self.default_headers).body).with_indifferent_access
558
- end
559
-
560
- def path(id = nil)
561
- "/candlepin/users/#{id}"
562
- end
563
- end
564
- end
565
-
566
- class Pool < CandlepinResource
567
- class << self
568
- def find(pool_id)
569
- pool_json = self.get(path(pool_id), self.default_headers).body
570
- fail ArgumentError, "pool id cannot contain ?" if pool_id["?"]
571
- JSON.parse(pool_json).with_indifferent_access
572
- end
573
-
574
- def get_for_owner(owner_key, include_temporary_guests = false)
575
- url = "/candlepin/owners/#{owner_key}/pools?add_future=true"
576
- url += "&attribute=unmapped_guests_only:!true" if include_temporary_guests
577
- pools_json = self.get(url, self.default_headers).body
578
- JSON.parse(pools_json)
579
- end
580
-
581
- def destroy(id)
582
- fail ArgumentError, "pool id has to be specified" unless id
583
- self.delete(path(id), self.default_headers).code.to_i
584
- end
585
-
586
- def entitlements(pool_id, included = [])
587
- entitlement_json = self.get("#{path(pool_id)}/entitlements?#{included_list(included)}", self.default_headers).body
588
- JSON.parse(entitlement_json)
589
- end
590
-
591
- def path(id = nil, owner_label = nil)
592
- if owner_label && id
593
- "/candlepin/owners/#{owner_label}/pools/#{id}"
594
- elsif owner_label
595
- "/candlepin/owners/#{owner_label}/pools/"
596
- else
597
- "/candlepin/pools/#{id}"
598
- end
599
- end
600
- end
601
- end
602
-
603
- class Content < CandlepinResource
604
- class << self
605
- def create(owner_label, attrs)
606
- JSON.parse(self.post(path(owner_label), JSON.generate(attrs), self.default_headers).body).with_indifferent_access
607
- end
608
-
609
- def get(owner_label, id)
610
- content_json = super(path(owner_label, id), self.default_headers).body
611
- JSON.parse(content_json).with_indifferent_access
612
- end
613
-
614
- def all(owner_label)
615
- content_json = Candlepin::CandlepinResource.get(path(owner_label), self.default_headers).body
616
- JSON.parse(content_json)
617
- end
618
-
619
- def destroy(owner_label, id)
620
- fail ArgumentError, "content id has to be specified" unless id
621
- self.delete(path(owner_label, id), self.default_headers).code.to_i
622
- end
623
-
624
- def update(owner_label, attrs)
625
- JSON.parse(self.put(path(owner_label, attrs[:id] || attrs['id']), JSON.generate(attrs), self.default_headers).body).with_indifferent_access
626
- end
627
-
628
- def path(owner_label, id = nil)
629
- "/candlepin/owners/#{owner_label}/content/#{id}"
630
- end
631
- end
632
- end
633
-
634
- class Subscription < CandlepinResource
635
- class << self
636
- def destroy(subscription_id)
637
- fail ArgumentError, "subscription id has to be specified" unless subscription_id
638
- self.delete(path(subscription_id), self.default_headers).code.to_i
639
- end
640
-
641
- def get(id = nil)
642
- content_json = super(path(id), self.default_headers).body
643
- JSON.parse(content_json)
644
- end
645
-
646
- def create_for_owner(owner_key, attrs)
647
- subscription = self.post("/candlepin/owners/#{owner_key}/subscriptions", attrs.to_json, self.default_headers).body
648
- subscription
649
- end
650
-
651
- def get_for_owner(owner_key, included = [])
652
- content_json = Candlepin::CandlepinResource.get(
653
- "/candlepin/owners/#{owner_key}/subscriptions?#{included_list(included)}",
654
- self.default_headers
655
- ).body
656
- JSON.parse(content_json)
657
- end
658
-
659
- def path(id = nil)
660
- "/candlepin/subscriptions/#{id}"
661
- end
662
- end
663
- end
664
-
665
- class Job < CandlepinResource
666
- class << self
667
- NOT_FINISHED_STATES = %w(CREATED PENDING RUNNING).freeze unless defined? NOT_FINISHED_STATES
668
-
669
- def not_finished?(job)
670
- NOT_FINISHED_STATES.include?(job[:state])
671
- end
672
-
673
- def get(id, params = {})
674
- job_json = super(path(id) + hash_to_query(params), self.default_headers).body
675
- job = JSON.parse(job_json)
676
- job.with_indifferent_access
677
- end
678
-
679
- def path(id = nil)
680
- "/candlepin/jobs/#{id}"
681
- end
682
- end
683
- end
684
-
685
- class Product < CandlepinResource
686
- class << self
687
- def all(owner_label, included = [])
688
- JSON.parse(Candlepin::CandlepinResource.get(path(owner_label) + "?#{included_list(included)}", self.default_headers).body)
689
- end
690
-
691
- def find_for_stacking_id(owner_key, stacking_id)
692
- Subscription.get_for_owner(owner_key).each do |subscription|
693
- if subscription['product']['attributes'].any? { |attr| attr['name'] == 'stacking_id' && attr['value'] == stacking_id }
694
- return subscription['product']
695
- end
696
- end
697
- nil
698
- end
699
-
700
- def create(owner_label, attr)
701
- JSON.parse(self.post(path(owner_label), attr.to_json, self.default_headers).body).with_indifferent_access
702
- end
703
-
704
- def get(owner_label, id = nil, included = [])
705
- products_json = super(path(owner_label, id + "/?#{included_list(included)}"), self.default_headers).body
706
- products = JSON.parse(products_json)
707
- products = [products] unless id.nil?
708
- ::Katello::Util::Data.array_with_indifferent_access products
709
- end
710
-
711
- def product_certificate(id, owner)
712
- included = %w(certificate product.id providedProducts.id
713
- derivedProvidedProducts.id)
714
- subscriptions_json = Candlepin::CandlepinResource.get(
715
- "/candlepin/owners/#{owner}/subscriptions?#{included_list(included)}",
716
- self.default_headers
717
- ).body
718
- subscriptions = JSON.parse(subscriptions_json)
719
-
720
- product_subscription = subscriptions.find do |sub|
721
- sub['certificate'] &&
722
- (sub["product"]["id"] == id ||
723
- sub["providedProducts"].any? { |provided| provided["id"] == id } ||
724
- sub["derivedProvidedProducts"].any? { |provided| provided["id"] == id })
725
- end
726
-
727
- if product_subscription
728
- return product_subscription["certificate"]
729
- end
730
- end
731
-
732
- def certificate(id, owner)
733
- self.product_certificate(id, owner).try :[], 'cert'
734
- end
735
-
736
- def key(id, owner)
737
- self.product_certificate(id, owner).try :[], 'key'
738
- end
739
-
740
- def destroy(owner_label, product_id)
741
- fail ArgumentError, "product id has to be specified" unless product_id
742
- self.delete(path(owner_label, product_id), self.default_headers).code.to_i
743
- end
744
-
745
- def add_content(owner_label, product_id, content_id, enabled)
746
- self.post(join_path(path(owner_label, product_id), "content/#{content_id}?enabled=#{enabled}"), nil, self.default_headers).code.to_i
747
- end
748
-
749
- def remove_content(owner_label, product_id, content_id)
750
- self.delete(join_path(path(owner_label, product_id), "content/#{content_id}"), self.default_headers).code.to_i
751
- end
752
-
753
- def create_unlimited_subscription(owner_key, product_id, start_date)
754
- start_date ||= Time.now
755
- # End it 100 years from now
756
- end_date ||= start_date + 10_950.days
757
-
758
- subscription = {
759
- 'startDate' => start_date,
760
- 'endDate' => end_date,
761
- 'quantity' => -1,
762
- 'accountNumber' => '',
763
- 'product' => { 'id' => product_id },
764
- 'providedProducts' => [],
765
- 'contractNumber' => ''
766
- }
767
- JSON.parse(Candlepin::Subscription.create_for_owner(owner_key, subscription))
768
- end
769
-
770
- def pools(owner_key, product_id)
771
- Candlepin::Pool.get_for_owner(owner_key).find_all { |pool| pool['productId'] == product_id }
772
- end
773
-
774
- def delete_subscriptions(owner_key, product_id)
775
- update_subscriptions = false
776
- subscriptions = Candlepin::Subscription.get_for_owner owner_key
777
- subscriptions.each do |s|
778
- products = ([s['product']] + s['providedProducts'])
779
- products.each do |p|
780
- if p['id'] == product_id
781
- logger.debug "Deleting subscription: " + s.to_json
782
- Candlepin::Subscription.destroy s['id']
783
- update_subscriptions = true
784
- end
785
- end
786
- end
787
- nil
788
- end
789
-
790
- def path(owner_label, id = nil)
791
- "/candlepin/owners/#{owner_label}/products/#{id}"
792
- end
793
- end
794
- end
795
-
796
- class Entitlement < CandlepinResource
797
- class << self
798
- def regenerate_entitlement_certificates_for_product(product_id)
799
- self.put("/candlepin/entitlements/product/#{product_id}", nil, self.default_headers).code.to_i
800
- end
801
-
802
- def get(id = nil, params = '')
803
- json = Candlepin::CandlepinResource.get(path(id) + params, self.default_headers).body
804
- JSON.parse(json)
805
- end
806
-
807
- def path(id = nil)
808
- "/candlepin/entitlements/#{id}"
809
- end
810
- end
811
- end
812
-
813
- class ActivationKey < CandlepinResource
814
- class << self
815
- def get(id = nil, params = '')
816
- akeys_json = super(path(id) + params, self.default_headers).body
817
- akeys = JSON.parse(akeys_json)
818
- akeys = [akeys] unless id.nil?
819
- ::Katello::Util::Data.array_with_indifferent_access akeys
820
- end
821
-
822
- def create(name, owner_key, auto_attach)
823
- url = "/candlepin/owners/#{owner_key}/activation_keys"
824
- JSON.parse(self.post(url, {:name => name, :autoAttach => auto_attach}.to_json, self.default_headers).body).with_indifferent_access
825
- end
826
-
827
- def update(id, release_version, service_level, auto_attach)
828
- attrs = { :releaseVer => release_version, :serviceLevel => service_level, :autoAttach => auto_attach }.delete_if { |_k, v| v.nil? }
829
- JSON.parse(self.put(path(id), attrs.to_json, self.default_headers).body).with_indifferent_access
830
- end
831
-
832
- def destroy(id)
833
- fail(ArgumentError, "activation key id has to be specified") unless id
834
- self.delete(path(id), self.default_headers).code.to_i
835
- end
836
-
837
- def pools(owner_key)
838
- Candlepin::Owner.pools(owner_key)
839
- end
840
-
841
- def key_pools(id)
842
- kp_json = Candlepin::CandlepinResource.get(join_path(path(id), "pools"), self.default_headers).body
843
- key_pools = JSON.parse(kp_json)
844
- ::Katello::Util::Data.array_with_indifferent_access key_pools
845
- end
846
-
847
- def add_product(id, product_id)
848
- cppath = join_path(path(id), "product/#{product_id}")
849
- product = self.post(cppath, {}, self.default_headers)
850
- JSON.parse(product).with_indifferent_access
851
- end
852
-
853
- def remove_product(id, product_id)
854
- product = self.delete(join_path(path(id), "product/#{product_id}"), self.default_headers)
855
- JSON.parse(product).with_indifferent_access
856
- end
857
-
858
- def add_pools(id, pool_id, quantity)
859
- cppath = join_path(path(id), "pools/#{pool_id}")
860
- quantity = Integer(quantity) rescue nil
861
- cppath += "?quantity=#{quantity}" if quantity && quantity > 0
862
- pool = self.post(cppath, {}, self.default_headers)
863
- JSON.parse(pool).with_indifferent_access
864
- end
865
-
866
- def remove_pools(id, pool_id)
867
- pool = self.delete(join_path(path(id), "pools/#{pool_id}"), self.default_headers)
868
- JSON.parse(pool).with_indifferent_access
869
- end
870
-
871
- def content_overrides(id)
872
- result = Candlepin::CandlepinResource.get(join_path(path(id), 'content_overrides'), self.default_headers).body
873
- ::Katello::Util::Data.array_with_indifferent_access(JSON.parse(result))
874
- end
875
-
876
- # expected params
877
- # id : ID of the Activation Key
878
- # content_overrides => Array of content override hashes
879
- def update_content_overrides(id, content_overrides)
880
- attrs_to_delete = []
881
- attrs_to_update = []
882
- content_overrides.each do |content_override|
883
- if content_override[:value]
884
- attrs_to_update << content_override
885
- else
886
- attrs_to_delete << content_override
887
- end
888
- end
889
-
890
- if attrs_to_update.present?
891
- result = Candlepin::CandlepinResource.put(join_path(path(id), 'content_overrides'),
892
- attrs_to_update.to_json, self.default_headers)
893
- end
894
- if attrs_to_delete.present?
895
- client = Candlepin::CandlepinResource.rest_client(Net::HTTP::Delete, :delete,
896
- join_path(path(id), 'content_overrides'))
897
- client.options[:payload] = attrs_to_delete.to_json
898
- result = client.delete({:accept => :json, :content_type => :json}.merge(User.cp_oauth_header))
899
- end
900
- ::Katello::Util::Data.array_with_indifferent_access(JSON.parse(result))
901
- end
902
-
903
- def path(id = nil)
904
- "/candlepin/activation_keys/#{id}"
164
+ module PoolResource
165
+ def path(id = nil, owner_label = nil)
166
+ if owner_label && id
167
+ "#{prefix}/owners/#{owner_label}/pools/#{id}"
168
+ elsif owner_label
169
+ "#{prefix}/owners/#{owner_label}/pools/"
170
+ else
171
+ "#{prefix}/pools/#{id}"
905
172
  end
906
173
  end
907
174
  end