@rancher/shell 0.1.3 → 0.1.4

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 (131) hide show
  1. package/assets/brand/suse/dark/rancher-logo.svg +1 -148
  2. package/assets/brand/suse/rancher-logo.svg +1 -130
  3. package/assets/images/featured/img1.jpg +0 -0
  4. package/assets/images/featured.jpg +0 -0
  5. package/assets/images/generic-plugin.svg +7 -0
  6. package/assets/styles/themes/_dark.scss +3 -0
  7. package/assets/styles/themes/_light.scss +3 -0
  8. package/assets/styles/themes/_suse.scss +1 -1
  9. package/assets/translations/en-us.yaml +183 -45
  10. package/assets/translations/zh-hans.yaml +21 -24
  11. package/components/AsyncButton.vue +17 -2
  12. package/components/ButtonDropdown.vue +4 -0
  13. package/components/Carousel.vue +291 -0
  14. package/components/CommunityLinks.vue +69 -18
  15. package/components/CruResource.vue +11 -3
  16. package/components/Dialog.vue +102 -0
  17. package/components/ExplorerMembers.vue +2 -4
  18. package/components/ExplorerProjectsNamespaces.vue +6 -7
  19. package/components/IconMessage.vue +9 -1
  20. package/components/LocaleSelector.vue +62 -29
  21. package/components/ResourceTable.vue +7 -2
  22. package/components/SimpleBox.vue +6 -4
  23. package/components/SortableTable/index.vue +11 -21
  24. package/components/Tabbed/Tab.vue +5 -0
  25. package/components/Tabbed/index.vue +29 -2
  26. package/components/auth/Principal.vue +1 -0
  27. package/components/fleet/FleetBundles.vue +8 -3
  28. package/components/fleet/FleetSummary.vue +6 -0
  29. package/components/form/KeyValue.vue +80 -58
  30. package/components/form/NameNsDescription.vue +10 -4
  31. package/components/form/ResourceTabs/index.vue +5 -1
  32. package/components/formatter/ClusterLink.vue +3 -7
  33. package/components/nav/NamespaceFilter.vue +3 -3
  34. package/components/nav/TopLevelMenu.vue +10 -28
  35. package/config/footer.js +13 -14
  36. package/config/labels-annotations.js +2 -1
  37. package/config/product/explorer.js +5 -4
  38. package/config/product/legacy.js +0 -47
  39. package/config/product/multi-cluster-apps.js +0 -12
  40. package/config/product/settings.js +12 -1
  41. package/config/product/uiplugins.js +17 -0
  42. package/config/settings.js +21 -2
  43. package/config/types.js +5 -1
  44. package/config/uiplugins.js +60 -0
  45. package/content/docs/en-us/getting-started.md +1 -26
  46. package/core/plugins.js +12 -0
  47. package/detail/provisioning.cattle.io.cluster.vue +3 -3
  48. package/detail/workload/index.vue +2 -2
  49. package/dialog/DiagnosticTimingsDialog.vue +116 -0
  50. package/dialog/RotateCertificatesDialog.vue +9 -3
  51. package/edit/auth/azuread.vue +28 -9
  52. package/edit/networking.k8s.io.ingress/index.vue +2 -2
  53. package/edit/persistentvolume/index.vue +3 -0
  54. package/edit/pod.vue +27 -0
  55. package/edit/provisioning.cattle.io.cluster/rke2.vue +76 -5
  56. package/edit/service.vue +7 -5
  57. package/edit/workload/__tests__/Upgrading.test.ts +1 -0
  58. package/edit/workload/index.vue +13 -1
  59. package/edit/workload/mixins/workload.js +13 -13
  60. package/edit/workload/storage/ContainerMountPaths.vue +240 -0
  61. package/edit/workload/storage/Mount.vue +1 -0
  62. package/edit/workload/storage/awsElasticBlockStore.vue +20 -1
  63. package/edit/workload/storage/azureDisk.vue +22 -2
  64. package/edit/workload/storage/azureFile.vue +20 -2
  65. package/edit/workload/storage/csi/index.vue +23 -1
  66. package/edit/workload/storage/gcePersistentDisk.vue +20 -2
  67. package/edit/workload/storage/index.vue +23 -49
  68. package/edit/workload/storage/vsphereVolume.vue +11 -1
  69. package/layouts/default.vue +14 -8
  70. package/layouts/home.vue +9 -4
  71. package/layouts/plain.vue +10 -5
  72. package/list/management.cattle.io.setting.vue +3 -3
  73. package/list/provisioning.cattle.io.cluster.vue +1 -1
  74. package/machine-config/harvester.vue +5 -3
  75. package/models/catalog.cattle.io.uiplugin.js +34 -0
  76. package/models/cluster/node.js +25 -2
  77. package/models/fleet.cattle.io.bundle.js +1 -1
  78. package/models/harvesterhci.io.management.cluster.js +11 -5
  79. package/models/provisioning.cattle.io.cluster.js +12 -6
  80. package/models/workload.js +5 -3
  81. package/nuxt.config.js +69 -25
  82. package/package.json +108 -109
  83. package/pages/auth/login.vue +1 -1
  84. package/pages/c/_cluster/apps/charts/index.vue +46 -1
  85. package/pages/c/_cluster/apps/charts/install.vue +10 -9
  86. package/pages/c/_cluster/explorer/index.vue +72 -9
  87. package/pages/c/_cluster/explorer/tools/index.vue +12 -5
  88. package/pages/c/_cluster/mcapps/index.vue +1 -1
  89. package/pages/c/_cluster/settings/brand.vue +0 -40
  90. package/pages/c/_cluster/settings/links.vue +200 -0
  91. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +232 -0
  92. package/pages/c/_cluster/uiplugins/InstallDialog.vue +242 -0
  93. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +284 -0
  94. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +130 -0
  95. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +253 -0
  96. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +115 -0
  97. package/pages/c/_cluster/uiplugins/index.vue +694 -0
  98. package/pages/diagnostic.vue +185 -101
  99. package/pages/docs/_doc.vue +3 -1
  100. package/pages/home.vue +21 -56
  101. package/pages/prefs.vue +108 -88
  102. package/pages/safeMode.vue +17 -0
  103. package/pages/support/index.vue +23 -15
  104. package/pkg/dynamic-importer.lib.js +4 -0
  105. package/plugins/dashboard-store/resource-class.js +2 -2
  106. package/plugins/formatters.js +15 -0
  107. package/plugins/plugin.js +56 -4
  108. package/plugins/steve/mutations.js +1 -1
  109. package/plugins/steve/subscribe.js +94 -72
  110. package/plugins/steve/web-worker.steve-sub-worker.js +24 -15
  111. package/promptRemove/management.cattle.io.globalrole.vue +47 -0
  112. package/promptRemove/management.cattle.io.roletemplate.vue +47 -0
  113. package/promptRemove/mixin/roleDeletionCheck.js +97 -0
  114. package/scripts/publish-shell.sh +1 -1
  115. package/scripts/sync-shell-deps +37 -0
  116. package/store/catalog.js +9 -8
  117. package/store/i18n.js +10 -1
  118. package/store/prefs.js +16 -0
  119. package/store/type-map.js +32 -5
  120. package/store/uiplugins.ts +15 -61
  121. package/utils/__tests__/object.test.ts +0 -24
  122. package/utils/__tests__/selector.test.ts +1 -1
  123. package/utils/dynamic-importer.js +4 -0
  124. package/utils/grafana.js +2 -6
  125. package/utils/socket.js +41 -20
  126. package/utils/string.js +1 -7
  127. package/utils/validators/formRules/__tests__/index.test.ts +108 -0
  128. package/utils/validators/formRules/index.ts +9 -1
  129. package/yarn-error.log +195 -0
  130. package/pages/plugins.vue +0 -387
  131. package/server/verdaccio-middleware.js +0 -56
package/layouts/home.vue CHANGED
@@ -3,7 +3,7 @@ import Header from '@shell/components/nav/Header';
3
3
  import Brand from '@shell/mixins/brand';
4
4
  import FixedBanner from '@shell/components/FixedBanner';
5
5
  import GrowlManager from '@shell/components/GrowlManager';
6
- import { mapPref, DEV } from '@shell/store/prefs';
6
+ import { mapPref, THEME_SHORTCUT } from '@shell/store/prefs';
7
7
  import AwsComplianceBanner from '@shell/components/AwsComplianceBanner';
8
8
  import AzureWarning from '@shell/components/auth/AzureWarning';
9
9
  import BrowserTabVisibility from '@shell/mixins/browser-tab-visibility';
@@ -26,12 +26,13 @@ export default {
26
26
  data() {
27
27
  return {
28
28
  // Assume home pages have routes where the name is the key to use for string lookup
29
- name: this.$route.name
29
+ name: this.$route.name,
30
+ noLocaleShortcut: process.env.dev || false
30
31
  };
31
32
  },
32
33
 
33
34
  computed: {
34
- dev: mapPref(DEV),
35
+ themeShortcut: mapPref(THEME_SHORTCUT),
35
36
  ...mapState(['managementReady']),
36
37
  },
37
38
 
@@ -39,6 +40,9 @@ export default {
39
40
  toggleTheme() {
40
41
  this.$store.dispatch('prefs/toggleTheme');
41
42
  },
43
+ toggleNoneLocale() {
44
+ this.$store.dispatch('i18n/toggleNone');
45
+ },
42
46
  }
43
47
 
44
48
  };
@@ -59,7 +63,8 @@ export default {
59
63
  </div>
60
64
  <FixedBanner :footer="true" />
61
65
  <GrowlManager />
62
- <button v-if="dev" v-shortkey.once="['shift','t']" class="hide" @shortkey="toggleTheme()" />
66
+ <button v-if="themeShortcut" v-shortkey.once="['shift','t']" class="hide" @shortkey="toggleTheme()" />
67
+ <button v-if="noLocaleShortcut" v-shortkey.once="['shift','l']" class="hide" @shortkey="toggleNoneLocale()" />
63
68
  </div>
64
69
  </template>
65
70
 
package/layouts/plain.vue CHANGED
@@ -1,5 +1,5 @@
1
1
  <script>
2
- import { mapPref, DEV } from '@shell/store/prefs';
2
+ import { mapPref, THEME_SHORTCUT } from '@shell/store/prefs';
3
3
  import ActionMenu from '@shell/components/ActionMenu';
4
4
  import Header from '@shell/components/nav/Header';
5
5
  import PromptRemove from '@shell/components/PromptRemove';
@@ -33,16 +33,20 @@ export default {
33
33
  data() {
34
34
  return {
35
35
  // Assume home pages have routes where the name is the key to use for string lookup
36
- name: this.$route.name,
36
+ name: this.$route.name,
37
+ noLocaleShortcut: process.env.dev || false,
37
38
  };
38
39
  },
39
40
 
40
- computed: { dev: mapPref(DEV) },
41
+ computed: { themeShortcut: mapPref(THEME_SHORTCUT) },
41
42
 
42
43
  methods: {
43
44
  toggleTheme() {
44
45
  this.$store.dispatch('prefs/toggleTheme');
45
- }
46
+ },
47
+ toggleNoneLocale() {
48
+ this.$store.dispatch('i18n/toggleNone');
49
+ },
46
50
  }
47
51
  };
48
52
  </script>
@@ -62,7 +66,8 @@ export default {
62
66
  <ActionMenu />
63
67
  <PromptRemove />
64
68
  <AssignTo />
65
- <button v-if="dev" v-shortkey.once="['shift','t']" class="hide" @shortkey="toggleTheme()" />
69
+ <button v-if="themeShortcut" v-shortkey.once="['shift','t']" class="hide" @shortkey="toggleTheme()" />
70
+ <button v-if="noLocaleShortcut" v-shortkey.once="['shift','l']" class="hide" @shortkey="toggleNoneLocale()" />
66
71
  </main>
67
72
  </div>
68
73
 
@@ -4,13 +4,13 @@ import { MANAGEMENT } from '@shell/config/types';
4
4
  import { ALLOWED_SETTINGS } from '@shell/config/settings';
5
5
  import { Banner } from '@components/Banner';
6
6
  import Loading from '@shell/components/Loading';
7
- import { DEV } from '@shell/store/prefs';
7
+ import { VIEW_IN_API } from '@shell/store/prefs';
8
8
 
9
9
  export default {
10
10
  components: { Banner, Loading },
11
11
 
12
12
  async fetch() {
13
- const isDev = this.$store.getters['prefs/get'](DEV);
13
+ const viewInApi = this.$store.getters['prefs/get'](VIEW_IN_API);
14
14
  const rows = await this.$store.dispatch(`management/findAll`, { type: MANAGEMENT.SETTING });
15
15
  const t = this.$store.getters['i18n/t'];
16
16
  // Map settings from array to object keyed by id
@@ -51,7 +51,7 @@ export default {
51
51
  }
52
52
  // There are only 2 actions that can be enabled - Edit Setting or View in API
53
53
  // If neither is available for this setting then we hide the action menu button
54
- s.hasActions = (!s.readOnly || isDev) && setting.availableActions?.length;
54
+ s.hasActions = (!s.readOnly || viewInApi) && setting.availableActions?.length;
55
55
  settings.push(s);
56
56
  }
57
57
 
@@ -149,7 +149,7 @@ export default {
149
149
  <template #cell:explorer="{row}">
150
150
  <span v-if="row.mgmt && row.mgmt.isHarvester"></span>
151
151
  <n-link
152
- v-else-if="row.mgmt && row.mgmt.isReady"
152
+ v-else-if="row.mgmt && row.mgmt.isReady && !row.hasError"
153
153
  data-testid="cluster-manager-list-explore-management"
154
154
  class="btn btn-sm role-secondary"
155
155
  :to="{name: 'c-cluster', params: {cluster: row.mgmt.id}}"
@@ -170,8 +170,10 @@ export default {
170
170
  };
171
171
  });
172
172
 
173
- (res.namespaces.value.data || []).forEach((namespace) => {
174
- if (!namespace.isSystem) {
173
+ (res.namespaces.value.data || []).forEach(async(namespace) => {
174
+ const proxyNamespace = await this.$store.dispatch('cluster/create', namespace);
175
+
176
+ if (!proxyNamespace.isSystem && namespace.links.update) {
175
177
  const value = namespace.metadata.name;
176
178
  const label = namespace.metadata.name;
177
179
 
@@ -519,7 +521,7 @@ export default {
519
521
  :options="imageOptions"
520
522
  :required="true"
521
523
  :searchable="true"
522
- :disabled="disabledEdit"
524
+ :disabled="disabled"
523
525
  label-key="cluster.credential.harvester.image"
524
526
  :placeholder="t('cluster.harvester.machinePool.image.placeholder')"
525
527
  @on-open="onOpen"
@@ -0,0 +1,34 @@
1
+ import SteveModel from '@shell/plugins/steve/steve-class';
2
+
3
+ const CACHED_STATUS = 'cached';
4
+
5
+ export default class UIPlugin extends SteveModel {
6
+ get name() {
7
+ return this.spec?.plugin?.name;
8
+ }
9
+
10
+ get description() {
11
+ return this.spec?.plugin?.description;
12
+ }
13
+
14
+ get version() {
15
+ return this.spec?.plugin?.version;
16
+ }
17
+
18
+ get willBeCached() {
19
+ return this.spec?.plugin?.noCache === false;
20
+ }
21
+
22
+ // Has the plugin been cached?
23
+ get isCached() {
24
+ return !this.willBeCached || (this.willBeCached && this.status?.cacheState === CACHED_STATUS);
25
+ }
26
+
27
+ get pluginMetadata() {
28
+ return this.spec?.plugin?.metadata || {};
29
+ }
30
+
31
+ get isDeveloper() {
32
+ return this.pluginMetadata?.developer === 'true';
33
+ }
34
+ }
@@ -153,6 +153,14 @@ export default class ClusterNode extends SteveModel {
153
153
  }
154
154
 
155
155
  get cpuUsage() {
156
+ /*
157
+ With EKS nodes that have been migrated from norman,
158
+ cpu/memory usage is by the annotation `management.cattle.io/pod-requests`
159
+ */
160
+ if ( this.isFromNorman && this.provider === 'eks' ) {
161
+ return parseSi(this.podRequests.cpu || '0');
162
+ }
163
+
156
164
  return parseSi(this.$rootGetters['cluster/byId'](METRIC.NODE, this.id)?.usage?.cpu || '0');
157
165
  }
158
166
 
@@ -165,6 +173,10 @@ export default class ClusterNode extends SteveModel {
165
173
  }
166
174
 
167
175
  get ramUsage() {
176
+ if ( this.isFromNorman && this.provider === 'eks' ) {
177
+ return parseSi(this.podRequests.memory || '0');
178
+ }
179
+
168
180
  return parseSi(this.$rootGetters['cluster/byId'](METRIC.NODE, this.id)?.usage?.memory || '0');
169
181
  }
170
182
 
@@ -192,6 +204,10 @@ export default class ClusterNode extends SteveModel {
192
204
  return this.pods.length;
193
205
  }
194
206
 
207
+ get podRequests() {
208
+ return JSON.parse(this.metadata.annotations['management.cattle.io/pod-requests'] || '{}');
209
+ }
210
+
195
211
  get isPidPressureOk() {
196
212
  return this.isCondition('PIDPressure', 'False');
197
213
  }
@@ -368,14 +384,13 @@ export default class ClusterNode extends SteveModel {
368
384
  }
369
385
 
370
386
  get canDelete() {
371
- const provider = this.$rootGetters['currentCluster'].provisioner.toLowerCase();
372
387
  const cloudProviders = [
373
388
  'aks', 'azureaks', 'azurekubernetesservice',
374
389
  'eks', 'amazoneks',
375
390
  'gke', 'googlegke'
376
391
  ];
377
392
 
378
- return !cloudProviders.includes(provider);
393
+ return !cloudProviders.includes(this.provider);
379
394
  }
380
395
 
381
396
  // You need to preload CAPI.MACHINEs to use this
@@ -389,6 +404,14 @@ export default class ClusterNode extends SteveModel {
389
404
 
390
405
  return null;
391
406
  }
407
+
408
+ get isFromNorman() {
409
+ return (this.$rootGetters['currentCluster'].metadata.labels || {})['cattle.io/creator'] === 'norman';
410
+ }
411
+
412
+ get provider() {
413
+ return this.$rootGetters['currentCluster'].provisioner.toLowerCase();
414
+ }
392
415
  }
393
416
 
394
417
  function calculatePercentage(allocatable, capacity) {
@@ -18,7 +18,7 @@ export default class FleetBundle extends SteveModel {
18
18
  }
19
19
 
20
20
  get lastUpdateTime() {
21
- return this.status.conditions[0].lastUpdateTime;
21
+ return this.status?.conditions?.[0].lastUpdateTime;
22
22
  }
23
23
 
24
24
  get bundleType() {
@@ -79,11 +79,11 @@ export default class HciCluster extends ProvCluster {
79
79
  const pkgName = `${ HARVESTER_NAME }-1.0.3`;
80
80
 
81
81
  if (uiOfflinePreferred === 'true') {
82
- // Embedded (aka give me the version of the embedded plugin that was in the last release)
83
- const embeddedPath = `dashboard/${ pkgName }/${ pkgName }.umd.min.js`;
82
+ // Embedded (aka give me the embedded plugin that was in the last rancher release)
83
+ const embeddedPath = `${ pkgName }/${ pkgName }.umd.min.js`;
84
84
 
85
85
  return {
86
- pkgUrl: process.env.dev ? `${ process.env.api }/${ embeddedPath }` : embeddedPath,
86
+ pkgUrl: process.env.dev ? `${ process.env.api }/dashboard/${ embeddedPath }` : embeddedPath,
87
87
  pkgName
88
88
  };
89
89
  }
@@ -111,15 +111,21 @@ export default class HciCluster extends ProvCluster {
111
111
  * Determine the harvester plugin's package name and url for clusters that provide the plugin
112
112
  */
113
113
  _supportedClusterPkgDetails(uiInfo, clusterId) {
114
- const pkgName = `${ HARVESTER_NAME }-${ uiInfo['ui-plugin-bundled-version'] }`;
114
+ let pkgName = `${ HARVESTER_NAME }-${ uiInfo['ui-plugin-bundled-version'] }`;
115
115
  const fileName = `${ pkgName }.umd.min.js`;
116
116
  let pkgUrl;
117
117
 
118
118
  if (uiInfo['ui-source'] === 'bundled' ) { // offline bundled
119
- pkgUrl = `k8s/clusters/${ clusterId }/v1/harvester/plugin-assets/${ fileName }`;
119
+ pkgUrl = `/k8s/clusters/${ clusterId }/v1/harvester/plugin-assets/${ fileName }`;
120
120
  } else if (uiInfo['ui-source'] === 'external') {
121
121
  if (uiInfo['ui-plugin-index']) {
122
122
  pkgUrl = uiInfo['ui-plugin-index'];
123
+
124
+ // When using an external address, the pkgName should also be get from the url
125
+ const names = pkgUrl.split('/');
126
+ const jsName = names[names.length - 1];
127
+
128
+ pkgName = jsName?.split('.umd.min.js')[0];
123
129
  } else {
124
130
  throw new Error('Harvester cluster requested the plugin at `ui-plugin-index` is used, however did not provide a value for it');
125
131
  }
@@ -197,12 +197,10 @@ export default class ProvCluster extends SteveModel {
197
197
  return super.canEditYaml;
198
198
  }
199
199
 
200
- get isAKS() {
201
- return this.provisioner === 'AKS';
202
- }
200
+ get isHostedKubernetesProvider() {
201
+ const providers = ['AKS', 'EKS', 'GKE'];
203
202
 
204
- get isEKS() {
205
- return this.provisioner === 'EKS';
203
+ return providers.includes(this.provisioner);
206
204
  }
207
205
 
208
206
  get isImported() {
@@ -230,13 +228,17 @@ export default class ProvCluster extends SteveModel {
230
228
  get isImportedK3s() {
231
229
  // As of Rancher v2.6.7, this returns false for imported K3s clusters,
232
230
  // in which this.provisioner is `k3s`.
233
- return this.isImported && this.mgmt?.status?.provider === 'k3s';
231
+ return this.isImported && this.isK3s;
234
232
  }
235
233
 
236
234
  get isImportedRke2() {
237
235
  return this.isImported && this.mgmt?.status?.provider?.startsWith('rke2');
238
236
  }
239
237
 
238
+ get isK3s() {
239
+ return this.mgmt?.status?.provider === 'k3s';
240
+ }
241
+
240
242
  get isRke2() {
241
243
  return !!this.spec?.rkeConfig;
242
244
  }
@@ -764,4 +766,8 @@ export default class ProvCluster extends SteveModel {
764
766
  await this.$dispatch('ws.resource.remove', { data: this });
765
767
  }
766
768
  }
769
+
770
+ get hasError() {
771
+ return this.status?.conditions?.some(condition => condition.error === true);
772
+ }
767
773
  }
@@ -218,7 +218,7 @@ export default class Workload extends WorkloadService {
218
218
  path: 'metadata.name',
219
219
  required: true,
220
220
  translationKey: 'generic.name',
221
- type: 'dnsLabel',
221
+ type: 'subDomain',
222
222
  },
223
223
  {
224
224
  nullable: false,
@@ -405,7 +405,7 @@ export default class Workload extends WorkloadService {
405
405
  case WORKLOAD_TYPES.CRON_JOB:
406
406
  out.push(detailItem.endpoint);
407
407
  break;
408
- case WORKLOAD_TYPES.POD:
408
+ case POD:
409
409
  out.push(detailItem.ready);
410
410
  break;
411
411
  default: break;
@@ -612,8 +612,10 @@ export default class Workload extends WorkloadService {
612
612
 
613
613
  async matchingPods() {
614
614
  const all = await this.$dispatch('findAll', { type: POD });
615
+ const allInNamespace = all.filter(pod => pod.metadata.namespace === this.metadata.namespace);
616
+
615
617
  const selector = convertSelectorObj(this.spec.selector);
616
618
 
617
- return matching(all, selector);
619
+ return matching(allInNamespace, selector);
618
620
  }
619
621
  }
package/nuxt.config.js CHANGED
@@ -185,8 +185,6 @@ export default function(dir, _appConfig) {
185
185
 
186
186
  // Serve up the dist-pkg folder under /pkg
187
187
  serverMiddleware.push({ path: `/pkg/`, handler: serveStatic(`${ dir }/dist-pkg/`) });
188
- // Endpoint to download and unpack a tgz from the local verdaccio rgistry (dev)
189
- serverMiddleware.push(path.resolve(dir, SHELL, 'server', 'verdaccio-middleware'));
190
188
  // Add the standard dashboard server middleware after the middleware added to serve up UI packages
191
189
  serverMiddleware.push(path.resolve(dir, SHELL, 'server', 'server-middleware'));
192
190
 
@@ -202,6 +200,8 @@ export default function(dir, _appConfig) {
202
200
  process.env.DRONE_VERSION ||
203
201
  require('./package.json').version;
204
202
 
203
+ const prime = process.env.PRIME;
204
+
205
205
  const dev = (process.env.NODE_ENV !== 'production');
206
206
  const devPorts = dev || process.env.DEV_PORTS === 'true';
207
207
  const pl = process.env.PL || STANDARD;
@@ -496,7 +496,8 @@ export default function(dir, _appConfig) {
496
496
  plugins: [
497
497
  // TODO: Browser support
498
498
  // ['@babel/plugin-transform-modules-commonjs'],
499
- ['@babel/plugin-proposal-private-property-in-object', { loose: true }]
499
+ ['@babel/plugin-proposal-private-property-in-object', { loose: true }],
500
+ 'babel-plugin-istanbul'
500
501
  ],
501
502
  }
502
503
  },
@@ -554,7 +555,7 @@ export default function(dir, _appConfig) {
554
555
  plugins: [
555
556
  // Extensions
556
557
  path.relative(dir, path.join(SHELL, 'core/plugins.js')),
557
- path.relative(dir, path.join(SHELL, 'core/plugins-loader.js')),
558
+ path.relative(dir, path.join(SHELL, 'core/plugins-loader.js')), // Load builtin plugins
558
559
 
559
560
  // Third-party
560
561
  path.join(NUXT_SHELL, 'plugins/axios'),
@@ -578,33 +579,33 @@ export default function(dir, _appConfig) {
578
579
  { src: path.join(NUXT_SHELL, 'plugins/nuxt-client-init'), ssr: false },
579
580
  path.join(NUXT_SHELL, 'plugins/replaceall'),
580
581
  path.join(NUXT_SHELL, 'plugins/back-button'),
581
- { src: path.join(NUXT_SHELL, 'plugins/plugin'), ssr: false },
582
+ { src: path.join(NUXT_SHELL, 'plugins/plugin'), ssr: false }, // Load dyanmic plugins
582
583
  { src: path.join(NUXT_SHELL, 'plugins/codemirror-loader'), ssr: false },
584
+ { src: path.join(NUXT_SHELL, 'plugins/formatters'), ssr: false }, // Populate formatters cache for sorted table
583
585
  ],
584
586
 
585
587
  // Proxy: https://github.com/nuxt-community/proxy-module#options
586
588
  proxy: {
587
- '/k8s': proxyWsOpts(api), // Straight to a remote cluster (/k8s/clusters/<id>/)
588
- '/pp': proxyWsOpts(api), // For (epinio) standalone API
589
- '/api': proxyWsOpts(api), // Management k8s API
590
- '/apis': proxyWsOpts(api), // Management k8s API
591
- '/v1': proxyWsOpts(api), // Management Steve API
592
- '/v3': proxyWsOpts(api), // Rancher API
593
- '/v3-public': proxyOpts(api), // Rancher Unauthed API
594
- '/api-ui': proxyOpts(api), // Browser API UI
595
- '/meta': proxyMetaOpts(api), // Browser API UI
596
- '/v1-*': proxyOpts(api), // SAML, KDM, etc
589
+ '/k8s': proxyWsOpts(api), // Straight to a remote cluster (/k8s/clusters/<id>/)
590
+ '/pp': proxyWsOpts(api), // For (epinio) standalone API
591
+ '/api': proxyWsOpts(api), // Management k8s API
592
+ '/apis': proxyWsOpts(api), // Management k8s API
593
+ '/v1': proxyWsOpts(api), // Management Steve API
594
+ '/v3': proxyWsOpts(api), // Rancher API
595
+ '/v3-public': proxyOpts(api), // Rancher Unauthed API
596
+ '/api-ui': proxyOpts(api), // Browser API UI
597
+ '/meta': proxyMetaOpts(api), // Browser API UI
598
+ '/rancherversion': proxyPrimeOpts(api), // Rancher version endpoint
599
+ '/v1-*': proxyOpts(api), // SAML, KDM, etc
597
600
  // These are for Ember embedding
598
- '/c/*/edit': proxyOpts('https://127.0.0.1:8000'), // Can't proxy all of /c because that's used by Vue too
599
- '/k/': proxyOpts('https://127.0.0.1:8000'),
600
- '/g/': proxyOpts('https://127.0.0.1:8000'),
601
- '/n/': proxyOpts('https://127.0.0.1:8000'),
602
- '/p/': proxyOpts('https://127.0.0.1:8000'),
603
- '/assets': proxyOpts('https://127.0.0.1:8000'),
604
- '/translations': proxyOpts('https://127.0.0.1:8000'),
605
- '/engines-dist': proxyOpts('https://127.0.0.1:8000'),
606
- // Plugin dev
607
- '/verdaccio/': proxyOpts('http://127.0.0.1:4873/-'),
601
+ '/c/*/edit': proxyOpts('https://127.0.0.1:8000'), // Can't proxy all of /c because that's used by Vue too
602
+ '/k/': proxyOpts('https://127.0.0.1:8000'),
603
+ '/g/': proxyOpts('https://127.0.0.1:8000'),
604
+ '/n/': proxyOpts('https://127.0.0.1:8000'),
605
+ '/p/': proxyOpts('https://127.0.0.1:8000'),
606
+ '/assets': proxyOpts('https://127.0.0.1:8000'),
607
+ '/translations': proxyOpts('https://127.0.0.1:8000'),
608
+ '/engines-dist': proxyOpts('https://127.0.0.1:8000'),
608
609
  },
609
610
 
610
611
  // Nuxt server
@@ -663,6 +664,49 @@ export default function(dir, _appConfig) {
663
664
  };
664
665
  }
665
666
 
667
+ // Intercept the /rancherversion API call wnad modify the 'RancherPrime' value
668
+ // if configured to do so by the environment variable PRIME
669
+ function proxyPrimeOpts(target) {
670
+ const opts = proxyOpts(target);
671
+
672
+ // Don't intercept if the PRIME environment variable is not set
673
+ if (!prime?.length) {
674
+ return opts;
675
+ }
676
+
677
+ opts.onProxyRes = (proxyRes, req, res) => {
678
+ const _end = res.end;
679
+ let body = '';
680
+
681
+ proxyRes.on( 'data', (data) => {
682
+ data = data.toString('utf-8');
683
+ body += data;
684
+ });
685
+
686
+ res.write = () => {};
687
+
688
+ res.end = () => {
689
+ let output = body;
690
+
691
+ try {
692
+ const out = JSON.parse(body);
693
+
694
+ out.RancherPrime = prime;
695
+ output = JSON.stringify(out);
696
+ } catch (err) {}
697
+
698
+ res.setHeader('content-length', output.length );
699
+ res.setHeader('content-type', 'application/json' );
700
+ res.setHeader('transfer-encoding', '');
701
+ res.setHeader('cache-control', 'no-cache');
702
+ res.writeHead(proxyRes.statusCode);
703
+ _end.apply(res, [output]);
704
+ };
705
+ };
706
+
707
+ return opts;
708
+ }
709
+
666
710
  function onProxyRes(proxyRes, req, res) {
667
711
  if (devPorts) {
668
712
  proxyRes.headers['X-Frame-Options'] = 'ALLOWALL';