katello 4.4.0.rc2 → 4.4.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/content_views_controller.rb +2 -0
  3. data/app/controllers/katello/api/v2/environments_controller.rb +2 -0
  4. data/app/lib/actions/katello/cdn_configuration/update.rb +2 -2
  5. data/app/lib/katello/resources/cdn/katello_cdn.rb +37 -14
  6. data/app/models/katello/candlepin/repository_mapper.rb +10 -2
  7. data/app/models/katello/cdn_configuration.rb +2 -0
  8. data/app/models/katello/kt_environment.rb +1 -0
  9. data/app/services/katello/organization_creator.rb +9 -5
  10. data/app/services/katello/registration_manager.rb +1 -0
  11. data/app/views/katello/api/v2/repositories/show.json.rabl +2 -2
  12. data/db/migrate/20220124191056_add_type_to_cdn_configuration.rb +1 -7
  13. data/db/migrate/20220303160220_remove_duplicate_errata.rb +34 -0
  14. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/views/sync-plan-products.html +1 -1
  15. data/lib/katello/tasks/pulp2to3_migrate_deb_attributes.rake +20 -0
  16. data/lib/katello/version.rb +1 -1
  17. data/webpack/components/RoutedTabs/index.js +1 -17
  18. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard.js +2 -1
  19. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.js +2 -1
  20. data/webpack/components/extensions/HostDetails/Cards/__tests__/contentViewDetailsCard.test.js +30 -31
  21. data/webpack/components/extensions/HostDetails/Cards/__tests__/errataOverviewCard.test.js +30 -3
  22. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/SecondaryTabsRoutes.js +1 -1
  23. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +1 -1
  24. data/webpack/components/extensions/HostDetails/{HostPackages → Tabs/PackagesTab}/HostPackagesActions.js +3 -3
  25. data/webpack/components/extensions/HostDetails/{HostPackages → Tabs/PackagesTab}/HostPackagesConstants.js +0 -0
  26. data/webpack/components/extensions/HostDetails/{HostPackages → Tabs/PackagesTab}/HostPackagesSelectors.js +0 -0
  27. data/webpack/components/extensions/HostDetails/Tabs/{PackageInstallModal.js → PackagesTab/PackageInstallModal.js} +9 -9
  28. data/webpack/components/extensions/HostDetails/Tabs/{PackageInstallModal.scss → PackagesTab/PackageInstallModal.scss} +0 -0
  29. data/webpack/components/extensions/HostDetails/Tabs/{PackagesTab.js → PackagesTab/PackagesTab.js} +11 -11
  30. data/webpack/components/extensions/HostDetails/Tabs/{PackagesTab.scss → PackagesTab/PackagesTab.scss} +0 -0
  31. data/webpack/components/extensions/HostDetails/{YumInstallablePackages → Tabs/PackagesTab}/YumInstallablePackagesActions.js +1 -1
  32. data/webpack/components/extensions/HostDetails/{YumInstallablePackages → Tabs/PackagesTab}/YumInstallablePackagesConstants.js +0 -0
  33. data/webpack/components/extensions/HostDetails/{YumInstallablePackages → Tabs/PackagesTab}/YumInstallablePackagesSelectors.js +0 -0
  34. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +2 -2
  35. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packageInstallModal.test.js +2 -2
  36. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +2 -2
  37. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +2 -2
  38. data/webpack/components/extensions/HostDetails/hostDetailsHelpers.js +10 -1
  39. data/webpack/global_index.js +4 -3
  40. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js +15 -19
  41. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/UpstreamServerTypeForm.js +3 -2
  42. metadata +16 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 294ac07f46dd213e4ebbdd13f97d387b39ef2e5859ed6224e354672f4b26f244
4
- data.tar.gz: b08b1182252900cc7390ae257b1a9243fcdb26f00d64b1f668cc17faff4f08e8
3
+ metadata.gz: e193a2273fbdeccfaeb286b7a86738e7bbb1bb78120a663e4309aac912ef4501
4
+ data.tar.gz: afbec4d28494d215e8b7c318cd403a632d3c8c14ccff79f809cc01f4fc713f3d
5
5
  SHA512:
6
- metadata.gz: 85c64b73f97252bd9f99c28071bddd97aebc83a525a5ec8559f4538180c733eca336e433e4d2f06204e6d57c5333246fc512e155c2396622daa369fd0dc0bbb4
7
- data.tar.gz: e5d7904f19cb93eac89ff6e27b6c585e53f9419e925c4c5bedce2b30ac7a1d8df6c3e518574ad86c6607edbacc99a21360df54cef3b3ddfb94c4c38570f945a7
6
+ metadata.gz: da5af110e6327f56eff8c5f72eb1e80936142b534e68d9bdc9f081efa9838f35b0eb03d99e461e59f9c0f2be1a55f7955f2fee6d97b8874f35ce4ba60bb4c1df
7
+ data.tar.gz: 6c6db26dac3ffa0ace7837e9774d56d93cba08df34fee0616bde18816a6785e5c54d697768d2f5a39bbd40a67b990462bb9e2e7e2d44cfdd74043221ca820dd6
@@ -53,6 +53,7 @@ module Katello
53
53
  param :composite, :bool, :desc => N_("Filter only composite content views")
54
54
  param :without, Array, :desc => N_("Do not include this array of content views")
55
55
  param :name, String, :desc => N_("Name of the content view"), :required => false
56
+ param :label, String, :desc => N_("Label of the content view"), :required => false
56
57
  param_group :search, Api::V2::ApiController
57
58
  add_scoped_search_description_for(ContentView)
58
59
  def index
@@ -69,6 +70,7 @@ module Katello
69
70
  content_views = ::Foreman::Cast.to_bool(params[:noncomposite]) ? content_views.non_composite : content_views.composite if params[:noncomposite]
70
71
  content_views = ::Foreman::Cast.to_bool(params[:composite]) ? content_views.composite : content_views.non_composite if params[:composite]
71
72
  content_views = content_views.where(:name => params[:name]) if params[:name]
73
+ content_views = content_views.where(:label => params[:label]) if params[:label]
72
74
  content_views = content_views.where("#{ContentView.table_name}.id NOT IN (?)", params[:without]) if params[:without]
73
75
  content_views
74
76
  end
@@ -48,6 +48,7 @@ module Katello
48
48
  param :organization_id, :number, :desc => N_("organization identifier")
49
49
  param :library, [true, false], :desc => N_("set true if you want to see only library environments")
50
50
  param :name, String, :desc => N_("filter only environments containing this name")
51
+ param :label, String, :desc => N_("filter only environments containing this label"), :required => false
51
52
  param_group :search, Api::V2::ApiController
52
53
  add_scoped_search_description_for(KTEnvironment)
53
54
  def index
@@ -58,6 +59,7 @@ module Katello
58
59
  query = KTEnvironment.readable
59
60
  query = query.where(organization: @organization) if @organization
60
61
  query = query.where(:name => params[:name]) if params[:name]
62
+ query = query.where(:label => params[:label]) if params[:label]
61
63
  query = query.where(:library => params[:library]) if params[:library]
62
64
  query
63
65
  end
@@ -4,10 +4,10 @@ module Actions
4
4
  class Update < Actions::EntryAction
5
5
  def plan(cdn_configuration, options)
6
6
  cdn_configuration.update!(options)
7
- return if cdn_configuration.airgapped?
8
7
 
9
8
  if cdn_configuration.upstream_server?
10
9
  resource = ::Katello::Resources::CDN::CdnResource.create(cdn_configuration: cdn_configuration)
10
+ resource.validate!
11
11
  keypair = resource.debug_certificate
12
12
  cdn_configuration.ssl_cert = OpenSSL::X509::Certificate.new(keypair)
13
13
  cdn_configuration.ssl_key = OpenSSL::PKey::RSA.new(keypair)
@@ -20,7 +20,7 @@ module Actions
20
20
  roots.each do |root|
21
21
  full_path = if cdn_configuration.redhat_cdn?
22
22
  root.product.repo_url(root.library_instance.generate_content_path)
23
- else
23
+ elsif cdn_configuration.upstream_server?
24
24
  resource.repository_url(content_label: root.content.label)
25
25
  end
26
26
  plan_action(::Actions::Katello::Repository::Update, root, url: full_path)
@@ -4,8 +4,8 @@ module Katello
4
4
  class KatelloCdn < CdnResource
5
5
  def initialize(url, options)
6
6
  @organization_label = options.delete(:organization_label)
7
- @content_view_label = options.delete(:content_view_label)
8
- @lifecycle_environment_label = options.delete(:lifecycle_environment_label)
7
+ @content_view_label = options.delete(:content_view_label) || ::Katello::OrganizationCreator::DEFAULT_CONTENT_VIEW_LABEL
8
+ @lifecycle_environment_label = options.delete(:lifecycle_environment_label) || ::Katello::OrganizationCreator::DEFAULT_LIFECYCLE_ENV_LABEL
9
9
  fail ArgumentError, "No upstream organization was specified" if @organization_label.nil?
10
10
 
11
11
  super
@@ -18,16 +18,33 @@ module Katello
18
18
 
19
19
  fail _("Upstream organization %s does not provide this content path") % @organization_label if repo_set.nil?
20
20
 
21
- # now get available repositories when we know the upstream repo set ID
22
- url = "/katello/api/v2/repository_sets/#{repo_set['id']}/available_repositories?organization_id=#{organization['id']}"
21
+ params = {
22
+ full_result: true,
23
+ organization_id: organization['id'],
24
+ content_view_id: content_view_id,
25
+ environment_id: lifecycle_environment_id,
26
+ search: CGI.escape("content_label = #{repo_set['label']}")
27
+ }
28
+ query_params = params.map { |key, value| "#{key}=#{value}" }
29
+
30
+ url = "/katello/api/v2/repositories?#{query_params.join("&")}"
23
31
  response = get(url)
24
32
  json_body = JSON.parse(response)
25
33
  results = json_body['results']
26
34
 
27
- results.map do |r|
35
+ results.map do |repo|
36
+ arch = repo['arch']
37
+ arch = nil if arch == "noarch"
38
+ substitutions = {
39
+ :releasever => repo['minor'],
40
+ :basearch => arch
41
+ }.compact
42
+ path = substitutions.inject(content_path) do |path_url, (key, value)|
43
+ path_url.gsub("$#{key}", value)
44
+ end
28
45
  {
29
- path: r['path'],
30
- substitutions: r['substitutions']
46
+ path: path,
47
+ substitutions: substitutions
31
48
  }
32
49
  end
33
50
  end
@@ -36,12 +53,16 @@ module Katello
36
53
  true
37
54
  end
38
55
 
56
+ def validate!
57
+ organization && content_view_id && lifecycle_environment_id
58
+ end
59
+
39
60
  def debug_certificate
40
61
  get("/katello/api/v2/organizations/#{organization['id']}/download_debug_certificate")
41
62
  end
42
63
 
43
64
  def content_view_id
44
- rs = get("/katello/api/v2/organizations/#{organization['id']}/content_views?name=#{CGI.escape(@content_view_label)}")
65
+ rs = get("/katello/api/v2/organizations/#{organization['id']}/content_views?search=#{CGI.escape("label=#{@content_view_label}")}")
45
66
  content_view = JSON.parse(rs)['results']&.first
46
67
  if content_view.blank?
47
68
  fail _("Upstream organization %{org_label} does not have a content view with the label %{cv_label}") % { org_label: @organization_label,
@@ -51,7 +72,7 @@ module Katello
51
72
  end
52
73
 
53
74
  def lifecycle_environment_id
54
- rs = get("/katello/api/v2/organizations/#{organization['id']}/environments")
75
+ rs = get("/katello/api/v2/organizations/#{organization['id']}/environments?full_result=true")
55
76
  env = JSON.parse(rs)['results'].find { |lce| lce['label'] == @lifecycle_environment_label }
56
77
 
57
78
  if env.blank?
@@ -61,7 +82,7 @@ module Katello
61
82
  env["id"]
62
83
  end
63
84
 
64
- def repository_url(content_label:)
85
+ def repository_url(content_label:, arch:, major:, minor:)
65
86
  params = {
66
87
  search: CGI.escape("content_label = #{content_label}")
67
88
  }
@@ -72,17 +93,19 @@ module Katello
72
93
  query_params = params.map { |key, value| "#{key}=#{value}" }
73
94
  url = "/katello/api/v2/organizations/#{organization['id']}/repositories?#{query_params.join('&')}"
74
95
  response = get(url)
75
- repository = JSON.parse(response)['results'].first
76
-
96
+ repository = JSON.parse(response)['results']&.find { |r| r['arch'] == arch && r['major'] == major && r['minor'] == minor }
77
97
  if repository.nil?
78
98
  msg_params = { content_label: content_label,
99
+ arch: arch,
100
+ major: major,
101
+ minor: minor,
79
102
  org_label: @organization_label,
80
103
  cv_label: @content_view_label || Katello::OrganizationCreator::DEFAULT_CONTENT_VIEW_LABEL,
81
104
  env_label: @lifecycle_environment_label || Katello::OrganizationCreator::DEFAULT_LIFECYCLE_ENV_LABEL
82
105
  }
83
106
 
84
- fail _("Repository with content label %{content_label} was not found in upstream organization %{org_label},"\
85
- " content view %{cv_label} and lifecycle environment %{env_label} ") % msg_params
107
+ fail _("Repository with content label: '%{content_label}'#{arch ? ', arch: \'%{arch}\'' : ''}#{minor ? ', version: \'%{minor}\'' : ''} was not found in upstream organization '%{org_label}',"\
108
+ " content view '%{cv_label}' and lifecycle environment '%{env_label}'") % msg_params
86
109
  end
87
110
  repository['full_path']
88
111
  end
@@ -34,7 +34,7 @@ module Katello
34
34
  :content_type => katello_content_type,
35
35
  :unprotected => unprotected?,
36
36
  :download_policy => download_policy,
37
- :mirroring_policy => Katello::RootRepository::MIRRORING_POLICY_COMPLETE
37
+ :mirroring_policy => mirroring_policy
38
38
  )
39
39
 
40
40
  Repository.new(:root => root,
@@ -76,7 +76,7 @@ module Katello
76
76
  def feed_url
77
77
  return if product.organization.cdn_configuration.airgapped?
78
78
  @feed_url ||= if product.cdn_resource&.respond_to?(:repository_url)
79
- product.cdn_resource.repository_url(content_label: content.label)
79
+ product.cdn_resource.repository_url(content_label: content.label, arch: arch, major: version[:major], minor: version[:minor])
80
80
  else
81
81
  product.repo_url(path)
82
82
  end
@@ -137,6 +137,14 @@ module Katello
137
137
  ""
138
138
  end
139
139
  end
140
+
141
+ def mirroring_policy
142
+ if katello_content_type == Repository::YUM_TYPE
143
+ Katello::RootRepository::MIRRORING_POLICY_COMPLETE
144
+ else
145
+ Katello::RootRepository::MIRRORING_POLICY_CONTENT
146
+ end
147
+ end
140
148
  end
141
149
  end
142
150
  end
@@ -53,6 +53,8 @@ module Katello
53
53
  self.ssl_ca_credential_id = nil
54
54
  self.upstream_content_view_label = nil
55
55
  self.upstream_lifecycle_environment_label = nil
56
+ self.ssl_cert = nil
57
+ self.ssl_key = nil
56
58
  end
57
59
 
58
60
  def non_redhat_configuration
@@ -75,6 +75,7 @@ module Katello
75
75
  ERROR_CLASS_NAME = "Environment".freeze
76
76
 
77
77
  scoped_search :on => :name, :complete_value => true
78
+ scoped_search :on => :label, :complete_value => true
78
79
  scoped_search :on => :organization_id, :complete_value => true, :only_explicit => true, :validator => ScopedSearch::Validators::INTEGER
79
80
  scoped_search :on => :id, :complete_value => true, :only_explicit => true, :validator => ScopedSearch::Validators::INTEGER
80
81
 
@@ -133,11 +133,15 @@ module Katello
133
133
  end
134
134
 
135
135
  def create_cdn_configuration
136
- @cdn_configuration = Katello::CdnConfiguration.where(
137
- organization: @organization,
138
- url: ::Katello::Resources::CDN::CdnResource.redhat_cdn_url,
139
- type: ::Katello::CdnConfiguration::CDN_TYPE
140
- ).first_or_create!
136
+ @cdn_configuration = Katello::CdnConfiguration.where(organization: @organization)
137
+
138
+ if @cdn_configuration.blank?
139
+ Katello::CdnConfiguration.where(
140
+ organization: @organization,
141
+ url: ::Katello::Resources::CDN::CdnResource.redhat_cdn_url,
142
+ type: ::Katello::CdnConfiguration::CDN_TYPE
143
+ ).first_or_create!
144
+ end
141
145
  end
142
146
  end
143
147
  end
@@ -297,6 +297,7 @@ module Katello
297
297
  host.content_facet.applicable_errata = []
298
298
  host.content_facet.uuid = nil
299
299
  host.content_facet.save!
300
+ host.content_facet.calculate_and_import_applicability
300
301
  end
301
302
 
302
303
  host.get_status(::Katello::ErrataStatus).destroy
@@ -48,8 +48,8 @@ glue(@resource.root) do
48
48
  attributes :id => @resource.root&.ssl_client_key&.id, :name => @resource.root&.ssl_client_key&.name
49
49
  end
50
50
 
51
- child :gpg_key do
52
- attributes :id, :name
51
+ node :gpg_key do
52
+ attributes :id => @resource.root&.gpg_key&.id, :name => @resource.root&.gpg_key&.name
53
53
  end
54
54
  end
55
55
 
@@ -1,16 +1,10 @@
1
1
  class AddTypeToCdnConfiguration < ActiveRecord::Migration[6.0]
2
2
  def change
3
+ add_index :katello_cdn_configurations, :organization_id, unique: true
3
4
  add_column :katello_cdn_configurations, :type, :string, default: ::Katello::CdnConfiguration::CDN_TYPE
4
5
 
5
6
  ::Katello::CdnConfiguration.reset_column_information
6
7
  ::Katello::CdnConfiguration.all.each do |config|
7
- unless Setting[:subscription_connection_enabled]
8
- # if subscription connection is not enabled
9
- # the user most likely wants the type to be airgapped
10
- config.update!(type: ::Katello::CdnConfiguration::AIRGAPPED_TYPE)
11
- next
12
- end
13
-
14
8
  unless config.username.blank? ||
15
9
  config.password.blank? ||
16
10
  config.upstream_organization_label.blank? ||
@@ -0,0 +1,34 @@
1
+ class RemoveDuplicateErrata < ActiveRecord::Migration[6.0]
2
+ def up
3
+ #Update all unique errata records to have pulp_id = errata_id
4
+ ::Katello::Erratum.group(:errata_id).having("count(errata_id) = 1").pluck(:errata_id).each do |original_errata_id|
5
+ erratum = ::Katello::Erratum.find_by(errata_id: original_errata_id)
6
+ if (erratum.pulp_id != erratum.errata_id)
7
+ erratum.pulp_id = erratum.errata_id
8
+ erratum.save!
9
+ end
10
+ end
11
+
12
+ #For duplicate errata,
13
+ # a) update all RepositoryErrata to point to unique errata,
14
+ # b) if repo-errata association for that combination exists, delete duplicate errata association
15
+ # c) Delete all duplicate errata
16
+ ::Katello::Erratum.group(:errata_id).having("count(errata_id) > 1").pluck(:errata_id).each do |original_errata_id|
17
+ errata_to_keep = ::Katello::Erratum.find_by(pulp_id: original_errata_id)
18
+ errata_all = ::Katello::Erratum.where(errata_id: original_errata_id)
19
+ dup_errata = errata_all - [errata_to_keep]
20
+ ::Katello::RepositoryErratum.where(erratum_id: dup_errata&.map(&:id)).each do |repo_erratum|
21
+ if ::Katello::RepositoryErratum.find_by(repository_id: repo_erratum.repository_id, erratum_id: errata_to_keep.id)
22
+ repo_erratum.delete
23
+ else
24
+ repo_erratum.update(erratum_id: errata_to_keep.id)
25
+ end
26
+ end
27
+ ::Katello::Erratum.delete(dup_errata&.pluck(:id))
28
+ end
29
+ end
30
+
31
+ def down
32
+ fail ActiveRecord::IrreversibleMigration
33
+ end
34
+ end
@@ -39,7 +39,7 @@
39
39
 
40
40
  <span data-block="no-rows-message">
41
41
  <span ng-if="isState('sync-plan.products.list')" translate>
42
- No products are have been added to this Sync Plan.
42
+ No products have been added to this Sync Plan.
43
43
  </span>
44
44
  <span ng-if="isState('sync-plan.products.add')" translate>
45
45
  No products are available to add to this Sync Plan.
@@ -0,0 +1,20 @@
1
+ namespace :katello do
2
+ desc "Migrate deb content attributes to Pulp3"
3
+ task :migrate_deb_content_attributes_to_pulp3 => ["environment", "check_ping"] do
4
+ User.current = User.anonymous_api_admin
5
+ repos = Katello::Repository.deb_type.where(library_instance_id: nil)
6
+
7
+ repos.find_each.with_index do |repo, index|
8
+ puts "Processing Repository #{index + 1}/#{repos.count}: #{repo.name} (#{repo.id})"
9
+ begin
10
+ ForemanTasks.sync_task(::Actions::Katello::Repository::Update, repo.root,
11
+ download_policy: 'immediate',
12
+ deb_architectures: repo.root.deb_architectures&.gsub(',', ' '),
13
+ deb_releases: repo.root.deb_releases&.gsub(',', ' ') || 'stable',
14
+ deb_components: repo.root.deb_components&.gsub(',', ' '))
15
+ rescue => e
16
+ puts "Failed to update repository #{repo.name} (#{repo.id}): #{e.message}"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module Katello
2
- VERSION = "4.4.0.rc2".freeze
2
+ VERSION = "4.4.0".freeze
3
3
  end
@@ -1,33 +1,18 @@
1
1
  import React from 'react';
2
2
  import { shape, string, number, element, arrayOf } from 'prop-types';
3
3
  import { Tab, Tabs, TabTitleText } from '@patternfly/react-core';
4
- import { Switch, Route, Redirect, useHistory, useLocation, withRouter, HashRouter } from 'react-router-dom';
4
+ import { Switch, Route, Redirect, useLocation, withRouter, HashRouter } from 'react-router-dom';
5
5
  import { head, last } from 'lodash';
6
6
 
7
7
  const RoutedTabs = ({
8
8
  tabs, defaultTabIndex,
9
9
  }) => {
10
- const { push } = useHistory();
11
10
  const {
12
11
  hash, key: locationKey,
13
12
  } = useLocation();
14
13
 
15
14
  // The below transforms #/history/6 to history
16
15
  const currentTabFromUrl = head(last(hash.split('#/')).split('/'));
17
- // Allows navigation back to mainTab
18
- const onSubTab = currentTabFromUrl !== last(last(hash.split('#/')).split('/'));
19
-
20
- const onSelect = (e, key) => {
21
- e.preventDefault();
22
- // See the below links for understanding of this mouseEvent
23
- // https://www.w3schools.com/jsref/event_which.asp
24
- // https://www.w3schools.com/jsref/event_button.asp
25
- const middleMouseButtonNotUsed = !(e.button === 1 || e.buttons === 4 || e.which === 2);
26
- const notCurrentTab = currentTabFromUrl !== key;
27
- if (middleMouseButtonNotUsed && (notCurrentTab || !!onSubTab)) {
28
- push(`#/${key}`);
29
- }
30
- };
31
16
 
32
17
  return (
33
18
  <>
@@ -39,7 +24,6 @@ const RoutedTabs = ({
39
24
  <a
40
25
  key={key}
41
26
  href={`#/${key}`}
42
- onMouseUp={e => onSelect(e, key)}
43
27
  style={{ textDecoration: 'none' }}
44
28
  >
45
29
  <Tab
@@ -15,6 +15,7 @@ import { translate as __ } from 'foremanReact/common/I18n';
15
15
  import { propsToCamelCase } from 'foremanReact/common/helpers';
16
16
  import PropTypes from 'prop-types';
17
17
  import ContentViewIcon from '../../../../scenes/ContentViews/components/ContentViewIcon';
18
+ import { hostIsRegistered } from '../hostDetailsHelpers';
18
19
 
19
20
  const HostContentViewDetails = ({
20
21
  contentView, lifecycleEnvironment, contentViewVersionId,
@@ -61,7 +62,7 @@ const HostContentViewDetails = ({
61
62
  };
62
63
 
63
64
  const ContentViewDetailsCard = ({ hostDetails }) => {
64
- if (hostDetails.content_facet_attributes) {
65
+ if (hostIsRegistered({ hostDetails }) && hostDetails.content_facet_attributes) {
65
66
  return <HostContentViewDetails {...propsToCamelCase(hostDetails.content_facet_attributes)} />;
66
67
  }
67
68
  return null;
@@ -13,6 +13,7 @@ import { propsToCamelCase } from 'foremanReact/common/helpers';
13
13
  import PropTypes from 'prop-types';
14
14
  import { ChartPie } from '@patternfly/react-charts';
15
15
  import { ErrataMapper } from '../../../../components/Errata';
16
+ import { hostIsRegistered } from '../hostDetailsHelpers';
16
17
 
17
18
  function HostInstallableErrata({
18
19
  id, errataCounts,
@@ -74,7 +75,7 @@ function HostInstallableErrata({
74
75
  }
75
76
 
76
77
  const ErrataOverviewCard = ({ hostDetails }) => {
77
- if (hostDetails.content_facet_attributes) {
78
+ if (hostIsRegistered({ hostDetails }) && hostDetails.content_facet_attributes) {
78
79
  const { id: hostId } = hostDetails;
79
80
  return (<HostInstallableErrata
80
81
  {...propsToCamelCase(hostDetails.content_facet_attributes)}
@@ -2,48 +2,47 @@ import React from 'react';
2
2
  import { render } from 'react-testing-lib-wrapper';
3
3
  import ContentViewDetailsCard from '../ContentViewDetailsCard';
4
4
 
5
- test('shows host details when content facet is set', () => {
6
- const hostDetails = {
7
- content_facet_attributes: {
8
- content_view: {
9
- name: 'CV',
10
- id: 100,
11
- composite: false,
12
- },
13
- lifecycle_environment: {
14
- name: 'ENV',
15
- id: 300,
16
- },
17
- content_view_version_id: 1000,
18
- content_view_version: '1.0',
19
- content_view_version_latest: true,
5
+ const baseHostDetails = {
6
+ content_facet_attributes: {
7
+ content_view: {
8
+ name: 'CV',
9
+ id: 100,
10
+ composite: false,
20
11
  },
21
- };
22
- const { getByText } = render(<ContentViewDetailsCard hostDetails={hostDetails} />);
12
+ lifecycle_environment: {
13
+ name: 'ENV',
14
+ id: 300,
15
+ },
16
+ content_view_version_id: 1000,
17
+ content_view_version: '1.0',
18
+ content_view_version_latest: true,
19
+ },
20
+ subscription_facet_attributes: {
21
+ uuid: '123',
22
+ },
23
+ };
24
+
25
+ test('shows content view details when host is registered', () => {
26
+ const { getByText } = render(<ContentViewDetailsCard hostDetails={baseHostDetails} />);
23
27
  expect(getByText('Version 1.0 (latest)')).toBeInTheDocument();
24
28
  });
25
29
 
26
30
 
27
- test('doesnot show host details when content facet is not set', () => {
28
- const { queryByText } = render(<ContentViewDetailsCard />);
31
+ test('does not show content view details when host is not registered', () => {
32
+ const hostDetails = {
33
+ ...baseHostDetails,
34
+ subscription_facet_attributes: undefined,
35
+ };
36
+ const { queryByText } = render(<ContentViewDetailsCard hostDetails={hostDetails} />);
29
37
  expect(queryByText('Version 1.0')).toBeNull();
30
38
  });
31
39
 
32
40
 
33
- test('shows host details not latest', () => {
41
+ test('shows when the CV in use is not the latest version', () => {
34
42
  const hostDetails = {
43
+ ...baseHostDetails,
35
44
  content_facet_attributes: {
36
- content_view: {
37
- name: 'CV',
38
- id: 100,
39
- composite: false,
40
- },
41
- lifecycle_environment: {
42
- name: 'ENV',
43
- id: 300,
44
- },
45
- content_view_version_id: 1000,
46
- content_view_version: '1.0',
45
+ ...baseHostDetails.content_facet_attributes,
47
46
  content_view_version_latest: false,
48
47
  },
49
48
  };
@@ -3,6 +3,13 @@ import { render } from 'react-testing-lib-wrapper';
3
3
  import ErrataOverviewCard from '../ErrataOverviewCard';
4
4
  import nock from '../../../../../test-utils/nockWrapper';
5
5
 
6
+ const baseHostDetails = {
7
+ id: 2,
8
+ subscription_facet_attributes: {
9
+ uuid: '123',
10
+ },
11
+ };
12
+
6
13
  describe('Without errata', () => {
7
14
  afterEach(() => {
8
15
  nock.cleanAll();
@@ -10,7 +17,7 @@ describe('Without errata', () => {
10
17
 
11
18
  test('does not show piechart when there are 0 errata', () => {
12
19
  const hostDetails = {
13
- id: 2,
20
+ ...baseHostDetails,
14
21
  content_facet_attributes: {
15
22
  errata_counts: {
16
23
  bugfix: 0,
@@ -26,6 +33,26 @@ describe('Without errata', () => {
26
33
  expect(queryByLabelText('errataChart')).not.toBeInTheDocument();
27
34
  expect(getByText('0 errata')).toBeInTheDocument();
28
35
  });
36
+
37
+ test('does not show errata card when host not registered', () => {
38
+ const hostDetails = {
39
+ ...baseHostDetails,
40
+ content_facet_attributes: {
41
+ errata_counts: {
42
+ bugfix: 0,
43
+ enhancement: 0,
44
+ security: 0,
45
+ total: 0,
46
+ },
47
+ },
48
+ subscription_facet_attributes: undefined,
49
+ };
50
+ /* eslint-disable max-len */
51
+ const { queryByLabelText, queryByText } = render(<ErrataOverviewCard hostDetails={hostDetails} />);
52
+ /* eslint-enable max-len */
53
+ expect(queryByLabelText('errataChart')).not.toBeInTheDocument();
54
+ expect(queryByText('0 errata')).not.toBeInTheDocument();
55
+ });
29
56
  });
30
57
 
31
58
  describe('With errata', () => {
@@ -33,9 +60,9 @@ describe('With errata', () => {
33
60
  nock.cleanAll();
34
61
  });
35
62
 
36
- test('show piechart when there are errata', () => {
63
+ test('shows piechart when there are errata', () => {
37
64
  const hostDetails = {
38
- id: 2,
65
+ ...baseHostDetails,
39
66
  content_facet_attributes: {
40
67
  errata_counts: {
41
68
  bugfix: 10,
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Route, Switch, Redirect } from 'react-router-dom';
3
- import { PackagesTab } from '../PackagesTab';
3
+ import { PackagesTab } from '../PackagesTab/PackagesTab.js';
4
4
  import { ErrataTab } from '../ErrataTab/ErrataTab.js';
5
5
  import { ModuleStreamsTab } from '../ModuleStreamsTab/ModuleStreamsTab';
6
6
  import { route } from './helpers';
@@ -33,7 +33,7 @@ import { installErrata } from '../RemoteExecutionActions';
33
33
  import { errataInstallUrl } from '../customizedRexUrlHelpers';
34
34
  import './ErrataTab.scss';
35
35
  import hostIdNotReady from '../../HostDetailsActions';
36
- import defaultRemoteActionMethod, { KATELLO_AGENT } from '../../hostDetailsHelpers';
36
+ import { defaultRemoteActionMethod, KATELLO_AGENT } from '../../hostDetailsHelpers';
37
37
 
38
38
  export const ErrataTab = () => {
39
39
  const hostDetails = useSelector(state => selectAPIResponse(state, 'HOST_DETAILS'));
@@ -1,7 +1,7 @@
1
1
  import { API_OPERATIONS, get, put } from 'foremanReact/redux/API';
2
- import { renderTaskStartedToast } from '../../../../scenes/Tasks/helpers';
3
- import { foremanApi } from '../../../../services/api';
4
- import { getResponseErrorMsgs } from '../../../../utils/helpers';
2
+ import { renderTaskStartedToast } from '../../../../../scenes/Tasks/helpers';
3
+ import { foremanApi } from '../../../../../services/api';
4
+ import { getResponseErrorMsgs } from '../../../../../utils/helpers';
5
5
  import {
6
6
  HOST_PACKAGES_INSTALL_KEY,
7
7
  HOST_PACKAGES_KEY,
@@ -9,16 +9,16 @@ import { translate as __ } from 'foremanReact/common/I18n';
9
9
  import { urlBuilder } from 'foremanReact/common/urlHelpers';
10
10
  import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
11
11
  import PropTypes from 'prop-types';
12
- import TableWrapper from '../../../Table/TableWrapper';
13
- import { useBulkSelect } from '../../../Table/TableHooks';
14
- import { HOST_YUM_INSTALLABLE_PACKAGES_KEY } from '../YumInstallablePackages/YumInstallablePackagesConstants';
15
- import { selectHostYumInstallablePackagesStatus } from '../YumInstallablePackages/YumInstallablePackagesSelectors';
16
- import { getHostYumInstallablePackages } from '../YumInstallablePackages/YumInstallablePackagesActions';
12
+ import TableWrapper from '../../../../Table/TableWrapper';
13
+ import { useBulkSelect } from '../../../../Table/TableHooks';
14
+ import { HOST_YUM_INSTALLABLE_PACKAGES_KEY } from './YumInstallablePackagesConstants';
15
+ import { selectHostYumInstallablePackagesStatus } from './YumInstallablePackagesSelectors';
16
+ import { getHostYumInstallablePackages } from './YumInstallablePackagesActions';
17
17
  import './PackageInstallModal.scss';
18
- import { installPackageBySearch } from './RemoteExecutionActions';
19
- import { katelloPackageInstallBySearchUrl, katelloPackageInstallUrl } from './customizedRexUrlHelpers';
20
- import hostIdNotReady from '../HostDetailsActions';
21
- import { installPackageViaKatelloAgent } from '../HostPackages/HostPackagesActions';
18
+ import { installPackageBySearch } from '../RemoteExecutionActions';
19
+ import { katelloPackageInstallBySearchUrl, katelloPackageInstallUrl } from '../customizedRexUrlHelpers';
20
+ import hostIdNotReady from '../../HostDetailsActions';
21
+ import { installPackageViaKatelloAgent } from './HostPackagesActions';
22
22
 
23
23
  const InstallDropdown = ({
24
24
  isDisabled, installViaRex, installViaKatelloAgent,
@@ -18,26 +18,26 @@ import { translate as __ } from 'foremanReact/common/I18n';
18
18
  import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
19
19
 
20
20
  import { urlBuilder } from 'foremanReact/common/urlHelpers';
21
- import { useBulkSelect } from '../../../../components/Table/TableHooks';
22
- import SelectableDropdown from '../../../SelectableDropdown';
23
- import TableWrapper from '../../../../components/Table/TableWrapper';
24
- import { PackagesStatus, PackagesLatestVersion } from '../../../../components/Packages';
21
+ import SelectableDropdown from '../../../../SelectableDropdown';
22
+ import TableWrapper from '../../../../../components/Table/TableWrapper';
23
+ import { useBulkSelect } from '../../../../../components/Table/TableHooks';
24
+ import { PackagesStatus, PackagesLatestVersion } from '../../../../../components/Packages';
25
25
  import {
26
26
  getInstalledPackagesWithLatest,
27
27
  removePackageViaKatelloAgent,
28
28
  upgradeAllViaKatelloAgent,
29
29
  upgradePackageViaKatelloAgent,
30
- } from '../HostPackages/HostPackagesActions';
31
- import { selectHostPackagesStatus } from '../HostPackages/HostPackagesSelectors';
30
+ } from './HostPackagesActions';
31
+ import { selectHostPackagesStatus } from './HostPackagesSelectors';
32
32
  import {
33
33
  HOST_PACKAGES_KEY, PACKAGES_VERSION_STATUSES, VERSION_STATUSES_TO_PARAM,
34
- } from '../HostPackages/HostPackagesConstants';
35
- import { removePackage, updatePackage, removePackages, updatePackages } from './RemoteExecutionActions';
36
- import { katelloPackageUpdateUrl, packagesUpdateUrl } from './customizedRexUrlHelpers';
34
+ } from './HostPackagesConstants';
35
+ import { removePackage, updatePackage, removePackages, updatePackages } from '../RemoteExecutionActions';
36
+ import { katelloPackageUpdateUrl, packagesUpdateUrl } from '../customizedRexUrlHelpers';
37
37
  import './PackagesTab.scss';
38
- import hostIdNotReady from '../HostDetailsActions';
38
+ import hostIdNotReady from '../../HostDetailsActions';
39
39
  import PackageInstallModal from './PackageInstallModal';
40
- import defaultRemoteActionMethod, { KATELLO_AGENT } from '../hostDetailsHelpers';
40
+ import { defaultRemoteActionMethod, KATELLO_AGENT } from '../../hostDetailsHelpers';
41
41
 
42
42
  export const PackagesTab = () => {
43
43
  const hostDetails = useSelector(state => selectAPIResponse(state, 'HOST_DETAILS'));
@@ -1,5 +1,5 @@
1
1
  import { API_OPERATIONS, get } from 'foremanReact/redux/API';
2
- import katelloApi from '../../../../services/api';
2
+ import katelloApi from '../../../../../services/api';
3
3
  import { HOST_YUM_INSTALLABLE_PACKAGES_KEY } from './YumInstallablePackagesConstants';
4
4
 
5
5
  export const getHostYumInstallablePackages = (hostId, params) => get({
@@ -5,8 +5,8 @@ import { getResponseErrorMsgs } from '../../../../utils/helpers';
5
5
  import { renderTaskStartedToast } from '../../../../scenes/Tasks/helpers';
6
6
  import { ERRATA_SEARCH_QUERY } from './ErrataTab/HostErrataConstants';
7
7
  import { TRACES_SEARCH_QUERY } from './TracesTab/HostTracesConstants';
8
- import { PACKAGE_SEARCH_QUERY } from '../YumInstallablePackages/YumInstallablePackagesConstants';
9
- import { PACKAGES_SEARCH_QUERY } from '../HostPackages/HostPackagesConstants';
8
+ import { PACKAGE_SEARCH_QUERY } from './PackagesTab/YumInstallablePackagesConstants';
9
+ import { PACKAGES_SEARCH_QUERY } from './PackagesTab/HostPackagesConstants';
10
10
 
11
11
  const errorToast = (error) => {
12
12
  const message = getResponseErrorMsgs(error.response);
@@ -3,8 +3,8 @@ import { renderWithRedux, patientlyWaitFor, fireEvent, within } from 'react-test
3
3
  import { nockInstance, assertNockRequest, mockForemanAutocomplete, mockSetting } from '../../../../../test-utils/nockWrapper';
4
4
  import katelloApi, { foremanApi } from '../../../../../services/api';
5
5
  import mockPackagesData from './yumInstallablePackages.fixtures.json';
6
- import PackageInstallModal from '../PackageInstallModal';
7
- import { HOST_YUM_INSTALLABLE_PACKAGES_KEY, PACKAGE_SEARCH_QUERY } from '../../YumInstallablePackages/YumInstallablePackagesConstants';
6
+ import PackageInstallModal from '../PackagesTab/PackageInstallModal';
7
+ import { HOST_YUM_INSTALLABLE_PACKAGES_KEY, PACKAGE_SEARCH_QUERY } from '../PackagesTab/YumInstallablePackagesConstants';
8
8
  import { REX_FEATURES } from '../RemoteExecutionConstants';
9
9
 
10
10
  const contentFacetAttributes = {
@@ -2,8 +2,8 @@ import React from 'react';
2
2
  import { renderWithRedux, patientlyWaitFor, fireEvent } from 'react-testing-lib-wrapper';
3
3
  import { nockInstance, assertNockRequest, mockForemanAutocomplete, mockSetting } from '../../../../../test-utils/nockWrapper';
4
4
  import { foremanApi } from '../../../../../services/api';
5
- import { HOST_PACKAGES_KEY, PACKAGES_SEARCH_QUERY } from '../../HostPackages/HostPackagesConstants';
6
- import { PackagesTab } from '../PackagesTab';
5
+ import { HOST_PACKAGES_KEY, PACKAGES_SEARCH_QUERY } from '../PackagesTab/HostPackagesConstants';
6
+ import { PackagesTab } from '../PackagesTab/PackagesTab.js';
7
7
  import mockPackagesData from './packages.fixtures.json';
8
8
  import { REX_FEATURES } from '../RemoteExecutionConstants';
9
9
 
@@ -1,8 +1,8 @@
1
1
  import { REX_FEATURES } from './RemoteExecutionConstants';
2
2
  import { TRACES_SEARCH_QUERY } from './TracesTab/HostTracesConstants';
3
3
  import { ERRATA_SEARCH_QUERY } from './ErrataTab/HostErrataConstants';
4
- import { PACKAGE_SEARCH_QUERY } from '../YumInstallablePackages/YumInstallablePackagesConstants';
5
- import { PACKAGES_SEARCH_QUERY } from '../HostPackages/HostPackagesConstants';
4
+ import { PACKAGE_SEARCH_QUERY } from './PackagesTab/YumInstallablePackagesConstants';
5
+ import { PACKAGES_SEARCH_QUERY } from './PackagesTab/HostPackagesConstants';
6
6
 
7
7
  export const createJob = ({
8
8
  hostname, feature, inputs,
@@ -3,7 +3,7 @@ import { propsToCamelCase } from 'foremanReact/common/helpers';
3
3
  export const REMOTE_EXECUTION = 'remoteExecution';
4
4
  export const KATELLO_AGENT = 'katelloAgent';
5
5
 
6
- const defaultRemoteActionMethod = ({ hostDetails }) => {
6
+ export const defaultRemoteActionMethod = ({ hostDetails }) => {
7
7
  const {
8
8
  content_facet_attributes: contentFacetAttributes,
9
9
  } = hostDetails;
@@ -16,4 +16,13 @@ const defaultRemoteActionMethod = ({ hostDetails }) => {
16
16
  return KATELLO_AGENT;
17
17
  };
18
18
 
19
+ export const hostIsNotRegistered = ({ hostDetails }) => {
20
+ const {
21
+ subscription_facet_attributes: subscriptionFacetAttributes,
22
+ } = hostDetails;
23
+ return !subscriptionFacetAttributes?.uuid;
24
+ };
25
+
26
+ export const hostIsRegistered = ({ hostDetails }) => !hostIsNotRegistered({ hostDetails });
27
+
19
28
  export default defaultRemoteActionMethod;
@@ -14,17 +14,18 @@ import RepositorySetsTab from './components/extensions/HostDetails/Tabs/Reposito
14
14
  import TracesTab from './components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js';
15
15
  import extendReducer from './components/extensions/reducers';
16
16
  import rootReducer from './redux/reducers';
17
+ import { hostIsNotRegistered } from './components/extensions/HostDetails/hostDetailsHelpers';
17
18
 
18
19
  registerReducer('katelloExtends', extendReducer);
19
20
  registerReducer('katello', rootReducer);
20
21
 
21
22
  addGlobalFill('aboutFooterSlot', '[katello]AboutSystemStatuses', <SystemStatuses key="katello-system-statuses" />, 100);
22
23
  addGlobalFill('registrationAdvanced', '[katello]RegistrationCommands', <RegistrationCommands key="katello-reg" />, 100);
23
- addGlobalFill('host-details-page-tabs', 'Content', <ContentTab key="content" />, 900, { title: __('Content') });
24
+ addGlobalFill('host-details-page-tabs', 'Content', <ContentTab key="content" />, 900, { title: __('Content'), hideTab: hostIsNotRegistered });
24
25
  /* eslint-disable max-len */
25
26
  // addGlobalFill('host-details-page-tabs', 'Subscription', <SubscriptionTab key="subscription" />, 100, { title: __('Subscription') });
26
- addGlobalFill('host-details-page-tabs', 'Traces', <TracesTab key="traces" />, 800, { title: __('Traces') });
27
- addGlobalFill('host-details-page-tabs', 'Repository sets', <RepositorySetsTab key="repository-sets" />, 700, { title: __('Repository sets') });
27
+ addGlobalFill('host-details-page-tabs', 'Traces', <TracesTab key="traces" />, 800, { title: __('Traces'), hideTab: hostIsNotRegistered });
28
+ addGlobalFill('host-details-page-tabs', 'Repository sets', <RepositorySetsTab key="repository-sets" />, 700, { title: __('Repository sets'), hideTab: hostIsNotRegistered });
28
29
 
29
30
  addGlobalFill(
30
31
  'details-cards',
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
2
2
  import { useDispatch } from 'react-redux';
3
3
  import PropTypes from 'prop-types';
4
4
  import {
5
+ Button,
5
6
  Grid,
6
7
  GridItem,
7
8
  TextContent,
@@ -12,7 +13,7 @@ import {
12
13
  FlexItem,
13
14
  Dropdown,
14
15
  DropdownItem,
15
- DropdownToggle,
16
+ KebabToggle,
16
17
  DropdownPosition,
17
18
  } from '@patternfly/react-core';
18
19
  import { translate as __ } from 'foremanReact/common/I18n';
@@ -43,14 +44,6 @@ const ContentViewVersionDetailsHeader = ({
43
44
  const [currentStep, setCurrentStep] = useState(1);
44
45
  const [deleteVersion, setDeleteVersion] = useState(false);
45
46
  const dropDownItems = [
46
- <DropdownItem
47
- key="promote"
48
- onClick={() => {
49
- setPromoting(true);
50
- }}
51
- >
52
- {__('Promote')}
53
- </DropdownItem>,
54
47
  <DropdownItem
55
48
  key="remove"
56
49
  onClick={() => {
@@ -73,23 +66,26 @@ const ContentViewVersionDetailsHeader = ({
73
66
 
74
67
  return (
75
68
  <Grid className="margin-0-24">
76
- <GridItem span={10}>
69
+ <GridItem sm={6} >
77
70
  <TextContent>
78
71
  <Text component={TextVariants.h2}>{__('Version ')}{version}</Text>
79
72
  </TextContent>
80
73
  </GridItem>
81
- <GridItem span={2} style={{ display: 'flex' }}>
74
+ <GridItem sm={6} style={{ display: 'flex' }}>
75
+ <Button
76
+ style={{ marginLeft: 'auto' }}
77
+ onClick={() => setPromoting(true)}
78
+ variant="primary"
79
+ aria-label="publish_content_view"
80
+ >
81
+ {__('Promote')}
82
+ </Button>
82
83
  <Dropdown
83
- aria-label="version-action-dropdown"
84
+ isPlain
85
+ style={{ width: 'inherit' }}
84
86
  position={DropdownPosition.right}
85
- style={{ marginLeft: 'auto' }}
86
87
  toggle={
87
- <DropdownToggle
88
- onToggle={setDropdownOpen}
89
- id="toggle-id"
90
- >
91
- {__('Actions')}
92
- </DropdownToggle>
88
+ <KebabToggle onToggle={setDropdownOpen} id="toggle-dropdown" />
93
89
  }
94
90
  isOpen={dropdownOpen}
95
91
  dropdownItems={dropDownItems}
@@ -87,8 +87,9 @@ const UpstreamServerTypeForm = ({
87
87
  password,
88
88
  upstream_organization_label: organizationLabel,
89
89
  ssl_ca_credential_id: sslCaCredentialId,
90
- upstream_content_view_label: contentViewLabel,
91
- upstream_lifecycle_environment_label: lifecycleEnvironmentLabel,
90
+ upstream_content_view_label: contentViewLabel || DEFAULT_CONTENT_VIEW_LABEL,
91
+ upstream_lifecycle_environment_label: lifecycleEnvironmentLabel ||
92
+ DEFAULT_LIFECYCLE_ENVIRONMENT_LABEL,
92
93
  type: UPSTREAM_SERVER,
93
94
  }, onUpdate, onError));
94
95
  };
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katello
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.0.rc2
4
+ version: 4.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - N/A
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-03 00:00:00.000000000 Z
11
+ date: 2022-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -2181,6 +2181,7 @@ files:
2181
2181
  - db/migrate/20220204171908_rename_docker_tags_whitelist_and_add_exclude_tags.rb
2182
2182
  - db/migrate/20220207140355_change_deb_attributes_size_limit.rb
2183
2183
  - db/migrate/20220209205137_expand_sync_timeout_settings.rb
2184
+ - db/migrate/20220303160220_remove_duplicate_errata.rb
2184
2185
  - db/seeds.d/101-locations.rb
2185
2186
  - db/seeds.d/102-organizations.rb
2186
2187
  - db/seeds.d/104-proxy.rb
@@ -4502,6 +4503,7 @@ files:
4502
4503
  - lib/katello/tasks/import_subscriptions.rake
4503
4504
  - lib/katello/tasks/jenkins.rake
4504
4505
  - lib/katello/tasks/job_templates.rake
4506
+ - lib/katello/tasks/pulp2to3_migrate_deb_attributes.rake
4505
4507
  - lib/katello/tasks/receptor/extract_orgs.rake
4506
4508
  - lib/katello/tasks/regenerate_ueber_certs.rake
4507
4509
  - lib/katello/tasks/reimport.rake
@@ -4716,9 +4718,6 @@ files:
4716
4718
  - webpack/components/extensions/HostDetails/HostDetailsActions.js
4717
4719
  - webpack/components/extensions/HostDetails/HostDetailsConstants.js
4718
4720
  - webpack/components/extensions/HostDetails/HostDetailsSelectors.js
4719
- - webpack/components/extensions/HostDetails/HostPackages/HostPackagesActions.js
4720
- - webpack/components/extensions/HostDetails/HostPackages/HostPackagesConstants.js
4721
- - webpack/components/extensions/HostDetails/HostPackages/HostPackagesSelectors.js
4722
4721
  - webpack/components/extensions/HostDetails/Tabs/ContentTab/EmptyPage.js
4723
4722
  - webpack/components/extensions/HostDetails/Tabs/ContentTab/SecondaryTabsRoutes.js
4724
4723
  - webpack/components/extensions/HostDetails/Tabs/ContentTab/constants.js
@@ -4737,10 +4736,16 @@ files:
4737
4736
  - webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js
4738
4737
  - webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/__tests__/moduleStreamsTab.test.js
4739
4738
  - webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/__tests__/modules.fixtures.json
4740
- - webpack/components/extensions/HostDetails/Tabs/PackageInstallModal.js
4741
- - webpack/components/extensions/HostDetails/Tabs/PackageInstallModal.scss
4742
- - webpack/components/extensions/HostDetails/Tabs/PackagesTab.js
4743
- - webpack/components/extensions/HostDetails/Tabs/PackagesTab.scss
4739
+ - webpack/components/extensions/HostDetails/Tabs/PackagesTab/HostPackagesActions.js
4740
+ - webpack/components/extensions/HostDetails/Tabs/PackagesTab/HostPackagesConstants.js
4741
+ - webpack/components/extensions/HostDetails/Tabs/PackagesTab/HostPackagesSelectors.js
4742
+ - webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js
4743
+ - webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.scss
4744
+ - webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js
4745
+ - webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.scss
4746
+ - webpack/components/extensions/HostDetails/Tabs/PackagesTab/YumInstallablePackagesActions.js
4747
+ - webpack/components/extensions/HostDetails/Tabs/PackagesTab/YumInstallablePackagesConstants.js
4748
+ - webpack/components/extensions/HostDetails/Tabs/PackagesTab/YumInstallablePackagesSelectors.js
4744
4749
  - webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js
4745
4750
  - webpack/components/extensions/HostDetails/Tabs/RemoteExecutionConstants.js
4746
4751
  - webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsActions.js
@@ -4772,9 +4777,6 @@ files:
4772
4777
  - webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js
4773
4778
  - webpack/components/extensions/HostDetails/Tabs/__tests__/yumInstallablePackages.fixtures.json
4774
4779
  - webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js
4775
- - webpack/components/extensions/HostDetails/YumInstallablePackages/YumInstallablePackagesActions.js
4776
- - webpack/components/extensions/HostDetails/YumInstallablePackages/YumInstallablePackagesConstants.js
4777
- - webpack/components/extensions/HostDetails/YumInstallablePackages/YumInstallablePackagesSelectors.js
4778
4780
  - webpack/components/extensions/HostDetails/hostDetailsHelpers.js
4779
4781
  - webpack/components/extensions/RegistrationCommands/RegistrationCommandsPageConstants.js
4780
4782
  - webpack/components/extensions/RegistrationCommands/RegistrationCommandsPageHelpers.js
@@ -5382,9 +5384,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
5382
5384
  version: '2.5'
5383
5385
  required_rubygems_version: !ruby/object:Gem::Requirement
5384
5386
  requirements:
5385
- - - ">"
5387
+ - - ">="
5386
5388
  - !ruby/object:Gem::Version
5387
- version: 1.3.1
5389
+ version: '0'
5388
5390
  requirements: []
5389
5391
  rubygems_version: 3.2.22
5390
5392
  signing_key: