katello 4.1.0.rc2.2 → 4.1.0

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

Potentially problematic release.


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

Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/content_export_incrementals_controller.rb +1 -1
  3. data/app/controllers/katello/api/v2/content_exports_controller.rb +1 -1
  4. data/app/controllers/katello/api/v2/content_imports_controller.rb +2 -2
  5. data/app/controllers/katello/api/v2/errata_controller.rb +2 -23
  6. data/app/controllers/katello/api/v2/host_errata_controller.rb +5 -32
  7. data/app/controllers/katello/api/v2/host_packages_controller.rb +1 -1
  8. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +1 -1
  9. data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +0 -1
  10. data/app/controllers/katello/api/v2/repositories_controller.rb +1 -1
  11. data/app/controllers/katello/concerns/api/v2/host_errata_extensions.rb +41 -0
  12. data/app/controllers/katello/remote_execution_controller.rb +5 -9
  13. data/app/lib/actions/candlepin/abstract_async_task.rb +9 -1
  14. data/app/lib/actions/katello/agent_action.rb +2 -0
  15. data/app/lib/actions/katello/applicability/repository/regenerate.rb +10 -10
  16. data/app/lib/actions/katello/capsule_content/sync.rb +1 -1
  17. data/app/lib/actions/katello/host/upload_package_profile.rb +1 -6
  18. data/app/lib/actions/katello/host/upload_profiles.rb +2 -41
  19. data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +2 -2
  20. data/app/lib/actions/katello/repository/check_matching_content.rb +13 -14
  21. data/app/lib/actions/katello/repository/sync.rb +3 -14
  22. data/app/lib/actions/katello/repository/verify_checksum.rb +1 -1
  23. data/app/lib/actions/katello/sync_plan/run.rb +7 -2
  24. data/app/lib/actions/pulp3/content_guard/refresh.rb +6 -10
  25. data/app/lib/actions/pulp3/orchestration/orphan_cleanup/remove_orphans.rb +1 -1
  26. data/app/lib/actions/pulp3/repository/save_version.rb +1 -0
  27. data/app/lib/katello/errors.rb +1 -1
  28. data/app/lib/katello/event_daemon/monitor.rb +1 -0
  29. data/app/lib/katello/event_daemon/services/agent_event_receiver.rb +6 -10
  30. data/app/lib/katello/util/hostgroup_facets_helper.rb +126 -0
  31. data/app/models/katello/authorization/content_view.rb +5 -9
  32. data/app/models/katello/authorization/organization.rb +4 -4
  33. data/app/models/katello/concerns/hostgroup_extensions.rb +3 -1
  34. data/app/models/katello/concerns/pulp_database_unit.rb +42 -0
  35. data/app/models/katello/concerns/redhat_extensions.rb +18 -10
  36. data/app/models/katello/erratum.rb +0 -4
  37. data/app/models/katello/glue/pulp/repo.rb +0 -19
  38. data/app/models/katello/host/content_facet.rb +11 -20
  39. data/app/models/katello/host_available_module_stream.rb +4 -4
  40. data/app/models/katello/module_stream.rb +0 -4
  41. data/app/models/katello/ping.rb +2 -9
  42. data/app/models/katello/repository.rb +14 -4
  43. data/app/models/katello/root_repository.rb +4 -0
  44. data/app/models/katello/rpm.rb +0 -4
  45. data/app/services/cert/certs.rb +4 -0
  46. data/app/services/katello/applicable_host_queue.rb +2 -2
  47. data/app/services/katello/pulp/yum_metadata_file.rb +6 -2
  48. data/app/services/katello/pulp3/api/content_guard.rb +39 -5
  49. data/app/services/katello/pulp3/repository/ansible_collection.rb +1 -1
  50. data/app/services/katello/pulp3/repository/yum.rb +1 -0
  51. data/app/services/katello/registration_manager.rb +4 -24
  52. data/app/services/katello/ui_notifications/pulp/proxy_disk_space.rb +1 -0
  53. data/app/views/katello/api/v2/repository_sets/show.json.rabl +9 -5
  54. data/config/katello.yaml.example +0 -13
  55. data/config/routes/api/v2.rb +0 -1
  56. data/db/migrate/20200514092553_move_katello_fields_from_hostgroups.katello.rb +15 -1
  57. data/db/migrate/20210119162528_delete_puppet_and_ostree_repos.rb +18 -22
  58. data/db/migrate/20210512170039_add_repo_timestamps.rb +6 -0
  59. data/db/migrate/20210512192745_fix_red_hat_root_repository_arch.rb +11 -0
  60. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-errata-modal.controller.js +26 -27
  61. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-module-streams-modal.controller.js +1 -3
  62. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-packages-modal.controller.js +1 -5
  63. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-host-bulk-module-streams-modal.html +1 -1
  64. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-errata-modal.html +2 -2
  65. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-packages-modal.html +7 -2
  66. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-errata.controller.js +5 -2
  67. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-module-streams.controller.js +1 -1
  68. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages.controller.js +1 -1
  69. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-errata.html +2 -2
  70. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-module-streams.html +1 -1
  71. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-actions.html +7 -2
  72. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages.html +2 -2
  73. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +5 -10
  74. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +3 -5
  75. data/lib/katello.rb +1 -1
  76. data/lib/katello/engine.rb +0 -2
  77. data/lib/katello/permission_creator.rb +7 -14
  78. data/lib/katello/plugin.rb +9 -0
  79. data/lib/katello/tasks/fix_hostgroup_facets.rake +8 -0
  80. data/lib/katello/tasks/upgrades/4.1/update_content_import_export_perms.rake +33 -0
  81. data/lib/katello/version.rb +1 -1
  82. data/locale/action_names.rb +39 -39
  83. data/locale/bn/katello.edit.po +114 -107
  84. data/locale/bn/katello.po +12 -6
  85. data/locale/cs/katello.edit.po +118 -115
  86. data/locale/cs/katello.po +12 -6
  87. data/locale/de/katello.edit.po +126 -136
  88. data/locale/de/katello.po +12 -6
  89. data/locale/en/katello.edit.po +114 -106
  90. data/locale/en/katello.po +12 -6
  91. data/locale/es/katello.edit.po +129 -165
  92. data/locale/es/katello.po +12 -6
  93. data/locale/fr/katello.edit.po +143 -247
  94. data/locale/fr/katello.po +13 -9
  95. data/locale/gu/katello.edit.po +114 -107
  96. data/locale/gu/katello.po +12 -6
  97. data/locale/hi/katello.edit.po +114 -107
  98. data/locale/hi/katello.po +12 -6
  99. data/locale/it/katello.edit.po +121 -131
  100. data/locale/it/katello.po +12 -6
  101. data/locale/ja/katello.edit.po +141 -229
  102. data/locale/ja/katello.po +13 -9
  103. data/locale/katello.pot +124 -114
  104. data/locale/kn/katello.edit.po +114 -107
  105. data/locale/kn/katello.po +12 -6
  106. data/locale/ko/katello.edit.po +126 -136
  107. data/locale/ko/katello.po +12 -6
  108. data/locale/mr/katello.edit.po +114 -107
  109. data/locale/mr/katello.po +12 -6
  110. data/locale/or/katello.edit.po +114 -107
  111. data/locale/or/katello.po +12 -6
  112. data/locale/pa/katello.edit.po +114 -107
  113. data/locale/pa/katello.po +12 -6
  114. data/locale/pt/katello.edit.po +114 -107
  115. data/locale/pt/katello.po +12 -6
  116. data/locale/pt_BR/katello.edit.po +129 -165
  117. data/locale/pt_BR/katello.po +12 -6
  118. data/locale/ru/katello.edit.po +126 -136
  119. data/locale/ru/katello.po +12 -6
  120. data/locale/ta/katello.edit.po +114 -107
  121. data/locale/ta/katello.po +12 -6
  122. data/locale/te/katello.edit.po +114 -107
  123. data/locale/te/katello.po +12 -6
  124. data/locale/zh_CN/katello.edit.po +140 -229
  125. data/locale/zh_CN/katello.po +13 -9
  126. data/locale/zh_TW/katello.edit.po +127 -153
  127. data/locale/zh_TW/katello.po +12 -6
  128. data/webpack/components/react-bootstrap-select/index.js +1 -1
  129. metadata +26 -18
  130. data/app/lib/actions/katello/host/generate_applicability.rb +0 -41
  131. data/app/lib/actions/katello/repository/import_applicability.rb +0 -25
  132. data/app/lib/actions/pulp/consumer.rb +0 -100
  133. data/app/lib/actions/pulp/consumer/create.rb +0 -19
  134. data/app/lib/actions/pulp/consumer/destroy.rb +0 -17
  135. data/app/lib/actions/pulp/consumer/generate_applicability.rb +0 -24
  136. data/app/lib/actions/pulp/consumer/update.rb +0 -20
  137. data/app/lib/actions/pulp3/capsule_content/refresh_content_guard.rb +0 -17
  138. data/app/models/katello/events/import_host_applicability.rb +0 -16
  139. data/app/services/katello/applicable_content_helper.rb +0 -111
  140. data/app/services/katello/pulp/consumer.rb +0 -83
  141. data/app/services/katello/pulp/consumer_group.rb +0 -95
@@ -13,6 +13,7 @@ module Actions
13
13
  def run
14
14
  source_repo = ::Katello::Repository.find(input[:source_repo_id])
15
15
  target_repo = ::Katello::Repository.find(input[:target_repo_id])
16
+ target_repo_published = target_repo.backend_service(SmartProxy.pulp_primary).published?
16
17
 
17
18
  if source_repo.content_type == ::Katello::Repository::YUM_TYPE
18
19
  srpms_match = srpms_match?(source_repo, target_repo)
@@ -23,16 +24,14 @@ module Actions
23
24
  yum_metadata_files = yum_metadata_files_match?(source_repo, target_repo)
24
25
  checksum_match = (target_repo.saved_checksum_type == source_repo.saved_checksum_type)
25
26
 
26
- published = target_repo.backend_service(SmartProxy.pulp_primary).published?
27
-
28
27
  output[:checksum_match] = checksum_match
29
- output[:matching_content] = yum_metadata_files && srpms_match && rpms && errata && package_groups && distributions && published && checksum_match
28
+ output[:matching_content] = yum_metadata_files && srpms_match && rpms && errata && package_groups && distributions && target_repo_published && checksum_match
30
29
  end
31
30
 
32
31
  if source_repo.content_type == ::Katello::Repository::DEB_TYPE
33
32
  debs = debs_match?(source_repo, target_repo)
34
33
 
35
- output[:matching_content] = debs && target_repo.published?
34
+ output[:matching_content] = debs && target_repo_published
36
35
  end
37
36
  end
38
37
 
@@ -41,26 +40,26 @@ module Actions
41
40
  end
42
41
 
43
42
  def srpms_match?(source_repo, target_repo)
44
- source_repo_ids = source_repo.srpm_ids.sort
45
- target_repo_ids = target_repo.srpm_ids.sort
43
+ source_repo_ids = source_repo.srpm_ids.sort.uniq
44
+ target_repo_ids = target_repo.srpm_ids.sort.uniq
46
45
  source_repo_ids == target_repo_ids
47
46
  end
48
47
 
49
48
  def rpms_match?(source_repo, target_repo)
50
- source_repo_ids = source_repo.rpm_ids.sort
51
- target_repo_ids = target_repo.rpm_ids.sort
49
+ source_repo_ids = source_repo.rpm_ids.sort.uniq
50
+ target_repo_ids = target_repo.rpm_ids.sort.uniq
52
51
  source_repo_ids == target_repo_ids
53
52
  end
54
53
 
55
54
  def errata_match?(source_repo, target_repo)
56
- source_repo_ids = source_repo.erratum_ids.sort
57
- target_repo_ids = target_repo.erratum_ids.sort
55
+ source_repo_ids = source_repo.erratum_ids.sort.uniq
56
+ target_repo_ids = target_repo.erratum_ids.sort.uniq
58
57
  source_repo_ids == target_repo_ids
59
58
  end
60
59
 
61
60
  def package_groups_match?(source_repo, target_repo)
62
- source_repo_ids = source_repo.package_groups.order(:name).pluck(:name)
63
- target_repo_ids = target_repo.package_groups.order(:name).pluck(:name)
61
+ source_repo_ids = source_repo.package_groups.order(:name).pluck(:name).uniq
62
+ target_repo_ids = target_repo.package_groups.order(:name).pluck(:name).uniq
64
63
  source_repo_ids == target_repo_ids
65
64
  end
66
65
 
@@ -69,8 +68,8 @@ module Actions
69
68
  end
70
69
 
71
70
  def yum_metadata_files_match?(source_repo, target_repo)
72
- source_repo_items = source_repo.yum_metadata_files.pluck(:name, :checksum).sort
73
- target_repo_items = target_repo.yum_metadata_files.pluck(:name, :checksum).sort
71
+ source_repo_items = source_repo.yum_metadata_files.pluck(:name, :checksum).sort.uniq
72
+ target_repo_items = target_repo.yum_metadata_files.pluck(:name, :checksum).sort.uniq
74
73
  source_repo_items == target_repo_items
75
74
  end
76
75
  end
@@ -21,14 +21,14 @@ module Actions
21
21
  # rubocop:disable Metrics/CyclomaticComplexity
22
22
  # rubocop:disable Metrics/PerceivedComplexity
23
23
  # rubocop:disable Metrics/AbcSize
24
- def plan(repo, _pulp_sync_task_id = nil, options = {})
24
+ def plan(repo, options = {})
25
25
  action_subject(repo)
26
26
 
27
27
  source_url = options.fetch(:source_url, nil)
28
28
  incremental = options.fetch(:incremental, false)
29
29
  validate_contents = options.fetch(:validate_contents, false)
30
30
  skip_metadata_check = options.fetch(:skip_metadata_check, false) || (validate_contents && repo.yum?)
31
- generate_applicability = repo.yum?
31
+ generate_applicability = options.fetch(:generate_applicability, repo.yum?)
32
32
 
33
33
  fail ::Katello::Errors::InvalidActionOptionError, _("Unable to sync repo. This repository does not have a feed url.") if repo.url.blank? && source_url.blank?
34
34
  fail ::Katello::Errors::InvalidActionOptionError, _("Cannot validate contents on non-yum/deb repositories.") if validate_contents && !repo.yum? && !repo.deb?
@@ -68,13 +68,10 @@ module Actions
68
68
  plan_action(Pulp::Repository::Download, :pulp_id => repo.pulp_id, :options => {:verify_all_units => true}) if validate_contents && repo.yum?
69
69
  plan_action(Katello::Repository::MetadataGenerate, repo, :force => true) if skip_metadata_check && repo.yum?
70
70
  plan_action(Katello::Repository::ErrataMail, repo, nil, contents_changed)
71
- if generate_applicability
72
- regenerate_applicability(repo, contents_changed)
73
- end
71
+ plan_action(Actions::Katello::Applicability::Repository::Regenerate, :repo_ids => [repo.id]) if generate_applicability
74
72
  end
75
73
  plan_self(:id => repo.id, :sync_result => output, :skip_metadata_check => skip_metadata_check, :validate_contents => validate_contents,
76
74
  :contents_changed => contents_changed)
77
- plan_action(Katello::Repository::ImportApplicability, :repo_id => repo.id, :contents_changed => contents_changed) if generate_applicability
78
75
  plan_action(Katello::Repository::SyncHook, :id => repo.id)
79
76
  end
80
77
  end
@@ -115,14 +112,6 @@ module Actions
115
112
  end
116
113
  end
117
114
 
118
- def regenerate_applicability(repo, contents_changed)
119
- if SETTINGS[:katello][:katello_applicability]
120
- plan_action(Actions::Katello::Applicability::Repository::Regenerate, :repo_id => repo.id, :contents_changed => contents_changed)
121
- else
122
- plan_action(Pulp::Repository::RegenerateApplicability, :repository_id => repo.id, :contents_changed => contents_changed)
123
- end
124
- end
125
-
126
115
  def rescue_strategy
127
116
  Dynflow::Action::Rescue::Skip
128
117
  end
@@ -13,7 +13,7 @@ module Actions
13
13
  else
14
14
  options = {}
15
15
  options[:validate_contents] = true
16
- plan_action(Actions::Katello::Repository::Sync, repo, nil, options)
16
+ plan_action(Actions::Katello::Repository::Sync, repo, options)
17
17
  end
18
18
  end
19
19
 
@@ -19,8 +19,13 @@ module Actions
19
19
  syncable_products = sync_plan.products.syncable
20
20
  syncable_roots = ::Katello::RootRepository.where(:product_id => syncable_products).has_url
21
21
 
22
- plan_action(::Actions::BulkAction, ::Actions::Katello::Repository::Sync, syncable_roots.map(&:library_instance).compact) unless syncable_roots.empty?
23
- plan_self(:sync_plan_name => sync_plan.name)
22
+ sequence do
23
+ plan_self(:sync_plan_name => sync_plan.name)
24
+ if syncable_roots.any?
25
+ plan_action(::Actions::BulkAction, ::Actions::Katello::Repository::Sync, syncable_roots.map(&:library_instance).compact, generate_applicability: false)
26
+ plan_action(Actions::Katello::Applicability::Repository::Regenerate, :repo_ids => syncable_roots.map(&:library_instance).map(&:id))
27
+ end
28
+ end
24
29
  end
25
30
  end
26
31
 
@@ -2,16 +2,12 @@ module Actions
2
2
  module Pulp3
3
3
  module ContentGuard
4
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
5
+ def plan(smart_proxy)
6
+ plan_self(smart_proxy_id: smart_proxy.id)
7
+ end
8
+
9
+ def run
10
+ ::Katello::Pulp3::Api::ContentGuard.new(smart_proxy).refresh
15
11
  end
16
12
  end
17
13
  end
@@ -2,7 +2,7 @@ module Actions
2
2
  module Pulp3
3
3
  module Orchestration
4
4
  module OrphanCleanup
5
- class RemoveOrphans < Pulp::Abstract
5
+ class RemoveOrphans < Pulp3::Abstract
6
6
  def plan(proxy)
7
7
  if proxy.pulp3_enabled?
8
8
  sequence do
@@ -23,6 +23,7 @@ module Actions
23
23
  if version_href
24
24
  if repo.version_href != version_href || input[:force_fetch_version]
25
25
  output[:contents_changed] = true
26
+ repo.update(:last_contents_changed => DateTime.now)
26
27
  repo.update(:version_href => version_href)
27
28
  end
28
29
  else
@@ -53,7 +53,7 @@ module Katello
53
53
 
54
54
  class PulpcoreMissingCapabilities < StandardError
55
55
  def message
56
- _("A smart proxy seems to have been refreshed without pulpcore being running. You may want to ")
56
+ _("A smart proxy seems to have been refreshed without pulpcore being running. Please refresh the smart proxy after ensuring that pulpcore services are running.")
57
57
  end
58
58
  end
59
59
 
@@ -38,6 +38,7 @@ module Katello
38
38
  begin
39
39
  service_class.close
40
40
  service_class.run
41
+ sleep 0.1
41
42
  @service_statuses[service_name] = service_class.status
42
43
  rescue => error
43
44
  Rails.logger.error("Error occurred while starting #{service_class}")
@@ -2,8 +2,6 @@ module Katello
2
2
  module EventDaemon
3
3
  module Services
4
4
  class AgentEventReceiver
5
- STATUS_CACHE_KEY = 'katello_agent_events'.freeze
6
-
7
5
  class Handler
8
6
  attr_accessor :processed, :failed
9
7
 
@@ -48,14 +46,12 @@ module Katello
48
46
  @agent_connection&.open? && @thread&.status.present?
49
47
  end
50
48
 
51
- def self.status(refresh: true)
52
- Rails.cache.fetch(STATUS_CACHE_KEY, force: refresh) do
53
- {
54
- running: running?,
55
- processed_count: @handler&.processed || 0,
56
- failed_count: @handler&.failed || 0
57
- }
58
- end
49
+ def self.status
50
+ {
51
+ running: running?,
52
+ processed_count: @handler&.processed || 0,
53
+ failed_count: @handler&.failed || 0
54
+ }
59
55
  end
60
56
  end
61
57
  end
@@ -0,0 +1,126 @@
1
+ # Used exclusively by fix_hostgroup_facets.rake task
2
+ module Katello
3
+ module Util
4
+ class HostgroupFacetsHelper
5
+ def initialize
6
+ @logger = Logger.new($stdout)
7
+ end
8
+
9
+ def interested_hostgroups
10
+ groups = ::Hostgroup.unscoped.where(
11
+ id: Katello::Hostgroup::ContentFacet.
12
+ where(content_source_id: nil,
13
+ kickstart_repository_id: nil,
14
+ content_view_id: nil,
15
+ lifecycle_environment_id: nil).select(:hostgroup_id))
16
+ parents = groups.select { |group| group.parent.blank? }
17
+ children = groups.reject { |group| group.parent.blank? }
18
+ # we want the parents to get created before the children
19
+ # hence the order
20
+ parents + children
21
+ end
22
+
23
+ def pick_facet_values(hg)
24
+ # This call looks at the audit logs for a host group.
25
+ # Pries out information related to lce, ks, cv and content_source_id from the audit logs.
26
+ # The audit logs typically only contain updates.
27
+ # So if the user changed just the content_view_id, then that is the only thing marked as audited_changes.
28
+ # Hence we need to go through all the audit logs until we have information on lce, ks, cv and cs.
29
+ # If there was only one audit log and that was during the creation of hostgroup
30
+ # the audited changes look like this
31
+ # ```ruby
32
+ # {
33
+ # content_view_id: 10,
34
+ # kickstart_repository_id: 1000
35
+ # ......
36
+ # }
37
+ # ```
38
+ # However if you updated the hostgroup and set the kickstart_repository_id, or
39
+ # content_view_id then audited changes look like
40
+ # ```ruby
41
+ # {
42
+ # content_view_id: [10, 11],
43
+ # kickstart_repository_id: [1000, 1200]
44
+ # ......
45
+ # }
46
+ # ```
47
+ # So the code says "if the attribute value is an array pick the last value else just keep the value as it is "
48
+
49
+ # Further along it is to be noted that `hostgroup.audits` returns the audits ordered by the version number in ascending order, so the latest audit will be `hostgroup.audits.last`
50
+
51
+ # We want to iterate though each audit from latest audit to start, and as soon as we find a content_view_id key or kickstart_repository_id key or lifecycle environment_id key or content_source_id key we want it to be set once.
52
+
53
+ # So if I had an audit history like
54
+ # ``` ruby
55
+ # {
56
+ # content_view_id: 10,
57
+ # kickstart_repository_id: 1000,
58
+ # version:1
59
+ # ......
60
+ # },
61
+ # {
62
+ # content_view_id: [10, 11],
63
+ # kickstart_repository_id: [1000, 1200],
64
+ # version: 2
65
+ # ......
66
+ # }
67
+ # ```
68
+
69
+ # The code would start at version 2, notice that cv_id and ks_repo were set there
70
+ # and keep them as the final.
71
+ # So when it goes to version 1 since cv_id and ks_repo are already set,
72
+ # it will ignore. It will finally
73
+ # return {content_view_id: 11, kickstart_repository_id: 1200}
74
+ facet_values = {}
75
+ hg.audits.reverse_each do |audit|
76
+ hg_changes = audit.audited_changes.slice("lifecycle_environment_id",
77
+ "kickstart_repository_id",
78
+ "content_view_id",
79
+ "content_source_id")
80
+ facet_values = hg_changes.merge(facet_values)
81
+ end
82
+
83
+ values = facet_values.map do |k, v|
84
+ v = v[-1] if v.is_a? Array
85
+ [k, v]
86
+ end
87
+ values.to_h.with_indifferent_access
88
+ end
89
+
90
+ def main
91
+ bad_hgs = []
92
+ good_hgs = []
93
+
94
+ groups = interested_hostgroups.each do |hg|
95
+ facet = hg.content_facet
96
+ values = pick_facet_values(hg)
97
+ if !values.empty? && facet.update(values)
98
+ good_hgs << { hostgroup: hg, facet_values: values }
99
+ else
100
+ bad_hgs << { hostgroup: hg, facet_values: values }
101
+ facet.save(validate: false)
102
+ end
103
+ end
104
+
105
+ unless bad_hgs.empty?
106
+ @logger.warn "Some of the hostgroups reported a validation error. "\
107
+ "The hostgroups have been updated. "\
108
+ "Check via the Web UI."
109
+
110
+ bad_hgs.each do |bad_group|
111
+ @logger.warn "Hostgroup #{bad_group[:hostgroup]}"
112
+ @logger.warn "Facet Values #{bad_group[:facet_values]}"
113
+ end
114
+ end
115
+ unless good_hgs.empty?
116
+ @logger.info "Following hostgroups were succesfully updated."
117
+ good_hgs.each do |good_group|
118
+ @logger.info "Hostgroup #{good_group[:hostgroup]}"
119
+ @logger.info "Facet Values #{good_group[:facet_values]}"
120
+ end
121
+ end
122
+ @logger.info("#{groups.count} Hostgroup(s) were updated.")
123
+ end
124
+ end
125
+ end
126
+ end
@@ -24,10 +24,6 @@ module Katello
24
24
  authorized?(:promote_or_remove_content_views) && Katello::KTEnvironment.any_promotable?
25
25
  end
26
26
 
27
- def exportable?
28
- authorized?(:export_content_views)
29
- end
30
-
31
27
  module ClassMethods
32
28
  def readable
33
29
  authorized(:view_content_views)
@@ -37,10 +33,6 @@ module Katello
37
33
  authorized(:view_content_views)
38
34
  end
39
35
 
40
- def importable?
41
- creatable? && publishable?
42
- end
43
-
44
36
  def readable_as(user)
45
37
  authorized_as(user, :view_content_views)
46
38
  end
@@ -75,7 +67,11 @@ module Katello
75
67
  end
76
68
 
77
69
  def exportable
78
- authorized(:export_content_views)
70
+ where(organization: Organization.authorized(:export_content))
71
+ end
72
+
73
+ def importable
74
+ where(organization: Organization.authorized(:import_content))
79
75
  end
80
76
 
81
77
  def readable_repositories(repo_ids = nil)
@@ -12,12 +12,12 @@ module Katello
12
12
  authorized?(:import_manifest)
13
13
  end
14
14
 
15
- def can_import_library_content?
16
- authorized?(:import_library_content)
15
+ def can_import_content?
16
+ authorized?(:import_content)
17
17
  end
18
18
 
19
- def can_export_library_content?
20
- authorized?(:export_library_content)
19
+ def can_export_content?
20
+ authorized?(:export_content)
21
21
  end
22
22
 
23
23
  def readable_promotion_paths
@@ -102,7 +102,9 @@ module Katello
102
102
  return true unless operatingsystem
103
103
 
104
104
  if operatingsystem.respond_to? :kickstart_repos
105
- return operatingsystem.kickstart_repos(self).any? { |repo| repo[:id] == (content_facet&.kickstart_repository_id || content_facet&.kickstart_repository&.id) }
105
+ operatingsystem.kickstart_repos(self, content_facet: content_facet).any? do |repo|
106
+ repo[:id] == (content_facet&.kickstart_repository_id || content_facet&.kickstart_repository&.id)
107
+ end
106
108
  end
107
109
  end
108
110
 
@@ -62,6 +62,48 @@ module Katello
62
62
  [Katello::Rpm, Katello::Srpm]
63
63
  end
64
64
 
65
+ def content_unit_association_id
66
+ "#{self.name.demodulize.underscore}_id".to_sym #Rpm => rpm_id
67
+ end
68
+
69
+ def repository_association_units
70
+ repository_association_class.name.demodulize.pluralize.underscore.to_sym
71
+ end
72
+
73
+ def content_units_name
74
+ self.name.demodulize.pluralize.underscore.to_sym
75
+ end
76
+
77
+ def installable_for_content_facet(facet, env = nil, content_view = nil)
78
+ repos = if env && content_view
79
+ Katello::Repository.in_environment(env).in_content_views([content_view])
80
+ else
81
+ facet.bound_repositories.pluck(:id)
82
+ end
83
+ facet.send("applicable_#{content_units_name}".to_sym).in_repositories(repos)
84
+ end
85
+
86
+ def installable_for_hosts(hosts = nil)
87
+ # Main goal of this query
88
+ # 1) Get me the applicable content units for these set of hosts
89
+ # 2) Now further prune this list. Only include units from repos that have been "enabled" on those hosts.
90
+ # In other words, prune the list to only include the units in the "bound" repositories signified by
91
+ # the inner join between ContentFacetRepository and Repository<Unit>
92
+
93
+ facet_repos = Katello::ContentFacetRepository.joins(:content_facet => :host).select(:repository_id)
94
+ facet_content_units = content_facet_association_class.joins(:content_facet => :host).select(content_unit_association_id)
95
+
96
+ if hosts
97
+ hosts = ::Host.where(id: hosts) if hosts.is_a?(Array)
98
+ facet_repos = facet_repos.merge(hosts).reorder(nil)
99
+ facet_content_units = facet_content_units.merge(hosts).reorder(nil)
100
+ end
101
+
102
+ self.joins(repository_association_units).
103
+ where(repository_association_class.table_name => {:repository_id => facet_repos,
104
+ content_unit_association_id => facet_content_units}).distinct
105
+ end
106
+
65
107
  def with_identifiers(ids)
66
108
  ids = [ids] unless ids.is_a?(Array)
67
109
  ids.map!(&:to_s)