@rancher/shell 0.3.4 → 0.3.6

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 (289) hide show
  1. package/assets/images/providers/outscale.svg +19 -0
  2. package/assets/styles/app.scss +1 -1
  3. package/assets/styles/base/_basic.scss +18 -0
  4. package/assets/styles/base/_mixins.scss +0 -11
  5. package/assets/styles/base/_variables.scss +2 -4
  6. package/assets/styles/fonts/_fontstack.scss +11 -11
  7. package/assets/styles/global/_button.scss +12 -2
  8. package/assets/styles/vendor/vue-js-modal.scss +3 -3
  9. package/assets/translations/en-us.yaml +113 -22
  10. package/assets/translations/zh-hans.yaml +113 -24
  11. package/babel.config.js +13 -0
  12. package/chart/gatekeeper.vue +78 -0
  13. package/chart/istio.vue +135 -112
  14. package/chart/logging/index.vue +13 -4
  15. package/chart/monitoring/index.vue +15 -5
  16. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  17. package/chart/rancher-backup/index.vue +10 -3
  18. package/cloud-credential/aws.vue +1 -1
  19. package/cloud-credential/digitalocean.vue +1 -1
  20. package/cloud-credential/gcp.vue +1 -1
  21. package/cloud-credential/generic.vue +2 -2
  22. package/cloud-credential/linode.vue +1 -1
  23. package/cloud-credential/pnap.vue +1 -1
  24. package/components/ActionMenu.vue +3 -4
  25. package/components/AssignTo.vue +1 -1
  26. package/components/AsyncButton.vue +1 -1
  27. package/components/BannerGraphic.vue +1 -1
  28. package/components/BrandImage.vue +1 -4
  29. package/components/ButtonDropdown.vue +2 -3
  30. package/components/Carousel.vue +85 -37
  31. package/components/ChartPsp.vue +76 -0
  32. package/components/CruResource.vue +6 -2
  33. package/components/DashboardMetrics.vue +12 -10
  34. package/components/DetailText.vue +1 -1
  35. package/components/DisableAuthProviderModal.vue +1 -1
  36. package/components/EmberPage.vue +1 -1
  37. package/components/EtcdInfoBanner.vue +12 -7
  38. package/components/ExplorerMembers.vue +101 -6
  39. package/components/ExplorerProjectsNamespaces.vue +46 -3
  40. package/components/FileDiff.vue +6 -7
  41. package/components/GrafanaDashboard.vue +27 -23
  42. package/components/LazyImage.vue +10 -12
  43. package/components/LogItem.vue +1 -1
  44. package/components/Markdown.vue +1 -1
  45. package/components/PromptRemove.vue +2 -2
  46. package/components/PromptRestore.vue +1 -1
  47. package/components/ResourceDetail/Masthead.vue +16 -0
  48. package/components/ResourceDetail/index.vue +21 -4
  49. package/components/ResourceList/index.vue +1 -1
  50. package/components/ResourceTable.vue +4 -1
  51. package/components/SingleClusterInfo.vue +2 -2
  52. package/components/SortableTable/THead.vue +1 -1
  53. package/components/SortableTable/index.vue +28 -13
  54. package/components/SortableTable/selection.js +58 -50
  55. package/components/Wizard.vue +4 -2
  56. package/components/__tests__/AsyncButton.test.ts +3 -1
  57. package/components/__tests__/ChartPsp.test.ts +75 -0
  58. package/components/__tests__/CruResource.test.ts +3 -1
  59. package/components/auth/Principal.vue +1 -1
  60. package/components/auth/RoleDetailEdit.vue +2 -2
  61. package/components/fleet/FleetBundles.vue +3 -1
  62. package/components/fleet/FleetClusters.vue +1 -2
  63. package/components/fleet/FleetIntro.vue +9 -1
  64. package/components/fleet/FleetNoWorkspaces.vue +62 -0
  65. package/components/fleet/FleetSummary.vue +7 -1
  66. package/components/form/HookOption.vue +14 -10
  67. package/components/form/LabeledSelect.vue +14 -11
  68. package/components/form/Labels.vue +32 -27
  69. package/components/form/MatchExpressions.vue +19 -4
  70. package/components/form/Members/ClusterPermissionsEditor.vue +32 -7
  71. package/components/form/NameNsDescription.vue +32 -46
  72. package/components/form/ProjectMemberEditor.vue +46 -21
  73. package/components/form/ResourceSelector.vue +1 -1
  74. package/components/form/SecretSelector.vue +5 -1
  75. package/components/form/ServiceNameSelect.vue +1 -1
  76. package/components/form/SimpleSecretSelector.vue +9 -9
  77. package/components/form/Tolerations.vue +4 -1
  78. package/components/form/ValueFromResource.vue +14 -9
  79. package/components/form/WorkloadPorts.vue +2 -2
  80. package/components/form/__tests__/LabeledSelect.test.ts +138 -0
  81. package/components/form/__tests__/NameNsDescription.ts +59 -0
  82. package/components/formatter/InternalExternalIP.vue +6 -0
  83. package/components/formatter/InvolvedObjectLink.vue +54 -0
  84. package/components/formatter/Link.vue +20 -4
  85. package/components/formatter/LinkName.vue +6 -1
  86. package/components/formatter/ServiceTargets.vue +1 -1
  87. package/components/formatter/WorkloadHealthScale.vue +8 -2
  88. package/components/nav/Group.vue +2 -2
  89. package/components/nav/NamespaceFilter.vue +23 -11
  90. package/components/nav/TopLevelMenu.vue +2 -4
  91. package/components/nav/Type.vue +1 -1
  92. package/components/nav/WorkspaceSwitcher.vue +46 -5
  93. package/components/nuxt/nuxt-build-indicator.vue +143 -0
  94. package/components/nuxt/nuxt-child.js +122 -0
  95. package/components/nuxt/nuxt-error.vue +98 -0
  96. package/components/nuxt/nuxt-link.client.js +98 -0
  97. package/components/nuxt/nuxt-link.server.js +16 -0
  98. package/components/nuxt/nuxt-loading.vue +154 -0
  99. package/components/nuxt/nuxt.js +101 -0
  100. package/config/labels-annotations.js +17 -0
  101. package/config/middleware.js +12 -0
  102. package/config/product/auth.js +3 -2
  103. package/config/product/explorer.js +34 -6
  104. package/config/product/fleet.js +2 -0
  105. package/config/query-params.js +1 -0
  106. package/config/router.js +414 -0
  107. package/config/store.js +181 -0
  108. package/config/table-headers.js +54 -12
  109. package/config/types.js +18 -8
  110. package/config/uiplugins.js +30 -0
  111. package/content/docs/en-us/whats-new.md +10 -0
  112. package/content/docs/zh-hans/whats-new.md +11 -1
  113. package/core/plugin-routes.ts +23 -0
  114. package/core/plugin.ts +4 -2
  115. package/core/types.ts +258 -1
  116. package/creators/app/app.package.json +2 -1
  117. package/creators/app/files/.eslintrc.js +1 -1
  118. package/creators/app/files/babel.config.js +1 -18
  119. package/creators/app/files/tsconfig.json +0 -1
  120. package/creators/app/files/vue.config.js +6 -0
  121. package/creators/app/init +5 -5
  122. package/creators/pkg/files/.github/workflows/build-extension.yml +110 -0
  123. package/creators/pkg/files/tsconfig.json +0 -1
  124. package/creators/pkg/init +35 -4
  125. package/creators/pkg/pkg.package.json +3 -3
  126. package/creators/update/init +1 -1
  127. package/detail/constraints.gatekeeper.sh.constraint.vue +34 -17
  128. package/detail/fleet.cattle.io.clustergroup.vue +7 -1
  129. package/detail/fleet.cattle.io.gitrepo.vue +19 -11
  130. package/detail/harvesterhci.io.management.cluster.vue +3 -3
  131. package/detail/provisioning.cattle.io.cluster.vue +54 -12
  132. package/detail/workload/index.vue +3 -3
  133. package/dialog/AddClusterMemberDialog.vue +1 -1
  134. package/dialog/AddProjectMemberDialog.vue +2 -2
  135. package/dialog/AddonConfigConfirmationDialog.vue +27 -15
  136. package/dialog/DiagnosticTimingsDialog.vue +1 -1
  137. package/dialog/ForceMachineRemoveDialog.vue +1 -1
  138. package/dialog/GenericPrompt.vue +18 -6
  139. package/dialog/RotateEncryptionKeyDialog.vue +1 -1
  140. package/dialog/SaveAsRKETemplateDialog.vue +1 -1
  141. package/dialog/ScaleMachineDownDialog.vue +1 -1
  142. package/edit/auth/github.vue +8 -8
  143. package/edit/auth/googleoauth.vue +5 -5
  144. package/edit/auth/ldap/index.vue +1 -1
  145. package/edit/auth/oidc.vue +1 -1
  146. package/edit/auth/saml.vue +1 -1
  147. package/edit/cis.cattle.io.clusterscan.vue +1 -1
  148. package/edit/fleet.cattle.io.clustergroup.vue +6 -4
  149. package/edit/fleet.cattle.io.gitrepo.vue +32 -4
  150. package/edit/helm.cattle.io.projecthelmchart.vue +5 -1
  151. package/edit/logging.banzaicloud.io.output/index.vue +18 -5
  152. package/edit/logging.banzaicloud.io.output/providers/loki.vue +1 -0
  153. package/edit/management.cattle.io.fleetworkspace.vue +141 -6
  154. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +4 -1
  155. package/edit/management.cattle.io.setting.vue +1 -1
  156. package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +2 -2
  157. package/edit/monitoring.coreos.com.receiver/tls.vue +18 -18
  158. package/edit/monitoring.coreos.com.receiver/types/webhook.banner.vue +4 -4
  159. package/edit/monitoring.coreos.com.receiver/types/webhook.vue +1 -1
  160. package/edit/namespace.vue +14 -10
  161. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +126 -45
  162. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  163. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +21 -4
  164. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +1 -0
  165. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +202 -2
  166. package/edit/provisioning.cattle.io.cluster/import.vue +23 -25
  167. package/edit/provisioning.cattle.io.cluster/rke2.vue +344 -102
  168. package/edit/resources.cattle.io.backup.vue +1 -1
  169. package/edit/service.vue +1 -1
  170. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +2 -2
  171. package/edit/workload/__tests__/Job.test.ts +3 -1
  172. package/edit/workload/index.vue +8 -3
  173. package/edit/workload/mixins/workload.js +22 -7
  174. package/edit/workload/storage/Mount.vue +3 -3
  175. package/initialize/App.js +206 -0
  176. package/initialize/client.js +863 -0
  177. package/initialize/index.js +364 -0
  178. package/layouts/default.vue +7 -3
  179. package/layouts/standalone.vue +13 -0
  180. package/list/catalog.cattle.io.clusterrepo.vue +1 -0
  181. package/list/fleet.cattle.io.bundle.vue +6 -3
  182. package/list/fleet.cattle.io.clusterregistrationtoken.vue +3 -1
  183. package/list/fleet.cattle.io.gitrepo.vue +44 -5
  184. package/list/management.cattle.io.fleetworkspace.vue +45 -0
  185. package/list/node.vue +69 -16
  186. package/list/provisioning.cattle.io.cluster.vue +30 -1
  187. package/list/rbac.authorization.k8s.io.clusterrolebinding.vue +48 -0
  188. package/list/workload.vue +6 -4
  189. package/machine-config/azure.vue +97 -38
  190. package/middleware/authenticated.js +34 -0
  191. package/mixins/chart.js +101 -2
  192. package/mixins/fetch.client.js +95 -0
  193. package/mixins/fetch.server.js +73 -0
  194. package/mixins/labeled-form-element.ts +2 -2
  195. package/mixins/resource-fetch.js +2 -2
  196. package/models/apps.statefulset.js +28 -0
  197. package/models/cluster/node.js +23 -2
  198. package/models/cluster.x-k8s.io.machine.js +4 -2
  199. package/models/clusterroletemplatebinding.js +7 -0
  200. package/models/constraints.gatekeeper.sh.constraint.js +46 -0
  201. package/models/fleet.cattle.io.cluster.js +19 -10
  202. package/models/fleet.cattle.io.gitrepo.js +7 -2
  203. package/models/management.cattle.io.cluster.js +1 -1
  204. package/models/management.cattle.io.fleetworkspace.js +12 -0
  205. package/models/management.cattle.io.gitreporestriction.js +5 -0
  206. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.js +3 -0
  207. package/models/pod.js +4 -0
  208. package/models/provisioning.cattle.io.cluster.js +7 -5
  209. package/models/rbac.authorization.k8s.io.clusterrolebinding.js +16 -0
  210. package/models/rbac.authorization.k8s.io.rolebinding.js +16 -0
  211. package/package.json +13 -21
  212. package/pages/auth/setup.vue +2 -2
  213. package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +33 -0
  214. package/pages/c/_cluster/apps/charts/chart.vue +4 -4
  215. package/pages/c/_cluster/apps/charts/install.helpers.js +26 -0
  216. package/pages/c/_cluster/apps/charts/install.vue +98 -102
  217. package/pages/c/_cluster/explorer/EventsTable.vue +5 -19
  218. package/pages/c/_cluster/explorer/index.vue +29 -25
  219. package/pages/c/_cluster/explorer/tools/index.vue +8 -8
  220. package/pages/c/_cluster/fleet/index.vue +95 -34
  221. package/pages/c/_cluster/gatekeeper/index.vue +1 -1
  222. package/pages/c/_cluster/istio/index.vue +5 -5
  223. package/pages/c/_cluster/manager/cloudCredential/index.vue +1 -1
  224. package/pages/c/_cluster/monitoring/index.vue +7 -0
  225. package/pages/c/_cluster/uiplugins/InstallDialog.vue +8 -8
  226. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +20 -7
  227. package/pages/c/_cluster/uiplugins/index.vue +49 -17
  228. package/pages/diagnostic.vue +32 -25
  229. package/pages/home.vue +9 -4
  230. package/pages/index.vue +10 -1
  231. package/pages/rio/mesh.vue +1 -2
  232. package/pkg/tsconfig.json +0 -1
  233. package/plugins/clean-html-directive.js +34 -0
  234. package/plugins/dashboard-store/actions.js +32 -9
  235. package/plugins/dashboard-store/index.js +1 -1
  236. package/plugins/dashboard-store/mutations.js +5 -2
  237. package/plugins/dashboard-store/resource-class.js +8 -1
  238. package/plugins/plugin.js +0 -14
  239. package/plugins/portal-vue.js +4 -0
  240. package/plugins/steve/mutations.js +3 -2
  241. package/plugins/steve/steve-description-class.js +5 -1
  242. package/plugins/steve/subscribe.js +63 -54
  243. package/plugins/steve-create-worker.js +14 -0
  244. package/promptRemove/management.cattle.io.globalrole.vue +2 -2
  245. package/promptRemove/management.cattle.io.project.vue +2 -2
  246. package/promptRemove/management.cattle.io.roletemplate.vue +2 -2
  247. package/promptRemove/pod.vue +1 -1
  248. package/public/index.html +65 -0
  249. package/rancher-components/components/Banner/Banner.test.ts +7 -1
  250. package/rancher-components/components/Banner/Banner.vue +2 -1
  251. package/rancher-components/components/Form/Checkbox/Checkbox.vue +2 -0
  252. package/rancher-components/components/Form/Radio/RadioButton.test.ts +31 -0
  253. package/rancher-components/components/Form/Radio/RadioButton.vue +14 -3
  254. package/scripts/build-pkg.sh +1 -0
  255. package/scripts/clean +6 -0
  256. package/scripts/extension/bundle +58 -0
  257. package/scripts/extension/helmpatch +89 -0
  258. package/scripts/extension/publish +333 -0
  259. package/scripts/serve-pkgs +6 -2
  260. package/scripts/test-plugins-build.sh +4 -0
  261. package/store/__tests__/index.test.ts +110 -0
  262. package/store/index.js +145 -58
  263. package/store/type-map.js +6 -2
  264. package/tsconfig.default.json +36 -0
  265. package/tsconfig.json +23 -0
  266. package/types/rancher/index.d.ts +2 -0
  267. package/types/shell/index.d.ts +466 -320
  268. package/utils/__tests__/grafana.test.ts +44 -0
  269. package/utils/__tests__/string.test.ts +12 -0
  270. package/utils/auth.js +65 -0
  271. package/utils/axios.js +190 -0
  272. package/utils/cookie-universal-nuxt.js +10 -0
  273. package/utils/dom.js +15 -0
  274. package/utils/grafana.js +35 -16
  275. package/utils/monitoring.js +2 -1
  276. package/utils/nuxt.js +659 -0
  277. package/utils/position.js +5 -8
  278. package/utils/router.scrollBehavior.js +80 -0
  279. package/utils/select.js +1 -3
  280. package/utils/socket.js +1 -0
  281. package/utils/string.js +13 -0
  282. package/utils/time.js +9 -0
  283. package/vue.config.js +690 -0
  284. package/chart/rancher-alerting-drivers.vue +0 -53
  285. package/chart/rancher-gatekeeper.vue +0 -37
  286. package/creators/app/files/nuxt.config.js +0 -6
  287. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +0 -4
  288. package/nuxt.config.js +0 -798
  289. package/plugins/dashboard-store/extensions.js +0 -22
package/list/node.vue CHANGED
@@ -12,7 +12,6 @@ import {
12
12
  MANAGEMENT, METRIC, NODE, NORMAN, POD
13
13
  } from '@shell/config/types';
14
14
  import { allHash } from '@shell/utils/promise';
15
- import { get } from '@shell/utils/object';
16
15
  import { GROUP_RESOURCES, mapPref } from '@shell/store/prefs';
17
16
  import { COLUMN_BREAKPOINTS } from '@shell/components/SortableTable/index.vue';
18
17
  import ResourceFetch from '@shell/mixins/resource-fetch';
@@ -84,8 +83,17 @@ export default {
84
83
  hasWindowsNodes() {
85
84
  return (this.rows || []).some(node => node.status.nodeInfo.operatingSystem === 'windows');
86
85
  },
86
+
87
87
  tableGroup: mapPref(GROUP_RESOURCES),
88
88
 
89
+ parsedRows() {
90
+ this.rows.forEach((row) => {
91
+ row.displayTaintsAndLabels = (row.spec.taints && row.spec.taints.length) || !!row.customLabelCount;
92
+ });
93
+
94
+ return this.rows;
95
+ },
96
+
89
97
  headers() {
90
98
  const headers = [
91
99
  STATE,
@@ -119,7 +127,6 @@ export default {
119
127
 
120
128
  return headers;
121
129
  },
122
-
123
130
  },
124
131
 
125
132
  methods: {
@@ -136,8 +143,9 @@ export default {
136
143
  }
137
144
  },
138
145
 
139
- get,
140
-
146
+ toggleLabels(row) {
147
+ this.$set(row, 'displayLabels', !row.displayLabels);
148
+ },
141
149
  }
142
150
 
143
151
  };
@@ -154,7 +162,7 @@ export default {
154
162
  v-bind="$attrs"
155
163
  :schema="schema"
156
164
  :headers="headers"
157
- :rows="rows"
165
+ :rows="parsedRows"
158
166
  :sub-rows="true"
159
167
  :loading="loading"
160
168
  :use-query-params-for-simple-filtering="useQueryParamsForSimpleFiltering"
@@ -164,22 +172,54 @@ export default {
164
172
  <template #sub-row="{fullColspan, row, onRowMouseEnter, onRowMouseLeave}">
165
173
  <tr
166
174
  class="taints sub-row"
167
- :class="{'empty-taints': !row.spec.taints || !row.spec.taints.length}"
175
+ :class="{'empty-taints': ! row.displayTaintsAndLabels}"
168
176
  @mouseenter="onRowMouseEnter"
169
177
  @mouseleave="onRowMouseLeave"
170
178
  >
171
- <template v-if="row.spec.taints && row.spec.taints.length">
179
+ <template v-if="row.displayTaintsAndLabels">
172
180
  <td>&nbsp;</td>
173
181
  <td>&nbsp;</td>
174
182
  <td :colspan="fullColspan-2">
175
- {{ t('node.list.nodeTaint') }}:
176
- <Tag
177
- v-for="taint in row.spec.taints"
178
- :key="taint.key + taint.value + taint.effect"
179
- class="mr-5"
180
- >
181
- {{ taint.key }}={{ taint.value }}:{{ taint.effect }}
182
- </Tag>
183
+ <span v-if="row.spec.taints && row.spec.taints.length">
184
+ {{ t('node.list.nodeTaint') }}:
185
+ <Tag
186
+ v-for="taint in row.spec.taints"
187
+ :key="taint.key + taint.value + taint.effect"
188
+ class="mr-5 mt-2"
189
+ >
190
+ {{ taint.key }}={{ taint.value }}:{{ taint.effect }}
191
+ </Tag>
192
+ </span>
193
+ <span
194
+ v-if="!!row.customLabelCount"
195
+ class="mt-5"
196
+ > {{ t('node.list.nodeLabels') }}:
197
+ <span
198
+ v-for="(label, i) in row.customLabels"
199
+ :key="i"
200
+ class="mt-5 labels"
201
+ >
202
+ <Tag
203
+ v-if="i < 7"
204
+ class="mr-2 label"
205
+ >
206
+ {{ label }}
207
+ </Tag>
208
+ <Tag
209
+ v-else-if="i > 6 && row.displayLabels"
210
+ class="mr-2 label"
211
+ >
212
+ {{ label }}
213
+ </Tag>
214
+ </span>
215
+ <a
216
+ v-if="row.customLabelCount > 7"
217
+ href="#"
218
+ @click.prevent="toggleLabels(row)"
219
+ >
220
+ {{ t(`node.list.${row.displayLabels? 'hideLabels' : 'showLabels'}`) }}
221
+ </a>
222
+ </span>
183
223
  </td>
184
224
  </template>
185
225
  <td
@@ -195,11 +235,24 @@ export default {
195
235
  </template>
196
236
 
197
237
  <style lang='scss' scoped>
238
+
239
+ .labels {
240
+ display: inline;
241
+ flex-wrap: wrap;
242
+
243
+ .label {
244
+ display: inline-block;
245
+ margin-top: 2px;
246
+ }
247
+
248
+ }
198
249
  .taints {
199
250
  td {
200
251
  padding-top:0;
201
252
  .tag {
202
- margin-right: 5px
253
+ margin-right: 5px;
254
+ display: inline-block;
255
+ margin-top: 2px;
203
256
  }
204
257
  }
205
258
  &.empty-taints {
@@ -9,10 +9,11 @@ import { filterOnlyKubernetesClusters, filterHiddenLocalCluster } from '@shell/u
9
9
  import { mapFeature, HARVESTER as HARVESTER_FEATURE } from '@shell/store/features';
10
10
  import { NAME as EXPLORER } from '@shell/config/product/explorer';
11
11
  import ResourceFetch from '@shell/mixins/resource-fetch';
12
+ import { BadgeState } from '@components/BadgeState';
12
13
 
13
14
  export default {
14
15
  components: {
15
- Banner, ResourceTable, Masthead
16
+ Banner, ResourceTable, Masthead, BadgeState
16
17
  },
17
18
  mixins: [ResourceFetch],
18
19
  props: {
@@ -187,6 +188,34 @@ export default {
187
188
  :data-testid="'cluster-list'"
188
189
  :force-update-live-and-delayed="forceUpdateLiveAndDelayed"
189
190
  >
191
+ <!-- Why are state column and subrow overwritten here? -->
192
+ <!-- for rke1 clusters, where they try to use the mgmt cluster stateObj instead of prov cluster stateObj, -->
193
+ <!-- updates were getting lost. This isn't performant as normal columns, but the list shouldn't grow -->
194
+ <!-- big enough for the performance to matter -->
195
+ <template #cell:state="{row}">
196
+ <BadgeState
197
+ :color="row.stateBackground"
198
+ :label="row.stateDisplay"
199
+ />
200
+ </template>
201
+ <template #sub-row="{fullColspan, row, keyField, componentTestid, i, onRowMouseEnter, onRowMouseLeave}">
202
+ <tr
203
+ v-if="row.stateDescription"
204
+ :key="row[keyField] + '-description'"
205
+ :data-testid="componentTestid + '-' + i + '-row-description'"
206
+ class="state-description sub-row"
207
+ @mouseenter="onRowMouseEnter"
208
+ @mouseleave="onRowMouseLeave"
209
+ >
210
+ <td>&nbsp;</td>
211
+ <td
212
+ :colspan="fullColspan - 1"
213
+ :class="{ 'text-error' : row.stateObj.error }"
214
+ >
215
+ {{ row.stateDescription }}
216
+ </td>
217
+ </tr>
218
+ </template>
190
219
  <template #cell:summary="{row}">
191
220
  <span v-if="!row.stateParts.length">{{ row.nodes.length }}</span>
192
221
  </template>
@@ -0,0 +1,48 @@
1
+ <script>
2
+ import ResourceTable from '@shell/components/ResourceTable';
3
+
4
+ export default {
5
+ name: 'ListNamespace',
6
+ components: { ResourceTable },
7
+ props: {
8
+ resource: {
9
+ type: String,
10
+ required: true,
11
+ },
12
+ schema: {
13
+ type: Object,
14
+ required: true,
15
+ },
16
+ rows: {
17
+ type: Array,
18
+ required: true,
19
+ },
20
+ loading: {
21
+ type: Boolean,
22
+ required: false,
23
+ },
24
+ useQueryParamsForSimpleFiltering: {
25
+ type: Boolean,
26
+ default: false
27
+ }
28
+ },
29
+
30
+ $loadingResources() {
31
+ return { loadIndeterminate: true };
32
+ },
33
+ };
34
+ </script>
35
+
36
+ <template>
37
+ <div>
38
+ <ResourceTable
39
+ v-bind="$attrs"
40
+ :rows="rows"
41
+ :groupable="false"
42
+ :schema="schema"
43
+ :loading="loading"
44
+ :use-query-params-for-simple-filtering="useQueryParamsForSimpleFiltering"
45
+ v-on="$listeners"
46
+ />
47
+ </div>
48
+ </template>
package/list/workload.vue CHANGED
@@ -1,6 +1,8 @@
1
1
  <script>
2
2
  import ResourceTable from '@shell/components/ResourceTable';
3
- import { WORKLOAD_TYPES, SCHEMA, NODE, POD } from '@shell/config/types';
3
+ import {
4
+ WORKLOAD_TYPES, SCHEMA, NODE, POD, LIST_WORKLOAD_TYPES
5
+ } from '@shell/config/types';
4
6
  import ResourceFetch from '@shell/mixins/resource-fetch';
5
7
 
6
8
  const schema = {
@@ -16,7 +18,7 @@ const schema = {
16
18
  const $loadingResources = ($route, $store) => {
17
19
  const allowedResources = [];
18
20
 
19
- Object.values(WORKLOAD_TYPES).forEach((type) => {
21
+ Object.values(LIST_WORKLOAD_TYPES).forEach((type) => {
20
22
  // You may not have RBAC to see some of the types
21
23
  if ($store.getters['cluster/schemaFor'](type) ) {
22
24
  allowedResources.push(type);
@@ -134,8 +136,8 @@ export default {
134
136
  } else {
135
137
  const type = this.$route.params.resource;
136
138
 
137
- if (type === WORKLOAD_TYPES.JOB) {
138
- // Ignore job (we're fetching this anyway, plus they contain their own state)
139
+ if (type === WORKLOAD_TYPES.JOB || type === POD) {
140
+ // Ignore job and pods (we're fetching this anyway, plus they contain their own state)
139
141
  return;
140
142
  }
141
143
 
@@ -1,6 +1,7 @@
1
1
  <script>
2
2
  import Loading from '@shell/components/Loading';
3
3
  import CreateEditView from '@shell/mixins/create-edit-view';
4
+ import FormValidation from '@shell/mixins/form-validation';
4
5
  import { stringify, exceptionToErrorsArray } from '@shell/utils/error';
5
6
  import { Banner } from '@components/Banner';
6
7
  import merge from 'lodash/merge';
@@ -13,7 +14,7 @@ import { randomStr } from '@shell/utils/string';
13
14
  import { addParam, addParams } from '@shell/utils/url';
14
15
  import KeyValue from '@shell/components/form/KeyValue';
15
16
  import { RadioGroup } from '@components/Form/Radio';
16
- import { _CREATE } from '@shell/config/query-params';
17
+ import { _CREATE, _EDIT } from '@shell/config/query-params';
17
18
 
18
19
  export const azureEnvironments = [
19
20
  { value: 'AzurePublicCloud' },
@@ -105,7 +106,7 @@ export default {
105
106
  RadioGroup
106
107
  },
107
108
 
108
- mixins: [CreateEditView],
109
+ mixins: [CreateEditView, FormValidation],
109
110
 
110
111
  props: {
111
112
  credentialId: {
@@ -162,6 +163,17 @@ export default {
162
163
 
163
164
  if (this.mode === _CREATE) {
164
165
  this.value.location = DEFAULT_REGION;
166
+
167
+ // when you edit an Azure cluster and add a new machine pool (edit)
168
+ // the location field doesn't come populated which causes the vmSizes request
169
+ // to return 200 but with a null response (also a bunch of other fields are undefined...)
170
+ // so let's prefill them with the defaults
171
+ } else if (this.mode === _EDIT && !this.value?.location) {
172
+ for (const key in this.defaultConfig) {
173
+ if (this.value[key] === undefined) {
174
+ this.$set(this.value, key, this.defaultConfig[key]);
175
+ }
176
+ }
165
177
  }
166
178
 
167
179
  this.vmSizes = await this.$store.dispatch('management/request', {
@@ -171,30 +183,29 @@ export default {
171
183
  }),
172
184
  method: 'GET',
173
185
  });
186
+
187
+ // set correct option for useAvailabilitySet (will consider correct state for UI form based on availabilitySet)
188
+ if (this.mode === _CREATE) {
189
+ this.useAvailabilitySet = true;
190
+ } else {
191
+ this.useAvailabilitySet = !!this.value.availabilitySet;
192
+ }
174
193
  } catch (e) {
175
194
  this.errors = exceptionToErrorsArray(e);
176
195
  }
177
196
  },
178
197
 
179
198
  data() {
180
- let useAvailabilitySet = false;
181
-
182
- if (this.mode === _CREATE) {
183
- useAvailabilitySet = true;
184
- } else {
185
- useAvailabilitySet = !!this.value.availabilitySet;
186
- }
187
-
188
199
  return {
189
200
  azureEnvironments,
190
201
  defaultConfig,
191
202
  storageTypes,
192
- credential: null,
193
- locationOptions: [],
194
- loading: false,
195
- useAvailabilitySet,
196
- vmSizes: [],
197
- valueCopy: this.value
203
+ credential: null,
204
+ locationOptions: [],
205
+ loading: false,
206
+ useAvailabilitySet: false,
207
+ vmSizes: [],
208
+ valueCopy: this.value,
198
209
  };
199
210
  },
200
211
 
@@ -202,6 +213,12 @@ export default {
202
213
  credentialId() {
203
214
  this.$fetch();
204
215
  },
216
+
217
+ 'value.availabilityZone'(neu) {
218
+ if (neu && (!this.value.managedDisks || !this.value.enablePublicIpStandardSku || !this.value.staticPublicIp)) {
219
+ this.$emit('expandAdvanced');
220
+ }
221
+ }
205
222
  },
206
223
 
207
224
  computed: {
@@ -368,7 +385,7 @@ export default {
368
385
  }
369
386
 
370
387
  return [];
371
- }
388
+ },
372
389
  },
373
390
 
374
391
  created() {
@@ -610,7 +627,7 @@ export default {
610
627
 
611
628
  <portal :to="'advanced-' + uuid">
612
629
  <div v-if="useAvailabilitySet">
613
- <h2>Availability Set Configuration</h2>
630
+ <h2>{{ t('cluster.machineConfig.azure.sections.availabilitySetConfiguration') }}</h2>
614
631
  <div class="row mt-20">
615
632
  <div class="col span-6">
616
633
  <LabeledInput
@@ -633,7 +650,7 @@ export default {
633
650
  </div>
634
651
  </div>
635
652
  <hr class="mt-20 mb-20">
636
- <h2>Purchase Plan</h2>
653
+ <h2>{{ t('cluster.machineConfig.azure.sections.purchasePlan') }}</h2>
637
654
  <div class="row mt-20">
638
655
  <div class="col span-6">
639
656
  <LabeledInput
@@ -645,9 +662,9 @@ export default {
645
662
  />
646
663
  </div>
647
664
  </div>
648
- <hr class="mt-20 mb-20">
649
- <h2>Network</h2>
650
- <div class="row mt-20">
665
+ <hr class="mt-20">
666
+ <h2>{{ t('cluster.machineConfig.azure.sections.network') }}</h2>
667
+ <div class="row mt-20 mb-20">
651
668
  <div class="col span-6">
652
669
  <LabeledInput
653
670
  v-model="value.subnet"
@@ -666,18 +683,20 @@ export default {
666
683
  </div>
667
684
  </div>
668
685
  <div class="row mt-20">
669
- <Checkbox
670
- v-model="value.acceleratedNetworking"
671
- :disabled="(!value.acceleratedNetworking && !selectedVmSizeSupportsAN)"
672
- :mode="mode"
673
- :label="t('cluster.machineConfig.azure.acceleratedNetworking.label')"
674
- />
686
+ <div class="col span-6">
687
+ <Checkbox
688
+ v-model="value.acceleratedNetworking"
689
+ :disabled="(!value.acceleratedNetworking && !selectedVmSizeSupportsAN)"
690
+ :mode="mode"
691
+ :label="t('cluster.machineConfig.azure.acceleratedNetworking.label')"
692
+ />
693
+ <Banner
694
+ v-if="!selectedVmSizeSupportsAN && value.acceleratedNetworking"
695
+ color="error"
696
+ :label="t('cluster.machineConfig.azure.size.selectedSizeAcceleratedNetworkingWarning')"
697
+ />
698
+ </div>
675
699
  </div>
676
- <Banner
677
- v-if="!selectedVmSizeSupportsAN && value.acceleratedNetworking"
678
- color="error"
679
- :label="t('cluster.machineConfig.azure.size.selectedSizeAcceleratedNetworkingWarning')"
680
- />
681
700
  <div class="row mt-20">
682
701
  <div class="col span-6">
683
702
  <LabeledInput
@@ -688,7 +707,7 @@ export default {
688
707
  :disabled="disabled"
689
708
  />
690
709
  </div>
691
- <div class="col span-6">
710
+ <div class="col span-6 inline-banner-container">
692
711
  <h3><t k="cluster.machineConfig.azure.publicIpOptions.header" /></h3>
693
712
  <Checkbox
694
713
  v-model="value.noPublicIp"
@@ -700,6 +719,31 @@ export default {
700
719
  :mode="mode"
701
720
  :label="t('cluster.machineConfig.azure.publicIpOptions.staticPublicIp.label')"
702
721
  />
722
+ <Checkbox
723
+ v-model="value.enablePublicIpStandardSku"
724
+ :mode="mode"
725
+ :label="t('cluster.machineConfig.azure.publicIpOptions.standardSKU.label')"
726
+ />
727
+ <div
728
+ v-if="value.availabilityZone && (!value.staticPublicIp || !value.enablePublicIpStandardSku)"
729
+ class="inline-error-banner"
730
+ >
731
+ <Banner
732
+ v-if="!value.staticPublicIp && !value.enablePublicIpStandardSku"
733
+ color="error"
734
+ :label="t('cluster.machineConfig.azure.availabilityZone.publicIpAndSKUWarning')"
735
+ />
736
+ <Banner
737
+ v-else-if="!value.staticPublicIp"
738
+ color="error"
739
+ :label="t('cluster.machineConfig.azure.availabilityZone.publicIpWarning')"
740
+ />
741
+ <Banner
742
+ v-else
743
+ color="error"
744
+ :label="t('cluster.machineConfig.azure.availabilityZone.standardSKUWarning')"
745
+ />
746
+ </div>
703
747
  </div>
704
748
  </div>
705
749
  <div class="row mt-20">
@@ -741,8 +785,8 @@ export default {
741
785
  </div>
742
786
  </div>
743
787
  <hr class="mt-20 mb-20">
744
- <h2>Disks</h2>
745
- <div class="row mt-20">
788
+ <h2>{{ t('cluster.machineConfig.azure.sections.disks') }}</h2>
789
+ <div class="row mt-20 mb-20">
746
790
  <div class="col span-6">
747
791
  <LabeledSelect
748
792
  v-model="value.storageType"
@@ -761,16 +805,21 @@ export default {
761
805
  :label="t('cluster.machineConfig.azure.storageType.warning')"
762
806
  />
763
807
  </div>
764
- <div class="col span-6">
808
+ <div class="col span-6 inline-banner-container">
765
809
  <Checkbox
766
810
  v-model="value.managedDisks"
767
811
  :mode="mode"
768
812
  :label="t('cluster.machineConfig.azure.managedDisks.label')"
769
813
  :disabled="disabled"
770
814
  />
815
+ <Banner
816
+ v-if="value.availabilityZone && !value.managedDisks"
817
+ color="error"
818
+ :label="t('cluster.machineConfig.azure.availabilityZone.managedDisksWarning')"
819
+ />
771
820
  </div>
772
821
  </div>
773
- <div class="row mt-20">
822
+ <div class="row">
774
823
  <div class="col span-6">
775
824
  <LabeledInput
776
825
  v-model="value.diskSize"
@@ -821,3 +870,13 @@ export default {
821
870
  </portal>
822
871
  </div>
823
872
  </template>
873
+
874
+ <style scoped>
875
+ .inline-banner-container{
876
+ position: relative;
877
+ }
878
+ .inline-error-banner {
879
+ position: absolute;
880
+ width:100%
881
+ }
882
+ </style>
@@ -28,6 +28,30 @@ const getPackageFromRoute = (route) => {
28
28
 
29
29
  let beforeEachSetup = false;
30
30
 
31
+ function findMeta(route, key) {
32
+ if (route?.meta) {
33
+ const meta = Array.isArray(route.meta) ? route.meta : [route.meta];
34
+
35
+ for (let i = 0; i < meta.length; i++) {
36
+ if (meta[i][key]) {
37
+ return meta[i][key];
38
+ }
39
+ }
40
+ }
41
+
42
+ return undefined;
43
+ }
44
+
45
+ export function getClusterFromRoute(to) {
46
+ let cluster = to.params?.cluster;
47
+
48
+ if (!cluster) {
49
+ cluster = findMeta(to, 'cluster');
50
+ }
51
+
52
+ return cluster;
53
+ }
54
+
31
55
  export function getProductFromRoute(to) {
32
56
  let product = to.params?.product;
33
57
 
@@ -39,6 +63,11 @@ export function getProductFromRoute(to) {
39
63
  }
40
64
  }
41
65
 
66
+ // If still no product, see if the route indicates the product via route metadata
67
+ if (!product) {
68
+ product = findMeta(to, 'product');
69
+ }
70
+
42
71
  return product;
43
72
  }
44
73
 
@@ -279,6 +308,11 @@ export default async function({
279
308
  try {
280
309
  let clusterId = get(route, 'params.cluster');
281
310
 
311
+ // Route can provide cluster ID via metadata
312
+ if (!clusterId && route) {
313
+ clusterId = getClusterFromRoute(route);
314
+ }
315
+
282
316
  const pkg = getPackageFromRoute(route);
283
317
  const product = getProductFromRoute(route);
284
318