@rancher/shell 3.0.2-rc.2 → 3.0.2-rc.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 (172) hide show
  1. package/assets/styles/base/_basic.scss +7 -8
  2. package/assets/styles/global/_button.scss +10 -0
  3. package/assets/styles/global/_form.scss +2 -1
  4. package/assets/styles/global/_tooltip.scss +2 -2
  5. package/assets/styles/themes/_dark.scss +15 -3
  6. package/assets/styles/themes/_light.scss +7 -2
  7. package/assets/styles/vendor/vue-select.scss +4 -0
  8. package/assets/translations/en-us.yaml +66 -9
  9. package/assets/translations/zh-hans.yaml +2 -3
  10. package/components/AppModal.vue +50 -0
  11. package/components/BannerGraphic.vue +0 -42
  12. package/components/ButtonMultiAction.vue +1 -1
  13. package/components/Carousel.vue +88 -74
  14. package/components/CommunityLinks.vue +6 -1
  15. package/components/CopyToClipboardText.vue +3 -0
  16. package/components/Dialog.vue +20 -1
  17. package/components/GrowlManager.vue +9 -2
  18. package/components/LocaleSelector.vue +8 -1
  19. package/components/PaginatedResourceTable.vue +4 -7
  20. package/components/ProgressBarMulti.vue +14 -0
  21. package/components/PromptChangePassword.vue +3 -0
  22. package/components/Questions/Reference.vue +57 -28
  23. package/components/ResourceDetail/Masthead.vue +1 -1
  24. package/components/SelectIconGrid.vue +12 -1
  25. package/components/SideNav.vue +12 -38
  26. package/components/SortableTable/index.vue +1 -0
  27. package/components/Tabbed/index.vue +9 -1
  28. package/components/YamlEditor.vue +1 -0
  29. package/components/__tests__/Carousel.test.ts +56 -27
  30. package/components/auth/Principal.vue +5 -3
  31. package/components/fleet/FleetClusters.vue +82 -1
  32. package/components/fleet/FleetRepos.vue +13 -30
  33. package/components/fleet/ForceDirectedTreeChart/index.vue +2 -2
  34. package/components/form/ChangePassword.vue +2 -0
  35. package/components/form/ColorInput.vue +24 -1
  36. package/components/form/FileSelector.vue +2 -0
  37. package/components/form/KeyValue.vue +230 -160
  38. package/components/form/LabeledSelect.vue +2 -2
  39. package/components/form/PlusMinus.vue +14 -2
  40. package/components/form/ResourceLabeledSelect.vue +13 -53
  41. package/components/form/ResourceSelector.vue +1 -0
  42. package/components/form/ResourceTabs/index.vue +79 -36
  43. package/components/form/SSHKnownHosts/KnownHostsEditDialog.vue +192 -0
  44. package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +104 -0
  45. package/components/form/SSHKnownHosts/index.vue +101 -0
  46. package/components/form/SecretSelector.vue +2 -2
  47. package/components/form/Select.vue +1 -1
  48. package/components/form/SelectOrCreateAuthSecret.vue +43 -11
  49. package/components/form/__tests__/KeyValue.test.ts +1 -1
  50. package/components/form/__tests__/SSHKnownHosts.test.ts +59 -0
  51. package/components/formatter/FleetClusterSummaryGraph.vue +2 -2
  52. package/components/formatter/FleetSummaryGraph.vue +6 -7
  53. package/components/formatter/WorkloadHealthScale.vue +7 -0
  54. package/components/nav/Group.vue +30 -4
  55. package/components/nav/Header.vue +82 -114
  56. package/components/nav/HeaderPageActionMenu.vue +27 -131
  57. package/components/nav/NamespaceFilter.vue +1 -1
  58. package/components/nav/Type.vue +15 -0
  59. package/composables/focusTrap.ts +68 -0
  60. package/config/home-links.js +21 -13
  61. package/config/labels-annotations.js +2 -0
  62. package/config/page-actions.js +1 -0
  63. package/config/pagination-table-headers.js +15 -1
  64. package/config/product/explorer.js +7 -17
  65. package/config/table-headers.js +6 -0
  66. package/config/version.js +5 -1
  67. package/core/plugin.ts +41 -1
  68. package/core/plugins.js +125 -72
  69. package/core/types-provisioning.ts +91 -2
  70. package/core/types.ts +55 -0
  71. package/detail/__tests__/autoscaling.horizontalpodautoscaler.test.ts +12 -3
  72. package/detail/catalog.cattle.io.app.vue +1 -1
  73. package/detail/fleet.cattle.io.cluster.vue +3 -3
  74. package/detail/namespace.vue +13 -19
  75. package/detail/networking.k8s.io.ingress.vue +13 -53
  76. package/detail/provisioning.cattle.io.cluster.vue +12 -1
  77. package/detail/secret.vue +25 -0
  78. package/detail/workload/index.vue +3 -3
  79. package/dialog/AddCustomBadgeDialog.vue +5 -1
  80. package/edit/auth/ldap/__tests__/config.test.ts +18 -0
  81. package/edit/auth/ldap/config.vue +24 -0
  82. package/edit/auth/saml.vue +8 -6
  83. package/edit/fleet.cattle.io.gitrepo.vue +34 -23
  84. package/edit/logging-flow/index.vue +4 -19
  85. package/edit/networking.k8s.io.ingress/index.vue +18 -65
  86. package/edit/networking.k8s.io.networkpolicy/index.vue +4 -5
  87. package/edit/provisioning.cattle.io.cluster/index.vue +27 -8
  88. package/edit/provisioning.cattle.io.cluster/rke2.vue +31 -115
  89. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +2 -2
  90. package/edit/provisioning.cattle.io.cluster/tabs/networking/ACE.vue +14 -28
  91. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +25 -12
  92. package/edit/secret/index.vue +1 -1
  93. package/edit/secret/ssh.vue +21 -3
  94. package/edit/service.vue +1 -2
  95. package/list/networking.k8s.io.ingress.vue +1 -1
  96. package/list/node.vue +15 -8
  97. package/list/persistentvolume.vue +12 -4
  98. package/list/provisioning.cattle.io.cluster.vue +1 -0
  99. package/list/service.vue +1 -1
  100. package/list/workload.vue +4 -0
  101. package/mixins/chart.js +4 -1
  102. package/models/catalog.cattle.io.app.js +3 -1
  103. package/models/catalog.cattle.io.clusterrepo.js +56 -7
  104. package/models/fleet.cattle.io.bundle.js +0 -11
  105. package/models/fleet.cattle.io.cluster.js +17 -1
  106. package/models/fleet.cattle.io.gitrepo.js +88 -52
  107. package/models/provisioning.cattle.io.cluster.js +36 -1
  108. package/models/secret.js +5 -0
  109. package/models/service.js +1 -0
  110. package/models/workload.js +19 -1
  111. package/package.json +5 -4
  112. package/pages/account/index.vue +4 -0
  113. package/pages/c/_cluster/apps/charts/index.vue +4 -0
  114. package/pages/c/_cluster/explorer/ConfigBadge.vue +4 -2
  115. package/pages/c/_cluster/explorer/index.vue +13 -6
  116. package/pages/c/_cluster/fleet/GitRepoGraphConfig.js +3 -3
  117. package/pages/c/_cluster/fleet/index.vue +75 -89
  118. package/pages/c/_cluster/settings/links.vue +2 -2
  119. package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +3 -1
  120. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +3 -0
  121. package/pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue +7 -1
  122. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +3 -1
  123. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +10 -7
  124. package/pages/c/_cluster/uiplugins/InstallDialog.vue +7 -0
  125. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +181 -106
  126. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +2 -0
  127. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +9 -1
  128. package/pages/c/_cluster/uiplugins/index.vue +50 -12
  129. package/pages/diagnostic.vue +17 -15
  130. package/pages/home.vue +32 -6
  131. package/plugins/clean-html.js +50 -0
  132. package/plugins/dashboard-store/resource-class.js +4 -0
  133. package/plugins/plugin.js +54 -49
  134. package/plugins/steve/mutations.js +1 -1
  135. package/plugins/steve/steve-class.js +8 -0
  136. package/plugins/steve/steve-pagination-utils.ts +3 -1
  137. package/rancher-components/Accordion/Accordion.vue +4 -4
  138. package/rancher-components/BadgeState/BadgeState.vue +7 -0
  139. package/rancher-components/Card/Card.vue +12 -0
  140. package/rancher-components/Form/Checkbox/Checkbox.vue +9 -2
  141. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +18 -1
  142. package/rancher-components/Form/LabeledInput/LabeledInput.vue +19 -1
  143. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +39 -2
  144. package/rancher-components/RcButton/RcButton.vue +90 -0
  145. package/rancher-components/RcButton/index.ts +2 -0
  146. package/rancher-components/RcButton/types.ts +17 -0
  147. package/rancher-components/RcDropdown/RcDropdown.vue +122 -0
  148. package/rancher-components/RcDropdown/RcDropdownItem.vue +127 -0
  149. package/rancher-components/RcDropdown/RcDropdownSeparator.vue +6 -0
  150. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +42 -0
  151. package/rancher-components/RcDropdown/index.ts +4 -0
  152. package/rancher-components/RcDropdown/types.ts +22 -0
  153. package/rancher-components/RcDropdown/useDropdownCollection.ts +46 -0
  154. package/rancher-components/RcDropdown/useDropdownContext.ts +110 -0
  155. package/scripts/test-plugins-build.sh +2 -0
  156. package/scripts/typegen.sh +2 -0
  157. package/store/catalog.js +1 -1
  158. package/tsconfig.json +2 -1
  159. package/types/components/paginatedResourceTable.ts +25 -0
  160. package/types/components/resourceLabeledSelect.ts +48 -0
  161. package/types/resources/fleet.d.ts +17 -0
  162. package/types/shell/index.d.ts +61 -0
  163. package/utils/auth.js +5 -1
  164. package/utils/cluster.js +106 -0
  165. package/utils/fleet.ts +35 -3
  166. package/utils/ingress.ts +64 -0
  167. package/utils/uiplugins.ts +56 -44
  168. package/utils/validators/cron-schedule.js +7 -2
  169. package/utils/validators/formRules/__tests__/index.test.ts +53 -17
  170. package/utils/validators/formRules/index.ts +20 -5
  171. package/vue.config.js +1 -1
  172. package/components/RelatedWorkloadsTable.vue +0 -50
@@ -43,12 +43,12 @@ export default {
43
43
 
44
44
  async fetch() {
45
45
  const hash = await allHash({
46
- allPods: this.$store.dispatch('cluster/findAll', { type: POD }),
47
- allNamespaces: this.$store.dispatch('cluster/findAll', { type: NAMESPACE }),
46
+ allPods: this.$store.dispatch('cluster/findAll', { type: POD }), // Used in conjunction with `matches/match/label selectors`. Requires https://github.com/rancher/dashboard/issues/10417 to fix
47
+ allNamespaces: this.$store.dispatch('cluster/findAll', { type: NAMESPACE }), // Used in conjunction with `matches/match/label selectors`. Requires https://github.com/rancher/dashboard/issues/10417 to fix
48
48
  });
49
49
 
50
- this.allPods = hash.allPods;
51
- this.allNamespaces = hash.allNamespaces;
50
+ this.allPods = hash.allPods; // Used in matchingPods, and PolicyRules --> PolicyRule --> PolicyRuleTarget
51
+ this.allNamespaces = hash.allNamespaces; // Used in PolicyRules --> PolicyRule --> PolicyRuleTarget
52
52
 
53
53
  this.updateMatchingPods();
54
54
  },
@@ -147,7 +147,6 @@ export default {
147
147
 
148
148
  methods: {
149
149
  updateMatchingPods: throttle(function() {
150
- // See https://github.com/rancher/dashboard/issues/10417, all pods bad, need to replace local selector somehow
151
150
  const allInNamespace = this.allPods.filter((pod) => pod.metadata.namespace === this.value.metadata.namespace);
152
151
  const match = matching(allInNamespace, this.podSelectorExpressions);
153
152
  const matched = match.length || 0;
@@ -12,7 +12,7 @@ import { mapGetters } from 'vuex';
12
12
  import { sortBy } from '@shell/utils/sort';
13
13
  import { PROVISIONER, _RKE1, _RKE2 } from '@shell/store/prefs';
14
14
  import { filterAndArrangeCharts } from '@shell/store/catalog';
15
- import { CATALOG } from '@shell/config/labels-annotations';
15
+ import { CATALOG, CAPI as CAPI_ANNOTATIONS } from '@shell/config/labels-annotations';
16
16
  import { CAPI, MANAGEMENT, DEFAULT_WORKSPACE } from '@shell/config/types';
17
17
  import { mapFeature, RKE2 as RKE2_FEATURE, RKE1_UI } from '@shell/store/features';
18
18
  import { allHash } from '@shell/utils/promise';
@@ -35,6 +35,8 @@ const SORT_GROUPS = {
35
35
 
36
36
  // uSed to proxy stylesheets for custom drivers that provide custom UI (RKE1)
37
37
  const PROXY_ENDPOINT = '/meta/proxy';
38
+ const IMPORTED = 'imported';
39
+ const LOCAL = 'local';
38
40
 
39
41
  export default {
40
42
  name: 'CruCluster',
@@ -211,6 +213,14 @@ export default {
211
213
 
212
214
  emberLink() {
213
215
  if (this.value) {
216
+ // for imported and local clusters, set subtype using properties from prov cluster model
217
+ //
218
+ if (this.value.isImported) {
219
+ this.selectType(IMPORTED, false);
220
+ } else if (this.value.isLocal) {
221
+ this.selectType(LOCAL, false);
222
+ }
223
+
214
224
  // set subtype if editing EKS/GKE/AKS cluster -- this ensures that the component provided by extension is loaded instead of iframing old ember ui
215
225
  if (this.value.provisioner) {
216
226
  const matchingSubtype = this.subTypes.find((st) => DRIVER_TO_IMPORT[st.id.toLowerCase()] === this.value.provisioner.toLowerCase());
@@ -219,6 +229,16 @@ export default {
219
229
  this.selectType(matchingSubtype.id, false);
220
230
  }
221
231
  }
232
+
233
+ // subType set by the ui during cluster creation
234
+ // this is likely from a ui extension trying to load custom ui to edit the cluster
235
+ const fromAnnotation = this.value.annotations?.[CAPI_ANNOTATIONS.UI_CUSTOM_PROVIDER];
236
+
237
+ if (fromAnnotation) {
238
+ this.selectType(fromAnnotation, false);
239
+
240
+ return '';
241
+ }
222
242
  // For custom RKE2 clusters, don't load an Ember page.
223
243
  // It should be the dashboard.
224
244
  if ( this.value.isRke2 && ((this.value.isCustom && this.mode === _EDIT) || (this.value.isCustom && this.as === _CONFIG && this.mode === _VIEW) || (this.subType || '').toLowerCase() === 'custom')) {
@@ -228,17 +248,18 @@ export default {
228
248
 
229
249
  return '';
230
250
  }
231
- // For RKE2/K3s clusters provisioned in Rancher with node pools,
251
+ // For existing RKE2/K3s clusters provisioned in Rancher,
252
+ // set the subtype using the machine pool provisioner
232
253
  // do not use an iFramed Ember page.
233
254
  if ( this.value.isRke2 && this.value.machineProvider ) {
234
- // Edit existing RKE2
235
255
  this.selectType(this.value.machineProvider, false);
236
256
 
237
257
  return '';
238
258
  }
259
+
239
260
  if ( this.subType ) {
240
261
  // if driver type has a custom form component, don't load an ember page
241
- if (this.selectedSubType.component) {
262
+ if (this.selectedSubType?.component) {
242
263
  return '';
243
264
  }
244
265
  // For RKE1 and hosted Kubernetes Clusters, set the ember link
@@ -247,8 +268,6 @@ export default {
247
268
  return this.selectedSubType.emberLink;
248
269
  }
249
270
 
250
- this.selectType(this.subType, false);
251
-
252
271
  return '';
253
272
  }
254
273
 
@@ -367,8 +386,8 @@ export default {
367
386
 
368
387
  // Add from extensions
369
388
  this.extensions.forEach((ext) => {
370
- // if the rke toggle is set to rke1, don't add extensions that specify rke2 group
371
- // default group is rke2
389
+ // if the rke toggle is set to rke1, don't add extensions that specify rke2 group
390
+ // default group is rke2
372
391
  if (!this.isRke2 && (ext.group === _RKE2 || !ext.group)) {
373
392
  return;
374
393
  }
@@ -25,10 +25,7 @@ import {
25
25
  clone, diff, set, get, isEmpty, mergeWithReplaceArrays
26
26
  } from '@shell/utils/object';
27
27
  import { allHash } from '@shell/utils/promise';
28
- import { sortBy } from '@shell/utils/sort';
29
-
30
- import { compare, sortable } from '@shell/utils/version';
31
- import { isHarvesterSatisfiesVersion, labelForAddon } from '@shell/utils/cluster';
28
+ import { getAllOptionsAfterCurrentVersion, filterOutDeprecatedPatchVersions, isHarvesterSatisfiesVersion, labelForAddon } from '@shell/utils/cluster';
32
29
 
33
30
  import { BadgeState } from '@components/BadgeState';
34
31
  import { Banner } from '@components/Banner';
@@ -321,15 +318,15 @@ export default {
321
318
  const existingK3s = this.mode === _EDIT && cur.includes('k3s');
322
319
  const isAzure = this.agentConfig?.['cloud-provider-name'] === 'azure';
323
320
 
324
- let allValidRke2Versions = this.getAllOptionsAfterCurrentVersion(this.rke2Versions, (existingRke2 ? cur : null), this.defaultRke2);
325
- let allValidK3sVersions = this.getAllOptionsAfterCurrentVersion(this.k3sVersions, (existingK3s ? cur : null), this.defaultK3s);
321
+ let allValidRke2Versions = getAllOptionsAfterCurrentVersion(this.$store, this.rke2Versions, (existingRke2 ? cur : null), this.defaultRke2);
322
+ let allValidK3sVersions = getAllOptionsAfterCurrentVersion(this.$store, this.k3sVersions, (existingK3s ? cur : null), this.defaultK3s);
326
323
 
327
324
  if (!this.showDeprecatedPatchVersions) {
328
325
  // Normally, we only want to show the most recent patch version
329
326
  // for each Kubernetes minor version. However, if the user
330
327
  // opts in to showing deprecated versions, we don't filter them.
331
- allValidRke2Versions = this.filterOutDeprecatedPatchVersions(allValidRke2Versions, cur);
332
- allValidK3sVersions = this.filterOutDeprecatedPatchVersions(allValidK3sVersions, cur);
328
+ allValidRke2Versions = filterOutDeprecatedPatchVersions(allValidRke2Versions, cur);
329
+ allValidK3sVersions = filterOutDeprecatedPatchVersions(allValidK3sVersions, cur);
333
330
  }
334
331
 
335
332
  if (isAzure) {
@@ -711,7 +708,7 @@ export default {
711
708
  const first = all[0]?.value;
712
709
  const preferred = all.find((x) => x.value === this.defaultRke2)?.value;
713
710
 
714
- const rke2 = this.getAllOptionsAfterCurrentVersion(this.rke2Versions, null);
711
+ const rke2 = getAllOptionsAfterCurrentVersion(this.$store, this.rke2Versions, null);
715
712
  const showRke2 = rke2.length;
716
713
  let out;
717
714
 
@@ -984,6 +981,10 @@ export default {
984
981
  if (this.value.spec.defaultPodSecurityAdmissionConfigurationTemplateName === undefined) {
985
982
  this.value.spec.defaultPodSecurityAdmissionConfigurationTemplateName = '';
986
983
  }
984
+
985
+ if ( isEmpty(this.value?.spec?.localClusterAuthEndpoint) ) {
986
+ set(this.value, 'spec.localClusterAuthEndpoint', { enabled: false });
987
+ }
987
988
  },
988
989
 
989
990
  /**
@@ -1111,6 +1112,17 @@ export default {
1111
1112
  }
1112
1113
  },
1113
1114
 
1115
+ enableLocalClusterAuthEndpoint(neu) {
1116
+ this.localValue.spec.localClusterAuthEndpoint.enabled = neu;
1117
+ if (!neu) {
1118
+ delete this.localValue.spec.localClusterAuthEndpoint.caCerts;
1119
+ delete this.localValue.spec.localClusterAuthEndpoint.fqdn;
1120
+ } else {
1121
+ this.localValue.spec.localClusterAuthEndpoint.caCerts = '';
1122
+ this.localValue.spec.localClusterAuthEndpoint.fqdn = '';
1123
+ }
1124
+ },
1125
+
1114
1126
  /**
1115
1127
  * Get machine pools from the cluster configuration
1116
1128
  * this.value.spec.rkeConfig.machinePools
@@ -1792,110 +1804,6 @@ export default {
1792
1804
  this.value.spec.rkeConfig.registries.configs = configs;
1793
1805
  },
1794
1806
 
1795
- getAllOptionsAfterCurrentVersion(versions, currentVersion, defaultVersion) {
1796
- const out = (versions || []).filter((obj) => !!obj.serverArgs).map((obj) => {
1797
- let disabled = false;
1798
- let experimental = false;
1799
- let isCurrentVersion = false;
1800
- let label = obj.id;
1801
-
1802
- if (currentVersion) {
1803
- disabled = compare(obj.id, currentVersion) < 0;
1804
- isCurrentVersion = compare(obj.id, currentVersion) === 0;
1805
- }
1806
-
1807
- if (defaultVersion) {
1808
- experimental = compare(defaultVersion, obj.id) < 0;
1809
- }
1810
-
1811
- if (isCurrentVersion) {
1812
- label = `${ label } ${ this.t('cluster.kubernetesVersion.current') }`;
1813
- }
1814
-
1815
- if (experimental) {
1816
- label = `${ label } ${ this.t('cluster.kubernetesVersion.experimental') }`;
1817
- }
1818
-
1819
- return {
1820
- label,
1821
- value: obj.id,
1822
- sort: sortable(obj.id),
1823
- serverArgs: obj.serverArgs,
1824
- agentArgs: obj.agentArgs,
1825
- charts: obj.charts,
1826
- disabled,
1827
- };
1828
- });
1829
-
1830
- if (currentVersion && !out.find((obj) => obj.value === currentVersion)) {
1831
- out.push({
1832
- label: `${ currentVersion } ${ this.t('cluster.kubernetesVersion.current') }`,
1833
- value: currentVersion,
1834
- sort: sortable(currentVersion),
1835
- });
1836
- }
1837
-
1838
- const sorted = sortBy(out, 'sort:desc');
1839
-
1840
- const mostRecentPatchVersions = this.getMostRecentPatchVersions(sorted);
1841
-
1842
- const sortedWithDeprecatedLabel = sorted.map((optionData) => {
1843
- const majorMinor = `${ semver.major(optionData.value) }.${ semver.minor(optionData.value) }`;
1844
-
1845
- if (mostRecentPatchVersions[majorMinor] === optionData.value) {
1846
- return optionData;
1847
- }
1848
-
1849
- return {
1850
- ...optionData,
1851
- label: `${ optionData.label } ${ this.t('cluster.kubernetesVersion.deprecated') }`
1852
- };
1853
- });
1854
-
1855
- return sortedWithDeprecatedLabel;
1856
- },
1857
-
1858
- getMostRecentPatchVersions(sortedVersions) {
1859
- // Get the most recent patch version for each Kubernetes minor version.
1860
- const versionMap = {};
1861
-
1862
- sortedVersions.forEach((version) => {
1863
- const majorMinor = `${ semver.major(version.value) }.${ semver.minor(version.value) }`;
1864
-
1865
- if (!versionMap[majorMinor]) {
1866
- // Because we start with a sorted list of versions, we know the
1867
- // highest patch version is first in the list, so we only keep the
1868
- // first of each minor version in the list.
1869
- versionMap[majorMinor] = version.value;
1870
- }
1871
- });
1872
-
1873
- return versionMap;
1874
- },
1875
-
1876
- filterOutDeprecatedPatchVersions(allVersions, currentVersion) {
1877
- // Get the most recent patch version for each Kubernetes minor version.
1878
- const mostRecentPatchVersions = this.getMostRecentPatchVersions(allVersions);
1879
-
1880
- const filteredVersions = allVersions.filter((version) => {
1881
- // Always show pre-releases
1882
- if (semver.prerelease(version.value)) {
1883
- return true;
1884
- }
1885
-
1886
- const majorMinor = `${ semver.major(version.value) }.${ semver.minor(version.value) }`;
1887
-
1888
- // Always show current version, else show if we haven't shown anything for this major.minor version yet
1889
- if (version.value === currentVersion || mostRecentPatchVersions[majorMinor] === version.value) {
1890
- return true;
1891
- }
1892
-
1893
- return false;
1894
- });
1895
-
1896
- return filteredVersions;
1897
- },
1898
-
1899
1807
  generateYaml() {
1900
1808
  const resource = this.value;
1901
1809
  const inStore = this.$store.getters['currentStore'](resource);
@@ -2393,8 +2301,16 @@ export default {
2393
2301
  :mode="mode"
2394
2302
  :selected-version="selectedVersion"
2395
2303
  :truncate-limit="truncateLimit"
2396
- @update:value="$emit('input', $event)"
2397
- @truncate-hostname="truncateHostname"
2304
+ @truncate-hostname-changed="truncateHostname"
2305
+ @cluster-cidr-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['cluster-cidr'] = val"
2306
+ @service-cidr-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['service-cidr'] = val"
2307
+ @cluster-domain-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['cluster-domain'] = val"
2308
+ @cluster-dns-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['cluster-dns'] = val"
2309
+ @service-node-port-range-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['service-node-port-range'] = val"
2310
+ @tls-san-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['tls-san'] = val"
2311
+ @local-cluster-auth-endpoint-changed="enableLocalClusterAuthEndpoint"
2312
+ @ca-certs-changed="(val)=>localValue.spec.localClusterAuthEndpoint.caCerts = val"
2313
+ @fqdn-changed="(val)=>localValue.spec.localClusterAuthEndpoint.fqdn = val"
2398
2314
  />
2399
2315
  </Tab>
2400
2316
 
@@ -300,7 +300,7 @@ export default {
300
300
  return name === 'rancher-vsphere';
301
301
  },
302
302
 
303
- showk8s21LegacyWarning() {
303
+ showk8sLegacyWarning() {
304
304
  const isLegacyEnabled = this.features(LEGACY);
305
305
 
306
306
  if (!isLegacyEnabled) {
@@ -437,7 +437,7 @@ export default {
437
437
  :label="t('cluster.banner.haveArgInfo')"
438
438
  />
439
439
  <Banner
440
- v-if="showk8s21LegacyWarning"
440
+ v-if="showk8sLegacyWarning"
441
441
  color="warning"
442
442
  :label="t('cluster.legacyWarning')"
443
443
  />
@@ -2,14 +2,14 @@
2
2
  import { RadioGroup } from '@components/Form/Radio';
3
3
  import { LabeledInput } from '@components/Form/LabeledInput';
4
4
  import FileSelector, { createOnSelected } from '@shell/components/form/FileSelector';
5
- import { set } from '@shell/utils/object';
6
- import isEmpty from 'lodash/isEmpty';
7
5
 
8
6
  export default {
9
7
  components: {
10
8
  RadioGroup, LabeledInput, FileSelector
11
9
  },
12
10
 
11
+ emits: ['fqdn-changed', 'ca-certs-changed', 'local-cluster-auth-endpoint-changed'],
12
+
13
13
  props: {
14
14
  mode: {
15
15
  type: String,
@@ -22,57 +22,43 @@ export default {
22
22
  },
23
23
  },
24
24
 
25
- data() {
26
- if ( isEmpty(this.value?.spec?.localClusterAuthEndpoint) ) {
27
- set(this.value, 'spec.localClusterAuthEndpoint', {
28
- enabled: false,
29
- caCerts: '',
30
- fqdn: '',
31
- });
32
- }
33
-
34
- return {};
35
- },
36
-
37
- computed: {
38
- config() {
39
- return this.value.spec.localClusterAuthEndpoint;
40
- },
41
- },
42
-
43
- methods: { onCertSelected: createOnSelected('config.caCerts') }
25
+ methods: { onCertSelected: createOnSelected('value.caCerts') }
44
26
  };
45
27
  </script>
46
28
 
47
29
  <template>
48
30
  <div>
49
- <h3 v-t="'cluster.tabs.ace'" />
50
-
51
31
  <RadioGroup
52
- v-model:value="config.enabled"
32
+ v-model:value="value.enabled"
53
33
  name="enabled"
34
+ data-testid="ace-enabled-radio-input"
54
35
  :options="[false, true]"
55
36
  :labels="[t('generic.disabled'), t('generic.enabled')]"
56
37
  :mode="mode"
38
+ @update:value="$emit('local-cluster-auth-endpoint-changed', $event)"
57
39
  />
58
40
 
59
- <template v-if="config.enabled">
41
+ <template v-if="value.enabled">
60
42
  <div class="row mb-20">
61
43
  <div class="col span-6">
62
44
  <LabeledInput
63
- v-model:value="config.fqdn"
45
+ :value="value.fqdn"
64
46
  :mode="mode"
65
- label="FQDN"
47
+ :label="t('cluster.rke2.address.fqdn.label')"
48
+ data-testid="ace-fqdn-input"
66
49
  :tooltip="t('cluster.rke2.address.fqdn.toolTip')"
50
+ @update:value="$emit('fqdn-changed', $event)"
67
51
  />
68
52
  </div>
69
53
  <div class="col span-6">
70
54
  <LabeledInput
71
- v-model:value="config.caCerts"
55
+ :value="value.caCerts"
72
56
  :mode="mode"
73
57
  :label="t('cluster.rke2.address.caCerts.label')"
74
58
  type="multiline"
59
+ data-testid="ace-cacerts-input"
75
60
  :tooltip="t('cluster.rke2.address.caCerts.toolTip')"
61
+ @update:value="$emit('ca-certs-changed', $event)"
76
62
  />
77
63
  <FileSelector
78
64
  :mode="mode"
@@ -9,7 +9,12 @@ import ACE from '@shell/edit/provisioning.cattle.io.cluster/tabs/networking/ACE'
9
9
  const NETBIOS_TRUNCATION_LENGTH = 15;
10
10
 
11
11
  export default {
12
- emits: ['update:value', 'truncate-hostname', 'input'],
12
+ emits: [
13
+ 'update:value', 'cluster-cidr-changed', 'local-cluster-auth-endpoint-changed',
14
+ 'service-cidr-changed', 'cluster-domain-changed', 'cluster-dns-changed',
15
+ 'truncate-hostname-changed', 'ca-certs-changed', 'service-node-port-range-changed',
16
+ 'fqdn-changed', 'tls-san-changed'
17
+ ],
13
18
 
14
19
  components: {
15
20
  LabeledInput,
@@ -74,7 +79,7 @@ export default {
74
79
  this.$emit('update:value', newValue);
75
80
  }
76
81
  },
77
- },
82
+ }
78
83
  };
79
84
  </script>
80
85
 
@@ -99,10 +104,11 @@ export default {
99
104
  class="col span-6"
100
105
  >
101
106
  <LabeledInput
102
- v-model:value="serverConfig['cluster-cidr']"
107
+ :value="serverConfig['cluster-cidr']"
103
108
  :mode="mode"
104
109
  :disabled="isEdit"
105
110
  :label="t('cluster.rke2.address.clusterCidr.label')"
111
+ @update:value="$emit('cluster-cidr-changed', $event)"
106
112
  />
107
113
  </div>
108
114
  <div
@@ -110,10 +116,11 @@ export default {
110
116
  class="col span-6"
111
117
  >
112
118
  <LabeledInput
113
- v-model:value="serverConfig['service-cidr']"
119
+ :value="serverConfig['service-cidr']"
114
120
  :mode="mode"
115
121
  :disabled="isEdit"
116
122
  :label="t('cluster.rke2.address.serviceCidr.label')"
123
+ @update:value="$emit('service-cidr-changed', $event)"
117
124
  />
118
125
  </div>
119
126
  </div>
@@ -124,10 +131,11 @@ export default {
124
131
  class="col span-6"
125
132
  >
126
133
  <LabeledInput
127
- v-model:value="serverConfig['cluster-dns']"
134
+ :value="serverConfig['cluster-dns']"
128
135
  :mode="mode"
129
136
  :disabled="isEdit"
130
137
  :label="t('cluster.rke2.address.dns.label')"
138
+ @update:value="$emit('cluster-dns-changed', $event)"
131
139
  />
132
140
  </div>
133
141
  <div
@@ -135,10 +143,11 @@ export default {
135
143
  class="col span-6"
136
144
  >
137
145
  <LabeledInput
138
- v-model:value="serverConfig['cluster-domain']"
146
+ :value="serverConfig['cluster-domain']"
139
147
  :mode="mode"
140
148
  :disabled="isEdit"
141
149
  :label="t('cluster.rke2.address.domain.label')"
150
+ @update:value="$emit('cluster-domain-changed', $event)"
142
151
  />
143
152
  </div>
144
153
  </div>
@@ -149,9 +158,10 @@ export default {
149
158
  >
150
159
  <div class="col span-6">
151
160
  <LabeledInput
152
- v-model:value="serverConfig['service-node-port-range']"
161
+ :value="serverConfig['service-node-port-range']"
153
162
  :mode="mode"
154
163
  :label="t('cluster.rke2.address.nodePortRange.label')"
164
+ @update:value="$emit('service-node-port-range-changed', $event)"
155
165
  />
156
166
  </div>
157
167
  <div
@@ -165,7 +175,7 @@ export default {
165
175
  :mode="mode"
166
176
  :label="t('cluster.rke2.truncateHostnames')"
167
177
  data-testid="network-tab-truncate-hostname"
168
- @update:value="$emit('truncate-hostname', $event)"
178
+ @update:value="$emit('truncate-hostname-changed', $event)"
169
179
  />
170
180
  <Banner
171
181
  v-if="hostnameTruncationManuallySet"
@@ -184,18 +194,21 @@ export default {
184
194
  >
185
195
  <div class="col span-6">
186
196
  <ArrayList
187
- v-model:value="serverConfig['tls-san']"
197
+ :value="serverConfig['tls-san']"
188
198
  :protip="false"
189
199
  :mode="mode"
190
200
  :title="t('cluster.rke2.address.tlsSan.label')"
201
+ @update:value="$emit('tls-san-changed', $event)"
191
202
  />
192
203
  </div>
193
204
  </div>
194
-
205
+ <h3 v-t="'cluster.tabs.ace'" />
195
206
  <ACE
196
- v-model:value="localValue"
207
+ v-model:value="localValue.spec.localClusterAuthEndpoint"
197
208
  :mode="mode"
198
- @update:value="$emit('input', $event)"
209
+ @fqdn-changed="$emit('fqdn-changed', $event)"
210
+ @caCerts-changed="$emit('ca-certs-changed', $event)"
211
+ @local-cluster-auth-endpoint-changed="$emit('local-cluster-auth-endpoint-changed', $event)"
199
212
  />
200
213
  </div>
201
214
  </template>
@@ -206,7 +206,7 @@ export default {
206
206
  case TYPES.TLS:
207
207
  return this.t('secret.certificate.certificate');
208
208
  case TYPES.SSH:
209
- return this.t('secret.ssh.keys');
209
+ return this.value.supportsSshKnownHosts ? this.t('secret.ssh.keysAndHosts') : this.t('secret.ssh.keys');
210
210
  case TYPES.BASIC:
211
211
  return this.t('secret.authentication');
212
212
  default:
@@ -20,16 +20,21 @@ export default {
20
20
  data() {
21
21
  const username = this.value.decodedData['ssh-publickey'] || '';
22
22
  const password = this.value.decodedData['ssh-privatekey'] || '';
23
+ const knownHosts = this.value.decodedData['known_hosts'] || '';
24
+ const showKnownHosts = this.value.supportsSshKnownHosts;
23
25
 
24
26
  return {
25
27
  username,
26
28
  password,
29
+ knownHosts,
30
+ showKnownHosts,
27
31
  };
28
32
  },
29
33
 
30
34
  watch: {
31
- username: 'update',
32
- password: 'update',
35
+ username: 'update',
36
+ password: 'update',
37
+ knownHosts: 'update'
33
38
  },
34
39
 
35
40
  methods: {
@@ -39,8 +44,9 @@ export default {
39
44
  update() {
40
45
  this.value.setData('ssh-publickey', this.username);
41
46
  this.value.setData('ssh-privatekey', this.password);
47
+ this.value.setData('known_hosts', this.knownHosts);
42
48
  }
43
- },
49
+ }
44
50
  };
45
51
  </script>
46
52
 
@@ -78,5 +84,17 @@ export default {
78
84
  />
79
85
  </div>
80
86
  </div>
87
+ <div class="row mt-40">
88
+ <div class="col span-12">
89
+ <LabeledInput
90
+ v-if="showKnownHosts"
91
+ v-model:value="knownHosts"
92
+ type="multiline"
93
+ :label="t('secret.ssh.knownHosts')"
94
+ :mode="mode"
95
+ :placeholder="t('secret.ssh.knownHostsPlaceholder')"
96
+ />
97
+ </div>
98
+ </div>
81
99
  </div>
82
100
  </template>
package/edit/service.vue CHANGED
@@ -259,7 +259,6 @@ export default {
259
259
  methods: {
260
260
  updateMatchingPods: throttle(function() {
261
261
  const { value: { spec: { selector = { } } } } = this;
262
- // See https://github.com/rancher/dashboard/issues/10417, all pods bad, need to replace local selector somehow
263
262
  const allInNamespace = this.allPods.filter((pod) => pod.metadata.namespace === this.value?.metadata?.namespace);
264
263
 
265
264
  if (isEmpty(selector)) {
@@ -287,7 +286,7 @@ export default {
287
286
 
288
287
  const hash = {
289
288
  provClusters: this.$store.dispatch('management/findAll', { type: CAPI.RANCHER_CLUSTER }),
290
- pods: this.$store.dispatch(`${ inStore }/findAll`, { type: POD }),
289
+ pods: this.$store.dispatch(`${ inStore }/findAll`, { type: POD }), // Used in conjunction with `matches/match/label selectors`. Requires https://github.com/rancher/dashboard/issues/10417 to fix
291
290
  harvesterConfigs: this.$store.dispatch(`management/findAll`, { type: HCI.HARVESTER_CONFIG }),
292
291
  };
293
292
 
@@ -20,7 +20,7 @@ export default {
20
20
 
21
21
  methods: {
22
22
  /**
23
- * opts: FetchSecondaryResourcesOpts
23
+ * of type PagTableFetchSecondaryResources
24
24
  */
25
25
  async fetchSecondaryResources(opts) {
26
26
  // pathExistsInSchema requires schema networking.k8s.io.ingress to have resources fields via schema definition but none were found. has the schema 'fetchResourceFields' been called?