@rancher/shell 0.3.17 → 0.3.19
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 +8 -4
- package/assets/translations/zh-hans.yaml +64 -8
- package/components/AsyncButton.vue +1 -1
- package/components/Inactivity.vue +10 -0
- package/components/LazyImage.vue +2 -2
- package/components/PromptRestore.vue +8 -6
- package/components/ResourceDetail/Masthead.vue +1 -1
- package/components/ResourceDetail/index.vue +4 -2
- package/components/__tests__/PromptRestore.test.ts +142 -0
- package/components/auth/AzureWarning.vue +1 -1
- package/components/auth/RoleDetailEdit.vue +2 -0
- package/components/fleet/FleetResources.vue +3 -64
- package/components/form/FileImageSelector.vue +9 -0
- package/components/form/FileSelector.vue +2 -1
- package/components/form/MatchExpressions.vue +1 -3
- package/components/form/__tests__/FileImageSelector.test.ts +42 -0
- package/components/form/__tests__/FileSelector.test.ts +76 -0
- package/components/formatter/ClusterProvider.vue +3 -1
- package/components/formatter/__tests__/ClusterProvider.test.ts +24 -0
- package/components/nav/WindowManager/ContainerShell.vue +60 -36
- package/components/nav/WindowManager/__tests__/ContainerShell.test.ts +561 -0
- package/config/labels-annotations.js +2 -1
- package/config/persistentVolume.ts +108 -0
- package/config/product/manager.js +5 -1
- package/config/types.js +2 -0
- package/core/plugin-helpers.js +19 -3
- package/core/types.ts +4 -0
- package/detail/fleet.cattle.io.gitrepo.vue +10 -2
- package/detail/pod.vue +36 -3
- package/detail/workload/index.vue +40 -9
- package/dialog/DiagnosticTimingsDialog.vue +1 -0
- package/edit/__tests__/ui.cattle.io.navlink.test.ts +110 -0
- package/edit/fleet.cattle.io.clustergroup.vue +14 -3
- package/edit/persistentvolume/__tests__/persistentvolume.test.ts +82 -0
- package/edit/persistentvolume/index.vue +2 -1
- package/edit/persistentvolume/plugins/csi.vue +3 -1
- package/edit/persistentvolume/plugins/longhorn.vue +12 -12
- package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +15 -11
- package/edit/provisioning.cattle.io.cluster/index.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/rke2.vue +5 -1
- package/edit/storage.k8s.io.storageclass/index.vue +1 -2
- package/edit/ui.cattle.io.navlink.vue +213 -186
- package/layouts/default.vue +1 -1
- package/list/group.principal.vue +1 -1
- package/middleware/authenticated.js +12 -4
- package/mixins/create-edit-view/impl.js +2 -2
- package/models/chart.js +1 -1
- package/models/etcdbackup.js +2 -1
- package/models/fleet.cattle.io.cluster.js +33 -4
- package/models/fleet.cattle.io.gitrepo.js +112 -38
- package/models/management.cattle.io.cluster.js +13 -3
- package/models/management.cattle.io.kontainerdriver.js +14 -0
- package/models/persistentvolume.js +2 -111
- package/models/pod.js +30 -0
- package/models/rke.cattle.io.etcdsnapshot.js +10 -7
- package/package.json +1 -1
- package/pages/c/_cluster/apps/charts/install.vue +74 -25
- package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
- package/pages/c/_cluster/auth/roles/index.vue +1 -1
- package/pages/c/_cluster/explorer/index.vue +1 -1
- package/pages/c/_cluster/manager/cloudCredential/_id.vue +0 -1
- package/pages/c/_cluster/manager/cloudCredential/create.vue +0 -1
- package/pages/c/_cluster/settings/brand.vue +11 -8
- package/pages/c/_cluster/uiplugins/index.vue +9 -4
- package/pages/diagnostic.vue +5 -3
- package/pages/home.vue +1 -1
- package/plugins/dashboard-store/__tests__/actions.spec.ts +165 -0
- package/plugins/dashboard-store/__tests__/getters.spec.ts +100 -0
- package/plugins/dashboard-store/__tests__/{mutations.spec.js → mutations.spec.ts} +2 -2
- package/plugins/dashboard-store/actions.js +1 -1
- package/plugins/dashboard-store/resource-class.js +4 -0
- package/plugins/steve/__tests__/getters.spec.ts +93 -0
- package/plugins/steve/getters.js +21 -1
- package/plugins/steve/subscribe.js +1 -3
- package/rancher-components/components/BadgeState/BadgeState.spec.ts +12 -0
- package/rancher-components/components/BadgeState/BadgeState.vue +111 -0
- package/rancher-components/components/BadgeState/index.ts +1 -0
- package/rancher-components/components/Banner/Banner.test.ts +63 -0
- package/rancher-components/components/Banner/Banner.vue +244 -0
- package/rancher-components/components/Banner/index.ts +1 -0
- package/rancher-components/components/Card/Card.test.ts +37 -0
- package/rancher-components/components/Card/Card.vue +167 -0
- package/rancher-components/components/Card/index.ts +1 -0
- package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +68 -0
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +420 -0
- package/rancher-components/components/Form/Checkbox/index.ts +1 -0
- package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +23 -0
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +355 -0
- package/rancher-components/components/Form/LabeledInput/index.ts +1 -0
- package/rancher-components/components/Form/Radio/RadioButton.test.ts +31 -0
- package/rancher-components/components/Form/Radio/RadioButton.vue +287 -0
- package/rancher-components/components/Form/Radio/RadioGroup.vue +254 -0
- package/rancher-components/components/Form/Radio/index.ts +2 -0
- package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +170 -0
- package/rancher-components/components/Form/TextArea/index.ts +1 -0
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +94 -0
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +149 -0
- package/rancher-components/components/Form/ToggleSwitch/index.ts +1 -0
- package/rancher-components/components/Form/index.ts +5 -0
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +151 -0
- package/rancher-components/components/LabeledTooltip/index.ts +1 -0
- package/rancher-components/components/StringList/StringList.test.ts +484 -0
- package/rancher-components/components/StringList/StringList.vue +611 -0
- package/rancher-components/components/StringList/index.ts +1 -0
- package/scripts/extension/publish +54 -14
- package/scripts/typegen.sh +10 -2
- package/store/index.js +1 -3
- package/store/store-types.js +2 -0
- package/types/api.d.ts +1 -0
- package/types/fleet.d.ts +1 -0
- package/types/shell/index.d.ts +696 -2
- package/types/userPreferences.d.ts +1 -1
- package/utils/__mocks__/socket.js +21 -0
- package/utils/grafana.js +23 -11
- package/utils/selector.js +2 -1
- package/utils/socket.js +1 -0
- package/utils/validators/formRules/index.ts +3 -3
- package/plugins/steve/urloptions.js +0 -47
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { convert, matching, convertSelectorObj } from '@shell/utils/selector';
|
|
2
2
|
import jsyaml from 'js-yaml';
|
|
3
|
-
import { escapeHtml } from '@shell/utils/string';
|
|
3
|
+
import { escapeHtml, randomStr } from '@shell/utils/string';
|
|
4
4
|
import { FLEET } from '@shell/config/types';
|
|
5
5
|
import { FLEET as FLEET_ANNOTATIONS } from '@shell/config/labels-annotations';
|
|
6
6
|
import { addObject, addObjects, findBy, insertAt } from '@shell/utils/array';
|
|
7
7
|
import { set } from '@shell/utils/object';
|
|
8
8
|
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
9
|
+
import { STATES_ENUM, colorForState, stateDisplay, stateSort } from '@shell/plugins/dashboard-store/resource-class';
|
|
10
|
+
import { NAME } from '@shell/config/product/explorer';
|
|
9
11
|
|
|
10
12
|
function quacksLikeAHash(str) {
|
|
11
|
-
if (
|
|
13
|
+
if (str.match(/^[a-f0-9]{40,}$/i)) {
|
|
12
14
|
return true;
|
|
13
15
|
}
|
|
14
16
|
|
|
@@ -24,7 +26,7 @@ export default class GitRepo extends SteveModel {
|
|
|
24
26
|
|
|
25
27
|
spec.repo = spec.repo || '';
|
|
26
28
|
|
|
27
|
-
if (
|
|
29
|
+
if (!spec.branch && !spec.revision) {
|
|
28
30
|
spec.branch = 'master';
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -86,7 +88,7 @@ export default class GitRepo extends SteveModel {
|
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
get state() {
|
|
89
|
-
if (
|
|
91
|
+
if (this.spec?.paused === true) {
|
|
90
92
|
return 'paused';
|
|
91
93
|
}
|
|
92
94
|
|
|
@@ -98,10 +100,10 @@ export default class GitRepo extends SteveModel {
|
|
|
98
100
|
const clusters = workspace?.clusters || [];
|
|
99
101
|
const groups = workspace?.clusterGroups || [];
|
|
100
102
|
|
|
101
|
-
if (
|
|
103
|
+
if (workspace?.id === 'fleet-local') {
|
|
102
104
|
const local = findBy(groups, 'id', 'fleet-local/default');
|
|
103
105
|
|
|
104
|
-
if (
|
|
106
|
+
if (local) {
|
|
105
107
|
return local.targetClusters;
|
|
106
108
|
}
|
|
107
109
|
|
|
@@ -114,30 +116,30 @@ export default class GitRepo extends SteveModel {
|
|
|
114
116
|
|
|
115
117
|
const out = [];
|
|
116
118
|
|
|
117
|
-
for (
|
|
118
|
-
if (
|
|
119
|
+
for (const tgt of this.spec.targets) {
|
|
120
|
+
if (tgt.clusterName) {
|
|
119
121
|
const cluster = findBy(clusters, 'metadata.name', tgt.clusterName);
|
|
120
122
|
|
|
121
|
-
if (
|
|
123
|
+
if (cluster) {
|
|
122
124
|
addObject(out, cluster);
|
|
123
125
|
}
|
|
124
|
-
} else if (
|
|
126
|
+
} else if (tgt.clusterGroup) {
|
|
125
127
|
const group = findBy(groups, {
|
|
126
128
|
'metadata.namespace': this.metadata.namespace,
|
|
127
129
|
'metadata.name': tgt.clusterGroup,
|
|
128
130
|
});
|
|
129
131
|
|
|
130
|
-
if (
|
|
132
|
+
if (group) {
|
|
131
133
|
addObjects(out, group.targetClusters);
|
|
132
134
|
}
|
|
133
|
-
} else if (
|
|
135
|
+
} else if (tgt.clusterGroupSelector) {
|
|
134
136
|
const expressions = convertSelectorObj(tgt.clusterGroupSelector);
|
|
135
137
|
const matchingGroups = matching(groups, expressions);
|
|
136
138
|
|
|
137
|
-
for (
|
|
139
|
+
for (const group of matchingGroups) {
|
|
138
140
|
addObjects(out, group.targetClusters);
|
|
139
141
|
}
|
|
140
|
-
} else if (
|
|
142
|
+
} else if (tgt.clusterSelector) {
|
|
141
143
|
const expressions = convertSelectorObj(tgt.clusterSelector);
|
|
142
144
|
const matchingClusters = matching(clusters, expressions);
|
|
143
145
|
|
|
@@ -151,7 +153,7 @@ export default class GitRepo extends SteveModel {
|
|
|
151
153
|
get github() {
|
|
152
154
|
const match = this.spec.repo.match(/^https?:\/\/github\.com\/(.*?)(\.git)?\/*$/);
|
|
153
155
|
|
|
154
|
-
if (
|
|
156
|
+
if (match) {
|
|
155
157
|
return match[1];
|
|
156
158
|
}
|
|
157
159
|
|
|
@@ -159,7 +161,7 @@ export default class GitRepo extends SteveModel {
|
|
|
159
161
|
}
|
|
160
162
|
|
|
161
163
|
get repoIcon() {
|
|
162
|
-
if (
|
|
164
|
+
if (this.github) {
|
|
163
165
|
return 'icon icon-github';
|
|
164
166
|
}
|
|
165
167
|
|
|
@@ -173,7 +175,7 @@ export default class GitRepo extends SteveModel {
|
|
|
173
175
|
repo = repo.replace(/^https:\/\//, '');
|
|
174
176
|
repo = repo.replace(/\/+$/, '');
|
|
175
177
|
|
|
176
|
-
if (
|
|
178
|
+
if (this.github) {
|
|
177
179
|
return this.github;
|
|
178
180
|
}
|
|
179
181
|
|
|
@@ -184,15 +186,15 @@ export default class GitRepo extends SteveModel {
|
|
|
184
186
|
const spec = this.spec;
|
|
185
187
|
const hash = this.status?.commit?.substr(0, 7);
|
|
186
188
|
|
|
187
|
-
if (
|
|
189
|
+
if (!spec || !spec.repo) {
|
|
188
190
|
return null;
|
|
189
191
|
}
|
|
190
192
|
|
|
191
|
-
if (
|
|
193
|
+
if (spec.revision && quacksLikeAHash(spec.revision)) {
|
|
192
194
|
return spec.revision.substr(0, 7);
|
|
193
|
-
} else if (
|
|
195
|
+
} else if (spec.revision) {
|
|
194
196
|
return spec.revision;
|
|
195
|
-
} else if (
|
|
197
|
+
} else if (spec.branch) {
|
|
196
198
|
return spec.branch + (hash ? ` @ ${ hash }` : '');
|
|
197
199
|
}
|
|
198
200
|
|
|
@@ -220,7 +222,7 @@ export default class GitRepo extends SteveModel {
|
|
|
220
222
|
|
|
221
223
|
advanced = jsyaml.dump(targets);
|
|
222
224
|
|
|
223
|
-
if (
|
|
225
|
+
if (advanced === '[]\n') {
|
|
224
226
|
advanced = `# - name:
|
|
225
227
|
# clusterSelector:
|
|
226
228
|
# matchLabels:
|
|
@@ -240,39 +242,39 @@ export default class GitRepo extends SteveModel {
|
|
|
240
242
|
`;
|
|
241
243
|
}
|
|
242
244
|
|
|
243
|
-
if (
|
|
245
|
+
if (this.metadata.namespace === 'fleet-local') {
|
|
244
246
|
mode = 'local';
|
|
245
|
-
} else if (
|
|
247
|
+
} else if (!targets.length) {
|
|
246
248
|
mode = 'none';
|
|
247
|
-
} else if (
|
|
249
|
+
} else if (targets.length === 1) {
|
|
248
250
|
const target = targets[0];
|
|
249
251
|
|
|
250
252
|
if (Object.keys(target).length > 1) {
|
|
251
253
|
// There are multiple properties in a single target, so use the 'advanced' mode
|
|
252
254
|
// (otherwise any existing content is nuked for what we provide)
|
|
253
255
|
mode = 'advanced';
|
|
254
|
-
} else if (
|
|
256
|
+
} else if (target.clusterGroup) {
|
|
255
257
|
clusterGroup = target.clusterGroup;
|
|
256
258
|
|
|
257
|
-
if (
|
|
259
|
+
if (!mode) {
|
|
258
260
|
mode = 'clusterGroup';
|
|
259
261
|
}
|
|
260
|
-
} else if (
|
|
262
|
+
} else if (target.clusterName) {
|
|
261
263
|
mode = 'cluster';
|
|
262
264
|
cluster = target.clusterName;
|
|
263
|
-
} else if (
|
|
264
|
-
if (
|
|
265
|
+
} else if (target.clusterSelector) {
|
|
266
|
+
if (Object.keys(target.clusterSelector).length === 0) {
|
|
265
267
|
mode = 'all';
|
|
266
268
|
} else {
|
|
267
269
|
const expressions = convert(target.clusterSelector.matchLabels, target.clusterSelector.matchExpressions);
|
|
268
270
|
|
|
269
|
-
if (
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
271
|
+
if (expressions.length === 1 &&
|
|
272
|
+
expressions[0].key === FLEET_ANNOTATIONS.CLUSTER_NAME &&
|
|
273
|
+
expressions[0].operator === 'In' &&
|
|
274
|
+
expressions[0].values.length === 1
|
|
273
275
|
) {
|
|
274
276
|
cluster = expressions[0].values[0];
|
|
275
|
-
if (
|
|
277
|
+
if (!mode) {
|
|
276
278
|
mode = 'cluster';
|
|
277
279
|
}
|
|
278
280
|
}
|
|
@@ -280,7 +282,7 @@ export default class GitRepo extends SteveModel {
|
|
|
280
282
|
}
|
|
281
283
|
}
|
|
282
284
|
|
|
283
|
-
if (
|
|
285
|
+
if (!mode) {
|
|
284
286
|
mode = 'advanced';
|
|
285
287
|
}
|
|
286
288
|
|
|
@@ -296,7 +298,7 @@ export default class GitRepo extends SteveModel {
|
|
|
296
298
|
get groupByLabel() {
|
|
297
299
|
const name = this.metadata.namespace;
|
|
298
300
|
|
|
299
|
-
if (
|
|
301
|
+
if (name) {
|
|
300
302
|
return this.$rootGetters['i18n/t']('resourceTable.groupLabel.workspace', { name: escapeHtml(name) });
|
|
301
303
|
} else {
|
|
302
304
|
return this.$rootGetters['i18n/t']('resourceTable.groupLabel.notInAWorkspace');
|
|
@@ -306,7 +308,7 @@ export default class GitRepo extends SteveModel {
|
|
|
306
308
|
get bundles() {
|
|
307
309
|
const all = this.$getters['all'](FLEET.BUNDLE);
|
|
308
310
|
|
|
309
|
-
return all.filter((bundle) => bundle.
|
|
311
|
+
return all.filter((bundle) => bundle.repoName === this.name &&
|
|
310
312
|
bundle.namespace === this.namespace &&
|
|
311
313
|
bundle.namespacedName.startsWith(`${ this.namespace }:${ this.name }`));
|
|
312
314
|
}
|
|
@@ -325,6 +327,78 @@ export default class GitRepo extends SteveModel {
|
|
|
325
327
|
return bds.filter((bd) => bd.metadata?.labels?.['fleet.cattle.io/repo-name'] === this.name);
|
|
326
328
|
}
|
|
327
329
|
|
|
330
|
+
get resourcesStatuses() {
|
|
331
|
+
const clusters = this.targetClusters || [];
|
|
332
|
+
const resources = this.status?.resources || [];
|
|
333
|
+
const conditions = this.status?.conditions || [];
|
|
334
|
+
|
|
335
|
+
const out = [];
|
|
336
|
+
|
|
337
|
+
for (const c of clusters) {
|
|
338
|
+
const clusterBundleDeploymentResources = this.bundleDeployments
|
|
339
|
+
.find((bd) => bd.metadata?.labels?.[FLEET_ANNOTATIONS.CLUSTER] === c.metadata.name)
|
|
340
|
+
?.status?.resources || [];
|
|
341
|
+
|
|
342
|
+
resources.forEach((r, i) => {
|
|
343
|
+
let namespacedName = r.name;
|
|
344
|
+
|
|
345
|
+
if (r.namespace) {
|
|
346
|
+
namespacedName = `${ r.namespace }:${ r.name }`;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
let state = r.state;
|
|
350
|
+
const perEntry = r.perClusterState?.find((x) => x.clusterId === c.id);
|
|
351
|
+
const tooMany = r.perClusterState?.length >= 10 || false;
|
|
352
|
+
|
|
353
|
+
if (perEntry) {
|
|
354
|
+
state = perEntry.state;
|
|
355
|
+
} else if (tooMany) {
|
|
356
|
+
state = STATES_ENUM.UNKNOWN;
|
|
357
|
+
} else {
|
|
358
|
+
state = STATES_ENUM.READY;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const color = colorForState(state).replace('text-', 'bg-');
|
|
362
|
+
const display = stateDisplay(state);
|
|
363
|
+
|
|
364
|
+
const detailLocation = {
|
|
365
|
+
name: `c-cluster-product-resource${ r.namespace ? '-namespace' : '' }-id`,
|
|
366
|
+
params: {
|
|
367
|
+
product: NAME,
|
|
368
|
+
cluster: c.metadata.labels[FLEET_ANNOTATIONS.CLUSTER_NAME],
|
|
369
|
+
resource: r.type,
|
|
370
|
+
namespace: r.namespace,
|
|
371
|
+
id: r.name,
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
out.push({
|
|
376
|
+
key: `${ r.id }-${ c.id }-${ r.type }-${ r.namespace }-${ r.name }`,
|
|
377
|
+
tableKey: `${ r.id }-${ c.id }-${ r.type }-${ r.namespace }-${ r.name }-${ randomStr(8) }`,
|
|
378
|
+
kind: r.kind,
|
|
379
|
+
apiVersion: r.apiVersion,
|
|
380
|
+
type: r.type,
|
|
381
|
+
id: r.id,
|
|
382
|
+
namespace: r.namespace,
|
|
383
|
+
name: r.name,
|
|
384
|
+
clusterId: c.id,
|
|
385
|
+
clusterName: c.nameDisplay,
|
|
386
|
+
state,
|
|
387
|
+
stateBackground: color,
|
|
388
|
+
stateDisplay: display,
|
|
389
|
+
stateSort: stateSort(color, display),
|
|
390
|
+
namespacedName,
|
|
391
|
+
detailLocation,
|
|
392
|
+
conditions: conditions[i],
|
|
393
|
+
bundleDeploymentStatus: clusterBundleDeploymentResources?.[i],
|
|
394
|
+
creationTimestamp: clusterBundleDeploymentResources?.[i]?.createdAt
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return out;
|
|
400
|
+
}
|
|
401
|
+
|
|
328
402
|
get clustersList() {
|
|
329
403
|
return this.$getters['all'](FLEET.CLUSTER);
|
|
330
404
|
}
|
|
@@ -19,6 +19,13 @@ import { KONTAINER_TO_DRIVER } from './management.cattle.io.kontainerdriver';
|
|
|
19
19
|
// If the logo is not named with the provider name, add an override here
|
|
20
20
|
const PROVIDER_LOGO_OVERRIDE = {};
|
|
21
21
|
|
|
22
|
+
function findRelationship(verb, type, relationships = []) {
|
|
23
|
+
const from = `${ verb }Type`;
|
|
24
|
+
const id = `${ verb }Id`;
|
|
25
|
+
|
|
26
|
+
return relationships.find((r) => r[from] === type)?.[id];
|
|
27
|
+
}
|
|
28
|
+
|
|
22
29
|
export default class MgmtCluster extends HybridModel {
|
|
23
30
|
get details() {
|
|
24
31
|
const out = [
|
|
@@ -440,9 +447,12 @@ export default class MgmtCluster extends HybridModel {
|
|
|
440
447
|
// cluster has the less human readable management cluster ID in it: fleet-default/c-khk48
|
|
441
448
|
|
|
442
449
|
const verb = this.isLocal || isRKE1 || this.isHostedKubernetesProvider ? 'to' : 'from';
|
|
443
|
-
const
|
|
444
|
-
|
|
450
|
+
const res = findRelationship(verb, CAPI.RANCHER_CLUSTER, this.metadata?.relationships);
|
|
451
|
+
|
|
452
|
+
if (res) {
|
|
453
|
+
return res;
|
|
454
|
+
}
|
|
445
455
|
|
|
446
|
-
return
|
|
456
|
+
return findRelationship(verb === 'to' ? 'from' : 'to', CAPI.RANCHER_CLUSTER, this.metadata?.relationships);
|
|
447
457
|
}
|
|
448
458
|
}
|
|
@@ -15,8 +15,10 @@ export const KONTAINER_TO_DRIVER = {
|
|
|
15
15
|
huaweicontainercloudengine: 'huaweicce', // Does this actually exist?
|
|
16
16
|
huaweiengine: 'huaweicce',
|
|
17
17
|
linodekubernetesengine: 'linodelke', // Does this actually exist?
|
|
18
|
+
lke: 'linodelke',
|
|
18
19
|
lkeengine: 'linodelke',
|
|
19
20
|
okeengine: 'oracleoke',
|
|
21
|
+
oke: 'oracleoke',
|
|
20
22
|
oraclecontainerengine: 'oracleoke', // Does this actually exist?
|
|
21
23
|
rke2: 'rke2',
|
|
22
24
|
tencentengine: 'tencenttke',
|
|
@@ -63,6 +65,18 @@ export default class KontainerDriver extends HybridModel {
|
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
get driverName() {
|
|
68
|
+
if (!this.spec.builtIn) {
|
|
69
|
+
// if the driver is not built in, there's a good change its a custom one
|
|
70
|
+
// custom drivers have a random id, so shouldn't be used as the type
|
|
71
|
+
// instead use the status.displayName. this will map to the name extracted from the binary
|
|
72
|
+
const driverName = this.status?.displayName?.toLowerCase();
|
|
73
|
+
|
|
74
|
+
if (driverName) {
|
|
75
|
+
// some drivers are built in but don't have the builtIn flag. ensure we pass these through K_TO_D
|
|
76
|
+
return KONTAINER_TO_DRIVER[driverName] || driverName;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
66
80
|
return KONTAINER_TO_DRIVER[this.id] || this.id;
|
|
67
81
|
}
|
|
68
82
|
}
|
|
@@ -1,116 +1,7 @@
|
|
|
1
|
-
import { PVC } from '@shell/config/types';
|
|
1
|
+
import { PVC, LONGHORN_DRIVER } from '@shell/config/types';
|
|
2
|
+
import { VOLUME_PLUGINS } from '@shell/config/persistentVolume';
|
|
2
3
|
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
3
4
|
|
|
4
|
-
export const VOLUME_PLUGINS = [
|
|
5
|
-
{
|
|
6
|
-
labelKey: 'persistentVolume.awsElasticBlockStore.label',
|
|
7
|
-
value: 'awsElasticBlockStore',
|
|
8
|
-
supported: true
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
labelKey: 'persistentVolume.azureDisk.label',
|
|
12
|
-
value: 'azureDisk',
|
|
13
|
-
supported: true
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
labelKey: 'persistentVolume.azureFile.label',
|
|
17
|
-
value: 'azureFile',
|
|
18
|
-
supported: true
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
labelKey: 'persistentVolume.cephfs.label',
|
|
22
|
-
value: 'cephfs',
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
labelKey: 'persistentVolume.rbd.label',
|
|
26
|
-
value: 'rbd',
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
labelKey: 'persistentVolume.csi.label',
|
|
30
|
-
value: 'csi',
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
labelKey: 'persistentVolume.fc.label',
|
|
34
|
-
value: 'fc',
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
labelKey: 'persistentVolume.flexVolume.label',
|
|
38
|
-
value: 'flexVolume',
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
labelKey: 'persistentVolume.flocker.label',
|
|
42
|
-
value: 'flocker',
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
labelKey: 'persistentVolume.glusterfs.label',
|
|
46
|
-
value: 'glusterfs',
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
labelKey: 'persistentVolume.gcePersistentDisk.label',
|
|
50
|
-
value: 'gcePersistentDisk',
|
|
51
|
-
supported: true
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
labelKey: 'persistentVolume.hostPath.label',
|
|
55
|
-
value: 'hostPath',
|
|
56
|
-
supported: true
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
labelKey: 'persistentVolume.iscsi.label',
|
|
60
|
-
value: 'iscsi',
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
labelKey: 'persistentVolume.local.label',
|
|
64
|
-
value: 'local',
|
|
65
|
-
supported: true
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
labelKey: 'persistentVolume.longhorn.label',
|
|
69
|
-
value: 'longhorn',
|
|
70
|
-
supported: true
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
labelKey: 'persistentVolume.nfs.label',
|
|
74
|
-
value: 'nfs',
|
|
75
|
-
supported: true
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
labelKey: 'persistentVolume.cinder.label',
|
|
79
|
-
value: 'cinder',
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
labelKey: 'persistentVolume.photonPersistentDisk.label',
|
|
83
|
-
value: 'photonPersistentDisk',
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
labelKey: 'persistentVolume.portworxVolume.label',
|
|
87
|
-
value: 'portworxVolume',
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
{
|
|
91
|
-
labelKey: 'persistentVolume.quobyte.label',
|
|
92
|
-
value: 'quobyte',
|
|
93
|
-
},
|
|
94
|
-
|
|
95
|
-
{
|
|
96
|
-
labelKey: 'persistentVolume.scaleIO.label',
|
|
97
|
-
value: 'scaleIO',
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
labelKey: 'persistentVolume.storageos.label',
|
|
101
|
-
value: 'storageos',
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
labelKey: 'persistentVolume.vsphereVolume.label',
|
|
105
|
-
value: 'vsphereVolume',
|
|
106
|
-
supported: true
|
|
107
|
-
},
|
|
108
|
-
];
|
|
109
|
-
|
|
110
|
-
export const LONGHORN_DRIVER = 'driver.longhorn.io';
|
|
111
|
-
|
|
112
|
-
export const LONGHORN_PLUGIN = VOLUME_PLUGINS.find((plugin) => plugin.value === 'longhorn');
|
|
113
|
-
|
|
114
5
|
export default class PV extends SteveModel {
|
|
115
6
|
// plugin display value table
|
|
116
7
|
get source() {
|
package/models/pod.js
CHANGED
|
@@ -15,6 +15,36 @@ export const WORKLOAD_PRIORITY = {
|
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
export default class Pod extends WorkloadService {
|
|
18
|
+
_os = undefined;
|
|
19
|
+
|
|
20
|
+
get inStore() {
|
|
21
|
+
return this.$rootGetters['currentProduct'].inStore;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
set os(operatingSystem) {
|
|
25
|
+
this._os = operatingSystem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get os() {
|
|
29
|
+
if (this._os) {
|
|
30
|
+
return this._os;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return this?.node?.status?.nodeInfo?.operatingSystem;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get node() {
|
|
37
|
+
try {
|
|
38
|
+
const schema = this.$store.getters[`cluster/schemaFor`](NODE);
|
|
39
|
+
|
|
40
|
+
if (schema) {
|
|
41
|
+
this.$dispatch(`find`, { type: NODE, id: this.spec.nodeName });
|
|
42
|
+
}
|
|
43
|
+
} catch {}
|
|
44
|
+
|
|
45
|
+
return this.$getters['byId'](NODE, this.spec.nodeName);
|
|
46
|
+
}
|
|
47
|
+
|
|
18
48
|
get _availableActions() {
|
|
19
49
|
const out = super._availableActions;
|
|
20
50
|
|
|
@@ -5,17 +5,20 @@ import { findBy } from '@shell/utils/array';
|
|
|
5
5
|
import { get } from '@shell/utils/object';
|
|
6
6
|
import { base64Decode } from '@shell/utils/crypto';
|
|
7
7
|
import { ucFirst } from '@shell/utils/string';
|
|
8
|
+
import { STATES_ENUM } from '@shell/plugins/dashboard-store/resource-class';
|
|
8
9
|
|
|
9
10
|
export default class EtcdBackup extends NormanModel {
|
|
10
11
|
/**
|
|
11
12
|
* Restrict actions for snapshots to restore only
|
|
12
13
|
*/
|
|
13
14
|
get _availableActions() {
|
|
15
|
+
const enabled = this.snapshotFile?.status === STATES_ENUM.SUCCESSFUL;
|
|
16
|
+
|
|
14
17
|
return [{
|
|
15
|
-
action:
|
|
16
|
-
enabled
|
|
17
|
-
icon:
|
|
18
|
-
label:
|
|
18
|
+
action: 'promptRestore',
|
|
19
|
+
enabled,
|
|
20
|
+
icon: 'icon icon-fw icon-backup-restore',
|
|
21
|
+
label: 'Restore'
|
|
19
22
|
}];
|
|
20
23
|
}
|
|
21
24
|
|
|
@@ -48,7 +51,7 @@ export default class EtcdBackup extends NormanModel {
|
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
get errorMessage() {
|
|
51
|
-
const inError = get(this, 'snapshotFile.status') ===
|
|
54
|
+
const inError = get(this, 'snapshotFile.status') === STATES_ENUM.FAILED;
|
|
52
55
|
|
|
53
56
|
if (inError) {
|
|
54
57
|
return base64Decode(this.snapshotFile?.message);
|
|
@@ -59,10 +62,10 @@ export default class EtcdBackup extends NormanModel {
|
|
|
59
62
|
|
|
60
63
|
get stateDescription() {
|
|
61
64
|
const trans = this.stateObj?.transitioning || false;
|
|
62
|
-
const error = this.stateObj?.error || this.snapshotFile?.status ===
|
|
65
|
+
const error = this.stateObj?.error || this.snapshotFile?.status === STATES_ENUM.FAILED || false;
|
|
63
66
|
const message = this.stateObj?.message;
|
|
64
67
|
|
|
65
|
-
const fileMessage = this.snapshotFile?.status ===
|
|
68
|
+
const fileMessage = this.snapshotFile?.status === STATES_ENUM.FAILED ? base64Decode(this.snapshotFile?.message) : null;
|
|
66
69
|
|
|
67
70
|
return trans || error ? fileMessage || ucFirst(message) : '';
|
|
68
71
|
}
|