@rancher/shell 0.3.28 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/.DS_Store +0 -0
  2. package/assets/translations/en-us.yaml +16 -2
  3. package/assets/translations/zh-hans.yaml +1 -1
  4. package/chart/monitoring/grafana/index.vue +2 -2
  5. package/components/AsyncButton.vue +9 -0
  6. package/components/CopyCode.vue +6 -2
  7. package/components/CopyToClipboard.vue +2 -1
  8. package/components/CopyToClipboardText.vue +14 -9
  9. package/components/EtcdInfoBanner.vue +4 -4
  10. package/components/Markdown.vue +16 -12
  11. package/components/ResourceDetail/Masthead.vue +9 -6
  12. package/components/SortableTable/THead.vue +7 -9
  13. package/components/SortableTable/index.vue +1 -2
  14. package/components/StatusTable.vue +5 -1
  15. package/components/__tests__/CopyCode.test.ts +5 -4
  16. package/components/fleet/FleetBundles.vue +5 -11
  17. package/components/fleet/FleetStatus.vue +3 -3
  18. package/components/fleet/FleetSummary.vue +35 -30
  19. package/components/fleet/__tests__/FleetSummary.test.ts +316 -0
  20. package/components/form/Password.vue +3 -1
  21. package/components/nav/Header.vue +1 -1
  22. package/config/home-links.js +1 -1
  23. package/core/plugin-helpers.js +3 -5
  24. package/creators/app/files/.gitlab-ci.yml +14 -0
  25. package/creators/app/init +19 -0
  26. package/detail/provisioning.cattle.io.cluster.vue +2 -1
  27. package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +12 -3
  28. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +2 -1
  29. package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.tests.ts +3 -1
  30. package/edit/workload/Upgrading.vue +3 -2
  31. package/edit/workload/index.vue +2 -1
  32. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +2 -1
  33. package/initialize/index.js +24 -5
  34. package/machine-config/__tests__/vmwarevsphere.test.ts +72 -0
  35. package/machine-config/vmwarevsphere.vue +68 -13
  36. package/models/__tests__/management.cattle.io.cluster.test.ts +4 -0
  37. package/models/management.cattle.io.cluster.js +7 -3
  38. package/models/provisioning.cattle.io.cluster.js +19 -1
  39. package/package.json +3 -2
  40. package/pages/c/_cluster/apps/charts/index.vue +64 -43
  41. package/plugins/clean-html-directive.js +1 -19
  42. package/plugins/clean-html.js +53 -0
  43. package/plugins/clean-tooltip-directive.js +1 -1
  44. package/plugins/index.js +11 -0
  45. package/rancher-components/BadgeState/BadgeState.vue +5 -1
  46. package/rancher-components/Banner/Banner.test.ts +51 -1
  47. package/rancher-components/Banner/Banner.vue +134 -53
  48. package/rancher-components/Card/Card.test.ts +37 -0
  49. package/rancher-components/Card/Card.vue +24 -7
  50. package/rancher-components/Form/Checkbox/Checkbox.test.ts +20 -29
  51. package/rancher-components/Form/Checkbox/Checkbox.vue +45 -20
  52. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +2 -8
  53. package/rancher-components/Form/LabeledInput/LabeledInput.vue +22 -10
  54. package/rancher-components/Form/Radio/RadioButton.test.ts +31 -0
  55. package/rancher-components/Form/Radio/RadioButton.vue +30 -13
  56. package/rancher-components/Form/Radio/RadioGroup.vue +26 -7
  57. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -6
  58. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +25 -38
  59. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +23 -11
  60. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +19 -5
  61. package/rancher-components/StringList/StringList.test.ts +453 -49
  62. package/rancher-components/StringList/StringList.vue +92 -58
  63. package/scripts/.DS_Store +0 -0
  64. package/scripts/extension/bundle +19 -7
  65. package/scripts/extension/helm/scripts/package +11 -3
  66. package/scripts/extension/publish +20 -9
  67. package/scripts/verdaccio.log +205 -0
  68. package/store/index.js +3 -4
  69. package/types/shell/index.d.ts +15 -9
  70. package/utils/clipboard.js +5 -0
  71. package/yarn-error.log +200 -0
  72. package/plugins/vue-clipboard2.js +0 -4
@@ -0,0 +1,316 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import FleetSummary from '@shell/components/fleet/FleetSummary.vue';
3
+
4
+ const REPO_NAME = 'testrepo';
5
+
6
+ const REPO_NAME_VARIANT = 'testrepo-again';
7
+
8
+ const CLUSTER_NAME = 'testcluster';
9
+
10
+ const mockedBundlesInRepo = [{
11
+ id: `fleet-default/${ REPO_NAME }-${ CLUSTER_NAME }-1234`,
12
+ type: 'fleet.cattle.io.bundle',
13
+ apiVersion: 'fleet.cattle.io/v1alpha1',
14
+ kind: 'Bundle',
15
+ repoName: REPO_NAME,
16
+ metadata: {
17
+ labels: {
18
+ 'fleet.cattle.io/commit': '3640888439d1b7b6a53dbeee291a533eea2632ab',
19
+ 'fleet.cattle.io/repo-name': REPO_NAME
20
+ },
21
+
22
+ name: `${ REPO_NAME }-${ CLUSTER_NAME }-1234`,
23
+ namespace: 'fleet-default',
24
+ state: {
25
+ error: false,
26
+ message: 'Resource is Ready',
27
+ name: 'active',
28
+ transitioning: false
29
+ },
30
+ },
31
+ spec: {
32
+ correctDrift: { },
33
+ forceSyncGeneration: 2,
34
+ ignore: { },
35
+ namespace: 'custom-namespace-name',
36
+ resources: [
37
+ {
38
+ content: 'apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: configmap-test\n annotations:\n {}\n# key: string\n labels:\n {}\n# key: string\ndata:\n key1: val1\n key2: val2\n key3: val3',
39
+ name: 'test-configmap.yaml'
40
+ }
41
+ ],
42
+ targets: [
43
+ {
44
+ clusterName: 'nb-cluster0-28',
45
+ namespace: 'custom-namespace-name'
46
+ }
47
+ ]
48
+ }
49
+ },
50
+ {
51
+ id: `fleet-default/${ REPO_NAME }-${ CLUSTER_NAME }-5678`,
52
+ type: 'fleet.cattle.io.bundle',
53
+ apiVersion: 'fleet.cattle.io/v1alpha1',
54
+ kind: 'Bundle',
55
+ repoName: REPO_NAME,
56
+ metadata: {
57
+ labels: {
58
+ 'fleet.cattle.io/commit': '3640888439d1b7b6a53dbeee291a533eea2632ab',
59
+ 'fleet.cattle.io/repo-name': REPO_NAME
60
+ },
61
+
62
+ name: `${ REPO_NAME }-${ CLUSTER_NAME }-5678`,
63
+ namespace: 'fleet-default',
64
+ state: {
65
+ error: false,
66
+ message: 'Resource is Ready',
67
+ name: 'active',
68
+ transitioning: false
69
+ },
70
+ },
71
+ spec: {
72
+ correctDrift: { },
73
+ forceSyncGeneration: 2,
74
+ ignore: { },
75
+ namespace: 'custom-namespace-name',
76
+ resources: [
77
+ {
78
+ content: 'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: nginx-cluster0\n labels:\n app: nginx\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: nginx\n template:\n metadata:\n labels:\n app: nginx\n spec:\n containers:\n - name: nginx\n image: nginx:latest\n ports:\n - containerPort: 80',
79
+ name: 'nginx.yml'
80
+ },
81
+ ],
82
+ targets: [
83
+ {
84
+ clusterName: 'nb-cluster0-28',
85
+ namespace: 'custom-namespace-name'
86
+ }
87
+ ]
88
+ }
89
+ }];
90
+
91
+ const mockedBundlesOutOfRepo = [{
92
+ id: `fleet-default/${ REPO_NAME_VARIANT }-${ CLUSTER_NAME }-1234`,
93
+ type: 'fleet.cattle.io.bundle',
94
+ apiVersion: 'fleet.cattle.io/v1alpha1',
95
+ kind: 'Bundle',
96
+ repoName: REPO_NAME_VARIANT,
97
+ metadata: {
98
+ labels: {
99
+ 'fleet.cattle.io/commit': '3640888439d1b7b6a53dbeee291a533eea2632ab',
100
+ 'fleet.cattle.io/repo-name': REPO_NAME_VARIANT
101
+ },
102
+
103
+ name: `${ REPO_NAME_VARIANT }-${ CLUSTER_NAME }-1234`,
104
+ namespace: 'fleet-default',
105
+ state: {
106
+ error: false,
107
+ message: 'Resource is Ready',
108
+ name: 'active',
109
+ transitioning: false
110
+ },
111
+ },
112
+ spec: {
113
+ correctDrift: { },
114
+ forceSyncGeneration: 2,
115
+ ignore: { },
116
+ namespace: 'custom-namespace-name',
117
+ resources: [
118
+ {
119
+ content: 'apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: configmap-test\n annotations:\n {}\n# key: string\n labels:\n {}\n# key: string\ndata:\n key1: val1\n key2: val2\n key3: val3',
120
+ name: 'test-configmap.yaml'
121
+ }
122
+ ],
123
+ targets: [
124
+ {
125
+ clusterName: 'nb-cluster0-28',
126
+ namespace: 'custom-namespace-name'
127
+ }
128
+ ]
129
+ }
130
+ },
131
+ {
132
+ id: `fleet-default/${ REPO_NAME_VARIANT }-${ CLUSTER_NAME }-5678`,
133
+ type: 'fleet.cattle.io.bundle',
134
+ apiVersion: 'fleet.cattle.io/v1alpha1',
135
+ kind: 'Bundle',
136
+ repoName: REPO_NAME_VARIANT,
137
+ metadata: {
138
+ labels: {
139
+ 'fleet.cattle.io/commit': '3640888439d1b7b6a53dbeee291a533eea2632ab',
140
+ 'fleet.cattle.io/repo-name': REPO_NAME_VARIANT
141
+ },
142
+
143
+ name: `${ REPO_NAME_VARIANT }-${ CLUSTER_NAME }-5678`,
144
+ namespace: 'fleet-default',
145
+ state: {
146
+ error: false,
147
+ message: 'Resource is Ready',
148
+ name: 'active',
149
+ transitioning: false
150
+ },
151
+ },
152
+ spec: {
153
+ correctDrift: { },
154
+ forceSyncGeneration: 2,
155
+ ignore: { },
156
+ namespace: 'custom-namespace-name',
157
+ resources: [
158
+ {
159
+ content: 'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: nginx-cluster0\n labels:\n app: nginx\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: nginx\n template:\n metadata:\n labels:\n app: nginx\n spec:\n containers:\n - name: nginx\n image: nginx:latest\n ports:\n - containerPort: 80',
160
+ name: 'nginx.yml'
161
+ },
162
+ ],
163
+ targets: [
164
+ {
165
+ clusterName: 'nb-cluster0-28',
166
+ namespace: 'custom-namespace-name'
167
+ }
168
+ ]
169
+ }
170
+ }];
171
+
172
+ const mockRepo = {
173
+ id: `fleet-default/${ REPO_NAME }`,
174
+ type: 'fleet.cattle.io.gitrepo',
175
+ apiVersion: 'fleet.cattle.io/v1alpha1',
176
+ kind: 'GitRepo',
177
+ metadata: {
178
+
179
+ name: `${ REPO_NAME }`,
180
+ namespace: 'fleet-default',
181
+ state: {
182
+ error: false,
183
+ message: 'Resource is Ready',
184
+ name: 'active',
185
+ transitioning: false
186
+ },
187
+ },
188
+ spec: {
189
+ branch: 'main',
190
+ correctDrift: { enabled: false },
191
+ forceSyncGeneration: 2,
192
+ insecureSkipTLSVerify: false,
193
+ paths: [
194
+ './cluster0'
195
+ ],
196
+ repo: 'https://github.com/testuser/testrepo.git',
197
+ targetNamespace: 'custom-namespace-name',
198
+ targets: [
199
+ { clusterName: `${ CLUSTER_NAME }` }
200
+ ]
201
+ },
202
+ status: {
203
+ commit: '3640888439d1b7b6a53dbeee291a533eea2632ab',
204
+ conditions: [
205
+ {
206
+ error: false,
207
+ lastUpdateTime: '2023-10-05T18:06:27Z',
208
+ status: 'True',
209
+ transitioning: false,
210
+ type: 'Ready'
211
+ },
212
+ {
213
+ error: false,
214
+ lastUpdateTime: '2023-10-05T20:35:07Z',
215
+ status: 'True',
216
+ transitioning: false,
217
+ type: 'Accepted'
218
+ },
219
+ {
220
+ error: false,
221
+ lastUpdateTime: '2023-10-05T18:05:09Z',
222
+ status: 'True',
223
+ transitioning: false,
224
+ type: 'ImageSynced'
225
+ },
226
+ {
227
+ error: false,
228
+ lastUpdateTime: '2023-10-05T18:06:22Z',
229
+ status: 'False',
230
+ transitioning: false,
231
+ type: 'Reconciling'
232
+ },
233
+ {
234
+ error: false,
235
+ lastUpdateTime: '2023-10-05T18:05:09Z',
236
+ status: 'False',
237
+ transitioning: false,
238
+ type: 'Stalled'
239
+ },
240
+ {
241
+ error: false,
242
+ lastUpdateTime: '2023-10-05T20:35:07Z',
243
+ status: 'True',
244
+ transitioning: false,
245
+ type: 'Synced'
246
+ }
247
+ ],
248
+ desiredReadyClusters: 1,
249
+ display: { readyBundleDeployments: '2/2' },
250
+ gitJobStatus: 'Current',
251
+ lastSyncedImageScanTime: null,
252
+ observedGeneration: 2,
253
+ readyClusters: 1,
254
+ resourceCounts: {
255
+ desiredReady: 2,
256
+ missing: 0,
257
+ modified: 0,
258
+ notReady: 0,
259
+ orphaned: 0,
260
+ ready: 2,
261
+ unknown: 0,
262
+ waitApplied: 0
263
+ },
264
+ resources: [
265
+ {
266
+ apiVersion: 'apps/v1',
267
+ id: 'custom-namespace-name/nginx-cluster0',
268
+ kind: 'Deployment',
269
+ name: 'nginx-cluster0',
270
+ namespace: 'custom-namespace-name',
271
+ state: 'Ready',
272
+ type: 'apps.deployment'
273
+ },
274
+ {
275
+ apiVersion: 'v1',
276
+ id: 'custom-namespace-name/configmap-test',
277
+ kind: 'ConfigMap',
278
+ name: 'configmap-test',
279
+ namespace: 'custom-namespace-name',
280
+ state: 'Ready',
281
+ type: 'configmap'
282
+ }
283
+ ],
284
+ summary: {
285
+ desiredReady: 1,
286
+ ready: 1
287
+ }
288
+ }
289
+ };
290
+
291
+ const mockStore = { getters: { 'i18n/withFallback': (key, opt, fallback) => fallback } };
292
+
293
+ describe('component: FleetSummary', () => {
294
+ it.each([
295
+ [[...mockedBundlesInRepo, ...mockedBundlesOutOfRepo], '2'],
296
+ [mockedBundlesInRepo, '2'],
297
+ ])('displays the number of bundles associated with the current gitrepo', (bundles: any[], bundleCount: string) => {
298
+ const wrapper = mount(FleetSummary, { propsData: { bundles, value: mockRepo }, mocks: { $store: mockStore } });
299
+
300
+ const bundleCountEl = wrapper.find('[data-testid="gitrepo-bundle-summary"] .count');
301
+
302
+ expect(bundleCountEl.text()).toBe(bundleCount);
303
+ });
304
+
305
+ it.each([
306
+ [[...mockedBundlesInRepo, ...mockedBundlesOutOfRepo], '2'],
307
+ [mockedBundlesInRepo, '2'],
308
+
309
+ ])('displays the number of deployments associated with the current gitrepo', (bundles: any[], bundleCount: string) => {
310
+ const wrapper = mount(FleetSummary, { propsData: { bundles, value: mockRepo }, mocks: { $store: mockStore } });
311
+
312
+ const bundleCountEl = wrapper.find('[data-testid="gitrepo-deployment-summary"] .count');
313
+
314
+ expect(bundleCountEl.text()).toBe(bundleCount);
315
+ });
316
+ });
@@ -2,6 +2,7 @@
2
2
  import { mapGetters } from 'vuex';
3
3
  import { LabeledInput } from '@components/Form/LabeledInput';
4
4
  import { CHARSET, randomStr } from '@shell/utils/string';
5
+ import { copyTextToClipboard } from '@shell/utils/clipboard';
5
6
 
6
7
  export default {
7
8
  components: { LabeledInput },
@@ -75,6 +76,7 @@ export default {
75
76
  }
76
77
  },
77
78
  methods: {
79
+ copyTextToClipboard,
78
80
  generatePassword() {
79
81
  this.password = randomStr(16, CHARSET.ALPHA_NUM);
80
82
  },
@@ -109,7 +111,7 @@ export default {
109
111
  >
110
112
  <a
111
113
  href="#"
112
- @click.prevent.stop="$copyText(password)"
114
+ @click.prevent.stop="copyTextToClipboard(password)"
113
115
  >{{ t('action.copy') }}</a>
114
116
  </div>
115
117
  <div
@@ -311,7 +311,7 @@ export default {
311
311
  product: this.currentProduct.name,
312
312
  cluster: this.currentCluster,
313
313
  };
314
- const enabled = action.enabled ? action.enabled.apply(this, [opts]) : true;
314
+ const enabled = action.enabled ? action.enabled.apply(this, [this.ctx]) : true;
315
315
 
316
316
  if (fn && enabled) {
317
317
  fn.apply(this, [opts, [], { $route: this.$route }]);
@@ -26,7 +26,7 @@ const DEFAULT_LINKS = [
26
26
  },
27
27
  {
28
28
  key: 'getStarted',
29
- value: 'https://ranchermanager.docs.rancher.com/getting-started/overview',
29
+ value: `${ DOCS_BASE }/getting-started/overview`,
30
30
  enabled: true,
31
31
  },
32
32
  ];
@@ -7,13 +7,11 @@ import {
7
7
  import { getProductFromRoute } from '@shell/middleware/authenticated';
8
8
  import { isEqual } from '@shell/utils/object';
9
9
 
10
- function checkRouteProduct({ name, params, query }, locationConfigParam) {
11
- const product = getProductFromRoute({
12
- name, params, query
13
- });
10
+ function checkRouteProduct($route, locationConfigParam) {
11
+ const product = getProductFromRoute($route);
14
12
 
15
13
  // alias for the homepage
16
- if (locationConfigParam === 'home' && name === 'home') {
14
+ if (locationConfigParam === 'home' && $route.name === 'home') {
17
15
  return true;
18
16
  } else if (locationConfigParam === product) {
19
17
  return true;
@@ -0,0 +1,14 @@
1
+ image: registry.suse.com/bci/bci-base:latest
2
+
3
+ stages:
4
+ - check_version
5
+ - build_catalog
6
+
7
+ variables:
8
+ REGISTRY: $CI_REGISTRY
9
+ REGISTRY_USER: $CI_REGISTRY_USER
10
+ REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD
11
+ IMAGE_NAMESPACE: $CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
12
+
13
+ include:
14
+ - remote: 'https://raw.githubusercontent.com/rancher/dashboard/master/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml'
package/creators/app/init CHANGED
@@ -34,6 +34,25 @@ if (args.length === 3) {
34
34
  fs.ensureDirSync(appFolder);
35
35
  }
36
36
 
37
+ let addGitlabWorkflow = false;
38
+
39
+ // Check for Gitlab integration option
40
+ if ( args.length > 3 ) {
41
+ for (let i = 3; i < args.length; i++) {
42
+ switch (args[i]) {
43
+ case '-l':
44
+ addGitlabWorkflow = true;
45
+ break;
46
+ default:
47
+ break;
48
+ }
49
+ }
50
+ }
51
+
52
+ if ( addGitlabWorkflow ) {
53
+ files.push('.gitlab-ci.yml');
54
+ }
55
+
37
56
  // Check that there is a package file
38
57
 
39
58
  let setName = false;
@@ -782,10 +782,11 @@ export default {
782
782
  </div>
783
783
  </div>
784
784
  <div
785
- v-if="group.ref && poolSummaryInfo[group.ref]"
785
+ v-if="group.ref"
786
786
  class="right group-header-buttons mr-20"
787
787
  >
788
788
  <MachineSummaryGraph
789
+ v-if="poolSummaryInfo[group.ref]"
789
790
  :row="poolSummaryInfo[group.ref]"
790
791
  :horizontal="true"
791
792
  class="mr-20"
@@ -47,9 +47,18 @@ export default {
47
47
  selectedSeverityLabel: null,
48
48
  ignoredAnnotations: IGNORED_ANNOTATIONS,
49
49
  severityOptions: [
50
- this.t('prometheusRule.alertingRules.labels.severity.choices.critical'),
51
- this.t('prometheusRule.alertingRules.labels.severity.choices.warning'),
52
- this.t('prometheusRule.alertingRules.labels.severity.choices.none'),
50
+ {
51
+ label: this.t('prometheusRule.alertingRules.labels.severity.choices.critical'),
52
+ value: 'critical'
53
+ },
54
+ {
55
+ label: this.t('prometheusRule.alertingRules.labels.severity.choices.warning'),
56
+ value: 'warning'
57
+ },
58
+ {
59
+ label: this.t('prometheusRule.alertingRules.labels.severity.choices.none'),
60
+ value: 'none'
61
+ },
53
62
  ],
54
63
  };
55
64
  },
@@ -6,6 +6,7 @@ import { _VIEW } from '@shell/config/query-params';
6
6
  import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
7
7
  import AlertingRule from './AlertingRule';
8
8
  import RecordingRule from './RecordingRule';
9
+ import { clone } from '@shell/utils/object';
9
10
 
10
11
  export default {
11
12
  components: {
@@ -105,7 +106,7 @@ export default {
105
106
  });
106
107
  break;
107
108
  case 'alert':
108
- value.push(this.defaultAlert);
109
+ value.push(clone(this.defaultAlert));
109
110
  break;
110
111
  default:
111
112
  break;
@@ -1,6 +1,8 @@
1
1
  import { mount } from '@vue/test-utils';
2
2
  import CustomCommand from '@shell/edit/provisioning.cattle.io.cluster/CustomCommand.vue';
3
-
3
+ jest.mock('@shell/utils/clipboard', () => {
4
+ return { copyTextToClipboard: jest.fn(() => Promise.resolve({})) };
5
+ });
4
6
  describe('component: CustomCommand', () => {
5
7
  const token = 'MY_TOKEN';
6
8
  const ip = 'MY_IP';
@@ -40,12 +40,13 @@ export default {
40
40
  data() {
41
41
  const {
42
42
  strategy:strategyObj = {},
43
+ updateStrategy: updateStrategyObj = {},
43
44
  minReadySeconds = 0,
44
45
  progressDeadlineSeconds = 600,
45
46
  revisionHistoryLimit = 10,
46
47
  podManagementPolicy = 'OrderedReady'
47
48
  } = this.value;
48
- const strategy = strategyObj.type || 'RollingUpdate';
49
+ const strategy = strategyObj.type || updateStrategyObj.type || 'RollingUpdate';
49
50
  let maxSurge = '25';
50
51
  let maxUnavailable = '25';
51
52
  let surgeUnits = '%';
@@ -97,7 +98,7 @@ export default {
97
98
  case WORKLOAD_TYPES.DAEMON_SET:
98
99
  case WORKLOAD_TYPES.STATEFUL_SET:
99
100
  return {
100
- options: ['RollingUpdate', 'Delete'],
101
+ options: ['RollingUpdate', 'OnDelete'],
101
102
  labels: [this.t('workload.upgrading.strategies.labels.rollingUpdate'), this.t('workload.upgrading.strategies.labels.delete')]
102
103
  };
103
104
  default:
@@ -235,7 +235,7 @@ export default {
235
235
  <div class="col span-6">
236
236
  <LabeledSelect
237
237
  v-model="imagePullSecrets"
238
- :label="t('workload.container.imagePullSecrets')"
238
+ :label="t('workload.container.imagePullSecrets.label')"
239
239
  :multiple="true"
240
240
  :taggable="true"
241
241
  :options="imagePullNamespacedSecrets"
@@ -243,6 +243,7 @@ export default {
243
243
  option-label="metadata.name"
244
244
  :reduce="service=>service.metadata.name"
245
245
  :create-option="createOption"
246
+ :tooltip="t('workload.container.imagePullSecrets.tooltip')"
246
247
  />
247
248
  </div>
248
249
  </div>
@@ -78,7 +78,8 @@ export default {
78
78
  * Required to initialize with default SC on creation
79
79
  */
80
80
  defaultStorageClassName() {
81
- return this.storageClasses.find((sc) => sc.metadata?.annotations?.['storageclass.beta.kubernetes.io/is-default-class'] || sc.metadata?.annotations?.['storageclass.kubernetes.io/is-default-class'])?.metadata.name;
81
+ return this.storageClasses.find((sc) => sc.metadata?.annotations?.['storageclass.beta.kubernetes.io/is-default-class'] === 'true' ||
82
+ sc.metadata?.annotations?.['storageclass.kubernetes.io/is-default-class'] === 'true')?.metadata.name ;
82
83
  },
83
84
 
84
85
  availablePVs() {
@@ -13,7 +13,7 @@ import { setContext, getLocation, getRouteData, normalizeError } from '../utils/
13
13
  import { createStore } from '../config/store.js';
14
14
 
15
15
  /* Plugins */
16
-
16
+ import { loadDirectives } from '@shell/plugins';
17
17
  import '../plugins/portal-vue.js';
18
18
  import cookieUniversalNuxt from '../utils/cookie-universal-nuxt.js';
19
19
  import axios from '../utils/axios.js';
@@ -21,11 +21,7 @@ import plugins from '../core/plugins.js';
21
21
  import pluginsLoader from '../core/plugins-loader.js';
22
22
  import axiosShell from '../plugins/axios';
23
23
  import '../plugins/tooltip';
24
- import '../plugins/clean-tooltip-directive';
25
- import '../plugins/vue-clipboard2';
26
24
  import '../plugins/v-select';
27
- import '../plugins/directives';
28
- import '../plugins/clean-html-directive';
29
25
  import '../plugins/transitions';
30
26
  import '../plugins/vue-js-modal';
31
27
  import '../plugins/js-yaml';
@@ -47,6 +43,29 @@ import '../plugins/formatters';
47
43
  import version from '../plugins/version';
48
44
  import steveCreateWorker from '../plugins/steve-create-worker';
49
45
 
46
+ // Prevent extensions from overriding existing directives
47
+ // Hook into Vue.directive and keep track of the directive names that have been added
48
+ // and prevent an existing directive from being overwritten
49
+ const directiveNames = {};
50
+ const vueDirective = Vue.directive;
51
+
52
+ Vue.directive = function(name) {
53
+ if (directiveNames[name]) {
54
+ console.log(`Can not override directive: ${ name }`); // eslint-disable-line no-console
55
+
56
+ return;
57
+ }
58
+
59
+ directiveNames[name] = true;
60
+
61
+ vueDirective.apply(Vue, arguments);
62
+ };
63
+
64
+ // Load the directives from the plugins - we do this with a function so we know
65
+ // these are initialized here, after the code above which keeps track of them and
66
+ // prevents over-writes
67
+ loadDirectives();
68
+
50
69
  // Component: <ClientOnly>
51
70
  Vue.component(ClientOnly.name, ClientOnly);
52
71
 
@@ -0,0 +1,72 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import vmwarevsphere, { DEFAULT_VALUES } from '@shell/machine-config/vmwarevsphere.vue';
3
+
4
+ describe('component: vmwarevsphere', () => {
5
+ it('should mount successfully with correct default values', () => {
6
+ const defaultGetters = { 'i18n/t': jest.fn() };
7
+ const wrapper = mount(vmwarevsphere, {
8
+ propsData: {
9
+ poolId: 'poolId',
10
+ credentialId: 'credentialId',
11
+ disabled: false,
12
+ mode: 'create',
13
+ value: {
14
+ initted: false,
15
+ network: [],
16
+ tag: []
17
+ },
18
+ provider: 'vmwarevsphere'
19
+ },
20
+ mocks: {
21
+ $fetchState: { pending: false },
22
+ $store: { getters: defaultGetters },
23
+ },
24
+ stubs: { CodeMirror: true }
25
+ });
26
+
27
+ const dataCenterElement = wrapper.find(`[data-testid="datacenter"]`).element;
28
+ const resourcePoolElement = wrapper.find(`[data-testid="resourcePool"]`).element;
29
+ const dataStoreElement = wrapper.find(`[data-testid="dataStore"]`).element;
30
+ const folderElement = wrapper.find(`[data-testid="folder"]`).element;
31
+ const hostElement = wrapper.find(`[data-testid="host"]`).element;
32
+ const gracefulShutdownTimeoutElement = wrapper.find(`[data-testid="gracefulShutdownTimeout"]`).element;
33
+
34
+ expect(dataCenterElement).toBeDefined();
35
+ expect(resourcePoolElement).toBeDefined();
36
+ expect(dataStoreElement).toBeDefined();
37
+ expect(folderElement).toBeDefined();
38
+ expect(hostElement).toBeDefined();
39
+ expect(gracefulShutdownTimeoutElement).toBeDefined();
40
+
41
+ const {
42
+ cpuCount: defaultCpuCount,
43
+ diskSize: defaultDiskSize,
44
+ memorySize: defaultMemorySize,
45
+ hostsystem: defaultHostsystem,
46
+ cloudConfig: defaultCloudConfig,
47
+ gracefulShutdownTimeout: defaultGracefulShutdownTimeout,
48
+ cfgparam: defaultCfgparam,
49
+ os: defaultOs
50
+ } = DEFAULT_VALUES;
51
+
52
+ const {
53
+ cpuCount,
54
+ diskSize,
55
+ memorySize,
56
+ hostsystem,
57
+ cloudConfig,
58
+ gracefulShutdownTimeout,
59
+ cfgparam,
60
+ os
61
+ } = wrapper.vm.$options.propsData.value;
62
+
63
+ expect(cpuCount).toStrictEqual(defaultCpuCount);
64
+ expect(diskSize).toStrictEqual(defaultDiskSize);
65
+ expect(memorySize).toStrictEqual(defaultMemorySize);
66
+ expect(hostsystem).toStrictEqual(defaultHostsystem);
67
+ expect(cloudConfig).toStrictEqual(defaultCloudConfig);
68
+ expect(gracefulShutdownTimeout).toStrictEqual(defaultGracefulShutdownTimeout);
69
+ expect(cfgparam).toStrictEqual(defaultCfgparam);
70
+ expect(os).toStrictEqual(defaultOs);
71
+ });
72
+ });