katello 3.16.0.rc2 → 3.16.0.rc2.1

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/app/lib/actions/katello/repository/update.rb +12 -1
  3. data/app/lib/actions/katello/repository/update_cv_repo_cert_guard.rb +17 -0
  4. data/app/lib/actions/pulp3/ContentGuard/refresh.rb +19 -0
  5. data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +6 -8
  6. data/app/lib/actions/pulp3/orchestration/repository/generate_metadata.rb +1 -1
  7. data/app/lib/actions/pulp3/repository/copy_content.rb +1 -0
  8. data/app/lib/actions/pulp3/repository/refresh_distribution.rb +1 -0
  9. data/app/lib/actions/pulp3/repository/save_distribution_references.rb +3 -1
  10. data/app/lib/actions/pulp3/repository/save_version.rb +3 -1
  11. data/app/lib/actions/pulp3/repository/update_cv_repository_cert_guard.rb +15 -0
  12. data/app/lib/katello/util/errata.rb +13 -0
  13. data/app/lib/katello/util/pulpcore_content_filters.rb +32 -0
  14. data/app/models/katello/concerns/pulp_database_unit.rb +2 -2
  15. data/app/models/katello/content_view_erratum_filter.rb +29 -0
  16. data/app/models/katello/content_view_package_filter.rb +16 -1
  17. data/app/models/katello/content_view_package_group_filter.rb +7 -0
  18. data/app/models/katello/package_group.rb +2 -1
  19. data/app/models/katello/pulp3/content_guard.rb +14 -0
  20. data/app/services/katello/pulp/pulp_content_unit.rb +4 -0
  21. data/app/services/katello/pulp3/api/content_guard.rb +45 -0
  22. data/app/services/katello/pulp3/api/yum.rb +24 -0
  23. data/app/services/katello/pulp3/erratum.rb +4 -0
  24. data/app/services/katello/pulp3/pulp_content_unit.rb +4 -0
  25. data/app/services/katello/pulp3/repository.rb +21 -5
  26. data/app/services/katello/pulp3/repository/yum.rb +90 -3
  27. data/db/migrate/20200407171926_create_content_guard.rb +10 -0
  28. data/lib/katello/version.rb +1 -1
  29. data/webpack/scenes/Subscriptions/SubscriptionActions.js +12 -14
  30. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +14 -4
  31. data/webpack/scenes/Subscriptions/SubscriptionsSelectors.js +8 -0
  32. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsActions.test.js +10 -21
  33. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +11 -6
  34. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap +2 -4
  35. data/webpack/scenes/Subscriptions/index.js +5 -1
  36. data/webpack/scenes/Tasks/TaskActions.js +2 -1
  37. metadata +24 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d597d3adc595085248321cc7335d3ade0a0d6633b391e7914e673610caafe440
4
- data.tar.gz: e41d0dca5de9743da0db2fcc0eb0949db86ad30bfd90246fddac455a8778b173
3
+ metadata.gz: 07abcc2d0e780bd3bfee4cd44b73ef4183e0a50daebe6a32cd056e162e3fde52
4
+ data.tar.gz: 6c95fe44a013f6e74d36098c3e96f8e669f5670925620a9dc26e6ed674cc2abb
5
5
  SHA512:
6
- metadata.gz: 132a3d704edfa1a85d55462b58e01e08429fe44f64f0ed4de35698fa20b3350036b4c32da9d59f6d80b201ed8039d54f03f005bf81960420235fca63857e6071
7
- data.tar.gz: c45c05cc5b43fae7061bd985d551e27c5bd59072b41b38d90fe8f241654168c2280f4319d48de8e30cdc0a77e04be84a58e0f7b96342c582e551bf11dc4f790e
6
+ metadata.gz: 17dece7796e9c33d88970ed5eaba5d810db5b84c76ddc03d0767c8bf426013ac9c3e29f14a3bb3be6663e0233e8968551294f51000fb4161e348028add9ecb0b
7
+ data.tar.gz: c8b139917779fb48e642270141eb4418c4f668433307cb8097661b581985edc7163f67524328f13368c5cf80d7fc51ef2c856816eacb19ff9a720f40cef595d8
@@ -10,6 +10,8 @@ module Actions
10
10
  action_subject root.library_instance
11
11
 
12
12
  repo_params[:url] = nil if repo_params[:url] == ''
13
+ update_cv_cert_protected = (repo_params[:unprotected] != repository.unprotected)
14
+
13
15
  root.update!(repo_params)
14
16
 
15
17
  if root.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_BACKGROUND
@@ -44,15 +46,24 @@ module Actions
44
46
  ::Actions::Pulp3::Orchestration::Repository::Update],
45
47
  repository,
46
48
  SmartProxy.pulp_master)
47
- plan_self(:repository_id => root.library_instance.id)
49
+ plan_self(:repository_id => root.library_instance.id, :update_cv_cert_protected => update_cv_cert_protected)
48
50
  end
49
51
  end
50
52
 
51
53
  def run
52
54
  repository = ::Katello::Repository.find(input[:repository_id])
55
+ output[:repository_id] = input[:repository_id]
56
+ output[:update_cv_cert_protected] = input[:update_cv_cert_protected]
53
57
  ForemanTasks.async_task(Katello::Repository::MetadataGenerate, repository)
54
58
  end
55
59
 
60
+ def finalize
61
+ repository = ::Katello::Repository.find(output[:repository_id])
62
+ if output[:update_cv_cert_protected]
63
+ ForemanTasks.async_task(::Actions::Katello::Repository::UpdateCVRepoCertGuard, repository, SmartProxy.pulp_master)
64
+ end
65
+ end
66
+
56
67
  private
57
68
 
58
69
  def update_content?(repository)
@@ -0,0 +1,17 @@
1
+ module Actions
2
+ module Katello
3
+ module Repository
4
+ class UpdateCVRepoCertGuard < Actions::Base
5
+ include Actions::Katello::PulpSelector
6
+
7
+ def plan(repository, smart_proxy)
8
+ plan_optional_pulp_action([::Actions::Pulp3::Repository::UpdateCVRepositoryCertGuard], repository, smart_proxy)
9
+ end
10
+
11
+ def humanized_name
12
+ _("Updating repository authentication configuration")
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ module Actions
2
+ module Pulp3
3
+ module ContentGuard
4
+ class Refresh < Pulp3::Abstract
5
+ def plan(smart_proxy, options = {})
6
+ return if (::Katello::Pulp3::ContentGuard.count > 0 || options.try(:[], :update))
7
+ content_guard_api = ::Katello::Pulp3::Api::ContentGuard.new(smart_proxy)
8
+ if options.try(:[], :update)
9
+ content_guard_href = ::Katello::Pulp3::ContentGuard.first.href
10
+ content_guard_api.partial_update content_guard_href
11
+ else
12
+ content_guard_api.create
13
+ ::Katello::Pulp3::ContentGuard.import(smart_proxy)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -13,25 +13,23 @@ module Actions
13
13
  if filter_ids.present? || rpm_filenames.present? || source_repositories.length > 1
14
14
  sequence do
15
15
  if filter_ids.present? || rpm_filenames.present?
16
- copy_action = plan_action(Actions::Pulp3::Repository::CopyContent,
17
- source_repositories.first, smart_proxy, target_repo,
16
+ copy_action = plan_action(Actions::Pulp3::Repository::CopyContent, source_repositories.first, smart_proxy, target_repo,
18
17
  filter_ids: filter_ids, solve_dependencies: solve_dependencies,
19
18
  rpm_filenames: rpm_filenames)
20
-
21
- plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo, tasks: copy_action.output[:pulp_tasks])
19
+ plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo,
20
+ repository_details: { latest_version_href: copy_action.output[:latest_version_href] }, tasks: copy_action.output[:pulp_tasks])
22
21
  else
23
22
  #if we are not filtering, copy the version to the cv repository, and the units for each additional repo
24
23
  action = plan_action(Actions::Pulp3::Repository::CopyVersion, source_repositories.first, smart_proxy, target_repo)
25
- plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo, tasks: action.output[:pulp_tasks])
24
+ plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo,
25
+ repository_details: { latest_version_href: action.output[:latest_version_output] }, tasks: action.output[:pulp_tasks])
26
26
  copy_actions = []
27
27
  #since we're creating a new version from the first repo, start copying at the 2nd
28
28
  source_repositories[1..-1].each do |source_repo|
29
- copy_actions << plan_action(Actions::Pulp3::Repository::CopyContent,
30
- source_repo, smart_proxy, target_repo,
29
+ copy_actions << plan_action(Actions::Pulp3::Repository::CopyContent, source_repo, smart_proxy, target_repo,
31
30
  filter_ids: filter_ids, solve_dependencies: solve_dependencies,
32
31
  rpm_filenames: rpm_filenames)
33
32
  end
34
-
35
33
  plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo, tasks: copy_actions.last.output[:pulp_tasks])
36
34
  end
37
35
  end
@@ -12,7 +12,7 @@ module Actions
12
12
  elsif publication_content_type
13
13
  plan_action(Actions::Pulp3::Repository::CreatePublication, repository, smart_proxy, options)
14
14
  end
15
-
15
+ plan_action(Actions::Pulp3::ContentGuard::Refresh, smart_proxy) unless repository.unprotected
16
16
  plan_action(Actions::Pulp3::Repository::RefreshDistribution, repository, smart_proxy, :contents_changed => options[:contents_changed]) if repository.environment
17
17
  end
18
18
  end
@@ -11,6 +11,7 @@ module Actions
11
11
  def invoke_external_task
12
12
  source = ::Katello::Repository.find(input[:source_repository_id])
13
13
  target = ::Katello::Repository.find(input[:target_repository_id] || input[:target_repository])
14
+ output[:latest_version_href] = target.backend_service(smart_proxy).read.latest_version_href
14
15
  output[:pulp_tasks] = target.backend_service(smart_proxy).copy_content_for_source(source, input)
15
16
  end
16
17
  end
@@ -9,6 +9,7 @@ module Actions
9
9
  sequence do
10
10
  options = {:repository_id => repository.id, :smart_proxy_id => smart_proxy.id}
11
11
  options[:contents_changed] if options.key?(:contents_changed)
12
+ plan_action(::Actions::Pulp3::ContentGuard::Refresh, smart_proxy) unless repository.unprotected
12
13
  action = plan_self(options)
13
14
  plan_action(SaveDistributionReferences, repository, smart_proxy,
14
15
  action.output, :contents_changed => options[:contents_changed])
@@ -12,9 +12,11 @@ module Actions
12
12
  if input[:tasks] && input[:tasks][:pulp_tasks] && input[:tasks][:pulp_tasks].first
13
13
  distribution_hrefs = input[:tasks][:pulp_tasks].map { |task| task[:created_resources].first }
14
14
  distribution_hrefs.compact!
15
+ repo = ::Katello::Repository.find(input[:repository_id])
15
16
  if distribution_hrefs.any?
16
- repo = ::Katello::Repository.find(input[:repository_id])
17
17
  repo.backend_service(smart_proxy).save_distribution_references(distribution_hrefs)
18
+ else
19
+ repo.backend_service(smart_proxy).update_distribution
18
20
  end
19
21
  end
20
22
  end
@@ -11,7 +11,9 @@ module Actions
11
11
 
12
12
  if input[:tasks]
13
13
  version_href = input[:tasks].last[:created_resources].first
14
- elsif input[:repository_details]
14
+ end
15
+
16
+ if !version_href && input[:repository_details]
15
17
  version_href = input[:repository_details][:latest_version_href]
16
18
  end
17
19
 
@@ -0,0 +1,15 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Repository
4
+ class UpdateCVRepositoryCertGuard < Pulp3::Abstract
5
+ def plan(repository, _smart_proxy)
6
+ root = repository.root
7
+ cv_repositories = root.repositories - [root.library_instance]
8
+ cv_repositories.each do |repo|
9
+ plan_action(::Actions::Pulp3::Repository::RefreshDistribution, repo, SmartProxy.pulp_master)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -45,6 +45,19 @@ module Katello
45
45
  return errata_list
46
46
  end
47
47
  end
48
+
49
+ def filter_errata_by_pulp_href(errata, package_pulp_hrefs)
50
+ return [] if package_pulp_hrefs.empty?
51
+ rpms = Katello::Rpm.where(:pulp_id => package_pulp_hrefs)
52
+ rpm_filenames = rpms.map { |rpm| File.basename(rpm.filename) }
53
+ matching_errata = []
54
+ errata.each do |erratum|
55
+ if erratum.packages.any? && (erratum.packages.pluck(:filename) - rpm_filenames).empty?
56
+ matching_errata << erratum
57
+ end
58
+ end
59
+ matching_errata
60
+ end
48
61
  end
49
62
  end
50
63
  end
@@ -0,0 +1,32 @@
1
+ module Katello
2
+ module Util
3
+ module PulpcoreContentFilters
4
+ def filter_distribution_trees_by_pulp_hrefs(distributiontree_results, _content_pulp_hrefs)
5
+ distributiontree_results.collect { |result| result.pulp_href }.flatten.uniq
6
+ end
7
+
8
+ def filter_package_groups_by_pulp_href(package_groups, package_pulp_hrefs)
9
+ rpms = Katello::Rpm.where(:pulp_id => package_pulp_hrefs)
10
+ package_groups.reject do |package_group|
11
+ (package_group.package_names & rpms.pluck(:name)).empty?
12
+ end
13
+ end
14
+
15
+ def filter_package_environments_by_pulp_hrefs(packageenvironment_results, package_pulp_hrefs)
16
+ matching_package_env_groups = []
17
+
18
+ packageenvironment_results.each do |result|
19
+ if (result.packagegroups & package_pulp_hrefs).any?
20
+ matching_package_env_groups << result.pulp_href
21
+ end
22
+ end
23
+
24
+ matching_package_env_groups.flatten.uniq
25
+ end
26
+
27
+ def filter_metadatafiles_by_pulp_hrefs(metadatafiles_results, _package_pulp_hrefs)
28
+ metadatafiles_results.collect { |result| result.pulp_href }.flatten.uniq
29
+ end
30
+ end
31
+ end
32
+ end
@@ -44,7 +44,6 @@ module Katello
44
44
  end
45
45
 
46
46
  def backend_identifier_field
47
- nil
48
47
  end
49
48
 
50
49
  def content_unit_class
@@ -108,7 +107,8 @@ module Katello
108
107
  pulp_id_href_map = {}
109
108
  service_class = SmartProxy.pulp_master!.content_service(content_type)
110
109
  fetch_only_ids = !repository.content_view.default? &&
111
- !repository.repository_type.unique_content_per_repo
110
+ !repository.repository_type.unique_content_per_repo &&
111
+ service_class.supports_id_fetch?
112
112
 
113
113
  service_class.pulp_units_batch_for_repo(repository, fetch_identifiers: fetch_only_ids).each do |units|
114
114
  units.each do |unit|
@@ -26,8 +26,37 @@ module Katello
26
26
  end
27
27
  end
28
28
 
29
+ def content_unit_pulp_ids(repo)
30
+ if filter_by_id?
31
+ errata_ids = erratum_rules.map(&:errata_id)
32
+ errata_pulp_ids = errata_package_pulp_ids_from_errata_ids(repo, errata_ids)
33
+ else
34
+ clauses = []
35
+ clauses << errata_from
36
+ clauses << errata_to
37
+ clauses << types_clause
38
+ package_filenames = Erratum.list_filenames_by_clauses(repo, clauses.compact)
39
+ errata_pulp_ids = errata_package_pulp_ids_from_package_filenames(repo, package_filenames)
40
+ end
41
+ errata_pulp_ids
42
+ end
43
+
29
44
  private
30
45
 
46
+ def rpms_by_filename(repo, package_filenames)
47
+ query_params = package_filenames.map { |filename| "%#{filename}" }
48
+ repo.rpms.where("filename ILIKE ANY ( array[?] )", query_params)
49
+ end
50
+
51
+ def errata_package_pulp_ids_from_package_filenames(repo, package_filenames)
52
+ rpms_by_filename(repo, package_filenames).pluck(:pulp_id)
53
+ end
54
+
55
+ def errata_package_pulp_ids_from_errata_ids(repo, errata_ids)
56
+ package_filenames = Katello::ErratumPackage.joins(:erratum).where("#{Erratum.table_name}.errata_id" => errata_ids).pluck(:filename)
57
+ rpms_by_filename(repo, package_filenames).pluck(:pulp_id)
58
+ end
59
+
31
60
  def erratum_arel
32
61
  ::Katello::Erratum.arel_table
33
62
  end
@@ -7,7 +7,11 @@ module Katello
7
7
  validates_lengths_from_database
8
8
 
9
9
  # Returns a set of Pulp/MongoDB conditions to filter out packages in the
10
- # repo repository that match parameters
10
+ # repo repository that match parameters if the repository content type
11
+ # is managed by pulp2.
12
+ #
13
+ # Returns a set of pulpcore hrefs (pulp_ids) if the repository content
14
+ # type is managed by pulpcore.
11
15
  #
12
16
  # @param repo [Repository] a repository containing packages to filter
13
17
  # @return [Array] an array of hashes with MongoDB conditions
@@ -20,6 +24,7 @@ module Katello
20
24
  if self.original_packages
21
25
  package_filenames.concat(repo.packages_without_errata.map(&:filename))
22
26
  end
27
+
23
28
  ContentViewPackageFilter.generate_rpm_clauses(package_filenames)
24
29
  end
25
30
 
@@ -27,6 +32,16 @@ module Katello
27
32
  self[:original_packages] = value
28
33
  end
29
34
 
35
+ def content_unit_pulp_ids(repo)
36
+ package_filenames = []
37
+ self.package_rules.each do |rule|
38
+ package_filenames.concat(query_rpms(repo, rule))
39
+ end
40
+
41
+ rpms = Rpm.in_repositories(repo)
42
+ rpms.where(filename: package_filenames).where(:modular => false).pluck(:pulp_id).flatten.uniq
43
+ end
44
+
30
45
  def self.generate_rpm_clauses(package_filenames = [])
31
46
  { 'filename' => { "$in" => package_filenames } } unless package_filenames.empty?
32
47
  end
@@ -10,5 +10,12 @@ module Katello
10
10
  package_group_ids = package_group_rules.reject { |rule| rule.uuid.blank? }.flat_map.map(&:uuid)
11
11
  { "_id" => { "$in" => package_group_ids } } unless package_group_ids.empty?
12
12
  end
13
+
14
+ def content_unit_pulp_ids(repo)
15
+ package_group_hrefs = package_group_rules.reject { |rule| rule.uuid.blank? }.flat_map.map(&:uuid)
16
+ package_group_names = repo.package_groups.
17
+ where(:pulp_id => package_group_hrefs).collect { |package_group| package_group.package_names }.flatten.uniq
18
+ repo.rpms.where(:name => package_group_names).pluck(:pulp_id).compact
19
+ end
13
20
  end
14
21
  end
@@ -25,7 +25,8 @@ module Katello
25
25
  end
26
26
 
27
27
  def package_names
28
- group = Pulp::PackageGroup.new(self.pulp_id)
28
+ service_class = SmartProxy.pulp_master!.content_service(CONTENT_TYPE)
29
+ group = service_class.new(self.pulp_id)
29
30
  group.default_package_names + group.conditional_package_names + group.optional_package_names + group.mandatory_package_names
30
31
  end
31
32
  end
@@ -0,0 +1,14 @@
1
+ module Katello
2
+ module Pulp3
3
+ class ContentGuard < Katello::Model
4
+ def self.import(smart_proxy = SmartProxy.pulp_master!, force = false)
5
+ return unless (count == 0 || force)
6
+ content_guard_api = Katello::Pulp3::Api::ContentGuard.new(smart_proxy)
7
+ content_guard = content_guard_api.list&.results&.first
8
+ fail _("No Content Guard configured!") unless content_guard
9
+ katello_content_guard = self.new(name: content_guard.name, pulp_href: content_guard.pulp_href)
10
+ katello_content_guard.save!
11
+ end
12
+ end
13
+ end
14
+ end
@@ -34,6 +34,10 @@ module Katello
34
34
  nil
35
35
  end
36
36
 
37
+ def self.supports_id_fetch?
38
+ true
39
+ end
40
+
37
41
  def self.content_type
38
42
  self::CONTENT_TYPE
39
43
  end
@@ -0,0 +1,45 @@
1
+ require 'pulp_certguard_client'
2
+
3
+ module Katello
4
+ module Pulp3
5
+ module Api
6
+ class ContentGuard < Core
7
+ def self.client_module
8
+ PulpCertguardClient
9
+ end
10
+
11
+ def self.api_exception_class
12
+ PulpCertguardClient::ApiError
13
+ end
14
+
15
+ def api_client
16
+ PulpCertguardClient::ApiClient.new(smart_proxy.pulp3_configuration(PulpCertguardClient::Configuration))
17
+ end
18
+
19
+ def rhsm_api_client
20
+ PulpCertguardClient::ContentguardsRhsmApi.new(api_client)
21
+ end
22
+
23
+ def create(name = "RHSMCertGuard", ca_certificate = Cert::Certs.ca_cert)
24
+ data = PulpCertguardClient::CertguardRHSMCertGuard.new(name: name, ca_certificate: ca_certificate)
25
+ rhsm_api_client.create(data)
26
+ rescue self.class.api_exception_class => e
27
+ raise e unless list&.results&.first
28
+ end
29
+
30
+ def list(options = {})
31
+ rhsm_api_client.list options
32
+ end
33
+
34
+ def partial_update(href, ca_certificate = Cert::Certs.ca_cert)
35
+ data = PulpCertguardClient::CertguardRHSMCertGuard.new(ca_certificate: ca_certificate)
36
+ rhsm_api_client.partial_update(href, data)
37
+ end
38
+
39
+ def delete(href)
40
+ rhsm_api_client.delete(href) if href
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -28,6 +28,10 @@ module Katello
28
28
  PulpRpmClient::RpmRepositorySyncURL
29
29
  end
30
30
 
31
+ def self.rpm_package_group_class
32
+ PulpRpmClient::RpmPackageGroup
33
+ end
34
+
31
35
  def api_client
32
36
  PulpRpmClient::ApiClient.new(smart_proxy.pulp3_configuration(PulpRpmClient::Configuration))
33
37
  end
@@ -51,6 +55,26 @@ module Katello
51
55
  def distributions_api
52
56
  PulpRpmClient::DistributionsRpmApi.new(api_client)
53
57
  end
58
+
59
+ def copy_api
60
+ PulpRpmClient::RpmCopyApi.new(api_client)
61
+ end
62
+
63
+ def content_package_groups_api
64
+ PulpRpmClient::ContentPackagegroupsApi.new(api_client)
65
+ end
66
+
67
+ def content_package_environments_api
68
+ PulpRpmClient::ContentPackageenvironmentsApi.new(api_client)
69
+ end
70
+
71
+ def content_repo_metadata_files_api
72
+ PulpRpmClient::ContentRepoMetadataFilesApi.new(api_client)
73
+ end
74
+
75
+ def content_distribution_trees_api
76
+ PulpRpmClient::ContentDistributionTreesApi.new(api_client)
77
+ end
54
78
  end
55
79
  end
56
80
  end
@@ -15,6 +15,10 @@ module Katello
15
15
  "pulp_href"
16
16
  end
17
17
 
18
+ def self.supports_id_fetch?
19
+ false
20
+ end
21
+
18
22
  def self.ids_for_repository(repo_id)
19
23
  repo = Katello::Pulp3::Repository::Yum.new(Katello::Repository.find(repo_id), SmartProxy.pulp_master)
20
24
  repo_content_list = repo.content_list
@@ -19,6 +19,10 @@ module Katello
19
19
  nil
20
20
  end
21
21
 
22
+ def self.supports_id_fetch?
23
+ true
24
+ end
25
+
22
26
  def update_model
23
27
  fail NotImplementedError
24
28
  end
@@ -143,7 +143,7 @@ module Katello
143
143
 
144
144
  def distribution_needs_update?
145
145
  if distribution_reference
146
- expected = distribution_options(relative_path).except(:name).compact
146
+ expected = secure_distribution_options(relative_path).except(:name).compact
147
147
  actual = get_distribution.to_hash
148
148
  expected != actual.slice(*expected.keys)
149
149
  elsif repo.environment
@@ -180,6 +180,10 @@ module Katello
180
180
  api.repositories_api.list(options).results
181
181
  end
182
182
 
183
+ def read
184
+ api.repositories_api.read(repository_reference.try(:repository_href))
185
+ end
186
+
183
187
  def delete(href = repository_reference.try(:repository_href))
184
188
  repository_reference.try(:destroy)
185
189
  ignore_404_exception { api.repositories_api.delete(href) } if href
@@ -209,7 +213,7 @@ module Katello
209
213
  end
210
214
 
211
215
  def create_distribution(path)
212
- distribution_data = api.class.distribution_class.new(distribution_options(path))
216
+ distribution_data = api.class.distribution_class.new(secure_distribution_options(path))
213
217
  api.distributions_api.create(distribution_data)
214
218
  end
215
219
 
@@ -219,7 +223,8 @@ module Katello
219
223
 
220
224
  def update_distribution
221
225
  if distribution_reference
222
- options = distribution_options(relative_path).except(:name)
226
+ options = secure_distribution_options(relative_path).except(:name)
227
+ distribution_reference.update(:content_guard_href => options[:content_guard])
223
228
  api.distributions_api.partial_update(distribution_reference.href, options)
224
229
  end
225
230
  end
@@ -246,9 +251,10 @@ module Katello
246
251
 
247
252
  def save_distribution_references(hrefs)
248
253
  hrefs.each do |href|
249
- path = api.get_distribution(href)&.base_path
254
+ pulp3_distribution_data = api.get_distribution(href)
255
+ path, content_guard_href = pulp3_distribution_data&.base_path, pulp3_distribution_data&.content_guard
250
256
  unless distribution_reference
251
- DistributionReference.create!(path: path, href: href, repository_id: repo.id)
257
+ DistributionReference.create!(path: path, href: href, repository_id: repo.id, content_guard_href: content_guard_href)
252
258
  end
253
259
  end
254
260
  end
@@ -284,6 +290,16 @@ module Katello
284
290
  remote_options.merge!(ssl_remote_options)
285
291
  end
286
292
 
293
+ def secure_distribution_options(path)
294
+ secured_distribution_options = {}
295
+ if root.unprotected
296
+ secured_distribution_options[:content_guard] = nil
297
+ else
298
+ secured_distribution_options[:content_guard] = ::Katello::Pulp3::ContentGuard.first.pulp_href
299
+ end
300
+ secured_distribution_options.merge!(distribution_options(path))
301
+ end
302
+
287
303
  def ssl_remote_options
288
304
  if root.redhat? && Katello::Resources::CDN::CdnResource.redhat_cdn?(root.url)
289
305
  {
@@ -4,6 +4,9 @@ module Katello
4
4
  module Pulp3
5
5
  class Repository
6
6
  class Yum < ::Katello::Pulp3::Repository
7
+ include Katello::Util::Errata
8
+ include Katello::Util::PulpcoreContentFilters
9
+
7
10
  def remote_options
8
11
  if root.url.blank?
9
12
  common_remote_options.merge(url: nil, policy: root.download_policy)
@@ -59,9 +62,93 @@ module Katello
59
62
  "/pulp/repos/#{repo.relative_path}/".sub('//', '/')
60
63
  end
61
64
 
62
- def copy_content_for_source
63
- # TODO
64
- fail NotImplementedError
65
+ def copy_units(source_repository_version_href, content_unit_hrefs, dependency_solving)
66
+ tasks = []
67
+
68
+ if content_unit_hrefs.any?
69
+ data = PulpRpmClient::Copy.new
70
+ data.config = [
71
+ source_repo_version: source_repository_version_href,
72
+ dest_repo: repository_reference.repository_href,
73
+ dest_base_version: 0,
74
+ content: content_unit_hrefs.sort
75
+ ]
76
+ data.dependency_solving = dependency_solving
77
+ tasks << api.copy_api.copy_content(data)
78
+ else
79
+ data = PulpRpmClient::RepositoryAddRemoveContent.new(
80
+ remove_content_units: ['*'])
81
+ tasks << api.repositories_api.modify(repository_reference.repository_href, data)
82
+ end
83
+
84
+ tasks
85
+ end
86
+
87
+ def packageenvironments(options = {})
88
+ api.content_package_environments_api.list(options)
89
+ end
90
+
91
+ def metadatafiles(options = {})
92
+ api.content_repo_metadata_files_api.list(options)
93
+ end
94
+
95
+ def distributiontrees(options = {})
96
+ api.content_distribution_trees_api.list(options)
97
+ end
98
+
99
+ def copy_content_for_source(source_repository, options = {})
100
+ filters = [ContentViewErratumFilter, ContentViewPackageGroupFilter, ContentViewPackageFilter].collect do |filter_class|
101
+ filter_class.where(:id => options[:filter_ids])
102
+ end
103
+
104
+ filters.flatten!.compact!
105
+
106
+ whitelist_ids = []
107
+ blacklist_ids = []
108
+ filters.each do |filter|
109
+ if filter.inclusion
110
+ whitelist_ids += filter.content_unit_pulp_ids(source_repository)
111
+ else
112
+ blacklist_ids += filter.content_unit_pulp_ids(source_repository)
113
+ end
114
+ end
115
+
116
+ if whitelist_ids.empty? && filters.select { |filter| filter.inclusion }.empty?
117
+ whitelist_ids = source_repository.rpms.where(:modular => false).pluck(:pulp_id).sort
118
+ end
119
+
120
+ content_unit_hrefs = whitelist_ids - blacklist_ids
121
+
122
+ if content_unit_hrefs.any?
123
+ content_unit_hrefs += additional_content_hrefs(source_repository, content_unit_hrefs)
124
+ end
125
+ content_unit_hrefs += source_repository.srpms.pluck(:pulp_id)
126
+
127
+ dependency_solving = options[:solve_dependencies] || false
128
+ copy_units(source_repository.version_href, content_unit_hrefs.uniq, dependency_solving)
129
+ end
130
+
131
+ def additional_content_hrefs(source_repository, content_unit_hrefs)
132
+ repo_service = source_repository.backend_service(SmartProxy.pulp_master)
133
+ options = { :repository_version => source_repository.version_href }
134
+
135
+ errata_to_include = filter_errata_by_pulp_href(source_repository.errata, content_unit_hrefs)
136
+ content_unit_hrefs += errata_to_include.collect { |erratum| erratum.repository_errata.pluck(:erratum_pulp3_href) }.flatten
137
+
138
+ package_groups_to_include = filter_package_groups_by_pulp_href(source_repository.package_groups, content_unit_hrefs)
139
+ content_unit_hrefs += package_groups_to_include.pluck(:pulp_id)
140
+
141
+ package_environment_hrefs_to_include = filter_package_environments_by_pulp_hrefs(
142
+ repo_service.packageenvironments(options).results, package_groups_to_include.pluck(:pulp_id))
143
+ content_unit_hrefs += package_environment_hrefs_to_include
144
+
145
+ metadata_file_hrefs_to_include = filter_metadatafiles_by_pulp_hrefs(
146
+ repo_service.metadatafiles(options).results, content_unit_hrefs)
147
+ content_unit_hrefs += metadata_file_hrefs_to_include
148
+
149
+ distribution_tree_hrefs_to_include = filter_distribution_trees_by_pulp_hrefs(
150
+ repo_service.distributiontrees(options).results, content_unit_hrefs)
151
+ content_unit_hrefs + distribution_tree_hrefs_to_include
65
152
  end
66
153
 
67
154
  def regenerate_applicability
@@ -0,0 +1,10 @@
1
+ class CreateContentGuard < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :katello_content_guards do |t|
4
+ t.string :pulp_href, :null => false
5
+ t.string :name, :null => false, :unique => true
6
+ end
7
+
8
+ add_column :katello_distribution_references, :content_guard_href, :string
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  module Katello
2
- VERSION = "3.16.0.rc2".freeze
2
+ VERSION = "3.16.0.rc2.1".freeze
3
3
  end
@@ -38,7 +38,7 @@ import {
38
38
  stopPollingTasks,
39
39
  toastTaskFinished,
40
40
  } from '../Tasks/TaskActions';
41
- import { selectIsPollingTasks, selectIsPollingTask } from '../Tasks/TaskSelectors';
41
+ import { selectIsPollingTasks } from '../Tasks/TaskSelectors';
42
42
 
43
43
  export const createSubscriptionParams = (extendedParams = {}) => ({
44
44
  ...{
@@ -104,19 +104,17 @@ export const resetTasks = () => (dispatch) => {
104
104
  });
105
105
  };
106
106
 
107
- export const handleTask = task => async (dispatch, getState) => {
108
- if (selectIsPollingTask(getState(), SUBSCRIPTIONS)) {
109
- if (!task.pending) {
110
- dispatch(stopPollingTask(SUBSCRIPTIONS));
111
- dispatch(toastTaskFinished(task));
112
- dispatch(resetTasks());
113
- dispatch(pollTasks());
114
- dispatch(loadSubscriptions());
115
- }
116
- } else {
117
- dispatch(cancelPollTasks());
118
- dispatch(startPollingTask(SUBSCRIPTIONS, task));
119
- }
107
+ export const handleFinishedTask = task => (dispatch) => {
108
+ dispatch(stopPollingTask(SUBSCRIPTIONS));
109
+ dispatch(toastTaskFinished(task));
110
+ dispatch(resetTasks());
111
+ dispatch(pollTasks());
112
+ dispatch(loadSubscriptions());
113
+ };
114
+
115
+ export const handleStartTask = task => (dispatch) => {
116
+ dispatch(cancelPollTasks());
117
+ dispatch(startPollingTask(SUBSCRIPTIONS, task));
120
118
  };
121
119
 
122
120
  export const updateQuantity = (quantities = {}) => async (dispatch) => {
@@ -39,11 +39,16 @@ class SubscriptionsPage extends Component {
39
39
 
40
40
  componentDidUpdate(prevProps) {
41
41
  const {
42
- organization, task, handleTask,
42
+ organization, task, handleStartTask, handleFinishedTask, isTaskPending, isPollingTask,
43
43
  } = this.props;
44
-
45
44
  if (task) {
46
- handleTask(task);
45
+ if (isPollingTask) {
46
+ if (prevProps.isTaskPending && !isTaskPending) {
47
+ handleFinishedTask(task);
48
+ }
49
+ } else {
50
+ handleStartTask(task);
51
+ }
47
52
  }
48
53
 
49
54
  if (organization) {
@@ -291,9 +296,12 @@ SubscriptionsPage.propTypes = {
291
296
  }),
292
297
  pending: PropTypes.bool,
293
298
  }),
299
+ isTaskPending: PropTypes.bool,
300
+ isPollingTask: PropTypes.bool,
294
301
  pollTasks: PropTypes.func.isRequired,
295
302
  cancelPollTasks: PropTypes.func.isRequired,
296
- handleTask: PropTypes.func.isRequired,
303
+ handleStartTask: PropTypes.func.isRequired,
304
+ handleFinishedTask: PropTypes.func.isRequired,
297
305
  loadSetting: PropTypes.func.isRequired,
298
306
  loadTables: PropTypes.func.isRequired,
299
307
  createColumns: PropTypes.func.isRequired,
@@ -314,6 +322,8 @@ SubscriptionsPage.propTypes = {
314
322
 
315
323
  SubscriptionsPage.defaultProps = {
316
324
  task: undefined,
325
+ isTaskPending: undefined,
326
+ isPollingTask: undefined,
317
327
  organization: undefined,
318
328
  searchQuery: '',
319
329
  deleteModalOpened: false,
@@ -16,5 +16,13 @@ export const selectActivePermissions = state =>
16
16
  export const selectSubscriptionsTask = state =>
17
17
  selectSubscriptionsState(state).task;
18
18
 
19
+ export const selectIsTaskPending = (state) => {
20
+ const task = selectSubscriptionsTask(state);
21
+ if (task) {
22
+ return task.pending || task.result === 'pending';
23
+ }
24
+ return false;
25
+ };
26
+
19
27
  export const selectTableSettings = (state, tableName) =>
20
28
  state.katello.settings.tables[tableName] || undefined;
@@ -18,7 +18,8 @@ import {
18
18
  loadTableColumnsSuccessAction,
19
19
  } from './subscriptions.fixtures';
20
20
  import {
21
- handleTask,
21
+ handleFinishedTask,
22
+ handleStartTask,
22
23
  pollTasks,
23
24
  cancelPollTasks,
24
25
  resetTasks,
@@ -33,7 +34,7 @@ import {
33
34
  enableDeleteButton,
34
35
  } from '../SubscriptionActions';
35
36
 
36
- import { getTaskPendingResponse, getTaskSuccessResponse } from '../../Tasks/__tests__/task.fixtures';
37
+ import { getTaskSuccessResponse } from '../../Tasks/__tests__/task.fixtures';
37
38
 
38
39
  const mockStore = configureMockStore([thunk]);
39
40
  const store = mockStore(Immutable({
@@ -159,27 +160,15 @@ describe('subscription actions', () => {
159
160
  );
160
161
  });
161
162
 
162
- describe('handleTask', () => {
163
- describe('when not polling a task', () => {
164
- it('starts polling the task', async () => {
165
- await store.dispatch(handleTask(getTaskSuccessResponse));
163
+ describe('handleStartTask', () => {
164
+ it('starts polling the task', async () => {
165
+ await store.dispatch(handleStartTask(getTaskSuccessResponse));
166
166
 
167
- expect(store.getActions()).toMatchSnapshot();
168
- });
169
- });
170
-
171
- it('does nothing if already polling and task is pending', async () => {
172
- const pollStore = configureMockStore([thunk])({
173
- intervals: {
174
- SUBSCRIPTIONS_POLL_TASK: 5,
175
- },
176
- });
177
-
178
- await pollStore.dispatch(handleTask(getTaskPendingResponse));
179
-
180
- expect(pollStore.getActions()).toMatchSnapshot();
167
+ expect(store.getActions()).toMatchSnapshot();
181
168
  });
169
+ });
182
170
 
171
+ describe('handleFinishedTask', () => {
183
172
  it('handles a finished task', async () => {
184
173
  const pollStore = configureMockStore([thunk])({
185
174
  intervals: {
@@ -187,7 +176,7 @@ describe('subscription actions', () => {
187
176
  },
188
177
  });
189
178
 
190
- await pollStore.dispatch(handleTask(getTaskSuccessResponse));
179
+ await pollStore.dispatch(handleFinishedTask(getTaskSuccessResponse));
191
180
 
192
181
  expect(pollStore.getActions()).toMatchSnapshot();
193
182
  });
@@ -16,11 +16,13 @@ const loadTables = () => new Promise((resolve) => {
16
16
  });
17
17
 
18
18
  const pollTasks = jest.fn();
19
- const handleTask = jest.fn();
19
+ const handleStartTask = jest.fn();
20
+ const handleFinishedTask = jest.fn();
20
21
 
21
22
  afterEach(() => {
22
23
  pollTasks.mockClear();
23
- handleTask.mockClear();
24
+ handleStartTask.mockClear();
25
+ handleFinishedTask.mockClear();
24
26
  });
25
27
 
26
28
  describe('subscriptions page', () => {
@@ -39,7 +41,8 @@ describe('subscriptions page', () => {
39
41
  updateColumns={updateColumns}
40
42
  loadSubscriptions={loadSubscriptions}
41
43
  updateQuantity={updateQuantity}
42
- handleTask={handleTask}
44
+ handleStartTask={handleStartTask}
45
+ handleFinishedTask={handleFinishedTask}
43
46
  pollTaskUntilDone={noop}
44
47
  pollBulkSearch={noop}
45
48
  pollTasks={pollTasks}
@@ -71,7 +74,8 @@ describe('subscriptions page', () => {
71
74
  updateColumns={updateColumns}
72
75
  loadSubscriptions={loadSubscriptions}
73
76
  updateQuantity={updateQuantity}
74
- handleTask={handleTask}
77
+ handleStartTask={handleStartTask}
78
+ handleFinishedTask={handleFinishedTask}
75
79
  pollTaskUntilDone={noop}
76
80
  pollBulkSearch={noop}
77
81
  pollTasks={pollTasks}
@@ -118,8 +122,9 @@ describe('subscriptions page', () => {
118
122
  },
119
123
  };
120
124
 
121
- page.setProps({ task: mockTask });
125
+ page.setProps({ isTaskPending: true, isPollingTask: true });
126
+ page.setProps({ task: mockTask, isPollingTask: true, isTaskPending: false });
122
127
 
123
- expect(handleTask).toHaveBeenCalledWith(mockTask);
128
+ expect(handleFinishedTask).toHaveBeenCalledWith(mockTask);
124
129
  });
125
130
  });
@@ -35,9 +35,7 @@ Object {
35
35
  }
36
36
  `;
37
37
 
38
- exports[`subscription actions handleTask does nothing if already polling and task is pending 1`] = `Array []`;
39
-
40
- exports[`subscription actions handleTask handles a finished task 1`] = `
38
+ exports[`subscription actions handleFinishedTask handles a finished task 1`] = `
41
39
  Array [
42
40
  Object {
43
41
  "key": "SUBSCRIPTIONS_POLL_TASK",
@@ -77,7 +75,7 @@ Array [
77
75
  ]
78
76
  `;
79
77
 
80
- exports[`subscription actions handleTask when not polling a task starts polling the task 1`] = `
78
+ exports[`subscription actions handleStartTask starts polling the task 1`] = `
81
79
  Array [
82
80
  Object {
83
81
  "key": "SUBSCRIPTIONS_TASK_SEARCH",
@@ -15,11 +15,13 @@ import {
15
15
  selectSubscriptionsTask,
16
16
  selectActivePermissions,
17
17
  selectTableSettings,
18
+ selectIsTaskPending,
18
19
  } from './SubscriptionsSelectors';
20
+ import { selectIsPollingTask } from '../Tasks/TaskSelectors';
19
21
  import { selectSimpleContentAccessEnabled } from '../Organizations/OrganizationSelectors';
20
22
 
21
23
  import reducer from './SubscriptionReducer';
22
- import { SUBSCRIPTION_TABLE_NAME } from './SubscriptionConstants';
24
+ import { SUBSCRIPTION_TABLE_NAME, SUBSCRIPTIONS } from './SubscriptionConstants';
23
25
  import SubscriptionsPage from './SubscriptionsPage';
24
26
 
25
27
  // map state to props
@@ -33,6 +35,8 @@ const mapStateToProps = (state) => {
33
35
  activePermissions: selectActivePermissions(state),
34
36
  simpleContentAccess: selectSimpleContentAccessEnabled(state),
35
37
  task: selectSubscriptionsTask(state),
38
+ isTaskPending: selectIsTaskPending(state),
39
+ isPollingTask: selectIsPollingTask(state, SUBSCRIPTIONS),
36
40
  searchQuery: selectSearchQuery(state),
37
41
  deleteModalOpened: selectDeleteModalOpened(state),
38
42
  deleteButtonDisabled: selectDeleteButtonDisabled(state),
@@ -5,8 +5,9 @@ import { stopInterval, withInterval } from 'foremanReact/redux/middlewares/Inter
5
5
  import { foremanTasksApi } from '../../services/api';
6
6
  import { bulkSearchKey, pollTaskKey, taskFinishedToast } from './helpers';
7
7
 
8
- export const toastTaskFinished = task => async dispatch =>
8
+ export const toastTaskFinished = task => async (dispatch) => {
9
9
  dispatch(addToast(taskFinishedToast(task)));
10
+ };
10
11
 
11
12
  const taskBulkSearchParams = params => ({
12
13
  search: Object.entries(propsToSnakeCase(params))
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katello
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.16.0.rc2
4
+ version: 3.16.0.rc2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - N/A
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-01 00:00:00.000000000 Z
11
+ date: 2020-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -332,6 +332,20 @@ dependencies:
332
332
  - - "<"
333
333
  - !ruby/object:Gem::Version
334
334
  version: 0.3.0
335
+ - !ruby/object:Gem::Dependency
336
+ name: pulp_certguard_client
337
+ requirement: !ruby/object:Gem::Requirement
338
+ requirements:
339
+ - - "<"
340
+ - !ruby/object:Gem::Version
341
+ version: '2.0'
342
+ type: :runtime
343
+ prerelease: false
344
+ version_requirements: !ruby/object:Gem::Requirement
345
+ requirements:
346
+ - - "<"
347
+ - !ruby/object:Gem::Version
348
+ version: '2.0'
335
349
  - !ruby/object:Gem::Dependency
336
350
  name: deface
337
351
  requirement: !ruby/object:Gem::Requirement
@@ -874,6 +888,7 @@ files:
874
888
  - app/lib/actions/katello/repository/sync_hook.rb
875
889
  - app/lib/actions/katello/repository/update.rb
876
890
  - app/lib/actions/katello/repository/update_content_urls.rb
891
+ - app/lib/actions/katello/repository/update_cv_repo_cert_guard.rb
877
892
  - app/lib/actions/katello/repository/update_http_proxy_details.rb
878
893
  - app/lib/actions/katello/repository/update_metadata_sync.rb
879
894
  - app/lib/actions/katello/repository/update_redhat_repository.rb
@@ -961,6 +976,7 @@ files:
961
976
  - app/lib/actions/pulp/repository_group/create.rb
962
977
  - app/lib/actions/pulp/repository_group/delete.rb
963
978
  - app/lib/actions/pulp/repository_group/export.rb
979
+ - app/lib/actions/pulp3/ContentGuard/refresh.rb
964
980
  - app/lib/actions/pulp3/abstract.rb
965
981
  - app/lib/actions/pulp3/abstract_async_task.rb
966
982
  - app/lib/actions/pulp3/capsule_content/generate_metadata.rb
@@ -1007,6 +1023,7 @@ files:
1007
1023
  - app/lib/actions/pulp3/repository/save_publication.rb
1008
1024
  - app/lib/actions/pulp3/repository/save_version.rb
1009
1025
  - app/lib/actions/pulp3/repository/sync.rb
1026
+ - app/lib/actions/pulp3/repository/update_cv_repository_cert_guard.rb
1010
1027
  - app/lib/actions/pulp3/repository/update_distributions.rb
1011
1028
  - app/lib/actions/pulp3/repository/update_remote.rb
1012
1029
  - app/lib/actions/pulp3/repository/update_repository.rb
@@ -1063,6 +1080,7 @@ files:
1063
1080
  - app/lib/katello/util/package_filter.rb
1064
1081
  - app/lib/katello/util/path_with_substitutions.rb
1065
1082
  - app/lib/katello/util/proxy_uri.rb
1083
+ - app/lib/katello/util/pulpcore_content_filters.rb
1066
1084
  - app/lib/katello/util/report_table.rb
1067
1085
  - app/lib/katello/util/search.rb
1068
1086
  - app/lib/katello/util/support.rb
@@ -1236,6 +1254,7 @@ files:
1236
1254
  - app/models/katello/product_content.rb
1237
1255
  - app/models/katello/provider.rb
1238
1256
  - app/models/katello/proxy_association_owner.rb
1257
+ - app/models/katello/pulp3/content_guard.rb
1239
1258
  - app/models/katello/pulp3/distribution_reference.rb
1240
1259
  - app/models/katello/pulp3/repository_reference.rb
1241
1260
  - app/models/katello/pulp_sync_status.rb
@@ -1350,6 +1369,7 @@ files:
1350
1369
  - app/services/katello/pulp/yum_metadata_file.rb
1351
1370
  - app/services/katello/pulp3/ansible_collection.rb
1352
1371
  - app/services/katello/pulp3/api/ansible_collection.rb
1372
+ - app/services/katello/pulp3/api/content_guard.rb
1353
1373
  - app/services/katello/pulp3/api/core.rb
1354
1374
  - app/services/katello/pulp3/api/docker.rb
1355
1375
  - app/services/katello/pulp3/api/file.rb
@@ -1954,6 +1974,7 @@ files:
1954
1974
  - db/migrate/20200213184848_create_evr_type.rb
1955
1975
  - db/migrate/20200304201026_create_katello_module_stream_rpms.rb
1956
1976
  - db/migrate/20200402130013_add_repsoitory_docker_meta_tag_f_key.rb
1977
+ - db/migrate/20200407171926_create_content_guard.rb
1957
1978
  - db/migrate/20200429153103_installed_package_bad_nvrea.rb
1958
1979
  - db/migrate/20200501155054_installed_package_unique_nvrea.rb
1959
1980
  - db/migrate/20200506163345_add_applicability_indicesto_katello_host_available_module_streams.rb
@@ -4850,7 +4871,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
4850
4871
  - !ruby/object:Gem::Version
4851
4872
  version: 1.3.1
4852
4873
  requirements: []
4853
- rubygems_version: 3.0.3
4874
+ rubygems_version: 3.1.2
4854
4875
  signing_key:
4855
4876
  specification_version: 4
4856
4877
  summary: Content and Subscription Management plugin for Foreman