@rancher/shell 2.0.1 → 2.0.2-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/assets/translations/en-us.yaml +51 -26
  2. package/assets/translations/zh-hans.yaml +1 -0
  3. package/components/AssignTo.vue +2 -0
  4. package/components/Questions/index.vue +2 -2
  5. package/components/auth/RoleDetailEdit.vue +5 -4
  6. package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
  7. package/components/form/ProjectMemberEditor.vue +1 -1
  8. package/components/form/ResourceLabeledSelect.vue +11 -3
  9. package/components/form/labeled-select-utils/labeled-select.utils.ts +1 -1
  10. package/config/pagination-table-headers.js +5 -4
  11. package/config/roles.ts +34 -19
  12. package/config/router/navigation-guards/attempt-first-login.js +1 -1
  13. package/config/router/navigation-guards/authentication.js +1 -1
  14. package/config/router/navigation-guards/i18n.js +1 -1
  15. package/config/router/navigation-guards/index.js +2 -1
  16. package/config/router/navigation-guards/load-initial-settings.js +1 -1
  17. package/config/router/navigation-guards/runtime-extension-route.js +31 -0
  18. package/config/router/routes.js +10 -1
  19. package/config/uiplugins.js +130 -61
  20. package/core/plugin.ts +5 -0
  21. package/core/plugins.js +7 -1
  22. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +86 -13
  23. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +3 -134
  24. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +209 -0
  25. package/edit/provisioning.cattle.io.cluster/index.vue +8 -4
  26. package/edit/provisioning.cattle.io.cluster/rke2.vue +115 -17
  27. package/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest.vue +50 -0
  28. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +29 -64
  29. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +42 -3
  30. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +22 -86
  31. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +8 -2
  32. package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +61 -0
  33. package/initialize/entry-helpers.js +4 -21
  34. package/mixins/__tests__/chart.test.ts +4 -1
  35. package/mixins/chart.js +30 -14
  36. package/models/__tests__/apps.deployment.test.ts +93 -0
  37. package/models/apps.deployment.js +18 -4
  38. package/models/management.cattle.io.cluster.js +2 -2
  39. package/models/management.cattle.io.user.js +3 -3
  40. package/models/nodedriver.js +5 -0
  41. package/models/provisioning.cattle.io.cluster.js +4 -0
  42. package/package.json +1 -1
  43. package/pages/404.vue +15 -0
  44. package/pages/auth/login.vue +4 -1
  45. package/pages/auth/setup.vue +4 -1
  46. package/pages/c/_cluster/explorer/index.vue +5 -0
  47. package/pages/c/_cluster/manager/jwt.authentication/index.vue +10 -4
  48. package/pages/c/_cluster/settings/performance.vue +2 -2
  49. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +7 -10
  50. package/pages/c/_cluster/uiplugins/index.vue +24 -16
  51. package/pages/home.vue +1 -13
  52. package/plugins/dashboard-store/actions.js +1 -1
  53. package/plugins/dashboard-store/getters.js +1 -1
  54. package/plugins/steve/__tests__/getters.test.ts +5 -5
  55. package/plugins/steve/getters.js +6 -4
  56. package/plugins/steve/hybrid-class.js +1 -5
  57. package/scripts/extension/helm/charts/ui-plugin-server/Chart.yaml +1 -1
  58. package/scripts/publish-shell.sh +53 -55
  59. package/scripts/test-plugins-build.sh +45 -39
  60. package/shell/types/shell/index.d.ts +2 -0
  61. package/store/type-map.js +4 -2
  62. package/types/store/pagination.types.ts +1 -1
  63. package/utils/cluster.js +9 -0
  64. package/utils/settings.ts +3 -1
  65. package/creators/app/app.package.json +0 -14
  66. package/creators/app/files/.eslintignore +0 -16
  67. package/creators/app/files/.eslintrc.js +0 -173
  68. package/creators/app/files/.gitignore +0 -70
  69. package/creators/app/files/.gitlab-ci.yml +0 -14
  70. package/creators/app/files/.vscode/settings.json +0 -21
  71. package/creators/app/files/babel.config.js +0 -1
  72. package/creators/app/files/tsconfig.json +0 -42
  73. package/creators/app/files/vue.config.js +0 -6
  74. package/creators/app/init +0 -120
  75. package/creators/app/package.json +0 -25
  76. package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +0 -24
  77. package/creators/pkg/files/.github/workflows/build-extension-charts.yml +0 -22
  78. package/creators/pkg/files/babel.config.js +0 -1
  79. package/creators/pkg/files/index.ts +0 -14
  80. package/creators/pkg/files/tsconfig.json +0 -53
  81. package/creators/pkg/files/vue.config.js +0 -1
  82. package/creators/pkg/init +0 -286
  83. package/creators/pkg/package.json +0 -19
  84. package/creators/pkg/pkg.package.json +0 -21
  85. package/creators/pkg/vue-shim.ts +0 -4
  86. package/creators/update/init +0 -56
  87. package/creators/update/package.json +0 -20
  88. package/creators/update/upgrade +0 -56
  89. package/types/shell/index.d.ts +0 -4585
@@ -10,14 +10,28 @@ const IGNORED_ANNOTATIONS = [
10
10
  'deprecated.deployment.rollback.to',
11
11
  ];
12
12
 
13
+ const replicasRegEx = /Replicas: (\d+)/;
14
+
13
15
  export default class Deployment extends Workload {
14
16
  get replicaSetId() {
15
- const set = this.metadata?.relationships?.find((relationship) => {
16
- return relationship.rel === 'owner' &&
17
- relationship.toType === WORKLOAD_TYPES.REPLICA_SET;
17
+ const relationships = this.metadata?.relationships || [];
18
+
19
+ // Find all relevant ReplicaSet relationships
20
+ const replicaSetRelationships = relationships.filter((relationship) => relationship.rel === 'owner' && relationship.toType === WORKLOAD_TYPES.REPLICA_SET
21
+ );
22
+
23
+ // Filter the ReplicaSets based on replicas > 0
24
+ const activeReplicaSet = replicaSetRelationships.find((relationship) => {
25
+ const replicasMatch = relationship.message?.match(replicasRegEx);
26
+ const replicas = replicasMatch ? parseInt(replicasMatch[1], 10) : 0;
27
+
28
+ return replicas > 0;
18
29
  });
19
30
 
20
- return set?.toId?.replace(`${ this.namespace }/`, '');
31
+ // If no active ReplicaSet is found, fall back to the first one from the list
32
+ const selectedReplicaSet = activeReplicaSet || replicaSetRelationships[0];
33
+
34
+ return selectedReplicaSet?.toId?.replace(`${ this.namespace }/`, '');
21
35
  }
22
36
 
23
37
  async rollBack(cluster, deployment, revision) {
@@ -10,7 +10,7 @@ import { addParams } from '@shell/utils/url';
10
10
  import { isEmpty } from '@shell/utils/object';
11
11
  import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
12
12
  import { isHarvesterCluster } from '@shell/utils/cluster';
13
- import HybridModel from '@shell/plugins/steve/hybrid-class';
13
+ import SteveModel from '@shell/plugins/steve/steve-class';
14
14
  import { LINUX, WINDOWS } from '@shell/store/catalog';
15
15
  import { KONTAINER_TO_DRIVER } from './management.cattle.io.kontainerdriver';
16
16
  import { PINNED_CLUSTERS } from '@shell/store/prefs';
@@ -27,7 +27,7 @@ function findRelationship(verb, type, relationships = []) {
27
27
  return relationships.find((r) => r[from] === type)?.[id];
28
28
  }
29
29
 
30
- export default class MgmtCluster extends HybridModel {
30
+ export default class MgmtCluster extends SteveModel {
31
31
  get details() {
32
32
  const out = [
33
33
  {
@@ -105,7 +105,7 @@ export default class User extends HybridModel {
105
105
  * @returns {number}
106
106
  */
107
107
  get userLastLogin() {
108
- return this.metadata?.labels?.['cattle.io/last-login'] * 1000;
108
+ return this.metadata?.labels?.['cattle.io/last-login'] * 1000 || 0;
109
109
  }
110
110
 
111
111
  /**
@@ -113,7 +113,7 @@ export default class User extends HybridModel {
113
113
  * @returns {number}
114
114
  */
115
115
  get userDisabledIn() {
116
- return this.metadata?.labels?.['cattle.io/disable-after'] * 1000;
116
+ return this.metadata?.labels?.['cattle.io/disable-after'] * 1000 || 0;
117
117
  }
118
118
 
119
119
  /**
@@ -129,7 +129,7 @@ export default class User extends HybridModel {
129
129
  * @returns {number}
130
130
  */
131
131
  get userDeletedIn() {
132
- return this.metadata?.labels?.['cattle.io/delete-after'] * 1000;
132
+ return this.metadata?.labels?.['cattle.io/delete-after'] * 1000 || 0;
133
133
  }
134
134
 
135
135
  get state() {
@@ -1,5 +1,10 @@
1
1
  import Driver from '@shell/models/driver';
2
2
 
3
+ /**
4
+ * Overrides for spec.addCloudCredential
5
+ */
6
+ export const CLOUD_CREDENTIAL_OVERRIDE = { nutanix: true };
7
+
3
8
  export default class NodeDriver extends Driver {
4
9
  get doneRoute() {
5
10
  return 'c-cluster-manager-driver-nodedriver';
@@ -986,4 +986,8 @@ export default class ProvCluster extends SteveModel {
986
986
  'spec.rkeConfig.machinePools.dynamicSchemaSpec',
987
987
  ];
988
988
  }
989
+
990
+ get description() {
991
+ return super.description || this.mgmt?.description;
992
+ }
989
993
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rancher/shell",
3
- "version": "2.0.1",
3
+ "version": "2.0.2-rc.1",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",
package/pages/404.vue ADDED
@@ -0,0 +1,15 @@
1
+ <script>
2
+ import Brand from '@shell/mixins/brand';
3
+
4
+ export default {
5
+ mixins: [Brand],
6
+ beforeMount() {
7
+ this.$store.commit('setError', { error: new Error('404: This page could not be found') });
8
+ this.$router.replace('/fail-whale');
9
+ }
10
+ };
11
+ </script>
12
+
13
+ <template>
14
+ <div class="dashboard-root" />
15
+ </template>
@@ -288,7 +288,10 @@ export default {
288
288
  </script>
289
289
 
290
290
  <template>
291
- <Loading v-if="$fetchState.pending" />
291
+ <Loading
292
+ v-if="$fetchState.pending"
293
+ mode="relative"
294
+ />
292
295
  <main
293
296
  v-else
294
297
  class="main-layout login"
@@ -276,7 +276,10 @@ export default {
276
276
  </script>
277
277
 
278
278
  <template>
279
- <Loading v-if="$fetchState.pending" />
279
+ <Loading
280
+ v-if="$fetchState.pending"
281
+ mode="relative"
282
+ />
280
283
  <form
281
284
  v-else
282
285
  class="setup"
@@ -48,6 +48,7 @@ import { NAME as EXPLORER } from '@shell/config/product/explorer';
48
48
  import TabTitle from '@shell/components/TabTitle';
49
49
  import { STATES_ENUM } from '@shell/plugins/dashboard-store/resource-class';
50
50
  import capitalize from 'lodash/capitalize';
51
+ import paginationUtils from '@shell/utils/pagination-utils';
51
52
 
52
53
  export const RESOURCES = [NAMESPACE, INGRESS, PV, WORKLOAD_TYPES.DEPLOYMENT, WORKLOAD_TYPES.STATEFUL_SET, WORKLOAD_TYPES.JOB, WORKLOAD_TYPES.DAEMON_SET, SERVICE];
53
54
 
@@ -122,6 +123,8 @@ export default {
122
123
  this.loadAgents();
123
124
  }
124
125
  }
126
+
127
+ this.showCertificates = !paginationUtils.isSteveCacheEnabled({ rootGetters: this.$store.getters });
125
128
  },
126
129
 
127
130
  data() {
@@ -156,6 +159,7 @@ export default {
156
159
  clusterCounts,
157
160
  selectedTab: 'cluster-events',
158
161
  extensionCards: getApplicableExtensionEnhancements(this, ExtensionPoint.CARD, CardLocation.CLUSTER_DASHBOARD_CARD, this.$route),
162
+ showCertificates: false,
159
163
  };
160
164
  },
161
165
 
@@ -739,6 +743,7 @@ export default {
739
743
  <AlertTable v-if="selectedTab === 'cluster-alerts'" />
740
744
  </Tab>
741
745
  <Tab
746
+ v-if="showCertificates"
742
747
  name="cluster-certs"
743
748
  :label="t('clusterIndexPage.sections.certs.label')"
744
749
  :weight="1"
@@ -22,7 +22,7 @@ export default {
22
22
  async fetch() {
23
23
  const hash = {
24
24
  mgmtClusters: this.$fetchType(MANAGEMENT.CLUSTER),
25
- proxyConfig: this.$fetchType(MANAGEMENT.CLUSTER_PROXY_CONFIG)
25
+ proxyConfig: this.$store.dispatch('management/findAll', { type: MANAGEMENT.CLUSTER_PROXY_CONFIG, opt: { omitExcludeFields: ['metadata.managedFields'] } })
26
26
  };
27
27
 
28
28
  const res = await allHash(hash);
@@ -150,7 +150,11 @@ export default {
150
150
 
151
151
  const value = config?.enabled || '';
152
152
  const configName = config?.metadata?.name || '';
153
- const updatedOn = value ? config?.metadata?.creationTimestamp : '';
153
+ let updatedOn = '';
154
+
155
+ if (value) {
156
+ updatedOn = config?.metadata?.managedFields?.find((field) => field.operation === 'Update')?.time || '';
157
+ }
154
158
  const stateBackground = value ? colorForState(STATES_ENUM.ACTIVE).replace('text', 'bg') : colorForState(STATES_ENUM.INFO).replace('text', 'bg');
155
159
  const stateLabel = value ? this.t('jwt.state.enabled') : this.t('jwt.state.disabled');
156
160
  const creationTimestamp = cluster.metadata.creationTimestamp;
@@ -159,7 +163,7 @@ export default {
159
163
  if (!configName) {
160
164
  const clusterProxyConfig = await this.$store.dispatch('management/create', {
161
165
  enabled: true,
162
- metadata: { namespace: id, generateName: 'cluster-proxy-config-' },
166
+ metadata: { namespace: id, name: 'clusterproxyconfig' },
163
167
  });
164
168
 
165
169
  return clusterProxyConfig.save({ url: 'v1/management.cattle.io.clusterproxyconfigs', method: 'POST' });
@@ -170,7 +174,9 @@ export default {
170
174
  }
171
175
  };
172
176
  const disable = async() => {
173
- return config.remove();
177
+ config.enabled = false;
178
+
179
+ return config.save();
174
180
  };
175
181
 
176
182
  rows.push({
@@ -61,7 +61,7 @@ export default {
61
61
 
62
62
  data() {
63
63
  return {
64
- uiPerfSetting: DEFAULT_PERF_SETTING,
64
+ uiPerfSetting: null,
65
65
  authUserTTL: null,
66
66
  bannerVal: {},
67
67
  value: {},
@@ -161,7 +161,7 @@ export default {
161
161
  return;
162
162
  }
163
163
 
164
- // We're enabling a preference. Are there any incomaptible preferences?
164
+ // We're enabling a preference. Are there any incompatible preferences?
165
165
  if ((incompatible[property] || []).every((p) => !this.value[p].enabled)) {
166
166
  // No, just set and exit
167
167
  this.value[property].enabled = true;
@@ -5,6 +5,7 @@ import { Banner } from '@components/Banner';
5
5
  import LazyImage from '@shell/components/LazyImage';
6
6
  import { MANAGEMENT } from '@shell/config/types';
7
7
  import { SETTING } from '@shell/config/settings';
8
+ import { EXTENSIONS_INCOMPATIBILITY_TYPES, UI_PLUGIN_HOST_APP } from '@shell/config/uiplugins';
8
9
 
9
10
  export default {
10
11
  async fetch() {
@@ -65,10 +66,9 @@ export default {
65
66
  async loadPluginVersionInfo(version) {
66
67
  const versionName = version || this.info.displayVersion;
67
68
 
68
- const isVersionNotCompatibleWithUi = this.info.versions?.find((v) => v.version === versionName && !v.isCompatibleWithUi);
69
- const isVersionNotCompatibleWithKubeVersion = this.info.versions?.find((v) => v.version === versionName && !v.isCompatibleWithKubeVersion);
69
+ const isVersionNotCompatible = this.info.versions?.find((v) => v.version === versionName && !v.isVersionCompatible);
70
70
 
71
- if (!this.info.chart || isVersionNotCompatibleWithUi || isVersionNotCompatibleWithKubeVersion) {
71
+ if (!this.info.chart || isVersionNotCompatible) {
72
72
  return;
73
73
  }
74
74
 
@@ -107,18 +107,15 @@ export default {
107
107
  },
108
108
 
109
109
  handleVersionBtnTooltip(version) {
110
- if (version.requiredUiVersion) {
111
- return this.t('plugins.info.requiresRancherVersion', { version: version.requiredUiVersion });
112
- }
113
- if (version.requiredKubeVersion) {
114
- return this.t('plugins.info.requiresKubeVersion', { version: version.requiredKubeVersion });
110
+ if (!version.isVersionCompatible && Object.keys(version.versionIncompatibilityData).length) {
111
+ return this.t(version.versionIncompatibilityData?.tooltipKey, { required: version.versionIncompatibilityData?.type === EXTENSIONS_INCOMPATIBILITY_TYPES.HOST ? UI_PLUGIN_HOST_APP : version.versionIncompatibilityData?.required });
115
112
  }
116
113
 
117
114
  return '';
118
115
  },
119
116
 
120
117
  handleVersionBtnClass(version) {
121
- return { 'version-active': version.version === this.infoVersion, disabled: !version.isCompatibleWithUi || !version.isCompatibleWithKubeVersion };
118
+ return { 'version-active': version.version === this.infoVersion, disabled: !version.isVersionCompatible };
122
119
  }
123
120
  }
124
121
  };
@@ -219,7 +216,7 @@ export default {
219
216
  <div class="plugin-versions mb-10">
220
217
  <div
221
218
  v-for="v in info.versions"
222
- :key="v.version"
219
+ :key="`${v.name}-${v.version}`"
223
220
  >
224
221
  <a
225
222
  v-clean-tooltip="handleVersionBtnTooltip(v)"
@@ -31,12 +31,13 @@ import {
31
31
  uiPluginAnnotation,
32
32
  uiPluginHasAnnotation,
33
33
  isSupportedChartVersion,
34
- isChartVersionAvailableForInstall,
35
34
  isChartVersionHigher,
36
35
  UI_PLUGIN_NAMESPACE,
37
36
  UI_PLUGIN_CHART_ANNOTATIONS,
38
37
  UI_PLUGINS_REPO_URL,
39
- UI_PLUGINS_PARTNERS_REPO_URL
38
+ UI_PLUGINS_PARTNERS_REPO_URL,
39
+ UI_PLUGIN_HOST_APP,
40
+ EXTENSIONS_INCOMPATIBILITY_TYPES
40
41
  } from '@shell/config/uiplugins';
41
42
  import TabTitle from '@shell/components/TabTitle';
42
43
 
@@ -258,19 +259,20 @@ export default {
258
259
 
259
260
  item.versions = [...chart.versions];
260
261
  item.chart = chart;
262
+ item.incompatibilityMessage = '';
261
263
 
262
264
  // Filter the versions available to install (plugins-api version and current dashboard version)
263
- item.installableVersions = item.versions.filter((version) => isSupportedChartVersion({ version, kubeVersion: this.kubeVersion }) && isChartVersionAvailableForInstall({
265
+ item.installableVersions = item.versions.filter((version) => isSupportedChartVersion({
264
266
  version, rancherVersion: this.rancherVersion, kubeVersion: this.kubeVersion
265
267
  }));
266
268
 
267
269
  // add prop to version object if version is compatible with the current dashboard version
268
- item.versions = item.versions.map((version) => isChartVersionAvailableForInstall({
270
+ item.versions = item.versions.map((version) => isSupportedChartVersion({
269
271
  version, rancherVersion: this.rancherVersion, kubeVersion: this.kubeVersion
270
272
  }, true));
271
273
 
272
274
  const latestCompatible = item.installableVersions?.[0];
273
- const latestNotCompatible = item.versions.find((version) => !version.isCompatibleWithUi || !version.isCompatibleWithKubeVersion);
275
+ const latestNotCompatible = item.versions.find((version) => !version.isVersionCompatible);
274
276
 
275
277
  if (latestCompatible) {
276
278
  item.displayVersion = latestCompatible.version;
@@ -280,11 +282,20 @@ export default {
280
282
  item.icon = chart.icon || latestCompatible?.annotations?.['catalog.cattle.io/ui-icon'];
281
283
  }
282
284
 
285
+ // add message of extension card if there's a newer version of the extension, but it's not available to be installed
283
286
  if (latestNotCompatible && item.installableVersions.length && isChartVersionHigher(latestNotCompatible.version, item.installableVersions?.[0].version)) {
284
- if (!item.isCompatibleWithUi) {
285
- item.incompatibleRancherVersion = this.t('plugins.incompatibleRancherVersion', { version: latestNotCompatible.version, rancherVersion: latestNotCompatible.requiredUiVersion }, true);
286
- } else if (!item.isCompatibleWithKubeVersion) {
287
- item.incompatibleKubeVersion = this.t('plugins.incompatibleKubeVersion', { version: latestNotCompatible.version, kubeVersion: latestNotCompatible.requiredKubeVersion }, true);
287
+ switch (latestNotCompatible.versionIncompatibilityData?.type) {
288
+ case EXTENSIONS_INCOMPATIBILITY_TYPES.HOST:
289
+ item.incompatibilityMessage = this.t(latestNotCompatible.versionIncompatibilityData?.cardMessageKey, {
290
+ version: latestNotCompatible.version, required: latestNotCompatible.versionIncompatibilityData?.required, mainHost: UI_PLUGIN_HOST_APP
291
+ }, true);
292
+ break;
293
+ default:
294
+ item.incompatibilityMessage = this.t(latestNotCompatible.versionIncompatibilityData?.cardMessageKey, {
295
+ version: latestNotCompatible.version,
296
+ required: latestNotCompatible.versionIncompatibilityData?.required
297
+ }, true);
298
+ break;
288
299
  }
289
300
  }
290
301
 
@@ -398,8 +409,9 @@ export default {
398
409
 
399
410
  if (versionInstalledData) {
400
411
  const kubeVersionToCheck = versionInstalledData.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.KUBE_VERSION];
412
+ const versionSupportedData = isSupportedChartVersion({ version: versionInstalledData, kubeVersion: this.kubeVersion });
401
413
 
402
- if (this.kubeVersion && !isSupportedChartVersion({ version: versionInstalledData, kubeVersion: this.kubeVersion })) {
414
+ if (this.kubeVersion && !versionSupportedData.isVersionCompatible && versionSupportedData.versionIncompatibilityData?.type === EXTENSIONS_INCOMPATIBILITY_TYPES.KUBE) {
403
415
  plugin.installedError = this.t('plugins.currentInstalledVersionBlockedByKubeVersion', { kubeVersion: this.kubeVersion, kubeVersionToCheck }, true);
404
416
  }
405
417
  }
@@ -848,13 +860,9 @@ export default {
848
860
  <span>{{ plugin.installedError }}</span>
849
861
  </p>
850
862
  <p
851
- v-else-if="plugin.incompatibleRancherVersion"
863
+ v-else-if="plugin.incompatibilityMessage"
852
864
  class="incompatible"
853
- >{{ plugin.incompatibleRancherVersion }}</p>
854
- <p
855
- v-else-if="plugin.incompatibleKubeVersion"
856
- class="incompatible"
857
- >{{ plugin.incompatibleKubeVersion }}</p>
865
+ >{{ plugin.incompatibilityMessage }}</p>
858
866
  </span>
859
867
  </div>
860
868
  <!-- plugin badges -->
package/pages/home.vue CHANGED
@@ -91,10 +91,6 @@ export default {
91
91
  ...mapGetters(['currentCluster', 'defaultClusterId', 'releaseNotesUrl']),
92
92
  mcm: mapFeature(MULTI_CLUSTER),
93
93
 
94
- mgmtClusters() {
95
- return this.$store.getters['management/all'](MANAGEMENT.CLUSTER);
96
- },
97
-
98
94
  provClusters() {
99
95
  return this.$store.getters['management/all'](CAPI.RANCHER_CLUSTER);
100
96
  },
@@ -211,15 +207,7 @@ export default {
211
207
  },
212
208
 
213
209
  kubeClusters() {
214
- const filteredClusters = filterHiddenLocalCluster(filterOnlyKubernetesClusters(this.provClusters || [], this.$store), this.$store);
215
-
216
- return filteredClusters.map((provCluster) => {
217
- const mgmtCluster = this.mgmtClusters?.find((c) => provCluster.mgmt?.id === c.id);
218
-
219
- provCluster.description = provCluster.description || mgmtCluster?.description;
220
-
221
- return provCluster;
222
- });
210
+ return filterHiddenLocalCluster(filterOnlyKubernetesClusters(this.provClusters || [], this.$store), this.$store);
223
211
  }
224
212
  },
225
213
 
@@ -419,7 +419,7 @@ export default {
419
419
  },
420
420
  result: {
421
421
  count: out.count,
422
- pages: out.pages,
422
+ pages: out.pages || Math.ceil(out.count / (opt.pagination.pageSize || Number.MAX_SAFE_INTEGER)),
423
423
  timestamp: new Date().getTime()
424
424
  }
425
425
  } : undefined,
@@ -429,7 +429,7 @@ export default {
429
429
  };
430
430
  }
431
431
 
432
- const namespaces = _typeObj?.namespaced ? Object.keys(rootGetters.activeNamespaceCache || {}) : [];
432
+ const namespaces = _typeObj?.namespaced && !rootGetters.isAllNamespaces ? Object.keys(rootGetters.activeNamespaceCache || {}) : [];
433
433
 
434
434
  return matchingCounts(_typeObj, namespaces.length ? namespaces : null);
435
435
  },
@@ -109,13 +109,13 @@ describe('steve: getters:', () => {
109
109
  it('returns a string with a labelSelector and filter, and formatted for steve if the url starts with "/v1"', () => {
110
110
  expect(urlOptionsGetter('/v1/foo', { labelSelector: 'a=b', filter: { bar: 'baz', far: 'faz' } })).toBe('/v1/foo?labelSelector=a=b&filter=bar=baz&far=faz&exclude=metadata.managedFields');
111
111
  });
112
- it('returns a string with an exclude statement for "bar" and "metadata.managedFields" if excludeFields is a single element array with the string "bar" and the url starts with "/v1/"', () => {
113
- expect(urlOptionsGetter('/v1/foo', { excludeFields: ['bar'] })).toBe('/v1/foo?exclude=bar&exclude=metadata.managedFields');
112
+ it('returns a string with an exclude statement for "bar" if excludeFields is a single element array with the string "bar" and the url starts with "/v1/"', () => {
113
+ expect(urlOptionsGetter('/v1/foo', { excludeFields: ['bar'] })).toBe('/v1/foo?exclude=bar');
114
114
  });
115
- it('returns a string without an exclude statement if excludeFields is but the url does not start with "/v1/"', () => {
116
- expect(urlOptionsGetter('foo', { excludeFields: ['bar'] })).toBe('foo');
115
+ it('returns a string without an exclude statement for "managedFields" if omitExcludeFields includes it and the url starts with "/v1/"', () => {
116
+ expect(urlOptionsGetter('/v1/foo', { omitExcludeFields: ['metadata.managedFields'] })).toBe('/v1/foo?');
117
117
  });
118
- it('returns a string without an exclude statement if excludeFields is an array but the URL doesn\'t include the "/v1/ string"', () => {
118
+ it('returns a string without an exclude statement if excludeFields is set but the url does not start with "/v1/"', () => {
119
119
  expect(urlOptionsGetter('foo', { excludeFields: ['bar'] })).toBe('foo');
120
120
  });
121
121
  it('returns a string with a limit applied if a limit is provided', () => {
@@ -119,11 +119,13 @@ export default {
119
119
  // excludeFields should be an array of strings representing the paths of the fields to exclude
120
120
  // only works on Steve but is ignored without error by Norman
121
121
  if (isSteve) {
122
- if (Array.isArray(opt?.excludeFields)) {
123
- opt.excludeFields = [...opt.excludeFields, 'metadata.managedFields'];
124
- } else {
125
- opt.excludeFields = ['metadata.managedFields'];
122
+ if (!Array.isArray(opt?.excludeFields)) {
123
+ const excludeFields = ['metadata.managedFields'];
124
+
125
+ // for some resources, we might want to include fields, excluded by default.
126
+ opt.excludeFields = Array.isArray(opt?.omitExcludeFields) ? excludeFields.filter((f) => !f.includes(opt.omitExcludeFields)) : excludeFields;
126
127
  }
128
+
127
129
  const excludeParamsString = opt.excludeFields.map((field) => `exclude=${ field }`).join('&');
128
130
 
129
131
  url += `${ url.includes('?') ? '&' : '?' }${ excludeParamsString }`;
@@ -1,4 +1,4 @@
1
- import { ANNOTATIONS_TO_IGNORE_REGEX, LABELS_TO_IGNORE_REGEX, DESCRIPTION } from '@shell/config/labels-annotations';
1
+ import { ANNOTATIONS_TO_IGNORE_REGEX, LABELS_TO_IGNORE_REGEX } from '@shell/config/labels-annotations';
2
2
  import omitBy from 'lodash/omitBy';
3
3
  import pickBy from 'lodash/pickBy';
4
4
  import Vue from 'vue';
@@ -100,8 +100,4 @@ export default class HybridModel extends Resource {
100
100
  get state() {
101
101
  return this.stateObj?.name || 'unknown';
102
102
  }
103
-
104
- get description() {
105
- return this.metadata?.annotations?.[DESCRIPTION] || this.spec?.description || this._description;
106
- }
107
103
  }
@@ -1,6 +1,6 @@
1
1
  annotations:
2
2
  catalog.cattle.io/certified: rancher # Any application we are adding as a helm chart
3
- catalog.cattle.io/kube-version: '>= 1.16.0-0 < 1.29.0-0'
3
+ catalog.cattle.io/kube-version: '>= 1.16.0-0'
4
4
  catalog.cattle.io/namespace: cattle-ui-plugin-system # Must prefix with cattle- and suffix with -system=
5
5
  catalog.cattle.io/os: linux
6
6
  catalog.cattle.io/permits-os: linux, windows
@@ -6,10 +6,15 @@ BASE_DIR="$(
6
6
  pwd
7
7
  )"
8
8
  SHELL_DIR=$BASE_DIR/shell/
9
- TMP_DIR=$BASE_DIR/tmp
10
- PUBLISH_ARGS="--no-git-tag-version --access public $PUBLISH_ARGS"
9
+ CREATORS_DIR=$BASE_DIR/creators/extension
11
10
  FORCE_PUBLISH_TO_NPM="false"
12
- DEFAULT_YARN_REGISTRY="https://registry.npmjs.org"
11
+ DEFAULT_NPM_REGISTRY="https://registry.npmjs.org"
12
+
13
+ # if TAG doesn't exist, we can exit as it's needed for any type of publish.
14
+ if [ -z "$TAG" ]; then
15
+ echo "You need to set the TAG variable first!"
16
+ exit 1
17
+ fi
13
18
 
14
19
  if [ ! -d "${BASE_DIR}/node_modules" ]; then
15
20
  echo "You need to run 'yarn install' first"
@@ -23,44 +28,25 @@ if [ "$1" == "--npm" ]; then
23
28
  fi
24
29
 
25
30
  if [ "$FORCE_PUBLISH_TO_NPM" == "true" ]; then
26
- export YARN_REGISTRY=$DEFAULT_YARN_REGISTRY
31
+ export NPM_REGISTRY=$DEFAULT_NPM_REGISTRY
27
32
  fi
28
33
 
29
- # We use the version from the shell package for the creator packages
30
- # Need to copy them to a temporary location, so we can patch the version number
31
- # before publishing
32
-
33
- # To set a token for NPM registry auth: `npm config set //registry.npmjs.org/:_authToken <TOKEN>``
34
-
35
- PKG_DIST=$BASE_DIR/dist-pkg/creators
36
- mkdir -p ${PKG_DIST}
37
- rm -rf ${PKG_DIST}/app
38
- rm -rf ${PKG_DIST}/pkg
39
- rm -rf ${PKG_DIST}/update
34
+ PUBLISH_ARGS="--no-git-tag-version --access public --registry $NPM_REGISTRY"
40
35
 
41
36
  pushd ${SHELL_DIR} >/dev/null
42
37
 
43
- PKG_VERSION=$(node -p "require('./package.json').version")
44
- popd >/dev/null
45
-
46
- echo "Publishing version: $PKG_VERSION"
47
-
48
- cp -R ${SHELL_DIR}/creators/app ${PKG_DIST}
49
- cp -R ${SHELL_DIR}/creators/pkg ${PKG_DIST}
50
- cp -R ${SHELL_DIR}/creators/update ${PKG_DIST}
51
-
52
- sed -i.bak -e "s/\"0.0.0/"\"$PKG_VERSION"/g" ${PKG_DIST}/app/package.json
53
- sed -i.bak -e "s/\"0.0.0/"\"$PKG_VERSION"/g" ${PKG_DIST}/pkg/package.json
54
- sed -i.bak -e "s/\"0.0.0/"\"$PKG_VERSION"/g" ${PKG_DIST}/update/package.json
55
-
56
- rm ${PKG_DIST}/app/package.json.bak
57
- rm ${PKG_DIST}/pkg/package.json.bak
58
- rm ${PKG_DIST}/update/package.json.bak
59
-
60
38
  function publish() {
61
39
  NAME=$1
62
40
  FOLDER=$2
63
41
 
42
+ # if we pass a third arg, that is the version number
43
+ # that we want to actually publish on NPM
44
+ # they should match with the package.json version stated
45
+ # because of the check in the "Check Tags Version Matching" step in the workflow
46
+ if [ -n "$3" ]; then
47
+ PKG_VERSION=$3
48
+ fi
49
+
64
50
  echo "Publishing ${NAME} from ${FOLDER}"
65
51
  pushd ${FOLDER} >/dev/null
66
52
 
@@ -71,25 +57,20 @@ function publish() {
71
57
  cp -R ${BASE_DIR}/pkg/rancher-components/src/components ./rancher-components/
72
58
  fi
73
59
 
74
- if [ "$NAME" == "Update" ]; then
75
- # Add files from the app and pkg creators to the update package
76
- mkdir -p ./app
77
- mkdir -p ./pkg
78
- cp -R ${BASE_DIR}/shell/creators/app/* ./app
79
- cp -R ${BASE_DIR}/shell/creators/pkg/* ./pkg
80
- # Remove index.ts from pkg files, as we don't want to replace that
81
- rm -f ./pkg/files/index.ts
82
-
83
- # Update the package.json for the app
84
- cd app
85
- node ${SCRIPT_DIR}/record-deps.js
86
- cd ..
60
+ # if the PKG_VERSION has a - it means it will be a pre-release of legacy-v2
61
+ if [[ $PKG_VERSION == *"-"* ]]; then
62
+ PUBLISH_ARGS="$PUBLISH_ARGS --tag legacy-v2-pre-release"
63
+ else
64
+ # If we need to release shell, we tag it as legacy-v2
65
+ PUBLISH_ARGS="$PUBLISH_ARGS --tag legacy-v2"
87
66
  fi
88
67
 
89
68
  # Make a note of dependency versions, if required
90
69
  node ${SCRIPT_DIR}/record-deps.js
91
70
 
92
- yarn publish . --new-version ${PKG_VERSION} ${PUBLISH_ARGS}
71
+ echo "Publishing to registry: $NPM_REGISTRY with args: $PUBLISH_ARGS"
72
+
73
+ npm publish ${PUBLISH_ARGS}
93
74
  RET=$?
94
75
 
95
76
  popd >/dev/null
@@ -100,15 +81,32 @@ function publish() {
100
81
  fi
101
82
  }
102
83
 
103
- # Generate the type definitions for the shell
104
- ${SCRIPT_DIR}/typegen.sh
105
-
106
- # Publish the packages - don't tag the git repo and don't auto-increment the version number
107
- publish "Shell" ${SHELL_DIR}
108
- publish "Application creator" ${PKG_DIST}/app/
109
- publish "Package creator" ${PKG_DIST}/pkg/
110
- publish "Update" ${PKG_DIST}/update/
84
+ echo "TAG ${TAG}"
85
+
86
+ # let's get the package name and version from the tag
87
+ PKG_NAME=$(sed 's/-pkg-v.*//' <<< "$TAG")
88
+ PKG_V=$(sed 's/.*-pkg-v//'<<< "$TAG")
111
89
 
112
- echo "Done"
90
+ echo "PKG_NAME ${PKG_NAME}"
91
+ echo "PKG_V ${PKG_V}"
113
92
 
93
+ # Generate the type definitions for the shell
94
+ if [ ${PKG_NAME} == "shell" ]; then
95
+ ${SCRIPT_DIR}/typegen.sh
96
+ fi
114
97
 
98
+ # version comparison checks
99
+ case $PKG_NAME in
100
+ "shell")
101
+ echo "Publishing only Shell pkg via tagged release"
102
+ publish "Shell" ${SHELL_DIR} ${PKG_V}
103
+ ;;
104
+ "creators")
105
+ echo "Publishing only Creators pkg via tagged release"
106
+ publish "Extension creator" ${CREATORS_DIR} ${PKG_V}
107
+ ;;
108
+ *)
109
+ echo "something went wrong with the tagging name => TAG: ${TAG} , PKG_NAME: ${PKG_NAME}. Admissable names are 'shell' and 'creator'"
110
+ exit 1
111
+ ;;
112
+ esac