katello 4.12.1 → 4.13.0.rc1
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/assets/javascripts/katello/locale/bn/katello.js +3365 -3350
- data/app/assets/javascripts/katello/locale/bn_IN/katello.js +3136 -3121
- data/app/assets/javascripts/katello/locale/ca/katello.js +3588 -3576
- data/app/assets/javascripts/katello/locale/cs/katello.js +3499 -3487
- data/app/assets/javascripts/katello/locale/cs_CZ/katello.js +4186 -4186
- data/app/assets/javascripts/katello/locale/de/katello.js +5553 -5562
- data/app/assets/javascripts/katello/locale/de_AT/katello.js +3008 -2993
- data/app/assets/javascripts/katello/locale/de_DE/katello.js +3066 -3051
- data/app/assets/javascripts/katello/locale/el/katello.js +3376 -3370
- data/app/assets/javascripts/katello/locale/en/katello.js +3008 -2993
- data/app/assets/javascripts/katello/locale/en_GB/katello.js +3076 -3073
- data/app/assets/javascripts/katello/locale/en_US/katello.js +3008 -2993
- data/app/assets/javascripts/katello/locale/es/katello.js +5366 -5372
- data/app/assets/javascripts/katello/locale/et_EE/katello.js +3008 -2993
- data/app/assets/javascripts/katello/locale/fr/katello.js +5975 -5984
- data/app/assets/javascripts/katello/locale/gl/katello.js +3125 -3113
- data/app/assets/javascripts/katello/locale/gu/katello.js +3119 -3104
- data/app/assets/javascripts/katello/locale/he_IL/katello.js +3020 -3005
- data/app/assets/javascripts/katello/locale/hi/katello.js +3137 -3122
- data/app/assets/javascripts/katello/locale/id/katello.js +3008 -2993
- data/app/assets/javascripts/katello/locale/it/katello.js +4469 -4466
- data/app/assets/javascripts/katello/locale/ja/katello.js +5969 -5978
- data/app/assets/javascripts/katello/locale/ka/katello.js +5649 -5652
- data/app/assets/javascripts/katello/locale/kn/katello.js +3136 -3121
- data/app/assets/javascripts/katello/locale/ko/katello.js +4717 -4720
- data/app/assets/javascripts/katello/locale/locale/katello.js +1050 -1084
- data/app/assets/javascripts/katello/locale/ml_IN/katello.js +3008 -2993
- data/app/assets/javascripts/katello/locale/mr/katello.js +3136 -3121
- data/app/assets/javascripts/katello/locale/nl_NL/katello.js +3116 -3101
- data/app/assets/javascripts/katello/locale/or/katello.js +3137 -3122
- data/app/assets/javascripts/katello/locale/pa/katello.js +3136 -3121
- data/app/assets/javascripts/katello/locale/pl/katello.js +3210 -3195
- data/app/assets/javascripts/katello/locale/pl_PL/katello.js +3008 -2993
- data/app/assets/javascripts/katello/locale/pt/katello.js +3009 -2994
- data/app/assets/javascripts/katello/locale/pt_BR/katello.js +5362 -5368
- data/app/assets/javascripts/katello/locale/ro/katello.js +3008 -2993
- data/app/assets/javascripts/katello/locale/ro_RO/katello.js +3008 -2993
- data/app/assets/javascripts/katello/locale/ru/katello.js +4638 -4641
- data/app/assets/javascripts/katello/locale/sl/katello.js +3051 -3036
- data/app/assets/javascripts/katello/locale/sv_SE/katello.js +3156 -3144
- data/app/assets/javascripts/katello/locale/ta/katello.js +3365 -3350
- data/app/assets/javascripts/katello/locale/ta_IN/katello.js +3121 -3106
- data/app/assets/javascripts/katello/locale/te/katello.js +3136 -3121
- data/app/assets/javascripts/katello/locale/tr/katello.js +3025 -3010
- data/app/assets/javascripts/katello/locale/vi/katello.js +3008 -2993
- data/app/assets/javascripts/katello/locale/vi_VN/katello.js +3008 -2993
- data/app/assets/javascripts/katello/locale/zh/katello.js +3008 -2993
- data/app/assets/javascripts/katello/locale/zh_CN/katello.js +5968 -5977
- data/app/assets/javascripts/katello/locale/zh_TW/katello.js +4694 -4697
- data/app/controllers/katello/api/registry/registry_proxies_controller.rb +51 -124
- data/app/controllers/katello/api/rhsm/candlepin_dynflow_proxy_controller.rb +12 -20
- data/app/controllers/katello/api/v2/activation_keys_controller.rb +10 -4
- data/app/controllers/katello/api/v2/capsule_content_controller.rb +24 -0
- data/app/controllers/katello/api/v2/content_view_versions_controller.rb +9 -2
- data/app/controllers/katello/api/v2/debs_controller.rb +1 -1
- data/app/controllers/katello/api/v2/errata_controller.rb +1 -1
- data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +12 -4
- data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +3 -3
- data/app/controllers/katello/api/v2/organizations_controller.rb +0 -11
- data/app/controllers/katello/api/v2/packages_controller.rb +1 -1
- data/app/controllers/katello/api/v2/repositories_controller.rb +18 -12
- data/app/controllers/katello/api/v2/repository_sets_controller.rb +2 -1
- data/app/controllers/katello/api/v2/simple_content_access_controller.rb +9 -22
- data/app/controllers/katello/concerns/api/v2/authorization.rb +1 -1
- data/app/helpers/katello/subscription_mailer_helper.rb +1 -1
- data/app/jobs/create_manifest_expire_soon_warning_notifications.rb +11 -0
- data/app/lib/actions/candlepin/owner/regenerate_upstream_identity_cert.rb +21 -0
- data/app/lib/actions/katello/capsule_content/sync.rb +1 -1
- data/app/lib/actions/katello/capsule_content/verify_checksum.rb +75 -0
- data/app/lib/actions/katello/content_view/promote.rb +1 -1
- data/app/lib/actions/katello/content_view/publish.rb +1 -1
- data/app/lib/actions/katello/content_view_version/verify_checksum.rb +29 -0
- data/app/lib/actions/katello/host/hypervisors_update.rb +1 -0
- data/app/lib/actions/katello/host/update_content_view.rb +2 -2
- data/app/lib/actions/katello/organization/manifest_import.rb +5 -0
- data/app/lib/actions/katello/organization/manifest_refresh.rb +3 -0
- data/app/lib/actions/katello/repository/metadata_generate.rb +7 -1
- data/app/lib/actions/katello/repository/remove_content.rb +1 -0
- data/app/lib/actions/katello/repository/sync.rb +2 -1
- data/app/lib/actions/katello/repository/upload_files.rb +1 -0
- data/app/lib/actions/pulp3/capsule_content/verify_checksum.rb +27 -0
- data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +7 -9
- data/app/lib/actions/pulp3/orchestration/content_view_version/syncable_export.rb +5 -4
- data/app/lib/katello/concerns/base_template_scope_extensions.rb +7 -2
- data/app/lib/katello/http_resource.rb +6 -1
- data/app/lib/katello/resources/candlepin/consumer.rb +1 -1
- data/app/lib/katello/resources/candlepin/upstream_consumer.rb +18 -6
- data/app/lib/katello/resources/candlepin/upstream_job.rb +1 -1
- data/app/lib/katello/resources/registry.rb +25 -0
- data/app/mailers/katello/subscription_mailer.rb +3 -6
- data/app/models/katello/concerns/organization_extensions.rb +42 -3
- data/app/models/katello/content_view.rb +28 -0
- data/app/models/katello/content_view_environment_content_facet.rb +4 -2
- data/app/models/katello/glue/provider.rb +19 -12
- data/app/models/katello/glue/pulp/repos.rb +3 -2
- data/app/models/katello/host/content_facet.rb +1 -1
- data/app/models/katello/host/subscription_facet.rb +1 -1
- data/app/models/katello/ping.rb +1 -1
- data/app/models/katello/repository.rb +27 -0
- data/app/models/katello/root_repository.rb +0 -4
- data/app/services/katello/content_unit_indexer.rb +9 -0
- data/app/services/katello/pulp3/alternate_content_source.rb +4 -6
- data/app/services/katello/pulp3/api/core.rb +13 -0
- data/app/services/katello/pulp3/api/yum.rb +11 -0
- data/app/services/katello/pulp3/docker_manifest.rb +5 -1
- data/app/services/katello/pulp3/repository/generic.rb +1 -1
- data/app/services/katello/pulp3/repository.rb +26 -6
- data/app/services/katello/pulp3/repository_mirror.rb +13 -12
- data/app/services/katello/pulp3/service_common.rb +2 -10
- data/app/services/katello/pulp3/smart_proxy_repository.rb +0 -2
- data/app/services/katello/ui_notifications/subscriptions/manifest_expire_soon_warning.rb +75 -0
- data/app/views/foreman/job_templates/update_package_-_katello_ansible_default.erb +5 -1
- data/app/views/foreman/job_templates/update_packages_by_search_query_-_katello_ansible_default.erb +2 -2
- data/app/views/foreman/job_templates/upload_profile.erb +16 -0
- data/app/views/katello/api/v2/content_view_filter_rules/show.json.rabl +9 -0
- data/app/views/katello/api/v2/docker_manifests/show.json.rabl +1 -0
- data/app/views/katello/api/v2/organizations/show.json.rabl +9 -1
- data/app/views/overrides/activation_keys/_host_environment_select.html.erb +1 -1
- data/app/views/overrides/activation_keys/_host_media_type_select.html.erb +15 -5
- data/config/routes/api/registry.rb +4 -8
- data/config/routes/api/v2.rb +2 -0
- data/db/migrate/20240423112842_add_fields_to_katello_docker_manifest.rb +8 -0
- data/db/migrate/20240502192021_change_katello_repository_rpms_id_seq_to_big_int.rb +9 -0
- data/db/seeds.d/109-katello-notification-blueprints.rb +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-repository-sets.controller.js +3 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/new/views/new-content-credential.html +2 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-repository-sets.controller.js +3 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +0 -15
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +8 -6
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +12 -10
- data/lib/katello/permission_creator.rb +3 -3
- data/lib/katello/permissions/registry_permissions.rb +4 -7
- data/lib/katello/plugin.rb +9 -8
- data/lib/katello/repository_types/ostree.rb +7 -0
- data/lib/katello/scheduled_jobs.rb +7 -1
- data/lib/katello/tasks/clean_backend_objects.rake +1 -1
- data/lib/katello/tasks/repository.rake +22 -0
- data/lib/katello/version.rb +1 -1
- data/locale/action_names.rb +4 -3
- data/locale/bn/katello.po +166 -151
- data/locale/bn_IN/katello.po +166 -151
- data/locale/ca/katello.po +166 -151
- data/locale/cs/katello.po +166 -151
- data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
- data/locale/cs_CZ/katello.po +172 -157
- data/locale/de/LC_MESSAGES/katello.mo +0 -0
- data/locale/de/katello.po +178 -163
- data/locale/de_AT/katello.po +166 -151
- data/locale/de_DE/katello.po +166 -151
- data/locale/el/katello.po +166 -151
- data/locale/en/katello.po +166 -151
- data/locale/en_GB/katello.po +166 -151
- data/locale/en_US/katello.po +166 -151
- data/locale/es/LC_MESSAGES/katello.mo +0 -0
- data/locale/es/katello.po +178 -163
- data/locale/et_EE/katello.po +166 -151
- data/locale/fr/LC_MESSAGES/katello.mo +0 -0
- data/locale/fr/katello.po +179 -164
- data/locale/gl/katello.po +166 -151
- data/locale/gu/katello.po +166 -151
- data/locale/he_IL/katello.po +166 -151
- data/locale/hi/katello.po +166 -151
- data/locale/id/katello.po +166 -151
- data/locale/it/LC_MESSAGES/katello.mo +0 -0
- data/locale/it/katello.po +169 -154
- data/locale/ja/LC_MESSAGES/katello.mo +0 -0
- data/locale/ja/katello.po +179 -164
- data/locale/ka/LC_MESSAGES/katello.mo +0 -0
- data/locale/ka/katello.po +177 -162
- data/locale/katello.pot +1119 -1062
- data/locale/kn/katello.po +166 -151
- data/locale/ko/LC_MESSAGES/katello.mo +0 -0
- data/locale/ko/katello.po +174 -159
- data/locale/ml_IN/katello.po +166 -151
- data/locale/mr/katello.po +166 -151
- data/locale/nl_NL/katello.po +166 -151
- data/locale/or/katello.po +166 -151
- data/locale/pa/katello.po +166 -151
- data/locale/pl/katello.po +166 -151
- data/locale/pl_PL/katello.po +166 -151
- data/locale/pt/katello.po +166 -151
- data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
- data/locale/pt_BR/katello.po +178 -163
- data/locale/ro/katello.po +166 -151
- data/locale/ro_RO/katello.po +166 -151
- data/locale/ru/LC_MESSAGES/katello.mo +0 -0
- data/locale/ru/katello.po +171 -156
- data/locale/sl/katello.po +166 -151
- data/locale/sv_SE/katello.po +166 -151
- data/locale/ta/katello.po +166 -151
- data/locale/ta_IN/katello.po +166 -151
- data/locale/te/katello.po +166 -151
- data/locale/tr/katello.po +166 -151
- data/locale/vi/katello.po +166 -151
- data/locale/vi_VN/katello.po +166 -151
- data/locale/zh/katello.po +166 -151
- data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
- data/locale/zh_CN/katello.po +179 -164
- data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
- data/locale/zh_TW/katello.po +171 -156
- data/webpack/ForemanColumnExtensions/index.js +129 -0
- data/webpack/components/Table/TableWrapper.js +14 -0
- data/webpack/components/extensions/HostDetails/ActionsBar/index.js +1 -1
- data/webpack/components/extensions/Hosts/ActionsBar/index.js +20 -1
- data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/BulkChangeHostCVModal.js +220 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/actions.js +23 -0
- data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/index.js +25 -0
- data/webpack/components/extensions/Hosts/BulkActions/__tests__/bulkChangeHostCVModal.test.js +133 -0
- data/webpack/global_index.js +9 -0
- data/webpack/scenes/Hosts/ChangeContentSource/actions.js +3 -1
- data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceForm.js +62 -24
- data/webpack/scenes/Hosts/ChangeContentSource/index.js +24 -16
- data/webpack/scenes/RedHatRepositories/__tests__/__snapshots__/RedHatRepositoriesPage.test.js.snap +1 -0
- data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +64 -5
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +16 -13
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +14 -8
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +1 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +1 -1
- metadata +59 -41
- data/app/lib/actions/katello/host/upload_package_profile.rb +0 -45
- data/app/lib/actions/katello/host/upload_profiles.rb +0 -47
data/webpack/global_index.js
CHANGED
@@ -2,8 +2,10 @@ import React from 'react';
|
|
2
2
|
import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
|
3
3
|
import { registerReducer } from 'foremanReact/common/MountingService';
|
4
4
|
import { translate as __ } from 'foremanReact/common/I18n';
|
5
|
+
import { registerColumns } from 'foremanReact/components/HostsIndex/Columns/core';
|
5
6
|
import componentRegistry from 'foremanReact/components/componentRegistry';
|
6
7
|
|
8
|
+
import hostsIndexColumnExtensions from './ForemanColumnExtensions/index';
|
7
9
|
import SystemStatuses from './components/extensions/about';
|
8
10
|
import {
|
9
11
|
RegistrationCommands,
|
@@ -30,6 +32,7 @@ import HostDetailsActionsBar from './components/extensions/HostDetails/ActionsBa
|
|
30
32
|
import HostsIndexActionsBar from './components/extensions/Hosts/ActionsBar';
|
31
33
|
import RecentCommunicationCardExtensions from './components/extensions/HostDetails/DetailsTabCards/RecentCommunicationCardExtensions';
|
32
34
|
import SystemPurposeCard from './components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard';
|
35
|
+
import BulkChangeHostCVModal from './components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/index.js';
|
33
36
|
|
34
37
|
|
35
38
|
import ActivationKeysSearch from './components/ActivationKeysSearch';
|
@@ -85,6 +88,12 @@ addGlobalFill(
|
|
85
88
|
|
86
89
|
addGlobalFill('host-tab-details-cards', 'HW properties', <HwPropertiesCard key="hw-properties" />, 200);
|
87
90
|
|
91
|
+
// Hosts Index page extensions
|
92
|
+
addGlobalFill('_all-hosts-modals', 'BulkChangeHostCVModal', <BulkChangeHostCVModal key="bulk-change-host-cv-modal" />, 100);
|
93
|
+
|
94
|
+
registerColumns(hostsIndexColumnExtensions);
|
95
|
+
|
96
|
+
|
88
97
|
componentRegistry.register({
|
89
98
|
name: 'ActivationKeysSearch',
|
90
99
|
type: ActivationKeysSearch,
|
@@ -18,7 +18,7 @@ export const getFormData = (hostIds, search) => (post({
|
|
18
18
|
}));
|
19
19
|
|
20
20
|
export const changeContentSource =
|
21
|
-
(environmentId, contentViewId, contentSourceId, hostIds, handleSuccess) =>
|
21
|
+
(environmentId, contentViewId, contentSourceId, hostIds, handleSuccess, successToast) =>
|
22
22
|
put({
|
23
23
|
key: CHANGE_CONTENT_SOURCE,
|
24
24
|
url: foremanUrl('/api/v2/hosts/bulk/change_content_source'),
|
@@ -29,6 +29,7 @@ export const changeContentSource =
|
|
29
29
|
host_ids: hostIds,
|
30
30
|
},
|
31
31
|
errorToast: () => __('Something went wrong while updating the content source. See the logs for more information'),
|
32
|
+
successToast,
|
32
33
|
handleSuccess,
|
33
34
|
});
|
34
35
|
|
@@ -46,6 +47,7 @@ export const getContentViews = environmentId =>
|
|
46
47
|
params: {
|
47
48
|
environment_id: environmentId,
|
48
49
|
full_result: true,
|
50
|
+
order: 'default DESC', // shows the default CV before all other options
|
49
51
|
},
|
50
52
|
errorToast: () => __('Something went wrong while loading the content views. See the logs for more information'),
|
51
53
|
});
|
@@ -23,7 +23,7 @@ import { ENVIRONMENT_PATHS_KEY } from '../../../../scenes/ContentViews/component
|
|
23
23
|
import EnvironmentPaths from '../../../../scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths';
|
24
24
|
import ContentViewSelect from '../../../../scenes/ContentViews/components/ContentViewSelect/ContentViewSelect';
|
25
25
|
import ContentViewSelectOption from '../../../../scenes/ContentViews/components/ContentViewSelect/ContentViewSelectOption';
|
26
|
-
import { selectContentViewsStatus } from '../selectors';
|
26
|
+
import { selectContentViewsStatus, selectJobInvocationPath } from '../selectors';
|
27
27
|
import { getCVPlaceholderText, shouldDisableCVSelect } from '../../../ContentViews/components/ContentViewSelect/helpers';
|
28
28
|
import { selectEnvironmentPaths } from '../../../ContentViews/components/EnvironmentPaths/EnvironmentPathSelectors';
|
29
29
|
|
@@ -95,6 +95,9 @@ const ContentSourceForm = ({
|
|
95
95
|
contentSources,
|
96
96
|
handleContentSource,
|
97
97
|
contentSourceId,
|
98
|
+
showCVOnlyAlert,
|
99
|
+
hostDetailsPath,
|
100
|
+
hostEditPath,
|
98
101
|
contentHosts,
|
99
102
|
isLoading,
|
100
103
|
hostsUpdated,
|
@@ -108,6 +111,7 @@ const ContentSourceForm = ({
|
|
108
111
|
);
|
109
112
|
const contentViewsStatus = useSelector(selectContentViewsStatus);
|
110
113
|
const environmentPathResponse = useSelector(selectEnvironmentPaths);
|
114
|
+
const jobInvocationPath = useSelector(selectJobInvocationPath);
|
111
115
|
const envList = environmentPathResponse?.results?.map(path => path.environments).flat();
|
112
116
|
const [csSelectOpen, setCSSelectOpen] = useState(false);
|
113
117
|
const [cvSelectOpen, setCVSelectOpen] = useState(false);
|
@@ -127,13 +131,12 @@ const ContentSourceForm = ({
|
|
127
131
|
!!contentViewName &&
|
128
132
|
!!contentSourceId &&
|
129
133
|
hostCount !== 0);
|
130
|
-
|
131
134
|
const contentSourcesIsDisabled = (isLoading || contentSources.length === 0 ||
|
132
135
|
hostCount === 0);
|
133
|
-
const environmentIsDisabled = (isLoading ||
|
136
|
+
const environmentIsDisabled = (isLoading ||
|
134
137
|
contentSourceId === '');
|
135
138
|
const viewIsDisabled = (isLoading || contentViews.length === 0 ||
|
136
|
-
contentSourceId === ''
|
139
|
+
contentSourceId === '');
|
137
140
|
|
138
141
|
const cvPlaceholderText = getCVPlaceholderText({
|
139
142
|
contentSourceId,
|
@@ -229,6 +232,15 @@ const ContentSourceForm = ({
|
|
229
232
|
env={environments[0]}
|
230
233
|
/>))}
|
231
234
|
</ContentViewSelect>
|
235
|
+
{showCVOnlyAlert &&
|
236
|
+
<Alert
|
237
|
+
ouiaId="cv-only-alert"
|
238
|
+
variant="info"
|
239
|
+
className="margin-top-20"
|
240
|
+
title={__('Host content source will remain the same. Click Save below to update the host\'s content view environment.')}
|
241
|
+
/>
|
242
|
+
}
|
243
|
+
{!showCVOnlyAlert &&
|
232
244
|
<TextContent>
|
233
245
|
<Text
|
234
246
|
ouiaId="ccs-options-description"
|
@@ -252,27 +264,49 @@ const ContentSourceForm = ({
|
|
252
264
|
/>
|
253
265
|
</Text>
|
254
266
|
</TextContent>
|
267
|
+
}
|
255
268
|
<ActionGroup style={{ display: 'block' }}>
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
269
|
+
{!showCVOnlyAlert &&
|
270
|
+
<>
|
271
|
+
<Button
|
272
|
+
variant="primary"
|
273
|
+
id="generate_btn"
|
274
|
+
ouiaId="run-job-invocation-button"
|
275
|
+
onClick={e => handleSubmit(e, { redirectTo: jobInvocationPath })}
|
276
|
+
isDisabled={isLoading || !formIsValid() || hostsUpdated}
|
277
|
+
isLoading={isLoading}
|
278
|
+
>
|
279
|
+
{__('Run job invocation')}
|
280
|
+
</Button>
|
281
|
+
<Button
|
282
|
+
variant="secondary"
|
283
|
+
id="generate_btn"
|
284
|
+
ouiaId="update-source-button"
|
285
|
+
onClick={showTemplate}
|
286
|
+
isDisabled={isLoading || !formIsValid() || hostsUpdated}
|
287
|
+
isLoading={isLoading}
|
288
|
+
>
|
289
|
+
{__('Update hosts manually')}
|
290
|
+
</Button>
|
291
|
+
</>
|
292
|
+
}
|
293
|
+
{showCVOnlyAlert &&
|
294
|
+
<Button
|
295
|
+
variant="primary"
|
296
|
+
id="generate_btn"
|
297
|
+
ouiaId="change-cv-button"
|
298
|
+
onClick={e =>
|
299
|
+
handleSubmit(e, {
|
300
|
+
redirectTo: hostEditPath || hostDetailsPath,
|
301
|
+
showSuccessToast: true,
|
302
|
+
})
|
303
|
+
}
|
304
|
+
isDisabled={isLoading || !formIsValid() || hostsUpdated}
|
305
|
+
isLoading={isLoading}
|
306
|
+
>
|
307
|
+
{__('Save')}
|
308
|
+
</Button>
|
309
|
+
}
|
276
310
|
|
277
311
|
</ActionGroup>
|
278
312
|
</Form>);
|
@@ -288,6 +322,9 @@ ContentSourceForm.propTypes = {
|
|
288
322
|
contentSources: PropTypes.arrayOf(PropTypes.shape({})),
|
289
323
|
handleContentSource: PropTypes.func.isRequired,
|
290
324
|
contentSourceId: PropTypes.string,
|
325
|
+
showCVOnlyAlert: PropTypes.bool,
|
326
|
+
hostDetailsPath: PropTypes.string.isRequired,
|
327
|
+
hostEditPath: PropTypes.string.isRequired,
|
291
328
|
contentHosts: PropTypes.arrayOf(PropTypes.shape({})),
|
292
329
|
isLoading: PropTypes.bool,
|
293
330
|
hostsUpdated: PropTypes.bool,
|
@@ -300,6 +337,7 @@ ContentSourceForm.defaultProps = {
|
|
300
337
|
contentViewName: '',
|
301
338
|
contentSources: [],
|
302
339
|
contentSourceId: '',
|
340
|
+
showCVOnlyAlert: false,
|
303
341
|
contentHosts: [],
|
304
342
|
isLoading: false,
|
305
343
|
hostsUpdated: false,
|
@@ -17,7 +17,6 @@ import { selectApiDataStatus,
|
|
17
17
|
selectContentHosts,
|
18
18
|
selectContentHostsWithoutContent,
|
19
19
|
selectContentSources,
|
20
|
-
selectJobInvocationPath,
|
21
20
|
selectContentViews,
|
22
21
|
selectTemplate } from './selectors';
|
23
22
|
|
@@ -46,31 +45,36 @@ const ChangeContentSourcePage = () => {
|
|
46
45
|
const contentHosts = useSelector(selectContentHosts);
|
47
46
|
const hostsWithoutContent = useSelector(selectContentHostsWithoutContent);
|
48
47
|
const contentSources = useSelector(selectContentSources);
|
49
|
-
const jobInvocationPath = useSelector(selectJobInvocationPath);
|
50
48
|
|
51
49
|
const template = useSelector(selectTemplate);
|
52
50
|
const contentViews = useSelector(selectContentViews);
|
53
|
-
|
54
|
-
const [contentSourceId, setCapsuleId] = useState('');
|
51
|
+
const { initialContentSourceId } = urlParams;
|
52
|
+
const [contentSourceId, setCapsuleId] = useState(initialContentSourceId ?? '');
|
53
|
+
// if this matches, we'll trust you that initialContentSourceId is the host's content source
|
54
|
+
const showCVOnlyAlert = (contentHosts.length === 1 &&
|
55
|
+
hostsWithoutContent.length === 0 &&
|
56
|
+
!!initialContentSourceId &&
|
57
|
+
initialContentSourceId === contentSourceId
|
58
|
+
);
|
59
|
+
const hostDetailsPath = showCVOnlyAlert ? `new/hosts/${contentHosts[0].name}` : '';
|
60
|
+
const hostEditPath = urlParams.fromPage === 'hostEdit' ? foremanUrl(`/hosts/${contentHosts[0]?.name}/edit`) : '';
|
55
61
|
const [selectedEnvironment, setSelectedEnvironment] = useState([]);
|
56
62
|
const [contentViewName, setContentViewName] = useState('');
|
57
63
|
const [shouldShowTemplate, setShouldShowTemplate] = useState(false);
|
58
|
-
const [redirect, setRedirect] = useState(
|
64
|
+
const [redirect, setRedirect] = useState('');
|
59
65
|
|
60
66
|
const contentViewId = contentViews?.find(cv => cv.name === contentViewName)?.id;
|
61
67
|
const hostIds = useMemo(() => getHostIds(urlParams.host_id), [urlParams.host_id]);
|
62
68
|
const noHostSpecified = (hostIds.length === 0 && urlParams.searchParam === '');
|
63
69
|
const environmentId = selectedEnvironment[0]?.id;
|
64
70
|
|
65
|
-
const
|
66
|
-
|
67
|
-
|
68
|
-
if (shouldRedirect) {
|
69
|
-
redirectToJobInvocationForm();
|
71
|
+
const handleSuccess = ({ redirectTo = '' }) => {
|
72
|
+
if (redirectTo) {
|
73
|
+
setRedirect(redirectTo);
|
70
74
|
}
|
71
75
|
};
|
72
76
|
|
73
|
-
const handleSubmit = (e, {
|
77
|
+
const handleSubmit = (e, { redirectTo = '', showSuccessToast = false } = {}) => {
|
74
78
|
e.preventDefault();
|
75
79
|
|
76
80
|
dispatch(changeContentSource(
|
@@ -78,7 +82,8 @@ const ChangeContentSourcePage = () => {
|
|
78
82
|
contentViewId,
|
79
83
|
contentSourceId,
|
80
84
|
contentHosts.map(h => h.id),
|
81
|
-
() => handleSuccess({
|
85
|
+
() => handleSuccess({ redirectTo }),
|
86
|
+
showSuccessToast ? () => __('Host content view environment(s) updated') : undefined,
|
82
87
|
));
|
83
88
|
};
|
84
89
|
|
@@ -93,7 +98,7 @@ const ChangeContentSourcePage = () => {
|
|
93
98
|
};
|
94
99
|
|
95
100
|
const showTemplate = (e) => {
|
96
|
-
handleSubmit(e
|
101
|
+
handleSubmit(e);
|
97
102
|
setShouldShowTemplate(true);
|
98
103
|
};
|
99
104
|
|
@@ -122,8 +127,8 @@ const ChangeContentSourcePage = () => {
|
|
122
127
|
dispatch(getFormData(hostIds, urlParams.searchParam));
|
123
128
|
}, [dispatch, hostIds, urlParams.searchParam]);
|
124
129
|
|
125
|
-
if (redirect &&
|
126
|
-
window.location.assign(
|
130
|
+
if (redirect && redirect !== '') {
|
131
|
+
window.location.assign(redirect);
|
127
132
|
}
|
128
133
|
|
129
134
|
return (
|
@@ -165,7 +170,7 @@ const ChangeContentSourcePage = () => {
|
|
165
170
|
title={__('No hosts were specified')}
|
166
171
|
/>
|
167
172
|
</GridItem>
|
168
|
-
|
173
|
+
}
|
169
174
|
{ !noHostSpecified &&
|
170
175
|
<>
|
171
176
|
<Hosts
|
@@ -182,6 +187,9 @@ const ChangeContentSourcePage = () => {
|
|
182
187
|
contentViewName={contentViewName}
|
183
188
|
contentSources={contentSources}
|
184
189
|
contentSourceId={contentSourceId}
|
190
|
+
showCVOnlyAlert={showCVOnlyAlert}
|
191
|
+
hostDetailsPath={hostDetailsPath}
|
192
|
+
hostEditPath={hostEditPath}
|
185
193
|
handleContentSource={handleContentSource}
|
186
194
|
contentHosts={contentHosts}
|
187
195
|
isLoading={isLoading}
|
@@ -1,7 +1,10 @@
|
|
1
1
|
import React, { Component } from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import { Grid, Col, Row, Tabs, Tab, FormControl, ControlLabel } from 'react-bootstrap';
|
4
|
+
import { FormattedMessage } from 'react-intl';
|
4
5
|
import { Button, Spinner } from 'patternfly-react';
|
6
|
+
import { Alert } from '@patternfly/react-core';
|
7
|
+
import { propsToCamelCase } from 'foremanReact/common/helpers';
|
5
8
|
import ForemanModal from 'foremanReact/components/ForemanModal';
|
6
9
|
import Slot from 'foremanReact/components/common/Slot';
|
7
10
|
import { translate as __ } from 'foremanReact/common/I18n';
|
@@ -92,22 +95,29 @@ class ManageManifestModal extends Component {
|
|
92
95
|
contentCredentials,
|
93
96
|
} = this.props;
|
94
97
|
|
98
|
+
const {
|
99
|
+
manifestExpiringSoon,
|
100
|
+
manifestExpired,
|
101
|
+
manifestExpirationDate,
|
102
|
+
manifestExpireDaysRemaining,
|
103
|
+
} = propsToCamelCase(organization);
|
104
|
+
|
95
105
|
const actionInProgress = (taskInProgress || manifestActionStarted);
|
96
106
|
const showCdnConfigurationTab = canEditOrganizations;
|
97
107
|
const showSubscriptionManifest = (canImportManifest || canDeleteManifest);
|
98
108
|
const showManifestTab = (canEditOrganizations || showSubscriptionManifest);
|
99
109
|
|
100
110
|
const emptyStateData = () => ({
|
101
|
-
header: __('There is no
|
102
|
-
description: __('Import a
|
111
|
+
header: __('There is no manifest history to display.'),
|
112
|
+
description: __('Import a manifest using the Manifest tab above.'),
|
103
113
|
documentation: {
|
104
|
-
label: __('Learn more about adding
|
114
|
+
label: __('Learn more about adding subscription manifests '),
|
105
115
|
url: 'https://access.redhat.com/solutions/3410771',
|
106
116
|
},
|
107
117
|
});
|
108
118
|
|
109
119
|
const getManifestName = () => {
|
110
|
-
let name = __('No
|
120
|
+
let name = __('No manifest imported');
|
111
121
|
|
112
122
|
if (
|
113
123
|
organization.owner_details &&
|
@@ -139,6 +149,46 @@ class ManageManifestModal extends Component {
|
|
139
149
|
<React.Fragment>
|
140
150
|
<Grid>
|
141
151
|
<h3>{__('Subscription Manifest')}</h3>
|
152
|
+
{manifestExpiringSoon &&
|
153
|
+
<Alert
|
154
|
+
ouiaId="manifest-expiring-soon-alert"
|
155
|
+
variant="warning"
|
156
|
+
title={__('Manifest expiring soon')}
|
157
|
+
>
|
158
|
+
<FormattedMessage
|
159
|
+
defaultMessage={__('Your manifest will expire in {daysMessage}. To extend the expiration date, refresh your manifest. Or, if your Foreman is disconnected, import a new manifest.')}
|
160
|
+
values={{
|
161
|
+
daysMessage: (
|
162
|
+
<FormattedMessage
|
163
|
+
defaultMessage="{daysRemaining, plural, one {{singular}} other {# {plural}}}"
|
164
|
+
values={{
|
165
|
+
daysRemaining: manifestExpireDaysRemaining,
|
166
|
+
singular: __('day'),
|
167
|
+
plural: __('days'),
|
168
|
+
}}
|
169
|
+
id="manage-manifest-expire-days-i18n"
|
170
|
+
/>
|
171
|
+
),
|
172
|
+
}}
|
173
|
+
id="manage-manifest-expire-i18n"
|
174
|
+
/>
|
175
|
+
</Alert>
|
176
|
+
}
|
177
|
+
{manifestExpired && isManifestImported &&
|
178
|
+
<Alert
|
179
|
+
ouiaId="manifest-expired-alert"
|
180
|
+
variant="danger"
|
181
|
+
title={__('Manifest expired')}
|
182
|
+
>
|
183
|
+
<FormattedMessage
|
184
|
+
defaultMessage={__('Your manifest expired on {expirationDate}. To continue using Red Hat content, import a new manifest.')}
|
185
|
+
values={{
|
186
|
+
expirationDate: new Date(manifestExpirationDate).toDateString(),
|
187
|
+
}}
|
188
|
+
id="manage-manifest-expired-i18n"
|
189
|
+
/>
|
190
|
+
</Alert>
|
191
|
+
}
|
142
192
|
<hr />
|
143
193
|
<Row>
|
144
194
|
<Col sm={5}>
|
@@ -148,13 +198,22 @@ class ManageManifestModal extends Component {
|
|
148
198
|
{getManifestName()}
|
149
199
|
</Col>
|
150
200
|
</Row>
|
201
|
+
{isManifestImported && manifestExpirationDate &&
|
202
|
+
<Row>
|
203
|
+
<Col sm={5} />
|
204
|
+
<Col sm={7}>
|
205
|
+
{manifestExpired ? __('Expired ') : __('Expires ')}
|
206
|
+
{new Date(manifestExpirationDate).toDateString()}
|
207
|
+
</Col>
|
208
|
+
</Row>
|
209
|
+
}
|
151
210
|
<Row>
|
152
211
|
<Col sm={5}>
|
153
212
|
{canImportManifest &&
|
154
213
|
<ControlLabel
|
155
214
|
style={{ paddingTop: '10px' }}
|
156
215
|
>
|
157
|
-
<div>{__('Import
|
216
|
+
<div>{__('Import new manifest')}</div>
|
158
217
|
</ControlLabel>
|
159
218
|
}
|
160
219
|
</Col>
|
@@ -222,19 +222,22 @@ class UpstreamSubscriptionsPage extends Component {
|
|
222
222
|
|
223
223
|
return (
|
224
224
|
<Grid bsClass="container-fluid">
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
{
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
225
|
+
{!upstreamSubscriptions.loading &&
|
226
|
+
<div style={{ marginBottom: '10px' }}>
|
227
|
+
<BreadcrumbsBar
|
228
|
+
isLoadingResources={upstreamSubscriptions.loading}
|
229
|
+
breadcrumbItems={[
|
230
|
+
{
|
231
|
+
caption: __('Subscriptions'),
|
232
|
+
url: '/subscriptions/',
|
233
|
+
},
|
234
|
+
{
|
235
|
+
caption: String(__('Add Subscriptions')),
|
236
|
+
},
|
237
|
+
]}
|
238
|
+
/>
|
239
|
+
</div>
|
240
|
+
}
|
238
241
|
|
239
242
|
<LoadingState loading={upstreamSubscriptions.loading} loadingText={__('Loading')}>
|
240
243
|
<Row>
|
@@ -6,22 +6,28 @@ exports[`upstream subscriptions page should render 1`] = `
|
|
6
6
|
componentClass="div"
|
7
7
|
fluid={false}
|
8
8
|
>
|
9
|
-
<
|
10
|
-
|
9
|
+
<div
|
10
|
+
style={
|
11
11
|
Object {
|
12
|
-
"
|
12
|
+
"marginBottom": "10px",
|
13
|
+
}
|
14
|
+
}
|
15
|
+
>
|
16
|
+
<BreadcrumbsBar
|
17
|
+
breadcrumbItems={
|
18
|
+
Array [
|
13
19
|
Object {
|
14
20
|
"caption": "Subscriptions",
|
15
|
-
"
|
21
|
+
"url": "/subscriptions/",
|
16
22
|
},
|
17
23
|
Object {
|
18
24
|
"caption": "Add Subscriptions",
|
19
25
|
},
|
20
|
-
]
|
21
|
-
"isSwitchable": false,
|
26
|
+
]
|
22
27
|
}
|
23
|
-
|
24
|
-
|
28
|
+
isLoadingResources={false}
|
29
|
+
/>
|
30
|
+
</div>
|
25
31
|
<LoadingState
|
26
32
|
loading={false}
|
27
33
|
loadingText="Loading"
|