@rancher/shell 0.1.3 → 0.1.21

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 (245) hide show
  1. package/assets/brand/suse/dark/rancher-logo.svg +1 -148
  2. package/assets/brand/suse/favicon.png +0 -0
  3. package/assets/brand/suse/rancher-logo.svg +1 -130
  4. package/assets/images/featured/img1.jpg +0 -0
  5. package/assets/images/featured.jpg +0 -0
  6. package/assets/images/generic-plugin.svg +1 -0
  7. package/assets/styles/themes/_dark.scss +3 -0
  8. package/assets/styles/themes/_light.scss +3 -0
  9. package/assets/styles/themes/_suse.scss +1 -1
  10. package/assets/translations/en-us.yaml +219 -47
  11. package/assets/translations/zh-hans.yaml +21 -24
  12. package/components/AsyncButton.vue +17 -2
  13. package/components/ButtonDropdown.vue +4 -0
  14. package/components/Carousel.vue +291 -0
  15. package/components/CommunityLinks.vue +64 -22
  16. package/components/CruResource.vue +11 -3
  17. package/components/Dialog.vue +102 -0
  18. package/components/ExplorerMembers.vue +2 -4
  19. package/components/ExplorerProjectsNamespaces.vue +25 -9
  20. package/components/IconMessage.vue +9 -1
  21. package/components/LazyImage.vue +21 -8
  22. package/components/LocaleSelector.vue +62 -29
  23. package/components/PromptRemove.vue +2 -2
  24. package/components/ResourceList/Masthead.vue +21 -1
  25. package/components/ResourceList/ResourceLoadingIndicator.vue +0 -8
  26. package/components/ResourceList/index.vue +9 -23
  27. package/components/ResourceTable.vue +7 -2
  28. package/components/SimpleBox.vue +6 -4
  29. package/components/SortableTable/index.vue +18 -25
  30. package/components/Tabbed/Tab.vue +5 -0
  31. package/components/Tabbed/index.vue +54 -9
  32. package/components/TypeDescription.vue +10 -1
  33. package/components/auth/Principal.vue +1 -0
  34. package/components/fleet/FleetBundles.vue +8 -3
  35. package/components/fleet/FleetClusters.vue +6 -0
  36. package/components/fleet/FleetRepos.vue +7 -1
  37. package/components/fleet/FleetSummary.vue +6 -0
  38. package/components/form/Command.vue +5 -0
  39. package/components/form/EnvVars.vue +5 -0
  40. package/components/form/KeyValue.vue +80 -58
  41. package/components/form/NameNsDescription.vue +13 -5
  42. package/components/form/NodeScheduling.vue +6 -1
  43. package/components/form/PodAffinity.vue +5 -0
  44. package/components/form/ResourceTabs/index.vue +5 -1
  45. package/components/form/ServiceNameSelect.vue +5 -0
  46. package/components/form/ValueFromResource.vue +7 -1
  47. package/components/formatter/ClusterLink.vue +3 -7
  48. package/components/nav/NamespaceFilter.vue +3 -3
  49. package/components/nav/TopLevelMenu.vue +12 -29
  50. package/config/home-links.js +155 -0
  51. package/config/labels-annotations.js +2 -1
  52. package/config/private-label.js +1 -1
  53. package/config/product/explorer.js +5 -4
  54. package/config/product/legacy.js +0 -47
  55. package/config/product/manager.js +0 -2
  56. package/config/product/multi-cluster-apps.js +0 -12
  57. package/config/product/settings.js +12 -1
  58. package/config/product/uiplugins.js +17 -0
  59. package/config/settings.js +23 -2
  60. package/config/types.js +5 -1
  61. package/config/uiplugins.js +117 -0
  62. package/config/version.js +17 -0
  63. package/content/docs/en-us/getting-started.md +1 -26
  64. package/core/plugin.ts +12 -0
  65. package/core/plugins.js +38 -2
  66. package/core/types.ts +6 -0
  67. package/creators/app/{.eslintignore → files/.eslintignore} +0 -0
  68. package/creators/app/{.eslintrc.js → files/.eslintrc.js} +0 -0
  69. package/creators/app/{.vscode → files/.vscode}/settings.json +0 -0
  70. package/creators/app/{babel.config.js → files/babel.config.js} +0 -0
  71. package/creators/app/{nuxt.config.js → files/nuxt.config.js} +0 -0
  72. package/creators/app/{tsconfig.json → files/tsconfig.json} +2 -1
  73. package/creators/app/init +16 -17
  74. package/creators/app/package.json +6 -0
  75. package/creators/pkg/{babel.config.js → files/babel.config.js} +0 -0
  76. package/creators/pkg/{index.ts → files/index.ts} +0 -0
  77. package/creators/pkg/{tsconfig.json → files/tsconfig.json} +13 -12
  78. package/creators/pkg/{vue.config.js → files/vue.config.js} +0 -0
  79. package/creators/pkg/init +1 -1
  80. package/creators/update/init +54 -0
  81. package/creators/update/package.json +20 -0
  82. package/creators/update/upgrade +56 -0
  83. package/creators/update/yarn-error.log +54 -0
  84. package/detail/provisioning.cattle.io.cluster.vue +3 -3
  85. package/detail/workload/index.vue +3 -2
  86. package/dialog/DiagnosticTimingsDialog.vue +116 -0
  87. package/dialog/RotateCertificatesDialog.vue +9 -3
  88. package/edit/auth/azuread.vue +28 -9
  89. package/edit/networking.k8s.io.ingress/index.vue +2 -2
  90. package/edit/persistentvolume/index.vue +51 -13
  91. package/edit/persistentvolumeclaim.vue +31 -13
  92. package/edit/pod.vue +27 -0
  93. package/edit/provisioning.cattle.io.cluster/rke2.vue +103 -24
  94. package/edit/service.vue +7 -5
  95. package/edit/workload/__tests__/Upgrading.test.ts +1 -0
  96. package/edit/workload/index.vue +32 -10
  97. package/edit/workload/mixins/workload.js +121 -126
  98. package/edit/workload/storage/ContainerMountPaths.vue +240 -0
  99. package/edit/workload/storage/Mount.vue +1 -0
  100. package/edit/workload/storage/awsElasticBlockStore.vue +20 -1
  101. package/edit/workload/storage/azureDisk.vue +22 -2
  102. package/edit/workload/storage/azureFile.vue +20 -2
  103. package/edit/workload/storage/csi/index.vue +23 -1
  104. package/edit/workload/storage/gcePersistentDisk.vue +20 -2
  105. package/edit/workload/storage/index.vue +33 -65
  106. package/edit/workload/storage/persistentVolumeClaim/index.vue +5 -0
  107. package/edit/workload/storage/secret.vue +6 -1
  108. package/edit/workload/storage/vsphereVolume.vue +11 -1
  109. package/layouts/default.vue +14 -8
  110. package/layouts/home.vue +9 -4
  111. package/layouts/plain.vue +10 -5
  112. package/list/catalog.cattle.io.app.vue +10 -9
  113. package/list/catalog.cattle.io.clusterrepo.vue +6 -61
  114. package/list/cis.cattle.io.clusterscan.vue +12 -12
  115. package/list/fleet.cattle.io.bundle.vue +33 -28
  116. package/list/fleet.cattle.io.cluster.vue +26 -22
  117. package/list/fleet.cattle.io.clustergroup.vue +6 -0
  118. package/list/fleet.cattle.io.clusterregistrationtoken.vue +28 -24
  119. package/list/fleet.cattle.io.gitrepo.vue +25 -14
  120. package/list/helm.cattle.io.projecthelmchart.vue +52 -33
  121. package/list/logging.banzaicloud.io.clusterflow.vue +7 -12
  122. package/list/logging.banzaicloud.io.flow.vue +7 -14
  123. package/list/management.cattle.io.cluster.vue +26 -15
  124. package/list/management.cattle.io.feature.vue +13 -8
  125. package/list/management.cattle.io.setting.vue +3 -3
  126. package/list/management.cattle.io.user.vue +38 -19
  127. package/list/monitoring.coreos.com.alertmanagerconfig.vue +8 -15
  128. package/list/namespace.vue +14 -1
  129. package/list/node.vue +13 -16
  130. package/list/persistentvolume.vue +16 -9
  131. package/list/persistentvolumeclaim.vue +5 -8
  132. package/list/provisioning.cattle.io.cluster.vue +35 -9
  133. package/list/service.vue +24 -12
  134. package/list/ui.cattle.io.navlink.vue +6 -0
  135. package/list/workload.vue +2 -2
  136. package/machine-config/harvester.vue +5 -3
  137. package/middleware/authenticated.js +6 -0
  138. package/mixins/resource-fetch.js +12 -18
  139. package/mixins/resource-manager.js +126 -0
  140. package/models/catalog.cattle.io.uiplugin.js +38 -0
  141. package/models/cluster/node.js +25 -2
  142. package/models/fleet.cattle.io.bundle.js +1 -1
  143. package/models/harvesterhci.io.management.cluster.js +11 -5
  144. package/models/pod.js +15 -5
  145. package/models/provisioning.cattle.io.cluster.js +16 -6
  146. package/models/workload.js +5 -3
  147. package/models/workload.service.js +10 -0
  148. package/nuxt.config.js +70 -25
  149. package/package.json +108 -109
  150. package/pages/auth/login.vue +11 -1
  151. package/pages/auth/verify.vue +9 -0
  152. package/pages/c/_cluster/apps/charts/index.vue +46 -1
  153. package/pages/c/_cluster/apps/charts/install.vue +10 -9
  154. package/pages/c/_cluster/explorer/index.vue +72 -9
  155. package/pages/c/_cluster/explorer/tools/index.vue +12 -5
  156. package/pages/c/_cluster/mcapps/index.vue +1 -1
  157. package/pages/c/_cluster/settings/DefaultLinksEditor.vue +108 -0
  158. package/pages/c/_cluster/settings/brand.vue +0 -40
  159. package/pages/c/_cluster/settings/links.vue +152 -0
  160. package/pages/c/_cluster/settings/performance.vue +90 -7
  161. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +232 -0
  162. package/pages/c/_cluster/uiplugins/InstallDialog.vue +293 -0
  163. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +300 -0
  164. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +125 -0
  165. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +261 -0
  166. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +122 -0
  167. package/pages/c/_cluster/uiplugins/index.vue +808 -0
  168. package/pages/diagnostic.vue +185 -101
  169. package/pages/docs/_doc.vue +3 -1
  170. package/pages/home.vue +21 -56
  171. package/pages/prefs.vue +108 -88
  172. package/pages/safeMode.vue +17 -0
  173. package/pages/support/index.vue +34 -137
  174. package/pkg/dynamic-importer.lib.js +4 -0
  175. package/plugins/dashboard-store/actions.js +19 -0
  176. package/plugins/dashboard-store/getters.js +20 -3
  177. package/plugins/dashboard-store/mutations.js +13 -7
  178. package/plugins/dashboard-store/resource-class.js +2 -2
  179. package/plugins/formatters.js +15 -0
  180. package/plugins/plugin.js +61 -6
  181. package/plugins/steve/getters.js +12 -0
  182. package/plugins/steve/mutations.js +1 -1
  183. package/plugins/steve/subscribe.js +94 -72
  184. package/plugins/steve/web-worker.steve-sub-worker.js +24 -15
  185. package/plugins/version.js +21 -0
  186. package/promptRemove/management.cattle.io.globalrole.vue +47 -0
  187. package/promptRemove/management.cattle.io.roletemplate.vue +47 -0
  188. package/promptRemove/mixin/roleDeletionCheck.js +97 -0
  189. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -7
  190. package/rancher-components/components/BadgeState/BadgeState.spec.ts +12 -0
  191. package/rancher-components/components/BadgeState/BadgeState.vue +107 -0
  192. package/rancher-components/components/BadgeState/index.ts +1 -0
  193. package/rancher-components/components/Banner/Banner.test.ts +13 -0
  194. package/rancher-components/components/Banner/Banner.vue +163 -0
  195. package/rancher-components/components/Banner/index.ts +1 -0
  196. package/rancher-components/components/Card/Card.vue +150 -0
  197. package/rancher-components/components/Card/index.ts +1 -0
  198. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +77 -0
  199. package/rancher-components/components/Form/Checkbox/Checkbox.vue +395 -0
  200. package/rancher-components/components/Form/Checkbox/index.ts +1 -0
  201. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +29 -0
  202. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +343 -0
  203. package/rancher-components/components/Form/LabeledInput/index.ts +1 -0
  204. package/rancher-components/components/Form/Radio/RadioButton.vue +270 -0
  205. package/rancher-components/components/Form/Radio/RadioGroup.vue +235 -0
  206. package/rancher-components/components/Form/Radio/index.ts +2 -0
  207. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +168 -0
  208. package/rancher-components/components/Form/TextArea/index.ts +1 -0
  209. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +107 -0
  210. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +137 -0
  211. package/rancher-components/components/Form/ToggleSwitch/index.ts +1 -0
  212. package/rancher-components/components/Form/index.ts +5 -0
  213. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +137 -0
  214. package/rancher-components/components/LabeledTooltip/index.ts +1 -0
  215. package/scripts/publish-shell.sh +40 -7
  216. package/scripts/record-deps.js +37 -0
  217. package/scripts/sync-shell-deps +37 -0
  218. package/scripts/test-plugins-build.sh +8 -5
  219. package/scripts/typegen.sh +84 -0
  220. package/store/auth.js +3 -0
  221. package/store/catalog.js +9 -8
  222. package/store/i18n.js +10 -1
  223. package/store/index.js +12 -3
  224. package/store/prefs.js +16 -0
  225. package/store/type-map.js +32 -5
  226. package/store/uiplugins.ts +15 -61
  227. package/types/shell/index.d.ts +3046 -0
  228. package/utils/__tests__/object.test.ts +0 -24
  229. package/utils/__tests__/selector.test.ts +1 -1
  230. package/utils/dynamic-importer.js +4 -0
  231. package/utils/favicon.js +8 -2
  232. package/utils/gc/gc-interval.ts +40 -0
  233. package/utils/gc/gc-root-store.js +76 -0
  234. package/utils/gc/gc-route-changed.ts +44 -0
  235. package/utils/gc/gc-types.ts +21 -0
  236. package/utils/gc/gc.ts +282 -0
  237. package/utils/grafana.js +2 -6
  238. package/utils/socket.js +41 -20
  239. package/utils/string.js +1 -7
  240. package/utils/validators/formRules/__tests__/index.test.ts +108 -0
  241. package/utils/validators/formRules/index.ts +9 -1
  242. package/config/footer.js +0 -19
  243. package/creators/pkg/nuxt.config.js +0 -6
  244. package/pages/plugins.vue +0 -387
  245. package/server/verdaccio-middleware.js +0 -56
@@ -93,7 +93,7 @@ export default {
93
93
  fetchOne.snapshots = this.$store.dispatch('management/findAll', { type: SNAPSHOT });
94
94
  }
95
95
 
96
- if ( this.value.isImported || this.value.isCustom || this.value.isAKS || this.value.isEKS ) {
96
+ if ( this.value.isImported || this.value.isCustom || this.value.isHostedKubernetesProvider ) {
97
97
  fetchOne.clusterToken = this.value.getOrCreateToken();
98
98
  }
99
99
 
@@ -322,7 +322,7 @@ export default {
322
322
  },
323
323
 
324
324
  showEksNodeGroupWarning() {
325
- if ( this.value.isEKS ) {
325
+ if ( this.value.provisioner === 'EKS' ) {
326
326
  const desiredTotal = this.value.eksNodeGroups.filter(g => g.desiredSize === 0);
327
327
 
328
328
  if ( desiredTotal.length === this.value.eksNodeGroups.length ) {
@@ -451,7 +451,7 @@ export default {
451
451
  return true;
452
452
  }
453
453
 
454
- if ( ( this.value.isAKS || this.value.isEKS ) && !this.isClusterReady ) {
454
+ if ( this.value.isHostedKubernetesProvider && !this.isClusterReady ) {
455
455
  return true;
456
456
  }
457
457
 
@@ -121,7 +121,7 @@ export default {
121
121
  },
122
122
 
123
123
  isPod() {
124
- return this.value.type === WORKLOAD_TYPES.POD;
124
+ return this.value.type === POD;
125
125
  },
126
126
 
127
127
  podSchema() {
@@ -141,7 +141,8 @@ export default {
141
141
  return this.value.spec.jobTemplate.spec.template.spec;
142
142
  }
143
143
 
144
- if ( this.value.type === WORKLOAD_TYPES.POD ) {
144
+ // This is for viewing
145
+ if ( this.value.type === POD ) {
145
146
  return this.value;
146
147
  }
147
148
 
@@ -0,0 +1,116 @@
1
+ <script>
2
+ import { exceptionToErrorsArray } from '@shell/utils/error';
3
+
4
+ import AsyncButton from '@shell/components/AsyncButton';
5
+ import { Card } from '@components/Card';
6
+ import { Banner } from '@components/Banner';
7
+
8
+ export default {
9
+ components: {
10
+ Card,
11
+ AsyncButton,
12
+ Banner,
13
+ },
14
+
15
+ props: {
16
+ resources: {
17
+ type: Array,
18
+ required: true
19
+ }
20
+ },
21
+
22
+ data() {
23
+ return { errors: [] };
24
+ },
25
+
26
+ computed: {
27
+ config() {
28
+ return this.resources[0];
29
+ },
30
+
31
+ applyMode() {
32
+ return 'diagnostic';
33
+ },
34
+
35
+ title() {
36
+ return this.t('about.diagnostic.modal.title');
37
+ },
38
+
39
+ body() {
40
+ return this.t('about.diagnostic.modal.body');
41
+ }
42
+ },
43
+
44
+ methods: {
45
+ close() {
46
+ this.$emit('close');
47
+ },
48
+
49
+ apply(btnCb) {
50
+ try {
51
+ this.config.downloadData(btnCb);
52
+ this.close();
53
+ } catch (err) {
54
+ console.error(err); // eslint-disable-line
55
+ this.errors = exceptionToErrorsArray(err);
56
+ btnCb(false);
57
+ }
58
+ }
59
+ }
60
+ };
61
+ </script>
62
+
63
+ <template>
64
+ <Card class="prompt-restore" :show-highlight-border="false">
65
+ <h4 slot="title" class="text-default-text" v-html="title" />
66
+
67
+ <template slot="body">
68
+ <slot name="body">
69
+ <div class="pl-10 pr-10" style="min-height: 50px;">
70
+ <div class="row">
71
+ {{ body }}
72
+ </div>
73
+
74
+ <AsyncButton
75
+ mode="timing"
76
+ class="row mt-20"
77
+ @click="config.gatherResponseTimes"
78
+ />
79
+ </div>
80
+ </slot>
81
+ </template>
82
+
83
+ <div slot="actions" class="bottom">
84
+ <Banner v-for="(err, i) in errors" :key="i" color="error" :label="err" />
85
+ <div class="buttons">
86
+ <button class="btn role-secondary mr-10" @click="close">
87
+ {{ t('generic.cancel') }}
88
+ </button>
89
+
90
+ <AsyncButton
91
+ :mode="applyMode"
92
+ @click="apply"
93
+ />
94
+ </div>
95
+ </div>
96
+ </Card>
97
+ </template>
98
+ <style lang='scss' scoped>
99
+ .prompt-restore {
100
+ margin: 0;
101
+ }
102
+ .bottom {
103
+ display: flex;
104
+ flex-direction: column;
105
+ flex: 1;
106
+ .banner {
107
+ margin-top: 0
108
+ }
109
+ .buttons {
110
+ display: flex;
111
+ justify-content: flex-end;
112
+ width: 100%;
113
+ }
114
+ }
115
+
116
+ </style>
@@ -40,19 +40,25 @@ export default {
40
40
 
41
41
  serviceOptions() {
42
42
  if (this.cluster.isRke2) {
43
- return [
43
+ const options = [
44
44
  'admin',
45
45
  'api-server',
46
46
  'controller-manager',
47
47
  'scheduler',
48
- 'rke2-controller',
49
- 'rke2-server',
50
48
  'cloud-controller',
51
49
  'etcd',
52
50
  'auth-proxy',
53
51
  'kubelet',
54
52
  'kube-proxy'
55
53
  ];
54
+
55
+ if ( this.cluster.isK3s ) {
56
+ options.push('k3s-controller', 'k3s-server');
57
+ } else {
58
+ options.push('rke2-controller', 'rke2-server');
59
+ }
60
+
61
+ return options.sort();
56
62
  }
57
63
  // For RKE1 clusters, Norman provides the list of service options:
58
64
  // type RotateCertificateInput struct {
@@ -1,4 +1,5 @@
1
1
  <script>
2
+ import isEqual from 'lodash/isEqual';
2
3
  import Loading from '@shell/components/Loading';
3
4
  import CreateEditView from '@shell/mixins/create-edit-view';
4
5
  import CruResource from '@shell/components/CruResource';
@@ -76,6 +77,8 @@ export default {
76
77
  data() {
77
78
  return {
78
79
  endpoint: 'standard',
80
+ oldEndpoint: false,
81
+
79
82
  // Storing the applicationSecret is necessary because norman doesn't support returning secrets and when we
80
83
  // override the steve authconfig with a norman config the applicationSecret is lost
81
84
  applicationSecret: this.value.applicationSecret
@@ -147,9 +150,6 @@ export default {
147
150
  handler() {
148
151
  this.model.accessMode = this.model.accessMode || 'unrestricted';
149
152
  this.model.rancherUrl = this.model.rancherUrl || this.replyUrl;
150
- if (this.endpoint !== 'custom') {
151
- this.setEndpoints(this.endpoint);
152
- }
153
153
 
154
154
  if (this.model.applicationSecret) {
155
155
  this.$set(this, 'applicationSecret', this.model.applicationSecret);
@@ -162,11 +162,13 @@ export default {
162
162
  methods: {
163
163
  setEndpoints(endpoint) {
164
164
  if (this.editConfig || !this.model.enabled) {
165
- Object.keys(ENDPOINT_MAPPING[endpoint]).forEach((key) => {
165
+ const endpointType = this.oldEndpoint && endpoint !== 'custom' ? OLD_ENDPOINTS : ENDPOINT_MAPPING;
166
+
167
+ Object.keys(endpointType[endpoint]).forEach((key) => {
166
168
  this.$set(
167
169
  this.model,
168
170
  key,
169
- ENDPOINT_MAPPING[endpoint][key].replace(
171
+ endpointType[endpoint][key].replace(
170
172
  TENANT_ID_TOKEN,
171
173
  this.model.tenantId
172
174
  )
@@ -176,13 +178,30 @@ export default {
176
178
  },
177
179
 
178
180
  setInitialEndpoint(endpoint) {
179
- const endpointKey = Object.keys(ENDPOINT_MAPPING).find(key => ENDPOINT_MAPPING[key].graphEndpoint === endpoint);
181
+ const newEndpointKey = this.determineEndpointKeyType(ENDPOINT_MAPPING);
182
+ const oldEndpointKey = Object.keys(OLD_ENDPOINTS).find(key => OLD_ENDPOINTS[key].graphEndpoint === endpoint);
180
183
 
181
- if ( endpointKey ) {
182
- this.endpoint = endpointKey;
184
+ if ( oldEndpointKey ) {
185
+ this.endpoint = this.determineEndpointKeyType(OLD_ENDPOINTS);
186
+ this.oldEndpoint = true;
183
187
  } else {
184
- this.endpoint = 'custom';
188
+ this.endpoint = newEndpointKey;
189
+ }
190
+ },
191
+
192
+ determineEndpointKeyType(endpointTypes) {
193
+ let out = 'custom';
194
+
195
+ for ( const [endpointKey, endpointKeyValues] of Object.entries(endpointTypes) ) {
196
+ const mappedValues = Object.values(endpointKeyValues).map(endpoint => endpoint.replace(TENANT_ID_TOKEN, this.model?.tenantId));
197
+ const valuesToCheck = Object.keys(endpointKeyValues).map(key => this.value[key]);
198
+
199
+ if ( isEqual(mappedValues, valuesToCheck) ) {
200
+ out = endpointKey;
201
+ }
185
202
  }
203
+
204
+ return out;
186
205
  },
187
206
 
188
207
  getNewApplicationSecret() {
@@ -65,7 +65,7 @@ export default {
65
65
  path: 'metadata.name', rules: ['required', 'hostname'], translationKey: 'nameNsDescription.name.label'
66
66
  },
67
67
  {
68
- path: 'spec.rules.host', rules: ['hostname'], translationKey: 'ingress.rules.requestHost.label'
68
+ path: 'spec.rules.host', rules: ['wildcardHostname'], translationKey: 'ingress.rules.requestHost.label'
69
69
  },
70
70
  {
71
71
  path: 'spec.rules.http.paths.path', rules: ['absolutePath'], translationKey: 'ingress.rules.path.label'
@@ -83,7 +83,7 @@ export default {
83
83
  {
84
84
  path: 'spec.defaultBackend.service.port.number', rules: ['required', 'requiredInt', 'portNumber'], translationKey: 'ingress.defaultBackend.port.label'
85
85
  },
86
- { path: 'spec.tls.hosts', rules: ['required', 'hostname'] }
86
+ { path: 'spec.tls.hosts', rules: ['required', 'wildcardHostname'] }
87
87
  ],
88
88
  fvReportedValidationPaths: ['spec.rules.http.paths.backend.service.port.number', 'spec.rules.http.paths.path', 'spec.rules.http.paths.backend.service.name']
89
89
  };
@@ -1,4 +1,5 @@
1
1
  <script>
2
+ import { mapGetters } from 'vuex';
2
3
  import CreateEditView from '@shell/mixins/create-edit-view';
3
4
  import CruResource from '@shell/components/CruResource';
4
5
  import NameNsDescription from '@shell/components/form/NameNsDescription';
@@ -15,10 +16,11 @@ import UnitInput from '@shell/components/form/UnitInput';
15
16
  import { NODE, PVC, STORAGE_CLASS } from '@shell/config/types';
16
17
  import Loading from '@shell/components/Loading';
17
18
  import { LONGHORN_PLUGIN, VOLUME_PLUGINS } from '@shell/models/persistentvolume';
18
- import { _CREATE, _VIEW } from '@shell/config/query-params';
19
+ import { _CREATE, _VIEW, _EDIT } from '@shell/config/query-params';
19
20
  import { clone } from '@shell/utils/object';
20
21
  import InfoBox from '@shell/components/InfoBox';
21
22
  import { mapFeature, UNSUPPORTED_STORAGE_DRIVERS } from '@shell/store/features';
23
+ import ResourceManager from '@shell/mixins/resource-manager';
22
24
 
23
25
  export default {
24
26
  name: 'PersistentVolume',
@@ -39,18 +41,26 @@ export default {
39
41
  UnitInput
40
42
  },
41
43
 
42
- mixins: [CreateEditView],
44
+ mixins: [CreateEditView, ResourceManager],
43
45
 
44
- async fetch() {
45
- const storageClasses = await this.$store.dispatch('cluster/findAll', { type: STORAGE_CLASS });
46
+ fetch() {
47
+ if (this.mode === _EDIT) {
48
+ this.secondaryResourceData.namespace = this.value?.spec?.claimRef?.namespace || null;
46
49
 
47
- await this.$store.dispatch('cluster/findAll', { type: PVC });
50
+ this.secondaryResourceData.data[PVC] = {
51
+ applyTo: [
52
+ {
53
+ var: 'currentClaim',
54
+ classify: true,
55
+ parsingFunc: (data) => {
56
+ return data.find(claim => claim.spec.volumeName === this.value.name);
57
+ }
58
+ }
59
+ ]
60
+ };
61
+ }
48
62
 
49
- this.storageClassOptions = storageClasses.map(s => ({
50
- label: s.name,
51
- value: s.name
52
- }));
53
- this.storageClassOptions.unshift(this.NONE_OPTION);
63
+ this.resourceManagerFetchSecondaryResources(this.secondaryResourceData);
54
64
  },
55
65
 
56
66
  data() {
@@ -70,7 +80,30 @@ export default {
70
80
  const plugin = (foundPlugin || VOLUME_PLUGINS[0]).value;
71
81
 
72
82
  return {
83
+ secondaryResourceData: {
84
+ namespace: null,
85
+ data: {
86
+ [STORAGE_CLASS]: {
87
+ applyTo: [
88
+ {
89
+ var: 'storageClassOptions',
90
+ parsingFunc: (data) => {
91
+ const storageClassOptions = data.map(s => ({
92
+ label: s.metadata.name,
93
+ value: s.metadata.name
94
+ }));
95
+
96
+ storageClassOptions.unshift(this.NONE_OPTION);
97
+
98
+ return storageClassOptions;
99
+ }
100
+ }
101
+ ]
102
+ },
103
+ }
104
+ },
73
105
  storageClassOptions: [],
106
+ currentClaim: null,
74
107
  plugin,
75
108
  NONE_OPTION,
76
109
  NODE,
@@ -80,6 +113,7 @@ export default {
80
113
 
81
114
  computed: {
82
115
  showUnsupportedStorage: mapFeature(UNSUPPORTED_STORAGE_DRIVERS),
116
+ ...mapGetters(['currentProduct', 'currentCluster']),
83
117
 
84
118
  readWriteOnce: {
85
119
  get() {
@@ -196,12 +230,12 @@ export default {
196
230
  :namespaced="false"
197
231
  />
198
232
 
199
- <InfoBox v-if="value.claim">
233
+ <InfoBox v-if="currentClaim">
200
234
  <div class="row">
201
235
  <div class="col span-6 text-center">
202
236
  <label class="text-muted">Persistent Volume Claim:</label>&nbsp;
203
- <n-link :to="value.claim.detailLocation">
204
- {{ value.claim.namespacedName }}
237
+ <n-link :to="currentClaim.detailLocation">
238
+ {{ currentClaim.namespacedName }}
205
239
  </n-link>
206
240
  </div>
207
241
  <div class="col span-6 text-center">
@@ -267,6 +301,7 @@ export default {
267
301
  v-model="value.spec.storageClassName"
268
302
  :label="t('persistentVolume.customize.assignToStorageClass.label')"
269
303
  :options="storageClassOptions"
304
+ :loading="isLoadingSecondaryResources"
270
305
  />
271
306
  </div>
272
307
  </div>
@@ -295,4 +330,7 @@ export default {
295
330
  max-height: 100%;
296
331
  height: 100%;
297
332
  }
333
+ .info-box {
334
+ flex-grow: 0;
335
+ }
298
336
  </style>
@@ -15,6 +15,7 @@ import StatusTable from '@shell/components/StatusTable';
15
15
  import ResourceTabs from '@shell/components/form/ResourceTabs';
16
16
  import Labels from '@shell/components/form/Labels';
17
17
  import { Banner } from '@components/Banner';
18
+ import ResourceManager from '@shell/mixins/resource-manager';
18
19
 
19
20
  const DEFAULT_STORAGE = '10Gi';
20
21
 
@@ -36,26 +37,17 @@ export default {
36
37
  UnitInput,
37
38
  },
38
39
 
39
- mixins: [CreateEditView],
40
+ mixins: [CreateEditView, ResourceManager],
40
41
  async fetch() {
41
42
  const storageClasses = await this.$store.dispatch('cluster/findAll', { type: STORAGE_CLASS });
42
43
 
43
44
  if (this.$store.getters['management/canList'](PV)) {
44
- this.persistentVolumes = await this.$store.dispatch('cluster/findAll', { type: PV });
45
+ this.resourceManagerFetchSecondaryResources(this.secondaryResourceData);
45
46
  }
46
47
 
47
48
  this.storageClassOptions = storageClasses.map(s => s.name).sort();
48
49
  this.storageClassOptions.unshift(this.t('persistentVolumeClaim.useDefault'));
49
- this.persistentVolumeOptions = this.persistentVolumes
50
- .map((s) => {
51
- const status = s.status.phase === 'Available' ? '' : ` (${ s.status.phase })`;
52
50
 
53
- return {
54
- label: `${ s.name }${ status }`,
55
- value: s.name
56
- };
57
- })
58
- .sort((l, r) => l.label.localeCompare(r.label));
59
51
  this.$set(this.value.spec, 'storageClassName', this.value.spec.storageClassName || this.storageClassOptions[0]);
60
52
  },
61
53
  data() {
@@ -85,6 +77,31 @@ export default {
85
77
  const defaultTab = this.$route.query[FOCUS] || null;
86
78
 
87
79
  return {
80
+ secondaryResourceData: {
81
+ namespace: this.value?.metadata?.namespace || null,
82
+ data: {
83
+ [PV]: {
84
+ applyTo: [
85
+ { var: 'persistentVolumes' },
86
+ {
87
+ var: 'persistentVolumeOptions',
88
+ parsingFunc: (data) => {
89
+ return data
90
+ .map((s) => {
91
+ const status = s.status.phase === 'Available' ? '' : ` (${ s.status.phase })`;
92
+
93
+ return {
94
+ label: `${ s.metadata.name }${ status }`,
95
+ value: s.metadata.name
96
+ };
97
+ })
98
+ .sort((l, r) => l.label.localeCompare(r.label));
99
+ }
100
+ }
101
+ ]
102
+ },
103
+ }
104
+ },
88
105
  sourceOptions,
89
106
  source: this.value.spec.volumeName ? sourceOptions[1].value : sourceOptions[0].value,
90
107
  immutableMode: this.realMode === _CREATE ? _CREATE : _VIEW,
@@ -126,7 +143,7 @@ export default {
126
143
  return this.value.spec.volumeName;
127
144
  },
128
145
  set(value) {
129
- const persistentVolume = this.persistentVolumes.find(pv => pv.name === value);
146
+ const persistentVolume = this.persistentVolumes.find(pv => pv.metadata.name === value);
130
147
 
131
148
  if (persistentVolume) {
132
149
  this.$set(this.value.spec.resources.requests, 'storage', persistentVolume.spec.capacity?.storage);
@@ -170,7 +187,7 @@ export default {
170
187
  }
171
188
  },
172
189
  isPersistentVolumeSelectable(option) {
173
- const persistentVolume = this.persistentVolumes.find(pv => pv.name === option.value);
190
+ const persistentVolume = this.persistentVolumes.find(pv => pv.metadata.name === option.value);
174
191
 
175
192
  return persistentVolume.status.phase === 'Available';
176
193
  },
@@ -248,6 +265,7 @@ export default {
248
265
  :label="t('persistentVolumeClaim.volumeClaim.persistentVolume')"
249
266
  :selectable="isPersistentVolumeSelectable"
250
267
  :mode="immutableMode"
268
+ :loading="isLoadingSecondaryResources"
251
269
  />
252
270
  <LabeledInput
253
271
  v-else
package/edit/pod.vue ADDED
@@ -0,0 +1,27 @@
1
+ <script>
2
+ import CreateEditView from '@shell/mixins/create-edit-view';
3
+ import FormValidation from '@shell/mixins/form-validation';
4
+ import WorkLoadMixin from '@shell/edit/workload/mixins/workload';
5
+ import Workload from '@shell/edit/workload/index.vue';
6
+
7
+ export default {
8
+ name: 'WorkloadDeployments',
9
+ components: { Workload },
10
+ mixins: [CreateEditView, FormValidation, WorkLoadMixin],
11
+ props: {
12
+ value: {
13
+ type: Object,
14
+ required: true,
15
+ },
16
+
17
+ mode: {
18
+ type: String,
19
+ default: 'create',
20
+ },
21
+ },
22
+ };
23
+ </script>
24
+
25
+ <template>
26
+ <Workload v-bind="$props" />
27
+ </template>