katello 3.16.0.rc4 → 3.16.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 (108) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +39 -23
  3. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +3 -3
  4. data/app/controllers/katello/api/v2/api_controller.rb +1 -0
  5. data/app/controllers/katello/api/v2/content_view_filters_controller.rb +5 -1
  6. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +3 -0
  7. data/app/controllers/katello/api/v2/content_views_controller.rb +7 -0
  8. data/app/controllers/katello/api/v2/host_tracer_controller.rb +0 -5
  9. data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +15 -0
  10. data/app/controllers/katello/api/v2/repositories_controller.rb +10 -1
  11. data/app/controllers/katello/concerns/api/v2/associations_permission_check.rb +67 -0
  12. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +11 -5
  13. data/app/helpers/katello/content_view_helper.rb +15 -0
  14. data/app/lib/actions/katello/capsule_content/refresh_repos.rb +5 -1
  15. data/app/lib/actions/katello/capsule_content/sync.rb +3 -6
  16. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +31 -17
  17. data/app/lib/actions/katello/content_view/incremental_updates.rb +8 -1
  18. data/app/lib/actions/katello/content_view/presenters/incremental_updates_presenter.rb +2 -1
  19. data/app/lib/actions/katello/content_view/publish.rb +55 -16
  20. data/app/lib/actions/katello/content_view_version/incremental_update.rb +120 -26
  21. data/app/lib/actions/katello/host/attach_subscriptions.rb +5 -1
  22. data/app/lib/actions/katello/product/destroy.rb +25 -4
  23. data/app/lib/actions/katello/repository/destroy.rb +5 -1
  24. data/app/lib/actions/katello/repository/multi_clone_contents.rb +62 -0
  25. data/app/lib/actions/katello/repository/multi_clone_to_version.rb +30 -0
  26. data/app/lib/actions/katello/repository/sync.rb +35 -25
  27. data/app/lib/actions/katello/repository/update.rb +11 -16
  28. data/app/lib/actions/katello/repository/verify_checksum.rb +28 -0
  29. data/app/lib/actions/katello/sync_plan/run.rb +1 -1
  30. data/app/lib/actions/pulp/abstract_async_task.rb +1 -0
  31. data/app/lib/actions/pulp/consumer/sync_capsule.rb +8 -0
  32. data/app/lib/actions/pulp/orchestration/repository/sync.rb +2 -1
  33. data/app/lib/actions/pulp/repository/presenters/deb_presenter.rb +2 -2
  34. data/app/lib/actions/pulp/repository/sync.rb +2 -1
  35. data/app/lib/actions/pulp3/abstract_async_task.rb +62 -58
  36. data/app/lib/actions/pulp3/capsule_content/refresh_content_guard.rb +17 -0
  37. data/app/lib/actions/pulp3/capsule_content/sync.rb +3 -1
  38. data/app/lib/actions/pulp3/{ContentGuard → content_guard}/refresh.rb +0 -0
  39. data/app/lib/actions/pulp3/content_migration.rb +4 -0
  40. data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +2 -4
  41. data/app/lib/actions/pulp3/orchestration/repository/multi_copy_all_units.rb +36 -0
  42. data/app/lib/actions/pulp3/orchestration/repository/sync.rb +3 -1
  43. data/app/lib/actions/pulp3/orchestration/repository/trigger_update_repo_cert_guard.rb +22 -0
  44. data/app/lib/actions/pulp3/repository/copy_content.rb +0 -1
  45. data/app/lib/actions/pulp3/repository/multi_copy_content.rb +28 -0
  46. data/app/lib/actions/pulp3/repository/multi_copy_units.rb +55 -0
  47. data/app/lib/actions/pulp3/repository/presenters/content_unit_presenter.rb +1 -1
  48. data/app/lib/actions/pulp3/repository/presenters/repair_presenter.rb +85 -0
  49. data/app/lib/actions/pulp3/repository/repair.rb +29 -0
  50. data/app/lib/actions/pulp3/repository/save_version.rb +20 -8
  51. data/app/lib/actions/pulp3/repository/save_versions.rb +73 -0
  52. data/app/lib/actions/pulp3/repository/sync.rb +1 -1
  53. data/app/lib/actions/pulp3/repository/update_cv_repository_cert_guard.rb +6 -2
  54. data/app/lib/actions/pulp3/repository/upload_file.rb +1 -1
  55. data/app/lib/katello/concerns/base_template_scope_extensions.rb +4 -14
  56. data/app/lib/katello/errors.rb +1 -15
  57. data/app/lib/katello/resources/cdn.rb +3 -2
  58. data/app/lib/katello/util/cdn_var_substitutor.rb +9 -6
  59. data/app/models/katello/concerns/smart_proxy_extensions.rb +14 -3
  60. data/app/models/katello/content_view.rb +18 -6
  61. data/app/models/katello/content_view_erratum_filter.rb +13 -0
  62. data/app/models/katello/content_view_filter.rb +4 -0
  63. data/app/models/katello/content_view_module_stream_filter.rb +30 -3
  64. data/app/models/katello/content_view_package_filter.rb +1 -1
  65. data/app/models/katello/glue/pulp/repo.rb +1 -0
  66. data/app/models/katello/host/content_facet.rb +11 -5
  67. data/app/models/katello/module_stream.rb +1 -1
  68. data/app/models/katello/ping.rb +1 -3
  69. data/app/models/katello/repository.rb +16 -0
  70. data/app/models/setting/content.rb +3 -1
  71. data/app/presenters/katello/sync_status_presenter.rb +4 -2
  72. data/app/services/cert/certs.rb +10 -2
  73. data/app/services/katello/pulp/repository/yum.rb +2 -1
  74. data/app/services/katello/pulp3/api/core.rb +4 -0
  75. data/app/services/katello/pulp3/erratum.rb +3 -1
  76. data/app/services/katello/pulp3/migration.rb +9 -4
  77. data/app/services/katello/pulp3/migration_plan.rb +6 -6
  78. data/app/services/katello/pulp3/repository.rb +13 -5
  79. data/app/services/katello/pulp3/repository/yum.rb +246 -25
  80. data/app/services/katello/pulp3/repository_mirror.rb +7 -2
  81. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +1 -1
  82. data/app/services/katello/pulp3/task.rb +100 -0
  83. data/app/services/katello/pulp3/task_group.rb +79 -0
  84. data/app/services/katello/smart_proxy_helper.rb +13 -16
  85. data/app/views/katello/api/v2/content_view_filters/base.json.rabl +4 -0
  86. data/config/routes/api/rhsm.rb +1 -0
  87. data/config/routes/api/v2.rb +2 -0
  88. data/db/migrate/20200709021250_add_original_modules_to_content_view_module_stream_filter.rb +5 -0
  89. data/db/migrate/20200721142707_remove_duplicate_katello_pools_index.rb +5 -0
  90. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.routes.js +1 -13
  91. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/filter-details.controller.js +17 -4
  92. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/views/module-stream-filter-details.html +17 -0
  93. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/errata.routes.js +1 -1
  94. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/product-bulk-action.factory.js +1 -0
  95. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +6 -0
  96. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +7 -1
  97. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository.factory.js +1 -0
  98. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +15 -0
  99. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/views/products.html +6 -0
  100. data/engines/bastion_katello/app/assets/stylesheets/bastion_katello/bastion_katello.scss +4 -0
  101. data/lib/katello/engine.rb +0 -1
  102. data/lib/katello/permission_creator.rb +2 -2
  103. data/lib/katello/plugin.rb +2 -1
  104. data/lib/katello/tasks/reports.rake +16 -0
  105. data/lib/katello/version.rb +1 -1
  106. data/webpack/redux/actions/RedHatRepositories/helpers.js +6 -6
  107. metadata +37 -14
  108. data/app/lib/actions/katello/repository/update_cv_repo_cert_guard.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 590a33ff3016ad29aaeca6e8d5a0c967b9053a01cf3dbf8f28fcb68b63d056bd
4
- data.tar.gz: e8c30ca9e88f472f3aabf89b7f2cc3c6122750706e9bdfbb9d1cfa8aa957d4a5
3
+ metadata.gz: 961e7dd9a56b1752c55e19c1f29dc6b4e55366db3e87ab59610d7b89e8dea975
4
+ data.tar.gz: aa5c95aec6191209c2bc76988bc81b18984167176bf71eaa4186f517a06028f6
5
5
  SHA512:
6
- metadata.gz: 2fbba71f828db21edacf4100aac226a638fa7c6dd59871f6d0f029846af27ff54914c803798fd6054463ae4f44bbfc29d9466fca8a19867e63c10486668ce30c
7
- data.tar.gz: 17347500daf6bb1b2dd1ff7126b97e84f2120e1c12e23066036d2f30402cdb9018dc5c6cb1f74ceff441f069a2733dceb4e3a4958032237034eaff5783915b49
6
+ metadata.gz: a60d61a7d375ff622d7d4db78fd7c5da3d78f8421d45cb5204ce7b690b031515412e727e03c906d96fb3ba538c585819350c2671d103e6415ea51987481df037
7
+ data.tar.gz: b62c7366deacc4d5875488bff0913e11fa61cf0a4e7077391a459a78587d598b032ce815b45ade45d0e6e3e870e09e87ebef0ba60034d5166aa83cf8520f501e
@@ -6,8 +6,8 @@ module Katello
6
6
  before_action :confirm_push_settings, only: [:start_upload_blob, :upload_blob, :finish_upload_blob,
7
7
  :chunk_upload_blob, :push_manifest]
8
8
  skip_before_action :authorize
9
- before_action :optional_authorize, only: [:token]
10
- before_action :registry_authorize, except: [:token, :v1_search]
9
+ before_action :optional_authorize, only: [:token, :catalog]
10
+ before_action :registry_authorize, except: [:token, :v1_search, :catalog]
11
11
  before_action :authorize_repository_read, only: [:pull_manifest, :tags_list]
12
12
  before_action :authorize_repository_write, only: [:push_manifest]
13
13
  skip_before_action :check_content_type, only: [:start_upload_blob, :upload_blob, :finish_upload_blob,
@@ -39,20 +39,7 @@ module Katello
39
39
  "scope=\"repository:registry:pull,push\""
40
40
  end
41
41
 
42
- def optional_authorize
43
- @repository = find_scope_repository
44
- if @repository && (@repository.environment.registry_unauthenticated_pull || ssl_client_authorized?(@repository.organization.label))
45
- true
46
- else
47
- authorize
48
- end
49
- end
50
-
51
- def registry_authorize
52
- @repository = find_readable_repository
53
- return true if ['GET', 'HEAD'].include?(request.method) && @repository && !require_user_authorization?
54
-
55
- token = request.headers['Authorization']
42
+ def set_user_by_token(token, redirect_on_failure = true)
56
43
  if token
57
44
  token_type, token = token.split
58
45
  if token_type == 'Bearer' && token
@@ -63,10 +50,34 @@ module Katello
63
50
  end
64
51
  elsif token_type == 'Basic' && token
65
52
  return true if authorize
66
- redirect_authorization_headers
53
+ redirect_authorization_headers if redirect_on_failure
67
54
  return false
68
55
  end
69
56
  end
57
+ false
58
+ end
59
+
60
+ def optional_authorize
61
+ @repository = find_scope_repository
62
+ if @repository && (@repository.environment.registry_unauthenticated_pull || ssl_client_authorized?(@repository.organization.label))
63
+ true
64
+ elsif params['action'] == 'catalog'
65
+ set_user_by_token(request.headers['Authorization'], false)
66
+ elsif (params['action'] == 'token' && params['scope'].blank? && params['account'].blank?)
67
+ true
68
+ else
69
+ authorize
70
+ end
71
+ end
72
+
73
+ def registry_authorize
74
+ @repository = find_readable_repository
75
+ return true if ['GET', 'HEAD'].include?(request.method) && @repository && !require_user_authorization?
76
+
77
+ is_user_set = set_user_by_token(request.headers['Authorization'])
78
+
79
+ return true if is_user_set
80
+
70
81
  redirect_authorization_headers
71
82
  render_error('unauthorized', :status => :unauthorized)
72
83
  return false
@@ -87,12 +98,8 @@ module Katello
87
98
  # Also include repositories in lifecycle environments with registry_unauthenticated_pull=true
88
99
  def readable_repositories
89
100
  table_name = Repository.table_name
90
- in_products = Repository.in_product(Katello::Product.authorized(:view_products)).select(:id)
91
- in_environments = Repository.where(:environment_id => Katello::KTEnvironment.authorized(:view_lifecycle_environments)).select(:id)
92
101
  in_unauth_environments = Repository.joins(:environment).where("#{Katello::KTEnvironment.table_name}.registry_unauthenticated_pull" => true).select(:id)
93
- in_content_views = Repository.joins(:content_view_repositories).where("#{ContentViewRepository.table_name}.content_view_id" => Katello::ContentView.readable).select(:id)
94
- in_versions = Repository.joins(:content_view_version).where("#{Katello::ContentViewVersion.table_name}.content_view_id" => Katello::ContentView.readable).select(:id)
95
- Repository.where("#{table_name}.id in (?) or #{table_name}.id in (?) or #{table_name}.id in (?) or #{table_name}.id in (?) or #{table_name}.id in (?)", in_products, in_content_views, in_versions, in_environments, in_unauth_environments)
102
+ Repository.readable.or(Repository.joins(:root).where("#{table_name}.id in (?)", in_unauth_environments))
96
103
  end
97
104
 
98
105
  def find_readable_repository
@@ -105,7 +112,8 @@ module Katello
105
112
  end
106
113
 
107
114
  def require_user_authorization?(repository = @repository)
108
- !repository || (!repository.environment.registry_unauthenticated_pull && !ssl_client_authorized?(repository.organization.label))
115
+ !(params['action'] == 'token' && params['scope'].blank? && params['account'].blank?) &&
116
+ (!repository || (!repository.environment.registry_unauthenticated_pull && !ssl_client_authorized?(repository.organization.label)))
109
117
  end
110
118
 
111
119
  def ssl_client_authorized?(org_label)
@@ -293,6 +301,14 @@ module Katello
293
301
  end
294
302
 
295
303
  def v1_search
304
+ # Checks for podman client and issues a 404 in that case. Podman
305
+ # examines the response from a /v1_search request. If the result
306
+ # is a 4XX, it will then proceed with a request to /_catalog
307
+ if request.headers['HTTP_USER_AGENT'].downcase.include?('libpod')
308
+ render json: {}, status: :not_found
309
+ return
310
+ end
311
+
296
312
  authenticate # to set current_user, not to enforce
297
313
  options = {
298
314
  resource_class: Katello::Repository
@@ -268,8 +268,8 @@ module Katello
268
268
  end
269
269
 
270
270
  def get_parent_host(headers)
271
- hostnames = headers["HTTP_X_FORWARDED_SERVER"]
272
- host = hostnames.split(",")[0] if hostnames
271
+ hostnames = headers["HTTP_X_FORWARDED_HOST"]
272
+ host = hostnames.split(/[\,,:]/)[0].strip if hostnames
273
273
  host || URI.parse(Setting[:foreman_url]).host
274
274
  end
275
275
 
@@ -480,7 +480,7 @@ module Katello
480
480
  else
481
481
  User.consumer? || ::User.current.can?(:view_organizations, self)
482
482
  end
483
- when "rhsm_proxy_owner_servicelevels_path"
483
+ when "rhsm_proxy_owner_servicelevels_path", "rhsm_proxy_owner_system_purpose_path"
484
484
  (User.consumer? || ::User.current.can?(:view_organizations, self))
485
485
  when "rhsm_proxy_consumer_accessible_content_path", "rhsm_proxy_consumer_certificates_path",
486
486
  "rhsm_proxy_consumer_releases_path", "rhsm_proxy_certificate_serials_path",
@@ -5,6 +5,7 @@ module Katello
5
5
  include Api::V2::Rendering
6
6
  include Api::V2::ErrorHandling
7
7
  include ::Foreman::Controller::CsvResponder
8
+ include Concerns::Api::V2::AssociationsPermissionCheck
8
9
 
9
10
  # support for session (thread-local) variables must be the last filter in this class
10
11
  include Foreman::ThreadSession::Cleaner
@@ -37,6 +37,8 @@ module Katello
37
37
  param :type, String, :desc => N_("type of filter (e.g. rpm, package_group, erratum, docker, modulemd)"), :required => true
38
38
  param :original_packages, :bool, :desc => N_("add all packages without errata to the included/excluded list. " \
39
39
  "(package filter only)")
40
+ param :original_module_streams, :bool, :desc => N_("add all module streams without errata to the included/excluded list. " \
41
+ "(module stream filter only)")
40
42
  param :inclusion, :bool, :desc => N_("specifies if content should be included or excluded, default: inclusion=false")
41
43
  param :repository_ids, Array, :desc => N_("list of repository ids")
42
44
  param :description, String, :desc => N_("description of the filter")
@@ -60,6 +62,8 @@ module Katello
60
62
  param :name, String, :desc => N_("new name for the filter")
61
63
  param :original_packages, :bool, :desc => N_("add all packages without errata to the included/excluded list. " \
62
64
  "(package filter only)")
65
+ param :original_module_streams, :bool, :desc => N_("add all module streams without errata to the included/excluded list. " \
66
+ "(module stream filter only)")
63
67
  param :inclusion, :bool, :desc => N_("specifies if content should be included or excluded, default: inclusion=false")
64
68
  param :repository_ids, Array, :desc => N_("list of repository ids")
65
69
  param :description, String, :desc => N_("description of the filter"), :required => false
@@ -95,7 +99,7 @@ module Katello
95
99
  end
96
100
 
97
101
  def filter_params
98
- params.require(:content_view_filter).permit(:name, :inclusion, :original_packages, :description, :repository_ids => [])
102
+ params.require(:content_view_filter).permit(:name, :inclusion, :original_packages, :original_module_streams, :description, :repository_ids => [])
99
103
  end
100
104
  end
101
105
  end
@@ -143,6 +143,9 @@ module Katello
143
143
  end
144
144
  end
145
145
  def incremental_update
146
+ if params[:add_content].values.flatten.empty?
147
+ fail HttpErrors::BadRequest, _("Incremental update requires at least one content unit")
148
+ end
146
149
  any_environments = params[:content_view_version_environments].any? { |cvve| cvve[:environment_ids].try(:any?) }
147
150
  if params[:add_content]&.key?(:errata_ids) && params[:update_hosts] && any_environments
148
151
  hosts = calculate_hosts_for_incremental(params[:update_hosts], params[:propagate_to_composites])
@@ -22,6 +22,13 @@ module Katello
22
22
  param :solve_dependencies, :bool, :desc => N_("Solve RPM dependencies by default on Content View publish, defaults to false")
23
23
  end
24
24
 
25
+ def filtered_associations
26
+ {
27
+ :component_ids => Katello::ContentViewVersion,
28
+ :repository_ids => Katello::Repository
29
+ }
30
+ end
31
+
25
32
  api :GET, "/organizations/:organization_id/content_views", N_("List content views")
26
33
  api :GET, "/content_views", N_("List content views")
27
34
  param :organization_id, :number, :desc => N_("organization identifier")
@@ -2,11 +2,6 @@ module Katello
2
2
  class Api::V2::HostTracerController < Api::V2::ApiController
3
3
  before_action :find_host, :only => :index
4
4
 
5
- resource_description do
6
- api_version 'v2'
7
- api_base_url "/api"
8
- end
9
-
10
5
  api :GET, "/hosts/:host_id/traces", N_("List services that need restarting on the host")
11
6
  param :host_id, :number, :required => true, :desc => N_("ID of the host")
12
7
  def index
@@ -50,6 +50,21 @@ module Katello
50
50
  respond_for_async :resource => task
51
51
  end
52
52
 
53
+ api :PUT, "/products/bulk/verify_checksum", N_("Verify checksum for one or more products")
54
+ param :ids, Array, :desc => N_("List of product ids"), :required => true
55
+ def verify_checksum_products
56
+ repairable_products = @products.syncable
57
+ repairable_roots = RootRepository.where(:product_id => repairable_products).
58
+ where(:content_type => ::Katello::Repository::YUM_TYPE).has_url.select { |r| r.library_instance }.uniq
59
+
60
+ repairable_repositories = Katello::Repository.where(:root_id => repairable_roots)
61
+ task = async_task(::Actions::BulkAction,
62
+ ::Actions::Katello::Repository::VerifyChecksum,
63
+ repairable_repositories)
64
+
65
+ respond_for_async :resource => task
66
+ end
67
+
53
68
  api :PUT, "/products/bulk/http_proxy", N_("Update the HTTP proxy configuration on the repositories of one or more products.")
54
69
  param :ids, Array, :desc => N_("List of product ids"), :required => true
55
70
  param :http_proxy_policy, ::Katello::RootRepository::HTTP_PROXY_POLICIES, :desc => N_("policy for HTTP proxy for content sync")
@@ -15,7 +15,7 @@ module Katello
15
15
  before_action :find_organization_from_product, :only => [:create]
16
16
  before_action :find_repository, :only => [:show, :update, :destroy, :sync, :export,
17
17
  :remove_content, :upload_content, :republish,
18
- :import_uploads, :gpg_key_content]
18
+ :import_uploads, :gpg_key_content, :verify_checksum]
19
19
  before_action :find_content, :only => :remove_content
20
20
  before_action :find_organization_from_repo, :only => [:update]
21
21
  before_action :error_on_rh_product, :only => [:create]
@@ -294,6 +294,15 @@ module Katello
294
294
  raise HttpErrors::BadRequest, e.message
295
295
  end
296
296
 
297
+ api :POST, "/repositories/:id/verify_checksum", N_("Verify checksum of repository contents")
298
+ param :id, :number, :required => true, :desc => N_("repository ID")
299
+ def verify_checksum
300
+ task = async_task(::Actions::Katello::Repository::VerifyChecksum, @repository)
301
+ respond_for_async :resource => task
302
+ rescue Errors::InvalidActionOptionError => e
303
+ raise HttpErrors::BadRequest, e.message
304
+ end
305
+
297
306
  api :POST, "/repositories/:id/export", N_("Export a repository")
298
307
  param :id, :number, :desc => N_("Repository identifier"), :required => true
299
308
  param :export_to_iso, :bool, :desc => N_("Export to ISO format"), :required => false
@@ -0,0 +1,67 @@
1
+ module Katello
2
+ module Concerns
3
+ module Api::V2::AssociationsPermissionCheck
4
+ extend ActiveSupport::Concern
5
+
6
+ # The purpose of this module is to protect a controller from a user creating or updating some association
7
+ # when they do not have permissions to view the associated items. An example would be adding random repository ids to
8
+ # content view.
9
+ # To support this, within the controller define a method such as:
10
+ # def filtered_associations
11
+ # {
12
+ # :component_ids => Katello::ContentViewVersion,
13
+ # :repository_ids => Katello::Repository
14
+ # }
15
+ # end
16
+ # This assumes that the parameters are 'wrapped'. So the above in the content_views_controller, actually looks at
17
+ # a subhash of 'content_view'
18
+
19
+ included do
20
+ before_action :check_association_ids, :only => [:create, :update]
21
+ end
22
+
23
+ def check_association_ids
24
+ if filtered_associations
25
+ wrapped_params = params[self._wrapper_options.name]
26
+ find_param_arrays(wrapped_params).each do |key_path|
27
+ if (model_class = filtered_associations.with_indifferent_access.dig(*key_path))
28
+ param_ids = wrapped_params.dig(*key_path)
29
+ filtered_ids = model_class.readable.where(:id => param_ids).pluck(:id)
30
+ if (unfound_ids = param_ids_missing(param_ids, filtered_ids)).any?
31
+ fail HttpErrors::NotFound, _("One or more ids (%{ids}) were not found for %{assoc}. You may not have permissions to see them.") %
32
+ {ids: unfound_ids, assoc: key_path.last}
33
+ end
34
+ else
35
+ fail _("Unfiltered params array: %s.") % key_path
36
+ end
37
+ end
38
+ else
39
+ Rails.logger.warn("#{self.class.name} may has unprotected associations, see associations_permission_check.rb for details.") if ENV['RAILS_ENV'] == 'development'
40
+ end
41
+ end
42
+
43
+ def filtered_associations
44
+ #should return {} when supported by all controllers
45
+ nil
46
+ end
47
+
48
+ def param_ids_missing(param_ids, filtered_ids)
49
+ param_ids.map(&:to_i).uniq - filtered_ids.map(&:to_i).uniq
50
+ end
51
+
52
+ #returns an array of list of keys pointing to an array in a params hash i.e.:
53
+ # {"a"=> {"b" => [3]}} => [["a", "b"]]
54
+ def find_param_arrays(hash = params)
55
+ list_of_paths = []
56
+ hash.each do |key, value|
57
+ if value.is_a?(ActionController::Parameters) || value.is_a?(Hash)
58
+ list_of_paths += find_param_arrays(value).compact.map { |inner_keys| [key] + inner_keys }
59
+ elsif value.is_a?(Array)
60
+ list_of_paths << [key]
61
+ end
62
+ end
63
+ list_of_paths.compact
64
+ end
65
+ end
66
+ end
67
+ end
@@ -19,11 +19,17 @@ module Katello
19
19
  prepend Overrides
20
20
 
21
21
  def update_multiple_taxonomies(type)
22
- registered_host = @hosts.detect { |host| host.subscription_facet }
23
- unless registered_host.nil?
24
- error _("Unregister host %s before assigning an organization") % registered_host.name
25
- redirect_back_or_to hosts_path
26
- return
22
+ if type == :organization
23
+ new_org_id = params.dig(type, 'id')
24
+
25
+ if new_org_id
26
+ registered_host = @hosts.where.not(organization_id: new_org_id).joins(:subscription_facet).first
27
+ if registered_host
28
+ error _("Unregister host %s before assigning an organization") % registered_host.name
29
+ redirect_back_or_to hosts_path
30
+ return
31
+ end
32
+ end
27
33
  end
28
34
 
29
35
  super
@@ -0,0 +1,15 @@
1
+ module Katello
2
+ module ContentViewHelper
3
+ def separated_repo_mapping(repo_mapping)
4
+ separated_mapping = { :pulp3_yum => {}, :other => {} }
5
+ repo_mapping.each do |source_repos, dest_repo|
6
+ if dest_repo.content_type == "yum" && SmartProxy.pulp_master.pulp3_support?(dest_repo)
7
+ separated_mapping[:pulp3_yum][source_repos] = dest_repo
8
+ else
9
+ separated_mapping[:other][source_repos] = dest_repo
10
+ end
11
+ end
12
+ separated_mapping
13
+ end
14
+ end
15
+ end
@@ -10,6 +10,10 @@ module Actions
10
10
  fail NotImplementedError
11
11
  end
12
12
 
13
+ def rescue_strategy
14
+ Dynflow::Action::Rescue::Skip if self.state == 'error'
15
+ end
16
+
13
17
  def plan(smart_proxy, options = {})
14
18
  plan_self(:smart_proxy_id => smart_proxy.id,
15
19
  :environment_id => options[:environment]&.id,
@@ -33,7 +37,7 @@ module Actions
33
37
  current_repos_on_capsule = smart_proxy_service.current_repositories(environment, content_view)
34
38
  current_repos_on_capsule_ids = current_repos_on_capsule.pluck(:id)
35
39
 
36
- list_of_repos_to_sync = smart_proxy_helper.repos_available_to_capsule(environment, content_view, repository)
40
+ list_of_repos_to_sync = smart_proxy_helper.combined_repos_available_to_capsule(environment, content_view, repository)
37
41
  list_of_repos_to_sync.each do |repo|
38
42
  if repo.is_a?(Katello::ContentViewPuppetEnvironment)
39
43
  repo = repo.nonpersisted_repository
@@ -31,8 +31,8 @@ module Actions
31
31
  fail _("Action not allowed for the default smart proxy.") if smart_proxy.pulp_master?
32
32
 
33
33
  smart_proxy_helper = ::Katello::SmartProxyHelper.new(smart_proxy)
34
- repositories = smart_proxy_helper.repos_available_to_capsule(environment, content_view, repository)
35
- smart_proxy.ping_pulp3 if repositories.any? { |repo| smart_proxy.pulp3_support?(repo) }
34
+ repositories = smart_proxy_helper.combined_repos_available_to_capsule(environment, content_view, repository)
35
+
36
36
  smart_proxy.ping_pulp if repositories.any? { |repo| !smart_proxy.pulp3_support?(repo) }
37
37
 
38
38
  refresh_options = options.merge(content_view: content_view,
@@ -40,14 +40,11 @@ module Actions
40
40
  repository: repository)
41
41
  sequence do
42
42
  plan_action(Actions::Pulp::Orchestration::Repository::RefreshRepos, smart_proxy, refresh_options)
43
+ plan_action(Actions::Pulp3::CapsuleContent::RefreshContentGuard, smart_proxy) if repositories.any? { |repo| smart_proxy.pulp3_support?(repo) }
43
44
  plan_action(Actions::Pulp3::Orchestration::Repository::RefreshRepos, smart_proxy, refresh_options) if smart_proxy.pulp3_enabled?
44
45
  plan_action(SyncCapsule, smart_proxy, refresh_options)
45
46
  end
46
47
  end
47
-
48
- def rescue_strategy
49
- Dynflow::Action::Rescue::Skip
50
- end
51
48
  end
52
49
  end
53
50
  end
@@ -10,31 +10,45 @@ module Actions
10
10
  repository = options[:repository]
11
11
  skip_metadata_check = options.fetch(:skip_metadata_check, false)
12
12
 
13
- smart_proxy_helper = ::Katello::SmartProxyHelper.new(smart_proxy)
14
- concurrence do
15
- smart_proxy_helper.repos_available_to_capsule(environment, content_view, repository).each do |repo|
16
- plan_pulp_action([Actions::Pulp::Orchestration::Repository::SmartProxySync,
17
- Actions::Pulp3::CapsuleContent::Sync],
18
- repo, smart_proxy,
19
- skip_metadata_check: skip_metadata_check)
13
+ sequence do
14
+ repos = repos_to_sync(smart_proxy, environment, content_view, repository)
15
+
16
+ repos.in_groups_of(Setting[:foreman_proxy_content_batch_size], false) do |repo_batch|
17
+ concurrence do
18
+ repo_batch.each do |repo|
19
+ plan_pulp_action([Actions::Pulp::Orchestration::Repository::SmartProxySync,
20
+ Actions::Pulp3::CapsuleContent::Sync],
21
+ repo, smart_proxy,
22
+ skip_metadata_check: skip_metadata_check)
20
23
 
21
- if repo.is_a?(::Katello::Repository) &&
22
- repo.distribution_bootable? &&
23
- repo.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND
24
- plan_action(Katello::Repository::FetchPxeFiles,
25
- id: repo.id,
26
- capsule_id: smart_proxy.id)
24
+ if repo.is_a?(::Katello::Repository) &&
25
+ repo.distribution_bootable? &&
26
+ repo.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND
27
+ plan_action(Katello::Repository::FetchPxeFiles,
28
+ id: repo.id,
29
+ capsule_id: smart_proxy.id)
30
+ end
31
+ end
27
32
  end
28
33
  end
29
34
  end
30
35
  end
31
36
 
32
- def resource_locks
33
- :link
37
+ def repos_to_sync(smart_proxy, environment, content_view, repository)
38
+ smart_proxy_helper = ::Katello::SmartProxyHelper.new(smart_proxy)
39
+ smart_proxy_helper.lifecycle_environment_check(environment, repository)
40
+
41
+ if repository
42
+ [repository]
43
+ else
44
+ repositories = smart_proxy_helper.repositories_available_to_capsule(environment, content_view).by_rpm_count
45
+ puppet_envs = smart_proxy_helper.puppet_environments_available_to_capsule(environment, content_view)
46
+ repositories + puppet_envs
47
+ end
34
48
  end
35
49
 
36
- def rescue_strategy
37
- Dynflow::Action::Rescue::Skip
50
+ def resource_locks
51
+ :link
38
52
  end
39
53
  end
40
54
  end