@rancher/shell 0.1.21 → 0.2.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 (99) hide show
  1. package/assets/styles/global/_button.scss +1 -0
  2. package/assets/translations/en-us.yaml +56 -10
  3. package/assets/translations/zh-hans.yaml +346 -117
  4. package/components/Carousel.vue +25 -9
  5. package/components/HarvesterServiceAddOnConfig.vue +10 -10
  6. package/components/Import.vue +7 -1
  7. package/components/ResourceList/index.vue +34 -14
  8. package/components/ResourceTable.vue +19 -0
  9. package/components/SortableTable/THead.vue +311 -70
  10. package/components/SortableTable/advanced-filtering.js +272 -0
  11. package/components/SortableTable/filtering.js +90 -29
  12. package/components/SortableTable/index.vue +480 -271
  13. package/components/form/MatchExpressions.vue +15 -3
  14. package/components/form/WorkloadPorts.vue +2 -2
  15. package/components/nav/Header.vue +14 -1
  16. package/config/product/settings.js +1 -0
  17. package/config/product/uiplugins.js +1 -0
  18. package/config/uiplugins.js +13 -0
  19. package/creators/app/init +2 -2
  20. package/creators/app/package.json +1 -1
  21. package/creators/pkg/package.json +1 -1
  22. package/detail/cis.cattle.io.clusterscan.vue +6 -2
  23. package/detail/provisioning.cattle.io.cluster.vue +3 -3
  24. package/edit/provisioning.cattle.io.cluster/DrainOptions.vue +0 -1
  25. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +5 -3
  26. package/edit/provisioning.cattle.io.cluster/rke2.vue +25 -24
  27. package/edit/service.vue +1 -1
  28. package/list/node.vue +7 -2
  29. package/mixins/resource-manager.js +5 -0
  30. package/models/cluster.x-k8s.io.machinedeployment.js +8 -0
  31. package/models/management.cattle.io.cluster.js +14 -1
  32. package/nuxt.config.js +113 -108
  33. package/package.json +1 -1
  34. package/pages/c/_cluster/apps/charts/index.vue +1 -1
  35. package/pages/c/_cluster/apps/charts/install.vue +106 -32
  36. package/pages/c/_cluster/settings/performance.vue +11 -0
  37. package/pages/c/_cluster/uiplugins/InstallDialog.vue +16 -2
  38. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +5 -2
  39. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +28 -6
  40. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +1 -1
  41. package/pages/c/_cluster/uiplugins/index.vue +49 -12
  42. package/promptRemove/mixin/roleDeletionCheck.js +15 -1
  43. package/scripts/record-deps.js +3 -3
  44. package/scripts/test-plugins-build.sh +1 -0
  45. package/scripts/typegen.sh +2 -2
  46. package/store/type-map.js +13 -2
  47. package/types/vue-shim.d +20 -0
  48. package/utils/create-yaml.js +30 -6
  49. package/creators/update/yarn-error.log +0 -54
  50. package/rancher-components/BadgeState/BadgeState.spec.ts +0 -12
  51. package/rancher-components/BadgeState/BadgeState.vue +0 -107
  52. package/rancher-components/BadgeState/index.ts +0 -1
  53. package/rancher-components/Banner/Banner.test.ts +0 -13
  54. package/rancher-components/Banner/Banner.vue +0 -163
  55. package/rancher-components/Banner/index.ts +0 -1
  56. package/rancher-components/Card/Card.vue +0 -150
  57. package/rancher-components/Card/index.ts +0 -1
  58. package/rancher-components/Form/Checkbox/Checkbox.test.ts +0 -77
  59. package/rancher-components/Form/Checkbox/Checkbox.vue +0 -395
  60. package/rancher-components/Form/Checkbox/index.ts +0 -1
  61. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +0 -29
  62. package/rancher-components/Form/LabeledInput/LabeledInput.vue +0 -343
  63. package/rancher-components/Form/LabeledInput/index.ts +0 -1
  64. package/rancher-components/Form/Radio/RadioButton.vue +0 -270
  65. package/rancher-components/Form/Radio/RadioGroup.vue +0 -235
  66. package/rancher-components/Form/Radio/index.ts +0 -2
  67. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +0 -168
  68. package/rancher-components/Form/TextArea/index.ts +0 -1
  69. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +0 -107
  70. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +0 -137
  71. package/rancher-components/Form/ToggleSwitch/index.ts +0 -1
  72. package/rancher-components/Form/index.ts +0 -5
  73. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +0 -137
  74. package/rancher-components/LabeledTooltip/index.ts +0 -1
  75. package/rancher-components/components/BadgeState/BadgeState.spec.ts +0 -12
  76. package/rancher-components/components/BadgeState/BadgeState.vue +0 -107
  77. package/rancher-components/components/BadgeState/index.ts +0 -1
  78. package/rancher-components/components/Banner/Banner.test.ts +0 -13
  79. package/rancher-components/components/Banner/Banner.vue +0 -163
  80. package/rancher-components/components/Banner/index.ts +0 -1
  81. package/rancher-components/components/Card/Card.vue +0 -150
  82. package/rancher-components/components/Card/index.ts +0 -1
  83. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +0 -77
  84. package/rancher-components/components/Form/Checkbox/Checkbox.vue +0 -395
  85. package/rancher-components/components/Form/Checkbox/index.ts +0 -1
  86. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +0 -29
  87. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +0 -343
  88. package/rancher-components/components/Form/LabeledInput/index.ts +0 -1
  89. package/rancher-components/components/Form/Radio/RadioButton.vue +0 -270
  90. package/rancher-components/components/Form/Radio/RadioGroup.vue +0 -235
  91. package/rancher-components/components/Form/Radio/index.ts +0 -2
  92. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +0 -168
  93. package/rancher-components/components/Form/TextArea/index.ts +0 -1
  94. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +0 -107
  95. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +0 -137
  96. package/rancher-components/components/Form/ToggleSwitch/index.ts +0 -1
  97. package/rancher-components/components/Form/index.ts +0 -5
  98. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -137
  99. package/rancher-components/components/LabeledTooltip/index.ts +0 -1
package/nuxt.config.js CHANGED
@@ -10,6 +10,29 @@ import { trimWhitespaceSsr as trimWhitespace } from './plugins/trim-whitespace';
10
10
 
11
11
  const createProxyMiddleware = require('http-proxy-middleware');
12
12
 
13
+ // Global variables
14
+ let api = process.env.API || 'http://localhost:8989';
15
+
16
+ if ( !api.startsWith('http') ) {
17
+ api = `https://${ api }`;
18
+ }
19
+
20
+ // needed for proxies
21
+ export const API_PATH = api;
22
+
23
+ const dev = (process.env.NODE_ENV !== 'production');
24
+ const devPorts = dev || process.env.DEV_PORTS === 'true';
25
+ const version = process.env.VERSION ||
26
+ process.env.DRONE_TAG ||
27
+ process.env.DRONE_VERSION ||
28
+ require('./package.json').version;
29
+
30
+ const prime = process.env.PRIME;
31
+
32
+ const pl = process.env.PL || STANDARD;
33
+ const commit = process.env.COMMIT || 'head';
34
+ const perfTest = (process.env.PERF_TEST === 'true'); // Enable performance testing when in dev
35
+
13
36
  // ===============================================================================================
14
37
  // Nuxt configuration
15
38
  // ===============================================================================================
@@ -195,25 +218,6 @@ export default function(dir, _appConfig) {
195
218
  require('events').EventEmitter.defaultMaxListeners = 20;
196
219
  require('dotenv').config();
197
220
 
198
- const version = process.env.VERSION ||
199
- process.env.DRONE_TAG ||
200
- process.env.DRONE_VERSION ||
201
- require('./package.json').version;
202
-
203
- const prime = process.env.PRIME;
204
-
205
- const dev = (process.env.NODE_ENV !== 'production');
206
- const devPorts = dev || process.env.DEV_PORTS === 'true';
207
- const pl = process.env.PL || STANDARD;
208
- const commit = process.env.COMMIT || 'head';
209
- const perfTest = (process.env.PERF_TEST === 'true'); // Enable performance testing when in dev
210
-
211
- let api = process.env.API || 'http://localhost:8989';
212
-
213
- if ( !api.startsWith('http') ) {
214
- api = `https://${ api }`;
215
- }
216
-
217
221
  let routerBasePath = '/';
218
222
  let resourceBase = '';
219
223
  let outputDir = 'dist';
@@ -587,6 +591,7 @@ export default function(dir, _appConfig) {
587
591
 
588
592
  // Proxy: https://github.com/nuxt-community/proxy-module#options
589
593
  proxy: {
594
+ ...appConfig.proxies,
590
595
  '/k8s': proxyWsOpts(api), // Straight to a remote cluster (/k8s/clusters/<id>/)
591
596
  '/pp': proxyWsOpts(api), // For (epinio) standalone API
592
597
  '/api': proxyWsOpts(api), // Management k8s API
@@ -637,114 +642,114 @@ export default function(dir, _appConfig) {
637
642
  };
638
643
 
639
644
  return config;
645
+ }
640
646
 
641
- // ===============================================================================================
642
- // Functions for the request proxying used in dev
643
- // ===============================================================================================
644
-
645
- function proxyMetaOpts(target) {
646
- return {
647
- target,
648
- followRedirects: true,
649
- secure: !dev,
650
- onProxyReq,
651
- onProxyReqWs,
652
- onError,
653
- onProxyRes,
654
- };
655
- }
656
-
657
- function proxyOpts(target) {
658
- return {
659
- target,
660
- secure: !devPorts,
661
- onProxyReq,
662
- onProxyReqWs,
663
- onError,
664
- onProxyRes,
665
- };
666
- }
647
+ // ===============================================================================================
648
+ // Functions for the request proxying used in dev
649
+ // ===============================================================================================
667
650
 
668
- // Intercept the /rancherversion API call wnad modify the 'RancherPrime' value
669
- // if configured to do so by the environment variable PRIME
670
- function proxyPrimeOpts(target) {
671
- const opts = proxyOpts(target);
651
+ export function proxyMetaOpts(target) {
652
+ return {
653
+ target,
654
+ followRedirects: true,
655
+ secure: !dev,
656
+ onProxyReq,
657
+ onProxyReqWs,
658
+ onError,
659
+ onProxyRes,
660
+ };
661
+ }
672
662
 
673
- // Don't intercept if the PRIME environment variable is not set
674
- if (!prime?.length) {
675
- return opts;
676
- }
663
+ export function proxyOpts(target) {
664
+ return {
665
+ target,
666
+ secure: !devPorts,
667
+ onProxyReq,
668
+ onProxyReqWs,
669
+ onError,
670
+ onProxyRes,
671
+ };
672
+ }
677
673
 
678
- opts.onProxyRes = (proxyRes, req, res) => {
679
- const _end = res.end;
680
- let body = '';
674
+ // Intercept the /rancherversion API call wnad modify the 'RancherPrime' value
675
+ // if configured to do so by the environment variable PRIME
676
+ export function proxyPrimeOpts(target) {
677
+ const opts = proxyOpts(target);
681
678
 
682
- proxyRes.on( 'data', (data) => {
683
- data = data.toString('utf-8');
684
- body += data;
685
- });
679
+ // Don't intercept if the PRIME environment variable is not set
680
+ if (!prime?.length) {
681
+ return opts;
682
+ }
686
683
 
687
- res.write = () => {};
684
+ opts.onProxyRes = (proxyRes, req, res) => {
685
+ const _end = res.end;
686
+ let body = '';
688
687
 
689
- res.end = () => {
690
- let output = body;
688
+ proxyRes.on( 'data', (data) => {
689
+ data = data.toString('utf-8');
690
+ body += data;
691
+ });
691
692
 
692
- try {
693
- const out = JSON.parse(body);
693
+ res.write = () => {};
694
694
 
695
- out.RancherPrime = prime;
696
- output = JSON.stringify(out);
697
- } catch (err) {}
695
+ res.end = () => {
696
+ let output = body;
698
697
 
699
- res.setHeader('content-length', output.length );
700
- res.setHeader('content-type', 'application/json' );
701
- res.setHeader('transfer-encoding', '');
702
- res.setHeader('cache-control', 'no-cache');
703
- res.writeHead(proxyRes.statusCode);
704
- _end.apply(res, [output]);
705
- };
698
+ try {
699
+ const out = JSON.parse(body);
700
+
701
+ out.RancherPrime = prime;
702
+ output = JSON.stringify(out);
703
+ } catch (err) {}
704
+
705
+ res.setHeader('content-length', output.length );
706
+ res.setHeader('content-type', 'application/json' );
707
+ res.setHeader('transfer-encoding', '');
708
+ res.setHeader('cache-control', 'no-cache');
709
+ res.writeHead(proxyRes.statusCode);
710
+ _end.apply(res, [output]);
706
711
  };
712
+ };
707
713
 
708
- return opts;
709
- }
710
-
711
- function onProxyRes(proxyRes, req, res) {
712
- if (devPorts) {
713
- proxyRes.headers['X-Frame-Options'] = 'ALLOWALL';
714
- }
715
- }
714
+ return opts;
715
+ }
716
716
 
717
- function proxyWsOpts(target) {
718
- return {
719
- ...proxyOpts(target),
720
- ws: true,
721
- changeOrigin: true,
722
- };
717
+ export function onProxyRes(proxyRes, req, res) {
718
+ if (devPorts) {
719
+ proxyRes.headers['X-Frame-Options'] = 'ALLOWALL';
723
720
  }
721
+ }
724
722
 
725
- function onProxyReq(proxyReq, req) {
726
- if (!(proxyReq._currentRequest && proxyReq._currentRequest._headerSent)) {
727
- proxyReq.setHeader('x-api-host', req.headers['host']);
728
- proxyReq.setHeader('x-forwarded-proto', 'https');
729
- // console.log(proxyReq.getHeaders());
730
- }
731
- }
723
+ export function proxyWsOpts(target) {
724
+ return {
725
+ ...proxyOpts(target),
726
+ ws: true,
727
+ changeOrigin: true,
728
+ };
729
+ }
732
730
 
733
- function onProxyReqWs(proxyReq, req, socket, options, head) {
734
- req.headers.origin = options.target.href;
735
- proxyReq.setHeader('origin', options.target.href);
731
+ export function onProxyReq(proxyReq, req) {
732
+ if (!(proxyReq._currentRequest && proxyReq._currentRequest._headerSent)) {
736
733
  proxyReq.setHeader('x-api-host', req.headers['host']);
737
734
  proxyReq.setHeader('x-forwarded-proto', 'https');
738
735
  // console.log(proxyReq.getHeaders());
739
-
740
- socket.on('error', (err) => {
741
- console.error('Proxy WS Error:', err); // eslint-disable-line no-console
742
- });
743
736
  }
737
+ }
744
738
 
745
- function onError(err, req, res) {
746
- res.statusCode = 598;
747
- console.error('Proxy Error:', err); // eslint-disable-line no-console
748
- res.write(JSON.stringify(err));
749
- }
739
+ export function onProxyReqWs(proxyReq, req, socket, options, head) {
740
+ req.headers.origin = options.target.href;
741
+ proxyReq.setHeader('origin', options.target.href);
742
+ proxyReq.setHeader('x-api-host', req.headers['host']);
743
+ proxyReq.setHeader('x-forwarded-proto', 'https');
744
+ // console.log(proxyReq.getHeaders());
745
+
746
+ socket.on('error', (err) => {
747
+ console.error('Proxy WS Error:', err); // eslint-disable-line no-console
748
+ });
749
+ }
750
+
751
+ export function onError(err, req, res) {
752
+ res.statusCode = 598;
753
+ console.error('Proxy Error:', err); // eslint-disable-line no-console
754
+ res.write(JSON.stringify(err));
750
755
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rancher/shell",
3
- "version": "0.1.21",
3
+ "version": "0.2.2",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",
@@ -353,7 +353,7 @@ export default {
353
353
  </div>
354
354
  </header>
355
355
  <div v-if="showCarousel">
356
- <h3>Featured Charts</h3>
356
+ <h3>{{ t('catalog.charts.featuredCharts') }}</h3>
357
357
  <Carousel
358
358
  :sliders="getFeaturedCharts"
359
359
  @clicked="(row) => selectChart(row)"
@@ -5,13 +5,13 @@ import isEqual from 'lodash/isEqual';
5
5
  import { mapPref, DIFF } from '@shell/store/prefs';
6
6
  import { mapFeature, MULTI_CLUSTER, LEGACY } from '@shell/store/features';
7
7
  import { mapGetters } from 'vuex';
8
-
9
8
  import { Banner } from '@components/Banner';
10
9
  import ButtonGroup from '@shell/components/ButtonGroup';
11
10
  import ChartReadme from '@shell/components/ChartReadme';
12
11
  import { Checkbox } from '@components/Form/Checkbox';
13
12
  import LabeledSelect from '@shell/components/form/LabeledSelect';
14
13
  import { LabeledInput } from '@components/Form/LabeledInput';
14
+ import { LabeledTooltip } from '@components/LabeledTooltip';
15
15
  import LazyImage from '@shell/components/LazyImage';
16
16
  import Loading from '@shell/components/Loading';
17
17
  import NameNsDescription from '@shell/components/form/NameNsDescription';
@@ -24,7 +24,7 @@ import Wizard from '@shell/components/Wizard';
24
24
  import TypeDescription from '@shell/components/TypeDescription';
25
25
  import ChartMixin from '@shell/mixins/chart';
26
26
  import ChildHook, { BEFORE_SAVE_HOOKS, AFTER_SAVE_HOOKS } from '@shell/mixins/child-hook';
27
- import { CATALOG, MANAGEMENT, DEFAULT_WORKSPACE } from '@shell/config/types';
27
+ import { CATALOG, MANAGEMENT, DEFAULT_WORKSPACE, CAPI } from '@shell/config/types';
28
28
  import {
29
29
  CHART, FROM_CLUSTER, FROM_TOOLS, HIDE_SIDE_NAV, NAMESPACE, REPO, REPO_TYPE, VERSION, _FLAGGED
30
30
  } from '@shell/config/query-params';
@@ -61,6 +61,7 @@ export default {
61
61
  Checkbox,
62
62
  LabeledInput,
63
63
  LabeledSelect,
64
+ LabeledTooltip,
64
65
  LazyImage,
65
66
  Loading,
66
67
  NameNsDescription,
@@ -93,10 +94,10 @@ export default {
93
94
 
94
95
  this.errors = [];
95
96
 
96
- this.defaultRegistrySetting = await this.$store.dispatch('management/find', {
97
- type: MANAGEMENT.SETTING,
98
- id: 'system-default-registry'
99
- });
97
+ // If the chart doesn't contain system `systemDefaultRegistry` properties there's no point applying them
98
+ this.clusterRegistry = await this.getClusterRegistry();
99
+ this.globalRegistry = await this.getGlobalRegistry();
100
+ this.defaultRegistrySetting = this.clusterRegistry || this.globalRegistry;
100
101
 
101
102
  this.serverUrlSetting = await this.$store.dispatch('management/find', {
102
103
  type: MANAGEMENT.SETTING,
@@ -281,6 +282,14 @@ export default {
281
282
  */
282
283
  this.chartValues = merge(merge({}, this.versionInfo?.values || {}), userValues);
283
284
 
285
+ const existingRegistry = this.chartValues?.global?.systemDefaultRegistry || this.chartValues?.global?.cattle?.systemDefaultRegistry;
286
+
287
+ delete this.chartValues?.global?.systemDefaultRegistry;
288
+ delete this.chartValues?.global?.cattle?.systemDefaultRegistry;
289
+
290
+ this.customRegistrySetting = existingRegistry || this.defaultRegistrySetting;
291
+ this.showCustomRegistryInput = !!this.customRegistrySetting;
292
+
284
293
  /* Serializes an object as a YAML document */
285
294
  this.valuesYaml = saferDump(this.chartValues);
286
295
 
@@ -292,6 +301,7 @@ export default {
292
301
  this.loadedVersionValues = this.versionInfo?.values || {};
293
302
  this.loadedVersion = this.version?.key;
294
303
  }
304
+
295
305
  /* Check if chart exists and if required values exist */
296
306
  this.updateStepOneReady();
297
307
 
@@ -317,13 +327,16 @@ export default {
317
327
  };
318
328
 
319
329
  return {
320
- defaultRegistrySetting: null,
330
+ defaultRegistrySetting: '',
331
+ customRegistrySetting: '',
321
332
  serverUrlSetting: null,
322
333
  chartValues: null,
334
+ clusterRegistry: '',
323
335
  originalYamlValues: null,
324
336
  previousYamlValues: null,
325
337
  errors: null,
326
338
  existing: null,
339
+ globalRegistry: '',
327
340
  forceNamespace: null,
328
341
  loadedVersion: null,
329
342
  loadedVersionValues: null,
@@ -335,22 +348,22 @@ export default {
335
348
  valuesYaml: '',
336
349
  project: null,
337
350
  migratedApp: false,
338
-
339
351
  defaultCmdOpts,
340
- customCmdOpts: { ...defaultCmdOpts },
352
+ customCmdOpts: { ...defaultCmdOpts },
341
353
 
342
354
  nameDisabled: false,
343
355
 
344
- preFormYamlOption: VALUES_STATE.YAML,
345
- formYamlOption: VALUES_STATE.YAML,
346
- showDiff: false,
347
- showValuesComponent: true,
348
- showQuestions: true,
349
- showSlideIn: false,
350
- shownReadmeWindows: [],
351
- componentHasTabs: false,
352
- showCommandStep: false,
353
- isNamespaceNew: false,
356
+ preFormYamlOption: VALUES_STATE.YAML,
357
+ formYamlOption: VALUES_STATE.YAML,
358
+ showDiff: false,
359
+ showValuesComponent: true,
360
+ showQuestions: true,
361
+ showSlideIn: false,
362
+ shownReadmeWindows: [],
363
+ componentHasTabs: false,
364
+ showCommandStep: false,
365
+ showCustomRegistryInput: false,
366
+ isNamespaceNew: false,
354
367
 
355
368
  stepBasic: {
356
369
  name: 'basics',
@@ -645,7 +658,8 @@ export default {
645
658
  }
646
659
 
647
660
  return null;
648
- }
661
+ },
662
+
649
663
  },
650
664
 
651
665
  watch: {
@@ -744,6 +758,55 @@ export default {
744
758
  },
745
759
 
746
760
  methods: {
761
+ async getClusterRegistry() {
762
+ const hasPermissionToSeeProvCluster = this.$store.getters[`management/schemaFor`](CAPI.RANCHER_CLUSTER);
763
+
764
+ if (hasPermissionToSeeProvCluster) {
765
+ const mgmCluster = this.$store.getters['currentCluster'];
766
+ const provCluster = await this.$store.dispatch('management/find', {
767
+ type: CAPI.RANCHER_CLUSTER,
768
+ id: mgmCluster.provClusterId
769
+ });
770
+
771
+ if (provCluster.isRke2) { // isRke2 returns true for both RKE2 and K3s clusters.
772
+ const agentConfig = provCluster.spec.rkeConfig.machineSelectorConfig.find(x => !x.machineLabelSelector).config;
773
+
774
+ // If a cluster scoped registry exists,
775
+ // it should be used by default.
776
+ const clusterRegistry = agentConfig?.['system-default-registry'] || '';
777
+
778
+ if (clusterRegistry) {
779
+ return clusterRegistry;
780
+ }
781
+ }
782
+ if (provCluster.isRke1) {
783
+ // For RKE1 clusters, the cluster scoped private registry is on the management
784
+ // cluster, not the provisioning cluster.
785
+ const rke1Registries = mgmCluster.spec.rancherKubernetesEngineConfig.privateRegistries;
786
+
787
+ if (rke1Registries?.length > 0) {
788
+ const defaultRegistry = rke1Registries.find((registry) => {
789
+ return registry.isDefault;
790
+ });
791
+
792
+ return defaultRegistry.url;
793
+ }
794
+ }
795
+ }
796
+ },
797
+
798
+ async getGlobalRegistry() {
799
+ // Use the global registry as a fallback.
800
+ // If it is an empty string, the container
801
+ // runtime will pull images from docker.io.
802
+ const globalRegistry = await this.$store.dispatch('management/find', {
803
+ type: MANAGEMENT.SETTING,
804
+ id: 'system-default-registry'
805
+ });
806
+
807
+ return globalRegistry.value;
808
+ },
809
+
747
810
  updateValue(value) {
748
811
  if (this.$refs.yaml) {
749
812
  this.$refs.yaml.updateValue(value);
@@ -905,7 +968,7 @@ export default {
905
968
  const cluster = this.currentCluster;
906
969
  const projects = this.$store.getters['management/all'](MANAGEMENT.PROJECT);
907
970
  const systemProjectId = projects.find(p => p.spec?.displayName === 'System')?.id?.split('/')?.[1] || '';
908
- const defaultRegistry = this.defaultRegistrySetting?.value || '';
971
+
909
972
  const serverUrl = this.serverUrlSetting?.value || '';
910
973
  const isWindows = (cluster.workerOSs || []).includes(WINDOWS);
911
974
  const pathPrefix = cluster?.spec?.rancherKubernetesEngineConfig?.prefixPath || '';
@@ -913,8 +976,9 @@ export default {
913
976
 
914
977
  setIfNotSet(cattle, 'clusterId', cluster?.id);
915
978
  setIfNotSet(cattle, 'clusterName', cluster?.nameDisplay);
916
- setIfNotSet(cattle, 'systemDefaultRegistry', defaultRegistry);
917
- setIfNotSet(global, 'systemDefaultRegistry', defaultRegistry);
979
+ set(cattle, 'systemDefaultRegistry', this.customRegistrySetting);
980
+ set(global, 'systemDefaultRegistry', this.customRegistrySetting);
981
+
918
982
  setIfNotSet(global, 'cattle.systemProjectId', systemProjectId);
919
983
  setIfNotSet(cattle, 'url', serverUrl);
920
984
  setIfNotSet(cattle, 'rkePathPrefix', pathPrefix);
@@ -939,7 +1003,6 @@ export default {
939
1003
  }
940
1004
 
941
1005
  const cluster = this.$store.getters['currentCluster'];
942
- const defaultRegistry = this.defaultRegistrySetting?.value || '';
943
1006
  const serverUrl = this.serverUrlSetting?.value || '';
944
1007
  const isWindows = (cluster.workerOSs || []).includes(WINDOWS);
945
1008
  const pathPrefix = cluster?.spec?.rancherKubernetesEngineConfig?.prefixPath || '';
@@ -948,7 +1011,6 @@ export default {
948
1011
  if ( values.global?.cattle ) {
949
1012
  deleteIfEqual(values.global.cattle, 'clusterId', cluster?.id);
950
1013
  deleteIfEqual(values.global.cattle, 'clusterName', cluster?.nameDisplay);
951
- deleteIfEqual(values.global.cattle, 'systemDefaultRegistry', defaultRegistry);
952
1014
  deleteIfEqual(values.global.cattle, 'url', serverUrl);
953
1015
  deleteIfEqual(values.global.cattle, 'rkePathPrefix', pathPrefix);
954
1016
  deleteIfEqual(values.global.cattle, 'rkeWindowsPathPrefix', windowsPathPrefix);
@@ -966,10 +1028,6 @@ export default {
966
1028
  delete values.global.cattle;
967
1029
  }
968
1030
 
969
- if ( values.global ) {
970
- deleteIfEqual(values.global, 'systemDefaultRegistry', defaultRegistry);
971
- }
972
-
973
1031
  if ( !Object.keys(values.global || {}).length ) {
974
1032
  delete values.global;
975
1033
  }
@@ -1289,7 +1347,6 @@ export default {
1289
1347
  </div>
1290
1348
  </div>
1291
1349
  <NameNsDescription
1292
- v-if="chart"
1293
1350
  v-model="value"
1294
1351
  :description-hidden="true"
1295
1352
  :mode="mode"
@@ -1316,13 +1373,30 @@ export default {
1316
1373
  />
1317
1374
  </template>
1318
1375
  </NameNsDescription>
1376
+ <Checkbox v-model="showCommandStep" class="mb-20" :label="t('catalog.install.steps.helmCli.checkbox', { action, existing: !!existing })" />
1377
+
1378
+ <Checkbox
1379
+ v-model="showCustomRegistryInput"
1380
+ class="mb-20"
1381
+ :label="t('catalog.chart.registry.custom.checkBoxLabel')"
1382
+ :tooltip="t('catalog.chart.registry.tooltip')"
1383
+ />
1384
+ <div class="row">
1385
+ <div class="col span-6">
1386
+ <LabeledInput
1387
+ v-if="showCustomRegistryInput"
1388
+ v-model="customRegistrySetting"
1389
+ label-key="catalog.chart.registry.custom.inputLabel"
1390
+ placeholder-key="catalog.chart.registry.custom.placeholder"
1391
+ :min-height="30"
1392
+ />
1393
+ </div>
1394
+ </div>
1319
1395
  <div class="step__values__controls--spacer" style="flex:1">
1320
1396
  &nbsp;
1321
1397
  </div>
1322
1398
  <Banner v-if="isNamespaceNew" color="info" v-html="t('catalog.install.steps.basics.createNamespace', {namespace: value.metadata.namespace}, true) ">
1323
1399
  </Banner>
1324
-
1325
- <Checkbox v-model="showCommandStep" class="mb-20" :label="t('catalog.install.steps.helmCli.checkbox', { action, existing: !!existing })" />
1326
1400
  </div>
1327
1401
  </template>
1328
1402
  <template #clusterTplVersion>
@@ -95,6 +95,7 @@ export default {
95
95
  <p>{{ t('performance.websocketNotification.description') }}</p>
96
96
  <Checkbox
97
97
  v-model="value.disableWebsocketNotification"
98
+ :mode="mode"
98
99
  :label="t('performance.websocketNotification.checkboxLabel')"
99
100
  class="mt-10 mb-20"
100
101
  :primary="true"
@@ -106,6 +107,7 @@ export default {
106
107
  <p>{{ t('performance.incrementalLoad.description') }}</p>
107
108
  <Checkbox
108
109
  v-model="value.incrementalLoading.enabled"
110
+ :mode="mode"
109
111
  :label="t('performance.incrementalLoad.checkboxLabel')"
110
112
  class="mt-10 mb-20"
111
113
  :primary="true"
@@ -116,6 +118,7 @@ export default {
116
118
  </p>
117
119
  <LabeledInput
118
120
  v-model="value.incrementalLoading.threshold"
121
+ :mode="mode"
119
122
  :label="t('performance.incrementalLoad.inputLabel')"
120
123
  :disabled="!value.incrementalLoading.enabled"
121
124
  class="input"
@@ -131,6 +134,7 @@ export default {
131
134
  <Banner color="error" label-key="performance.manualRefresh.banner" />
132
135
  <Checkbox
133
136
  v-model="value.manualRefresh.enabled"
137
+ :mode="mode"
134
138
  :label="t('performance.manualRefresh.checkboxLabel')"
135
139
  class="mt-10 mb-20"
136
140
  :primary="true"
@@ -141,6 +145,7 @@ export default {
141
145
  </p>
142
146
  <LabeledInput
143
147
  v-model.number="value.manualRefresh.threshold"
148
+ :mode="mode"
144
149
  :label="t('performance.manualRefresh.inputLabel')"
145
150
  :disabled="!value.manualRefresh.enabled"
146
151
  class="input"
@@ -156,6 +161,7 @@ export default {
156
161
  <Banner color="error" label-key="performance.gc.banner" />
157
162
  <Checkbox
158
163
  v-model="value.garbageCollection.enabled"
164
+ :mode="mode"
159
165
  :label="t('performance.gc.checkboxLabel')"
160
166
  class="mt-10 mb-20"
161
167
  :primary="true"
@@ -165,6 +171,7 @@ export default {
165
171
  <div class="ml-20 mb-10">
166
172
  <Checkbox
167
173
  v-model="value.garbageCollection.enabledInterval"
174
+ :mode="mode"
168
175
  :class="{ 'text-muted': !value.garbageCollection.enabled }"
169
176
  :label="t('performance.gc.whenRun.intervalCheckBox.label')"
170
177
  class="mt-10 mb-10"
@@ -174,6 +181,7 @@ export default {
174
181
  <div class="ml-20">
175
182
  <UnitInput
176
183
  v-model="value.garbageCollection.interval"
184
+ :mode="mode"
177
185
  :suffix="t('suffix.seconds', { count: value.garbageCollection.interval })"
178
186
  :label="t('performance.gc.whenRun.interval.inputLabel')"
179
187
  :disabled="!value.garbageCollection.enabled || !value.garbageCollection.enabledInterval"
@@ -183,6 +191,7 @@ export default {
183
191
  </div>
184
192
  <Checkbox
185
193
  v-model="value.garbageCollection.enabledOnNavigate"
194
+ :mode="mode"
186
195
  :class="{ 'text-muted': !value.garbageCollection.enabled }"
187
196
  :label="t('performance.gc.whenRun.route.description')"
188
197
  class="mt-20 mb-10"
@@ -197,6 +206,7 @@ export default {
197
206
  </p>
198
207
  <UnitInput
199
208
  v-model="value.garbageCollection.ageThreshold"
209
+ :mode="mode"
200
210
  :suffix="t('suffix.seconds', { count: value.garbageCollection.ageThreshold })"
201
211
  :label="t('performance.gc.howRun.age.inputLabel')"
202
212
  :disabled="!value.garbageCollection.enabled"
@@ -208,6 +218,7 @@ export default {
208
218
  </p>
209
219
  <LabeledInput
210
220
  v-model.number="value.garbageCollection.countThreshold"
221
+ :mode="mode"
211
222
  :label="t('performance.gc.howRun.count.inputLabel')"
212
223
  :disabled="!value.garbageCollection.enabled"
213
224
  class="input"