@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.
Files changed (118) hide show
  1. package/assets/translations/en-us.yaml +8 -4
  2. package/assets/translations/zh-hans.yaml +64 -8
  3. package/components/AsyncButton.vue +1 -1
  4. package/components/Inactivity.vue +10 -0
  5. package/components/LazyImage.vue +2 -2
  6. package/components/PromptRestore.vue +8 -6
  7. package/components/ResourceDetail/Masthead.vue +1 -1
  8. package/components/ResourceDetail/index.vue +4 -2
  9. package/components/__tests__/PromptRestore.test.ts +142 -0
  10. package/components/auth/AzureWarning.vue +1 -1
  11. package/components/auth/RoleDetailEdit.vue +2 -0
  12. package/components/fleet/FleetResources.vue +3 -64
  13. package/components/form/FileImageSelector.vue +9 -0
  14. package/components/form/FileSelector.vue +2 -1
  15. package/components/form/MatchExpressions.vue +1 -3
  16. package/components/form/__tests__/FileImageSelector.test.ts +42 -0
  17. package/components/form/__tests__/FileSelector.test.ts +76 -0
  18. package/components/formatter/ClusterProvider.vue +3 -1
  19. package/components/formatter/__tests__/ClusterProvider.test.ts +24 -0
  20. package/components/nav/WindowManager/ContainerShell.vue +60 -36
  21. package/components/nav/WindowManager/__tests__/ContainerShell.test.ts +561 -0
  22. package/config/labels-annotations.js +2 -1
  23. package/config/persistentVolume.ts +108 -0
  24. package/config/product/manager.js +5 -1
  25. package/config/types.js +2 -0
  26. package/core/plugin-helpers.js +19 -3
  27. package/core/types.ts +4 -0
  28. package/detail/fleet.cattle.io.gitrepo.vue +10 -2
  29. package/detail/pod.vue +36 -3
  30. package/detail/workload/index.vue +40 -9
  31. package/dialog/DiagnosticTimingsDialog.vue +1 -0
  32. package/edit/__tests__/ui.cattle.io.navlink.test.ts +110 -0
  33. package/edit/fleet.cattle.io.clustergroup.vue +14 -3
  34. package/edit/persistentvolume/__tests__/persistentvolume.test.ts +82 -0
  35. package/edit/persistentvolume/index.vue +2 -1
  36. package/edit/persistentvolume/plugins/csi.vue +3 -1
  37. package/edit/persistentvolume/plugins/longhorn.vue +12 -12
  38. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +15 -11
  39. package/edit/provisioning.cattle.io.cluster/index.vue +1 -1
  40. package/edit/provisioning.cattle.io.cluster/rke2.vue +5 -1
  41. package/edit/storage.k8s.io.storageclass/index.vue +1 -2
  42. package/edit/ui.cattle.io.navlink.vue +213 -186
  43. package/layouts/default.vue +1 -1
  44. package/list/group.principal.vue +1 -1
  45. package/middleware/authenticated.js +12 -4
  46. package/mixins/create-edit-view/impl.js +2 -2
  47. package/models/chart.js +1 -1
  48. package/models/etcdbackup.js +2 -1
  49. package/models/fleet.cattle.io.cluster.js +33 -4
  50. package/models/fleet.cattle.io.gitrepo.js +112 -38
  51. package/models/management.cattle.io.cluster.js +13 -3
  52. package/models/management.cattle.io.kontainerdriver.js +14 -0
  53. package/models/persistentvolume.js +2 -111
  54. package/models/pod.js +30 -0
  55. package/models/rke.cattle.io.etcdsnapshot.js +10 -7
  56. package/package.json +1 -1
  57. package/pages/c/_cluster/apps/charts/install.vue +74 -25
  58. package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
  59. package/pages/c/_cluster/auth/roles/index.vue +1 -1
  60. package/pages/c/_cluster/explorer/index.vue +1 -1
  61. package/pages/c/_cluster/manager/cloudCredential/_id.vue +0 -1
  62. package/pages/c/_cluster/manager/cloudCredential/create.vue +0 -1
  63. package/pages/c/_cluster/settings/brand.vue +11 -8
  64. package/pages/c/_cluster/uiplugins/index.vue +9 -4
  65. package/pages/diagnostic.vue +5 -3
  66. package/pages/home.vue +1 -1
  67. package/plugins/dashboard-store/__tests__/actions.spec.ts +165 -0
  68. package/plugins/dashboard-store/__tests__/getters.spec.ts +100 -0
  69. package/plugins/dashboard-store/__tests__/{mutations.spec.js → mutations.spec.ts} +2 -2
  70. package/plugins/dashboard-store/actions.js +1 -1
  71. package/plugins/dashboard-store/resource-class.js +4 -0
  72. package/plugins/steve/__tests__/getters.spec.ts +93 -0
  73. package/plugins/steve/getters.js +21 -1
  74. package/plugins/steve/subscribe.js +1 -3
  75. package/rancher-components/components/BadgeState/BadgeState.spec.ts +12 -0
  76. package/rancher-components/components/BadgeState/BadgeState.vue +111 -0
  77. package/rancher-components/components/BadgeState/index.ts +1 -0
  78. package/rancher-components/components/Banner/Banner.test.ts +63 -0
  79. package/rancher-components/components/Banner/Banner.vue +244 -0
  80. package/rancher-components/components/Banner/index.ts +1 -0
  81. package/rancher-components/components/Card/Card.test.ts +37 -0
  82. package/rancher-components/components/Card/Card.vue +167 -0
  83. package/rancher-components/components/Card/index.ts +1 -0
  84. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +68 -0
  85. package/rancher-components/components/Form/Checkbox/Checkbox.vue +420 -0
  86. package/rancher-components/components/Form/Checkbox/index.ts +1 -0
  87. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +23 -0
  88. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +355 -0
  89. package/rancher-components/components/Form/LabeledInput/index.ts +1 -0
  90. package/rancher-components/components/Form/Radio/RadioButton.test.ts +31 -0
  91. package/rancher-components/components/Form/Radio/RadioButton.vue +287 -0
  92. package/rancher-components/components/Form/Radio/RadioGroup.vue +254 -0
  93. package/rancher-components/components/Form/Radio/index.ts +2 -0
  94. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +170 -0
  95. package/rancher-components/components/Form/TextArea/index.ts +1 -0
  96. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +94 -0
  97. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +149 -0
  98. package/rancher-components/components/Form/ToggleSwitch/index.ts +1 -0
  99. package/rancher-components/components/Form/index.ts +5 -0
  100. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +151 -0
  101. package/rancher-components/components/LabeledTooltip/index.ts +1 -0
  102. package/rancher-components/components/StringList/StringList.test.ts +484 -0
  103. package/rancher-components/components/StringList/StringList.vue +611 -0
  104. package/rancher-components/components/StringList/index.ts +1 -0
  105. package/scripts/extension/publish +54 -14
  106. package/scripts/typegen.sh +10 -2
  107. package/store/index.js +1 -3
  108. package/store/store-types.js +2 -0
  109. package/types/api.d.ts +1 -0
  110. package/types/fleet.d.ts +1 -0
  111. package/types/shell/index.d.ts +696 -2
  112. package/types/userPreferences.d.ts +1 -1
  113. package/utils/__mocks__/socket.js +21 -0
  114. package/utils/grafana.js +23 -11
  115. package/utils/selector.js +2 -1
  116. package/utils/socket.js +1 -0
  117. package/utils/validators/formRules/index.ts +3 -3
  118. 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 ( str.match(/^[a-f0-9]{40,}$/i) ) {
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 ( !spec.branch && !spec.revision ) {
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 ( this.spec?.paused === true ) {
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 ( workspace?.id === 'fleet-local' ) {
103
+ if (workspace?.id === 'fleet-local') {
102
104
  const local = findBy(groups, 'id', 'fleet-local/default');
103
105
 
104
- if ( local ) {
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 ( const tgt of this.spec.targets ) {
118
- if ( tgt.clusterName ) {
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 ( cluster ) {
123
+ if (cluster) {
122
124
  addObject(out, cluster);
123
125
  }
124
- } else if ( tgt.clusterGroup ) {
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 ( group ) {
132
+ if (group) {
131
133
  addObjects(out, group.targetClusters);
132
134
  }
133
- } else if ( tgt.clusterGroupSelector ) {
135
+ } else if (tgt.clusterGroupSelector) {
134
136
  const expressions = convertSelectorObj(tgt.clusterGroupSelector);
135
137
  const matchingGroups = matching(groups, expressions);
136
138
 
137
- for ( const group of matchingGroups ) {
139
+ for (const group of matchingGroups) {
138
140
  addObjects(out, group.targetClusters);
139
141
  }
140
- } else if ( tgt.clusterSelector ) {
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 ( match ) {
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 ( this.github ) {
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 ( this.github ) {
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 ( !spec || !spec.repo ) {
189
+ if (!spec || !spec.repo) {
188
190
  return null;
189
191
  }
190
192
 
191
- if ( spec.revision && quacksLikeAHash(spec.revision) ) {
193
+ if (spec.revision && quacksLikeAHash(spec.revision)) {
192
194
  return spec.revision.substr(0, 7);
193
- } else if ( spec.revision ) {
195
+ } else if (spec.revision) {
194
196
  return spec.revision;
195
- } else if ( spec.branch ) {
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 ( advanced === '[]\n' ) {
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 ( this.metadata.namespace === 'fleet-local' ) {
245
+ if (this.metadata.namespace === 'fleet-local') {
244
246
  mode = 'local';
245
- } else if ( !targets.length ) {
247
+ } else if (!targets.length) {
246
248
  mode = 'none';
247
- } else if ( targets.length === 1) {
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 ( target.clusterGroup ) {
256
+ } else if (target.clusterGroup) {
255
257
  clusterGroup = target.clusterGroup;
256
258
 
257
- if ( !mode ) {
259
+ if (!mode) {
258
260
  mode = 'clusterGroup';
259
261
  }
260
- } else if ( target.clusterName ) {
262
+ } else if (target.clusterName) {
261
263
  mode = 'cluster';
262
264
  cluster = target.clusterName;
263
- } else if ( target.clusterSelector ) {
264
- if ( Object.keys(target.clusterSelector).length === 0 ) {
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 ( expressions.length === 1 &&
270
- expressions[0].key === FLEET_ANNOTATIONS.CLUSTER_NAME &&
271
- expressions[0].operator === 'In' &&
272
- expressions[0].values.length === 1
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 ( !mode ) {
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 ( !mode ) {
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 ( name ) {
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.name.startsWith(`${ this.name }-`) &&
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 from = `${ verb }Type`;
444
- const id = `${ verb }Id`;
450
+ const res = findRelationship(verb, CAPI.RANCHER_CLUSTER, this.metadata?.relationships);
451
+
452
+ if (res) {
453
+ return res;
454
+ }
445
455
 
446
- return this.metadata.relationships.find((r) => r[from] === CAPI.RANCHER_CLUSTER)?.[id];
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: 'promptRestore',
16
- enabled: true,
17
- icon: 'icon icon-fw icon-backup-restore',
18
- label: 'Restore'
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') === 'failed';
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 === 'failed' || false;
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 === 'failed' ? base64Decode(this.snapshotFile?.message) : null;
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rancher/shell",
3
- "version": "0.3.17",
3
+ "version": "0.3.19",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",