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.
- checksums.yaml +4 -4
- data/app/controllers/katello/api/v2/content_views_controller.rb +2 -0
- data/app/controllers/katello/api/v2/environments_controller.rb +2 -0
- data/app/lib/actions/katello/cdn_configuration/update.rb +2 -2
- data/app/lib/katello/resources/cdn/katello_cdn.rb +37 -14
- data/app/models/katello/candlepin/repository_mapper.rb +10 -2
- data/app/models/katello/cdn_configuration.rb +2 -0
- data/app/models/katello/kt_environment.rb +1 -0
- data/app/services/katello/organization_creator.rb +9 -5
- data/app/services/katello/registration_manager.rb +1 -0
- data/app/views/katello/api/v2/repositories/show.json.rabl +2 -2
- data/db/migrate/20220124191056_add_type_to_cdn_configuration.rb +1 -7
- data/db/migrate/20220303160220_remove_duplicate_errata.rb +34 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/views/sync-plan-products.html +1 -1
- data/lib/katello/tasks/pulp2to3_migrate_deb_attributes.rake +20 -0
- data/lib/katello/version.rb +1 -1
- data/webpack/components/RoutedTabs/index.js +1 -17
- data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard.js +2 -1
- data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.js +2 -1
- data/webpack/components/extensions/HostDetails/Cards/__tests__/contentViewDetailsCard.test.js +30 -31
- data/webpack/components/extensions/HostDetails/Cards/__tests__/errataOverviewCard.test.js +30 -3
- data/webpack/components/extensions/HostDetails/Tabs/ContentTab/SecondaryTabsRoutes.js +1 -1
- data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +1 -1
- data/webpack/components/extensions/HostDetails/{HostPackages → Tabs/PackagesTab}/HostPackagesActions.js +3 -3
- data/webpack/components/extensions/HostDetails/{HostPackages → Tabs/PackagesTab}/HostPackagesConstants.js +0 -0
- data/webpack/components/extensions/HostDetails/{HostPackages → Tabs/PackagesTab}/HostPackagesSelectors.js +0 -0
- data/webpack/components/extensions/HostDetails/Tabs/{PackageInstallModal.js → PackagesTab/PackageInstallModal.js} +9 -9
- data/webpack/components/extensions/HostDetails/Tabs/{PackageInstallModal.scss → PackagesTab/PackageInstallModal.scss} +0 -0
- data/webpack/components/extensions/HostDetails/Tabs/{PackagesTab.js → PackagesTab/PackagesTab.js} +11 -11
- data/webpack/components/extensions/HostDetails/Tabs/{PackagesTab.scss → PackagesTab/PackagesTab.scss} +0 -0
- data/webpack/components/extensions/HostDetails/{YumInstallablePackages → Tabs/PackagesTab}/YumInstallablePackagesActions.js +1 -1
- data/webpack/components/extensions/HostDetails/{YumInstallablePackages → Tabs/PackagesTab}/YumInstallablePackagesConstants.js +0 -0
- data/webpack/components/extensions/HostDetails/{YumInstallablePackages → Tabs/PackagesTab}/YumInstallablePackagesSelectors.js +0 -0
- data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +2 -2
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/packageInstallModal.test.js +2 -2
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +2 -2
- data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +2 -2
- data/webpack/components/extensions/HostDetails/hostDetailsHelpers.js +10 -1
- data/webpack/global_index.js +4 -3
- data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js +15 -19
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/UpstreamServerTypeForm.js +3 -2
- metadata +16 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e193a2273fbdeccfaeb286b7a86738e7bbb1bb78120a663e4309aac912ef4501
|
4
|
+
data.tar.gz: afbec4d28494d215e8b7c318cd403a632d3c8c14ccff79f809cc01f4fc713f3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
22
|
-
|
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 |
|
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:
|
30
|
-
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?
|
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']
|
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}
|
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 =>
|
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
|
@@ -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
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|
@@ -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
|
-
|
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
|
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
|
data/lib/katello/version.rb
CHANGED
@@ -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,
|
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)}
|
data/webpack/components/extensions/HostDetails/Cards/__tests__/contentViewDetailsCard.test.js
CHANGED
@@ -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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
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('
|
28
|
-
const
|
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
|
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
|
-
|
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
|
-
|
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('
|
63
|
+
test('shows piechart when there are errata', () => {
|
37
64
|
const hostDetails = {
|
38
|
-
|
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,
|
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 '
|
3
|
-
import { foremanApi } from '
|
4
|
-
import { getResponseErrorMsgs } from '
|
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,
|
File without changes
|
File without changes
|
@@ -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 '
|
13
|
-
import { useBulkSelect } from '
|
14
|
-
import { HOST_YUM_INSTALLABLE_PACKAGES_KEY } from '
|
15
|
-
import { selectHostYumInstallablePackagesStatus } from '
|
16
|
-
import { getHostYumInstallablePackages } from '
|
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 '
|
19
|
-
import { katelloPackageInstallBySearchUrl, katelloPackageInstallUrl } from '
|
20
|
-
import hostIdNotReady from '
|
21
|
-
import { installPackageViaKatelloAgent } from '
|
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,
|
File without changes
|
data/webpack/components/extensions/HostDetails/Tabs/{PackagesTab.js → PackagesTab/PackagesTab.js}
RENAMED
@@ -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
|
22
|
-
import
|
23
|
-
import
|
24
|
-
import { PackagesStatus, PackagesLatestVersion } from '
|
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 '
|
31
|
-
import { selectHostPackagesStatus } from '
|
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 '
|
35
|
-
import { removePackage, updatePackage, removePackages, updatePackages } from '
|
36
|
-
import { katelloPackageUpdateUrl, packagesUpdateUrl } from '
|
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 '
|
38
|
+
import hostIdNotReady from '../../HostDetailsActions';
|
39
39
|
import PackageInstallModal from './PackageInstallModal';
|
40
|
-
import defaultRemoteActionMethod,
|
40
|
+
import { defaultRemoteActionMethod, KATELLO_AGENT } from '../../hostDetailsHelpers';
|
41
41
|
|
42
42
|
export const PackagesTab = () => {
|
43
43
|
const hostDetails = useSelector(state => selectAPIResponse(state, 'HOST_DETAILS'));
|
File without changes
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { API_OPERATIONS, get } from 'foremanReact/redux/API';
|
2
|
-
import katelloApi from '
|
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({
|
File without changes
|
File without changes
|
@@ -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 '
|
9
|
-
import { PACKAGES_SEARCH_QUERY } from '
|
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 '
|
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 '
|
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 '
|
5
|
-
import { PACKAGES_SEARCH_QUERY } from '
|
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;
|
data/webpack/global_index.js
CHANGED
@@ -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',
|
data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js
CHANGED
@@ -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
|
-
|
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
|
69
|
+
<GridItem sm={6} >
|
77
70
|
<TextContent>
|
78
71
|
<Text component={TextVariants.h2}>{__('Version ')}{version}</Text>
|
79
72
|
</TextContent>
|
80
73
|
</GridItem>
|
81
|
-
<GridItem
|
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
|
-
|
84
|
+
isPlain
|
85
|
+
style={{ width: 'inherit' }}
|
84
86
|
position={DropdownPosition.right}
|
85
|
-
style={{ marginLeft: 'auto' }}
|
86
87
|
toggle={
|
87
|
-
<
|
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
|
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-
|
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/
|
4741
|
-
- webpack/components/extensions/HostDetails/Tabs/
|
4742
|
-
- webpack/components/extensions/HostDetails/Tabs/PackagesTab.js
|
4743
|
-
- webpack/components/extensions/HostDetails/Tabs/PackagesTab.
|
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:
|
5389
|
+
version: '0'
|
5388
5390
|
requirements: []
|
5389
5391
|
rubygems_version: 3.2.22
|
5390
5392
|
signing_key:
|