@rancher/shell 2.0.0 → 2.0.2-rc.1
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 +69 -29
- package/assets/translations/zh-hans.yaml +1 -0
- package/components/AlertTable.vue +17 -7
- package/components/AssignTo.vue +2 -0
- package/components/GrafanaDashboard.vue +6 -4
- package/components/PromptRemove.vue +1 -0
- package/components/Questions/index.vue +2 -2
- package/components/auth/RoleDetailEdit.vue +5 -4
- package/components/form/KeyValue.vue +1 -0
- package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
- package/components/form/ProjectMemberEditor.vue +1 -1
- package/components/form/ResourceLabeledSelect.vue +11 -3
- package/components/form/Taints.vue +13 -7
- package/components/form/__tests__/Taints.test.ts +70 -0
- package/components/form/labeled-select-utils/labeled-select.utils.ts +1 -1
- package/components/nav/Header.vue +1 -1
- package/components/nav/TopLevelMenu.vue +1 -4
- package/config/pagination-table-headers.js +5 -4
- package/config/product/auth.js +1 -1
- package/config/roles.ts +34 -19
- package/config/router/navigation-guards/attempt-first-login.js +1 -1
- package/config/router/navigation-guards/authentication.js +1 -1
- package/config/router/navigation-guards/i18n.js +13 -0
- package/config/router/navigation-guards/index.js +3 -1
- package/config/router/navigation-guards/load-initial-settings.js +1 -1
- package/config/router/navigation-guards/runtime-extension-route.js +31 -0
- package/config/router/routes.js +10 -1
- package/config/uiplugins.js +130 -61
- package/core/plugin.ts +5 -0
- package/core/plugins.js +7 -1
- package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +42 -0
- package/detail/provisioning.cattle.io.cluster.vue +4 -4
- package/dialog/DeactivateDriverDialog.vue +30 -11
- package/edit/auth/__tests__/oidc.test.ts +2 -2
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +86 -13
- package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +3 -134
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +209 -0
- package/edit/provisioning.cattle.io.cluster/index.vue +8 -4
- package/edit/provisioning.cattle.io.cluster/rke2.vue +115 -17
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest.vue +50 -0
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +29 -64
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +42 -3
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +22 -86
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +8 -2
- package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +61 -0
- package/edit/token.vue +2 -1
- package/initialize/entry-helpers.js +4 -24
- package/list/management.cattle.io.feature.vue +4 -2
- package/middleware/authenticated.js +0 -19
- package/mixins/__tests__/chart.test.ts +4 -1
- package/mixins/auth-config.js +1 -1
- package/mixins/chart.js +30 -14
- package/models/__tests__/apps.deployment.test.ts +93 -0
- package/models/apps.deployment.js +18 -4
- package/models/driver.js +3 -2
- package/models/kontainerdriver.js +30 -13
- package/models/management.cattle.io.authconfig.js +2 -2
- package/models/management.cattle.io.cluster.js +2 -2
- package/models/management.cattle.io.user.js +3 -3
- package/models/nodedriver.js +35 -13
- package/models/provisioning.cattle.io.cluster.js +4 -0
- package/package.json +3 -2
- package/pages/404.vue +15 -0
- package/pages/auth/login.vue +4 -1
- package/pages/auth/setup.vue +4 -1
- package/pages/c/_cluster/apps/charts/install.vue +3 -2
- package/pages/c/_cluster/explorer/index.vue +5 -0
- package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +0 -3
- package/pages/c/_cluster/manager/drivers/nodeDriver/index.vue +1 -4
- package/pages/c/_cluster/manager/jwt.authentication/index.vue +10 -4
- package/pages/c/_cluster/settings/performance.vue +2 -2
- package/pages/c/_cluster/uiplugins/InstallDialog.vue +2 -1
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +7 -10
- package/pages/c/_cluster/uiplugins/index.vue +24 -16
- package/pages/home.vue +1 -13
- package/plugins/dashboard-store/actions.js +1 -1
- package/plugins/dashboard-store/getters.js +1 -1
- package/plugins/steve/__tests__/getters.test.ts +5 -5
- package/plugins/steve/getters.js +6 -4
- package/plugins/steve/hybrid-class.js +1 -5
- package/promptRemove/pod.vue +15 -7
- package/scripts/extension/helm/charts/ui-plugin-server/Chart.yaml +1 -1
- package/scripts/publish-shell.sh +54 -55
- package/scripts/test-plugins-build.sh +45 -39
- package/shell/types/shell/index.d.ts +2 -0
- package/store/auth.js +1 -1
- package/store/index.js +1 -1
- package/store/type-map.js +4 -2
- package/types/store/pagination.types.ts +1 -1
- package/utils/__tests__/kontainer.test.ts +89 -1
- package/utils/auth.js +1 -1
- package/utils/cluster.js +9 -0
- package/utils/kontainer.ts +5 -1
- package/utils/settings.ts +3 -1
- package/utils/version.js +2 -1
- package/creators/app/app.package.json +0 -13
- package/creators/app/files/.eslintignore +0 -16
- package/creators/app/files/.eslintrc.js +0 -173
- package/creators/app/files/.gitignore +0 -70
- package/creators/app/files/.gitlab-ci.yml +0 -14
- package/creators/app/files/.vscode/settings.json +0 -21
- 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 -120
- package/creators/app/package.json +0 -25
- package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +0 -24
- package/creators/pkg/files/.github/workflows/build-extension-charts.yml +0 -22
- 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 -286
- 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
- package/rancher-components/components/Accordion/Accordion.test.ts +0 -45
- package/rancher-components/components/Accordion/Accordion.vue +0 -86
- package/rancher-components/components/Accordion/index.ts +0 -1
- package/rancher-components/components/BadgeState/BadgeState.test.ts +0 -12
- package/rancher-components/components/BadgeState/BadgeState.vue +0 -111
- package/rancher-components/components/BadgeState/index.ts +0 -1
- package/rancher-components/components/Banner/Banner.test.ts +0 -59
- package/rancher-components/components/Banner/Banner.vue +0 -244
- package/rancher-components/components/Banner/index.ts +0 -1
- package/rancher-components/components/Card/Card.test.ts +0 -37
- package/rancher-components/components/Card/Card.vue +0 -167
- package/rancher-components/components/Card/index.ts +0 -1
- package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +0 -68
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +0 -421
- package/rancher-components/components/Form/Checkbox/index.ts +0 -1
- package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +0 -40
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +0 -402
- package/rancher-components/components/Form/LabeledInput/index.ts +0 -1
- package/rancher-components/components/Form/Radio/RadioButton.test.ts +0 -33
- package/rancher-components/components/Form/Radio/RadioButton.vue +0 -293
- package/rancher-components/components/Form/Radio/RadioGroup.test.ts +0 -30
- package/rancher-components/components/Form/Radio/RadioGroup.vue +0 -259
- package/rancher-components/components/Form/Radio/index.ts +0 -2
- package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +0 -172
- package/rancher-components/components/Form/TextArea/index.ts +0 -1
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +0 -94
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +0 -152
- package/rancher-components/components/Form/ToggleSwitch/index.ts +0 -1
- package/rancher-components/components/Form/index.ts +0 -5
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -156
- package/rancher-components/components/LabeledTooltip/index.ts +0 -1
- package/rancher-components/components/StringList/StringList.test.ts +0 -754
- package/rancher-components/components/StringList/StringList.vue +0 -650
- package/rancher-components/components/StringList/index.ts +0 -1
- package/types/shell/index.d.ts +0 -4585
|
@@ -15,10 +15,10 @@ export const configType = {
|
|
|
15
15
|
local: '',
|
|
16
16
|
github: 'oauth',
|
|
17
17
|
keycloakoidc: 'oidc',
|
|
18
|
-
|
|
18
|
+
genericoidc: 'oidc',
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const imageOverrides = { keycloakoidc: 'keycloak',
|
|
21
|
+
const imageOverrides = { keycloakoidc: 'keycloak', genericoidc: 'openid' };
|
|
22
22
|
|
|
23
23
|
export default class AuthConfig extends SteveModel {
|
|
24
24
|
get _availableActions() {
|
|
@@ -10,7 +10,7 @@ import { addParams } from '@shell/utils/url';
|
|
|
10
10
|
import { isEmpty } from '@shell/utils/object';
|
|
11
11
|
import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
|
|
12
12
|
import { isHarvesterCluster } from '@shell/utils/cluster';
|
|
13
|
-
import
|
|
13
|
+
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
14
14
|
import { LINUX, WINDOWS } from '@shell/store/catalog';
|
|
15
15
|
import { KONTAINER_TO_DRIVER } from './management.cattle.io.kontainerdriver';
|
|
16
16
|
import { PINNED_CLUSTERS } from '@shell/store/prefs';
|
|
@@ -27,7 +27,7 @@ function findRelationship(verb, type, relationships = []) {
|
|
|
27
27
|
return relationships.find((r) => r[from] === type)?.[id];
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export default class MgmtCluster extends
|
|
30
|
+
export default class MgmtCluster extends SteveModel {
|
|
31
31
|
get details() {
|
|
32
32
|
const out = [
|
|
33
33
|
{
|
|
@@ -105,7 +105,7 @@ export default class User extends HybridModel {
|
|
|
105
105
|
* @returns {number}
|
|
106
106
|
*/
|
|
107
107
|
get userLastLogin() {
|
|
108
|
-
return this.metadata?.labels?.['cattle.io/last-login'] * 1000;
|
|
108
|
+
return this.metadata?.labels?.['cattle.io/last-login'] * 1000 || 0;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
/**
|
|
@@ -113,7 +113,7 @@ export default class User extends HybridModel {
|
|
|
113
113
|
* @returns {number}
|
|
114
114
|
*/
|
|
115
115
|
get userDisabledIn() {
|
|
116
|
-
return this.metadata?.labels?.['cattle.io/disable-after'] * 1000;
|
|
116
|
+
return this.metadata?.labels?.['cattle.io/disable-after'] * 1000 || 0;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
/**
|
|
@@ -129,7 +129,7 @@ export default class User extends HybridModel {
|
|
|
129
129
|
* @returns {number}
|
|
130
130
|
*/
|
|
131
131
|
get userDeletedIn() {
|
|
132
|
-
return this.metadata?.labels?.['cattle.io/delete-after'] * 1000;
|
|
132
|
+
return this.metadata?.labels?.['cattle.io/delete-after'] * 1000 || 0;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
get state() {
|
package/models/nodedriver.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import Driver from '@shell/models/driver';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Overrides for spec.addCloudCredential
|
|
5
|
+
*/
|
|
6
|
+
export const CLOUD_CREDENTIAL_OVERRIDE = { nutanix: true };
|
|
7
|
+
|
|
3
8
|
export default class NodeDriver extends Driver {
|
|
4
9
|
get doneRoute() {
|
|
5
10
|
return 'c-cluster-manager-driver-nodedriver';
|
|
@@ -8,19 +13,21 @@ export default class NodeDriver extends Driver {
|
|
|
8
13
|
get _availableActions() {
|
|
9
14
|
const out = [
|
|
10
15
|
{
|
|
11
|
-
action:
|
|
12
|
-
label:
|
|
13
|
-
icon:
|
|
14
|
-
bulkable:
|
|
15
|
-
|
|
16
|
+
action: 'activate',
|
|
17
|
+
label: this.t('action.activate'),
|
|
18
|
+
icon: 'icon icon-play',
|
|
19
|
+
bulkable: true,
|
|
20
|
+
bulkAction: 'activateBulk',
|
|
21
|
+
enabled: !!this.actions.activate && this.state === 'inactive',
|
|
16
22
|
},
|
|
17
23
|
{
|
|
18
|
-
action:
|
|
19
|
-
label:
|
|
20
|
-
icon:
|
|
21
|
-
bulkable:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
action: 'deactivate',
|
|
25
|
+
label: this.t('action.deactivate'),
|
|
26
|
+
icon: 'icon icon-pause',
|
|
27
|
+
bulkable: true,
|
|
28
|
+
bulkAction: 'deactivateBulk',
|
|
29
|
+
enabled: !!this.actions.deactivate && this.state === 'active',
|
|
30
|
+
weight: -1,
|
|
24
31
|
},
|
|
25
32
|
{ divider: true },
|
|
26
33
|
{
|
|
@@ -52,9 +59,16 @@ export default class NodeDriver extends Driver {
|
|
|
52
59
|
return out;
|
|
53
60
|
}
|
|
54
61
|
|
|
55
|
-
deactivate() {
|
|
62
|
+
deactivate(resources = [this]) {
|
|
56
63
|
this.$dispatch('promptModal', {
|
|
57
|
-
componentProps: {
|
|
64
|
+
componentProps: { drivers: resources, driverType: 'nodeDrivers' },
|
|
65
|
+
component: 'DeactivateDriverDialog'
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
deactivateBulk(resources) {
|
|
70
|
+
this.$dispatch('promptModal', {
|
|
71
|
+
componentProps: { drivers: resources, driverType: 'nodeDrivers' },
|
|
58
72
|
component: 'DeactivateDriverDialog'
|
|
59
73
|
});
|
|
60
74
|
}
|
|
@@ -65,4 +79,12 @@ export default class NodeDriver extends Driver {
|
|
|
65
79
|
method: 'post',
|
|
66
80
|
}, { root: true });
|
|
67
81
|
}
|
|
82
|
+
|
|
83
|
+
async activateBulk(resources) {
|
|
84
|
+
await Promise.all(resources.map((resource) => this.$dispatch('rancher/request', {
|
|
85
|
+
url: `v3/nodeDrivers/${ escape(resource.id) }?action=activate`,
|
|
86
|
+
method: 'post',
|
|
87
|
+
}, { root: true }
|
|
88
|
+
)));
|
|
89
|
+
}
|
|
68
90
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rancher/shell",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2-rc.1",
|
|
4
4
|
"description": "Rancher Dashboard Shell",
|
|
5
5
|
"repository": "https://github.com/rancherlabs/dashboard",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -153,7 +153,8 @@
|
|
|
153
153
|
"nth-check": ">=2.0.1",
|
|
154
154
|
"follow-redirects": ">=1.14.7",
|
|
155
155
|
"merge": ">=2.1.1",
|
|
156
|
-
"semver": ">=7.5.2"
|
|
156
|
+
"semver": ">=7.5.2",
|
|
157
|
+
"glob": "7.2.3"
|
|
157
158
|
},
|
|
158
159
|
"nyc": {
|
|
159
160
|
"extension": [
|
package/pages/404.vue
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import Brand from '@shell/mixins/brand';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
mixins: [Brand],
|
|
6
|
+
beforeMount() {
|
|
7
|
+
this.$store.commit('setError', { error: new Error('404: This page could not be found') });
|
|
8
|
+
this.$router.replace('/fail-whale');
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<div class="dashboard-root" />
|
|
15
|
+
</template>
|
package/pages/auth/login.vue
CHANGED
package/pages/auth/setup.vue
CHANGED
|
@@ -37,6 +37,7 @@ import { findBy, insertAt } from '@shell/utils/array';
|
|
|
37
37
|
import Vue from 'vue';
|
|
38
38
|
import { saferDump } from '@shell/utils/create-yaml';
|
|
39
39
|
import { LINUX, WINDOWS } from '@shell/store/catalog';
|
|
40
|
+
import { SETTING } from '@shell/config/settings';
|
|
40
41
|
|
|
41
42
|
const VALUES_STATE = {
|
|
42
43
|
FORM: 'FORM',
|
|
@@ -126,7 +127,7 @@ export default {
|
|
|
126
127
|
try {
|
|
127
128
|
this.serverUrlSetting = await this.$store.dispatch('management/find', {
|
|
128
129
|
type: MANAGEMENT.SETTING,
|
|
129
|
-
id:
|
|
130
|
+
id: SETTING.SERVER_URL,
|
|
130
131
|
});
|
|
131
132
|
} catch (e) {
|
|
132
133
|
console.error('Unable to fetch `server-url` setting: ', e); // eslint-disable-line no-console
|
|
@@ -888,7 +889,7 @@ export default {
|
|
|
888
889
|
// runtime will pull images from docker.io.
|
|
889
890
|
const globalRegistry = await this.$store.dispatch('management/find', {
|
|
890
891
|
type: MANAGEMENT.SETTING,
|
|
891
|
-
id:
|
|
892
|
+
id: SETTING.SYSTEM_DEFAULT_REGISTRY,
|
|
892
893
|
});
|
|
893
894
|
|
|
894
895
|
return globalRegistry.value;
|
|
@@ -48,6 +48,7 @@ import { NAME as EXPLORER } from '@shell/config/product/explorer';
|
|
|
48
48
|
import TabTitle from '@shell/components/TabTitle';
|
|
49
49
|
import { STATES_ENUM } from '@shell/plugins/dashboard-store/resource-class';
|
|
50
50
|
import capitalize from 'lodash/capitalize';
|
|
51
|
+
import paginationUtils from '@shell/utils/pagination-utils';
|
|
51
52
|
|
|
52
53
|
export const RESOURCES = [NAMESPACE, INGRESS, PV, WORKLOAD_TYPES.DEPLOYMENT, WORKLOAD_TYPES.STATEFUL_SET, WORKLOAD_TYPES.JOB, WORKLOAD_TYPES.DAEMON_SET, SERVICE];
|
|
53
54
|
|
|
@@ -122,6 +123,8 @@ export default {
|
|
|
122
123
|
this.loadAgents();
|
|
123
124
|
}
|
|
124
125
|
}
|
|
126
|
+
|
|
127
|
+
this.showCertificates = !paginationUtils.isSteveCacheEnabled({ rootGetters: this.$store.getters });
|
|
125
128
|
},
|
|
126
129
|
|
|
127
130
|
data() {
|
|
@@ -156,6 +159,7 @@ export default {
|
|
|
156
159
|
clusterCounts,
|
|
157
160
|
selectedTab: 'cluster-events',
|
|
158
161
|
extensionCards: getApplicableExtensionEnhancements(this, ExtensionPoint.CARD, CardLocation.CLUSTER_DASHBOARD_CARD, this.$route),
|
|
162
|
+
showCertificates: false,
|
|
159
163
|
};
|
|
160
164
|
},
|
|
161
165
|
|
|
@@ -739,6 +743,7 @@ export default {
|
|
|
739
743
|
<AlertTable v-if="selectedTab === 'cluster-alerts'" />
|
|
740
744
|
</Tab>
|
|
741
745
|
<Tab
|
|
746
|
+
v-if="showCertificates"
|
|
742
747
|
name="cluster-certs"
|
|
743
748
|
:label="t('clusterIndexPage.sections.certs.label')"
|
|
744
749
|
:weight="1"
|
|
@@ -22,7 +22,7 @@ export default {
|
|
|
22
22
|
async fetch() {
|
|
23
23
|
const hash = {
|
|
24
24
|
mgmtClusters: this.$fetchType(MANAGEMENT.CLUSTER),
|
|
25
|
-
proxyConfig: this.$
|
|
25
|
+
proxyConfig: this.$store.dispatch('management/findAll', { type: MANAGEMENT.CLUSTER_PROXY_CONFIG, opt: { omitExcludeFields: ['metadata.managedFields'] } })
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
const res = await allHash(hash);
|
|
@@ -150,7 +150,11 @@ export default {
|
|
|
150
150
|
|
|
151
151
|
const value = config?.enabled || '';
|
|
152
152
|
const configName = config?.metadata?.name || '';
|
|
153
|
-
|
|
153
|
+
let updatedOn = '';
|
|
154
|
+
|
|
155
|
+
if (value) {
|
|
156
|
+
updatedOn = config?.metadata?.managedFields?.find((field) => field.operation === 'Update')?.time || '';
|
|
157
|
+
}
|
|
154
158
|
const stateBackground = value ? colorForState(STATES_ENUM.ACTIVE).replace('text', 'bg') : colorForState(STATES_ENUM.INFO).replace('text', 'bg');
|
|
155
159
|
const stateLabel = value ? this.t('jwt.state.enabled') : this.t('jwt.state.disabled');
|
|
156
160
|
const creationTimestamp = cluster.metadata.creationTimestamp;
|
|
@@ -159,7 +163,7 @@ export default {
|
|
|
159
163
|
if (!configName) {
|
|
160
164
|
const clusterProxyConfig = await this.$store.dispatch('management/create', {
|
|
161
165
|
enabled: true,
|
|
162
|
-
metadata: { namespace: id,
|
|
166
|
+
metadata: { namespace: id, name: 'clusterproxyconfig' },
|
|
163
167
|
});
|
|
164
168
|
|
|
165
169
|
return clusterProxyConfig.save({ url: 'v1/management.cattle.io.clusterproxyconfigs', method: 'POST' });
|
|
@@ -170,7 +174,9 @@ export default {
|
|
|
170
174
|
}
|
|
171
175
|
};
|
|
172
176
|
const disable = async() => {
|
|
173
|
-
|
|
177
|
+
config.enabled = false;
|
|
178
|
+
|
|
179
|
+
return config.save();
|
|
174
180
|
};
|
|
175
181
|
|
|
176
182
|
rows.push({
|
|
@@ -61,7 +61,7 @@ export default {
|
|
|
61
61
|
|
|
62
62
|
data() {
|
|
63
63
|
return {
|
|
64
|
-
uiPerfSetting:
|
|
64
|
+
uiPerfSetting: null,
|
|
65
65
|
authUserTTL: null,
|
|
66
66
|
bannerVal: {},
|
|
67
67
|
value: {},
|
|
@@ -161,7 +161,7 @@ export default {
|
|
|
161
161
|
return;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
// We're enabling a preference. Are there any
|
|
164
|
+
// We're enabling a preference. Are there any incompatible preferences?
|
|
165
165
|
if ((incompatible[property] || []).every((p) => !this.value[p].enabled)) {
|
|
166
166
|
// No, just set and exit
|
|
167
167
|
this.value[property].enabled = true;
|
|
@@ -6,6 +6,7 @@ import { CATALOG, MANAGEMENT } from '@shell/config/types';
|
|
|
6
6
|
import { CATALOG as CATALOG_ANNOTATIONS } from '@shell/config/labels-annotations';
|
|
7
7
|
import { UI_PLUGIN_NAMESPACE } from '@shell/config/uiplugins';
|
|
8
8
|
import Banner from '@components/Banner/Banner.vue';
|
|
9
|
+
import { SETTING } from '@shell/config/settings';
|
|
9
10
|
|
|
10
11
|
// Note: This dialog handles installation and update of a plugin
|
|
11
12
|
|
|
@@ -20,7 +21,7 @@ export default {
|
|
|
20
21
|
async fetch() {
|
|
21
22
|
this.defaultRegistrySetting = await this.$store.dispatch('management/find', {
|
|
22
23
|
type: MANAGEMENT.SETTING,
|
|
23
|
-
id:
|
|
24
|
+
id: SETTING.SYSTEM_DEFAULT_REGISTRY,
|
|
24
25
|
});
|
|
25
26
|
},
|
|
26
27
|
|
|
@@ -5,6 +5,7 @@ import { Banner } from '@components/Banner';
|
|
|
5
5
|
import LazyImage from '@shell/components/LazyImage';
|
|
6
6
|
import { MANAGEMENT } from '@shell/config/types';
|
|
7
7
|
import { SETTING } from '@shell/config/settings';
|
|
8
|
+
import { EXTENSIONS_INCOMPATIBILITY_TYPES, UI_PLUGIN_HOST_APP } from '@shell/config/uiplugins';
|
|
8
9
|
|
|
9
10
|
export default {
|
|
10
11
|
async fetch() {
|
|
@@ -65,10 +66,9 @@ export default {
|
|
|
65
66
|
async loadPluginVersionInfo(version) {
|
|
66
67
|
const versionName = version || this.info.displayVersion;
|
|
67
68
|
|
|
68
|
-
const
|
|
69
|
-
const isVersionNotCompatibleWithKubeVersion = this.info.versions?.find((v) => v.version === versionName && !v.isCompatibleWithKubeVersion);
|
|
69
|
+
const isVersionNotCompatible = this.info.versions?.find((v) => v.version === versionName && !v.isVersionCompatible);
|
|
70
70
|
|
|
71
|
-
if (!this.info.chart ||
|
|
71
|
+
if (!this.info.chart || isVersionNotCompatible) {
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
74
|
|
|
@@ -107,18 +107,15 @@ export default {
|
|
|
107
107
|
},
|
|
108
108
|
|
|
109
109
|
handleVersionBtnTooltip(version) {
|
|
110
|
-
if (version.
|
|
111
|
-
return this.t(
|
|
112
|
-
}
|
|
113
|
-
if (version.requiredKubeVersion) {
|
|
114
|
-
return this.t('plugins.info.requiresKubeVersion', { version: version.requiredKubeVersion });
|
|
110
|
+
if (!version.isVersionCompatible && Object.keys(version.versionIncompatibilityData).length) {
|
|
111
|
+
return this.t(version.versionIncompatibilityData?.tooltipKey, { required: version.versionIncompatibilityData?.type === EXTENSIONS_INCOMPATIBILITY_TYPES.HOST ? UI_PLUGIN_HOST_APP : version.versionIncompatibilityData?.required });
|
|
115
112
|
}
|
|
116
113
|
|
|
117
114
|
return '';
|
|
118
115
|
},
|
|
119
116
|
|
|
120
117
|
handleVersionBtnClass(version) {
|
|
121
|
-
return { 'version-active': version.version === this.infoVersion, disabled: !version.
|
|
118
|
+
return { 'version-active': version.version === this.infoVersion, disabled: !version.isVersionCompatible };
|
|
122
119
|
}
|
|
123
120
|
}
|
|
124
121
|
};
|
|
@@ -219,7 +216,7 @@ export default {
|
|
|
219
216
|
<div class="plugin-versions mb-10">
|
|
220
217
|
<div
|
|
221
218
|
v-for="v in info.versions"
|
|
222
|
-
:key="v.version"
|
|
219
|
+
:key="`${v.name}-${v.version}`"
|
|
223
220
|
>
|
|
224
221
|
<a
|
|
225
222
|
v-clean-tooltip="handleVersionBtnTooltip(v)"
|
|
@@ -31,12 +31,13 @@ import {
|
|
|
31
31
|
uiPluginAnnotation,
|
|
32
32
|
uiPluginHasAnnotation,
|
|
33
33
|
isSupportedChartVersion,
|
|
34
|
-
isChartVersionAvailableForInstall,
|
|
35
34
|
isChartVersionHigher,
|
|
36
35
|
UI_PLUGIN_NAMESPACE,
|
|
37
36
|
UI_PLUGIN_CHART_ANNOTATIONS,
|
|
38
37
|
UI_PLUGINS_REPO_URL,
|
|
39
|
-
UI_PLUGINS_PARTNERS_REPO_URL
|
|
38
|
+
UI_PLUGINS_PARTNERS_REPO_URL,
|
|
39
|
+
UI_PLUGIN_HOST_APP,
|
|
40
|
+
EXTENSIONS_INCOMPATIBILITY_TYPES
|
|
40
41
|
} from '@shell/config/uiplugins';
|
|
41
42
|
import TabTitle from '@shell/components/TabTitle';
|
|
42
43
|
|
|
@@ -258,19 +259,20 @@ export default {
|
|
|
258
259
|
|
|
259
260
|
item.versions = [...chart.versions];
|
|
260
261
|
item.chart = chart;
|
|
262
|
+
item.incompatibilityMessage = '';
|
|
261
263
|
|
|
262
264
|
// Filter the versions available to install (plugins-api version and current dashboard version)
|
|
263
|
-
item.installableVersions = item.versions.filter((version) => isSupportedChartVersion({
|
|
265
|
+
item.installableVersions = item.versions.filter((version) => isSupportedChartVersion({
|
|
264
266
|
version, rancherVersion: this.rancherVersion, kubeVersion: this.kubeVersion
|
|
265
267
|
}));
|
|
266
268
|
|
|
267
269
|
// add prop to version object if version is compatible with the current dashboard version
|
|
268
|
-
item.versions = item.versions.map((version) =>
|
|
270
|
+
item.versions = item.versions.map((version) => isSupportedChartVersion({
|
|
269
271
|
version, rancherVersion: this.rancherVersion, kubeVersion: this.kubeVersion
|
|
270
272
|
}, true));
|
|
271
273
|
|
|
272
274
|
const latestCompatible = item.installableVersions?.[0];
|
|
273
|
-
const latestNotCompatible = item.versions.find((version) => !version.
|
|
275
|
+
const latestNotCompatible = item.versions.find((version) => !version.isVersionCompatible);
|
|
274
276
|
|
|
275
277
|
if (latestCompatible) {
|
|
276
278
|
item.displayVersion = latestCompatible.version;
|
|
@@ -280,11 +282,20 @@ export default {
|
|
|
280
282
|
item.icon = chart.icon || latestCompatible?.annotations?.['catalog.cattle.io/ui-icon'];
|
|
281
283
|
}
|
|
282
284
|
|
|
285
|
+
// add message of extension card if there's a newer version of the extension, but it's not available to be installed
|
|
283
286
|
if (latestNotCompatible && item.installableVersions.length && isChartVersionHigher(latestNotCompatible.version, item.installableVersions?.[0].version)) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
287
|
+
switch (latestNotCompatible.versionIncompatibilityData?.type) {
|
|
288
|
+
case EXTENSIONS_INCOMPATIBILITY_TYPES.HOST:
|
|
289
|
+
item.incompatibilityMessage = this.t(latestNotCompatible.versionIncompatibilityData?.cardMessageKey, {
|
|
290
|
+
version: latestNotCompatible.version, required: latestNotCompatible.versionIncompatibilityData?.required, mainHost: UI_PLUGIN_HOST_APP
|
|
291
|
+
}, true);
|
|
292
|
+
break;
|
|
293
|
+
default:
|
|
294
|
+
item.incompatibilityMessage = this.t(latestNotCompatible.versionIncompatibilityData?.cardMessageKey, {
|
|
295
|
+
version: latestNotCompatible.version,
|
|
296
|
+
required: latestNotCompatible.versionIncompatibilityData?.required
|
|
297
|
+
}, true);
|
|
298
|
+
break;
|
|
288
299
|
}
|
|
289
300
|
}
|
|
290
301
|
|
|
@@ -398,8 +409,9 @@ export default {
|
|
|
398
409
|
|
|
399
410
|
if (versionInstalledData) {
|
|
400
411
|
const kubeVersionToCheck = versionInstalledData.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.KUBE_VERSION];
|
|
412
|
+
const versionSupportedData = isSupportedChartVersion({ version: versionInstalledData, kubeVersion: this.kubeVersion });
|
|
401
413
|
|
|
402
|
-
if (this.kubeVersion && !
|
|
414
|
+
if (this.kubeVersion && !versionSupportedData.isVersionCompatible && versionSupportedData.versionIncompatibilityData?.type === EXTENSIONS_INCOMPATIBILITY_TYPES.KUBE) {
|
|
403
415
|
plugin.installedError = this.t('plugins.currentInstalledVersionBlockedByKubeVersion', { kubeVersion: this.kubeVersion, kubeVersionToCheck }, true);
|
|
404
416
|
}
|
|
405
417
|
}
|
|
@@ -848,13 +860,9 @@ export default {
|
|
|
848
860
|
<span>{{ plugin.installedError }}</span>
|
|
849
861
|
</p>
|
|
850
862
|
<p
|
|
851
|
-
v-else-if="plugin.
|
|
863
|
+
v-else-if="plugin.incompatibilityMessage"
|
|
852
864
|
class="incompatible"
|
|
853
|
-
>{{ plugin.
|
|
854
|
-
<p
|
|
855
|
-
v-else-if="plugin.incompatibleKubeVersion"
|
|
856
|
-
class="incompatible"
|
|
857
|
-
>{{ plugin.incompatibleKubeVersion }}</p>
|
|
865
|
+
>{{ plugin.incompatibilityMessage }}</p>
|
|
858
866
|
</span>
|
|
859
867
|
</div>
|
|
860
868
|
<!-- plugin badges -->
|
package/pages/home.vue
CHANGED
|
@@ -91,10 +91,6 @@ export default {
|
|
|
91
91
|
...mapGetters(['currentCluster', 'defaultClusterId', 'releaseNotesUrl']),
|
|
92
92
|
mcm: mapFeature(MULTI_CLUSTER),
|
|
93
93
|
|
|
94
|
-
mgmtClusters() {
|
|
95
|
-
return this.$store.getters['management/all'](MANAGEMENT.CLUSTER);
|
|
96
|
-
},
|
|
97
|
-
|
|
98
94
|
provClusters() {
|
|
99
95
|
return this.$store.getters['management/all'](CAPI.RANCHER_CLUSTER);
|
|
100
96
|
},
|
|
@@ -211,15 +207,7 @@ export default {
|
|
|
211
207
|
},
|
|
212
208
|
|
|
213
209
|
kubeClusters() {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return filteredClusters.map((provCluster) => {
|
|
217
|
-
const mgmtCluster = this.mgmtClusters?.find((c) => provCluster.mgmt?.id === c.id);
|
|
218
|
-
|
|
219
|
-
provCluster.description = provCluster.description || mgmtCluster?.description;
|
|
220
|
-
|
|
221
|
-
return provCluster;
|
|
222
|
-
});
|
|
210
|
+
return filterHiddenLocalCluster(filterOnlyKubernetesClusters(this.provClusters || [], this.$store), this.$store);
|
|
223
211
|
}
|
|
224
212
|
},
|
|
225
213
|
|
|
@@ -429,7 +429,7 @@ export default {
|
|
|
429
429
|
};
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
-
const namespaces = _typeObj?.namespaced ? Object.keys(rootGetters.activeNamespaceCache || {}) : [];
|
|
432
|
+
const namespaces = _typeObj?.namespaced && !rootGetters.isAllNamespaces ? Object.keys(rootGetters.activeNamespaceCache || {}) : [];
|
|
433
433
|
|
|
434
434
|
return matchingCounts(_typeObj, namespaces.length ? namespaces : null);
|
|
435
435
|
},
|
|
@@ -109,13 +109,13 @@ describe('steve: getters:', () => {
|
|
|
109
109
|
it('returns a string with a labelSelector and filter, and formatted for steve if the url starts with "/v1"', () => {
|
|
110
110
|
expect(urlOptionsGetter('/v1/foo', { labelSelector: 'a=b', filter: { bar: 'baz', far: 'faz' } })).toBe('/v1/foo?labelSelector=a=b&filter=bar=baz&far=faz&exclude=metadata.managedFields');
|
|
111
111
|
});
|
|
112
|
-
it('returns a string with an exclude statement for "bar"
|
|
113
|
-
expect(urlOptionsGetter('/v1/foo', { excludeFields: ['bar'] })).toBe('/v1/foo?exclude=bar
|
|
112
|
+
it('returns a string with an exclude statement for "bar" if excludeFields is a single element array with the string "bar" and the url starts with "/v1/"', () => {
|
|
113
|
+
expect(urlOptionsGetter('/v1/foo', { excludeFields: ['bar'] })).toBe('/v1/foo?exclude=bar');
|
|
114
114
|
});
|
|
115
|
-
it('returns a string without an exclude statement if
|
|
116
|
-
expect(urlOptionsGetter('foo', {
|
|
115
|
+
it('returns a string without an exclude statement for "managedFields" if omitExcludeFields includes it and the url starts with "/v1/"', () => {
|
|
116
|
+
expect(urlOptionsGetter('/v1/foo', { omitExcludeFields: ['metadata.managedFields'] })).toBe('/v1/foo?');
|
|
117
117
|
});
|
|
118
|
-
it('returns a string without an exclude statement if excludeFields is
|
|
118
|
+
it('returns a string without an exclude statement if excludeFields is set but the url does not start with "/v1/"', () => {
|
|
119
119
|
expect(urlOptionsGetter('foo', { excludeFields: ['bar'] })).toBe('foo');
|
|
120
120
|
});
|
|
121
121
|
it('returns a string with a limit applied if a limit is provided', () => {
|
package/plugins/steve/getters.js
CHANGED
|
@@ -119,11 +119,13 @@ export default {
|
|
|
119
119
|
// excludeFields should be an array of strings representing the paths of the fields to exclude
|
|
120
120
|
// only works on Steve but is ignored without error by Norman
|
|
121
121
|
if (isSteve) {
|
|
122
|
-
if (Array.isArray(opt?.excludeFields)) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
122
|
+
if (!Array.isArray(opt?.excludeFields)) {
|
|
123
|
+
const excludeFields = ['metadata.managedFields'];
|
|
124
|
+
|
|
125
|
+
// for some resources, we might want to include fields, excluded by default.
|
|
126
|
+
opt.excludeFields = Array.isArray(opt?.omitExcludeFields) ? excludeFields.filter((f) => !f.includes(opt.omitExcludeFields)) : excludeFields;
|
|
126
127
|
}
|
|
128
|
+
|
|
127
129
|
const excludeParamsString = opt.excludeFields.map((field) => `exclude=${ field }`).join('&');
|
|
128
130
|
|
|
129
131
|
url += `${ url.includes('?') ? '&' : '?' }${ excludeParamsString }`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ANNOTATIONS_TO_IGNORE_REGEX, LABELS_TO_IGNORE_REGEX
|
|
1
|
+
import { ANNOTATIONS_TO_IGNORE_REGEX, LABELS_TO_IGNORE_REGEX } from '@shell/config/labels-annotations';
|
|
2
2
|
import omitBy from 'lodash/omitBy';
|
|
3
3
|
import pickBy from 'lodash/pickBy';
|
|
4
4
|
import Vue from 'vue';
|
|
@@ -100,8 +100,4 @@ export default class HybridModel extends Resource {
|
|
|
100
100
|
get state() {
|
|
101
101
|
return this.stateObj?.name || 'unknown';
|
|
102
102
|
}
|
|
103
|
-
|
|
104
|
-
get description() {
|
|
105
|
-
return this.metadata?.annotations?.[DESCRIPTION] || this.spec?.description || this._description;
|
|
106
|
-
}
|
|
107
103
|
}
|