katello 3.16.0.rc3.1 → 3.16.0.rc4

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/api_controller.rb +8 -4
  3. data/app/controllers/katello/api/v2/subscriptions_controller.rb +1 -1
  4. data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +13 -1
  5. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +11 -0
  6. data/app/lib/katello/errors.rb +25 -0
  7. data/app/lib/katello/resources/candlepin.rb +1 -1
  8. data/app/lib/katello/resources/candlepin/upstream_consumer.rb +6 -0
  9. data/app/models/katello/concerns/host_managed_extensions.rb +7 -0
  10. data/app/models/katello/concerns/organization_extensions.rb +14 -0
  11. data/app/models/katello/pulp3/content_guard.rb +1 -1
  12. data/app/services/katello/candlepin/message_handler.rb +2 -3
  13. data/app/services/katello/pulp3/repository.rb +8 -1
  14. data/app/services/katello/pulp3/repository/yum.rb +8 -0
  15. data/app/services/katello/ui_notifications/subscriptions/manifest_expired_warning.rb +20 -8
  16. data/app/services/katello/upstream_connection_checker.rb +48 -0
  17. data/app/views/katello/api/v2/srpms/backend.json.rabl +11 -0
  18. data/app/views/katello/api/v2/srpms/base.json.rabl +5 -0
  19. data/app/views/katello/api/v2/srpms/compare.json.rabl +10 -0
  20. data/app/views/katello/api/v2/srpms/index.json.rabl +1 -1
  21. data/app/views/katello/api/v2/srpms/show.json.rabl +3 -3
  22. data/config/routes/api/v2.rb +2 -0
  23. data/db/seeds.d/109-katello-notification-blueprints.rb +1 -1
  24. data/lib/katello/permission_creator.rb +1 -1
  25. data/lib/katello/version.rb +1 -1
  26. data/package.json +3 -3
  27. data/webpack/components/Content/ContentTable.js +2 -0
  28. data/webpack/components/Content/Details/ContentDetails.js +3 -0
  29. data/webpack/scenes/AnsibleCollections/Details/AnsibleCollectionDetails.js +3 -0
  30. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +3 -0
  31. data/webpack/scenes/RedHatRepositories/RedHatRepositoriesPage.js +2 -0
  32. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepository.js +2 -0
  33. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository/RepositorySetRepository.js +2 -0
  34. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailAssociations.js +2 -0
  35. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProductContent.js +2 -0
  36. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProducts.js +2 -0
  37. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +2 -0
  38. data/webpack/scenes/Subscriptions/SubscriptionActions.js +8 -8
  39. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +3 -1
  40. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +15 -1
  41. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +54 -7
  42. data/webpack/scenes/Subscriptions/SubscriptionsSelectors.js +3 -0
  43. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsActions.js +15 -1
  44. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/{UpstreamSubscriptionsContstants.js → UpstreamSubscriptionsConstants.js} +3 -0
  45. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +2 -0
  46. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsReducer.js +1 -1
  47. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsReducer.test.js +1 -1
  48. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsActions.test.js +0 -13
  49. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +6 -1
  50. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +6 -4
  51. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsReducer.test.js.snap +26 -25
  52. data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +0 -58
  53. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js +10 -4
  54. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +1 -0
  55. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +1 -68
  56. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Dialogs/UpdateDialog.js +1 -1
  57. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Dialogs/index.js +4 -4
  58. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Table.js +12 -10
  59. data/webpack/scenes/Subscriptions/index.js +6 -3
  60. metadata +27 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c111ad081f2588aaf6e770186fc98a2945887a06e465cdce62cc7fc20d56205
4
- data.tar.gz: bb1a4f8f3872e632bf36deb2db63a92753f5f4eaab3cea97bb47d5809d24e9ec
3
+ metadata.gz: 590a33ff3016ad29aaeca6e8d5a0c967b9053a01cf3dbf8f28fcb68b63d056bd
4
+ data.tar.gz: e8c30ca9e88f472f3aabf89b7f2cc3c6122750706e9bdfbb9d1cfa8aa957d4a5
5
5
  SHA512:
6
- metadata.gz: 30b8f98b25c3a1f04d8796a9e060868e306f802dc50fc140f8d528eec3afe4c2c564d8f20858edb753c9ba75a6c3e56d26636c2b8bdbb5e6363e07d2af1d81a6
7
- data.tar.gz: af95e39c10ea7d9ed8805db3dc18be1a58e90a2e24d18fbf9e99ff1eb710abb657737b6a5094c693a2cee42f2bcdc798a9de6395e250645059f3134c89d913c7
6
+ metadata.gz: 2fbba71f828db21edacf4100aac226a638fa7c6dd59871f6d0f029846af27ff54914c803798fd6054463ae4f44bbfc29d9466fca8a19867e63c10486668ce30c
7
+ data.tar.gz: 17347500daf6bb1b2dd1ff7126b97e84f2120e1c12e23066036d2f30402cdb9018dc5c6cb1f74ceff441f069a2733dceb4e3a4958032237034eaff5783915b49
@@ -211,10 +211,14 @@ module Katello
211
211
  fail HttpErrors::BadRequest, _("Host has not been registered with subscription-manager") if @host.subscription_facet.nil?
212
212
  end
213
213
 
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]
214
+ def check_upstream_connection
215
+ checker = Katello::UpstreamConnectionChecker.new(@organization)
216
+
217
+ begin
218
+ checker.assert_connection
219
+ rescue => e
220
+ raise HttpErrors::BadRequest, e.message
221
+ end
218
222
  end
219
223
  end
220
224
  end
@@ -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
@@ -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
@@ -39,6 +39,12 @@ module Katello
39
39
  end
40
40
  end
41
41
 
42
+ class HostRegisteredException < StandardError
43
+ def message
44
+ _("Content host must be unregistered before performing this action.")
45
+ end
46
+ end
47
+
42
48
  class EmptyBulkActionException < StandardError
43
49
  def message
44
50
  _("No hosts registered with subscription-manager found in selection.")
@@ -154,5 +160,24 @@ module Katello
154
160
  _("No URL found for a container registry. Please check the configuration.")
155
161
  end
156
162
  end
163
+
164
+ class DisconnectedMode < StandardError
165
+ def message
166
+ _("You are currently operating in disconnected mode where access to Red Hat Subcription Management " \
167
+ "is prohibited. If you would like to change this, please update the content setting 'Disconnected mode'.")
168
+ end
169
+ end
170
+
171
+ class NoManifestImported < StandardError
172
+ def message
173
+ _("Current organization has no manifest imported.")
174
+ end
175
+ end
176
+
177
+ class ManifestExpired < StandardError
178
+ def message
179
+ _("This Organization's subscription manifest has expired. Please import a new manifest.")
180
+ end
181
+ end
157
182
  end
158
183
  end
@@ -142,7 +142,7 @@ module Katello
142
142
  def upstream_consumer
143
143
  fail _("Current organization not set.") unless Organization.current
144
144
  upstream_consumer = Organization.current.owner_details['upstreamConsumer']
145
- fail _("Current organization has no manifest imported.") unless upstream_consumer
145
+ fail Katello::Errors::NoManifestImported unless upstream_consumer
146
146
 
147
147
  upstream_consumer
148
148
  end
@@ -9,6 +9,12 @@ module Katello
9
9
  super(id)
10
10
  end
11
11
 
12
+ def ping
13
+ resource.head
14
+ rescue RestClient::Unauthorized, RestClient::Gone
15
+ raise ::Katello::Errors::UpstreamConsumerGone
16
+ end
17
+
12
18
  # Overrides the HttpResource get method to check if the upstream
13
19
  # consumer exists.
14
20
  def get(params)
@@ -50,6 +50,7 @@ module Katello
50
50
 
51
51
  before_save :correct_puppet_environment
52
52
  before_validation :correct_kickstart_repository
53
+ before_update :check_host_registration, :if => proc { organization_id_changed? }
53
54
 
54
55
  scope :with_pools_expiring_in_days, ->(days) { joins(:pools).merge(Katello::Pool.expiring_in_days(days)).distinct }
55
56
 
@@ -76,6 +77,12 @@ module Katello
76
77
  end
77
78
  end
78
79
 
80
+ def check_host_registration
81
+ if subscription_facet
82
+ fail ::Katello::Errors::HostRegisteredException
83
+ end
84
+ end
85
+
79
86
  def correct_kickstart_repository
80
87
  return unless content_facet
81
88
 
@@ -82,6 +82,20 @@ module Katello
82
82
  self.providers.anonymous.first
83
83
  end
84
84
 
85
+ def manifest_imported?
86
+ owner_details['upstreamConsumer'].present?
87
+ end
88
+
89
+ def manifest_expired?
90
+ manifest_expiry = owner_details.dig(:upstreamConsumer, :idCert, :serial, :expiration)
91
+
92
+ if manifest_expiry
93
+ DateTime.parse(manifest_expiry) < DateTime.now
94
+ else
95
+ false
96
+ end
97
+ end
98
+
85
99
  def manifest_history
86
100
  imports.map { |i| OpenStruct.new(i) }
87
101
  end
@@ -5,7 +5,7 @@ module Katello
5
5
  return unless (count == 0 || force)
6
6
  content_guard_api = Katello::Pulp3::Api::ContentGuard.new(smart_proxy)
7
7
  content_guard = content_guard_api.list&.results&.first
8
- fail _("No Content Guard configured!") unless content_guard
8
+ return unless content_guard
9
9
  katello_content_guard = self.new(name: content_guard.name, pulp_href: content_guard.pulp_href)
10
10
  katello_content_guard.save!
11
11
  end
@@ -81,9 +81,8 @@ module Katello
81
81
  end
82
82
 
83
83
  def delete_pool
84
- if pool
85
- Rails.logger.info "deleting pool #{pool.id} from Katello"
86
- pool.destroy!
84
+ if Katello::Pool.where(:cp_id => pool_id).destroy_all.any?
85
+ Rails.logger.info "deleted pool #{pool_id} from Katello"
87
86
  end
88
87
  end
89
88
  end
@@ -48,6 +48,10 @@ module Katello
48
48
  nil
49
49
  end
50
50
 
51
+ def skip_types
52
+ nil
53
+ end
54
+
51
55
  def content_service
52
56
  Katello::Pulp3::Content
53
57
  end
@@ -190,7 +194,10 @@ module Katello
190
194
  end
191
195
 
192
196
  def sync
193
- repository_sync_url_data = api.class.repository_sync_url_class.new(remote: repo.remote_href, mirror: repo.root.mirror_on_sync)
197
+ sync_url_params = {remote: repo.remote_href, mirror: repo.root.mirror_on_sync}
198
+ skip_type_param = skip_types
199
+ sync_url_params[:skip_types] = skip_type_param if skip_type_param
200
+ repository_sync_url_data = api.class.repository_sync_url_class.new(sync_url_params)
194
201
  [api.repositories_api.sync(repository_reference.repository_href, repository_sync_url_data)]
195
202
  end
196
203
 
@@ -15,6 +15,14 @@ module Katello
15
15
  end
16
16
  end
17
17
 
18
+ def skip_types
19
+ skip_types = []
20
+ if root.ignorable_content.try(:include?, "srpm")
21
+ skip_types << "srpm"
22
+ end
23
+ skip_types
24
+ end
25
+
18
26
  def distribution_options(path)
19
27
  {
20
28
  base_path: path,
@@ -7,14 +7,11 @@ module Katello
7
7
  CDN_PATH = '/content/dist/rhel/server/7/listing'.freeze
8
8
 
9
9
  def self.deliver!(orgs = ::Organization.all)
10
+ return if Setting[:content_disconnected]
11
+
10
12
  orgs.each do |org|
11
- next unless redhat_connected?(org)
12
- content = org.contents.find_by(:label => CONTENT_LABEL)
13
- product = content&.products&.find { |p| p.key }
14
- if content && product && product.pools.any?
15
- if got_403? { product.cdn_resource.get(CDN_PATH) }
16
- new(org).deliver!
17
- end
13
+ if cdn_inaccessible?(org) || upstream_inaccessible?(org)
14
+ new(org).deliver!
18
15
  end
19
16
  end
20
17
  rescue StandardError => e
@@ -47,6 +44,14 @@ module Katello
47
44
  @blueprint ||= NotificationBlueprint.find_by(name: 'manifest_expired_warning')
48
45
  end
49
46
 
47
+ def self.cdn_inaccessible?(org)
48
+ content = org.contents.find_by(:label => CONTENT_LABEL)
49
+ product = content&.products&.find { |p| p.key }
50
+ if content && product && product.pools.any?
51
+ return got_403? { product.cdn_resource.get(CDN_PATH) }
52
+ end
53
+ end
54
+
50
55
  def self.got_403?
51
56
  yield
52
57
  false
@@ -54,8 +59,15 @@ module Katello
54
59
  true
55
60
  end
56
61
 
62
+ def self.upstream_inaccessible?(org)
63
+ return unless org.manifest_imported?
64
+
65
+ checker = Katello::UpstreamConnectionChecker.new(org)
66
+ !checker.can_connect?
67
+ end
68
+
57
69
  def self.redhat_connected?(org)
58
- org.redhat_provider.repository_url.include?(CDN_HOSTNAME) && !Setting[:content_disconnected]
70
+ org.redhat_provider.repository_url.include?(CDN_HOSTNAME)
59
71
  end
60
72
  end
61
73
  end
@@ -0,0 +1,48 @@
1
+ module Katello
2
+ class UpstreamConnectionChecker
3
+ POSSIBLE_EXCEPTIONS = [
4
+ Katello::Errors::DisconnectedMode,
5
+ Katello::Errors::ManifestExpired,
6
+ Katello::Errors::UpstreamConsumerGone,
7
+ Katello::Errors::NoManifestImported
8
+ ].freeze
9
+
10
+ def initialize(organization)
11
+ @organization = organization
12
+ end
13
+
14
+ def can_connect?
15
+ assert_connection
16
+ rescue StandardError => e
17
+ if POSSIBLE_EXCEPTIONS.include?(e.class)
18
+ false
19
+ else
20
+ raise e
21
+ end
22
+ end
23
+
24
+ def assert_connection
25
+ assert_connected
26
+ assert_unexpired_manifest
27
+ assert_can_upstream_ping
28
+
29
+ true
30
+ end
31
+
32
+ private
33
+
34
+ def assert_connected
35
+ fail Katello::Errors::DisconnectedMode if Setting[:content_disconnected]
36
+ end
37
+
38
+ def assert_can_upstream_ping
39
+ ::Organization.as_org(@organization) do
40
+ Katello::Resources::Candlepin::UpstreamConsumer.ping
41
+ end
42
+ end
43
+
44
+ def assert_unexpired_manifest
45
+ fail Katello::Errors::ManifestExpired if @organization.manifest_expired?
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,11 @@
1
+ attributes :description
2
+ attributes :license, :buildhost, :vendor, :relativepath
3
+ attributes :children, :checksumtype, :size, :url, :build_time, :summary, :group, :requires, :provides, :files
4
+
5
+ node :human_readable_size do |package|
6
+ number_to_human_size(package.size) if package.size
7
+ end
8
+
9
+ node :build_time_utc do |package|
10
+ Time.at(package.build_time).to_datetime if package.build_time
11
+ end
@@ -0,0 +1,5 @@
1
+ object @resource
2
+
3
+ attributes :id, :pulp_id, :name, :filename
4
+ attributes :created_at, :updated, :version, :arch, :release
5
+ attributes :epoch, :checksum, :summary, :nvra
@@ -0,0 +1,10 @@
1
+ object false
2
+
3
+ extends "katello/api/v2/common/metadata"
4
+
5
+ child @collection[:results] => :results do
6
+ extends 'katello/api/v2/srpms/base'
7
+ node :comparison do |result|
8
+ result.comparison
9
+ end
10
+ end
@@ -3,5 +3,5 @@ object false
3
3
  extends "katello/api/v2/common/metadata"
4
4
 
5
5
  child @collection[:results] => :results do
6
- extends 'katello/api/v2/srpms/show'
6
+ extends 'katello/api/v2/srpms/base'
7
7
  end
@@ -1,5 +1,5 @@
1
1
  object @resource
2
2
 
3
- attributes :id, :pulp_id, :name, :filename
4
- attributes :created_at, :updated, :version, :arch, :release
5
- attributes :epoch, :checksum, :summary, :nvra
3
+ extends "katello/api/v2/srpms/base"
4
+ extends "katello/api/v2/srpms/backend",
5
+ :object => SmartProxy.pulp_master!.content_service("srpm").new(@resource.pulp_id)
@@ -349,10 +349,12 @@ Katello::Engine.routes.draw do
349
349
  put :refresh_manifest
350
350
  end
351
351
  end
352
+
352
353
  api_resources :upstream_subscriptions, only: [:index, :create] do
353
354
  collection do
354
355
  delete :destroy
355
356
  put :update
357
+ get :ping
356
358
  end
357
359
  end
358
360
  end
@@ -22,7 +22,7 @@ blueprints = [
22
22
  {
23
23
  group: N_('Subscriptions'),
24
24
  name: 'manifest_expired_warning',
25
- message: N_('The manifest imported within Organization %{subject} is no longer valid. Attempted CDN access returned Forbidden. Refreshing the manifest may resolve this issue.'),
25
+ message: N_('The manifest imported within Organization %{subject} is no longer valid. Please import a new manifest.'),
26
26
  level: 'warning'
27
27
  },
28
28
  {
@@ -367,7 +367,7 @@ module Katello
367
367
  :resource_type => 'Katello::Subscription'
368
368
  @plugin.permission :manage_subscription_allocations,
369
369
  {
370
- 'katello/api/v2/upstream_subscriptions' => [:index, :create, :destroy, :update]
370
+ 'katello/api/v2/upstream_subscriptions' => [:index, :create, :destroy, :update, :ping]
371
371
  },
372
372
  :resource_type => 'Katello::Subscription'
373
373
  end
@@ -1,3 +1,3 @@
1
1
  module Katello
2
- VERSION = "3.16.0.rc3.1".freeze
2
+ VERSION = "3.16.0.rc4".freeze
3
3
  end
@@ -29,8 +29,8 @@
29
29
  "@storybook/storybook-deployer": "^2.0.0",
30
30
  "@testing-library/jest-dom": "^5.3.0",
31
31
  "@testing-library/react": "^10.0.2",
32
- "@theforeman/builder": "^4.2.0",
33
- "@theforeman/vendor-dev": "^4.2.0",
32
+ "@theforeman/builder": "4.3.0",
33
+ "@theforeman/vendor-dev": "4.3.0",
34
34
  "axios-mock-adapter": "^1.10.0",
35
35
  "babel-eslint": "^10.0.3",
36
36
  "babel-jest": "^24.9.0",
@@ -56,8 +56,8 @@
56
56
  "react-test-renderer": "^16.0.0",
57
57
  "redux-mock-store": "^1.3.0"
58
58
  },
59
- "_comment": "We don't include @theforeman/vendor because it's assumed to be present in Foreman",
60
59
  "dependencies": {
60
+ "@theforeman/vendor-core": "4.3.0",
61
61
  "@patternfly/react-icons": "^3.15.15",
62
62
  "@patternfly/react-tokens": "^2.8.13",
63
63
  "angular": "1.7.9",