katello 3.17.3 → 3.18.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +38 -21
  3. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +3 -1
  4. data/app/controllers/katello/api/v2/activation_keys_controller.rb +10 -15
  5. data/app/controllers/katello/api/v2/api_controller.rb +2 -1
  6. data/app/controllers/katello/api/v2/content_credentials_controller.rb +1 -8
  7. data/app/controllers/katello/api/v2/content_view_components_controller.rb +31 -14
  8. data/app/controllers/katello/api/v2/content_view_repositories_controller.rb +1 -0
  9. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +65 -36
  10. data/app/controllers/katello/api/v2/content_views_controller.rb +27 -25
  11. data/app/controllers/katello/api/v2/environments_controller.rb +8 -8
  12. data/app/controllers/katello/api/v2/gpg_keys_controller.rb +5 -5
  13. data/app/controllers/katello/api/v2/host_collections_controller.rb +19 -16
  14. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +17 -0
  15. data/app/controllers/katello/api/v2/repositories_bulk_actions_controller.rb +1 -1
  16. data/app/controllers/katello/api/v2/repositories_controller.rb +8 -5
  17. data/app/controllers/katello/api/v2/subscriptions_controller.rb +1 -1
  18. data/app/controllers/katello/api/v2/sync_plans_controller.rb +8 -9
  19. data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +9 -2
  20. data/app/controllers/katello/concerns/api/v2/authorization.rb +9 -5
  21. data/app/controllers/katello/concerns/api/v2/registration_controller_extensions.rb +21 -0
  22. data/app/controllers/katello/concerns/api/v2/repository_content_controller.rb +1 -1
  23. data/app/controllers/katello/concerns/organizations_controller_extensions.rb +2 -1
  24. data/app/helpers/katello/katello_urls_helper.rb +5 -2
  25. data/app/lib/actions/candlepin/product/content_create.rb +2 -0
  26. data/app/lib/actions/candlepin/product/content_update.rb +2 -0
  27. data/app/lib/actions/katello/applicability/hosts/bulk_generate.rb +2 -6
  28. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +2 -6
  29. data/app/lib/actions/katello/content_view/publish.rb +3 -4
  30. data/app/lib/actions/katello/content_view_version/import.rb +4 -3
  31. data/app/lib/actions/katello/content_view_version/incremental_update.rb +18 -3
  32. data/app/lib/actions/katello/host/update_system_purpose.rb +31 -0
  33. data/app/lib/actions/katello/organization/manifest_delete.rb +0 -1
  34. data/app/lib/actions/katello/organization/manifest_import.rb +0 -1
  35. data/app/lib/actions/katello/organization/manifest_refresh.rb +0 -1
  36. data/app/lib/actions/katello/product/content_create.rb +7 -6
  37. data/app/lib/actions/katello/repository/filtered_index_content.rb +10 -1
  38. data/app/lib/actions/katello/repository/import_upload.rb +2 -1
  39. data/app/lib/actions/katello/repository/update.rb +4 -1
  40. data/app/lib/actions/pulp3/abstract_async_task.rb +0 -1
  41. data/app/lib/actions/pulp3/content_view/delete_repository_references.rb +1 -1
  42. data/app/lib/actions/pulp3/content_view_version/create_importer.rb +7 -3
  43. data/app/lib/actions/pulp3/content_view_version/export.rb +2 -1
  44. data/app/lib/actions/pulp3/content_view_version/import.rb +7 -3
  45. data/app/lib/actions/pulp3/orchestration/content_view_version/export.rb +15 -10
  46. data/app/lib/actions/pulp3/orchestration/content_view_version/import.rb +16 -10
  47. data/app/lib/actions/pulp3/repository/commit_upload.rb +2 -1
  48. data/app/lib/actions/pulp3/repository/delete.rb +1 -1
  49. data/app/lib/actions/pulp3/repository/save_artifact.rb +1 -1
  50. data/app/lib/katello/resources/candlepin/consumer.rb +2 -2
  51. data/app/lib/katello/resources/candlepin/owner.rb +5 -0
  52. data/app/lib/katello/resources/candlepin/upstream_consumer.rb +6 -0
  53. data/app/lib/katello/resources/registry.rb +3 -3
  54. data/app/models/katello/authorization/activation_key.rb +4 -0
  55. data/app/models/katello/authorization/content_view.rb +13 -0
  56. data/app/models/katello/authorization/content_view_component.rb +15 -0
  57. data/app/models/katello/authorization/gpg_key.rb +12 -4
  58. data/app/models/katello/authorization/lifecycle_environment.rb +8 -0
  59. data/app/models/katello/authorization/sync_plan.rb +16 -0
  60. data/app/models/katello/concerns/organization_extensions.rb +4 -5
  61. data/app/models/katello/concerns/redhat_extensions.rb +2 -2
  62. data/app/models/katello/concerns/smart_proxy_extensions.rb +1 -3
  63. data/app/models/katello/content_view_component.rb +2 -0
  64. data/app/models/katello/content_view_version_export_history.rb +2 -0
  65. data/app/models/katello/glue/candlepin/pool.rb +9 -14
  66. data/app/models/katello/glue/pulp/repo.rb +8 -0
  67. data/app/models/katello/gpg_key.rb +1 -1
  68. data/app/models/katello/root_repository.rb +26 -1
  69. data/app/services/katello/applicability/applicable_content_helper.rb +1 -12
  70. data/app/services/katello/candlepin/event_handler.rb +2 -0
  71. data/app/services/katello/candlepin/message_handler.rb +34 -0
  72. data/app/services/katello/candlepin/upstream_consumer.rb +28 -0
  73. data/app/services/katello/host_status_manager.rb +9 -0
  74. data/app/services/katello/pulp3/api/apt.rb +57 -0
  75. data/app/services/katello/pulp3/api/core.rb +8 -0
  76. data/app/services/katello/pulp3/content_view_version/export.rb +4 -3
  77. data/app/services/katello/pulp3/content_view_version/import.rb +5 -15
  78. data/app/services/katello/pulp3/deb.rb +38 -0
  79. data/app/services/katello/pulp3/erratum.rb +1 -2
  80. data/app/services/katello/pulp3/pulp_content_unit.rb +5 -0
  81. data/app/services/katello/pulp3/repository/ansible_collection.rb +9 -0
  82. data/app/services/katello/pulp3/repository/apt.rb +63 -0
  83. data/app/services/katello/pulp3/repository/docker.rb +4 -0
  84. data/app/services/katello/pulp3/repository/yum.rb +2 -1
  85. data/app/services/katello/pulp3/repository.rb +11 -9
  86. data/app/services/katello/pulp3/repository_mirror.rb +9 -4
  87. data/app/services/katello/pulp3/task.rb +3 -3
  88. data/app/services/katello/pulp3/task_group.rb +0 -6
  89. data/app/views/dashboard/_subscription_widget.html.erb +0 -5
  90. data/app/views/katello/api/v2/content_view_version_export_histories/show.json.rabl +1 -1
  91. data/app/views/katello/api/v2/repositories/base.json.rabl +1 -1
  92. data/app/views/overrides/organizations/_index_row_override.html.erb +1 -1
  93. data/config/routes/api/v2.rb +2 -0
  94. data/config/routes/overrides.rb +1 -0
  95. data/db/migrate/20150930183738_migrate_content_hosts.rb +1 -1
  96. data/db/migrate/20200514092553_move_katello_fields_from_hostgroups.katello.rb +2 -5
  97. data/db/migrate/20201008204114_add_os_versions_to_katello_root_repositories.rb +5 -0
  98. data/db/migrate/20201012172713_remove_gpg_key_perms.rb +23 -0
  99. data/db/migrate/20201012192035_add_metadata_to_katello_content_view_version_export_history.rb +5 -0
  100. data/db/seeds.d/111-upgrade_tasks.rb +2 -1
  101. data/engines/bastion/app/assets/javascripts/bastion/components/notification.service.js +1 -1
  102. data/engines/bastion/app/assets/javascripts/bastion/components/nutupane.factory.js +8 -13
  103. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/katello-agent-notice.html +1 -1
  104. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-system-purpose-modal.controller.js +112 -0
  105. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-system-purpose-modal.html +78 -0
  106. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-debs-installed.controller.js +2 -42
  107. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-host-modal-helper.service.js +11 -0
  108. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +5 -0
  109. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +4 -0
  110. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/register-client.html +1 -1
  111. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-details.controller.js +4 -0
  112. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/views/host-collection-info.html +6 -0
  113. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-bulk-action.factory.js +2 -1
  114. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +16 -14
  115. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/products-bulk-advanced-sync-modal.controller.js +6 -7
  116. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +168 -155
  117. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +17 -2
  118. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +125 -113
  119. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +15 -3
  120. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/os-versions.service.js +46 -0
  121. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/content-access-mode-banner.html +1 -1
  122. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/views/sync-plan-details.html +1 -1
  123. data/lib/katello/engine.rb +1 -0
  124. data/lib/katello/permission_creator.rb +68 -59
  125. data/lib/katello/permissions/host_permissions.rb +1 -0
  126. data/lib/katello/plugin.rb +4 -1
  127. data/lib/katello/repository_types/deb.rb +9 -1
  128. data/lib/katello/tasks/pulp3_content_switchover.rake +1 -3
  129. data/lib/katello/tasks/pulp3_migration_stats.rake +21 -0
  130. data/lib/katello/tasks/reports.rake +1 -4
  131. data/lib/katello/tasks/reset.rake +2 -1
  132. data/lib/katello/tasks/upgrades/3.18/add_cvv_export_history_metadata.rb +18 -0
  133. data/lib/katello/version.rb +1 -1
  134. data/locale/action_names.rb +54 -47
  135. data/locale/bn/katello.po +165 -26
  136. data/locale/cs/katello.po +164 -24
  137. data/locale/de/katello.po +165 -26
  138. data/locale/en/katello.po +164 -23
  139. data/locale/es/katello.po +165 -25
  140. data/locale/fr/katello.po +165 -25
  141. data/locale/gu/katello.po +165 -26
  142. data/locale/hi/katello.po +165 -26
  143. data/locale/it/katello.po +165 -25
  144. data/locale/ja/katello.po +165 -26
  145. data/locale/katello.pot +1036 -802
  146. data/locale/kn/katello.po +165 -26
  147. data/locale/ko/katello.po +165 -25
  148. data/locale/mr/katello.po +165 -26
  149. data/locale/or/katello.po +165 -26
  150. data/locale/pa/katello.po +165 -26
  151. data/locale/pt/katello.po +164 -23
  152. data/locale/pt_BR/katello.po +165 -25
  153. data/locale/ru/katello.po +165 -25
  154. data/locale/ta/katello.po +165 -26
  155. data/locale/te/katello.po +165 -26
  156. data/locale/zh_CN/katello.po +165 -25
  157. data/locale/zh_TW/katello.po +165 -26
  158. data/webpack/components/ActionableDetail.js +2 -1
  159. data/webpack/components/Search/Search.js +1 -1
  160. data/webpack/components/Table/MainTable.js +6 -2
  161. data/webpack/components/Table/TableWrapper.js +46 -9
  162. data/webpack/scenes/ContentViews/ContentViewSelectors.js +7 -3
  163. data/webpack/scenes/ContentViews/ContentViewsConstants.js +8 -0
  164. data/webpack/scenes/ContentViews/ContentViewsPage.js +2 -9
  165. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +25 -3
  166. data/webpack/scenes/ContentViews/Details/ContentViewDetailSelectors.js +14 -4
  167. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +2 -1
  168. data/webpack/scenes/ContentViews/Details/Repositories/ContentCounts.js +56 -0
  169. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +169 -0
  170. data/webpack/scenes/ContentViews/Details/Repositories/LastSync.js +47 -0
  171. data/webpack/scenes/ContentViews/Details/Repositories/RepoAddedStatus.js +17 -0
  172. data/webpack/scenes/ContentViews/Details/Repositories/RepoIcon.js +23 -0
  173. data/webpack/scenes/ContentViews/Details/Repositories/SelectableDropdown.js +49 -0
  174. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewDetailRepos.fixtures.json +154 -0
  175. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewDetailRepos.test.js +131 -0
  176. data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetail.test.js +3 -0
  177. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +4 -1
  178. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +2 -2
  179. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +16 -8
  180. data/webpack/scenes/Subscriptions/Manifest/ManifestActions.js +17 -0
  181. data/webpack/scenes/Subscriptions/Manifest/ManifestConstants.js +4 -0
  182. data/webpack/scenes/Subscriptions/Manifest/SimpleContentAccess.js +19 -2
  183. data/webpack/scenes/Subscriptions/Manifest/__tests__/SimpleContentAccess.test.js +9 -1
  184. data/webpack/scenes/Subscriptions/Manifest/index.js +2 -1
  185. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +1 -1
  186. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +3 -0
  187. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +8 -2
  188. data/webpack/scenes/Subscriptions/SubscriptionsSelectors.js +3 -0
  189. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +3 -0
  190. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsSelectors.test.js +6 -0
  191. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsSelectors.test.js.snap +6 -0
  192. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +1 -13
  193. metadata +69 -26
@@ -37,7 +37,7 @@ module Katello
37
37
  before_action :find_organization, :only => [:create, :paths, :auto_complete_search]
38
38
  before_action :find_optional_organization, :only => [:index, :show, :update, :destroy]
39
39
  before_action :find_prior, :only => [:create]
40
- before_action :find_environment, :only => [:show, :update, :destroy, :repositories]
40
+ before_action :find_authorized_katello_resource, :only => [:show, :update, :destroy, :repositories]
41
41
  before_action :find_content_view, :only => [:repositories]
42
42
  before_action :find_path, :only => [:create]
43
43
 
@@ -154,16 +154,16 @@ module Katello
154
154
  respond_for_index(:collection => collection, :template => :paths)
155
155
  end
156
156
 
157
- protected
157
+ def resource_name
158
+ 'environment'
159
+ end
158
160
 
159
- def find_environment
160
- identifier = params.require(:id) || params.require(:environment).require(:id)
161
- @environment = KTEnvironment.find(identifier)
162
- fail HttpErrors::NotFound, _("Couldn't find environment '%s'") % identifier.to_s if @environment.nil?
163
- @organization = @environment.organization
164
- @environment
161
+ def resource_class
162
+ Katello::KTEnvironment
165
163
  end
166
164
 
165
+ protected
166
+
167
167
  def find_prior
168
168
  prior = params[:environment][:prior] || params.require(:environment).require(:prior_id)
169
169
  @prior = KTEnvironment.readable.find(prior)
@@ -52,13 +52,13 @@ module Katello
52
52
  respond_for_create(:resource => gpg_key)
53
53
  end
54
54
 
55
- api :GET, "/gpg_keys/:id", N_("Show a gpg key")
55
+ api :GET, "/gpg_keys/:id", N_("Show a gpg key"), :deprecated => true
56
56
  param :id, :number, :desc => N_("gpg key numeric identifier"), :required => true
57
57
  def show
58
58
  respond_for_show(:resource => @gpg_key)
59
59
  end
60
60
 
61
- api :PUT, "/gpg_keys/:id", N_("Update a repository")
61
+ api :PUT, "/gpg_keys/:id", N_("Update a repository"), :deprecated => true
62
62
  param :id, :number, :desc => N_("gpg key numeric identifier"), :required => true
63
63
  param_group :gpg_key
64
64
  def update
@@ -67,20 +67,20 @@ module Katello
67
67
  respond_for_show(:resource => @gpg_key)
68
68
  end
69
69
 
70
- api :DELETE, "/gpg_keys/:id", N_("Destroy a gpg key")
70
+ api :DELETE, "/gpg_keys/:id", N_("Destroy a gpg key"), :deprecated => true
71
71
  param :id, :number, :desc => N_("gpg key numeric identifier"), :required => true
72
72
  def destroy
73
73
  @gpg_key.destroy
74
74
  respond_for_destroy
75
75
  end
76
76
 
77
- api :GET, "/gpg_keys/:id/content", N_("Return the content of a gpg key, used directly by yum")
77
+ api :GET, "/gpg_keys/:id/content", N_("Return the content of a gpg key, used directly by yum"), :deprecated => true
78
78
  param :id, :number, :required => true
79
79
  def content
80
80
  render(:plain => @gpg_key.content, :layout => false)
81
81
  end
82
82
 
83
- api :POST, "/gpg_keys/:id/content", N_("Upload gpg key contents")
83
+ api :POST, "/gpg_keys/:id/content", N_("Upload gpg key contents"), :deprecated => true
84
84
  param :id, :number, :desc => N_("gpg key numeric identifier"), :required => true
85
85
  param :content, File, :desc => N_("file contents"), :required => true
86
86
  def set_content
@@ -1,10 +1,17 @@
1
1
  module Katello
2
2
  class Api::V2::HostCollectionsController < Api::V2::ApiController
3
3
  include Katello::Concerns::FilteredAutoCompleteSearch
4
- before_action :find_host_collection, :only => [:copy, :show, :update, :destroy,
5
- :add_hosts, :remove_hosts, :hosts]
6
- before_action :find_activation_key
7
- before_action :find_host
4
+ before_action :find_authorized_katello_resource, :only => [
5
+ :copy,
6
+ :show,
7
+ :update,
8
+ :destroy,
9
+ :add_hosts,
10
+ :remove_hosts,
11
+ :hosts
12
+ ]
13
+ before_action :find_readable_activation_key, :only => [:index]
14
+ before_action :find_editable_host, :only => [:index]
8
15
  before_action :find_optional_organization, :only => [:index]
9
16
  before_action :find_organization, :only => [:create, :auto_complete_search]
10
17
 
@@ -175,14 +182,6 @@ module Katello
175
182
 
176
183
  private
177
184
 
178
- def find_host_collection
179
- @organization = @host.organization if @host
180
- @organization = @activation_key.organization if @activation_key
181
- id = params[:host_collection_id] || params[:id]
182
- @host_collection = HostCollection.where(:id => id).first
183
- fail HttpErrors::NotFound, _("Couldn't find host collection '%s'") % id if @host_collection.nil?
184
- end
185
-
186
185
  def host_collection_params
187
186
  attrs = [:name,
188
187
  :description,
@@ -199,14 +198,18 @@ module Katello
199
198
  result
200
199
  end
201
200
 
202
- def find_host
201
+ def find_editable_host
203
202
  @host = resource_finder(::Host::Managed.authorized("edit_hosts"), params[:host_id]) if params[:host_id]
204
203
  @organization = @host.organization if @host
205
204
  end
206
205
 
207
- def find_activation_key
208
- @activation_key = ActivationKey.find_by!(:id => params[:activation_key_id]) if params[:activation_key_id]
209
- @organization = @activation_key.organization if @activation_key
206
+ def find_readable_activation_key
207
+ @activation_key = ActivationKey.readable.find_by(:id => params[:activation_key_id]) if params[:activation_key_id]
208
+ if params[:activation_key_id] && @activation_key.nil?
209
+ throw_resource_not_found(name: 'activation_key', id: params[:activation_key_id])
210
+ else
211
+ @organization = @activation_key&.organization
212
+ end
210
213
  end
211
214
  end
212
215
  end
@@ -247,6 +247,23 @@ module Katello
247
247
  render json: result
248
248
  end
249
249
 
250
+ api :PUT, "/hosts/bulk/system_purpose", N_("Assign system purpose attributes on one or more hosts")
251
+ param_group :bulk_params
252
+ param :service_level, String, :desc => N_("Service level of host")
253
+ param :purpose_role, String, :desc => N_("Role of host")
254
+ param :purpose_usage, String, :desc => N_("Usage of host")
255
+ param :purpose_addons, Array, :desc => N_("Sets the system add-ons")
256
+ def system_purpose
257
+ task = async_task(::Actions::BulkAction, ::Actions::Katello::Host::UpdateSystemPurpose,
258
+ @hosts,
259
+ params[:service_level],
260
+ params[:purpose_role],
261
+ params[:purpose_usage],
262
+ params[:purpose_addons])
263
+
264
+ respond_for_async :resource => task
265
+ end
266
+
250
267
  api :POST, "/hosts/bulk/available_incremental_updates", N_("Given a set of hosts and errata, lists the content view versions" \
251
268
  " and environments that need updating.")
252
269
  param_group :bulk_params
@@ -62,7 +62,7 @@ module Katello
62
62
 
63
63
  def find_repositories
64
64
  params.require(:ids)
65
- @repositories = Repository.where(:id => params[:ids])
65
+ @repositories = Repository.readable.where(:id => params[:ids])
66
66
  end
67
67
  end
68
68
  end
@@ -35,6 +35,8 @@ module Katello
35
35
 
36
36
  def_param_group :repo do
37
37
  param :url, String, :desc => N_("repository source url")
38
+ param :os_versions, Array,
39
+ :desc => N_("Identifies whether the repository should be disabled on a client with a non-matching OS version. Pass [] to enable regardless of OS version. Maximum length 1; allowed tags are: %s") % Katello::RootRepository::ALLOWED_OS_VERSIONS.join(', ')
38
40
  param :gpg_key_id, :number, :desc => N_("id of the gpg key that will be assigned to the new repository")
39
41
  param :ssl_ca_cert_id, :number, :desc => N_("Identifier of the content credential containing the SSL CA Cert")
40
42
  param :ssl_client_cert_id, :number, :desc => N_("Identifier of the content credential containing the SSL Client Cert")
@@ -42,7 +44,7 @@ module Katello
42
44
  param :unprotected, :bool, :desc => N_("true if this repository can be published via HTTP")
43
45
  param :checksum_type, String, :desc => N_("Checksum of the repository, currently 'sha1' & 'sha256' are supported")
44
46
  param :docker_upstream_name, String, :desc => N_("Name of the upstream docker repository")
45
- param :docker_tags_whitelist, Array, :desc => N_("Comma separated list of tags to sync for Container Image repository")
47
+ param :docker_tags_whitelist, Array, :desc => N_("Comma-separated list of tags to sync for Container Image repository")
46
48
  param :download_policy, ["immediate", "on_demand", "background"], :desc => N_("download policy for yum repos (either 'immediate', 'on_demand', or 'background (deprecated)')")
47
49
  param :download_concurrency, :number, :desc => N_("Used to determine download concurrency of the repository in pulp3. Use value less than 20. Defaults to 10")
48
50
  param :mirror_on_sync, :bool, :desc => N_("true if this repository when synced has to be mirrored from the source and stale rpms removed")
@@ -51,9 +53,9 @@ module Katello
51
53
  param :upstream_password, String, :desc => N_("Password of the upstream repository user used for authentication")
52
54
  param :ostree_upstream_sync_policy, ::Katello::RootRepository::OSTREE_UPSTREAM_SYNC_POLICIES, :desc => N_("policies for syncing upstream ostree repositories")
53
55
  param :ostree_upstream_sync_depth, :number, :desc => N_("if a custom sync policy is chosen for ostree repositories then a 'depth' value must be provided")
54
- param :deb_releases, String, :desc => N_("comma separated list of releases to be synched from deb-archive")
55
- param :deb_components, String, :desc => N_("comma separated list of repo components to be synched from deb-archive")
56
- param :deb_architectures, String, :desc => N_("comma separated list of architectures to be synched from deb-archive")
56
+ param :deb_releases, String, :desc => N_("comma-separated list of releases to be synced from deb-archive")
57
+ param :deb_components, String, :desc => N_("comma-separated list of repo components to be synced from deb-archive")
58
+ param :deb_architectures, String, :desc => N_("comma-separated list of architectures to be synced from deb-archive")
57
59
  param :ignore_global_proxy, :bool, :desc => N_("if true, will ignore the globally configured proxy when syncing"), :deprecated => true
58
60
  param :ignorable_content, Array, :desc => N_("List of content units to ignore while syncing a yum repository. Must be subset of %s") % RootRepository::IGNORABLE_CONTENT_UNIT_TYPES.join(",")
59
61
  param :ansible_collection_requirements, String, :desc => N_("Contents of requirement yaml file to sync from URL")
@@ -476,7 +478,7 @@ module Katello
476
478
 
477
479
  def repository_params
478
480
  keys = [:download_policy, :mirror_on_sync, :arch, :verify_ssl_on_sync, :upstream_password, :upstream_username, :download_concurrency,
479
- :ostree_upstream_sync_depth, :ostree_upstream_sync_policy,
481
+ :ostree_upstream_sync_depth, :ostree_upstream_sync_policy, {:os_versions => []},
480
482
  :deb_releases, :deb_components, :deb_architectures, :description, :http_proxy_policy, :http_proxy_id,
481
483
  {:ignorable_content => []}
482
484
  ]
@@ -527,6 +529,7 @@ module Katello
527
529
  root.ansible_collection_requirements = repo_params[:ansible_collection_requirements] if root.ansible_collection?
528
530
  root.http_proxy_policy = repo_params[:http_proxy_policy] if repo_params.key?(:http_proxy_policy)
529
531
  root.http_proxy_id = repo_params[:http_proxy_id] if repo_params.key?(:http_proxy_id)
532
+ root.os_versions = repo_params.fetch(:os_versions, []) if root.yum?
530
533
 
531
534
  if root.ostree?
532
535
  root.ostree_upstream_sync_policy = repo_params[:ostree_upstream_sync_policy]
@@ -19,7 +19,7 @@ module Katello
19
19
 
20
20
  api :GET, "/organizations/:organization_id/subscriptions", N_("List organization subscriptions")
21
21
  api :GET, "/activation_keys/:activation_key_id/subscriptions", N_("List an activation key's subscriptions")
22
- api :GET, "/subscriptions"
22
+ api :GET, "/subscriptions", N_("List subscriptions")
23
23
  param_group :search, Api::V2::ApiController
24
24
  param :organization_id, :number, :desc => N_("Organization ID"), :required => false
25
25
  param :host_id, String, :desc => N_("id of a host"), :required => false
@@ -4,8 +4,10 @@ module Katello
4
4
 
5
5
  include Katello::Concerns::FilteredAutoCompleteSearch
6
6
  before_action :find_organization, :only => [:create, :index, :auto_complete_search]
7
- before_action :find_plan, :only => [:update, :show, :destroy, :sync,
8
- :add_products, :remove_products]
7
+ before_action :find_authorized_katello_resource, :only => [:update, :show, :destroy, :sync,
8
+ :add_products, :remove_products]
9
+ before_action :set_organization, :only => [:update, :show, :destroy, :sync,
10
+ :add_products, :remove_products]
9
11
 
10
12
  def_param_group :sync_plan do
11
13
  param :name, String, :desc => N_("sync plan name"), :required => true, :action_aware => true
@@ -117,16 +119,13 @@ module Katello
117
119
 
118
120
  protected
119
121
 
120
- def find_plan
121
- @sync_plan = SyncPlan.find_by(:id => params[:id])
122
- fail HttpErrors::NotFound, _("Couldn't find sync plan '%{plan}' in organization '%{org}'") % { :plan => params[:id], :org => params[:organization_id] } if @sync_plan.nil?
123
- @organization ||= @sync_plan.organization
124
- @sync_plan
125
- end
126
-
127
122
  def sync_plan_params
128
123
  params[:sync_plan][:enabled] = params[:enabled] unless params[:enabled].nil?
129
124
  params.require(:sync_plan).permit(:name, :description, :interval, :sync_date, :product_ids, :enabled, :cron_expression)
130
125
  end
126
+
127
+ def set_organization
128
+ @organization ||= @sync_plan.try(:organization)
129
+ end
131
130
  end
132
131
  end
@@ -77,7 +77,14 @@ module Katello
77
77
  render json: { status: 'OK' }
78
78
  end
79
79
 
80
- api :PUT, "/organizations/:organization_id/simple_content_access/enable",
80
+ api :GET, "/organizations/:organization_id/upstream_subscriptions/simple_content_access/eligible",
81
+ N_("Check if the specified organization is eligible for Simple Content Access")
82
+ def simple_content_access_eligible
83
+ eligible = @organization.upstream_consumer.simple_content_access_eligible?
84
+ render json: { simple_content_access_eligible: eligible }
85
+ end
86
+
87
+ api :PUT, "/organizations/:organization_id/upstream_subscriptions/simple_content_access/enable",
81
88
  N_("Enable simple content access for a manifest")
82
89
  param :organization_id, :number, :desc => N_("Organization ID"), :required => true
83
90
  def enable_simple_content_access
@@ -85,7 +92,7 @@ module Katello
85
92
  respond_for_async :resource => task
86
93
  end
87
94
 
88
- api :PUT, "/organizations/:organization_id/simple_content_access/disable",
95
+ api :PUT, "/organizations/:organization_id/upstream_subscriptions/simple_content_access/disable",
89
96
  N_("Disable simple content access for a manifest")
90
97
  param :organization_id, :number, :desc => N_("Organization ID"), :required => true
91
98
  def disable_simple_content_access
@@ -21,12 +21,16 @@ module Katello
21
21
  end
22
22
 
23
23
  def find_authorized_katello_resource
24
- finder_scope = ::Foreman::AccessControl.permissions_for_controller_action(path_to_authenticate).first&.finder_scope
25
- if finder_scope
26
- instance_variable_set("@#{resource_name}", resource_class.send(finder_scope).find_by(:id => params[:id]))
24
+ found_entity = nil
25
+ ::Foreman::AccessControl.permissions_for_controller_action(path_to_authenticate).each do |permission|
26
+ next unless found_entity.blank?
27
+ finder_scope = permission&.finder_scope
28
+ if finder_scope
29
+ found_entity = resource_class.send(finder_scope).find_by(:id => params[:id])
30
+ end
27
31
  end
28
-
29
- throw_resource_not_found if instance_variable_get("@#{resource_name}").nil?
32
+ throw_resource_not_found if found_entity.blank?
33
+ instance_variable_set("@#{resource_name}", found_entity)
30
34
  end
31
35
 
32
36
  def find_unauthorized_katello_resource
@@ -0,0 +1,21 @@
1
+ module Katello
2
+ module Concerns
3
+ module Api::V2::RegistrationControllerExtensions
4
+ extend ActiveSupport::Concern
5
+
6
+ def prepare_host
7
+ if params['uuid']
8
+ @host = Katello::Host::SubscriptionFacet.find_by(uuid: params['uuid'])&.host
9
+ if @host.nil?
10
+ msg = N_("Host was not found by the subscription UUID: '%s', this can happen if the host is registered already, but not to this Foreman") % params['uuid']
11
+ fail ActiveRecord::RecordNotFound, msg
12
+ end
13
+ @host.assign_attributes(host_params('host'))
14
+ @host.save!
15
+ else
16
+ super
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -60,7 +60,7 @@ module Katello
60
60
  collection = custom_collection_by_content_view_version(@versions)
61
61
  else
62
62
  repos = Katello::Repository.where(:content_view_version_id => @versions.pluck(:id))
63
- repos = repos.where(:library_instance_id => @repo.id) if @repo
63
+ repos = repos.where(:root_id => @repo.root_id) if @repo
64
64
  collection = filter_by_repos(repos, resource_class.all)
65
65
  end
66
66
 
@@ -7,7 +7,8 @@ module Katello
7
7
 
8
8
  module Overrides
9
9
  def edit
10
- @can_toggle_sca = Katello::UpstreamConnectionChecker.new(@taxonomy).can_connect?
10
+ @can_toggle_sca = Katello::UpstreamConnectionChecker.new(@taxonomy).can_connect? &&
11
+ (@taxonomy.upstream_consumer.simple_content_access_eligible? || @taxonomy.simple_content_access?)
11
12
  super
12
13
  end
13
14
 
@@ -6,12 +6,15 @@ module Katello
6
6
  ::Setting[:foreman_url].sub(%r|^.*?:|, "#{schema}:")
7
7
  end
8
8
 
9
- def subscription_manager_configuration_url(host = nil, rpm = true)
10
- prefix = if host&.content_source
9
+ def subscription_manager_configuration_url(host = nil, rpm = true, hostname: nil)
10
+ prefix = if hostname
11
+ "http://#{hostname}"
12
+ elsif host&.content_source
11
13
  "http://#{host.content_source.hostname}"
12
14
  else
13
15
  foreman_settings_url
14
16
  end
17
+
15
18
  config = rpm ? SETTINGS[:katello][:consumer_cert_rpm] : SETTINGS[:katello][:consumer_cert_sh]
16
19
 
17
20
  "#{prefix}/pub/#{config}"
@@ -9,6 +9,7 @@ module Actions
9
9
  param :label
10
10
  param :content_url
11
11
  param :owner
12
+ param :os_versions
12
13
  end
13
14
 
14
15
  def run
@@ -19,6 +20,7 @@ module Actions
19
20
  type: input[:type],
20
21
  arches: input[:arches],
21
22
  label: input[:label],
23
+ requiredTags: input[:os_versions],
22
24
  metadataExpire: 1,
23
25
  vendor: ::Katello::Provider::CUSTOM)
24
26
  end
@@ -7,6 +7,7 @@ module Actions
7
7
  param :name
8
8
  param :type
9
9
  param :arches
10
+ param :os_versions
10
11
  param :label
11
12
  param :content_url
12
13
  param :gpg_key_url
@@ -22,6 +23,7 @@ module Actions
22
23
  gpgUrl: input[:gpg_key_url] || '', #candlepin ignores nil
23
24
  type: input[:type],
24
25
  arches: input[:arches],
26
+ requiredTags: input[:os_versions],
25
27
  label: input[:label],
26
28
  metadataExpire: 1,
27
29
  vendor: ::Katello::Provider::CUSTOM)
@@ -9,12 +9,8 @@ module Actions
9
9
 
10
10
  def run
11
11
  input[:host_ids].each do |host_id|
12
- content_facet = ::Katello::Host::ContentFacet.find_by_host_id(host_id)
13
- if content_facet.present?
14
- content_facet.calculate_and_import_applicability
15
- else
16
- Rails.logger.warn(_("Content Facet for host with id %s is non-existent. Skipping applicability calculation.") % host_id)
17
- end
12
+ content_facet = ::Host.find(host_id).content_facet
13
+ content_facet.calculate_and_import_applicability
18
14
  end
19
15
  end
20
16
 
@@ -20,14 +20,10 @@ module Actions
20
20
  Actions::Pulp3::CapsuleContent::Sync],
21
21
  repo, smart_proxy,
22
22
  skip_metadata_check: skip_metadata_check)
23
- end
24
- end
25
23
 
26
- concurrence do
27
- repo_batch.each do |repo|
28
24
  if repo.is_a?(::Katello::Repository) &&
29
- repo.distribution_bootable? &&
30
- repo.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND
25
+ repo.distribution_bootable? &&
26
+ repo.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND
31
27
  plan_action(Katello::Repository::FetchPxeFiles,
32
28
  id: repo.id,
33
29
  capsule_id: smart_proxy.id)
@@ -9,7 +9,6 @@ module Actions
9
9
  def plan(content_view, description = "", options = {})
10
10
  action_subject(content_view)
11
11
  import_only = options.fetch(:import_only, false)
12
- path = options[:path]
13
12
  content_view.check_ready_to_publish! unless import_only
14
13
 
15
14
  if options[:repos_units].present?
@@ -54,7 +53,7 @@ module Actions
54
53
  if separated_repo_map[:pulp3_yum].keys.flatten.present? &&
55
54
  SmartProxy.pulp_primary.pulp3_support?(separated_repo_map[:pulp3_yum].keys.flatten.first)
56
55
  if import_only
57
- handle_import(version, path)
56
+ handle_import(version, options.slice(:path, :metadata))
58
57
  else
59
58
  plan_action(Repository::MultiCloneToVersion, separated_repo_map[:pulp3_yum], version)
60
59
  end
@@ -188,8 +187,8 @@ module Actions
188
187
  end
189
188
  end
190
189
 
191
- def handle_import(version, path)
192
- plan_action(::Actions::Pulp3::Orchestration::ContentViewVersion::Import, version, path: path)
190
+ def handle_import(version, path:, metadata:)
191
+ plan_action(::Actions::Pulp3::Orchestration::ContentViewVersion::Import, version, path: path, metadata: metadata)
193
192
  plan_action(::Actions::Pulp3::Orchestration::ContentViewVersion::CopyVersionUnitsToLibrary, version)
194
193
  concurrence do
195
194
  version.importable_repositories.pluck(:id).each do |id|
@@ -4,13 +4,13 @@ module Actions
4
4
  class Import < Actions::EntryAction
5
5
  PULP_USER = 'pulp'.freeze
6
6
 
7
- def plan(content_view, path:)
7
+ def plan(content_view, path:, metadata:)
8
8
  content_view.check_ready_to_import!
9
9
  unless SmartProxy.pulp_primary.pulp3_repository_type_support?(::Katello::Repository::YUM_TYPE)
10
- fail HttpErrors::BadRequest, _("This API endpoint is only valid for Pulp 3 repositories.")
10
+ fail ::Katello::HttpErrors::BadRequest, _("This API endpoint is only valid for Pulp 3 repositories.")
11
11
  end
12
12
  ::Katello::Pulp3::ContentViewVersion::Import.check_permissions!(path)
13
- metadata = ::Katello::Pulp3::ContentViewVersion::Import.metadata(path)
13
+
14
14
  major = metadata[:content_view_version][:major]
15
15
  minor = metadata[:content_view_version][:minor]
16
16
 
@@ -22,6 +22,7 @@ module Actions
22
22
 
23
23
  plan_action(::Actions::Katello::ContentView::Publish, content_view, '',
24
24
  path: path,
25
+ metadata: metadata,
25
26
  import_only: true,
26
27
  major: major,
27
28
  minor: minor)
@@ -91,7 +91,8 @@ module Actions
91
91
  sequence do
92
92
  new_puppet_environment = plan_action(Katello::ContentViewPuppetEnvironment::Clone, old_version,
93
93
  :new_version => new_content_view_version).new_puppet_environment
94
- copy_action_outputs += copy_puppet_content(new_puppet_environment, content[:puppet_module_ids]) unless content[:puppet_module_ids].blank?
94
+ check_puppet_module_duplicates(content[:puppet_module_ids])
95
+ copy_action_outputs += copy_puppet_content(new_puppet_environment, content[:puppet_module_ids], old_version) unless content[:puppet_module_ids].blank?
95
96
  end
96
97
  end
97
98
 
@@ -368,14 +369,28 @@ module Actions
368
369
  copy_outputs
369
370
  end
370
371
 
372
+ def check_puppet_module_duplicates(puppet_module_ids)
373
+ puppet_module_dup_counts = ::Katello::PuppetModule.where(id: puppet_module_ids).
374
+ select(:name, :author).group(:name, :author).having("count(*) > 1").size
375
+ if puppet_module_dup_counts.present?
376
+ offending_puppet_modules = puppet_module_dup_counts.keys.collect do |dup|
377
+ "#{dup[0]}-#{dup[1]}"
378
+ end
379
+ fail _("Adding multiple versions of the same Puppet Module is not supported by incremental update. The following Puppet Modules have duplicate versions in the incremental update content list: %{dup_list}" % {:dup_list => offending_puppet_modules})
380
+ end
381
+ end
382
+
371
383
  def remove_puppet_modules(repo, puppet_module_ids)
372
384
  plan_action(Pulp::Repository::RemoveUnits, :content_view_puppet_environment_id => repo.id, :contents => puppet_module_ids, :content_unit_type => ::Katello::PuppetModule::CONTENT_TYPE)
373
385
  end
374
386
 
375
- def copy_puppet_content(new_repo, puppet_module_ids)
387
+ def copy_puppet_content(new_repo, puppet_module_ids, old_version)
376
388
  copy_outputs = []
389
+ # Remove older versions
390
+ query = 'SELECT a.* FROM katello_puppet_modules a LEFT JOIN katello_puppet_modules b ON a.name = b.name AND a.author = b.author AND a.sortable_version < b.sortable_version WHERE b.sortable_version IS NOT NULL AND a.id IN (:old_version_puppet_module_ids)'
391
+ old_puppet_module_ids = ::Katello::PuppetModule.find_by_sql([query, :old_version_puppet_module_ids => old_version.puppet_modules.map(&:id)]).map(&:id)
377
392
  unless puppet_module_ids.blank?
378
- remove_puppet_modules(new_repo, puppet_module_ids)
393
+ remove_puppet_modules(new_repo, (old_puppet_module_ids + puppet_module_ids).uniq)
379
394
  copy_outputs = puppet_module_ids.map { |module_id| copy_puppet_module(new_repo, module_id).output }
380
395
  plan_action(Pulp::ContentViewPuppetEnvironment::IndexContent, id: new_repo.id)
381
396
  end
@@ -0,0 +1,31 @@
1
+ module Actions
2
+ module Katello
3
+ module Host
4
+ class UpdateSystemPurpose < Actions::EntryAction
5
+ def plan(host, service_level, purpose_role, purpose_usage, purpose_addons)
6
+ fail _("Host %s has not been registered with subscription-manager.") % host.name unless host.subscription_facet
7
+
8
+ host.subscription_facet.service_level = service_level unless service_level.nil?
9
+ host.subscription_facet.purpose_role = purpose_role unless purpose_role.nil?
10
+ host.subscription_facet.purpose_usage = purpose_usage unless purpose_usage.nil?
11
+
12
+ if purpose_addons
13
+ purpose_addon_objects = purpose_addons.delete_if(&:blank?).uniq.map { |x| ::Katello::PurposeAddon.find_or_create_by(name: x) }
14
+ host.subscription_facet.purpose_addons = purpose_addon_objects
15
+ end
16
+
17
+ host.subscription_facet.save!
18
+ plan_self(:hostname => host.name)
19
+ end
20
+
21
+ def humanized_name
22
+ if input&.dig(:hostname)
23
+ _("Updating System Purpose for host %s") % input[:hostname]
24
+ else
25
+ _("Updating System Purpose for host")
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -40,7 +40,6 @@ module Actions
40
40
  end
41
41
 
42
42
  def finalize
43
- subject_organization.clear_syspurpose_status if subject_organization.simple_content_access?(cached: false)
44
43
  subject_organization.audit_manifest_action(_('Manifest deleted'))
45
44
  end
46
45
  end
@@ -45,7 +45,6 @@ module Actions
45
45
  end
46
46
 
47
47
  def finalize
48
- subject_organization.clear_syspurpose_status if subject_organization.simple_content_access?(cached: false)
49
48
  subject_organization.clear_manifest_expired_notifications
50
49
  subject_organization.audit_manifest_action(_('Manifest imported'))
51
50
  end
@@ -61,7 +61,6 @@ module Actions
61
61
 
62
62
  def finalize
63
63
  org = ::Organization.find(input[:organization_id])
64
- subject_organization.clear_syspurpose_status if subject_organization.simple_content_access?(cached: false)
65
64
  org.clear_manifest_expired_notifications
66
65
  subject_organization.audit_manifest_action(_('Manifest refreshed'))
67
66
  end
@@ -8,12 +8,13 @@ module Actions
8
8
  sequence do
9
9
  if root.content_id.nil?
10
10
  content_create = plan_action(Candlepin::Product::ContentCreate,
11
- owner: root.product.organization.label,
12
- name: root.name,
13
- type: root.content_type,
14
- arches: root.format_arches,
15
- label: root.custom_content_label,
16
- content_url: root.custom_content_path)
11
+ owner: root.product.organization.label,
12
+ name: root.name,
13
+ type: root.content_type,
14
+ arches: root.format_arches,
15
+ label: root.custom_content_label,
16
+ os_versions: root.os_versions&.join(','),
17
+ content_url: root.custom_content_path)
17
18
  content_id = content_create.output[:response][:id]
18
19
  plan_action(Candlepin::Product::ContentAdd, owner: root.product.organization.label,
19
20
  product_id: root.product.cp_id,
@@ -10,6 +10,7 @@ module Actions
10
10
  param :upload_actions
11
11
  end
12
12
 
13
+ # rubocop:disable Metrics/MethodLength
13
14
  def run
14
15
  repo = ::Katello::Repository.find(input[:id])
15
16
  if repo.puppet?
@@ -21,7 +22,15 @@ module Actions
21
22
  elsif repo.file?
22
23
  ::Katello::FileUnit.import_for_repository(repo)
23
24
  elsif repo.deb?
24
- unit_ids = search_units(repo)
25
+ if input[:import_upload_task] && input[:import_upload_task][:content_unit_href]
26
+ unit_ids = [input[:import_upload_task][:content_unit_href]]
27
+ elsif input[:upload_actions]&.any? { |action| action.try(:[], "content_unit_href") }
28
+ uploaded_content_unit_hrefs = []
29
+ input[:upload_actions].each { |action| uploaded_content_unit_hrefs << action.try(:[], "content_unit_href") }
30
+ unit_ids = uploaded_content_unit_hrefs.compact
31
+ else
32
+ unit_ids = search_units(repo)
33
+ end
25
34
  ::Katello::Deb.import_all(unit_ids, repo)
26
35
  elsif repo.yum?
27
36
  if input[:import_upload_task] && input[:import_upload_task][:content_unit_href]