katello 3.16.0.rc3.1 → 3.16.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 (120) 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 +2 -2
  4. data/app/controllers/katello/api/v2/api_controller.rb +9 -4
  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/subscriptions_controller.rb +1 -1
  9. data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +13 -1
  10. data/app/controllers/katello/concerns/api/v2/associations_permission_check.rb +67 -0
  11. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +11 -0
  12. data/app/helpers/katello/content_view_helper.rb +15 -0
  13. data/app/lib/actions/katello/capsule_content/refresh_repos.rb +4 -0
  14. data/app/lib/actions/katello/capsule_content/sync.rb +0 -4
  15. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +16 -16
  16. data/app/lib/actions/katello/content_view/incremental_updates.rb +8 -1
  17. data/app/lib/actions/katello/content_view/presenters/incremental_updates_presenter.rb +2 -1
  18. data/app/lib/actions/katello/content_view/publish.rb +55 -16
  19. data/app/lib/actions/katello/content_view_version/incremental_update.rb +120 -26
  20. data/app/lib/actions/katello/host/attach_subscriptions.rb +5 -1
  21. data/app/lib/actions/katello/repository/multi_clone_contents.rb +66 -0
  22. data/app/lib/actions/katello/repository/multi_clone_to_version.rb +30 -0
  23. data/app/lib/actions/katello/sync_plan/run.rb +1 -1
  24. data/app/lib/actions/pulp/abstract_async_task.rb +1 -0
  25. data/app/lib/actions/pulp/consumer/sync_capsule.rb +8 -0
  26. data/app/lib/actions/pulp/repository/presenters/deb_presenter.rb +2 -2
  27. data/app/lib/actions/pulp3/abstract_async_task.rb +62 -58
  28. data/app/lib/actions/pulp3/content_migration.rb +4 -0
  29. data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +1 -2
  30. data/app/lib/actions/pulp3/orchestration/repository/multi_copy_all_units.rb +36 -0
  31. data/app/lib/actions/pulp3/repository/multi_copy_content.rb +28 -0
  32. data/app/lib/actions/pulp3/repository/multi_copy_units.rb +55 -0
  33. data/app/lib/actions/pulp3/repository/presenters/content_unit_presenter.rb +1 -1
  34. data/app/lib/actions/pulp3/repository/save_version.rb +11 -3
  35. data/app/lib/actions/pulp3/repository/save_versions.rb +73 -0
  36. data/app/lib/katello/concerns/base_template_scope_extensions.rb +0 -14
  37. data/app/lib/katello/errors.rb +26 -15
  38. data/app/lib/katello/resources/candlepin.rb +1 -1
  39. data/app/lib/katello/resources/candlepin/upstream_consumer.rb +6 -0
  40. data/app/models/katello/concerns/host_managed_extensions.rb +7 -0
  41. data/app/models/katello/concerns/organization_extensions.rb +14 -0
  42. data/app/models/katello/content_view.rb +18 -6
  43. data/app/models/katello/content_view_erratum_filter.rb +13 -0
  44. data/app/models/katello/content_view_filter.rb +4 -0
  45. data/app/models/katello/content_view_module_stream_filter.rb +30 -3
  46. data/app/models/katello/glue/pulp/repo.rb +1 -0
  47. data/app/models/katello/host/content_facet.rb +10 -5
  48. data/app/models/katello/module_stream.rb +1 -1
  49. data/app/models/katello/pulp3/content_guard.rb +1 -1
  50. data/app/models/katello/repository.rb +11 -0
  51. data/app/models/setting/content.rb +3 -1
  52. data/app/presenters/katello/sync_status_presenter.rb +4 -2
  53. data/app/services/katello/candlepin/message_handler.rb +2 -3
  54. data/app/services/katello/pulp/repository/yum.rb +2 -1
  55. data/app/services/katello/pulp3/api/core.rb +4 -0
  56. data/app/services/katello/pulp3/erratum.rb +3 -1
  57. data/app/services/katello/pulp3/migration.rb +9 -4
  58. data/app/services/katello/pulp3/migration_plan.rb +6 -6
  59. data/app/services/katello/pulp3/repository.rb +17 -1
  60. data/app/services/katello/pulp3/repository/yum.rb +187 -25
  61. data/app/services/katello/pulp3/task.rb +100 -0
  62. data/app/services/katello/pulp3/task_group.rb +79 -0
  63. data/app/services/katello/ui_notifications/subscriptions/manifest_expired_warning.rb +20 -8
  64. data/app/services/katello/upstream_connection_checker.rb +48 -0
  65. data/app/views/katello/api/v2/content_view_filters/base.json.rabl +4 -0
  66. data/app/views/katello/api/v2/srpms/backend.json.rabl +11 -0
  67. data/app/views/katello/api/v2/srpms/base.json.rabl +5 -0
  68. data/app/views/katello/api/v2/srpms/compare.json.rabl +10 -0
  69. data/app/views/katello/api/v2/srpms/index.json.rabl +1 -1
  70. data/app/views/katello/api/v2/srpms/show.json.rabl +3 -3
  71. data/config/routes/api/v2.rb +2 -0
  72. data/db/migrate/20200709021250_add_original_modules_to_content_view_module_stream_filter.rb +5 -0
  73. data/db/migrate/20200721142707_remove_duplicate_katello_pools_index.rb +5 -0
  74. data/db/seeds.d/109-katello-notification-blueprints.rb +1 -1
  75. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.routes.js +1 -13
  76. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/filter-details.controller.js +17 -4
  77. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/views/module-stream-filter-details.html +17 -0
  78. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/errata.routes.js +1 -1
  79. data/engines/bastion_katello/app/assets/stylesheets/bastion_katello/bastion_katello.scss +4 -0
  80. data/lib/katello/engine.rb +0 -1
  81. data/lib/katello/permission_creator.rb +1 -1
  82. data/lib/katello/plugin.rb +2 -0
  83. data/lib/katello/tasks/reports.rake +16 -0
  84. data/lib/katello/version.rb +1 -1
  85. data/package.json +3 -3
  86. data/webpack/components/Content/ContentTable.js +2 -0
  87. data/webpack/components/Content/Details/ContentDetails.js +3 -0
  88. data/webpack/redux/actions/RedHatRepositories/helpers.js +5 -5
  89. data/webpack/scenes/AnsibleCollections/Details/AnsibleCollectionDetails.js +3 -0
  90. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +3 -0
  91. data/webpack/scenes/RedHatRepositories/RedHatRepositoriesPage.js +2 -0
  92. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepository.js +2 -0
  93. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository/RepositorySetRepository.js +2 -0
  94. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailAssociations.js +2 -0
  95. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProductContent.js +2 -0
  96. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProducts.js +2 -0
  97. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +2 -0
  98. data/webpack/scenes/Subscriptions/SubscriptionActions.js +8 -8
  99. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +3 -1
  100. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +15 -1
  101. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +54 -7
  102. data/webpack/scenes/Subscriptions/SubscriptionsSelectors.js +3 -0
  103. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsActions.js +15 -1
  104. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/{UpstreamSubscriptionsContstants.js → UpstreamSubscriptionsConstants.js} +3 -0
  105. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +2 -0
  106. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsReducer.js +1 -1
  107. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsReducer.test.js +1 -1
  108. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsActions.test.js +0 -13
  109. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +6 -1
  110. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +6 -4
  111. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsReducer.test.js.snap +26 -25
  112. data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +0 -58
  113. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js +10 -4
  114. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +1 -0
  115. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +1 -68
  116. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Dialogs/UpdateDialog.js +1 -1
  117. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Dialogs/index.js +4 -4
  118. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Table.js +12 -10
  119. data/webpack/scenes/Subscriptions/index.js +6 -3
  120. metadata +44 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c111ad081f2588aaf6e770186fc98a2945887a06e465cdce62cc7fc20d56205
4
- data.tar.gz: bb1a4f8f3872e632bf36deb2db63a92753f5f4eaab3cea97bb47d5809d24e9ec
3
+ metadata.gz: 3c1b5ae508e6d13abb97dd4fa5dcb3a869b5a8ee2f6a2a2e574bcde16faa1c41
4
+ data.tar.gz: e5dc1c88a336020bf333e9f781eac5790b588139bd8d813433bea739ee7077ca
5
5
  SHA512:
6
- metadata.gz: 30b8f98b25c3a1f04d8796a9e060868e306f802dc50fc140f8d528eec3afe4c2c564d8f20858edb753c9ba75a6c3e56d26636c2b8bdbb5e6363e07d2af1d81a6
7
- data.tar.gz: af95e39c10ea7d9ed8805db3dc18be1a58e90a2e24d18fbf9e99ff1eb710abb657737b6a5094c693a2cee42f2bcdc798a9de6395e250645059f3134c89d913c7
6
+ metadata.gz: c6e0279e68e389701bcf84815bd401fe64375259da0ff533e4ae53fbf51f99b93837be754c0fb8d2d0457e6a8d299e4527c26d5c51fb4e81870f78592bbd46bf
7
+ data.tar.gz: 2296caf477bbb72d78f187e53a493b9e4c8657119424939063a8a6c6c40435d5e9bda70490351101207694cf9511a59de939397c53c623f11a2f30eba564ff91
@@ -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
 
@@ -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
@@ -211,10 +212,14 @@ module Katello
211
212
  fail HttpErrors::BadRequest, _("Host has not been registered with subscription-manager") if @host.subscription_facet.nil?
212
213
  end
213
214
 
214
- def check_disconnected
215
- msg = "You are currently operating in disconnected mode where access to Red Hat Subcription Management " \
216
- "is prohibited. If you would like to change this, please update the content setting 'Disconnected mode'."
217
- fail HttpErrors::BadRequest, _(msg) if Setting[:content_disconnected]
215
+ def check_upstream_connection
216
+ checker = Katello::UpstreamConnectionChecker.new(@organization)
217
+
218
+ begin
219
+ checker.assert_connection
220
+ rescue => e
221
+ raise HttpErrors::BadRequest, e.message
222
+ end
218
223
  end
219
224
  end
220
225
  end
@@ -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")
@@ -7,7 +7,7 @@ module Katello
7
7
  before_action :find_optional_organization, :only => [:index, :available, :show]
8
8
  before_action :find_organization, :only => [:upload, :delete_manifest,
9
9
  :refresh_manifest, :manifest_history]
10
- before_action :check_disconnected, only: [:refresh_manifest]
10
+ before_action :check_upstream_connection, only: [:refresh_manifest]
11
11
  before_action :find_provider
12
12
 
13
13
  skip_before_action :check_content_type, :only => [:upload]
@@ -1,6 +1,7 @@
1
1
  module Katello
2
2
  class Api::V2::UpstreamSubscriptionsController < Api::V2::ApiController
3
- before_action :check_disconnected
3
+ before_action :find_organization
4
+ before_action :check_upstream_connection
4
5
 
5
6
  resource_description do
6
7
  description "Red Hat subscriptions management platform."
@@ -65,6 +66,17 @@ module Katello
65
66
  respond_for_async resource: task
66
67
  end
67
68
 
69
+ api :GET, "/organizations/:organization_id/upstream_subscriptions/ping",
70
+ N_("Check if a connection can be made to Red Hat Subscription Management.")
71
+ def ping
72
+ # This API raises an error if:
73
+ # - Katello is in disconnected mode
74
+ # - There is no manifest imported
75
+ # - The local manifest identity certs have expired
76
+ # - The manifest has been deleted upstream
77
+ render json: { status: 'OK' }
78
+ end
79
+
68
80
  private
69
81
 
70
82
  def update_params
@@ -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
@@ -18,6 +18,17 @@ module Katello
18
18
  included do
19
19
  prepend Overrides
20
20
 
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
27
+ end
28
+
29
+ super
30
+ end
31
+
21
32
  def destroy
22
33
  if Katello::RegistrationManager.unregister_host(@host, :unregistering => false)
23
34
  process_success redirection_url_on_host_deletion
@@ -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,
@@ -44,10 +44,6 @@ module Actions
44
44
  plan_action(SyncCapsule, smart_proxy, refresh_options)
45
45
  end
46
46
  end
47
-
48
- def rescue_strategy
49
- Dynflow::Action::Rescue::Skip
50
- end
51
47
  end
52
48
  end
53
49
  end
@@ -11,19 +11,23 @@ module Actions
11
11
  skip_metadata_check = options.fetch(:skip_metadata_check, false)
12
12
 
13
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)
14
+ sequence do
15
+ smart_proxy_helper.repos_available_to_capsule(environment, content_view, repository).in_groups_of(Setting[:foreman_proxy_content_batch_size], false) do |repos|
16
+ concurrence do
17
+ repos.each do |repo|
18
+ plan_pulp_action([Actions::Pulp::Orchestration::Repository::SmartProxySync,
19
+ Actions::Pulp3::CapsuleContent::Sync],
20
+ repo, smart_proxy,
21
+ skip_metadata_check: skip_metadata_check)
20
22
 
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)
23
+ if repo.is_a?(::Katello::Repository) &&
24
+ repo.distribution_bootable? &&
25
+ repo.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND
26
+ plan_action(Katello::Repository::FetchPxeFiles,
27
+ id: repo.id,
28
+ capsule_id: smart_proxy.id)
29
+ end
30
+ end
27
31
  end
28
32
  end
29
33
  end
@@ -32,10 +36,6 @@ module Actions
32
36
  def resource_locks
33
37
  :link
34
38
  end
35
-
36
- def rescue_strategy
37
- Dynflow::Action::Rescue::Skip
38
- end
39
39
  end
40
40
  end
41
41
  end
@@ -52,7 +52,9 @@ module Actions
52
52
  action = plan_action(ContentViewVersion::IncrementalUpdate, composite_version, environments,
53
53
  :new_components => new_components, :description => description,
54
54
  :content => {:puppet_module_ids => puppet_module_ids})
55
- output_for_version_ids << {:version_id => action.new_content_view_version.id, :output => action.output}
55
+ unless SmartProxy.pulp_master.pulp3_repository_type_support?("yum")
56
+ output_for_version_ids << {:version_id => action.new_content_view_version.id, :output => action.output}
57
+ end
56
58
  end
57
59
  end
58
60
  end
@@ -80,6 +82,7 @@ module Actions
80
82
  added_units = version_output.try(:[], :output).try(:[], :added_units)
81
83
  if added_units
82
84
  total_count[:errata_count] = added_units[:erratum].try(:count)
85
+ total_count[:modulemd_count] = added_units[:modulemd].try(:count)
83
86
  total_count[:rpm_count] = added_units[:rpm].try(:count)
84
87
  total_count[:puppet_module_count] = added_units[:puppet_module].try(:count)
85
88
  end
@@ -117,6 +120,10 @@ module Actions
117
120
  errata = _(" %{errata_count} Errata" % {:errata_count => total_count[:errata_count]})
118
121
  content << errata
119
122
  end
123
+ if total_count[:modulemd_count] && total_count[:modulemd_count] > 0
124
+ modulemd = _(" %{modulemd_count} Module Stream(s)" % {:modulemd_count => total_count[:modulemd_count]})
125
+ content << modulemd
126
+ end
120
127
  if total_count[:rpm_count] && total_count[:rpm_count] > 0
121
128
  rpm = _(" %{package_count} Package(s)" % {:package_count => total_count[:rpm_count]})
122
129
  content << rpm