@rancher/shell 0.4.0 → 0.5.0
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/images/providers/ovhcloudmks.svg +122 -0
- package/assets/images/providers/ovhcloudpubliccloud.svg +122 -0
- package/assets/styles/global/_layout.scss +99 -0
- package/assets/translations/en-us.yaml +30 -5
- package/assets/translations/zh-hans.yaml +1 -1
- package/babel.config.js +7 -1
- package/chart/monitoring/alerting/index.vue +7 -21
- package/chart/monitoring/grafana/index.vue +55 -0
- package/chart/monitoring/index.vue +51 -17
- package/chart/monitoring/prometheus/index.vue +37 -43
- package/chart/rancher-backup/index.vue +2 -1
- package/cloud-credential/azure.vue +4 -17
- package/components/AsyncButton.vue +17 -5
- package/components/Certificates.vue +164 -0
- package/components/CodeMirror.vue +19 -21
- package/components/CruResource.vue +1 -0
- package/components/DraggableZone.vue +2 -2
- package/components/EtcdInfoBanner.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +25 -1
- package/components/IconOrSvg.vue +1 -1
- package/components/LandingPagePreference.vue +1 -4
- package/components/PodSecurityAdmission.vue +2 -2
- package/components/Questions/index.vue +1 -1
- package/components/ResourceDetail/Masthead.vue +16 -3
- package/components/ResourceTable.vue +14 -2
- package/components/ResourceYaml.vue +5 -0
- package/components/SideNav.vue +1 -1
- package/components/SingleClusterInfo.vue +1 -4
- package/components/Tabbed/index.vue +12 -0
- package/components/fleet/FleetRepos.vue +62 -27
- package/components/fleet/FleetResources.vue +6 -1
- package/components/form/ArrayListSelect.vue +10 -0
- package/components/form/Error.vue +3 -3
- package/components/form/Footer.vue +2 -2
- package/components/form/GitPicker.vue +83 -38
- package/components/form/KeyValue.vue +4 -0
- package/components/form/LabeledSelect.vue +4 -0
- package/components/formatter/Checked.vue +11 -3
- package/components/formatter/FleetClusterSummaryGraph.vue +27 -0
- package/components/formatter/FleetSummaryGraph.vue +23 -11
- package/components/formatter/LiveDuration.vue +1 -1
- package/components/formatter/PercentageBar.vue +1 -1
- package/components/formatter/__tests__/Checked.test.ts +19 -0
- package/components/nav/Group.vue +2 -2
- package/components/nav/Header.vue +0 -1
- package/components/nav/TopLevelMenu.vue +36 -6
- package/components/nav/Type.vue +1 -3
- package/components/nav/WindowManager/ContainerLogs.vue +101 -3
- package/components/nav/WindowManager/ContainerShell.vue +6 -1
- package/components/nav/WindowManager/__tests__/ContainerLogs.test.ts +186 -0
- package/components/nav/WindowManager/index.vue +11 -10
- package/components/nav/__tests__/TopLevelMenu.test.ts +33 -0
- package/components/nav/__tests__/Type.test.ts +1 -1
- package/components/nuxt/nuxt-child.js +14 -78
- package/components/nuxt/nuxt.js +1 -1
- package/{layouts → components/templates}/blank.vue +1 -1
- package/{layouts → components/templates}/default.vue +8 -98
- package/{layouts → components/templates}/error.vue +10 -19
- package/{layouts → components/templates}/home.vue +4 -1
- package/{layouts → components/templates}/plain.vue +4 -1
- package/{layouts → components/templates}/standalone.vue +1 -1
- package/{layouts → components/templates}/unauthenticated.vue +1 -1
- package/composables/useCompactInput.test.ts +36 -0
- package/composables/useCompactInput.ts +20 -0
- package/composables/useLabeledFormElement.test.ts +135 -0
- package/composables/useLabeledFormElement.ts +138 -0
- package/config/harvester-manager-types.js +2 -0
- package/config/private-label.js +22 -0
- package/config/product/explorer.js +3 -0
- package/config/product/fleet.js +6 -1
- package/config/product/manager.js +8 -2
- package/config/query-params.js +1 -0
- package/config/router.js +385 -364
- package/config/settings.ts +1 -0
- package/config/store.js +1 -1
- package/config/system-namespaces.js +3 -0
- package/config/table-headers.js +47 -0
- package/core/plugin-routes.ts +56 -114
- package/core/plugin.ts +16 -10
- package/core/plugins-loader.js +7 -9
- package/core/plugins.js +0 -3
- package/creators/app/files/.gitlab-ci.yml +1 -1
- package/detail/fleet.cattle.io.cluster.vue +11 -1
- package/detail/provisioning.cattle.io.cluster.vue +4 -3
- package/dialog/ScaleMachineDownDialog.vue +34 -17
- package/edit/__tests__/service.test.ts +89 -0
- package/edit/auth/googleoauth.vue +1 -5
- package/edit/cloudcredential.vue +2 -0
- package/edit/configmap.vue +2 -1
- package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +2 -2
- package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +1 -1
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +15 -7
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +112 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +473 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/{CustomCommand.tests.ts → CustomCommand.test.ts} +4 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +1 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +73 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +7 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +386 -0
- package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/index.vue +92 -36
- package/edit/provisioning.cattle.io.cluster/rke2.vue +171 -583
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +137 -0
- package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +157 -0
- package/edit/provisioning.cattle.io.cluster/{Basics.vue → tabs/Basics.vue} +94 -19
- package/edit/provisioning.cattle.io.cluster/{MachinePool.vue → tabs/MachinePool.vue} +1 -0
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +135 -0
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +189 -0
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +144 -0
- package/edit/provisioning.cattle.io.cluster/tabs/upgrade/index.vue +76 -0
- package/edit/service.vue +12 -0
- package/edit/workload/mixins/workload.js +1 -1
- package/initialize/App.js +25 -71
- package/initialize/client.js +21 -162
- package/initialize/index.js +27 -123
- package/list/management.cattle.io.feature.vue +1 -7
- package/list/node.vue +1 -0
- package/machine-config/__tests__/vmwarevsphere.test.ts +100 -21
- package/machine-config/vmwarevsphere.vue +73 -51
- package/middleware/authenticated.js +10 -17
- package/mixins/auth-config.js +2 -7
- package/mixins/brand.js +29 -41
- package/mixins/create-edit-view/index.js +2 -2
- package/mixins/labeled-form-element.ts +6 -1
- package/models/__tests__/management.cattle.io.node.ts +85 -0
- package/models/__tests__/management.cattle.io.nodepool.ts +83 -0
- package/models/__tests__/namespace.test.ts +49 -9
- package/models/__tests__/workload.test.ts +91 -0
- package/models/cluster/node.js +4 -4
- package/models/cluster.x-k8s.io.machinedeployment.js +14 -0
- package/models/fleet.cattle.io.cluster.js +4 -0
- package/models/fleet.cattle.io.gitrepo.js +56 -13
- package/models/management.cattle.io.kontainerdriver.js +1 -1
- package/models/management.cattle.io.node.js +18 -14
- package/models/management.cattle.io.nodepool.js +17 -0
- package/models/namespace.js +1 -1
- package/models/pod.js +20 -0
- package/models/provisioning.cattle.io.cluster.js +20 -3
- package/models/secret.js +117 -18
- package/models/workload.js +16 -0
- package/models/workload.service.js +18 -0
- package/package.json +10 -9
- package/pages/about.vue +0 -1
- package/pages/account/create-key.vue +0 -1
- package/pages/account/index.vue +0 -1
- package/pages/auth/login.vue +0 -1
- package/pages/auth/logout.vue +0 -2
- package/pages/auth/setup.vue +0 -4
- package/pages/auth/verify.vue +14 -8
- package/pages/c/_cluster/apps/charts/install.vue +4 -4
- package/pages/c/_cluster/apps/index.vue +0 -2
- package/pages/c/_cluster/auth/index.vue +0 -2
- package/pages/c/_cluster/ecm/index.vue +0 -2
- package/pages/c/_cluster/explorer/index.vue +28 -2
- package/pages/c/_cluster/fleet/index.vue +1 -1
- package/pages/c/_cluster/index.vue +0 -2
- package/pages/c/_cluster/settings/banners.vue +0 -2
- package/pages/c/_cluster/settings/brand.vue +0 -2
- package/pages/c/_cluster/settings/index.vue +0 -2
- package/pages/c/_cluster/settings/links.vue +0 -1
- package/pages/c/_cluster/settings/performance.vue +0 -1
- package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +2 -1
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +10 -46
- package/pages/c/_cluster/uiplugins/index.vue +0 -2
- package/pages/diagnostic.vue +1 -2
- package/pages/fail-whale.vue +0 -1
- package/pages/prefs.vue +0 -1
- package/pages/support/index.vue +2 -8
- package/pkg/auto-import.js +1 -1
- package/plugins/axios.js +0 -36
- package/plugins/back-button.js +3 -5
- package/plugins/codemirror-loader.js +1 -1
- package/plugins/codemirror.js +41 -0
- package/plugins/dashboard-store/__tests__/{mutations.spec.ts → mutations.test.ts} +1 -1
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +49 -0
- package/plugins/dashboard-store/__tests__/utils/store-mocks.ts +7 -0
- package/plugins/dashboard-store/actions.js +30 -4
- package/plugins/dashboard-store/classify.js +1 -18
- package/plugins/dashboard-store/getters.js +10 -5
- package/plugins/dashboard-store/index.js +0 -12
- package/plugins/dashboard-store/mutations.js +0 -4
- package/plugins/dashboard-store/resource-class.js +59 -18
- package/plugins/steve/__tests__/steve-class.spec.ts +59 -0
- package/plugins/steve/__tests__/utils/steve-mocks.ts +31 -0
- package/plugins/steve/getters.js +4 -1
- package/plugins/steve/norman-class.js +19 -0
- package/plugins/steve/steve-class.js +22 -0
- package/plugins/steve/subscribe.js +4 -10
- package/rancher-components/Accordion/Accordion.test.ts +45 -0
- package/rancher-components/Accordion/Accordion.vue +86 -0
- package/rancher-components/Accordion/index.ts +1 -0
- package/rancher-components/BadgeState/BadgeState.vue +3 -3
- package/rancher-components/Banner/Banner.vue +2 -2
- package/rancher-components/Card/Card.vue +3 -3
- package/rancher-components/Form/Checkbox/Checkbox.vue +3 -3
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +18 -1
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +65 -24
- package/rancher-components/Form/Radio/RadioButton.test.ts +7 -3
- package/rancher-components/Form/Radio/RadioButton.vue +13 -7
- package/rancher-components/Form/Radio/RadioGroup.test.ts +30 -0
- package/rancher-components/Form/Radio/RadioGroup.vue +8 -3
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -4
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
- package/rancher-components/StringList/StringList.test.ts +270 -0
- package/rancher-components/StringList/StringList.vue +65 -26
- package/rancher-components/components/Accordion/Accordion.test.ts +45 -0
- package/rancher-components/components/Accordion/Accordion.vue +86 -0
- package/rancher-components/components/Accordion/index.ts +1 -0
- package/rancher-components/components/BadgeState/BadgeState.vue +3 -3
- package/rancher-components/components/Banner/Banner.vue +2 -2
- package/rancher-components/components/Card/Card.vue +3 -3
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +3 -3
- package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +18 -1
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +57 -24
- package/rancher-components/components/Form/Radio/RadioButton.vue +13 -7
- package/rancher-components/components/Form/Radio/RadioGroup.vue +4 -3
- package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +6 -4
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +9 -4
- package/rancher-components/components/StringList/StringList.vue +8 -8
- package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +50 -0
- package/scripts/extension/parse-tag-name +2 -2
- package/scripts/publish-shell.sh +10 -0
- package/scripts/test-plugins-build.sh +85 -9
- package/server/har-file.js +183 -0
- package/store/catalog.js +1 -1
- package/store/features.js +1 -0
- package/store/i18n.js +11 -0
- package/store/index.js +10 -11
- package/store/prefs.js +33 -35
- package/store/type-map.js +8 -7
- package/tsconfig.json +35 -9
- package/tsconfig.paths.json +21 -0
- package/types/shell/index.d.ts +427 -234
- package/types/vue-shim.d.ts +42 -0
- package/utils/__tests__/create-yaml.test.ts +60 -0
- package/utils/axios.js +0 -19
- package/utils/azure.js +24 -0
- package/utils/create-yaml.js +17 -10
- package/utils/git.ts +1 -1
- package/utils/monitoring.js +1 -1
- package/utils/nuxt.js +18 -39
- package/utils/object.js +14 -0
- package/utils/router.scrollBehavior.js +12 -14
- package/utils/time.js +1 -1
- package/utils/url.ts +1 -1
- package/vue.config.js +23 -2
- package/.DS_Store +0 -0
- package/assets/images/providers/aks-black.svg +0 -28
- package/assets/images/providers/aks.svg +0 -31
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +0 -234
- package/initialize/layouts.ts +0 -26
- package/mixins/fetch.server.js +0 -73
- package/pages/c/index.vue +0 -9
- package/pages/rio/mesh.vue +0 -508
- package/plugins/transitions.js +0 -4
- package/scripts/.DS_Store +0 -0
- package/scripts/verdaccio.log +0 -205
- package/tsconfig.default.json +0 -46
- package/yarn-error.log +0 -200
- /package/components/form/__tests__/{NameNsDescription.ts → NameNsDescription.test.ts} +0 -0
- /package/edit/networking.k8s.io.networkpolicy/__tests__/utils/{selectors.ts → selectors.test.ts} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{AgentConfiguration.vue → tabs/AgentConfiguration.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{MemberRoles.vue → tabs/MemberRoles.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{S3Config.vue → tabs/etcd/S3Config.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{ACE.vue → tabs/networking/ACE.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{RegistryConfigs.vue → tabs/registries/RegistryConfigs.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{RegistryMirrors.vue → tabs/registries/RegistryMirrors.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{DrainOptions.vue → tabs/upgrade/DrainOptions.vue} +0 -0
- /package/plugins/dashboard-store/__tests__/{actions.spec.ts → actions.test.ts} +0 -0
- /package/plugins/dashboard-store/__tests__/{getters.spec.ts → getters.test.ts} +0 -0
- /package/rancher-components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
- /package/rancher-components/components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
|
@@ -8,6 +8,7 @@ import { insertAt } from '@shell/utils/array';
|
|
|
8
8
|
import { downloadUrl } from '@shell/utils/download';
|
|
9
9
|
import findLast from 'lodash/findLast';
|
|
10
10
|
import HybridModel from '@shell/plugins/steve/hybrid-class';
|
|
11
|
+
import { notOnlyOfRole } from '@shell/models/cluster.x-k8s.io.machine';
|
|
11
12
|
|
|
12
13
|
export default class MgmtNode extends HybridModel {
|
|
13
14
|
get _availableActions() {
|
|
@@ -21,11 +22,12 @@ export default class MgmtNode extends HybridModel {
|
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
const scaleDown = {
|
|
24
|
-
action:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
action: 'scaleDown',
|
|
26
|
+
bulkAction: 'scaleDown',
|
|
27
|
+
enabled: !!this.canScaleDown,
|
|
28
|
+
icon: 'icon icon-minus icon-fw',
|
|
29
|
+
label: this.t('node.actions.scaleDown'),
|
|
30
|
+
bulkable: true,
|
|
29
31
|
};
|
|
30
32
|
|
|
31
33
|
insertAt(out, 0, { divider: true });
|
|
@@ -105,12 +107,12 @@ export default class MgmtNode extends HybridModel {
|
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
109
|
|
|
108
|
-
async scaleDown(resources) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
})
|
|
110
|
+
async scaleDown(resources = this) {
|
|
111
|
+
this.$dispatch('promptModal', {
|
|
112
|
+
resources,
|
|
113
|
+
component: 'ScaleMachineDownDialog',
|
|
114
|
+
modalWidth: '450px'
|
|
115
|
+
});
|
|
114
116
|
}
|
|
115
117
|
|
|
116
118
|
get provisioningCluster() {
|
|
@@ -166,10 +168,12 @@ export default class MgmtNode extends HybridModel {
|
|
|
166
168
|
}
|
|
167
169
|
|
|
168
170
|
get canScaleDown() {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
+
if (!this.isEtcd && !this.isControlPlane) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
|
|
171
175
|
const hasAction = this.norman?.actions?.scaledown;
|
|
172
176
|
|
|
173
|
-
return hasAction && (
|
|
177
|
+
return hasAction && notOnlyOfRole(this, this.provisioningCluster?.nodes);
|
|
174
178
|
}
|
|
175
179
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CAPI, MANAGEMENT, NORMAN } from '@shell/config/types';
|
|
2
2
|
import { sortBy } from '@shell/utils/sort';
|
|
3
3
|
import HybridModel from '@shell/plugins/steve/hybrid-class';
|
|
4
|
+
import { notOnlyOfRole } from '@shell/models/cluster.x-k8s.io.machine';
|
|
4
5
|
|
|
5
6
|
export default class MgmtNodePool extends HybridModel {
|
|
6
7
|
get nodeTemplate() {
|
|
@@ -161,6 +162,22 @@ export default class MgmtNodePool extends HybridModel {
|
|
|
161
162
|
return this.norman?.hasLink('update');
|
|
162
163
|
}
|
|
163
164
|
|
|
165
|
+
get isControlPlane() {
|
|
166
|
+
return this.spec?.controlPlane === true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
get isEtcd() {
|
|
170
|
+
return this.spec?.etcd === true;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
canScaleDownPool() {
|
|
174
|
+
if (!this.isEtcd && !this.isControlPlane) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return notOnlyOfRole(this, this?.provisioningCluster?.nodes);
|
|
179
|
+
}
|
|
180
|
+
|
|
164
181
|
remove() {
|
|
165
182
|
return this.norman?.remove();
|
|
166
183
|
}
|
package/models/namespace.js
CHANGED
package/models/pod.js
CHANGED
|
@@ -3,6 +3,7 @@ import { colorForState, stateDisplay } from '@shell/plugins/dashboard-store/reso
|
|
|
3
3
|
import { NODE, WORKLOAD_TYPES } from '@shell/config/types';
|
|
4
4
|
import { escapeHtml, shortenedImage } from '@shell/utils/string';
|
|
5
5
|
import WorkloadService from '@shell/models/workload.service';
|
|
6
|
+
import { deleteProperty } from '@shell/utils/object';
|
|
6
7
|
|
|
7
8
|
export const WORKLOAD_PRIORITY = {
|
|
8
9
|
[WORKLOAD_TYPES.DEPLOYMENT]: 1,
|
|
@@ -256,4 +257,23 @@ export default class Pod extends WorkloadService {
|
|
|
256
257
|
return Promise.reject(e);
|
|
257
258
|
});
|
|
258
259
|
}
|
|
260
|
+
|
|
261
|
+
cleanForSave(data) {
|
|
262
|
+
const val = super.cleanForSave(data);
|
|
263
|
+
|
|
264
|
+
// remove fields from containers
|
|
265
|
+
val.spec?.containers?.forEach((container) => {
|
|
266
|
+
this.cleanContainerForSave(container);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// remove fields from initContainers
|
|
270
|
+
val.spec?.initContainers?.forEach((container) => {
|
|
271
|
+
this.cleanContainerForSave(container);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
// This is probably added by generic workload components that shouldn't be added to pods
|
|
275
|
+
deleteProperty(val, 'spec.selector');
|
|
276
|
+
|
|
277
|
+
return val;
|
|
278
|
+
}
|
|
259
279
|
}
|
|
@@ -180,6 +180,16 @@ export default class ProvCluster extends SteveModel {
|
|
|
180
180
|
return out;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
async findNormanCluster() {
|
|
184
|
+
const name = this.status?.clusterName;
|
|
185
|
+
|
|
186
|
+
if ( !name ) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return await this.$dispatch('rancher/find', { type: NORMAN.CLUSTER, id: name }, { root: true });
|
|
191
|
+
}
|
|
192
|
+
|
|
183
193
|
explore() {
|
|
184
194
|
const location = {
|
|
185
195
|
name: 'c-cluster',
|
|
@@ -284,7 +294,7 @@ export default class ProvCluster extends SteveModel {
|
|
|
284
294
|
}
|
|
285
295
|
|
|
286
296
|
get isK3s() {
|
|
287
|
-
return this.mgmt?.status?.provider === 'k3s';
|
|
297
|
+
return this.mgmt?.status ? this.mgmt?.status.provider === 'k3s' : (this.spec?.kubernetesVersion || '').includes('k3s') ;
|
|
288
298
|
}
|
|
289
299
|
|
|
290
300
|
get isRke2() {
|
|
@@ -827,11 +837,11 @@ export default class ProvCluster extends SteveModel {
|
|
|
827
837
|
get agentConfig() {
|
|
828
838
|
// The one we want is the first one with no selector.
|
|
829
839
|
// If there are multiple with no selector, that will fall under the unsupported message below.
|
|
830
|
-
return this.spec.rkeConfig.machineSelectorConfig.find((x) => !x.machineLabelSelector)
|
|
840
|
+
return this.spec.rkeConfig.machineSelectorConfig.find((x) => !x.machineLabelSelector)?.config;
|
|
831
841
|
}
|
|
832
842
|
|
|
833
843
|
get cloudProvider() {
|
|
834
|
-
return this.agentConfig['cloud-provider-name'];
|
|
844
|
+
return this.agentConfig?.['cloud-provider-name'];
|
|
835
845
|
}
|
|
836
846
|
|
|
837
847
|
get canClone() {
|
|
@@ -901,4 +911,11 @@ export default class ProvCluster extends SteveModel {
|
|
|
901
911
|
|
|
902
912
|
return null;
|
|
903
913
|
}
|
|
914
|
+
|
|
915
|
+
// JSON Paths that should be folded in the YAML editor by default
|
|
916
|
+
get yamlFolding() {
|
|
917
|
+
return [
|
|
918
|
+
'spec.rkeConfig.machinePools.dynamicSchemaSpec',
|
|
919
|
+
];
|
|
920
|
+
}
|
|
904
921
|
}
|
package/models/secret.js
CHANGED
|
@@ -6,6 +6,9 @@ import { SERVICE_ACCOUNT } from '@shell/config/types';
|
|
|
6
6
|
import { set } from '@shell/utils/object';
|
|
7
7
|
import { NAME as MANAGER } from '@shell/config/product/manager';
|
|
8
8
|
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
9
|
+
import { colorForState, stateDisplay, STATES_ENUM } from '@shell/plugins/dashboard-store/resource-class';
|
|
10
|
+
import { diffFrom } from '@shell/utils/time';
|
|
11
|
+
import day from 'dayjs';
|
|
9
12
|
|
|
10
13
|
export const TYPES = {
|
|
11
14
|
OPAQUE: 'Opaque',
|
|
@@ -23,7 +26,12 @@ export const TYPES = {
|
|
|
23
26
|
RKE_AUTH_CONFIG: 'rke.cattle.io/auth-config'
|
|
24
27
|
};
|
|
25
28
|
|
|
29
|
+
/** Class a cert as expiring if in eight days */
|
|
30
|
+
const certExpiringPeriod = 1000 * 60 * 60 * 24 * 8;
|
|
31
|
+
|
|
26
32
|
export default class Secret extends SteveModel {
|
|
33
|
+
_cachedCertInfo;
|
|
34
|
+
|
|
27
35
|
get hasSensitiveData() {
|
|
28
36
|
return true;
|
|
29
37
|
}
|
|
@@ -46,7 +54,7 @@ export default class Secret extends SteveModel {
|
|
|
46
54
|
if (annotations[CERTMANAGER.ISSUER]) {
|
|
47
55
|
return annotations[CERTMANAGER.ISSUER];
|
|
48
56
|
} else if (this.isCertificate) {
|
|
49
|
-
return this.
|
|
57
|
+
return this.cachedCertInfo?.issuer;
|
|
50
58
|
} else {
|
|
51
59
|
return null;
|
|
52
60
|
}
|
|
@@ -54,7 +62,7 @@ export default class Secret extends SteveModel {
|
|
|
54
62
|
|
|
55
63
|
get notAfter() {
|
|
56
64
|
if (this.isCertificate) {
|
|
57
|
-
return this.
|
|
65
|
+
return this.cachedCertInfo?.notAfter;
|
|
58
66
|
} else {
|
|
59
67
|
return null;
|
|
60
68
|
}
|
|
@@ -62,7 +70,7 @@ export default class Secret extends SteveModel {
|
|
|
62
70
|
|
|
63
71
|
get cn() {
|
|
64
72
|
if (this.isCertificate) {
|
|
65
|
-
return this.
|
|
73
|
+
return this.cachedCertInfo?.cn;
|
|
66
74
|
}
|
|
67
75
|
|
|
68
76
|
return null;
|
|
@@ -80,14 +88,13 @@ export default class Secret extends SteveModel {
|
|
|
80
88
|
// use text-warning' or 'text-error' if cert is expiring within 8 days or is expired
|
|
81
89
|
get dateClass() {
|
|
82
90
|
if (this.isCertificate) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (this.timeTilExpiration > eightDays ) {
|
|
86
|
-
return '';
|
|
87
|
-
} else if (this.timeTilExpiration > 0) {
|
|
91
|
+
switch (this.certState) {
|
|
92
|
+
case STATES_ENUM.EXPIRING:
|
|
88
93
|
return 'text-warning';
|
|
89
|
-
|
|
94
|
+
case STATES_ENUM.EXPIRED:
|
|
90
95
|
return 'text-error';
|
|
96
|
+
default:
|
|
97
|
+
return '';
|
|
91
98
|
}
|
|
92
99
|
}
|
|
93
100
|
|
|
@@ -248,7 +255,7 @@ export default class Secret extends SteveModel {
|
|
|
248
255
|
// parse TLS certs and return issuer, notAfter, cn, sans
|
|
249
256
|
get certInfo() {
|
|
250
257
|
const pem = base64Decode(this.data['tls.crt']);
|
|
251
|
-
let issuer, notAfter, cn, sans, x;
|
|
258
|
+
let issuer, notBefore, notAfter, cn, sans, x;
|
|
252
259
|
const END_MARKER = '-----END CERTIFICATE-----';
|
|
253
260
|
|
|
254
261
|
if (pem) {
|
|
@@ -266,6 +273,7 @@ export default class Secret extends SteveModel {
|
|
|
266
273
|
const issuerString = x.getIssuerString();
|
|
267
274
|
|
|
268
275
|
issuer = issuerString.slice(issuerString.indexOf('CN=') + 3);
|
|
276
|
+
notBefore = r.zulutodate(x.getNotBefore());
|
|
269
277
|
notAfter = r.zulutodate(x.getNotAfter());
|
|
270
278
|
|
|
271
279
|
const cnString = x.getSubjectString();
|
|
@@ -281,25 +289,39 @@ export default class Secret extends SteveModel {
|
|
|
281
289
|
sans = [];
|
|
282
290
|
}
|
|
283
291
|
|
|
284
|
-
|
|
285
|
-
issuer, notAfter, cn, sans
|
|
292
|
+
const certInfo = {
|
|
293
|
+
issuer, notBefore, notAfter, cn, sans
|
|
286
294
|
};
|
|
295
|
+
|
|
296
|
+
return certInfo;
|
|
287
297
|
}
|
|
288
298
|
|
|
289
299
|
return null;
|
|
290
300
|
}
|
|
291
301
|
|
|
302
|
+
get cachedCertInfo() {
|
|
303
|
+
if (!this._cachedCertInfo) {
|
|
304
|
+
this._cachedCertInfo = this.certInfo;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return this._cachedCertInfo;
|
|
308
|
+
}
|
|
309
|
+
|
|
292
310
|
// use for + n more name display
|
|
293
311
|
get unrepeatedSans() {
|
|
294
312
|
if (this._type === TYPES.TLS ) {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
313
|
+
const certInfo = this.cachedCertInfo;
|
|
314
|
+
|
|
315
|
+
if (certInfo?.sans?.filter) {
|
|
316
|
+
const commonBases = certInfo?.sans
|
|
317
|
+
.filter((name) => name.indexOf('*.') === 0 || name.indexOf('www.') === 0)
|
|
318
|
+
.map((name) => name.substr(name.indexOf('.')));
|
|
319
|
+
const displaySans = removeObjects(certInfo?.sans, commonBases);
|
|
298
320
|
|
|
299
321
|
return displaySans;
|
|
300
322
|
}
|
|
301
323
|
|
|
302
|
-
return
|
|
324
|
+
return certInfo?.sans?.array || certInfo?.sans || [];
|
|
303
325
|
}
|
|
304
326
|
|
|
305
327
|
return null;
|
|
@@ -307,16 +329,28 @@ export default class Secret extends SteveModel {
|
|
|
307
329
|
|
|
308
330
|
get timeTilExpiration() {
|
|
309
331
|
if (this._type === TYPES.TLS) {
|
|
310
|
-
const
|
|
332
|
+
const certInfo = this.cachedCertInfo;
|
|
333
|
+
|
|
334
|
+
if (!certInfo?.notAfter) {
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const expiration = certInfo.notAfter;
|
|
311
339
|
const timeThen = expiration.valueOf();
|
|
312
340
|
const timeNow = Date.now();
|
|
313
341
|
|
|
314
|
-
|
|
342
|
+
const timeTilExpiration = timeThen - timeNow;
|
|
343
|
+
|
|
344
|
+
return timeTilExpiration < 0 ? 0 : timeTilExpiration;
|
|
315
345
|
}
|
|
316
346
|
|
|
317
347
|
return null;
|
|
318
348
|
}
|
|
319
349
|
|
|
350
|
+
get timeTilExpirationDate() {
|
|
351
|
+
return this.timeTilExpiration > 0 ? this.cachedCertInfo?.notAfter?.valueOf() : null;
|
|
352
|
+
}
|
|
353
|
+
|
|
320
354
|
get decodedData() {
|
|
321
355
|
const out = {};
|
|
322
356
|
|
|
@@ -357,4 +391,69 @@ export default class Secret extends SteveModel {
|
|
|
357
391
|
return 'c-cluster-product-resource';
|
|
358
392
|
}
|
|
359
393
|
}
|
|
394
|
+
|
|
395
|
+
get certLifetime() {
|
|
396
|
+
if (this._type === TYPES.TLS) {
|
|
397
|
+
const certInfo = this.cachedCertInfo;
|
|
398
|
+
|
|
399
|
+
if (certInfo) {
|
|
400
|
+
return diffFrom(day(certInfo.notBefore), day(certInfo.notAfter), (key, args) => this.t(key, args)).string;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Get the model `state` for secrets of type cert
|
|
409
|
+
*/
|
|
410
|
+
get certState() {
|
|
411
|
+
if (this._type !== TYPES.TLS) {
|
|
412
|
+
return undefined;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (typeof this.timeTilExpiration !== 'number' || this.timeTilExpiration > certExpiringPeriod ) {
|
|
416
|
+
return '';
|
|
417
|
+
} else if (this.timeTilExpiration > 0) {
|
|
418
|
+
return STATES_ENUM.EXPIRING;
|
|
419
|
+
} else {
|
|
420
|
+
return STATES_ENUM.EXPIRED;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Get the model `state display` for secrets of type cert
|
|
426
|
+
*/
|
|
427
|
+
get certStateDisplay() {
|
|
428
|
+
if (this._type !== TYPES.TLS) {
|
|
429
|
+
return undefined;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return stateDisplay(this.certState);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Get the model `state background` for secrets of type cert
|
|
437
|
+
*/
|
|
438
|
+
get certStateBackground() {
|
|
439
|
+
if (this._type !== TYPES.TLS) {
|
|
440
|
+
return undefined;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const color = colorForState(this.certState);
|
|
444
|
+
|
|
445
|
+
return color.replace('text-', 'bg-');
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
cleanForSave(data, forNew) {
|
|
449
|
+
const val = super.cleanForSave(data, forNew);
|
|
450
|
+
|
|
451
|
+
// Secrets on create with _type will return validation error
|
|
452
|
+
// Secrets on edit without _type will return http error
|
|
453
|
+
if (forNew) {
|
|
454
|
+
delete val._type;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return val;
|
|
458
|
+
}
|
|
360
459
|
}
|
package/models/workload.js
CHANGED
|
@@ -649,4 +649,20 @@ export default class Workload extends WorkloadService {
|
|
|
649
649
|
|
|
650
650
|
return matching(allInNamespace, selector);
|
|
651
651
|
}
|
|
652
|
+
|
|
653
|
+
cleanForSave(data) {
|
|
654
|
+
const val = super.cleanForSave(data);
|
|
655
|
+
|
|
656
|
+
// remove fields from containers
|
|
657
|
+
val.spec?.template?.spec?.containers?.forEach((container) => {
|
|
658
|
+
this.cleanContainerForSave(container);
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
// remove fields from initContainers
|
|
662
|
+
val.spec?.template?.spec?.initContainers?.forEach((container) => {
|
|
663
|
+
this.cleanContainerForSave(container);
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
return val;
|
|
667
|
+
}
|
|
652
668
|
}
|
|
@@ -320,4 +320,22 @@ export default class WorkloadService extends SteveModel {
|
|
|
320
320
|
|
|
321
321
|
return { toSave, toRemove };
|
|
322
322
|
}
|
|
323
|
+
|
|
324
|
+
cleanForSave(data) {
|
|
325
|
+
const val = super.cleanForSave(data);
|
|
326
|
+
|
|
327
|
+
delete val.__active;
|
|
328
|
+
delete val.type;
|
|
329
|
+
|
|
330
|
+
return val;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
cleanContainerForSave(container) {
|
|
334
|
+
delete container.__active;
|
|
335
|
+
delete container.active;
|
|
336
|
+
delete container._init;
|
|
337
|
+
delete container.error;
|
|
338
|
+
|
|
339
|
+
return container;
|
|
340
|
+
}
|
|
323
341
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rancher/shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Rancher Dashboard Shell",
|
|
5
5
|
"repository": "https://github.com/rancherlabs/dashboard",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
"start-server-and-test": "1.13.1",
|
|
117
117
|
"style-loader": "1.2.1",
|
|
118
118
|
"ts-node": "8.10.2",
|
|
119
|
-
"typescript": "4.
|
|
119
|
+
"typescript": "4.5.5",
|
|
120
120
|
"url-parse": "1.5.10",
|
|
121
121
|
"v-tooltip": "2.0.3",
|
|
122
122
|
"vue": "2.7.14",
|
|
@@ -129,16 +129,16 @@
|
|
|
129
129
|
"vue-shortkey": "3.1.7",
|
|
130
130
|
"vue-template-compiler": "2.7.14",
|
|
131
131
|
"vue-virtual-scroll-list": "^2.3.4",
|
|
132
|
-
"vue2-transitions": "0.3.0",
|
|
133
132
|
"vuedraggable": "2.24.3",
|
|
134
133
|
"vuex": "3.6.2",
|
|
135
134
|
"webpack-bundle-analyzer": "4.5.0",
|
|
136
135
|
"webpack-virtual-modules": "0.4.3",
|
|
137
|
-
"xterm": "5.
|
|
138
|
-
"xterm-addon-
|
|
139
|
-
"xterm-addon-
|
|
140
|
-
"xterm-addon-
|
|
141
|
-
"xterm-addon-
|
|
136
|
+
"xterm": "5.2.1",
|
|
137
|
+
"xterm-addon-canvas": "^0.5.0",
|
|
138
|
+
"xterm-addon-fit": "0.8.0",
|
|
139
|
+
"xterm-addon-search": "0.13.0",
|
|
140
|
+
"xterm-addon-web-links": "0.9.0",
|
|
141
|
+
"xterm-addon-webgl": "0.16.0",
|
|
142
142
|
"worker-loader": "3.0.8",
|
|
143
143
|
"yarn": "1.22.18"
|
|
144
144
|
},
|
|
@@ -151,7 +151,8 @@
|
|
|
151
151
|
"qs": ">=6.7.3",
|
|
152
152
|
"nth-check": ">=2.0.1",
|
|
153
153
|
"follow-redirects": ">=1.14.7",
|
|
154
|
-
"merge": ">=2.1.1"
|
|
154
|
+
"merge": ">=2.1.1",
|
|
155
|
+
"semver": ">=7.5.2"
|
|
155
156
|
},
|
|
156
157
|
"nyc": {
|
|
157
158
|
"extension": [
|
package/pages/about.vue
CHANGED
package/pages/account/index.vue
CHANGED
|
@@ -15,7 +15,6 @@ import CopyToClipboardText from '@shell/components/CopyToClipboardText';
|
|
|
15
15
|
const API_ENDPOINT = '/v3';
|
|
16
16
|
|
|
17
17
|
export default {
|
|
18
|
-
layout: 'plain',
|
|
19
18
|
components: {
|
|
20
19
|
CopyToClipboardText, BackLink, Banner, PromptChangePassword, Loading, ResourceTable, Principal
|
|
21
20
|
},
|
package/pages/auth/login.vue
CHANGED
package/pages/auth/logout.vue
CHANGED
package/pages/auth/setup.vue
CHANGED
|
@@ -38,8 +38,6 @@ const calcMustChangePassword = async(store) => {
|
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
export default {
|
|
41
|
-
layout: 'unauthenticated',
|
|
42
|
-
|
|
43
41
|
mixins: [FormValidation],
|
|
44
42
|
|
|
45
43
|
data() {
|
|
@@ -146,8 +144,6 @@ export default {
|
|
|
146
144
|
|
|
147
145
|
if (serverUrlSetting?.value) {
|
|
148
146
|
serverUrl = serverUrlSetting.value;
|
|
149
|
-
} else if ( process.server ) {
|
|
150
|
-
serverUrl = req.headers.host;
|
|
151
147
|
} else {
|
|
152
148
|
serverUrl = window.location.origin;
|
|
153
149
|
}
|
package/pages/auth/verify.vue
CHANGED
|
@@ -17,9 +17,14 @@ function reply(err, code) {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
function isSaml($route) {
|
|
21
|
+
const { query } = $route;
|
|
22
|
+
const configQuery = get(query, 'config');
|
|
23
|
+
|
|
24
|
+
return samlProviders.includes(configQuery);
|
|
25
|
+
}
|
|
22
26
|
|
|
27
|
+
export default {
|
|
23
28
|
async fetch({ store, route, redirect }) {
|
|
24
29
|
const code = route.query[GITHUB_CODE];
|
|
25
30
|
const stateStr = route.query[GITHUB_NONCE];
|
|
@@ -43,9 +48,14 @@ export default {
|
|
|
43
48
|
try {
|
|
44
49
|
parsed = JSON.parse(base64Decode((stateStr)));
|
|
45
50
|
} catch (err) {
|
|
51
|
+
if (isSaml(route)) {
|
|
52
|
+
// This is an ok failure. SAML has no state string so a failure is fine (see similar check in mounted).
|
|
53
|
+
// This whole file could be re-written with that in mind, but this change keeps things simple and fixes a breaking addition
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
46
56
|
const out = store.getters['i18n/t'](`login.error`);
|
|
47
57
|
|
|
48
|
-
console.error('Failed to parse nonce'); // eslint-disable-line no-console
|
|
58
|
+
console.error('Failed to parse nonce', stateStr, err); // eslint-disable-line no-console
|
|
49
59
|
|
|
50
60
|
redirect(`/auth/login?err=${ escape(out) }`);
|
|
51
61
|
|
|
@@ -117,12 +127,8 @@ export default {
|
|
|
117
127
|
window.close();
|
|
118
128
|
}
|
|
119
129
|
} else {
|
|
120
|
-
const { query } = this.$route;
|
|
121
|
-
|
|
122
130
|
if ( window.opener ) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if ( samlProviders.includes(configQuery) ) {
|
|
131
|
+
if (isSaml(this.$route)) {
|
|
126
132
|
if ( window.opener.window.onAuthTest ) {
|
|
127
133
|
reply(null, null);
|
|
128
134
|
} else {
|
|
@@ -248,7 +248,7 @@ export default {
|
|
|
248
248
|
return;
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
if ( this.version
|
|
251
|
+
if ( this.version ) {
|
|
252
252
|
/*
|
|
253
253
|
Check if the Helm chart has provided the name
|
|
254
254
|
of a Vue component to use for configuring
|
|
@@ -857,11 +857,9 @@ export default {
|
|
|
857
857
|
}
|
|
858
858
|
|
|
859
859
|
if (provCluster?.isRke2) { // isRke2 returns true for both RKE2 and K3s clusters.
|
|
860
|
-
const agentConfig = provCluster.spec?.rkeConfig?.machineSelectorConfig?.find((x) => !x.machineLabelSelector).config;
|
|
861
|
-
|
|
862
860
|
// If a cluster scoped registry exists,
|
|
863
861
|
// it should be used by default.
|
|
864
|
-
const clusterRegistry = agentConfig?.['system-default-registry'] || '';
|
|
862
|
+
const clusterRegistry = provCluster.agentConfig?.['system-default-registry'] || '';
|
|
865
863
|
|
|
866
864
|
if (clusterRegistry) {
|
|
867
865
|
return clusterRegistry;
|
|
@@ -1603,6 +1601,7 @@ export default {
|
|
|
1603
1601
|
v-if="componentHasTabs"
|
|
1604
1602
|
ref="tabs"
|
|
1605
1603
|
:side-tabs="true"
|
|
1604
|
+
:hide-single-tab="true"
|
|
1606
1605
|
:class="{'with-name': showNameEditor}"
|
|
1607
1606
|
class="step__values__content"
|
|
1608
1607
|
@changed="tabChanged($event)"
|
|
@@ -1647,6 +1646,7 @@ export default {
|
|
|
1647
1646
|
v-else-if="hasQuestions && showQuestions"
|
|
1648
1647
|
ref="tabs"
|
|
1649
1648
|
:side-tabs="true"
|
|
1649
|
+
:hide-single-tab="true"
|
|
1650
1650
|
:class="{'with-name': showNameEditor}"
|
|
1651
1651
|
class="step__values__content"
|
|
1652
1652
|
@changed="tabChanged($event)"
|