@rancher/shell 3.0.0 → 3.0.1-rc.2

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 (92) hide show
  1. package/assets/brand/harvester/favicon.png +0 -0
  2. package/assets/brand/harvester/metadata.json +3 -0
  3. package/assets/images/pl/harvester.svg +1 -0
  4. package/assets/translations/en-us.yaml +26 -8
  5. package/assets/translations/zh-hans.yaml +1 -1
  6. package/components/BrandImage.vue +5 -1
  7. package/components/CopyToClipboardText.vue +2 -0
  8. package/components/CruResourceFooter.vue +1 -0
  9. package/components/DetailTop.vue +1 -1
  10. package/components/ExplorerMembers.vue +5 -1
  11. package/components/ExplorerProjectsNamespaces.vue +39 -15
  12. package/components/HardwareResourceGauge.vue +12 -2
  13. package/components/InputOrDisplay.vue +6 -2
  14. package/components/LandingPagePreference.vue +2 -2
  15. package/components/MessageLink.vue +1 -1
  16. package/components/ResourceDetail/Masthead.vue +22 -1
  17. package/components/ResourceDetail/index.vue +2 -8
  18. package/components/ResourceTable.vue +14 -6
  19. package/components/ResourceYaml.vue +1 -1
  20. package/components/SideNav.vue +6 -4
  21. package/components/TableDataUserIcon.vue +1 -1
  22. package/components/fleet/FleetRepos.vue +0 -7
  23. package/components/form/ArrayList.vue +5 -1
  24. package/components/form/ArrayListSelect.vue +5 -1
  25. package/components/form/KeyValue.vue +1 -1
  26. package/components/form/LabeledSelect.vue +26 -6
  27. package/components/form/Password.vue +7 -1
  28. package/components/form/UnitInput.vue +10 -1
  29. package/components/form/__tests__/UnitInput.test.ts +1 -0
  30. package/components/formatter/ClusterProvider.vue +3 -3
  31. package/components/formatter/ImagePercentageBar.vue +1 -1
  32. package/components/formatter/Si.vue +5 -1
  33. package/components/formatter/Translate.vue +1 -1
  34. package/components/nav/Header.vue +29 -5
  35. package/components/nav/NamespaceFilter.vue +5 -8
  36. package/components/nav/TopLevelMenu.vue +16 -14
  37. package/config/labels-annotations.js +2 -0
  38. package/config/table-headers.js +15 -0
  39. package/config/types.js +3 -0
  40. package/detail/fleet.cattle.io.bundle.vue +5 -68
  41. package/detail/fleet.cattle.io.gitrepo.vue +2 -1
  42. package/directives/clean-tooltip.js +4 -4
  43. package/edit/constraints.gatekeeper.sh.constraint/index.vue +5 -2
  44. package/edit/logging-flow/Match.vue +75 -42
  45. package/edit/logging-flow/index.vue +89 -10
  46. package/edit/logging.banzaicloud.io.output/index.vue +2 -2
  47. package/edit/management.cattle.io.project.vue +2 -2
  48. package/edit/namespace.vue +1 -1
  49. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +17 -7
  50. package/edit/provisioning.cattle.io.cluster/index.vue +2 -1
  51. package/edit/provisioning.cattle.io.cluster/rke2.vue +1 -3
  52. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +20 -6
  53. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryMirrors.vue +1 -1
  54. package/list/harvesterhci.io.management.cluster.vue +244 -0
  55. package/list/namespace.vue +16 -4
  56. package/models/__tests__/management.cattle.io.cluster.test.ts +45 -3
  57. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +0 -86
  58. package/models/fleet.cattle.io.bundle.js +3 -1
  59. package/models/fleet.cattle.io.gitrepo.js +46 -48
  60. package/models/k8s.cni.cncf.io.networkattachmentdefinition.js +88 -0
  61. package/models/management.cattle.io.cluster.js +26 -5
  62. package/models/management.cattle.io.setting.js +25 -0
  63. package/models/provisioning.cattle.io.cluster.js +5 -14
  64. package/models/storage.k8s.io.storageclass.js +15 -4
  65. package/package.json +8 -6
  66. package/pages/auth/login.vue +8 -2
  67. package/pages/auth/setup.vue +1 -1
  68. package/pages/c/_cluster/fleet/index.vue +2 -4
  69. package/pages/c/_cluster/settings/brand.vue +4 -1
  70. package/pages/prefs.vue +22 -10
  71. package/plugins/dashboard-store/resource-class.js +11 -3
  72. package/plugins/steve/steve-pagination-utils.ts +1 -1
  73. package/rancher-components/Form/LabeledInput/LabeledInput.vue +7 -2
  74. package/scripts/extension/parse-tag-name +19 -12
  75. package/scripts/publish-shell.sh +10 -2
  76. package/scripts/test-plugins-build.sh +8 -9
  77. package/scripts/typegen.sh +2 -0
  78. package/store/features.js +1 -0
  79. package/store/i18n.js +5 -1
  80. package/store/prefs.js +8 -0
  81. package/types/resources/fleet.d.ts +40 -0
  82. package/types/shell/index.d.ts +524 -396
  83. package/utils/auth.js +1 -1
  84. package/utils/create-yaml.js +1 -1
  85. package/utils/favicon.js +2 -0
  86. package/utils/fleet.ts +159 -0
  87. package/utils/gc/gc.ts +1 -1
  88. package/utils/v-sphere.ts +31 -0
  89. package/utils/validators/cron-schedule.js +1 -1
  90. package/utils/validators/formRules/index.ts +1 -1
  91. package/utils/version.js +1 -1
  92. package/vue.config.js +2 -2
@@ -89,11 +89,31 @@ export default class MgmtCluster extends SteveModel {
89
89
  return pools.filter((x) => x.spec?.clusterName === this.id);
90
90
  }
91
91
 
92
- get provisioner() {
93
- if (this.status?.provider ) {
94
- return this.status.provider;
92
+ get isImported() {
93
+ if (this.isLocal) {
94
+ return false;
95
+ }
96
+ // imported rke2 and k3s have status.driver === rke2 and k3s respectively
97
+ // Provisioned rke2 and k3s have status.driver === imported
98
+ if (this.status?.provider === 'k3s' || this.status?.provider === 'rke2') {
99
+ return this.status?.driver === this.status?.provider;
100
+ }
101
+
102
+ // imported KEv2
103
+ const kontainerConfigs = ['aksConfig', 'eksConfig', 'gkeConfig'];
104
+
105
+ const isImportedKontainer = kontainerConfigs.filter((key) => {
106
+ return this.spec?.[key]?.imported === true;
107
+ }).length;
108
+
109
+ if (isImportedKontainer) {
110
+ return true;
95
111
  }
96
112
 
113
+ return this.provisioner === 'imported';
114
+ }
115
+
116
+ get provisioner() {
97
117
  // For imported K3s clusters, this.status.driver is 'k3s.'
98
118
  return this.status?.driver ? this.status.driver : 'imported';
99
119
  }
@@ -117,10 +137,11 @@ export default class MgmtCluster extends SteveModel {
117
137
  get providerForEmberParam() {
118
138
  // Ember wants one word called provider to tell what component to show, but has much indirect mapping to figure out what it is.
119
139
  let provider;
120
- // Provisioner is the "<something>Config" in the model
140
+
141
+ // provisioner is status.driver
121
142
  const provisioner = KONTAINER_TO_DRIVER[(this.provisioner || '').toLowerCase()] || this.provisioner;
122
143
 
123
- if ( provisioner === 'rancherKubernetesEngine' || provisioner === 'rke') {
144
+ if ( provisioner === 'rancherKubernetesEngine') {
124
145
  // Look for a cloud provider in one of the node templates
125
146
  if ( this.machinePools?.[0] ) {
126
147
  provider = this.machinePools[0]?.nodeTemplate?.spec?.driver || null;
@@ -1,6 +1,13 @@
1
1
  import { ALLOWED_SETTINGS } from '@shell/config/settings';
2
2
  import HybridModel from '@shell/plugins/steve/hybrid-class';
3
3
  import { isServerUrl } from '@shell/utils/validators/setting';
4
+ import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
5
+ import {
6
+ _EDIT,
7
+ _UNFLAG,
8
+ AS,
9
+ MODE
10
+ } from '@shell/config/query-params';
4
11
 
5
12
  export default class Setting extends HybridModel {
6
13
  get fromEnv() {
@@ -43,4 +50,22 @@ export default class Setting extends HybridModel {
43
50
 
44
51
  return out;
45
52
  }
53
+
54
+ goToEdit(moreQuery = {}) {
55
+ if (this.$rootGetters['currentProduct'].inStore === HARVESTER) {
56
+ location.name = `${ HARVESTER }-c-cluster-brand`;
57
+ location.params = { cluster: this.$rootGetters['currentCluster'].id, product: HARVESTER };
58
+
59
+ location.query = {
60
+ ...location.query,
61
+ [MODE]: _EDIT,
62
+ [AS]: _UNFLAG,
63
+ ...moreQuery
64
+ };
65
+
66
+ this.currentRouter().push(location);
67
+ } else {
68
+ super.goToEdit();
69
+ }
70
+ }
46
71
  }
@@ -282,19 +282,7 @@ export default class ProvCluster extends SteveModel {
282
282
  }
283
283
 
284
284
  get isImported() {
285
- // As of Rancher v2.6.7, this returns false for imported K3s clusters,
286
- // in which this.provisioner is `k3s`.
287
-
288
- const isImportedProvisioner = this.provisioner === 'imported';
289
- const isImportedSpecialCases = this.mgmt?.providerForEmberParam === 'import' ||
290
- // when imported cluster is GKE
291
- !!this.mgmt?.spec?.gkeConfig?.imported ||
292
- // or AKS
293
- !!this.mgmt?.spec?.aksConfig?.imported ||
294
- // or EKS
295
- !!this.mgmt?.spec?.eksConfig?.imported;
296
-
297
- return !this.isLocal && (isImportedProvisioner || (!this.isRke2 && !this.mgmt?.machineProvider && isImportedSpecialCases));
285
+ return this.mgmt?.isImported;
298
286
  }
299
287
 
300
288
  get isCustom() {
@@ -330,7 +318,8 @@ export default class ProvCluster extends SteveModel {
330
318
  }
331
319
 
332
320
  get isRke1() {
333
- return !!this.mgmt?.spec?.rancherKubernetesEngineConfig || this.labels['provider.cattle.io'] === 'rke';
321
+ // rancherKubernetesEngineConfig is not defined on imported RKE1 clusters
322
+ return !!this.mgmt?.spec?.rancherKubernetesEngineConfig || this.mgmt?.labels['provider.cattle.io'] === 'rke';
334
323
  }
335
324
 
336
325
  get isHarvester() {
@@ -407,6 +396,8 @@ export default class ProvCluster extends SteveModel {
407
396
  provisioner = 'k3s';
408
397
  } else if ( this.isImportedRke2 ) {
409
398
  provisioner = 'rke2';
399
+ } else if ((this.isImported || this.isLocal) && this.isRke1) {
400
+ provisioner = 'rke';
410
401
  }
411
402
 
412
403
  return this.$rootGetters['i18n/withFallback'](`cluster.provider."${ provisioner }"`, null, ucFirst(provisioner));
@@ -112,16 +112,21 @@ export default class extends SteveModel {
112
112
  return this.patch(data, {}, true, true);
113
113
  }
114
114
 
115
- setDefault() {
116
- const allStorageClasses = this.$rootGetters['cluster/all'](STORAGE_CLASS) || [];
115
+ async setDefault() {
116
+ const inStore = this.$rootGetters['currentProduct'].inStore;
117
+ const allStorageClasses = this.$rootGetters[`${ inStore }/all`](STORAGE_CLASS) || [];
118
+
119
+ for (const storageClass of allStorageClasses) {
120
+ await storageClass.resetDefault();
121
+ }
117
122
 
118
123
  allStorageClasses.forEach((storageClass) => storageClass.resetDefault());
119
124
  this.updateDefault(true);
120
125
  }
121
126
 
122
- resetDefault() {
127
+ async resetDefault() {
123
128
  if (this.isDefault) {
124
- this.updateDefault(false);
129
+ await this.updateDefault(false);
125
130
  }
126
131
  }
127
132
 
@@ -146,4 +151,10 @@ export default class extends SteveModel {
146
151
 
147
152
  return out;
148
153
  }
154
+
155
+ cleanForNew() {
156
+ this.$dispatch(`cleanForNew`, this);
157
+
158
+ delete this?.metadata?.annotations?.[STORAGE.DEFAULT_STORAGE_CLASS];
159
+ }
149
160
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rancher/shell",
3
- "version": "3.0.0",
3
+ "version": "3.0.1-rc.2",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",
@@ -36,7 +36,6 @@
36
36
  "@babel/plugin-proposal-private-property-in-object": "7.14.5",
37
37
  "@babel/preset-typescript": "7.16.7",
38
38
  "@novnc/novnc": "1.2.0",
39
- "@nuxtjs/axios": "5.13.6",
40
39
  "@popperjs/core": "2.4.4",
41
40
  "@rancher/icons": "2.0.29",
42
41
  "@types/is-url": "1.2.30",
@@ -51,6 +50,8 @@
51
50
  "@vue/vue3-jest": "^27.0.0-alpha.1",
52
51
  "add": "2.0.6",
53
52
  "ansi_up": "5.0.0",
53
+ "axios": "0.21.4",
54
+ "axios-retry": "3.1.9",
54
55
  "babel-eslint": "10.1.0",
55
56
  "babel-plugin-module-resolver": "4.0.0",
56
57
  "babel-preset-vue": "2.0.2",
@@ -62,8 +63,8 @@
62
63
  "cookie": "0.5.0",
63
64
  "cookie-universal": "2.2.2",
64
65
  "core-js": "3.25.3",
65
- "cron-validator": "1.2.0",
66
- "cronstrue": "1.95.0",
66
+ "cron-validator": "1.3.1",
67
+ "cronstrue": "2.50.0",
67
68
  "cross-env": "6.0.3",
68
69
  "css-loader": "6.7.3",
69
70
  "csv-loader": "3.0.3",
@@ -73,6 +74,7 @@
73
74
  "d3-selection": "1.4.1",
74
75
  "dagre-d3": "0.6.4",
75
76
  "dayjs": "1.8.29",
77
+ "defu": "5.0.1",
76
78
  "diff2html": "3.4.24",
77
79
  "dompurify": "2.5.4",
78
80
  "element-matches": "^0.1.2",
@@ -160,7 +162,7 @@
160
162
  "semver": "7.5.4",
161
163
  "@types/lodash": "4.17.5",
162
164
  "@types/node": "~20.10.0",
163
- "@vue/cli-service/html-webpack-plugin": "^5.0.0"
165
+ "@vue/cli-service/html-webpack-plugin": "^5.0.0"
164
166
  },
165
167
  "nyc": {
166
168
  "extension": [
@@ -168,4 +170,4 @@
168
170
  ".vue"
169
171
  ]
170
172
  }
171
- }
173
+ }
@@ -31,6 +31,7 @@ import {
31
31
  import loadPlugins from '@shell/plugins/plugin';
32
32
  import Loading from '@shell/components/Loading';
33
33
  import { getGlobalBannerFontSizes } from '@shell/utils/banners';
34
+ import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
34
35
 
35
36
  export default {
36
37
  name: 'Login',
@@ -64,7 +65,8 @@ export default {
64
65
  },
65
66
 
66
67
  computed: {
67
- ...mapGetters({ t: 'i18n/t' }),
68
+ ...mapGetters(['isSingleProduct']),
69
+ ...mapGetters({ t: 'i18n/t', hasMultipleLocales: 'i18n/hasMultipleLocales' }),
68
70
 
69
71
  loggedOutSuccessMsg() {
70
72
  if (this.isSlo) {
@@ -76,6 +78,10 @@ export default {
76
78
  return this.t('login.loggedOut');
77
79
  },
78
80
 
81
+ isHarvester() {
82
+ return this.isSingleProduct?.productName === HARVESTER;
83
+ },
84
+
79
85
  singleProvider() {
80
86
  return this.providers.length === 1 ? this.providers[0] : undefined;
81
87
  },
@@ -497,7 +503,7 @@ export default {
497
503
  </div>
498
504
  </template>
499
505
  <div
500
- v-if="showLocaleSelector"
506
+ v-if="showLocaleSelector && hasMultipleLocales && !isHarvester"
501
507
  class="locale-selector"
502
508
  >
503
509
  <LocaleSelector
@@ -141,7 +141,7 @@ export default {
141
141
  type: MANAGEMENT.FEATURE, id: 'multi-cluster-management', opt: { url: `/v1/${ MANAGEMENT.FEATURE }/multi-cluster-management` }
142
142
  });
143
143
 
144
- const mcmEnabled = mcmFeature?.spec?.value || mcmFeature?.status?.default;
144
+ const mcmEnabled = (mcmFeature?.spec?.value || mcmFeature?.status?.default) && productName !== 'Harvester';
145
145
 
146
146
  let serverUrl;
147
147
 
@@ -40,6 +40,7 @@ export default {
40
40
  allBundles: {
41
41
  inStoreType: 'management',
42
42
  type: FLEET.BUNDLE,
43
+ opt: { excludeFields: ['metadata.managedFields', 'spec.resources'] },
43
44
  },
44
45
  gitRepos: {
45
46
  inStoreType: 'management',
@@ -300,7 +301,7 @@ export default {
300
301
  </script>
301
302
 
302
303
  <template>
303
- <div class="fleet-dashboard">
304
+ <div>
304
305
  <Loading v-if="$fetchState.pending" />
305
306
  <!-- no git repos -->
306
307
  <FleetNoWorkspaces
@@ -450,9 +451,6 @@ export default {
450
451
  </template>
451
452
 
452
453
  <style lang="scss" scoped>
453
- .fleet-dashboard {
454
- min-height: 100vh;
455
- }
456
454
  .fleet-empty-dashboard {
457
455
  flex: 1;
458
456
  display: flex;
@@ -141,6 +141,9 @@ export default {
141
141
  const schema = this.$store.getters[`management/schemaFor`](MANAGEMENT.SETTING);
142
142
 
143
143
  return schema?.resourceMethods?.includes('PUT') ? _EDIT : _VIEW;
144
+ },
145
+ customLinkColor() {
146
+ return { color: this.uiLinkColor };
144
147
  }
145
148
  },
146
149
 
@@ -564,7 +567,7 @@ export default {
564
567
  component-testid="link"
565
568
  />
566
569
  <span class="col link-example">
567
- <a>
570
+ <a :style="customLinkColor">
568
571
  {{ t('branding.linkColor.example') }}
569
572
  </a>
570
573
  </span>
package/pages/prefs.vue CHANGED
@@ -40,6 +40,11 @@ export default {
40
40
  scalingDownPrompt: mapPref(SCALE_POOL_PROMPT),
41
41
 
42
42
  ...mapGetters(['isSingleProduct']),
43
+ ...mapGetters({ hasMultipleLocales: 'i18n/hasMultipleLocales' }),
44
+
45
+ isHarvester() {
46
+ return this.isSingleProduct?.productName === 'harvester';
47
+ },
43
48
 
44
49
  theme: {
45
50
  get() {
@@ -182,7 +187,10 @@ export default {
182
187
  </h1>
183
188
 
184
189
  <!-- Language -->
185
- <div class="mt-10 mb-10">
190
+ <div
191
+ v-if="hasMultipleLocales && !isHarvester"
192
+ class="mt-10 mb-10"
193
+ >
186
194
  <h4 v-t="'prefs.language'" />
187
195
  <div class="row">
188
196
  <div class="col span-4">
@@ -194,7 +202,6 @@ export default {
194
202
  </div>
195
203
  <!-- Theme -->
196
204
  <div class="mt-10 mb-10">
197
- <hr>
198
205
  <h4 v-t="'prefs.theme.label'" />
199
206
  <ButtonGroup
200
207
  v-model:value="theme"
@@ -262,7 +269,10 @@ export default {
262
269
  </div>
263
270
  </div>
264
271
  <!-- Confirmation setting -->
265
- <div class="col adv-features mt-10 mb-10">
272
+ <div
273
+ v-if="!isSingleProduct"
274
+ class="col adv-features mt-10 mb-10"
275
+ >
266
276
  <hr>
267
277
  <h4 v-t="'prefs.confirmationSetting.title'" />
268
278
  <Checkbox
@@ -282,13 +292,15 @@ export default {
282
292
  :label="t('prefs.advFeatures.viewInApi', {}, true)"
283
293
  class="mt-10"
284
294
  />
285
- <br>
286
- <Checkbox
287
- v-model:value="allNamespaces"
288
- data-testid="prefs__allNamespaces"
289
- :label="t('prefs.advFeatures.allNamespaces', {}, true)"
290
- class="mt-20"
291
- />
295
+ <template v-if="!isHarvester">
296
+ <br>
297
+ <Checkbox
298
+ v-model:value="allNamespaces"
299
+ data-testid="prefs__allNamespaces"
300
+ :label="t('prefs.advFeatures.allNamespaces', {}, true)"
301
+ class="mt-20"
302
+ />
303
+ </template>
292
304
  <br>
293
305
  <Checkbox
294
306
  v-model:value="themeShortcut"
@@ -9,7 +9,7 @@ import {
9
9
  AS,
10
10
  MODE
11
11
  } from '@shell/config/query-params';
12
- import { VIEW_IN_API } from '@shell/store/prefs';
12
+ import { VIEW_IN_API, DEV } from '@shell/store/prefs';
13
13
  import { addObject, addObjects, findBy, removeAt } from '@shell/utils/array';
14
14
  import CustomValidators from '@shell/utils/custom-validators';
15
15
  import { downloadFile, generateZip } from '@shell/utils/download';
@@ -84,6 +84,7 @@ export const STATES_ENUM = {
84
84
  DISCONNECTED: 'disconnected',
85
85
  DRAINED: 'drained',
86
86
  DRAINING: 'draining',
87
+ ENABLED: 'enabled',
87
88
  ERR_APPLIED: 'errapplied',
88
89
  ERROR: 'error',
89
90
  ERRORING: 'erroring',
@@ -232,6 +233,9 @@ export const STATES = {
232
233
  [STATES_ENUM.DRAINING]: {
233
234
  color: 'warning', icon: 'tag', label: 'Draining', compoundIcon: 'warning'
234
235
  },
236
+ [STATES_ENUM.ENABLED]: {
237
+ color: 'success', icon: 'dot-open', label: 'Enabled', compoundIcon: 'checkmark'
238
+ },
235
239
  [STATES_ENUM.ERR_APPLIED]: {
236
240
  color: 'error', icon: 'error', label: 'Error Applied', compoundIcon: 'error'
237
241
  },
@@ -997,7 +1001,11 @@ export default class Resource {
997
1001
  }
998
1002
 
999
1003
  get canViewInApi() {
1000
- return this.hasLink('self') && this.$rootGetters['prefs/get'](VIEW_IN_API);
1004
+ try {
1005
+ return this.hasLink('self') && this.$rootGetters['prefs/get'](VIEW_IN_API);
1006
+ } catch {
1007
+ return this.hasLink('self') && this.$rootGetters['prefs/get'](DEV);
1008
+ }
1001
1009
  }
1002
1010
 
1003
1011
  get canYaml() {
@@ -1055,7 +1063,7 @@ export default class Resource {
1055
1063
 
1056
1064
  async doActionGrowl(actionName, body, opt = {}) {
1057
1065
  try {
1058
- await this.$dispatch('resourceAction', {
1066
+ return await this.$dispatch('resourceAction', {
1059
1067
  resource: this,
1060
1068
  actionName,
1061
1069
  body,
@@ -6,7 +6,7 @@ import { uniq } from '@shell/utils/array';
6
6
  import {
7
7
  CONFIG_MAP, MANAGEMENT, NAMESPACE, NODE, POD
8
8
  } from '@shell/config/types';
9
- import { Schema } from 'plugins/steve/schema';
9
+ import { Schema } from '@shell/plugins/steve/schema';
10
10
 
11
11
  class NamespaceProjectFilters {
12
12
  /**
@@ -177,11 +177,16 @@ export default defineComponent({
177
177
  if (this.type !== 'cron' || !this.value) {
178
178
  return;
179
179
  }
180
- if (typeof this.value === 'string' && !isValidCron(this.value)) {
180
+ // refer https://github.com/GuillaumeRochat/cron-validator#readme
181
+ if (!isValidCron(this.value as string, {
182
+ alias: true,
183
+ allowBlankDay: true,
184
+ allowSevenAsSunday: true,
185
+ })) {
181
186
  return this.t('generic.invalidCron');
182
187
  }
183
188
  try {
184
- const hint = cronstrue.toString(this.value || '');
189
+ const hint = cronstrue.toString(this.value as string || '', { verbose: true });
185
190
 
186
191
  return hint;
187
192
  } catch (e) {
@@ -4,27 +4,34 @@ GITHUB_RELEASE_TAG=$1
4
4
  GITHUB_RUN_ID=$2
5
5
  GITHUB_WORKFLOW_TYPE=$3
6
6
 
7
- # Ensure "catalog" workflow release tag name does not match a pkg/<pkg-name>
7
+ echo "Parse tag name - evaluating release tag $GITHUB_RELEASE_TAG"
8
+
9
+ # Ensure "catalog" workflow release tag name matches the root <pkg-name>
8
10
  if [[ "${GITHUB_WORKFLOW_TYPE}" == "catalog" ]]; then
11
+ BASE_EXT=$(jq -r .name package.json)
12
+ EXT_VERSION=$(jq -r .version package.json)
13
+
14
+ if [[ "${GITHUB_RELEASE_TAG}" != "${BASE_EXT}-${EXT_VERSION}" ]]; then
15
+ echo -e "release tag doesn't match catalog tag: release tag -> ${GITHUB_RELEASE_TAG} ::: curr catalog tag -> ${BASE_EXT}-${EXT_VERSION}"
16
+ gh run cancel ${GITHUB_RUN_ID}
17
+ fi
18
+ # Ensure "chart" workflow release tag name matches some pkg/<pkg-name>
19
+ else
20
+ NO_MATCHES="true"
21
+
9
22
  for d in pkg/*/ ; do
10
23
  pkg=$(basename $d)
11
24
 
12
25
  PKG_VERSION=$(jq -r .version pkg/${pkg}/package.json)
13
- PKG_NAME="${pkg}-${PKG_VERSION}"
26
+ CURR_PKG_TAG="${pkg}-${PKG_VERSION}"
14
27
 
15
- if [[ "${GITHUB_RELEASE_TAG}" == "${PKG_NAME}" ]]; then
16
- gh run cancel ${GITHUB_RUN_ID}
17
- else
18
- continue
28
+ if [[ "${GITHUB_RELEASE_TAG}" == "${CURR_PKG_TAG}" ]]; then
29
+ NO_MATCHES="false"
19
30
  fi
20
31
  done
21
- else
22
- # Ensure "charts" workflow release tag name does not match the root <pkg-name>
23
- BASE_EXT=$(jq -r .name package.json)
24
- EXT_VERSION=$(jq -r .version package.json)
25
32
 
26
- if [[ "${GITHUB_RELEASE_TAG}" == "${BASE_EXT}-${EXT_VERSION}" ]]; then
27
- echo -e "tag: ${GITHUB_RELEASE_TAG}"
33
+ if [[ "${NO_MATCHES}" == "true" ]]; then
34
+ echo -e "release tag doesn't match any chart tag: ${GITHUB_RELEASE_TAG}. Check your pkg/<!-YOUR-EXT-> folders and corresponding versions to complete the match"
28
35
  gh run cancel ${GITHUB_RUN_ID}
29
36
  fi
30
37
  fi
@@ -6,7 +6,6 @@ SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
6
6
  BASE_DIR="$(cd $SCRIPT_DIR && cd ../.. && pwd)"
7
7
  SHELL_DIR=$BASE_DIR/shell/
8
8
  CREATORS_DIR=$BASE_DIR/creators/extension
9
- PUBLISH_ARGS="--no-git-tag-version --access public --registry $NPM_REGISTRY $NPM_TAG"
10
9
  FORCE_PUBLISH_TO_NPM="false"
11
10
  DEFAULT_NPM_REGISTRY="https://registry.npmjs.org"
12
11
 
@@ -31,6 +30,8 @@ if [ "$FORCE_PUBLISH_TO_NPM" == "true" ]; then
31
30
  export NPM_REGISTRY=$DEFAULT_NPM_REGISTRY
32
31
  fi
33
32
 
33
+ PUBLISH_ARGS="--no-git-tag-version --access public --registry $NPM_REGISTRY"
34
+
34
35
  pushd ${SHELL_DIR} >/dev/null
35
36
 
36
37
  function publish() {
@@ -47,9 +48,16 @@ function publish() {
47
48
 
48
49
  # if the PKG_VERSION has a - it means it will be a pre-release
49
50
  if [[ $PKG_VERSION == *"-"* ]]; then
50
- PUBLISH_ARGS="--no-git-tag-version --access public --registry $NPM_REGISTRY --tag pre-release"
51
+ PUBLISH_ARGS="$PUBLISH_ARGS --tag pre-release"
52
+ fi
53
+
54
+ # when testing the workflow, we don't want to actually do an npm publish but only a dry run
55
+ if [ ${DRY_RUN} == "true" ]; then
56
+ PUBLISH_ARGS="$PUBLISH_ARGS --dry-run"
51
57
  fi
52
58
 
59
+ echo "Publish to NPM - arguments ::: ${PUBLISH_ARGS}"
60
+
53
61
  echo "Publishing ${NAME} from ${FOLDER}"
54
62
  pushd ${FOLDER} >/dev/null
55
63
 
@@ -169,8 +169,9 @@ fi
169
169
 
170
170
  # function to clone repos and install dependencies (including the newly published shell version)
171
171
  function clone_repo_test_extension_build() {
172
- REPO_NAME=$1
173
- PKG_NAME=$2
172
+ REPO_ORG=$1
173
+ REPO_NAME=$2
174
+ PKG_NAME=$3
174
175
 
175
176
  echo -e "\nSetting up $REPO_NAME repository locally\n"
176
177
 
@@ -183,7 +184,7 @@ function clone_repo_test_extension_build() {
183
184
  fi
184
185
 
185
186
  # cloning repo
186
- git clone https://github.com/rancher/$REPO_NAME.git
187
+ git clone https://github.com/$REPO_ORG/$REPO_NAME.git
187
188
  pushd ${BASE_DIR}/$REPO_NAME
188
189
 
189
190
  echo -e "\nInstalling dependencies for $REPO_NAME\n"
@@ -196,9 +197,6 @@ function clone_repo_test_extension_build() {
196
197
  sed -i.bak -e "s/\"\@rancher\/shell\": \"[0-9]*.[0-9]*.[0-9]*\",/\"\@rancher\/shell\": \"${SHELL_VERSION}\",/g" package.json
197
198
  rm package.json.bak
198
199
 
199
- # we need to remove yarn.lock, otherwise it would install a version that we don't want
200
- rm yarn.lock
201
-
202
200
  echo -e "\nInstalling newly built shell version\n"
203
201
 
204
202
  # installing new version of shell
@@ -223,8 +221,9 @@ function clone_repo_test_extension_build() {
223
221
 
224
222
  # Here we just add the extension that we want to include as a check (all our official extensions should be included here)
225
223
  # Don't forget to add the unit tests exception to clone_repo_test_extension_build function if a new extension has those
226
- # clone_repo_test_extension_build "kubewarden-ui" "kubewarden"
227
- # clone_repo_test_extension_build "elemental-ui" "elemental"
228
- # clone_repo_test_extension_build "capi-ui-extension" "capi"
224
+ clone_repo_test_extension_build "rancher" "kubewarden-ui" "kubewarden"
225
+ clone_repo_test_extension_build "rancher" "elemental-ui" "elemental"
226
+ clone_repo_test_extension_build "neuvector" "manager-ext" "neuvector-ui-ext"
227
+ # clone_repo_test_extension_build "rancher" "capi-ui-extension" "capi"
229
228
 
230
229
  echo "All done"
@@ -31,9 +31,11 @@ ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/plugins/dashboard-store/normalize
31
31
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/plugins/dashboard-store/resource-class.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/plugins/dashboard-store/ > /dev/null
32
32
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/plugins/dashboard-store/classify.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/plugins/dashboard-store/ > /dev/null
33
33
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/plugins/dashboard-store/actions.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/plugins/dashboard-store/ > /dev/null
34
+ ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/plugins/steve/steve-class.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/plugins/steve/ > /dev/null
34
35
 
35
36
  # # mixins
36
37
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/mixins/create-edit-view/index.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/mixins/create-edit-view > /dev/null
38
+ ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/mixins/resource-fetch.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/mixins > /dev/null
37
39
 
38
40
  # # models
39
41
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/models/namespace.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/models/ > /dev/null
package/store/features.js CHANGED
@@ -35,6 +35,7 @@ export const HARVESTER_CONTAINER = create('harvester-baremetal-container-workloa
35
35
  export const FLEET_WORKSPACE_BACK = create('provisioningv2-fleet-workspace-back-population', false);
36
36
  export const STEVE_CACHE = create('ui-sql-cache', false);
37
37
  export const UIEXTENSION = create('uiextension', true);
38
+ export const PROVISIONING_PRE_BOOTSTRAP = create('provisioningprebootstrap', false);
38
39
 
39
40
  // Not currently used.. no point defining ones we don't use
40
41
  // export const EMBEDDED_CLUSTER_API = create('embedded-cluster-api', true);
package/store/i18n.js CHANGED
@@ -58,6 +58,10 @@ export const getters = {
58
58
  return out;
59
59
  },
60
60
 
61
+ hasMultipleLocales(state) {
62
+ return state.available.length > 1;
63
+ },
64
+
61
65
  t: (state) => (key, args, language) => {
62
66
  if (state.selected === NONE && !language) {
63
67
  return `%${ key }%`;
@@ -333,7 +337,7 @@ export const actions = {
333
337
 
334
338
  commit('setSelected', locale);
335
339
 
336
- // Ony update the preference if the locale changed
340
+ // Only update the preference if the locale changed
337
341
  if (currentLocale !== locale) {
338
342
  dispatch('prefs/set', {
339
343
  key: 'locale',
package/store/prefs.js CHANGED
@@ -233,6 +233,14 @@ export const getters = {
233
233
  default:
234
234
  return { name: afterLoginRoutePref };
235
235
  }
236
+ },
237
+
238
+ dev: (state, getters) => {
239
+ try {
240
+ return getters['get'](PLUGIN_DEVELOPER);
241
+ } catch {
242
+ return getters['get'](DEV);
243
+ }
236
244
  }
237
245
  };
238
246