@rancher/shell 1.2.3 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/translations/en-us.yaml +49 -18
- package/assets/translations/zh-hans.yaml +1 -0
- package/cloud-credential/__tests__/harvester.test.ts +18 -0
- package/cloud-credential/harvester.vue +9 -1
- package/components/AlertTable.vue +17 -7
- package/components/GrafanaDashboard.vue +6 -4
- package/components/nav/Header.vue +9 -5
- package/components/nav/TopLevelMenu.vue +1 -4
- package/config/product/explorer.js +11 -4
- package/config/settings.ts +9 -2
- package/config/types.js +1 -1
- package/config/uiplugins.js +2 -2
- package/detail/catalog.cattle.io.app.vue +17 -4
- package/edit/management.cattle.io.setting.vue +15 -2
- package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +8 -2
- package/edit/provisioning.cattle.io.cluster/__tests__/RegistryConfigs.test.ts +61 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +386 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +73 -77
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest.vue +45 -0
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +97 -0
- package/mixins/chart.js +6 -2
- package/models/catalog.cattle.io.app.js +112 -21
- package/models/management.cattle.io.cluster.js +18 -6
- package/package.json +1 -1
- package/pages/c/_cluster/apps/charts/install.vue +2 -1
- package/plugins/dashboard-store/actions.js +3 -2
- package/scripts/extension/bundle +1 -1
- package/scripts/publish-shell.sh +62 -55
- package/scripts/test-plugins-build.sh +111 -29
- package/scripts/typegen.sh +26 -23
- package/store/catalog.js +1 -1
- package/store/features.js +1 -0
- package/store/type-map.utils.ts +44 -0
- package/types/shell/index.d.ts +2 -0
- package/types/store/dashboard-store.types.ts +23 -0
- package/types/store/vuex.d.ts +9 -0
- package/utils/cluster.js +9 -0
- package/utils/v-sphere.ts +277 -0
- package/.DS_Store +0 -0
- package/creators/app/app.package.json +0 -13
- package/creators/app/files/.eslintignore +0 -18
- package/creators/app/files/.eslintrc.js +0 -173
- package/creators/app/files/.gitignore +0 -70
- package/creators/app/files/.vscode/settings.json +0 -22
- package/creators/app/files/babel.config.js +0 -1
- package/creators/app/files/tsconfig.json +0 -42
- package/creators/app/files/vue.config.js +0 -6
- package/creators/app/init +0 -101
- package/creators/app/package.json +0 -25
- package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +0 -28
- package/creators/pkg/files/.github/workflows/build-extension-charts.yml +0 -26
- package/creators/pkg/files/babel.config.js +0 -1
- package/creators/pkg/files/index.ts +0 -14
- package/creators/pkg/files/tsconfig.json +0 -53
- package/creators/pkg/files/vue.config.js +0 -1
- package/creators/pkg/init +0 -254
- package/creators/pkg/package.json +0 -19
- package/creators/pkg/pkg.package.json +0 -21
- package/creators/pkg/vue-shim.ts +0 -4
- package/creators/update/init +0 -56
- package/creators/update/package.json +0 -20
- package/creators/update/upgrade +0 -56
|
@@ -355,9 +355,8 @@ addClusterMemberDialog:
|
|
|
355
355
|
title: Add Cluster Member
|
|
356
356
|
|
|
357
357
|
addonConfigConfirmation:
|
|
358
|
-
title: Add-On
|
|
359
|
-
body: Changing the Kubernetes Version can reset
|
|
360
|
-
|
|
358
|
+
title: Add-On Reset
|
|
359
|
+
body: Changing the Kubernetes Version can reset Add-On values. You should check that the values are as expected before continuing.
|
|
361
360
|
addProjectMemberDialog:
|
|
362
361
|
title: Add Project Member
|
|
363
362
|
|
|
@@ -1107,17 +1106,39 @@ cis:
|
|
|
1107
1106
|
|
|
1108
1107
|
cluster:
|
|
1109
1108
|
addonChart:
|
|
1110
|
-
rancher-vsphere-cpi:
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
rke2-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
rke2-
|
|
1120
|
-
|
|
1109
|
+
rancher-vsphere-cpi:
|
|
1110
|
+
label: "Add-on: vSphere CPI"
|
|
1111
|
+
configuration: vSphere CPI
|
|
1112
|
+
rancher-vsphere-csi:
|
|
1113
|
+
label: "Add-on: vSphere CSI"
|
|
1114
|
+
configuration: vSphere CSI
|
|
1115
|
+
rke2-calico:
|
|
1116
|
+
label: "Add-on: Calico"
|
|
1117
|
+
configuration: Calico
|
|
1118
|
+
rke2-calico-crd:
|
|
1119
|
+
label: "Add-on: Calico"
|
|
1120
|
+
configuration: Calico
|
|
1121
|
+
rke2-canal:
|
|
1122
|
+
label: "Add-on: Canal"
|
|
1123
|
+
configuration: Canal
|
|
1124
|
+
rke2-cilium:
|
|
1125
|
+
label: "Add-on: Cilium"
|
|
1126
|
+
configuration: Cilium
|
|
1127
|
+
rke2-coredns:
|
|
1128
|
+
label: "Add-on: CoreDNS"
|
|
1129
|
+
configuration: CoreDNS
|
|
1130
|
+
rke2-ingress-nginx:
|
|
1131
|
+
label: "Add-on: NGINX"
|
|
1132
|
+
configuration: NGINX Ingress
|
|
1133
|
+
rke2-kube-proxy:
|
|
1134
|
+
label: "Add-on: Kube Proxy"
|
|
1135
|
+
configuration: Kube Proxy
|
|
1136
|
+
rke2-metrics-server:
|
|
1137
|
+
label: "Add-on: Metrics Server"
|
|
1138
|
+
configuration: Metrics Server
|
|
1139
|
+
rke2-multus:
|
|
1140
|
+
label: "Add-on: Multus"
|
|
1141
|
+
configuration: Multus
|
|
1121
1142
|
agentEnvVars:
|
|
1122
1143
|
label: Agent Environment
|
|
1123
1144
|
detail: Add additional environment variables to the agent container. This is most commonly useful for configuring a HTTP proxy.
|
|
@@ -1133,7 +1154,7 @@ cluster:
|
|
|
1133
1154
|
label: Google
|
|
1134
1155
|
rancher-vsphere:
|
|
1135
1156
|
label: vSphere
|
|
1136
|
-
note: '<b>Important:</b> Configure the vSphere Cloud Provider and Storage Provider options in the Add-
|
|
1157
|
+
note: '<b>Important:</b> Configure the vSphere Cloud Provider and Storage Provider options in the Add-on tabs.'
|
|
1137
1158
|
harvester:
|
|
1138
1159
|
label: Harvester
|
|
1139
1160
|
copyConfig: Copy KubeConfig to Clipboard
|
|
@@ -1279,8 +1300,10 @@ cluster:
|
|
|
1279
1300
|
macAddress: Mac Address
|
|
1280
1301
|
macFormat: 'Invalid MAC address format.'
|
|
1281
1302
|
vGpus:
|
|
1303
|
+
warnings:
|
|
1304
|
+
minimumAllocatable: It's highly recommended to select a vGPU with a number of allocatable devices greater than the number of nodes (Machine Count) to avoid "un-schedulable" errors after cluster updates.
|
|
1282
1305
|
errors:
|
|
1283
|
-
notAllocatable: '
|
|
1306
|
+
notAllocatable: '[{vGpu}] vGPU device is not allocatable; required: {allocated}, allocatable: {allocatable}'
|
|
1284
1307
|
volume:
|
|
1285
1308
|
title: Volumes
|
|
1286
1309
|
volume: Volume
|
|
@@ -1300,6 +1323,7 @@ cluster:
|
|
|
1300
1323
|
placeholder: 'Namespace/Name'
|
|
1301
1324
|
cluster: Imported Harvester Cluster
|
|
1302
1325
|
installGuestAgent: Install guest agent
|
|
1326
|
+
tokenExpirationWarning: 'Warning: Harvester Cloud Credentials use an underlying authentication token that may have an expiry time - please see the following <a href="https://harvesterhci.io/kb/renew_harvester_cloud_credentials" target="_blank" rel="noopener nofollow">knowledge base article</a> for possible implications on management operations.'
|
|
1303
1327
|
description:
|
|
1304
1328
|
label: Cluster Description
|
|
1305
1329
|
placeholder: Any text you want that better describes this cluster
|
|
@@ -1632,7 +1656,7 @@ cluster:
|
|
|
1632
1656
|
serverOs:
|
|
1633
1657
|
label: OS
|
|
1634
1658
|
addOns:
|
|
1635
|
-
dependencyBanner: Add-On
|
|
1659
|
+
dependencyBanner: Add-On Configuration can vary between Kubernetes versions. Changing the Kubernetes version may reset the values below.
|
|
1636
1660
|
additionalManifest:
|
|
1637
1661
|
title: Additional Manifest
|
|
1638
1662
|
tooltip: 'Additional Kubernetes Manifest YAML to be applied to the cluster on startup.'
|
|
@@ -1818,6 +1842,7 @@ cluster:
|
|
|
1818
1842
|
oracleoke: Oracle OKE
|
|
1819
1843
|
otc: Open Telekom Cloud
|
|
1820
1844
|
other: Other
|
|
1845
|
+
ovhcloudmks: OVHcloud MKS
|
|
1821
1846
|
packet: Equinix Metal
|
|
1822
1847
|
pinganyunecs: Pinganyun ECS
|
|
1823
1848
|
pnap: phoenixNAP
|
|
@@ -1979,7 +2004,7 @@ cluster:
|
|
|
1979
2004
|
s3: s3
|
|
1980
2005
|
tabs:
|
|
1981
2006
|
ace: Authorized Endpoint
|
|
1982
|
-
|
|
2007
|
+
addOnAdditionalManifest: Additional Manifest
|
|
1983
2008
|
advanced: Advanced
|
|
1984
2009
|
agentEnv: Agent Environment Vars
|
|
1985
2010
|
basic: Basics
|
|
@@ -7128,6 +7153,9 @@ advancedSettings:
|
|
|
7128
7153
|
'ui-default-landing': 'The default page users land on after login.'
|
|
7129
7154
|
'brand': Folder name for an alternative theme defined in '/assets/brand'
|
|
7130
7155
|
'hide-local-cluster': Hide the local cluster
|
|
7156
|
+
'agent-tls-mode': "Rancher Certificate Verification. In `strict` mode the agents (system, cluster, fleet, etc) will only trust Rancher installations which are using a certificate signed by the CABundle in the `cacerts` setting. When the mode is system-store, the agents will trust any certificate signed by a CABundle in the operating system’s trust store."
|
|
7157
|
+
warnings:
|
|
7158
|
+
'agent-tls-mode': 'Changing this setting will cause all agents to be redeployed.'
|
|
7131
7159
|
editHelp:
|
|
7132
7160
|
'ui-banners': This setting takes a JSON object containing 3 root parameters; <code>banner</code>, <code>showHeader</code>, <code>showFooter</code>. <code>banner</code> is an object containing; <code>textColor</code>, <code>background</code>, and <code>text</code>, where <code>textColor</code> and <code>background</code> are any valid CSS color value.
|
|
7133
7161
|
enum:
|
|
@@ -7150,6 +7178,9 @@ advancedSettings:
|
|
|
7150
7178
|
info: Info
|
|
7151
7179
|
debug: Debug
|
|
7152
7180
|
trace: Trace
|
|
7181
|
+
'agent-tls-mode':
|
|
7182
|
+
strict: 'Strict'
|
|
7183
|
+
system-store: 'System Store'
|
|
7153
7184
|
|
|
7154
7185
|
featureFlags:
|
|
7155
7186
|
label: Feature Flags
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import HarvesterCloudCreds from '@shell/cloud-credential/harvester.vue';
|
|
3
|
+
|
|
4
|
+
const mockStore = { getters: { 'i18n/t': jest.fn() } };
|
|
5
|
+
|
|
6
|
+
describe('cloud credentials: Harvester', () => {
|
|
7
|
+
const wrapper = mount(HarvesterCloudCreds, {
|
|
8
|
+
propsData: { value: {} },
|
|
9
|
+
mocks: { $store: mockStore }
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('should display the warning banner for token expiration', async() => {
|
|
13
|
+
const warningBanner = wrapper.find('[data-testid="harvester-token-expiration-warning-banner"]');
|
|
14
|
+
|
|
15
|
+
expect(warningBanner.exists()).toBe(true);
|
|
16
|
+
expect(warningBanner.isVisible()).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
3
3
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
4
|
+
import { Banner } from '@components/Banner';
|
|
4
5
|
|
|
5
6
|
import { get, set } from '@shell/utils/object';
|
|
6
7
|
import { MANAGEMENT, VIRTUAL_HARVESTER_PROVIDER } from '@shell/config/types';
|
|
7
8
|
|
|
8
9
|
export default {
|
|
9
|
-
components: { LabeledSelect },
|
|
10
|
+
components: { LabeledSelect, Banner },
|
|
10
11
|
mixins: [CreateEditView],
|
|
11
12
|
|
|
12
13
|
async fetch() {
|
|
@@ -97,6 +98,13 @@ export default {
|
|
|
97
98
|
|
|
98
99
|
<template>
|
|
99
100
|
<div>
|
|
101
|
+
<div class="row mb-10">
|
|
102
|
+
<Banner
|
|
103
|
+
color="warning"
|
|
104
|
+
label-key="cluster.credential.harvester.tokenExpirationWarning"
|
|
105
|
+
data-testid="harvester-token-expiration-warning-banner"
|
|
106
|
+
/>
|
|
107
|
+
</div>
|
|
100
108
|
<div class="row mb-10">
|
|
101
109
|
<div
|
|
102
110
|
class="col span-6"
|
|
@@ -49,6 +49,7 @@ export default {
|
|
|
49
49
|
];
|
|
50
50
|
|
|
51
51
|
return {
|
|
52
|
+
inStore: this.$store.getters['currentProduct'].inStore,
|
|
52
53
|
alertManagerPoller: new Poller(
|
|
53
54
|
this.loadAlertManagerEvents,
|
|
54
55
|
ALERTMANAGER_POLL_RATE_MS,
|
|
@@ -69,15 +70,24 @@ export default {
|
|
|
69
70
|
},
|
|
70
71
|
|
|
71
72
|
methods: {
|
|
72
|
-
async
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
{ url: `/k8s/clusters/${ this.currentCluster.id }/api/v1/namespaces/${ this.monitoringNamespace }/services/http:${ this.alertServiceEndpoint }:9093/proxy/api/v1/alerts` }
|
|
73
|
+
async fetchAlertManagerEvents(version) {
|
|
74
|
+
return await this.$store.dispatch(
|
|
75
|
+
`${ this.inStore }/request`,
|
|
76
|
+
{ url: `/k8s/clusters/${ this.currentCluster.id }/api/v1/namespaces/${ this.monitoringNamespace }/services/http:${ this.alertServiceEndpoint }:9093/proxy/api/${ version }/alerts` }
|
|
77
77
|
);
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
async loadAlertManagerEvents() {
|
|
81
|
+
let alertEvents;
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
alertEvents = await this.fetchAlertManagerEvents('v2');
|
|
85
|
+
} catch (err) {
|
|
86
|
+
alertEvents = await this.fetchAlertManagerEvents('v1').then((res) => res?.data);
|
|
87
|
+
}
|
|
78
88
|
|
|
79
|
-
if (
|
|
80
|
-
this.allAlerts =
|
|
89
|
+
if (alertEvents) {
|
|
90
|
+
this.allAlerts = alertEvents;
|
|
81
91
|
}
|
|
82
92
|
},
|
|
83
93
|
|
|
@@ -114,10 +114,12 @@ export default {
|
|
|
114
114
|
this.interval = setInterval(() => {
|
|
115
115
|
try {
|
|
116
116
|
const graphWindow = this.$refs.frame?.contentWindow;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
const
|
|
117
|
+
|
|
118
|
+
// Note. getElementsByClassName won't work, following a grafana bump class names are now unique - for example css-2qng6u-panel-container
|
|
119
|
+
const errorElements = graphWindow.document.querySelectorAll('[class$="alert-error');
|
|
120
|
+
const errorCornerElements = graphWindow.document.querySelectorAll('[class$="panel-info-corner--error');
|
|
121
|
+
const panelInFullScreenElements = graphWindow.document.querySelectorAll('[class$="panel-in-fullscreen');
|
|
122
|
+
const panelContainerElements = graphWindow.document.querySelectorAll('[class$="panel-container');
|
|
121
123
|
const error = errorElements.length > 0 || errorCornerElements.length > 0;
|
|
122
124
|
const loaded = panelInFullScreenElements.length > 0 || panelContainerElements.length > 0;
|
|
123
125
|
const errorMessageElms = graphWindow.document.getElementsByTagName('pre');
|
|
@@ -178,12 +178,16 @@ export default {
|
|
|
178
178
|
}
|
|
179
179
|
},
|
|
180
180
|
// since the Header is a "persistent component" we need to update it at every route change...
|
|
181
|
-
$route
|
|
182
|
-
|
|
183
|
-
|
|
181
|
+
$route: {
|
|
182
|
+
handler(nue) {
|
|
183
|
+
if (nue) {
|
|
184
|
+
this.extensionHeaderActions = getApplicableExtensionEnhancements(this, ExtensionPoint.ACTION, ActionLocation.HEADER, nue);
|
|
184
185
|
|
|
185
|
-
|
|
186
|
-
|
|
186
|
+
this.navHeaderRight = this.$plugin?.getDynamic('component', 'NavHeaderRight');
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
immediate: true,
|
|
190
|
+
deep: true,
|
|
187
191
|
}
|
|
188
192
|
},
|
|
189
193
|
|
|
@@ -855,7 +855,7 @@ export default {
|
|
|
855
855
|
}
|
|
856
856
|
}
|
|
857
857
|
|
|
858
|
-
> i {
|
|
858
|
+
> i, > img {
|
|
859
859
|
display: block;
|
|
860
860
|
width: 42px;
|
|
861
861
|
font-size: $icon-size;
|
|
@@ -867,9 +867,6 @@ export default {
|
|
|
867
867
|
margin-right: 16px;
|
|
868
868
|
fill: var(--link);
|
|
869
869
|
}
|
|
870
|
-
img {
|
|
871
|
-
margin-right: 16px;
|
|
872
|
-
}
|
|
873
870
|
|
|
874
871
|
&.nuxt-link-active {
|
|
875
872
|
background: var(--primary-hover-bg);
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
} from '@shell/config/table-headers';
|
|
23
23
|
|
|
24
24
|
import { DSL } from '@shell/store/type-map';
|
|
25
|
+
import { configureConditionalDepaginate } from '@shell/store/type-map.utils';
|
|
25
26
|
|
|
26
27
|
export const NAME = 'explorer';
|
|
27
28
|
|
|
@@ -49,7 +50,9 @@ export function init(store) {
|
|
|
49
50
|
typeStoreMap: {
|
|
50
51
|
[MANAGEMENT.PROJECT]: 'management',
|
|
51
52
|
[MANAGEMENT.CLUSTER_ROLE_TEMPLATE_BINDING]: 'management',
|
|
52
|
-
[MANAGEMENT.PROJECT_ROLE_TEMPLATE_BINDING]: 'management'
|
|
53
|
+
[MANAGEMENT.PROJECT_ROLE_TEMPLATE_BINDING]: 'management',
|
|
54
|
+
[NORMAN.CLUSTER_ROLE_TEMPLATE_BINDING]: 'rancher',
|
|
55
|
+
[NORMAN.PROJECT_ROLE_TEMPLATE_BINDING]: 'rancher',
|
|
53
56
|
}
|
|
54
57
|
});
|
|
55
58
|
|
|
@@ -156,12 +159,16 @@ export function init(store) {
|
|
|
156
159
|
mapGroup(/^(.*\.)?cluster\.x-k8s\.io$/, 'clusterProvisioning');
|
|
157
160
|
mapGroup(/^(aks|eks|gke|rke|rke-machine-config|rke-machine|provisioning)\.cattle\.io$/, 'clusterProvisioning');
|
|
158
161
|
|
|
162
|
+
const dePaginateBindings = configureConditionalDepaginate({ maxResourceCount: 5000 });
|
|
163
|
+
const dePaginateNormanBindings = configureConditionalDepaginate({ maxResourceCount: 5000, isNorman: true }) ;
|
|
164
|
+
|
|
159
165
|
configureType(NODE, { isCreatable: false, isEditable: true });
|
|
160
166
|
configureType(WORKLOAD_TYPES.JOB, { isEditable: false, match: WORKLOAD_TYPES.JOB });
|
|
161
|
-
configureType(MANAGEMENT.CLUSTER_ROLE_TEMPLATE_BINDING, { isEditable: false });
|
|
162
|
-
configureType(MANAGEMENT.PROJECT_ROLE_TEMPLATE_BINDING, { isEditable: false, depaginate:
|
|
167
|
+
configureType(MANAGEMENT.CLUSTER_ROLE_TEMPLATE_BINDING, { isEditable: false, depaginate: dePaginateBindings });
|
|
168
|
+
configureType(MANAGEMENT.PROJECT_ROLE_TEMPLATE_BINDING, { isEditable: false, depaginate: dePaginateBindings });
|
|
163
169
|
configureType(MANAGEMENT.PROJECT, { displayName: store.getters['i18n/t']('namespace.project.label') });
|
|
164
|
-
configureType(NORMAN.
|
|
170
|
+
configureType(NORMAN.CLUSTER_ROLE_TEMPLATE_BINDING, { depaginate: dePaginateNormanBindings });
|
|
171
|
+
configureType(NORMAN.PROJECT_ROLE_TEMPLATE_BINDING, { depaginate: dePaginateNormanBindings });
|
|
165
172
|
|
|
166
173
|
configureType(EVENT, { limit: 500 });
|
|
167
174
|
weightType(EVENT, -1, true);
|
package/config/settings.ts
CHANGED
|
@@ -19,7 +19,8 @@ interface GlobalSetting {
|
|
|
19
19
|
/**
|
|
20
20
|
* Function used from the form validation
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
ruleSet?: GlobalSettingRuleset[],
|
|
23
|
+
warning?: string
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
|
|
@@ -90,8 +91,9 @@ export const SETTING = {
|
|
|
90
91
|
FLEET_AGENT_DEFAULT_AFFINITY: 'fleet-agent-default-affinity',
|
|
91
92
|
/**
|
|
92
93
|
* manage rancher repositories in extensions (official, partners repos)
|
|
93
|
-
|
|
94
|
+
*/
|
|
94
95
|
ADD_EXTENSION_REPOS_BANNER_DISPLAY: 'display-add-extension-repos-banner',
|
|
96
|
+
AGENT_TLS_MODE: 'agent-tls-mode',
|
|
95
97
|
/**
|
|
96
98
|
* User retention settings
|
|
97
99
|
*/
|
|
@@ -152,6 +154,11 @@ export const ALLOWED_SETTINGS: GlobalSetting = {
|
|
|
152
154
|
options: ['prompt', 'in', 'out']
|
|
153
155
|
},
|
|
154
156
|
[SETTING.HIDE_LOCAL_CLUSTER]: { kind: 'boolean' },
|
|
157
|
+
[SETTING.AGENT_TLS_MODE]: {
|
|
158
|
+
kind: 'enum',
|
|
159
|
+
options: ['strict', 'system-store'],
|
|
160
|
+
warning: 'agent-tls-mode'
|
|
161
|
+
},
|
|
155
162
|
};
|
|
156
163
|
|
|
157
164
|
/**
|
package/config/types.js
CHANGED
|
@@ -14,7 +14,7 @@ export const NORMAN = {
|
|
|
14
14
|
ETCD_BACKUP: 'etcdbackup',
|
|
15
15
|
CLUSTER: 'cluster',
|
|
16
16
|
CLUSTER_TOKEN: 'clusterregistrationtoken',
|
|
17
|
-
CLUSTER_ROLE_TEMPLATE_BINDING: '
|
|
17
|
+
CLUSTER_ROLE_TEMPLATE_BINDING: 'clusterroletemplatebinding',
|
|
18
18
|
CLOUD_CREDENTIAL: 'cloudcredential',
|
|
19
19
|
FLEET_WORKSPACES: 'fleetworkspace',
|
|
20
20
|
GLOBAL_ROLE: 'globalRole',
|
package/config/uiplugins.js
CHANGED
|
@@ -178,7 +178,7 @@ export function isChartVersionAvailableForInstall(versionsData, returnObj = fals
|
|
|
178
178
|
|
|
179
179
|
const parsedRancherVersion = rancherVersion.split('-')?.[0];
|
|
180
180
|
const regexHashString = new RegExp('^[A-Za-z0-9]{9}$');
|
|
181
|
-
const
|
|
181
|
+
const isRancherVersionHashStringOrHead = regexHashString.test(rancherVersion) || rancherVersion.includes('head');
|
|
182
182
|
const requiredUiVersion = version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.UI_VERSION];
|
|
183
183
|
const requiredKubeVersion = version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.KUBE_VERSION];
|
|
184
184
|
const versionObj = { ...version };
|
|
@@ -187,7 +187,7 @@ export function isChartVersionAvailableForInstall(versionsData, returnObj = fals
|
|
|
187
187
|
versionObj.isCompatibleWithKubeVersion = true;
|
|
188
188
|
|
|
189
189
|
// if it's a head version of Rancher, then we skip the validation and enable them all
|
|
190
|
-
if (!
|
|
190
|
+
if (!isRancherVersionHashStringOrHead && requiredUiVersion && !semver.satisfies(parsedRancherVersion, requiredUiVersion)) {
|
|
191
191
|
if (!returnObj) {
|
|
192
192
|
return false;
|
|
193
193
|
}
|
|
@@ -9,7 +9,8 @@ import RelatedResources from '@shell/components/RelatedResources';
|
|
|
9
9
|
import jsyaml from 'js-yaml';
|
|
10
10
|
import merge from 'lodash/merge';
|
|
11
11
|
import { CATALOG } from '@shell/config/types';
|
|
12
|
-
import { sortBy } from '
|
|
12
|
+
import { sortBy } from '@shell/utils/sort';
|
|
13
|
+
import { allHash } from '@shell/utils/promise';
|
|
13
14
|
|
|
14
15
|
export default {
|
|
15
16
|
name: 'DetailRelease',
|
|
@@ -30,9 +31,15 @@ export default {
|
|
|
30
31
|
},
|
|
31
32
|
|
|
32
33
|
async fetch() {
|
|
33
|
-
|
|
34
|
+
const promises = {
|
|
35
|
+
catalog: this.$store.dispatch('catalog/load', { force: true, reset: true }),
|
|
36
|
+
allOperations: this.$store.dispatch('cluster/findAll', { type: CATALOG.OPERATION }),
|
|
37
|
+
secrets: this.value.fetchValues(true),
|
|
38
|
+
};
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
const res = await allHash(promises);
|
|
41
|
+
|
|
42
|
+
this.allOperations = res.allOperations;
|
|
36
43
|
},
|
|
37
44
|
|
|
38
45
|
computed: {
|
|
@@ -45,7 +52,7 @@ export default {
|
|
|
45
52
|
},
|
|
46
53
|
|
|
47
54
|
valuesYaml() {
|
|
48
|
-
const combined = merge(merge({}, this.value?.
|
|
55
|
+
const combined = merge(merge({}, this.value?.chartValues || {}), this.value?.values || {});
|
|
49
56
|
|
|
50
57
|
return jsyaml.dump(combined);
|
|
51
58
|
},
|
|
@@ -95,6 +102,12 @@ export default {
|
|
|
95
102
|
}
|
|
96
103
|
},
|
|
97
104
|
},
|
|
105
|
+
|
|
106
|
+
watch: {
|
|
107
|
+
'value.secretId'(neu, old) {
|
|
108
|
+
this.value.fetchValues(true);
|
|
109
|
+
}
|
|
110
|
+
},
|
|
98
111
|
};
|
|
99
112
|
</script>
|
|
100
113
|
|
|
@@ -4,6 +4,7 @@ import { LabeledInput } from '@components/Form/LabeledInput';
|
|
|
4
4
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
5
5
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
6
6
|
import { TextAreaAutoGrow } from '@components/Form/TextArea';
|
|
7
|
+
import { Banner } from '@components/Banner';
|
|
7
8
|
import formRulesGenerator from '@shell/utils/validators/formRules/index';
|
|
8
9
|
|
|
9
10
|
import { ALLOWED_SETTINGS, SETTING } from '@shell/config/settings';
|
|
@@ -18,7 +19,8 @@ export default {
|
|
|
18
19
|
LabeledInput,
|
|
19
20
|
LabeledSelect,
|
|
20
21
|
RadioGroup,
|
|
21
|
-
TextAreaAutoGrow
|
|
22
|
+
TextAreaAutoGrow,
|
|
23
|
+
Banner,
|
|
22
24
|
},
|
|
23
25
|
|
|
24
26
|
mixins: [CreateEditView, FormValidation],
|
|
@@ -63,7 +65,11 @@ export default {
|
|
|
63
65
|
|
|
64
66
|
return factoryArg ? rule(factoryArg) : rule;
|
|
65
67
|
}) : {};
|
|
66
|
-
}
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
showWarningBanner() {
|
|
71
|
+
return this.setting?.warning;
|
|
72
|
+
},
|
|
67
73
|
},
|
|
68
74
|
|
|
69
75
|
methods: {
|
|
@@ -118,6 +124,13 @@ export default {
|
|
|
118
124
|
@finish="saveSettings"
|
|
119
125
|
@cancel="done"
|
|
120
126
|
>
|
|
127
|
+
<Banner
|
|
128
|
+
v-if="showWarningBanner"
|
|
129
|
+
color="warning"
|
|
130
|
+
:label="t(`advancedSettings.warnings.${ setting.warning }`)"
|
|
131
|
+
data-testid="advanced_settings_warning_banner"
|
|
132
|
+
/>
|
|
133
|
+
|
|
121
134
|
<h4>{{ description }}</h4>
|
|
122
135
|
|
|
123
136
|
<h5
|
|
@@ -7,6 +7,7 @@ import SelectOrCreateAuthSecret from '@shell/components/form/SelectOrCreateAuthS
|
|
|
7
7
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
8
8
|
import SecretSelector from '@shell/components/form/SecretSelector';
|
|
9
9
|
import { SECRET_TYPES as TYPES } from '@shell/config/secret';
|
|
10
|
+
import { base64Decode, base64Encode } from '@shell/utils/crypto';
|
|
10
11
|
|
|
11
12
|
export default {
|
|
12
13
|
components: {
|
|
@@ -55,7 +56,7 @@ export default {
|
|
|
55
56
|
if (configMap[hostname]) {
|
|
56
57
|
configMap[hostname].insecureSkipVerify = configMap[hostname].insecureSkipVerify ?? defaultAddValue.insecureSkipVerify;
|
|
57
58
|
configMap[hostname].authConfigSecretName = configMap[hostname].authConfigSecretName ?? defaultAddValue.authConfigSecretName;
|
|
58
|
-
configMap[hostname].caBundle = configMap[hostname].caBundle ?? defaultAddValue.caBundle;
|
|
59
|
+
configMap[hostname].caBundle = base64Decode(configMap[hostname].caBundle ?? defaultAddValue.caBundle);
|
|
59
60
|
configMap[hostname].tlsSecretName = configMap[hostname].tlsSecretName ?? defaultAddValue.tlsSecretName;
|
|
60
61
|
}
|
|
61
62
|
entries.push({
|
|
@@ -94,7 +95,11 @@ export default {
|
|
|
94
95
|
continue;
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
configs[h] = {
|
|
98
|
+
configs[h] = {
|
|
99
|
+
...entry,
|
|
100
|
+
caBundle: base64Encode(entry.caBundle)
|
|
101
|
+
};
|
|
102
|
+
|
|
98
103
|
delete configs[h].hostname;
|
|
99
104
|
}
|
|
100
105
|
|
|
@@ -174,6 +179,7 @@ export default {
|
|
|
174
179
|
|
|
175
180
|
<LabeledInput
|
|
176
181
|
v-model="row.value.caBundle"
|
|
182
|
+
:data-testid="`registry-caBundle-${i}`"
|
|
177
183
|
class="mt-20"
|
|
178
184
|
type="multiline"
|
|
179
185
|
label="CA Cert Bundle"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { mount, Wrapper } from '@vue/test-utils';
|
|
2
|
+
import { clone } from '@shell/utils/object';
|
|
3
|
+
import { _EDIT } from '@shell/config/query-params';
|
|
4
|
+
import { PROV_CLUSTER } from '@shell/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster';
|
|
5
|
+
import RegistryConfigs from '@shell/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue';
|
|
6
|
+
|
|
7
|
+
describe('component: RegistryConfigs', () => {
|
|
8
|
+
let wrapper: Wrapper<InstanceType<typeof RegistryConfigs> & { [key: string]: any }>;
|
|
9
|
+
|
|
10
|
+
const mountOptions = {
|
|
11
|
+
propsData: {
|
|
12
|
+
value: {},
|
|
13
|
+
mode: _EDIT,
|
|
14
|
+
clusterRegisterBeforeHook: () => {}
|
|
15
|
+
},
|
|
16
|
+
stubs: {
|
|
17
|
+
SelectOrCreateAuthSecret: true,
|
|
18
|
+
SecretSelector: true,
|
|
19
|
+
},
|
|
20
|
+
mocks: { $store: { getters: { 'i18n/t': jest.fn() } } }
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
describe('key CA Cert Bundle', () => {
|
|
24
|
+
it('should display default key', () => {
|
|
25
|
+
const value = clone(PROV_CLUSTER);
|
|
26
|
+
|
|
27
|
+
value.spec.rkeConfig.registries.configs = { foo: { caBundle: 'Zm9vYmFy' } };
|
|
28
|
+
|
|
29
|
+
mountOptions.propsData.value = value;
|
|
30
|
+
|
|
31
|
+
wrapper = mount(
|
|
32
|
+
RegistryConfigs,
|
|
33
|
+
mountOptions
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const registry = wrapper.find('[data-testid^="registry-caBundle"]').element as HTMLTextAreaElement;
|
|
37
|
+
|
|
38
|
+
expect(registry.value).toBe('foobar');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should update key in base64 format', async() => {
|
|
42
|
+
const value = clone(PROV_CLUSTER);
|
|
43
|
+
|
|
44
|
+
value.spec.rkeConfig.registries.configs = { foo: { caBundle: 'Zm9vYmFy' } };
|
|
45
|
+
|
|
46
|
+
mountOptions.propsData.value = value;
|
|
47
|
+
|
|
48
|
+
wrapper = mount(
|
|
49
|
+
RegistryConfigs,
|
|
50
|
+
mountOptions
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const registry = wrapper.find('[data-testid^="registry-caBundle"]');
|
|
54
|
+
|
|
55
|
+
await registry.setValue('ssh key');
|
|
56
|
+
wrapper.vm.update();
|
|
57
|
+
|
|
58
|
+
expect(wrapper.emitted('updateConfigs')![0][0]['foo']['caBundle']).toBe('c3NoIGtleQ==');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|