katello 3.18.0.rc1 → 3.18.0.rc2

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/content_view_filters_controller.rb +17 -8
  3. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +5 -2
  4. data/app/controllers/katello/api/v2/content_views_controller.rb +10 -1
  5. data/app/controllers/katello/api/v2/host_debs_controller.rb +1 -0
  6. data/app/controllers/katello/api/v2/host_errata_controller.rb +2 -2
  7. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +18 -6
  8. data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +1 -1
  9. data/app/controllers/katello/api/v2/products_controller.rb +9 -9
  10. data/app/controllers/katello/api/v2/repository_sets_controller.rb +24 -14
  11. data/app/controllers/katello/concerns/api/v2/authorization.rb +10 -0
  12. data/app/controllers/katello/concerns/api/v2/bulk_hosts_extensions.rb +22 -18
  13. data/app/controllers/katello/concerns/registration_controller_extensions.rb +16 -0
  14. data/app/lib/actions/helpers/smart_proxy_sync_history_helper.rb +24 -0
  15. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +16 -7
  16. data/app/lib/actions/katello/content_view/publish.rb +5 -4
  17. data/app/lib/actions/katello/content_view_version/import.rb +3 -10
  18. data/app/lib/actions/katello/host/upload_package_profile.rb +3 -1
  19. data/app/lib/actions/katello/host/upload_profiles.rb +8 -6
  20. data/app/lib/actions/katello/repository/import_upload.rb +2 -0
  21. data/app/lib/actions/katello/repository/remove_content.rb +1 -1
  22. data/app/lib/actions/katello/repository/sync.rb +3 -1
  23. data/app/lib/actions/katello/repository/update.rb +1 -0
  24. data/app/lib/actions/katello/repository/upload_files.rb +1 -0
  25. data/app/lib/actions/middleware/record_smart_proxy_sync_history.rb +15 -0
  26. data/app/lib/actions/pulp/consumer/sync_capsule.rb +4 -2
  27. data/app/lib/actions/pulp/repository/distributor_publish.rb +1 -1
  28. data/app/lib/actions/pulp3/abstract_async_task.rb +1 -0
  29. data/app/lib/actions/pulp3/capsule_content/sync.rb +1 -0
  30. data/app/lib/actions/pulp3/content_view_version/export.rb +5 -1
  31. data/app/lib/actions/pulp3/orchestration/content_view_version/export.rb +23 -6
  32. data/app/lib/actions/pulp3/orchestration/repository/generate_metadata.rb +4 -1
  33. data/app/models/katello/authorization/content_view_filter.rb +15 -0
  34. data/app/models/katello/concerns/smart_proxy_extensions.rb +2 -0
  35. data/app/models/katello/content_view.rb +25 -4
  36. data/app/models/katello/content_view_filter.rb +5 -0
  37. data/app/models/katello/content_view_puppet_module.rb +8 -0
  38. data/app/models/katello/content_view_repository.rb +13 -1
  39. data/app/models/katello/ping.rb +8 -3
  40. data/app/models/katello/repository.rb +26 -0
  41. data/app/models/katello/smart_proxy_sync_history.rb +8 -0
  42. data/app/services/katello/pulp3/content_view_version/export.rb +64 -6
  43. data/app/services/katello/pulp3/content_view_version/import.rb +2 -27
  44. data/app/services/katello/pulp3/content_view_version/import_export_common.rb +6 -0
  45. data/app/services/katello/pulp3/content_view_version/import_validator.rb +107 -0
  46. data/app/services/katello/pulp3/migration.rb +7 -1
  47. data/app/services/katello/pulp3/repository/yum.rb +1 -2
  48. data/app/services/katello/pulp3/task.rb +3 -3
  49. data/app/services/katello/pulp3/task_group.rb +6 -0
  50. data/app/services/katello/repository_type.rb +2 -1
  51. data/app/services/katello/smart_proxy_helper.rb +9 -0
  52. data/app/views/foreman/hosts/_registration.html.erb +12 -0
  53. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -0
  54. data/db/migrate/20200929200357_create_katello_smart_proxy_sync_history.rb +13 -0
  55. data/db/migrate/20201021150008_add_import_only_to_katello_content_view.rb +5 -0
  56. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/content-views.controller.js +6 -2
  57. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-details.controller.js +12 -0
  58. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-details.html +7 -7
  59. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-info.html +7 -1
  60. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/new/content-view-new.controller.js +17 -3
  61. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/new/views/content-view-new.html +16 -2
  62. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/views/content-views.html +5 -0
  63. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository-types.service.js +8 -1
  64. data/lib/katello/engine.rb +1 -0
  65. data/lib/katello/permission_creator.rb +11 -11
  66. data/lib/katello/plugin.rb +6 -1
  67. data/lib/katello/tasks/pulp3_migration_abort.rake +17 -0
  68. data/lib/katello/version.rb +1 -1
  69. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +13 -11
  70. data/webpack/test-utils/react-testing-lib-wrapper.js +3 -0
  71. metadata +12 -3
  72. data/webpack/__mocks__/foremanReact/components/common/Fill/GlobalFill.js +0 -3
@@ -9,9 +9,8 @@ module Actions
9
9
  content_view = options[:content_view]
10
10
  repository = options[:repository]
11
11
  skip_metadata_check = options.fetch(:skip_metadata_check, false)
12
-
13
12
  sequence do
14
- repos = repos_to_sync(smart_proxy, environment, content_view, repository)
13
+ repos = repos_to_sync(smart_proxy, environment, content_view, repository, skip_metadata_check)
15
14
 
16
15
  repos.in_groups_of(Setting[:foreman_proxy_content_batch_size], false) do |repo_batch|
17
16
  concurrence do
@@ -20,7 +19,6 @@ module Actions
20
19
  Actions::Pulp3::CapsuleContent::Sync],
21
20
  repo, smart_proxy,
22
21
  skip_metadata_check: skip_metadata_check)
23
-
24
22
  if repo.is_a?(::Katello::Repository) &&
25
23
  repo.distribution_bootable? &&
26
24
  repo.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND
@@ -34,22 +32,33 @@ module Actions
34
32
  end
35
33
  end
36
34
 
37
- def repos_to_sync(smart_proxy, environment, content_view, repository)
35
+ def repos_to_sync(smart_proxy, environment, content_view, repository, skip_metatadata_check = false)
38
36
  smart_proxy_helper = ::Katello::SmartProxyHelper.new(smart_proxy)
39
37
  smart_proxy_helper.lifecycle_environment_check(environment, repository)
40
-
41
38
  if repository
42
- [repository]
39
+ if skip_metatadata_check || !repository.smart_proxy_sync_histories.where(:smart_proxy_id => smart_proxy).any? { |sph| !sph.finished_at.nil? }
40
+ [repository]
41
+ end
43
42
  else
44
43
  repositories = smart_proxy_helper.repositories_available_to_capsule(environment, content_view).by_rpm_count
45
44
  puppet_envs = smart_proxy_helper.puppet_environments_available_to_capsule(environment, content_view)
46
- repositories + puppet_envs
45
+ repositories_to_skip = []
46
+ if skip_metatadata_check
47
+ smart_proxy_helper.clear_smart_proxy_sync_histories repositories
48
+ else
49
+ repositories_to_skip = ::Katello::Repository.synced_on_capsule smart_proxy
50
+ end
51
+ repositories - repositories_to_skip + puppet_envs
47
52
  end
48
53
  end
49
54
 
50
55
  def resource_locks
51
56
  :link
52
57
  end
58
+
59
+ def rescue_strategy
60
+ Dynflow::Action::Rescue::Skip
61
+ end
53
62
  end
54
63
  end
55
64
  end
@@ -6,10 +6,10 @@ module Actions
6
6
  include ::Katello::ContentViewHelper
7
7
  attr_accessor :version
8
8
  # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity
9
- def plan(content_view, description = "", options = {})
9
+ def plan(content_view, description = "", options = {importing: false})
10
10
  action_subject(content_view)
11
- import_only = options.fetch(:import_only, false)
12
- content_view.check_ready_to_publish! unless import_only
11
+
12
+ content_view.check_ready_to_publish!(importing: options[:importing])
13
13
 
14
14
  if options[:repos_units].present?
15
15
  valid_labels_from_cv = content_view.repositories.map(&:label)
@@ -52,7 +52,8 @@ module Actions
52
52
 
53
53
  if separated_repo_map[:pulp3_yum].keys.flatten.present? &&
54
54
  SmartProxy.pulp_primary.pulp3_support?(separated_repo_map[:pulp3_yum].keys.flatten.first)
55
- if import_only
55
+
56
+ if options[:importing]
56
57
  handle_import(version, options.slice(:path, :metadata))
57
58
  else
58
59
  plan_action(Repository::MultiCloneToVersion, separated_repo_map[:pulp3_yum], version)
@@ -2,28 +2,21 @@ module Actions
2
2
  module Katello
3
3
  module ContentViewVersion
4
4
  class Import < Actions::EntryAction
5
- PULP_USER = 'pulp'.freeze
6
-
7
5
  def plan(content_view, path:, metadata:)
8
6
  content_view.check_ready_to_import!
9
7
  unless SmartProxy.pulp_primary.pulp3_repository_type_support?(::Katello::Repository::YUM_TYPE)
10
8
  fail ::Katello::HttpErrors::BadRequest, _("This API endpoint is only valid for Pulp 3 repositories.")
11
9
  end
12
- ::Katello::Pulp3::ContentViewVersion::Import.check_permissions!(path)
10
+
11
+ ::Katello::Pulp3::ContentViewVersion::Import.check!(content_view: content_view, metadata: metadata, path: path)
13
12
 
14
13
  major = metadata[:content_view_version][:major]
15
14
  minor = metadata[:content_view_version][:minor]
16
15
 
17
- if ::Katello::ContentViewVersion.where(major: major, minor: minor, content_view: content_view).exists?
18
- cvv_name = "#{content_view.name} #{major}.#{minor}"
19
- fail _("Content View Version specified in the metadata - '%{name}' already exists. "\
20
- "If you wish to replace the existing version, delete %{name} and try again. " % { name: cvv_name })
21
- end
22
-
23
16
  plan_action(::Actions::Katello::ContentView::Publish, content_view, '',
24
17
  path: path,
25
18
  metadata: metadata,
26
- import_only: true,
19
+ importing: true,
27
20
  major: major,
28
21
  minor: minor)
29
22
  end
@@ -39,7 +39,9 @@ module Actions
39
39
  Rails.logger.warn("Host with ID %s has no content facet, continuing" % host_id)
40
40
  else
41
41
  begin
42
- ::Katello::Pulp::Consumer.new(host.content_facet.uuid).upload_package_profile(profile)
42
+ unless SmartProxy.pulp_primary&.pulp3_repository_type_support?(::Katello::Repository::YUM_TYPE)
43
+ ::Katello::Pulp::Consumer.new(host.content_facet.uuid).upload_package_profile(profile)
44
+ end
43
45
  simple_packages = profile.map { |item| ::Katello::Pulp::SimplePackage.new(item) }
44
46
  host.import_package_profile(simple_packages)
45
47
  rescue RestClient::ResourceNotFound
@@ -60,12 +60,14 @@ module Actions
60
60
 
61
61
  module_stream_profile = updated_profiles + unassociated_profiles
62
62
 
63
- unless module_stream_profile.empty?
64
- begin
65
- ::Katello::Pulp::Consumer.new(host.content_facet.uuid).
66
- upload_module_stream_profile(module_stream_profile)
67
- rescue RestClient::ResourceNotFound
68
- Rails.logger.warn("Host with ID %s was not known to Pulp, continuing" % host.id)
63
+ unless SmartProxy.pulp_primary&.pulp3_repository_type_support?(::Katello::Repository::YUM_TYPE)
64
+ unless module_stream_profile.empty?
65
+ begin
66
+ ::Katello::Pulp::Consumer.new(host.content_facet.uuid).
67
+ upload_module_stream_profile(module_stream_profile)
68
+ rescue RestClient::ResourceNotFound
69
+ Rails.logger.warn("Host with ID %s was not known to Pulp, continuing" % host.id)
70
+ end
69
71
  end
70
72
  end
71
73
  end
@@ -4,8 +4,10 @@ module Actions
4
4
  module Repository
5
5
  class ImportUpload < Actions::EntryAction
6
6
  include Actions::Katello::PulpSelector
7
+ # rubocop:disable Metrics/MethodLength
7
8
  def plan(repository, uploads, options = {})
8
9
  action_subject(repository)
10
+ repository.clear_smart_proxy_sync_histories
9
11
  repo_service = repository.backend_service(::SmartProxy.pulp_primary)
10
12
 
11
13
  upload_ids = uploads.pluck('id')
@@ -23,7 +23,7 @@ module Actions
23
23
  remove_content_args = {
24
24
  :contents => content_unit_ids,
25
25
  :content_unit_type => content_unit_type}
26
-
26
+ repository.clear_smart_proxy_sync_histories
27
27
  pulp_action = plan_pulp_action(
28
28
  [Pulp::Orchestration::Repository::RemoveUnits,
29
29
  Pulp3::Orchestration::Repository::RemoveUnits],
@@ -79,7 +79,9 @@ module Actions
79
79
  end
80
80
 
81
81
  def run
82
- ForemanTasks.async_task(Repository::CapsuleSync, ::Katello::Repository.find(input[:id])) if Setting[:foreman_proxy_content_auto_sync]
82
+ repo = ::Katello::Repository.find(input[:id])
83
+ repo.clear_smart_proxy_sync_histories if input[:contents_changed]
84
+ ForemanTasks.async_task(Repository::CapsuleSync, repo) if Setting[:foreman_proxy_content_auto_sync]
83
85
  rescue ::Katello::Errors::CapsuleCannotBeReached # skip any capsules that cannot be connected to
84
86
  end
85
87
 
@@ -60,6 +60,7 @@ module Actions
60
60
  def run
61
61
  repository = ::Katello::Repository.find(input[:repository_id])
62
62
  ForemanTasks.async_task(Katello::Repository::MetadataGenerate, repository)
63
+ repository.clear_smart_proxy_sync_histories
63
64
  end
64
65
 
65
66
  private
@@ -9,6 +9,7 @@ module Actions
9
9
  include Actions::Katello::PulpSelector
10
10
  def plan(repository, files, content_type = nil)
11
11
  action_subject(repository)
12
+ repository.clear_smart_proxy_sync_histories
12
13
  tmp_files = prepare_tmp_files(files)
13
14
 
14
15
  content_type ||= ::Katello::RepositoryTypeManager.find(repository.content_type).default_managed_content_type.label
@@ -0,0 +1,15 @@
1
+ module Actions
2
+ module Middleware
3
+ class RecordSmartProxySyncHistory < Dynflow::Middleware
4
+ def run(*args)
5
+ if (action.input[:repository_id] && (action.input[:smart_proxy_id] || action.input[:capsule_id]) && !self.action.output[:smart_proxy_history_id])
6
+ repo = ::Katello::Repository.find(action.input[:repository_id])
7
+ smart_proxy_id = action.input[:smart_proxy_id] || action.input[:capsule_id]
8
+ smart_proxy = ::SmartProxy.find(smart_proxy_id)
9
+ self.action.output[:smart_proxy_history_id] = repo.create_smart_proxy_sync_history(smart_proxy)
10
+ end
11
+ pass(*args)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,14 +2,16 @@ module Actions
2
2
  module Pulp
3
3
  module Consumer
4
4
  class SyncCapsule < ::Actions::Pulp::AbstractAsyncTask
5
+ include ::Actions::Helpers::SmartProxySyncHistoryHelper
5
6
  input_format do
6
7
  param :capsule_id, Integer
7
8
  param :repo_pulp_id, String
9
+ param :repository_id, Integer
8
10
  param :sync_options
9
11
  end
10
12
 
11
13
  def plan(repository, smart_proxy, options)
12
- plan_self(:capsule_id => smart_proxy.id, :repo_pulp_id => repository.pulp_id, :sync_options => options)
14
+ plan_self(:capsule_id => smart_proxy.id, :repo_pulp_id => repository.pulp_id, :repository_id => repository.id, :sync_options => options)
13
15
  end
14
16
 
15
17
  def humanized_name
@@ -17,7 +19,7 @@ module Actions
17
19
  end
18
20
 
19
21
  def invoke_external_task
20
- pulp_resources.repository.sync(input[:repo_pulp_id], override_config: input[:sync_options])
22
+ output[:pulp_tasks] = pulp_resources.repository.sync(input[:repo_pulp_id], override_config: input[:sync_options])
21
23
  end
22
24
 
23
25
  def run_progress
@@ -20,7 +20,7 @@ module Actions
20
20
  else
21
21
  repo = ::Katello::ContentViewPuppetEnvironment.find_by(:id => input[:content_view_puppet_environment_id]).nonpersisted_repository
22
22
  end
23
-
23
+ repo.clear_smart_proxy_sync_histories if smart_proxy(input[:smart_proxy_id]).pulp_primary?
24
24
  repo.backend_service(smart_proxy(input[:smart_proxy_id])).distributor_publish(input[:options])
25
25
  end
26
26
 
@@ -74,6 +74,7 @@ module Actions
74
74
 
75
75
  def cancel
76
76
  pulp_tasks.each { |task| task.cancel }
77
+ task_groups.each { |task_group| task_group.cancel }
77
78
  end
78
79
 
79
80
  def rescue_external_task(error)
@@ -2,6 +2,7 @@ module Actions
2
2
  module Pulp3
3
3
  module CapsuleContent
4
4
  class Sync < Pulp3::AbstractAsyncTask
5
+ include ::Actions::Helpers::SmartProxySyncHistoryHelper
5
6
  def plan(repository, smart_proxy, options = {})
6
7
  sequence do
7
8
  plan_self(:repository_id => repository.id, :smart_proxy_id => smart_proxy.id, :options => options)
@@ -4,6 +4,7 @@ module Actions
4
4
  class Export < Pulp3::AbstractAsyncTask
5
5
  input_format do
6
6
  param :content_view_version_id, Integer
7
+ param :from_content_view_version_id, Integer
7
8
  param :smart_proxy_id, Integer
8
9
  param :exporter_data, Hash
9
10
  param :chunk_size, Integer
@@ -11,8 +12,11 @@ module Actions
11
12
 
12
13
  def invoke_external_task
13
14
  cvv = ::Katello::ContentViewVersion.find(input[:content_view_version_id])
15
+ from_cvv = ::Katello::ContentViewVersion.find(input[:from_content_view_version_id]) unless input[:from_content_view_version_id].blank?
14
16
  ::Katello::Pulp3::ContentViewVersion::Export.new(smart_proxy: smart_proxy,
15
- content_view_version: cvv).create_export(input[:exporter_data][:pulp_href], input[:chunk_size])
17
+ content_view_version: cvv,
18
+ from_content_view_version: from_cvv).create_export(input[:exporter_data][:pulp_href],
19
+ chunk_size: input[:chunk_size])
16
20
  end
17
21
  end
18
22
  end
@@ -6,6 +6,7 @@ module Actions
6
6
  input_format do
7
7
  param :smart_proxy_id, Integer
8
8
  param :content_view_version_id, Integer
9
+ param :from_content_view_version_id, Integer
9
10
  param :export_history_id, Integer
10
11
  param :exporter_data, Hash
11
12
  param :destination_server, String
@@ -16,7 +17,8 @@ module Actions
16
17
  param :export_path, String
17
18
  end
18
19
 
19
- def plan(content_view_version, destination_server:, chunk_size: nil)
20
+ # rubocop:disable Metrics/MethodLength
21
+ def plan(content_view_version, destination_server:, chunk_size: nil, from_history: nil)
20
22
  action_subject(content_view_version)
21
23
  unless File.directory?(Setting['pulpcore_export_destination'])
22
24
  fail ::Foreman::Exception, N_("Unable to export. 'pulpcore_export_destination' setting is not set to a valid directory.")
@@ -24,6 +26,16 @@ module Actions
24
26
 
25
27
  sequence do
26
28
  smart_proxy = SmartProxy.pulp_primary!
29
+ from_content_view_version = from_history&.content_view_version
30
+ if from_content_view_version.present?
31
+ export_service = ::Katello::Pulp3::ContentViewVersion::Export.new(
32
+ smart_proxy: smart_proxy,
33
+ content_view_version: content_view_version,
34
+ destination_server: destination_server,
35
+ from_content_view_version: from_content_view_version)
36
+ export_service.validate_incremental_export!
37
+ end
38
+
27
39
  action_output = plan_action(::Actions::Pulp3::ContentViewVersion::CreateExporter,
28
40
  content_view_version_id: content_view_version.id,
29
41
  smart_proxy_id: smart_proxy.id,
@@ -33,12 +45,13 @@ module Actions
33
45
  content_view_version_id: content_view_version.id,
34
46
  smart_proxy_id: smart_proxy.id,
35
47
  exporter_data: action_output[:exporter_data],
36
- chunk_size: chunk_size
37
- )
48
+ chunk_size: chunk_size,
49
+ from_content_view_version_id: from_content_view_version&.id)
38
50
 
39
51
  plan_self(exporter_data: action_output[:exporter_data], smart_proxy_id: smart_proxy.id,
40
52
  destination_server: destination_server,
41
- content_view_version_id: content_view_version.id)
53
+ content_view_version_id: content_view_version.id,
54
+ from_content_view_version_id: from_content_view_version&.id)
42
55
 
43
56
  plan_action(::Actions::Pulp3::ContentViewVersion::DestroyExporter,
44
57
  smart_proxy_id: smart_proxy.id,
@@ -55,9 +68,13 @@ module Actions
55
68
  path = File.dirname(file_name.to_s)
56
69
  output[:export_path] = path
57
70
  cvv = ::Katello::ContentViewVersion.find(input[:content_view_version_id])
71
+ from_cvv = ::Katello::ContentViewVersion.find(input[:from_content_view_version_id]) unless input[:from_content_view_version_id].blank?
58
72
 
59
- export_metadata = ::Katello::Pulp3::ContentViewVersion::Export.new(:content_view_version => cvv,
60
- :smart_proxy => smart_proxy).generate_metadata
73
+ export_metadata = ::Katello::Pulp3::ContentViewVersion::Export.new(
74
+ content_view_version: cvv,
75
+ smart_proxy: smart_proxy,
76
+ from_content_view_version: from_cvv).generate_metadata
77
+ export_metadata[:incremental] = from_cvv.present?
61
78
  toc = Dir.glob("#{path}/*toc.json").first
62
79
  export_metadata[:toc] = File.basename(toc) if toc
63
80
  ::Katello::ContentViewVersionExportHistory.create!(
@@ -8,7 +8,7 @@ module Actions
8
8
  publication_content_type = !::Katello::RepositoryTypeManager.find(repository.content_type).pulp3_skip_publication
9
9
  sequence do
10
10
  if options[:source_repository] && publication_content_type
11
- plan_self(source_repository_id: options[:source_repository].id, target_repository_id: repository.id)
11
+ plan_self(source_repository_id: options[:source_repository].id, target_repository_id: repository.id, smart_proxy_id: smart_proxy.id)
12
12
  elsif publication_content_type
13
13
  plan_action(Actions::Pulp3::Repository::CreatePublication, repository, smart_proxy, options)
14
14
  end
@@ -21,6 +21,9 @@ module Actions
21
21
  #we don't have to actually generate a publication, we can reuse the old one
22
22
  target_repo = ::Katello::Repository.find(input[:target_repository_id])
23
23
  source_repo = ::Katello::Repository.find(input[:source_repository_id])
24
+ if (target_repo.publication_href != source_repo.publication_href && smart_proxy.pulp_primary?)
25
+ target_repo.clear_smart_proxy_sync_histories
26
+ end
24
27
  target_repo.update!(publication_href: source_repo.publication_href)
25
28
  end
26
29
  end
@@ -0,0 +1,15 @@
1
+ module Katello
2
+ module Authorization::ContentViewFilter
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def readable
7
+ where(:content_view_id => ::Katello::ContentView.readable)
8
+ end
9
+
10
+ def editable
11
+ where(:content_view_id => ::Katello::ContentView.editable)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -49,6 +49,8 @@ module Katello
49
49
  has_many :content_facets, :class_name => "::Katello::Host::ContentFacet", :foreign_key => :content_source_id,
50
50
  :inverse_of => :content_source, :dependent => :nullify
51
51
 
52
+ has_many :smart_proxy_sync_histories, :class_name => "::Katello::SmartProxySyncHistory", :inverse_of => :smart_proxy, dependent: :delete_all
53
+
52
54
  has_many :hostgroup_content_facets, :class_name => "::Katello::Hostgroup::ContentFacet", :foreign_key => :content_source_id,
53
55
  :inverse_of => :content_source, :dependent => :nullify
54
56
  has_many :hostgroups, :class_name => "::Hostgroup", :through => :hostgroup_content_facets
@@ -67,6 +67,14 @@ module Katello
67
67
  validates :composite,
68
68
  inclusion: { in: [false], message: "Composite Content Views can not solve dependencies"},
69
69
  if: :solve_dependencies
70
+ validates :import_only, :inclusion => [true, false]
71
+ validates :import_only,
72
+ inclusion: { in: [false], message: "Import-only Content Views can not be Composite"},
73
+ if: :composite
74
+ validates :import_only,
75
+ inclusion: { in: [false], message: "Import-only Content Views can not solve dependencies"},
76
+ if: :solve_dependencies
77
+ validate :import_only_immutable
70
78
 
71
79
  validates_with Validators::KatelloNameFormatValidator, :attributes => :name
72
80
  validates_with Validators::KatelloLabelFormatValidator, :attributes => :label
@@ -580,16 +588,23 @@ module Katello
580
588
  end
581
589
 
582
590
  def check_ready_to_import!
583
- fail _("User must be logged in.") if ::User.current.nil?
584
591
  fail _("Cannot import a composite content view") if composite?
592
+ fail _("This Content View must be set to Import-only before performing an import") unless import_only?
585
593
  true
586
594
  end
587
595
 
588
- def check_ready_to_publish!
596
+ def check_ready_to_publish!(importing: false)
589
597
  fail _("User must be logged in.") if ::User.current.nil?
590
598
  fail _("Cannot publish default content view") if default?
591
- check_composite_action_allowed!(organization.library)
592
- check_docker_repository_names!([organization.library])
599
+
600
+ if importing
601
+ check_ready_to_import!
602
+ else
603
+ fail _("Import-only content views can not be published directly") if import_only?
604
+ check_composite_action_allowed!(organization.library)
605
+ check_docker_repository_names!([organization.library])
606
+ end
607
+
593
608
  true
594
609
  end
595
610
 
@@ -698,6 +713,12 @@ module Katello
698
713
 
699
714
  private
700
715
 
716
+ def import_only_immutable
717
+ if import_only_changed? && self.persisted?
718
+ errors.add(:import_only, _("Import-only can not be changed after creation"))
719
+ end
720
+ end
721
+
701
722
  def generate_cp_environment_label(env)
702
723
  # The label for a default view, will simply be the env label; otherwise, it
703
724
  # will be a combination of env and view label. The reason being, the label