@rancher/shell 0.5.3 → 1.2.1

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 (356) hide show
  1. package/.DS_Store +0 -0
  2. package/assets/images/providers/aks-black.svg +28 -0
  3. package/assets/images/providers/aks.svg +31 -0
  4. package/assets/styles/global/_labeled-input.scss +1 -0
  5. package/assets/styles/global/_layout.scss +0 -99
  6. package/assets/translations/en-us.yaml +76 -74
  7. package/assets/translations/zh-hans.yaml +25 -23
  8. package/babel.config.js +1 -7
  9. package/chart/gatekeeper.vue +11 -2
  10. package/chart/istio.vue +10 -1
  11. package/chart/logging/index.vue +11 -2
  12. package/chart/monitoring/alerting/index.vue +21 -7
  13. package/chart/monitoring/grafana/index.vue +2 -57
  14. package/chart/monitoring/index.vue +26 -52
  15. package/chart/monitoring/prometheus/index.vue +43 -37
  16. package/chart/rancher-backup/index.vue +10 -3
  17. package/cloud-credential/azure.vue +17 -4
  18. package/components/AsyncButton.vue +0 -9
  19. package/components/Carousel.vue +0 -1
  20. package/components/ChartPsp.vue +76 -0
  21. package/components/ClusterIconMenu.vue +9 -24
  22. package/components/CodeMirror.vue +16 -75
  23. package/components/CopyCode.vue +2 -6
  24. package/components/CopyToClipboard.vue +1 -2
  25. package/components/CopyToClipboardText.vue +9 -14
  26. package/components/CruResource.vue +0 -1
  27. package/components/EtcdInfoBanner.vue +5 -5
  28. package/components/ExplorerProjectsNamespaces.vue +1 -25
  29. package/components/FixedBanner.vue +0 -1
  30. package/components/IconOrSvg.vue +1 -1
  31. package/components/Markdown.vue +12 -16
  32. package/components/Questions/index.vue +1 -1
  33. package/components/ResourceDetail/Masthead.vue +9 -25
  34. package/components/ResourceDetail/index.vue +4 -1
  35. package/components/ResourceList/Masthead.vue +18 -1
  36. package/components/ResourceTable.vue +2 -14
  37. package/components/ResourceYaml.vue +5 -34
  38. package/components/SideNav.vue +65 -43
  39. package/components/SortableTable/THead.vue +9 -7
  40. package/components/SortableTable/index.vue +2 -1
  41. package/components/StatusTable.vue +1 -5
  42. package/components/TabTitle.vue +84 -0
  43. package/components/Tabbed/index.vue +0 -12
  44. package/components/YamlEditor.vue +0 -1
  45. package/components/__tests__/ChartPsp.test.ts +75 -0
  46. package/components/__tests__/CopyCode.test.ts +4 -5
  47. package/components/fleet/FleetBundles.vue +11 -5
  48. package/components/fleet/FleetRepos.vue +27 -62
  49. package/components/fleet/FleetResources.vue +1 -6
  50. package/components/fleet/FleetStatus.vue +3 -3
  51. package/components/fleet/FleetSummary.vue +30 -35
  52. package/components/form/ArrayList.vue +8 -1
  53. package/components/form/ArrayListSelect.vue +9 -9
  54. package/components/form/BannerSettings.vue +0 -3
  55. package/components/form/FileSelector.vue +0 -1
  56. package/components/form/KeyValue.vue +0 -2
  57. package/components/form/LabeledSelect.vue +0 -4
  58. package/components/form/Password.vue +1 -3
  59. package/components/form/Select.vue +1 -1
  60. package/components/form/SelectOrCreateAuthSecret.vue +4 -4
  61. package/components/form/__tests__/KeyValue.test.ts +1 -1
  62. package/components/formatter/Checked.vue +3 -11
  63. package/components/formatter/ClusterProvider.vue +18 -1
  64. package/components/formatter/FleetSummaryGraph.vue +11 -23
  65. package/components/formatter/LiveDate.vue +16 -0
  66. package/components/formatter/LiveDuration.vue +1 -1
  67. package/components/formatter/PercentageBar.vue +1 -1
  68. package/components/formatter/WorkloadDetailEndpoints.vue +22 -12
  69. package/components/formatter/__tests__/ClusterProvider.test.ts +28 -0
  70. package/components/nav/Group.vue +2 -2
  71. package/components/nav/Header.vue +2 -2
  72. package/components/nav/Jump.vue +9 -19
  73. package/components/nav/TopLevelMenu.vue +18 -66
  74. package/components/nav/Type.vue +7 -16
  75. package/components/nav/WindowManager/ContainerLogs.vue +19 -120
  76. package/components/nav/WindowManager/ContainerShell.vue +1 -6
  77. package/components/nav/WindowManager/index.vue +10 -11
  78. package/components/nav/__tests__/TopLevelMenu.test.ts +1 -34
  79. package/components/nav/__tests__/Type.test.ts +1 -31
  80. package/components/nuxt/nuxt-child.js +78 -14
  81. package/components/nuxt/nuxt.js +1 -1
  82. package/components/user.retention/user-retention-header.vue +34 -0
  83. package/composables/useI18n.ts +26 -0
  84. package/composables/useStore.ts +16 -0
  85. package/config/harvester-manager-types.js +0 -2
  86. package/config/home-links.js +32 -2
  87. package/config/private-label.js +0 -22
  88. package/config/product/explorer.js +4 -4
  89. package/config/product/fleet.js +1 -6
  90. package/config/product/legacy.js +1 -84
  91. package/config/product/manager.js +15 -8
  92. package/config/query-params.js +0 -1
  93. package/config/router.js +368 -385
  94. package/config/settings.ts +9 -2
  95. package/config/store.js +1 -1
  96. package/config/system-namespaces.js +0 -3
  97. package/config/table-headers.js +27 -47
  98. package/config/types.js +5 -0
  99. package/config/uiplugins.js +1 -1
  100. package/core/plugin-helpers.js +5 -3
  101. package/core/plugin-routes.ts +114 -56
  102. package/core/plugin.ts +10 -16
  103. package/core/plugins-loader.js +9 -7
  104. package/core/plugins.js +3 -0
  105. package/core/types-provisioning.ts +0 -7
  106. package/creators/app/init +0 -19
  107. package/detail/fleet.cattle.io.bundle.vue +1 -1
  108. package/detail/fleet.cattle.io.cluster.vue +1 -11
  109. package/detail/node.vue +0 -42
  110. package/detail/pod.vue +1 -68
  111. package/detail/provisioning.cattle.io.cluster.vue +8 -25
  112. package/detail/workload/index.vue +1 -15
  113. package/dialog/ScaleMachineDownDialog.vue +17 -34
  114. package/edit/auth/googleoauth.vue +5 -1
  115. package/edit/catalog.cattle.io.clusterrepo.vue +7 -20
  116. package/edit/cloudcredential.vue +0 -2
  117. package/edit/fleet.cattle.io.gitrepo.vue +4 -3
  118. package/edit/management.cattle.io.project.vue +52 -1
  119. package/edit/management.cattle.io.setting.vue +2 -32
  120. package/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue +1 -1
  121. package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +2 -1
  122. package/edit/monitoring.coreos.com.alertmanagerconfig/types/slack.vue +1 -1
  123. package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +3 -12
  124. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +1 -2
  125. package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +1 -1
  126. package/edit/provisioning.cattle.io.cluster/{tabs/Basics.vue → Basics.vue} +125 -106
  127. package/edit/provisioning.cattle.io.cluster/{tabs/MachinePool.vue → MachinePool.vue} +7 -1
  128. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +7 -15
  129. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +237 -0
  130. package/edit/provisioning.cattle.io.cluster/__tests__/{CustomCommand.test.ts → CustomCommand.tests.ts} +0 -6
  131. package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +1 -1
  132. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +1 -7
  133. package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
  134. package/edit/provisioning.cattle.io.cluster/index.vue +40 -109
  135. package/edit/provisioning.cattle.io.cluster/rke2.vue +689 -152
  136. package/edit/service.vue +0 -12
  137. package/edit/token.vue +0 -1
  138. package/edit/workload/Upgrading.vue +2 -3
  139. package/edit/workload/index.vue +1 -2
  140. package/edit/workload/mixins/workload.js +1 -1
  141. package/initialize/App.js +71 -25
  142. package/initialize/client.js +162 -21
  143. package/initialize/index.js +124 -47
  144. package/initialize/layouts.ts +26 -0
  145. package/{components/templates → layouts}/blank.vue +1 -1
  146. package/{components/templates → layouts}/default.vue +98 -8
  147. package/{components/templates → layouts}/error.vue +19 -10
  148. package/{components/templates → layouts}/home.vue +1 -4
  149. package/{components/templates → layouts}/plain.vue +1 -4
  150. package/{components/templates → layouts}/standalone.vue +1 -1
  151. package/{components/templates → layouts}/unauthenticated.vue +1 -1
  152. package/list/catalog.cattle.io.app.vue +0 -1
  153. package/list/management.cattle.io.feature.vue +7 -1
  154. package/list/management.cattle.io.setting.vue +0 -1
  155. package/list/management.cattle.io.user.vue +25 -1
  156. package/list/node.vue +0 -1
  157. package/machine-config/__tests__/vmwarevsphere.test.ts +161 -56
  158. package/machine-config/azure.vue +37 -21
  159. package/machine-config/vmwarevsphere.vue +47 -42
  160. package/middleware/authenticated.js +19 -14
  161. package/mixins/auth-config.js +7 -2
  162. package/mixins/brand.js +41 -29
  163. package/mixins/fetch.server.js +73 -0
  164. package/mixins/labeled-form-element.ts +1 -6
  165. package/models/__tests__/management.cattle.io.node.ts +0 -85
  166. package/models/__tests__/namespace.test.ts +9 -49
  167. package/models/cluster/node.js +4 -4
  168. package/models/cluster.x-k8s.io.machine.js +1 -1
  169. package/models/cluster.x-k8s.io.machinedeployment.js +0 -14
  170. package/models/fleet.cattle.io.cluster.js +0 -4
  171. package/models/fleet.cattle.io.gitrepo.js +13 -56
  172. package/models/management.cattle.io.cluster.js +3 -11
  173. package/models/management.cattle.io.kontainerdriver.js +0 -1
  174. package/models/management.cattle.io.node.js +14 -18
  175. package/models/management.cattle.io.nodepool.js +0 -17
  176. package/models/management.cattle.io.project.js +36 -0
  177. package/models/management.cattle.io.setting.js +7 -11
  178. package/models/management.cattle.io.user.js +65 -0
  179. package/models/namespace.js +1 -1
  180. package/models/pod.js +0 -20
  181. package/models/provisioning.cattle.io.cluster.js +9 -91
  182. package/models/secret.js +18 -126
  183. package/models/storage.k8s.io.storageclass.js +1 -1
  184. package/models/workload.js +0 -16
  185. package/models/workload.service.js +0 -18
  186. package/package.json +10 -12
  187. package/pages/about.vue +1 -0
  188. package/pages/account/create-key.vue +1 -0
  189. package/pages/account/index.vue +1 -0
  190. package/pages/auth/login.vue +1 -0
  191. package/pages/auth/logout.vue +2 -0
  192. package/pages/auth/setup.vue +4 -37
  193. package/pages/auth/verify.vue +8 -14
  194. package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +17 -2
  195. package/pages/c/_cluster/apps/charts/index.vue +58 -64
  196. package/pages/c/_cluster/apps/charts/install.helpers.js +13 -2
  197. package/pages/c/_cluster/apps/charts/install.vue +5 -5
  198. package/pages/c/_cluster/apps/index.vue +2 -0
  199. package/pages/c/_cluster/auth/index.vue +2 -0
  200. package/pages/c/_cluster/auth/user.retention/index.vue +384 -0
  201. package/pages/c/_cluster/ecm/index.vue +2 -0
  202. package/pages/c/_cluster/explorer/index.vue +53 -56
  203. package/pages/c/_cluster/explorer/tools/index.vue +3 -171
  204. package/pages/c/_cluster/fleet/index.vue +1 -1
  205. package/pages/c/_cluster/index.vue +2 -0
  206. package/pages/c/_cluster/manager/pages/_page.vue +5 -4
  207. package/pages/c/_cluster/monitoring/index.vue +1 -17
  208. package/pages/c/_cluster/settings/DefaultLinksEditor.vue +1 -1
  209. package/pages/c/_cluster/settings/banners.vue +2 -0
  210. package/pages/c/_cluster/settings/brand.vue +2 -3
  211. package/pages/c/_cluster/settings/index.vue +2 -0
  212. package/pages/c/_cluster/settings/links.vue +3 -2
  213. package/pages/c/_cluster/settings/performance.vue +1 -0
  214. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +1 -2
  215. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +46 -10
  216. package/pages/c/_cluster/uiplugins/index.vue +2 -0
  217. package/pages/c/index.vue +9 -0
  218. package/pages/diagnostic.vue +2 -1
  219. package/pages/fail-whale.vue +1 -0
  220. package/pages/prefs.vue +1 -0
  221. package/pages/rio/mesh.vue +508 -0
  222. package/pages/support/index.vue +8 -2
  223. package/pkg/auto-import.js +1 -1
  224. package/plugins/axios.js +36 -0
  225. package/plugins/back-button.js +5 -3
  226. package/plugins/clean-html-directive.js +19 -1
  227. package/plugins/clean-tooltip-directive.js +1 -1
  228. package/plugins/codemirror-loader.js +1 -1
  229. package/plugins/codemirror.js +0 -41
  230. package/plugins/dashboard-store/__tests__/{mutations.test.ts → mutations.spec.ts} +1 -1
  231. package/plugins/dashboard-store/actions.js +17 -16
  232. package/plugins/dashboard-store/classify.js +18 -1
  233. package/plugins/dashboard-store/getters.js +7 -70
  234. package/plugins/dashboard-store/index.js +12 -0
  235. package/plugins/dashboard-store/mutations.js +4 -0
  236. package/plugins/dashboard-store/resource-class.js +20 -65
  237. package/plugins/i18n.js +1 -1
  238. package/plugins/steve/__tests__/getters.spec.ts +48 -26
  239. package/plugins/steve/__tests__/subscribe.spec.ts +106 -0
  240. package/plugins/steve/actions.js +37 -3
  241. package/plugins/steve/getters.js +24 -7
  242. package/plugins/steve/mutations.js +5 -2
  243. package/plugins/steve/norman-class.js +0 -19
  244. package/plugins/steve/steve-class.js +0 -22
  245. package/plugins/steve/subscribe.js +34 -13
  246. package/plugins/transitions.js +4 -0
  247. package/plugins/vue-clipboard2.js +4 -0
  248. package/rancher-components/Accordion/Accordion.vue +3 -2
  249. package/rancher-components/BadgeState/BadgeState.vue +3 -3
  250. package/rancher-components/Banner/Banner.test.ts +1 -5
  251. package/rancher-components/Banner/Banner.vue +2 -2
  252. package/rancher-components/Card/Card.vue +4 -4
  253. package/rancher-components/Form/Checkbox/Checkbox.vue +4 -3
  254. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +1 -1
  255. package/rancher-components/Form/LabeledInput/LabeledInput.vue +55 -24
  256. package/rancher-components/Form/Radio/RadioButton.test.ts +1 -3
  257. package/rancher-components/Form/Radio/RadioButton.vue +13 -7
  258. package/rancher-components/Form/Radio/RadioGroup.vue +4 -3
  259. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -5
  260. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
  261. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
  262. package/rancher-components/StringList/StringList.vue +8 -8
  263. package/rancher-components/components/Accordion/Accordion.vue +3 -2
  264. package/rancher-components/components/BadgeState/BadgeState.test.ts +12 -0
  265. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +2 -19
  266. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +14 -11
  267. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +1 -1
  268. package/rancher-components/components/StringList/StringList.test.ts +0 -270
  269. package/rancher-components/components/StringList/StringList.vue +18 -57
  270. package/scripts/extension/bundle +7 -19
  271. package/scripts/extension/helm/scripts/package +3 -11
  272. package/scripts/extension/parse-tag-name +4 -4
  273. package/scripts/extension/publish +9 -20
  274. package/scripts/publish-shell.sh +1 -11
  275. package/scripts/test-plugins-build.sh +9 -85
  276. package/store/catalog.js +1 -1
  277. package/store/features.js +0 -1
  278. package/store/i18n.js +0 -11
  279. package/store/index.js +13 -11
  280. package/store/prefs.js +38 -33
  281. package/store/type-map.js +82 -157
  282. package/tsconfig.default.json +46 -0
  283. package/tsconfig.json +9 -35
  284. package/types/shell/index.d.ts +407 -468
  285. package/utils/axios.js +19 -0
  286. package/utils/create-yaml.js +1 -5
  287. package/utils/custom-validators.js +2 -0
  288. package/utils/error.js +1 -16
  289. package/utils/monitoring.js +2 -37
  290. package/utils/nuxt.js +39 -18
  291. package/utils/object.js +0 -24
  292. package/utils/router.scrollBehavior.js +14 -12
  293. package/utils/socket.js +1 -0
  294. package/utils/time.js +1 -1
  295. package/utils/title.ts +3 -0
  296. package/utils/url.ts +1 -1
  297. package/utils/validators/formRules/__tests__/index.test.ts +4 -49
  298. package/utils/validators/formRules/index.ts +9 -12
  299. package/utils/validators/setting.js +10 -6
  300. package/vue.config.js +3 -24
  301. package/chart/monitoring/steps/uninstall-v1.vue +0 -135
  302. package/components/Certificates.vue +0 -164
  303. package/components/__tests__/CodeMirror.spec.ts +0 -99
  304. package/components/fleet/__tests__/FleetSummary.test.ts +0 -316
  305. package/components/formatter/FleetClusterSummaryGraph.vue +0 -27
  306. package/components/formatter/__tests__/Checked.test.ts +0 -19
  307. package/components/formatter/__tests__/WorkloadDetailEndpoints.test.ts +0 -81
  308. package/components/nav/WindowManager/__tests__/ContainerLogs.test.ts +0 -186
  309. package/composables/useCompactInput.ts +0 -20
  310. package/composables/useLabeledFormElement.ts +0 -138
  311. package/creators/app/files/.gitlab-ci.yml +0 -14
  312. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +0 -77
  313. package/edit/__tests__/service.test.ts +0 -89
  314. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +0 -112
  315. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +0 -473
  316. package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +0 -73
  317. package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +0 -386
  318. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +0 -137
  319. package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +0 -157
  320. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +0 -135
  321. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +0 -189
  322. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +0 -147
  323. package/edit/provisioning.cattle.io.cluster/tabs/upgrade/index.vue +0 -76
  324. package/mixins/v1-workload-metrics.js +0 -43
  325. package/models/__tests__/management.cattle.io.cluster.test.ts +0 -23
  326. package/models/__tests__/management.cattle.io.nodepool.ts +0 -83
  327. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +0 -241
  328. package/models/__tests__/secret.test.ts +0 -37
  329. package/models/__tests__/storage.k8s.io.storageclass.test.ts +0 -22
  330. package/models/__tests__/workload.test.ts +0 -91
  331. package/plugins/clean-html.js +0 -53
  332. package/plugins/dashboard-store/__tests__/resource-class.test.ts +0 -49
  333. package/plugins/dashboard-store/__tests__/utils/store-mocks.ts +0 -7
  334. package/plugins/index.js +0 -11
  335. package/plugins/steve/__tests__/resource-utils.test.ts +0 -159
  336. package/plugins/steve/__tests__/steve-class.spec.ts +0 -59
  337. package/plugins/steve/__tests__/utils/steve-mocks.ts +0 -31
  338. package/plugins/steve/resource-utils.ts +0 -38
  339. package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +0 -50
  340. package/server/har-file.js +0 -183
  341. package/store/__tests__/type-map.test.ts +0 -1122
  342. package/tsconfig.paths.json +0 -18
  343. package/utils/azure.js +0 -24
  344. package/utils/clipboard.js +0 -5
  345. /package/components/form/__tests__/{NameNsDescription.test.ts → NameNsDescription.ts} +0 -0
  346. /package/edit/networking.k8s.io.networkpolicy/__tests__/utils/{selectors.test.ts → selectors.ts} +0 -0
  347. /package/edit/provisioning.cattle.io.cluster/{tabs/networking/ACE.vue → ACE.vue} +0 -0
  348. /package/edit/provisioning.cattle.io.cluster/{tabs/AgentConfiguration.vue → AgentConfiguration.vue} +0 -0
  349. /package/edit/provisioning.cattle.io.cluster/{tabs/upgrade/DrainOptions.vue → DrainOptions.vue} +0 -0
  350. /package/edit/provisioning.cattle.io.cluster/{tabs/MemberRoles.vue → MemberRoles.vue} +0 -0
  351. /package/edit/provisioning.cattle.io.cluster/{tabs/registries/RegistryConfigs.vue → RegistryConfigs.vue} +0 -0
  352. /package/edit/provisioning.cattle.io.cluster/{tabs/registries/RegistryMirrors.vue → RegistryMirrors.vue} +0 -0
  353. /package/edit/provisioning.cattle.io.cluster/{tabs/etcd/S3Config.vue → S3Config.vue} +0 -0
  354. /package/plugins/dashboard-store/__tests__/{actions.test.ts → actions.spec.ts} +0 -0
  355. /package/plugins/dashboard-store/__tests__/{getters.test.ts → getters.spec.ts} +0 -0
  356. /package/rancher-components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
@@ -93,89 +93,4 @@ describe('class MgmtNode', () => {
93
93
  resetMocks();
94
94
  });
95
95
  });
96
-
97
- describe('canScaleDown', () => {
98
- const mgmtClusterId = 'test';
99
- const nodeId = 'test/id';
100
- const specs = {
101
- worker: {
102
- worker: true, etcd: false, controlPlane: false
103
- },
104
- etcd: {
105
- worker: false, etcd: true, controlPlane: false
106
- },
107
- controlPlane: {
108
- worker: false, etcd: false, controlPlane: true
109
- },
110
- etcdAndControlPlane: {
111
- worker: false, etcd: true, controlPlane: true
112
- },
113
- all: {
114
- worker: true, etcd: true, controlPlane: true
115
- }
116
- };
117
-
118
- const workerNode = {
119
- id: '01',
120
- isWorker: true,
121
- isControlPlane: false,
122
- isEtcd: false
123
- };
124
- const etcdNode = {
125
- id: '02',
126
- isWorker: false,
127
- isControlPlane: false,
128
- isEtcd: true
129
- };
130
- const controlPlaneNode = {
131
- id: '03',
132
- isWorker: false,
133
- isControlPlane: true,
134
- isEtcd: false
135
- };
136
- const etcdAndControlPlaneNode = {
137
- id: '03',
138
- isWorker: false,
139
- isControlPlane: true,
140
- isEtcd: true
141
- };
142
- const allNode = {
143
- id: '04',
144
- isWorker: true,
145
- isControlPlane: true,
146
- isEtcd: true
147
- };
148
-
149
- const baseCtx = {
150
- rootGetters: {
151
- 'rancher/byId': () => ({ actions: { scaledown: 'scaledown' } }),
152
- 'i18n/t': t
153
- }
154
- };
155
-
156
- it.each([
157
- [{ spec: specs.worker, nodes: [workerNode] }, true],
158
- [{ spec: specs.etcd, nodes: [etcdNode, etcdNode, controlPlaneNode] }, true],
159
- [{ spec: specs.etcdAndControlPlane, nodes: [etcdAndControlPlaneNode, etcdAndControlPlaneNode] }, true],
160
- [{ spec: specs.etcdAndControlPlane, nodes: [etcdAndControlPlaneNode] }, false],
161
- [{ spec: specs.all, nodes: [allNode] }, false],
162
- [{ spec: specs.all, nodes: [allNode, allNode] }, true],
163
- ])('should return canScaleDown properly', (data, expected) => {
164
- const { spec, nodes } = data;
165
- const mgmtNode = new MgmtNode({
166
- spec,
167
- id: nodeId
168
- }, {
169
- ...baseCtx,
170
- getters: {
171
- all: () => [{
172
- mgmtClusterId,
173
- nodes
174
- }]
175
- }
176
- });
177
-
178
- expect(mgmtNode.canScaleDown).toStrictEqual(expected);
179
- });
180
- });
181
96
  });
@@ -1,48 +1,11 @@
1
1
  import Namespace from '@shell/models/namespace';
2
- import { SYSTEM_NAMESPACE } from '@shell/config/labels-annotations';
3
- import SYSTEM_NAMESPACES from '@shell/config/system-namespaces';
4
2
 
5
3
  describe('class Namespace', () => {
6
4
  describe('checking if isSystem', () => {
7
5
  it.each([
8
- ['whatever1', SYSTEM_NAMESPACE, true],
9
- ['whatever2', 'any-annotation', false],
10
- ['whatever3', '', false]
11
- ])('should return true if it has the correct annotation', (name, annotation, expectation) => {
12
- const namespace = new Namespace({});
13
-
14
- namespace.metadata = { ...namespace.metadata, name };
15
-
16
- if (annotation) {
17
- namespace.metadata.annotations = { [annotation]: 'true' };
18
- }
19
-
20
- expect(namespace.isSystem).toBe(expectation);
21
- });
22
-
23
- const assertionsArr = [];
24
-
25
- SYSTEM_NAMESPACES.forEach((ns) => {
26
- assertionsArr.push([ns, true]);
27
- });
28
-
29
- assertionsArr.push(['c-whatever-system', false]);
30
- assertionsArr.push(['cattle-whatever', false]);
31
- assertionsArr.push(['', false]);
32
-
33
- it.each(assertionsArr)('should return true if it belongs to the curated list of namespaces', (name, expectation) => {
34
- const namespace = new Namespace({});
35
-
36
- namespace.metadata = { ...namespace.metadata, name };
37
-
38
- expect(namespace.isSystem).toBe(expectation);
39
- });
40
-
41
- it.each([
42
- ['cattle-c-whatever-system', true],
43
- ['cattle-whatever', false],
44
- ['c-whatever-system', false]
45
- ])('should return true if starts with "cattle-" end with "-system', (name, expectation) => {
6
+ ['c-whatever-system', true],
7
+ ['whatever', false]
8
+ ])('should return true if end with "-system', (name, expectation) => {
46
9
  const namespace = new Namespace({});
47
10
 
48
11
  namespace.metadata = { ...namespace.metadata, name };
@@ -55,21 +18,18 @@ describe('class Namespace', () => {
55
18
 
56
19
  describe('checking if isObscure', () => {
57
20
  it.each([
58
- ['c-whatever-system', 'management.cattle.io/system-namespace', true],
59
- ['p-whatever', SYSTEM_NAMESPACE, true],
60
- ['p-whatever', '', false],
61
- ['', '', false]
62
- ])('should return a value if is system AND has the correct prefix', (name, annotation, expectation) => {
21
+ ['c-whatever-system', true],
22
+ ['whatever', false],
23
+ ['', false]
24
+ ])('should return a value if has or not a name in the metadata', (name, expectation) => {
63
25
  const namespace = new Namespace({});
64
26
 
65
27
  namespace.metadata = { ...namespace.metadata, name };
66
28
 
67
- if (annotation) {
68
- namespace.metadata.annotations = { [annotation]: 'true' };
69
- }
70
-
71
29
  expect(namespace.isObscure).toBe(expectation);
72
30
  });
31
+
32
+ it.todo('should return a value if is or not system');
73
33
  });
74
34
 
75
35
  it.each([
@@ -187,7 +187,7 @@ export default class ClusterNode extends SteveModel {
187
187
  }
188
188
 
189
189
  get cpuCapacity() {
190
- return parseSi(this.status.allocatable?.cpu);
190
+ return parseSi(this.status.allocatable.cpu);
191
191
  }
192
192
 
193
193
  get cpuUsagePercentage() {
@@ -203,7 +203,7 @@ export default class ClusterNode extends SteveModel {
203
203
  }
204
204
 
205
205
  get ramCapacity() {
206
- return parseSi(this.status.capacity?.memory);
206
+ return parseSi(this.status.capacity.memory);
207
207
  }
208
208
 
209
209
  get ramUsagePercentage() {
@@ -219,7 +219,7 @@ export default class ClusterNode extends SteveModel {
219
219
  }
220
220
 
221
221
  get podUsage() {
222
- return calculatePercentage(this.status.allocatable?.pods, this.status.capacity?.pods);
222
+ return calculatePercentage(this.status.allocatable.pods, this.status.capacity.pods);
223
223
  }
224
224
 
225
225
  get podConsumedUsage() {
@@ -227,7 +227,7 @@ export default class ClusterNode extends SteveModel {
227
227
  }
228
228
 
229
229
  get podCapacity() {
230
- return Number.parseInt(this.status.capacity?.pods);
230
+ return Number.parseInt(this.status.capacity.pods);
231
231
  }
232
232
 
233
233
  get podConsumed() {
@@ -231,7 +231,7 @@ export default class CapiMachine extends SteveModel {
231
231
  return false;
232
232
  }
233
233
 
234
- return notOnlyOfRole(this, this.cluster?.machines);
234
+ return notOnlyOfRole(this, this.cluster.machines);
235
235
  }
236
236
 
237
237
  get roles() {
@@ -7,7 +7,6 @@ import { handleConflict } from '@shell/plugins/dashboard-store/normalize';
7
7
  import { MACHINE_ROLES } from '@shell/config/labels-annotations';
8
8
  import { notOnlyOfRole } from '@shell/models/cluster.x-k8s.io.machine';
9
9
  import { KIND } from '../config/elemental-types';
10
- import { KIND as HARVESTER_KIND } from '../config/harvester-manager-types';
11
10
 
12
11
  export default class CapiMachineDeployment extends SteveModel {
13
12
  get cluster() {
@@ -70,19 +69,6 @@ export default class CapiMachineDeployment extends SteveModel {
70
69
  return this.template?.providerSize || this.t('node.list.poolDescription.noSize');
71
70
  }
72
71
 
73
- get providerSummary() {
74
- if (this.template) {
75
- switch (this.infrastructureRefKind) {
76
- case HARVESTER_KIND.MACHINE_TEMPLATE:
77
- return null;
78
- default:
79
- return `${ this.providerDisplay } \u2013 ${ this.providerLocation } / ${ this.providerSize } (${ this.providerName })`;
80
- }
81
- }
82
-
83
- return null;
84
- }
85
-
86
72
  get desired() {
87
73
  return this.spec?.replicas || 0;
88
74
  }
@@ -107,10 +107,6 @@ export default class FleetCluster extends SteveModel {
107
107
  return this.metadata?.labels?.[FLEET_LABELS.CLUSTER_DISPLAY_NAME] || this.metadata?.name || this.id;
108
108
  }
109
109
 
110
- get name() {
111
- return this.metadata?.name || this.metadata?.labels?.[FLEET_LABELS.CLUSTER_NAME];
112
- }
113
-
114
110
  get state() {
115
111
  if (this.spec?.paused === true) {
116
112
  return 'paused';
@@ -7,9 +7,7 @@ import { FLEET as FLEET_ANNOTATIONS } from '@shell/config/labels-annotations';
7
7
  import { addObject, addObjects, findBy, insertAt } from '@shell/utils/array';
8
8
  import { set } from '@shell/utils/object';
9
9
  import SteveModel from '@shell/plugins/steve/steve-class';
10
- import {
11
- STATES_ENUM, colorForState, mapStateToEnum, primaryDisplayStatusFromCount, stateDisplay, stateSort
12
- } from '@shell/plugins/dashboard-store/resource-class';
10
+ import { STATES_ENUM, colorForState, stateDisplay, stateSort } from '@shell/plugins/dashboard-store/resource-class';
13
11
  import { NAME } from '@shell/config/product/explorer';
14
12
 
15
13
  function quacksLikeAHash(str) {
@@ -205,6 +203,17 @@ export default class GitRepo extends SteveModel {
205
203
  return hash;
206
204
  }
207
205
 
206
+ get clusterInfo() {
207
+ const ready = this.status?.readyClusters || 0;
208
+ const total = this.status?.desiredReadyClusters || 0;
209
+
210
+ return {
211
+ ready,
212
+ unready: total - ready,
213
+ total,
214
+ };
215
+ }
216
+
208
217
  get targetInfo() {
209
218
  let mode = null;
210
219
  let cluster = null;
@@ -375,9 +384,8 @@ export default class GitRepo extends SteveModel {
375
384
  namespace: r.namespace,
376
385
  name: r.name,
377
386
  clusterId: c.id,
378
- clusterLabel: c.metadata.labels[FLEET_ANNOTATIONS.CLUSTER_NAME],
379
387
  clusterName: c.nameDisplay,
380
- state: mapStateToEnum(state),
388
+ state,
381
389
  stateBackground: color,
382
390
  stateDisplay: display,
383
391
  stateSort: stateSort(color, display),
@@ -393,57 +401,6 @@ export default class GitRepo extends SteveModel {
393
401
  return out;
394
402
  }
395
403
 
396
- get clusterInfo() {
397
- const ready = this.status?.readyClusters || 0;
398
- const total = this.status?.desiredReadyClusters || 0;
399
-
400
- return {
401
- ready,
402
- unready: total - ready,
403
- total,
404
- };
405
- }
406
-
407
- get clusterResourceStatus() {
408
- const clusterStatuses = this.resourcesStatuses.reduce((prev, curr) => {
409
- const { clusterId, clusterLabel } = curr;
410
-
411
- const state = curr.state;
412
-
413
- if (!prev[clusterId]) {
414
- prev[clusterId] = {
415
- clusterLabel,
416
- resourceCounts: { [state]: 0, desiredReady: 0 }
417
-
418
- };
419
- }
420
-
421
- if (!prev[clusterId].resourceCounts[state]) {
422
- prev[clusterId].resourceCounts[state] = 0;
423
- }
424
-
425
- prev[clusterId].resourceCounts[state] += 1;
426
- prev[clusterId].resourceCounts.desiredReady += 1;
427
-
428
- return prev;
429
- }, {});
430
-
431
- const values = Object.keys(clusterStatuses).map((key) => {
432
- const { clusterLabel, resourceCounts } = clusterStatuses[key];
433
-
434
- return {
435
- clusterId: key,
436
- clusterLabel, // FLEET LABEL
437
- status: {
438
- displayStatus: primaryDisplayStatusFromCount(resourceCounts),
439
- resourceCounts: { ...resourceCounts }
440
- }
441
- };
442
- });
443
-
444
- return values;
445
- }
446
-
447
404
  get clustersList() {
448
405
  return this.$getters['all'](FLEET.CLUSTER);
449
406
  }
@@ -1,3 +1,4 @@
1
+ import Vue from 'vue';
1
2
  import { CATALOG, CLUSTER_BADGE } from '@shell/config/labels-annotations';
2
3
  import { NODE, FLEET, MANAGEMENT, CAPI } from '@shell/config/types';
3
4
  import { insertAt, addObject, removeObject } from '@shell/utils/array';
@@ -14,7 +15,6 @@ import HybridModel from '@shell/plugins/steve/hybrid-class';
14
15
  import { LINUX, WINDOWS } from '@shell/store/catalog';
15
16
  import { KONTAINER_TO_DRIVER } from './management.cattle.io.kontainerdriver';
16
17
  import { PINNED_CLUSTERS } from '@shell/store/prefs';
17
- import { copyTextToClipboard } from '@shell/utils/clipboard';
18
18
 
19
19
  // See translation file cluster.providers for list of providers
20
20
  // If the logo is not named with the provider name, add an override here
@@ -88,10 +88,6 @@ export default class MgmtCluster extends HybridModel {
88
88
  }
89
89
 
90
90
  get provisioner() {
91
- if (this.status?.provider ) {
92
- return this.status.provider;
93
- }
94
-
95
91
  // For imported K3s clusters, this.status.driver is 'k3s.'
96
92
  return this.status?.driver ? this.status.driver : 'imported';
97
93
  }
@@ -408,13 +404,9 @@ export default class MgmtCluster extends HybridModel {
408
404
  }
409
405
 
410
406
  async copyKubeConfig() {
411
- try {
412
- const config = await this.generateKubeConfig();
407
+ const config = await this.generateKubeConfig();
413
408
 
414
- if (config) {
415
- await copyTextToClipboard(config);
416
- }
417
- } catch {}
409
+ Vue.prototype.$copyText(config);
418
410
  }
419
411
 
420
412
  async fetchNodeMetrics() {
@@ -1,7 +1,6 @@
1
1
  import HybridModel from '@shell/plugins/steve/hybrid-class';
2
2
 
3
3
  const HIDDEN = ['rke', 'rancherkubernetesengine'];
4
-
5
4
  const V2 = ['amazoneks', 'googlegke', 'azureaks'];
6
5
  const IMPORTABLE = ['amazoneks', 'googlegke', 'azureaks'];
7
6
 
@@ -8,7 +8,6 @@ import { insertAt } from '@shell/utils/array';
8
8
  import { downloadUrl } from '@shell/utils/download';
9
9
  import findLast from 'lodash/findLast';
10
10
  import HybridModel from '@shell/plugins/steve/hybrid-class';
11
- import { notOnlyOfRole } from '@shell/models/cluster.x-k8s.io.machine';
12
11
 
13
12
  export default class MgmtNode extends HybridModel {
14
13
  get _availableActions() {
@@ -22,12 +21,11 @@ export default class MgmtNode extends HybridModel {
22
21
  };
23
22
 
24
23
  const scaleDown = {
25
- action: 'scaleDown',
26
- bulkAction: 'scaleDown',
27
- enabled: !!this.canScaleDown,
28
- icon: 'icon icon-minus icon-fw',
29
- label: this.t('node.actions.scaleDown'),
30
- bulkable: true,
24
+ action: 'scaleDown',
25
+ enabled: !!this.canScaleDown,
26
+ icon: 'icon icon-minus icon-fw',
27
+ label: this.t('node.actions.scaleDown'),
28
+ bulkable: true,
31
29
  };
32
30
 
33
31
  insertAt(out, 0, { divider: true });
@@ -107,12 +105,12 @@ export default class MgmtNode extends HybridModel {
107
105
  }
108
106
  }
109
107
 
110
- async scaleDown(resources = this) {
111
- this.$dispatch('promptModal', {
112
- resources,
113
- component: 'ScaleMachineDownDialog',
114
- modalWidth: '450px'
115
- });
108
+ async scaleDown(resources) {
109
+ const safeResources = Array.isArray(resources) ? resources : [this];
110
+
111
+ await Promise.all(safeResources.map((node) => {
112
+ return node.norman?.doAction('scaledown');
113
+ }));
116
114
  }
117
115
 
118
116
  get provisioningCluster() {
@@ -168,12 +166,10 @@ export default class MgmtNode extends HybridModel {
168
166
  }
169
167
 
170
168
  get canScaleDown() {
171
- if (!this.isEtcd && !this.isControlPlane) {
172
- return true;
173
- }
174
-
169
+ const isInOnlyPool = this.pool?.provisioningCluster?.pools?.length === 1;
170
+ const isOnlyNode = this.pool?.nodes?.length === 1;
175
171
  const hasAction = this.norman?.actions?.scaledown;
176
172
 
177
- return hasAction && notOnlyOfRole(this, this.provisioningCluster?.nodes);
173
+ return hasAction && (!isInOnlyPool || !isOnlyNode);
178
174
  }
179
175
  }
@@ -1,7 +1,6 @@
1
1
  import { CAPI, MANAGEMENT, NORMAN } from '@shell/config/types';
2
2
  import { sortBy } from '@shell/utils/sort';
3
3
  import HybridModel from '@shell/plugins/steve/hybrid-class';
4
- import { notOnlyOfRole } from '@shell/models/cluster.x-k8s.io.machine';
5
4
 
6
5
  export default class MgmtNodePool extends HybridModel {
7
6
  get nodeTemplate() {
@@ -162,22 +161,6 @@ export default class MgmtNodePool extends HybridModel {
162
161
  return this.norman?.hasLink('update');
163
162
  }
164
163
 
165
- get isControlPlane() {
166
- return this.spec?.controlPlane === true;
167
- }
168
-
169
- get isEtcd() {
170
- return this.spec?.etcd === true;
171
- }
172
-
173
- canScaleDownPool() {
174
- if (!this.isEtcd && !this.isControlPlane) {
175
- return true;
176
- }
177
-
178
- return notOnlyOfRole(this, this?.provisioningCluster?.nodes);
179
- }
180
-
181
164
  remove() {
182
165
  return this.norman?.remove();
183
166
  }
@@ -99,6 +99,42 @@ export default class Project extends HybridModel {
99
99
  // and the PUT request should have a query param _replace=true.
100
100
  const newValue = await norman.save({ replace: forceReplaceOnReq });
101
101
 
102
+ let retryCount = 0;
103
+
104
+ const finishProjectCreation = async() => {
105
+ try {
106
+ await newValue.doAction('setpodsecuritypolicytemplate', { podSecurityPolicyTemplateId: this.spec.podSecurityPolicyTemplateId || null });
107
+ } catch (err) {
108
+ if ( err.status === 409 || err.status === 403 ) {
109
+ // The backend updates each new project soon after it is created,
110
+ // so there is a chance of a 409 resource conflict or forbidden error. If that happens,
111
+ // retry the action.
112
+
113
+ // The 403 permission error can happen due to the user requesting
114
+ // the project before the project is fully created and the project
115
+ // permissions are assigned to the user so we allow some
116
+ // time for that process to complete.
117
+
118
+ if (retryCount < 3) {
119
+ retryCount++;
120
+ await setTimeout(() => {
121
+ // Delay for three seconds to avoid another failure due to latency.
122
+ finishProjectCreation();
123
+ }, '3000');
124
+ } else {
125
+ throw err;
126
+ }
127
+ }
128
+ }
129
+ };
130
+
131
+ // Only update PSP template if the value changed
132
+ const newPSPTemplateID = this.spec.podSecurityPolicyTemplateId || null;
133
+
134
+ if (norman.podSecurityPolicyTemplateId !== newPSPTemplateID) {
135
+ await finishProjectCreation();
136
+ }
137
+
102
138
  return newValue;
103
139
  }
104
140
 
@@ -1,6 +1,5 @@
1
1
  import { ALLOWED_SETTINGS } from '@shell/config/settings';
2
2
  import HybridModel from '@shell/plugins/steve/hybrid-class';
3
- import { isServerUrl } from '@shell/utils/validators/setting';
4
3
 
5
4
  export default class Setting extends HybridModel {
6
5
  get fromEnv() {
@@ -32,15 +31,12 @@ export default class Setting extends HybridModel {
32
31
  }
33
32
 
34
33
  get customValidationRules() {
35
- const out = [];
36
-
37
- if (isServerUrl(this.metadata.name)) {
38
- out.push({
39
- path: 'value',
40
- validators: ['required', 'https', 'url', 'trailingForwardSlash']
41
- });
42
- }
43
-
44
- return out;
34
+ return [
35
+ {
36
+ path: 'value',
37
+ translationKey: 'setting.serverUrl.https',
38
+ validators: [`isHttps:${ this.metadata.name }`]
39
+ },
40
+ ];
45
41
  }
46
42
  }
@@ -1,5 +1,6 @@
1
1
  import { NORMAN } from '@shell/config/types';
2
2
  import HybridModel, { cleanHybridResources } from '@shell/plugins/steve/hybrid-class';
3
+ import day from 'dayjs';
3
4
 
4
5
  export default class User extends HybridModel {
5
6
  // Preserve description
@@ -99,6 +100,38 @@ export default class User extends HybridModel {
99
100
  return this.$rootGetters['i18n/withFallback'](`model.authConfig.provider."${ this.provider }"`, null, this.provider);
100
101
  }
101
102
 
103
+ /**
104
+ * Gets the last-login label in milliseconds
105
+ * @returns {number}
106
+ */
107
+ get userLastLogin() {
108
+ return this.metadata?.labels?.['cattle.io/last-login'] * 1000;
109
+ }
110
+
111
+ /**
112
+ * Gets the disabled-after label in milliseconds
113
+ * @returns {number}
114
+ */
115
+ get userDisabledIn() {
116
+ return this.metadata?.labels?.['cattle.io/disable-after'] * 1000;
117
+ }
118
+
119
+ /**
120
+ * Provides a display value for the userDisabledIn date based on the user
121
+ * state.
122
+ */
123
+ get userDisabledInDisplay() {
124
+ return this.state === 'inactive' ? null : this.userDisabledIn;
125
+ }
126
+
127
+ /**
128
+ * Gets the delete-after label in milliseconds
129
+ * @returns {number}
130
+ */
131
+ get userDeletedIn() {
132
+ return this.metadata?.labels?.['cattle.io/delete-after'] * 1000;
133
+ }
134
+
102
135
  get state() {
103
136
  if ( this.enabled === false ) {
104
137
  return 'inactive';
@@ -107,6 +140,19 @@ export default class User extends HybridModel {
107
140
  return this.metadata?.state?.name || 'unknown';
108
141
  }
109
142
 
143
+ get stateDisplay() {
144
+ switch (this.state) {
145
+ case 'inactive':
146
+ return this.t('user.state.inactive');
147
+ case 'active':
148
+ return this.t('user.state.active');
149
+ case 'unknown':
150
+ return this.t('user.state.unknown');
151
+ default:
152
+ return this.state;
153
+ }
154
+ }
155
+
110
156
  get description() {
111
157
  return this._description;
112
158
  }
@@ -211,6 +257,25 @@ export default class User extends HybridModel {
211
257
  formatter: 'CopyToClipboard',
212
258
  content: this.username
213
259
  },
260
+ { separator: true },
261
+ {
262
+ label: this.t('tableHeaders.userLastLogin'),
263
+ formatter: 'LiveDate',
264
+ formatterOpts: { addSuffix: true, suffix: `${ this.t('suffix.ago') } (${ day(this.userLastLogin) })` },
265
+ content: this.userLastLogin,
266
+ },
267
+ {
268
+ label: this.t('tableHeaders.userDisabledIn'),
269
+ formatter: 'LiveDate',
270
+ formatterOpts: { isCountdown: true },
271
+ content: this.userDisabledInDisplay,
272
+ },
273
+ {
274
+ label: this.t('tableHeaders.userDeletedIn'),
275
+ formatter: 'LiveDate',
276
+ formatterOpts: { isCountdown: true },
277
+ content: this.userDeletedIn,
278
+ },
214
279
  ...this._details
215
280
  ];
216
281
  }
@@ -87,7 +87,7 @@ export default class Namespace extends SteveModel {
87
87
  return true;
88
88
  }
89
89
 
90
- if ( this.metadata.name.startsWith('cattle-') && this.metadata.name.endsWith('-system') ) {
90
+ if ( this.metadata.name.endsWith('-system') ) {
91
91
  return true;
92
92
  }
93
93