@rancher/shell 2.0.1 → 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 +51 -26
- package/assets/translations/zh-hans.yaml +1 -0
- package/components/AssignTo.vue +2 -0
- package/components/Questions/index.vue +2 -2
- package/components/auth/RoleDetailEdit.vue +5 -4
- 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/labeled-select-utils/labeled-select.utils.ts +1 -1
- package/config/pagination-table-headers.js +5 -4
- 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 +1 -1
- package/config/router/navigation-guards/index.js +2 -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/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/initialize/entry-helpers.js +4 -21
- package/mixins/__tests__/chart.test.ts +4 -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/management.cattle.io.cluster.js +2 -2
- package/models/management.cattle.io.user.js +3 -3
- package/models/nodedriver.js +5 -0
- package/models/provisioning.cattle.io.cluster.js +4 -0
- package/package.json +1 -1
- package/pages/404.vue +15 -0
- package/pages/auth/login.vue +4 -1
- package/pages/auth/setup.vue +4 -1
- package/pages/c/_cluster/explorer/index.vue +5 -0
- 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/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/scripts/extension/helm/charts/ui-plugin-server/Chart.yaml +1 -1
- package/scripts/publish-shell.sh +53 -55
- package/scripts/test-plugins-build.sh +45 -39
- package/shell/types/shell/index.d.ts +2 -0
- package/store/type-map.js +4 -2
- package/types/store/pagination.types.ts +1 -1
- package/utils/cluster.js +9 -0
- package/utils/settings.ts +3 -1
- package/creators/app/app.package.json +0 -14
- 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/types/shell/index.d.ts +0 -4585
|
@@ -10,14 +10,28 @@ const IGNORED_ANNOTATIONS = [
|
|
|
10
10
|
'deprecated.deployment.rollback.to',
|
|
11
11
|
];
|
|
12
12
|
|
|
13
|
+
const replicasRegEx = /Replicas: (\d+)/;
|
|
14
|
+
|
|
13
15
|
export default class Deployment extends Workload {
|
|
14
16
|
get replicaSetId() {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
const relationships = this.metadata?.relationships || [];
|
|
18
|
+
|
|
19
|
+
// Find all relevant ReplicaSet relationships
|
|
20
|
+
const replicaSetRelationships = relationships.filter((relationship) => relationship.rel === 'owner' && relationship.toType === WORKLOAD_TYPES.REPLICA_SET
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
// Filter the ReplicaSets based on replicas > 0
|
|
24
|
+
const activeReplicaSet = replicaSetRelationships.find((relationship) => {
|
|
25
|
+
const replicasMatch = relationship.message?.match(replicasRegEx);
|
|
26
|
+
const replicas = replicasMatch ? parseInt(replicasMatch[1], 10) : 0;
|
|
27
|
+
|
|
28
|
+
return replicas > 0;
|
|
18
29
|
});
|
|
19
30
|
|
|
20
|
-
|
|
31
|
+
// If no active ReplicaSet is found, fall back to the first one from the list
|
|
32
|
+
const selectedReplicaSet = activeReplicaSet || replicaSetRelationships[0];
|
|
33
|
+
|
|
34
|
+
return selectedReplicaSet?.toId?.replace(`${ this.namespace }/`, '');
|
|
21
35
|
}
|
|
22
36
|
|
|
23
37
|
async rollBack(cluster, deployment, revision) {
|
|
@@ -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';
|
package/package.json
CHANGED
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
|
@@ -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;
|
|
@@ -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
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
annotations:
|
|
2
2
|
catalog.cattle.io/certified: rancher # Any application we are adding as a helm chart
|
|
3
|
-
catalog.cattle.io/kube-version: '>= 1.16.0-0
|
|
3
|
+
catalog.cattle.io/kube-version: '>= 1.16.0-0'
|
|
4
4
|
catalog.cattle.io/namespace: cattle-ui-plugin-system # Must prefix with cattle- and suffix with -system=
|
|
5
5
|
catalog.cattle.io/os: linux
|
|
6
6
|
catalog.cattle.io/permits-os: linux, windows
|
package/scripts/publish-shell.sh
CHANGED
|
@@ -6,10 +6,15 @@ BASE_DIR="$(
|
|
|
6
6
|
pwd
|
|
7
7
|
)"
|
|
8
8
|
SHELL_DIR=$BASE_DIR/shell/
|
|
9
|
-
|
|
10
|
-
PUBLISH_ARGS="--no-git-tag-version --access public $PUBLISH_ARGS"
|
|
9
|
+
CREATORS_DIR=$BASE_DIR/creators/extension
|
|
11
10
|
FORCE_PUBLISH_TO_NPM="false"
|
|
12
|
-
|
|
11
|
+
DEFAULT_NPM_REGISTRY="https://registry.npmjs.org"
|
|
12
|
+
|
|
13
|
+
# if TAG doesn't exist, we can exit as it's needed for any type of publish.
|
|
14
|
+
if [ -z "$TAG" ]; then
|
|
15
|
+
echo "You need to set the TAG variable first!"
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
13
18
|
|
|
14
19
|
if [ ! -d "${BASE_DIR}/node_modules" ]; then
|
|
15
20
|
echo "You need to run 'yarn install' first"
|
|
@@ -23,44 +28,25 @@ if [ "$1" == "--npm" ]; then
|
|
|
23
28
|
fi
|
|
24
29
|
|
|
25
30
|
if [ "$FORCE_PUBLISH_TO_NPM" == "true" ]; then
|
|
26
|
-
export
|
|
31
|
+
export NPM_REGISTRY=$DEFAULT_NPM_REGISTRY
|
|
27
32
|
fi
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
# Need to copy them to a temporary location, so we can patch the version number
|
|
31
|
-
# before publishing
|
|
32
|
-
|
|
33
|
-
# To set a token for NPM registry auth: `npm config set //registry.npmjs.org/:_authToken <TOKEN>``
|
|
34
|
-
|
|
35
|
-
PKG_DIST=$BASE_DIR/dist-pkg/creators
|
|
36
|
-
mkdir -p ${PKG_DIST}
|
|
37
|
-
rm -rf ${PKG_DIST}/app
|
|
38
|
-
rm -rf ${PKG_DIST}/pkg
|
|
39
|
-
rm -rf ${PKG_DIST}/update
|
|
34
|
+
PUBLISH_ARGS="--no-git-tag-version --access public --registry $NPM_REGISTRY"
|
|
40
35
|
|
|
41
36
|
pushd ${SHELL_DIR} >/dev/null
|
|
42
37
|
|
|
43
|
-
PKG_VERSION=$(node -p "require('./package.json').version")
|
|
44
|
-
popd >/dev/null
|
|
45
|
-
|
|
46
|
-
echo "Publishing version: $PKG_VERSION"
|
|
47
|
-
|
|
48
|
-
cp -R ${SHELL_DIR}/creators/app ${PKG_DIST}
|
|
49
|
-
cp -R ${SHELL_DIR}/creators/pkg ${PKG_DIST}
|
|
50
|
-
cp -R ${SHELL_DIR}/creators/update ${PKG_DIST}
|
|
51
|
-
|
|
52
|
-
sed -i.bak -e "s/\"0.0.0/"\"$PKG_VERSION"/g" ${PKG_DIST}/app/package.json
|
|
53
|
-
sed -i.bak -e "s/\"0.0.0/"\"$PKG_VERSION"/g" ${PKG_DIST}/pkg/package.json
|
|
54
|
-
sed -i.bak -e "s/\"0.0.0/"\"$PKG_VERSION"/g" ${PKG_DIST}/update/package.json
|
|
55
|
-
|
|
56
|
-
rm ${PKG_DIST}/app/package.json.bak
|
|
57
|
-
rm ${PKG_DIST}/pkg/package.json.bak
|
|
58
|
-
rm ${PKG_DIST}/update/package.json.bak
|
|
59
|
-
|
|
60
38
|
function publish() {
|
|
61
39
|
NAME=$1
|
|
62
40
|
FOLDER=$2
|
|
63
41
|
|
|
42
|
+
# if we pass a third arg, that is the version number
|
|
43
|
+
# that we want to actually publish on NPM
|
|
44
|
+
# they should match with the package.json version stated
|
|
45
|
+
# because of the check in the "Check Tags Version Matching" step in the workflow
|
|
46
|
+
if [ -n "$3" ]; then
|
|
47
|
+
PKG_VERSION=$3
|
|
48
|
+
fi
|
|
49
|
+
|
|
64
50
|
echo "Publishing ${NAME} from ${FOLDER}"
|
|
65
51
|
pushd ${FOLDER} >/dev/null
|
|
66
52
|
|
|
@@ -71,25 +57,20 @@ function publish() {
|
|
|
71
57
|
cp -R ${BASE_DIR}/pkg/rancher-components/src/components ./rancher-components/
|
|
72
58
|
fi
|
|
73
59
|
|
|
74
|
-
if
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# Remove index.ts from pkg files, as we don't want to replace that
|
|
81
|
-
rm -f ./pkg/files/index.ts
|
|
82
|
-
|
|
83
|
-
# Update the package.json for the app
|
|
84
|
-
cd app
|
|
85
|
-
node ${SCRIPT_DIR}/record-deps.js
|
|
86
|
-
cd ..
|
|
60
|
+
# if the PKG_VERSION has a - it means it will be a pre-release of legacy-v2
|
|
61
|
+
if [[ $PKG_VERSION == *"-"* ]]; then
|
|
62
|
+
PUBLISH_ARGS="$PUBLISH_ARGS --tag legacy-v2-pre-release"
|
|
63
|
+
else
|
|
64
|
+
# If we need to release shell, we tag it as legacy-v2
|
|
65
|
+
PUBLISH_ARGS="$PUBLISH_ARGS --tag legacy-v2"
|
|
87
66
|
fi
|
|
88
67
|
|
|
89
68
|
# Make a note of dependency versions, if required
|
|
90
69
|
node ${SCRIPT_DIR}/record-deps.js
|
|
91
70
|
|
|
92
|
-
|
|
71
|
+
echo "Publishing to registry: $NPM_REGISTRY with args: $PUBLISH_ARGS"
|
|
72
|
+
|
|
73
|
+
npm publish ${PUBLISH_ARGS}
|
|
93
74
|
RET=$?
|
|
94
75
|
|
|
95
76
|
popd >/dev/null
|
|
@@ -100,15 +81,32 @@ function publish() {
|
|
|
100
81
|
fi
|
|
101
82
|
}
|
|
102
83
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
publish "Application creator" ${PKG_DIST}/app/
|
|
109
|
-
publish "Package creator" ${PKG_DIST}/pkg/
|
|
110
|
-
publish "Update" ${PKG_DIST}/update/
|
|
84
|
+
echo "TAG ${TAG}"
|
|
85
|
+
|
|
86
|
+
# let's get the package name and version from the tag
|
|
87
|
+
PKG_NAME=$(sed 's/-pkg-v.*//' <<< "$TAG")
|
|
88
|
+
PKG_V=$(sed 's/.*-pkg-v//'<<< "$TAG")
|
|
111
89
|
|
|
112
|
-
echo "
|
|
90
|
+
echo "PKG_NAME ${PKG_NAME}"
|
|
91
|
+
echo "PKG_V ${PKG_V}"
|
|
113
92
|
|
|
93
|
+
# Generate the type definitions for the shell
|
|
94
|
+
if [ ${PKG_NAME} == "shell" ]; then
|
|
95
|
+
${SCRIPT_DIR}/typegen.sh
|
|
96
|
+
fi
|
|
114
97
|
|
|
98
|
+
# version comparison checks
|
|
99
|
+
case $PKG_NAME in
|
|
100
|
+
"shell")
|
|
101
|
+
echo "Publishing only Shell pkg via tagged release"
|
|
102
|
+
publish "Shell" ${SHELL_DIR} ${PKG_V}
|
|
103
|
+
;;
|
|
104
|
+
"creators")
|
|
105
|
+
echo "Publishing only Creators pkg via tagged release"
|
|
106
|
+
publish "Extension creator" ${CREATORS_DIR} ${PKG_V}
|
|
107
|
+
;;
|
|
108
|
+
*)
|
|
109
|
+
echo "something went wrong with the tagging name => TAG: ${TAG} , PKG_NAME: ${PKG_NAME}. Admissable names are 'shell' and 'creator'"
|
|
110
|
+
exit 1
|
|
111
|
+
;;
|
|
112
|
+
esac
|