katello 3.9.1 → 3.10.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 (229) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js +28 -12
  3. data/app/controllers/katello/api/rhsm/candlepin_dynflow_proxy_controller.rb +12 -3
  4. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +4 -13
  5. data/app/controllers/katello/api/v2/content_credentials_controller.rb +1 -1
  6. data/app/controllers/katello/api/v2/content_view_filter_rules_controller.rb +1 -1
  7. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +6 -4
  8. data/app/controllers/katello/api/v2/content_views_controller.rb +8 -3
  9. data/app/controllers/katello/api/v2/gpg_keys_controller.rb +2 -1
  10. data/app/controllers/katello/api/v2/host_module_streams_controller.rb +39 -0
  11. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +20 -11
  12. data/app/controllers/katello/api/v2/module_streams_controller.rb +2 -1
  13. data/app/controllers/katello/api/v2/repository_sets_controller.rb +17 -8
  14. data/app/controllers/katello/application_controller.rb +0 -2
  15. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +5 -2
  16. data/app/lib/actions/candlepin/consumer/attach_subscription.rb +0 -2
  17. data/app/lib/actions/candlepin/consumer/remove_subscription.rb +0 -2
  18. data/app/lib/actions/katello/capsule_content/create_repos.rb +1 -25
  19. data/app/lib/actions/katello/capsule_content/sync.rb +1 -1
  20. data/app/lib/actions/katello/content_view/promote.rb +2 -5
  21. data/app/lib/actions/katello/content_view/promote_to_environment.rb +2 -5
  22. data/app/lib/actions/katello/content_view/publish.rb +1 -4
  23. data/app/lib/actions/katello/content_view_puppet_environment/create.rb +6 -10
  24. data/app/lib/actions/katello/content_view_version/export.rb +0 -2
  25. data/app/lib/actions/katello/content_view_version/incremental_update.rb +19 -1
  26. data/app/lib/actions/katello/environment/publish_repositories.rb +2 -1
  27. data/app/lib/actions/katello/gpg_key/update.rb +17 -0
  28. data/app/lib/actions/katello/host/attach_subscriptions.rb +0 -2
  29. data/app/lib/actions/katello/host/erratum/install.rb +6 -0
  30. data/app/lib/actions/katello/host/generate_applicability.rb +0 -2
  31. data/app/lib/actions/katello/host/hypervisors_update.rb +11 -6
  32. data/app/lib/actions/katello/host/package/install.rb +6 -0
  33. data/app/lib/actions/katello/host/package/remove.rb +6 -0
  34. data/app/lib/actions/katello/host/package/update.rb +7 -1
  35. data/app/lib/actions/katello/host/package_group/install.rb +6 -0
  36. data/app/lib/actions/katello/host/package_group/remove.rb +6 -0
  37. data/app/lib/actions/katello/host/recalculate_errata_status.rb +0 -2
  38. data/app/lib/actions/katello/host/remove_subscriptions.rb +0 -2
  39. data/app/lib/actions/katello/host/update.rb +1 -0
  40. data/app/lib/actions/katello/host/update_content_overrides.rb +0 -2
  41. data/app/lib/actions/katello/host/upload_package_profile.rb +13 -12
  42. data/app/lib/actions/katello/host/upload_profiles.rb +70 -0
  43. data/app/lib/actions/katello/product/reindex_subscriptions.rb +0 -2
  44. data/app/lib/actions/katello/product/repositories_certs_reset.rb +4 -4
  45. data/app/lib/actions/katello/product/repositories_gpg_reset.rb +2 -2
  46. data/app/lib/actions/katello/repository/check_matching_content.rb +18 -6
  47. data/app/lib/actions/katello/repository/clone_deb_content.rb +1 -1
  48. data/app/lib/actions/katello/repository/clone_to_environment.rb +3 -5
  49. data/app/lib/actions/katello/repository/clone_to_version.rb +2 -3
  50. data/app/lib/actions/katello/repository/clone_yum_content.rb +1 -2
  51. data/app/lib/actions/katello/repository/clone_yum_metadata.rb +2 -2
  52. data/app/lib/actions/katello/repository/create.rb +1 -31
  53. data/app/lib/actions/katello/repository/destroy.rb +1 -2
  54. data/app/lib/actions/katello/repository/export.rb +0 -2
  55. data/app/lib/actions/katello/repository/fetch_pxe_files.rb +0 -2
  56. data/app/lib/actions/katello/repository/filtered_index_content.rb +0 -2
  57. data/app/lib/actions/katello/repository/finish_upload.rb +0 -2
  58. data/app/lib/actions/katello/repository/import_upload.rb +0 -2
  59. data/app/lib/actions/katello/repository/index_content.rb +0 -1
  60. data/app/lib/actions/katello/repository/index_package_groups.rb +0 -2
  61. data/app/lib/actions/katello/repository/instance_update.rb +21 -0
  62. data/app/lib/actions/katello/repository/remove_content.rb +0 -2
  63. data/app/lib/actions/katello/repository/sync.rb +0 -1
  64. data/app/lib/actions/katello/repository/update.rb +0 -2
  65. data/app/lib/actions/katello/upstream_subscriptions/bind_entitlement.rb +0 -2
  66. data/app/lib/actions/katello/upstream_subscriptions/bind_entitlements.rb +0 -2
  67. data/app/lib/actions/katello/upstream_subscriptions/remove_entitlement.rb +0 -1
  68. data/app/lib/actions/katello/upstream_subscriptions/remove_entitlements.rb +0 -2
  69. data/app/lib/actions/katello/upstream_subscriptions/update_entitlement.rb +0 -1
  70. data/app/lib/actions/katello/upstream_subscriptions/update_entitlements.rb +0 -2
  71. data/app/lib/actions/pulp/abstract.rb +13 -14
  72. data/app/lib/actions/pulp/repository/create.rb +13 -211
  73. data/app/lib/actions/pulp/repository/create_in_plan.rb +4 -18
  74. data/app/lib/actions/pulp/repository/refresh.rb +7 -70
  75. data/app/lib/actions/pulp/repository/sync.rb +1 -2
  76. data/app/lib/katello/capsule_content.rb +3 -3
  77. data/app/lib/katello/resources/candlepin/consumer.rb +1 -1
  78. data/app/lib/katello/resources/candlepin/product.rb +1 -1
  79. data/app/lib/katello/validators/hostgroup_kickstart_repository_validator.rb +1 -1
  80. data/app/models/katello/available_module_stream.rb +11 -0
  81. data/app/models/katello/concerns/content_facet_host_extensions.rb +1 -0
  82. data/app/models/katello/concerns/host_managed_extensions.rb +56 -0
  83. data/app/models/katello/concerns/hostgroup_extensions.rb +17 -0
  84. data/app/models/katello/concerns/redhat_extensions.rb +20 -6
  85. data/app/models/katello/concerns/search_by_repository_name.rb +0 -1
  86. data/app/models/katello/concerns/smart_proxy_extensions.rb +26 -12
  87. data/app/models/katello/content_facet_applicable_module_stream.rb +7 -0
  88. data/app/models/katello/content_view_puppet_environment.rb +14 -35
  89. data/app/models/katello/erratum.rb +54 -24
  90. data/app/models/katello/erratum_package.rb +6 -0
  91. data/app/models/katello/glue/pulp/repo.rb +5 -228
  92. data/app/models/katello/gpg_key.rb +1 -0
  93. data/app/models/katello/host/content_facet.rb +38 -83
  94. data/app/models/katello/host_available_module_stream.rb +47 -0
  95. data/app/models/katello/module_stream.rb +18 -0
  96. data/app/models/katello/module_stream_erratum_package.rb +6 -0
  97. data/app/models/katello/product.rb +0 -2
  98. data/app/models/katello/product_content.rb +1 -0
  99. data/app/models/katello/repository.rb +15 -6
  100. data/app/models/katello/root_repository.rb +1 -1
  101. data/app/models/katello/rpm.rb +5 -17
  102. data/app/services/katello/applicable_content_helper.rb +111 -0
  103. data/app/services/katello/managed_content_medium_provider.rb +7 -0
  104. data/app/services/katello/pulp/consumer.rb +13 -7
  105. data/app/services/katello/pulp/repository.rb +157 -4
  106. data/app/services/katello/pulp/repository/deb.rb +47 -0
  107. data/app/services/katello/pulp/repository/docker.rb +43 -0
  108. data/app/services/katello/pulp/repository/file.rb +31 -0
  109. data/app/services/katello/pulp/repository/ostree.rb +40 -0
  110. data/app/services/katello/pulp/repository/puppet.rb +43 -0
  111. data/app/services/katello/pulp/repository/yum.rb +61 -0
  112. data/app/services/katello/repository_type.rb +1 -1
  113. data/app/views/katello/api/v2/content_facet/base.json.rabl +1 -0
  114. data/app/views/katello/api/v2/content_view_versions/base.json.rabl +0 -1
  115. data/app/views/katello/api/v2/errata/_counts.json.rabl +0 -1
  116. data/app/views/katello/api/v2/errata/show.json.rabl +9 -3
  117. data/app/views/katello/api/v2/host_collections/delta_activation_keys.rabl +0 -1
  118. data/app/views/katello/api/v2/host_module_streams/base.json.rabl +8 -0
  119. data/app/views/katello/api/v2/host_module_streams/index.json.rabl +7 -0
  120. data/app/views/katello/api/v2/packages/backend.json.rabl +0 -1
  121. data/app/views/katello/api/v2/repositories/show.json.rabl +6 -6
  122. data/app/views/katello/layouts/react.html.erb +2 -2
  123. data/app/views/overrides/activation_keys/_host_synced_content_select.html.erb +0 -1
  124. data/config/routes/api/rhsm.rb +1 -0
  125. data/config/routes/overrides.rb +4 -0
  126. data/db/migrate/20181008201422_add_modules_to_errata_packages.rb +29 -0
  127. data/db/migrate/20181017181806_available_module_streams.rb +34 -0
  128. data/db/migrate/20181027014323_add_applicable_modules.rb +24 -0
  129. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/module-stream-actions.service.js +2 -1
  130. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/views/content-credential-info.html +1 -1
  131. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/new/views/new-content-credential.html +1 -0
  132. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-host-bulk-module-streams-modal.html +2 -2
  133. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-errata-modal.html +37 -22
  134. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +4 -1
  135. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-module-streams.controller.js +27 -7
  136. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-module-streams.html +29 -0
  137. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/errata-details.html +15 -1
  138. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +1 -1
  139. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-promotion.controller.js +0 -1
  140. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-publish.controller.js +1 -2
  141. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-versions.controller.js +3 -1
  142. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/histories/content-view-history.controller.js +1 -1
  143. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-promotion.html +0 -15
  144. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-publish.html +0 -14
  145. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum.controller.js +19 -0
  146. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-info.html +0 -12
  147. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-packages.html +36 -0
  148. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum.html +7 -0
  149. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/errata.routes.js +9 -0
  150. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-module-streams.factory.js +18 -0
  151. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +4 -2
  152. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +2 -2
  153. data/engines/bastion_katello/app/assets/stylesheets/bastion_katello/bastion_katello.scss +13 -0
  154. data/lib/katello/permissions/host_permissions.rb +3 -0
  155. data/lib/katello/repository_types/deb.rb +3 -1
  156. data/lib/katello/repository_types/docker.rb +3 -1
  157. data/lib/katello/repository_types/file.rb +1 -0
  158. data/lib/katello/repository_types/ostree.rb +3 -1
  159. data/lib/katello/repository_types/puppet.rb +3 -1
  160. data/lib/katello/repository_types/yum.rb +3 -1
  161. data/lib/katello/tasks/delete_orphaned_content.rake +1 -1
  162. data/lib/katello/tasks/reset.rake +1 -0
  163. data/lib/katello/tasks/test.rake +14 -0
  164. data/lib/katello/tasks/unify_hosts.rake +2 -0
  165. data/lib/katello/tasks/virt_who_report.rake +2 -1
  166. data/lib/katello/version.rb +1 -1
  167. data/locale/Makefile +52 -17
  168. data/locale/update-i18n +22 -0
  169. data/package.json +11 -1
  170. data/webpack/__mocks__/foremanReact/components/common/EmptyState.js +8 -0
  171. data/webpack/move_to_foreman/components/common/table/components/Table.js +2 -1
  172. data/webpack/move_to_pf/react-bootstrap-select/index.js +4 -2
  173. data/webpack/move_to_pf/test-utils/testHelpers.js +9 -0
  174. data/webpack/redux/OrganizationProducts/OrganizationProductsActions.js +24 -0
  175. data/webpack/redux/OrganizationProducts/OrganizationProductsConstants.js +5 -0
  176. data/webpack/redux/OrganizationProducts/OrganizationProductsReducer.js +38 -0
  177. data/webpack/redux/OrganizationProducts/OrganizationProductsSelectors.js +7 -0
  178. data/webpack/redux/OrganizationProducts/__tests__/OrganizationProductsActions.test.js +47 -0
  179. data/webpack/redux/OrganizationProducts/__tests__/OrganizationProductsReducer.test.js +33 -0
  180. data/webpack/redux/OrganizationProducts/__tests__/OrganizationProductsSelectors.test.js +19 -0
  181. data/webpack/redux/OrganizationProducts/__tests__/__snapshots__/OrganizationProductsActions.test.js.snap +49 -0
  182. data/webpack/redux/OrganizationProducts/__tests__/__snapshots__/OrganizationProductsReducer.test.js.snap +36 -0
  183. data/webpack/redux/OrganizationProducts/__tests__/__snapshots__/OrganizationProductsSelectors.test.js.snap +9 -0
  184. data/webpack/redux/OrganizationProducts/index.js +13 -0
  185. data/webpack/redux/actions/RedHatRepositories/enabled.js +7 -1
  186. data/webpack/redux/actions/RedHatRepositories/helpers.js +4 -0
  187. data/webpack/redux/actions/RedHatRepositories/sets.js +2 -0
  188. data/webpack/redux/reducers/RedHatRepositories/enabled.fixtures.js +8 -2
  189. data/webpack/redux/reducers/RedHatRepositories/enabled.js +1 -1
  190. data/webpack/redux/reducers/RedHatRepositories/sets.fixtures.js +12 -3
  191. data/webpack/redux/reducers/index.js +2 -0
  192. data/webpack/scenes/RedHatRepositories/components/SearchBar.js +68 -33
  193. data/webpack/scenes/RedHatRepositories/index.js +13 -2
  194. data/webpack/scenes/RedHatRepositories/index.scss +26 -0
  195. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +1 -1
  196. data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +1 -1
  197. data/webpack/scenes/Subscriptions/SubscriptionActions.js +18 -2
  198. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +8 -0
  199. data/webpack/scenes/Subscriptions/SubscriptionHelpers.js +15 -0
  200. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +22 -14
  201. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +39 -90
  202. data/webpack/scenes/Subscriptions/SubscriptionsSelectors.js +14 -0
  203. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +1 -3
  204. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +0 -1
  205. data/webpack/scenes/Subscriptions/__tests__/SubscriptionHelpers.test.js +84 -0
  206. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsActions.test.js +26 -1
  207. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +5 -0
  208. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsReducer.test.js +177 -75
  209. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsSelectors.test.js +29 -0
  210. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionHelpers.test.js.snap +31 -0
  211. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap +32 -0
  212. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +18 -96
  213. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsReducer.test.js.snap +511 -0
  214. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsSelectors.test.js.snap +26 -0
  215. data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +6 -1
  216. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +3 -21
  217. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +113 -0
  218. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.test.js +47 -0
  219. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/__snapshots__/SubscriptionsToolbar.test.js.snap +504 -0
  220. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/index.js +1 -0
  221. data/webpack/scenes/Subscriptions/index.js +15 -4
  222. metadata +59 -14
  223. data/app/lib/actions/pulp/repository/associate_distributor.rb +0 -20
  224. data/app/lib/actions/pulp/repository/associate_importer.rb +0 -23
  225. data/app/lib/actions/pulp/repository/delete_distributor.rb +0 -18
  226. data/app/lib/actions/pulp/repository/refresh_distributor.rb +0 -19
  227. data/app/lib/actions/pulp/repository/update_importer.rb +0 -33
  228. data/app/lib/katello/bulk_actions.rb +0 -63
  229. data/webpack/move_to_foreman/components/common/EmptyState/index.js +0 -68
@@ -48,6 +48,10 @@ module Katello
48
48
  RepositoryErratum
49
49
  end
50
50
 
51
+ def self.content_facet_association_class
52
+ ContentFacetErratum
53
+ end
54
+
51
55
  def self.applicable_to_hosts(hosts)
52
56
  # Note: ContentFacetErrata actually holds the "Applicable Errata" to that host
53
57
  # It is not the errata "belonging" to the host. Its rather the errata that is "applicable"
@@ -88,32 +92,11 @@ module Katello
88
92
  end
89
93
 
90
94
  def self.installable_for_hosts(hosts = nil)
91
- self.where(:id => ids_installable_for_hosts(hosts))
95
+ ApplicableContentHelper.new(Erratum).installable_for_hosts(hosts)
92
96
  end
93
97
 
94
98
  def self.ids_installable_for_hosts(hosts = nil)
95
- hosts = ::Host.where(:id => hosts) if hosts && hosts.is_a?(Array)
96
-
97
- # Main goal of this query
98
- # 1) Get me the applicable errata for these set of hosts
99
- # 2) Now further prune this list. Only include errata from repos that have been "enabled" on those hosts.
100
- # In other words, prune the list to only include the errate in the "bound" repositories signified by
101
- # the inner join between ContentFacetRepository and RepositoryErratum
102
- query = self.joins(:content_facet_errata).
103
- joins("INNER JOIN #{Katello::ContentFacetRepository.table_name} on \
104
- #{Katello::ContentFacetRepository.table_name}.content_facet_id = #{Katello::ContentFacetErratum.table_name}.content_facet_id").
105
- joins("INNER JOIN #{Katello::RepositoryErratum.table_name} AS host_repo_errata ON \
106
- host_repo_errata.erratum_id = #{Katello::Erratum.table_name}.id AND \
107
- #{Katello::ContentFacetRepository.table_name}.repository_id = host_repo_errata.repository_id")
108
-
109
- if hosts
110
- query = query.where("#{Katello::ContentFacetRepository.table_name}.content_facet_id" => hosts.joins(:content_facet)
111
- .select("#{Katello::Host::ContentFacet.table_name}.id"))
112
- else
113
- query = query.joins(:content_facet_errata)
114
- end
115
-
116
- query
99
+ installable_for_hosts(hosts).select(:id)
117
100
  end
118
101
 
119
102
  def update_from_json(json)
@@ -136,6 +119,7 @@ module Katello
136
119
  end
137
120
  end
138
121
  update_packages(json['pkglist']) unless json['pkglist'].blank?
122
+ update_modules(json['pkglist']) unless json['pkglist'].blank?
139
123
  end
140
124
 
141
125
  def self.list_filenames_by_clauses(repo, clauses)
@@ -149,6 +133,21 @@ module Katello
149
133
  where(statement).pluck(:filename)
150
134
  end
151
135
 
136
+ def module_streams
137
+ # return something like
138
+ # {module_stream => [packages]}
139
+ module_stream_rpms = {}
140
+ packages.each do |pack|
141
+ pack.module_streams.each do |mod|
142
+ module_stream_rpms[mod.module_spec_hash] ||= []
143
+ module_stream_rpms[mod.module_spec_hash] << pack.nvrea unless module_stream_rpms[mod.module_spec_hash].include?(pack.nvrea)
144
+ end
145
+ end
146
+ module_stream_rpms.map do |module_hash, nvreas|
147
+ module_hash.merge(:packages => nvreas)
148
+ end
149
+ end
150
+
152
151
  private
153
152
 
154
153
  def convert_date_if_epoch(date)
@@ -200,7 +199,7 @@ module Katello
200
199
  needed_function = lambda do
201
200
  package_hashes = json.map { |list| list['packages'] }.flatten
202
201
  package_attributes = package_hashes.map do |hash|
203
- nvrea = "#{hash['name']}-#{hash['version']}-#{hash['release']}.#{hash['arch']}"
202
+ nvrea = Util::Package.build_nvra(hash)
204
203
  {'name' => hash['name'], 'nvrea' => nvrea, 'filename' => hash['filename']}
205
204
  end
206
205
  existing_nvreas = self.packages.pluck(:nvrea)
@@ -213,6 +212,37 @@ module Katello
213
212
  run_until(needed_function, action_function)
214
213
  end
215
214
 
215
+ def update_modules(json)
216
+ needed_function = lambda do
217
+ module_stream_attributes = []
218
+ json.each do |package_item|
219
+ if package_item['module']
220
+ module_stream = ModuleStream.where(package_item['module']).first_or_create!
221
+ nvreas = package_item["packages"].map { |hash| Util::Package.build_nvra(hash) }
222
+ module_stream_id_column = "#{ModuleStreamErratumPackage.table_name}.module_stream_id"
223
+ existing = ErratumPackage.joins(:module_streams).
224
+ where(module_stream_id_column => module_stream.id,
225
+ :nvrea => nvreas).pluck(:nvrea)
226
+
227
+ (nvreas - existing).each do |nvrea|
228
+ package = self.packages.find_by(:nvrea => nvrea)
229
+ module_stream_attributes << { :module_stream_id => module_stream.id,
230
+ :erratum_package_id => package.id }
231
+ end
232
+ end
233
+ end
234
+ module_stream_attributes.uniq
235
+ end
236
+
237
+ action_function = lambda do |needed|
238
+ needed.each do |msep|
239
+ ModuleStreamErratumPackage.create!(msep)
240
+ end
241
+ end
242
+
243
+ run_until(needed_function, action_function)
244
+ end
245
+
216
246
  class Jail < ::Safemode::Jail
217
247
  allow :errata_id, :errata_type, :issued, :created_at, :severity, :package_names, :cves, :reboot_suggested
218
248
  end
@@ -1,5 +1,11 @@
1
1
  module Katello
2
2
  class ErratumPackage < Katello::Model
3
3
  belongs_to :erratum, :inverse_of => :packages, :class_name => 'Katello::Erratum'
4
+ has_many :module_stream_errata_packages, class_name: "Katello::ModuleStreamErratumPackage", dependent: :destroy, inverse_of: :erratum_package
5
+ has_many :module_streams, class_name: "Katello::ModuleStream", :through => :module_stream_errata_packages
6
+
7
+ def self.non_module_stream_packages
8
+ where.not(:id => Katello::ModuleStreamErratumPackage.select(:erratum_package_id))
9
+ end
4
10
  end
5
11
  end
@@ -2,7 +2,6 @@ module Katello
2
2
  module Glue::Pulp::Repo
3
3
  # TODO: move into submodules
4
4
  # rubocop:disable MethodLength
5
- # rubocop:disable ModuleLength
6
5
  def self.included(base)
7
6
  base.send :include, LazyAccessor
8
7
  base.send :include, InstanceMethods
@@ -116,233 +115,12 @@ module Katello
116
115
  pulp_repo_facts[:content_unit_counts].values.all? { |value| value == 0 }
117
116
  end
118
117
 
119
- def create_pulp_repo
120
- #if we are in library, no need for an distributor, but need to sync
121
- if self.environment.try(:library?)
122
- importer = generate_importer
123
- else
124
- #if not in library, no need for sync info, but we need a distributor
125
- case self.content_type
126
- when Repository::YUM_TYPE
127
- importer = Runcible::Models::YumImporter.new
128
- when Repository::PUPPET_TYPE
129
- importer = Runcible::Models::PuppetImporter.new
130
- when Repository::DEB_TYPE
131
- importer = Runcible::Models::DebImporter.new
132
- end
133
- end
134
-
135
- distributors = generate_distributors
136
-
137
- Katello.pulp_server.extensions.repository.create_with_importer_and_distributors(self.pulp_id,
138
- importer,
139
- distributors,
140
- :display_name => self.name)
141
- rescue RestClient::ServiceUnavailable => e
142
- message = _("Pulp service unavailable during creating repository '%s', please try again later.") % self.name
143
- raise PulpErrors::ServiceUnavailable.new(message, e)
144
- end
145
-
146
118
  def generate_importer(capsule = SmartProxy.default_capsule!)
147
- case self.content_type
148
- when Repository::YUM_TYPE
149
- Runcible::Models::YumImporter.new(yum_importer_values(capsule))
150
- when Repository::FILE_TYPE
151
- Runcible::Models::IsoImporter.new(importer_connection_options(capsule).merge(:feed => importer_feed_url(capsule)))
152
- when Repository::PUPPET_TYPE
153
- Runcible::Models::PuppetImporter.new(puppet_importer_values(capsule))
154
- when Repository::DOCKER_TYPE
155
- options = {}
156
- options[:upstream_name] = capsule.default_capsule? ? self.docker_upstream_name : self.container_repository_name
157
- options[:feed] = docker_feed_url(capsule)
158
- options[:enable_v1] = false
159
- options[:tags] = capsule.default_capsule? ? self.docker_tags_whitelist : nil
160
- Runcible::Models::DockerImporter.new(importer_connection_options(capsule).merge(options))
161
- when Repository::OSTREE_TYPE
162
- options = importer_connection_options(capsule)
163
- options[:depth] = capsule.default_capsule? ? root.compute_ostree_upstream_sync_depth : ostree_capsule_sync_depth
164
- options[:feed] = self.importer_feed_url(capsule)
165
- Runcible::Models::OstreeImporter.new(options)
166
- when Repository::DEB_TYPE
167
- Runcible::Models::DebImporter.new(deb_importer_values(capsule))
168
- else
169
- fail _("Unexpected repo type %s") % self.content_type
170
- end
171
- end
172
-
173
- def docker_feed_url(capsule = SmartProxy.default_capsule!)
174
- pulp_uri = URI.parse(SETTINGS[:katello][:pulp][:url])
175
- if capsule.default_capsule?
176
- self.url if self.respond_to?(:url)
177
- else
178
- "https://#{pulp_uri.host.downcase}:#{Setting['pulp_docker_registry_port']}"
179
- end
180
- end
181
-
182
- def importer_feed_url(capsule = SmartProxy.default_capsule!)
183
- if capsule.default_capsule?
184
- self.url if self.respond_to?(:url)
185
- else
186
- self.full_path(nil, true)
187
- end
188
- end
189
-
190
- def yum_importer_values(capsule)
191
- if capsule.default_capsule?
192
- new_download_policy = self.download_policy
193
- else
194
- new_download_policy = capsule_download_policy(capsule)
195
- end
196
-
197
- config = {
198
- :feed => self.importer_feed_url(capsule),
199
- :download_policy => new_download_policy,
200
- :remove_missing => capsule.default_capsule? ? self.mirror_on_sync? : true
201
- }
202
- config[:type_skip_list] = ignorable_content if ignorable_content
203
- config.merge(importer_connection_options(capsule))
204
- end
205
-
206
- def proxy_host_value
207
- self.ignore_global_proxy ? "" : nil
208
- end
209
-
210
- def puppet_importer_values(capsule)
211
- config = {
212
- :feed => self.importer_feed_url(capsule),
213
- :remove_missing => capsule.default_capsule? ? self.mirror_on_sync? : true
214
- }
215
- config.merge(importer_connection_options(capsule))
216
- end
217
-
218
- def deb_importer_values(capsule)
219
- config = {
220
- feed: self.importer_feed_url(capsule),
221
- releases: self.deb_releases,
222
- components: self.deb_components,
223
- architectures: self.deb_architectures
224
- }
225
- config.merge(importer_connection_options(capsule))
226
- end
227
-
228
- def importer_connection_options(capsule = SmartProxy.default_capsule!)
229
- if !capsule.default_capsule?
230
- ueber_cert = ::Cert::Certs.ueber_cert(organization)
231
- importer_options = {
232
- :ssl_client_cert => ueber_cert[:cert],
233
- :ssl_client_key => ueber_cert[:key],
234
- :ssl_ca_cert => ::Cert::Certs.ca_cert
235
- }
236
- elsif self.try(:redhat?) && self.content_view.default? && Katello::Resources::CDN::CdnResource.redhat_cdn?(url)
237
- importer_options = {
238
- :ssl_client_cert => self.product.certificate,
239
- :ssl_client_key => self.product.key,
240
- :ssl_ca_cert => Katello::Repository.feed_ca_cert(url),
241
- :proxy_host => self.proxy_host_value
242
- }
243
- elsif self.ssl_client_cert && self.ssl_client_key && self.ssl_ca_cert
244
- importer_options = {
245
- :ssl_client_cert => self.ssl_client_cert.content,
246
- :ssl_client_key => self.ssl_client_key.content,
247
- :ssl_ca_cert => self.ssl_ca_cert.content
248
- }
249
- else
250
- importer_options = {
251
- :ssl_client_cert => nil,
252
- :ssl_client_key => nil,
253
- :ssl_ca_cert => nil,
254
- :proxy_host => self.proxy_host_value
255
- }
256
- end
257
- unless self.is_a?(::Katello::ContentViewPuppetEnvironment)
258
- importer_options.merge!(:ssl_validation => verify_ssl_on_sync?)
259
- if capsule.default_capsule?
260
- importer_options.merge!(:basic_auth_username => upstream_username,
261
- :basic_auth_password => upstream_password)
262
- end
263
- end
264
- importer_options
119
+ backend_service(capsule).generate_importer
265
120
  end
266
121
 
267
122
  def generate_distributors(capsule = SmartProxy.default_capsule!)
268
- case self.content_type
269
- when Repository::YUM_TYPE
270
- yum_dist_id = self.pulp_id
271
- yum_dist_options = {:protected => true, :id => yum_dist_id, :auto_publish => true}
272
- yum_dist_options[:skip] = ignorable_content if ignorable_content
273
- #check the instance variable, as we do not want to go to pulp
274
- yum_dist_options['checksum_type'] = self.saved_checksum_type || self.checksum_type
275
- yum_dist = Runcible::Models::YumDistributor.new(self.relative_path, self.unprotected, true,
276
- yum_dist_options)
277
- clone_dist = Runcible::Models::YumCloneDistributor.new(:id => "#{self.pulp_id}_clone",
278
- :destination_distributor_id => yum_dist_id)
279
- export_dist = Runcible::Models::ExportDistributor.new(false, false, self.relative_path)
280
- distributors = [yum_dist, export_dist]
281
- distributors << clone_dist if capsule.default_capsule?
282
- when Repository::FILE_TYPE
283
- dist = Runcible::Models::IsoDistributor.new(self.relative_path, self.unprotected, true, auto_publish: true)
284
- distributors = [dist]
285
- when Repository::PUPPET_TYPE
286
- capsule ||= SmartProxy.default_capsule!
287
- dist_options = { :id => self.pulp_id, :auto_publish => true }
288
- repo_path = File.join(capsule.puppet_path,
289
- Environment.construct_name(self.organization,
290
- self.environment,
291
- self.content_view),
292
- 'modules')
293
- puppet_install_dist = Runcible::Models::PuppetInstallDistributor.new(repo_path, dist_options)
294
-
295
- dist_options[:id] = "#{self.pulp_id}_puppet"
296
- puppet_dist = Runcible::Models::PuppetDistributor.new(nil, (self.unprotected || false),
297
- true, dist_options)
298
-
299
- distributors = [puppet_dist, puppet_install_dist]
300
- when Repository::DOCKER_TYPE
301
- options = { :protected => !self.unprotected, :id => self.pulp_id, :auto_publish => true,
302
- :repo_registry_id => container_repository_name}
303
- docker_dist = Runcible::Models::DockerDistributor.new(options)
304
- distributors = [docker_dist]
305
- when Repository::OSTREE_TYPE
306
- options = { :id => self.pulp_id,
307
- :auto_publish => true,
308
- :relative_path => relative_path,
309
- :depth => self.root.compute_ostree_upstream_sync_depth }
310
-
311
- dist = Runcible::Models::OstreeDistributor.new(options)
312
- distributors = [dist]
313
- when Repository::DEB_TYPE
314
- options = {
315
- id: self.pulp_id,
316
- auto_publish: true
317
- }
318
- http = self.unprotected
319
- https = true
320
- dist = Runcible::Models::DebDistributor.new(self.relative_path, http, https, options)
321
- distributors = [dist]
322
- else
323
- fail _("Unexpected repo type %s") % self.content_type
324
- end
325
-
326
- distributors
327
- end
328
-
329
- def importer_type
330
- case self.content_type
331
- when Repository::YUM_TYPE
332
- Runcible::Models::YumImporter::ID
333
- when Repository::FILE_TYPE
334
- Runcible::Models::IsoImporter::ID
335
- when Repository::PUPPET_TYPE
336
- Runcible::Models::PuppetImporter::ID
337
- when Repository::DOCKER_TYPE
338
- Runcible::Models::DockerImporter::ID
339
- when Repository::OSTREE_TYPE
340
- Runcible::Models::OstreeImporter::ID
341
- when Repository::DEB_TYPE
342
- Runcible::Models::DebImporter::ID
343
- else
344
- fail _("Unexpected repo type %s") % self.content_type
345
- end
123
+ backend_service(capsule).generate_distributors
346
124
  end
347
125
 
348
126
  def populate_from(repos_map)
@@ -575,14 +353,13 @@ module Katello
575
353
  generated.delete('checksum_type')
576
354
  actual.delete('checksum_type')
577
355
  end
578
- generated.delete('repo-registry-id')
579
- generated == actual
356
+ generated.compact == actual.compact
580
357
  end
581
358
 
582
359
  def importer_matches?(capsule_importer, capsule)
583
360
  generated_importer = self.generate_importer(capsule)
584
361
  capsule_importer.try(:[], 'importer_type_id') == generated_importer.id &&
585
- generated_importer.config == capsule_importer['config']
362
+ generated_importer.config.compact == capsule_importer['config'].compact
586
363
  end
587
364
 
588
365
  protected
@@ -635,9 +412,9 @@ module Katello
635
412
  if self.master?
636
413
  Katello::Rpm.import_for_repository(self, full_index)
637
414
  Katello::Srpm.import_for_repository(self, full_index)
415
+ Katello::ModuleStream.import_for_repository(self)
638
416
  Katello::Erratum.import_for_repository(self)
639
417
  Katello::PackageGroup.import_for_repository(self)
640
- Katello::ModuleStream.import_for_repository(self)
641
418
  self.import_distribution_data
642
419
  else
643
420
  index_linked_repo
@@ -2,6 +2,7 @@ module Katello
2
2
  class GpgKey < Katello::Model
3
3
  audited :associations => [:products]
4
4
 
5
+ include ForemanTasks::Concerns::ActionSubject
5
6
  include Katello::Authorization::GpgKey
6
7
  MAX_CONTENT_LINE_LENGTH = 65
7
8
 
@@ -19,6 +19,9 @@ module Katello
19
19
  has_many :content_facet_applicable_rpms, :class_name => "Katello::ContentFacetApplicableRpm", :dependent => :delete_all, :inverse_of => :content_facet
20
20
  has_many :applicable_rpms, :through => :content_facet_applicable_rpms, :class_name => "Katello::Rpm", :source => :rpm
21
21
 
22
+ has_many :content_facet_applicable_module_streams, :class_name => "Katello::ContentFacetApplicableModuleStream", :dependent => :delete_all, :inverse_of => :content_facet
23
+ has_many :applicable_module_streams, :through => :content_facet_applicable_module_streams, :class_name => "Katello::ModuleStream", :source => :module_stream
24
+
22
25
  validates :content_view, :presence => true, :allow_blank => false
23
26
  validates :lifecycle_environment, :presence => true, :allow_blank => false
24
27
  validates_with ::AssociationExistsValidator, attributes: [:content_source]
@@ -49,21 +52,15 @@ module Katello
49
52
  end
50
53
 
51
54
  def installable_errata(env = nil, content_view = nil)
52
- repos = if env && content_view
53
- Katello::Repository.in_environment(env).in_content_views([content_view])
54
- else
55
- self.bound_repositories.pluck(:id)
56
- end
57
- self.applicable_errata.in_repositories(repos)
55
+ ApplicableContentHelper.new(Erratum, self).installable(env, content_view)
58
56
  end
59
57
 
60
58
  def installable_rpms(env = nil, content_view = nil)
61
- repos = if env && content_view
62
- Katello::Repository.in_environment(env).in_content_views([content_view])
63
- else
64
- self.bound_repositories.pluck(:id)
65
- end
66
- self.applicable_rpms.in_repositories(repos)
59
+ ApplicableContentHelper.new(Rpm, self).installable(env, content_view)
60
+ end
61
+
62
+ def installable_module_streams(env = nil, content_view = nil)
63
+ ApplicableContentHelper.new(ModuleStream, self).installable(env, content_view)
67
64
  end
68
65
 
69
66
  def errata_counts
@@ -77,6 +74,7 @@ module Katello
77
74
  end
78
75
 
79
76
  def import_applicability(partial = false)
77
+ import_module_stream_applicability(partial)
80
78
  import_errata_applicability(partial)
81
79
  import_rpm_applicability(partial)
82
80
  update_applicability_counts
@@ -88,54 +86,24 @@ module Katello
88
86
  :installable_bugfix_errata_count => self.installable_errata.bugfix.count,
89
87
  :installable_enhancement_errata_count => self.installable_errata.enhancement.count,
90
88
  :applicable_rpm_count => self.content_facet_applicable_rpms.count,
91
- :upgradable_rpm_count => self.installable_rpms.count
89
+ :upgradable_rpm_count => self.installable_rpms.count,
90
+ :applicable_module_stream_count => self.content_facet_applicable_module_streams.count,
91
+ :upgradable_module_stream_count => self.installable_module_streams.count
92
92
  )
93
93
  self.save!(:validate => false)
94
94
  end
95
95
 
96
96
  def import_rpm_applicability(partial)
97
- to_add, to_remove = applicable_rpm_differences(partial)
98
- Katello::ContentFacetApplicableRpm.where(:content_facet_id => self.id).delete_all unless partial
99
- ActiveRecord::Base.transaction do
100
- insert_rpm_applicability(to_add) unless to_add.blank?
101
- remove_rpm_applicability(to_remove) unless to_remove.blank?
102
- end
97
+ ApplicableContentHelper.new(Rpm, self).import(partial)
103
98
  end
104
99
 
105
100
  def import_errata_applicability(partial)
106
- to_add, to_remove = applicable_errata_differences(partial)
107
- Katello::ContentFacetErratum.where(:content_facet_id => self.id).delete_all unless partial
108
- ActiveRecord::Base.transaction do
109
- insert_errata_applicability(to_add) unless to_add.blank?
110
- remove_errata_applicability(to_remove) unless to_remove.blank?
111
- end
101
+ ApplicableContentHelper.new(Erratum, self).import(partial)
112
102
  self.update_errata_status
113
103
  end
114
104
 
115
- def applicable_errata_differences(partial)
116
- errata_uuids = ::Katello::Pulp::Consumer.new(self.uuid).applicable_errata_ids
117
- if partial
118
- consumer_uuids = applicable_errata.pluck("#{Erratum.table_name}.uuid")
119
- to_remove = consumer_uuids - errata_uuids
120
- to_add = errata_uuids - consumer_uuids
121
- else
122
- to_add = errata_uuids
123
- to_remove = nil
124
- end
125
- [to_add, to_remove]
126
- end
127
-
128
- def applicable_rpm_differences(partial)
129
- rpm_uuids = ::Katello::Pulp::Consumer.new(self.uuid).applicable_rpm_ids
130
- if partial
131
- consumer_uuids = applicable_rpms.pluck("#{Rpm.table_name}.uuid")
132
- to_remove = consumer_uuids - rpm_uuids
133
- to_add = rpm_uuids - consumer_uuids
134
- else
135
- to_add = rpm_uuids
136
- to_remove = nil
137
- end
138
- [to_add, to_remove]
105
+ def import_module_stream_applicability(partial)
106
+ ApplicableContentHelper.new(ModuleStream, self).import(partial)
139
107
  end
140
108
 
141
109
  def self.in_content_view_version_environments(version_environments)
@@ -148,10 +116,27 @@ module Katello
148
116
  where(queries.join(" OR "))
149
117
  end
150
118
 
151
- def self.with_non_installable_errata(errata)
152
- subquery = Katello::Erratum.select("#{Katello::Erratum.table_name}.id").ids_installable_for_hosts
153
- .where("#{Katello::ContentFacetRepository.table_name}.content_facet_id = #{Katello::Host::ContentFacet.table_name}.id").to_sql
154
- self.joins(:applicable_errata).where("#{Katello::Erratum.table_name}.id" => errata).where("#{Katello::Erratum.table_name}.id NOT IN (#{subquery})").distinct
119
+ def self.with_non_installable_errata(errata, hosts = nil)
120
+ content_facets = Katello::Host::ContentFacet.select(:id).where(:host_id => hosts)
121
+ reachable_repos = ::Katello::ContentFacetRepository.where(content_facet_id: content_facets).distinct.pluck(:repository_id)
122
+ installable_errata = ::Katello::ContentFacetErratum.select(:id).
123
+ where(content_facet_id: content_facets).
124
+ joins(
125
+ "inner join #{::Katello::RepositoryErratum.table_name} ON #{Katello::ContentFacetErratum.table_name}.erratum_id = #{Katello::RepositoryErratum.table_name}.erratum_id",
126
+ "inner JOIN #{Katello::ContentFacetRepository.table_name} "\
127
+ "ON #{Katello::ContentFacetErratum.table_name}.content_facet_id = #{Katello::ContentFacetRepository.table_name}.content_facet_id "\
128
+ "AND #{Katello::RepositoryErratum.table_name}.repository_id = #{Katello::ContentFacetRepository.table_name}.repository_id"
129
+ ).
130
+ where("#{Katello::RepositoryErratum.table_name}.repository_id" => reachable_repos).
131
+ where("#{Katello::RepositoryErratum.table_name}.erratum_id" => errata).
132
+ where("#{Katello::ContentFacetRepository.table_name}.repository_id" => reachable_repos).
133
+ where("#{Katello::ContentFacetRepository.table_name}.content_facet_id" => content_facets)
134
+
135
+ non_installable_errata = ::Katello::ContentFacetErratum.select(:content_facet_id).
136
+ where.not(id: installable_errata).
137
+ where(content_facet_id: content_facets, erratum_id: errata)
138
+
139
+ Katello::Host::ContentFacet.where(id: non_installable_errata)
155
140
  end
156
141
 
157
142
  def self.with_applicable_errata(errata)
@@ -207,36 +192,6 @@ module Katello
207
192
  facet_attributes[:content_source_id] ||= hostgroup.inherited_content_source_id
208
193
  facet_attributes
209
194
  end
210
-
211
- private
212
-
213
- def insert_rpm_applicability(uuids)
214
- applicable_rpm_ids = ::Katello::Rpm.where(:uuid => uuids).pluck(:id)
215
- unless applicable_rpm_ids.empty?
216
- inserts = applicable_rpm_ids.map { |erratum_id| "(#{erratum_id.to_i}, #{self.id.to_i})" }
217
- sql = "INSERT INTO #{Katello::ContentFacetApplicableRpm.table_name} (rpm_id, content_facet_id) VALUES #{inserts.join(', ')}"
218
- ActiveRecord::Base.connection.execute(sql)
219
- end
220
- end
221
-
222
- def remove_rpm_applicability(uuids)
223
- applicable_rpm_ids = ::Katello::Rpm.where(:uuid => uuids).pluck(:id)
224
- Katello::ContentFacetApplicableRpm.where(:content_facet_id => self.id, :rpm_id => applicable_rpm_ids).delete_all
225
- end
226
-
227
- def insert_errata_applicability(uuids)
228
- applicable_errata_ids = ::Katello::Erratum.where(:uuid => uuids).pluck(:id)
229
- unless applicable_errata_ids.empty?
230
- inserts = applicable_errata_ids.map { |erratum_id| "(#{erratum_id.to_i}, #{self.id.to_i})" }
231
- sql = "INSERT INTO #{Katello::ContentFacetErratum.table_name} (erratum_id, content_facet_id) VALUES #{inserts.join(', ')}"
232
- ActiveRecord::Base.connection.execute(sql)
233
- end
234
- end
235
-
236
- def remove_errata_applicability(uuids)
237
- applicable_errata_ids = ::Katello::Erratum.where(:uuid => uuids).pluck(:id)
238
- Katello::ContentFacetErratum.where(:content_facet_id => self.id, :erratum_id => applicable_errata_ids).delete_all
239
- end
240
195
  end
241
196
  end
242
197
  end