@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
@@ -0,0 +1,508 @@
1
+ <script>
2
+ import { escapeHtml } from '@shell/utils/string';
3
+
4
+ const RADIUS = 5;
5
+
6
+ const INTERVAL = 10000;
7
+
8
+ /*
9
+ function randomStats() {
10
+ return {
11
+ 'p50ms': Math.random(),
12
+ 'p90ms': Math.random() * 2,
13
+ 'p99ms': Math.random() * 5,
14
+ 'rps': Math.random() * 100,
15
+ 'successRate': Math.random(),
16
+ };
17
+ }
18
+
19
+ function randomItem(ary) {
20
+ const idx = Math.floor(Math.random() * ary.length);
21
+
22
+ return ary[idx];
23
+ }
24
+
25
+ function randomData() {
26
+ const nodes = [];
27
+ const edges = [];
28
+
29
+ ['foo', 'bar', 'baz', 'bat', 'qux'].forEach((name) => {
30
+ nodes.push({
31
+ 'namespace': 'default',
32
+ 'app': name,
33
+ 'version': 'v1',
34
+ 'stats': randomStats(),
35
+ });
36
+ });
37
+
38
+ ['a', 'b', 'c', 'd', 'e'].forEach((name) => {
39
+ nodes.push({
40
+ 'namespace': 'another',
41
+ 'app': name,
42
+ 'version': 'v1',
43
+ 'stats': randomStats(),
44
+ });
45
+ });
46
+
47
+ for ( let i = 0 ; i < 10 ; i++ ) {
48
+ const from = randomItem(nodes);
49
+ const crossNs = Math.random() < 0.2;
50
+ const toChoices = nodes.filter((x) => {
51
+ if ( x === from ) {
52
+ return false;
53
+ }
54
+
55
+ if ( crossNs ) {
56
+ return x.namespace !== from.namespace;
57
+ } else {
58
+ return x.namespace === from.namespace;
59
+ }
60
+ });
61
+ const to = randomItem(toChoices);
62
+
63
+ edges.push({
64
+ fromNamespace: from.namespace,
65
+ fromApp: from.app,
66
+ fromVersion: from.version,
67
+ toNamespace: to.namespace,
68
+ toApp: to.app,
69
+ toVersion: to.version,
70
+ stats: randomStats(),
71
+ });
72
+ }
73
+
74
+ return {
75
+ nodes,
76
+ edges
77
+ };
78
+ }
79
+ */
80
+
81
+ function nodeIdFor(obj) {
82
+ return `${ obj.namespace }:${ obj.app }@${ obj.version }`;
83
+ }
84
+
85
+ function fromId(obj) {
86
+ return `${ obj.fromNamespace }:${ obj.fromApp }@${ obj.fromVersion }`;
87
+ }
88
+
89
+ function toId(obj) {
90
+ return `${ obj.toNamespace }:${ obj.toApp }@${ obj.toVersion }`;
91
+ }
92
+
93
+ async function loadData(store) {
94
+ const data = await store.dispatch('rancher/request', { url: '/v1-metrics/meshsummary' });
95
+
96
+ const known = {};
97
+
98
+ data.nodes = data.nodes.filter((x) => !!x.app && !!x.namespace);
99
+ data.nodes.forEach((x) => {
100
+ x.id = nodeIdFor(x);
101
+ known[x.id] = true;
102
+ });
103
+
104
+ data.edges = data.edges.filter((x) => known[fromId(x)] && known[toId(x)]);
105
+
106
+ return data;
107
+ }
108
+
109
+ function round3Digits(num) {
110
+ if ( !num ) {
111
+ return 0;
112
+ }
113
+
114
+ if ( num > 100 ) {
115
+ return Math.round(num);
116
+ } else if ( num > 10 ) {
117
+ return Math.round(num * 10) / 10;
118
+ } else {
119
+ return Math.round(num * 100) / 100;
120
+ }
121
+ }
122
+
123
+ export default {
124
+
125
+ /* (
126
+ data() {
127
+ return {
128
+ loading: true,
129
+ ...randomData(),
130
+ };
131
+ },
132
+ */
133
+
134
+ async asyncData({ store }) {
135
+ const data = await loadData(store);
136
+
137
+ return data;
138
+ },
139
+ computed: {
140
+ namespaces() {
141
+ return this.$store.getters['namespaces']();
142
+ },
143
+
144
+ displayNodes() {
145
+ console.log('get displayNodes'); // eslint-disable-line no-console
146
+ const namespaces = this.namespaces;
147
+
148
+ const out = this.nodes.filter((x) => {
149
+ return namespaces[x.namespace];
150
+ });
151
+
152
+ return out;
153
+ },
154
+
155
+ displayEdges() {
156
+ console.log('get displayEdges'); // eslint-disable-line no-console
157
+ const namespaces = this.namespaces;
158
+
159
+ const out = this.edges.filter((x) => {
160
+ const ns1 = x.fromNamespace;
161
+ const ns2 = x.toNamespace;
162
+
163
+ return namespaces[ns1] && namespaces[ns2];
164
+ });
165
+
166
+ return out;
167
+ },
168
+ },
169
+
170
+ watch: {
171
+ // Nodes isn't watched, but gets updated at the same time...
172
+ nodes() {
173
+ console.log('nodes updated'); // eslint-disable-line no-console
174
+ this.updateGraph();
175
+ this.renderGraph();
176
+ },
177
+
178
+ namespaces() {
179
+ console.log('namespaces updated'); // eslint-disable-line no-console
180
+ this.updateGraph();
181
+ this.renderGraph();
182
+ },
183
+
184
+ edges() {
185
+ console.log('edges updated'); // eslint-disable-line no-console
186
+ this.updateGraph();
187
+ this.renderGraph();
188
+ },
189
+ },
190
+
191
+ async mounted() {
192
+ console.log('Mounted'); // eslint-disable-line no-console
193
+ this.timer = setInterval(() => {
194
+ console.log('Timer'); // eslint-disable-line no-console
195
+ this.refreshData();
196
+ }, INTERVAL);
197
+
198
+ await this.initGraph();
199
+ this.updateGraph();
200
+ this.renderGraph();
201
+
202
+ window.m = this;
203
+ },
204
+
205
+ beforeDestroy() {
206
+ clearInterval(this.timer);
207
+ },
208
+
209
+ methods: {
210
+ async refreshData() {
211
+ console.log('Refreshing...'); // eslint-disable-line no-console
212
+ const neu = await loadData(this.$store);
213
+
214
+ this.nodes = neu.nodes;
215
+ this.edges = neu.edges;
216
+ console.log('Refreshed'); // eslint-disable-line no-console
217
+ },
218
+
219
+ async initGraph() {
220
+ const d3 = await import('d3');
221
+ const dagreD3 = await import('dagre-d3');
222
+
223
+ const g = new dagreD3.graphlib.Graph({ compound: true });
224
+
225
+ g.setGraph({
226
+ marginx: 0,
227
+ marginy: 0,
228
+ rankdir: 'LR',
229
+ align: 'UL',
230
+ ranker: 'longest-path', // 'tight-tree',
231
+ });
232
+
233
+ g.setDefaultEdgeLabel(() => {
234
+ return {};
235
+ });
236
+
237
+ // Create the renderer
238
+ const render = new dagreD3.render();
239
+
240
+ // Add our custom arrow
241
+ render.arrows().smaller = function normal(parent, id, edge, type) {
242
+ const marker = parent.append('marker')
243
+ .attr('id', id)
244
+ .attr('viewBox', '0 0 12 12')
245
+ .attr('refX', 6)
246
+ .attr('refY', 6)
247
+ .attr('markerUnits', 'userSpaceOnUse')
248
+ .attr('markerWidth', 12)
249
+ .attr('markerHeight', 12)
250
+ .attr('orient', 'auto');
251
+ const path = marker.append('path')
252
+ .attr('class', 'arrowhead')
253
+ .attr('d', 'M 6 0 L 0 6 L 6 12 L 12 6 z')
254
+ .style('stroke-width', 1)
255
+ .style('stroke-dasharray', '1,0');
256
+
257
+ dagreD3.util.applyStyle(path, edge[`${ type }Style`]);
258
+ };
259
+
260
+ // Set up an SVG group so that we can translate the final graph.
261
+ const svg = d3.select(this.$refs.mesh);
262
+ const group = svg.append('g');
263
+
264
+ const zoom = d3.zoom().on('zoom', () => {
265
+ if ( d3.event.sourceEvent ) {
266
+ this.lastZoom = d3.event.transform;
267
+ }
268
+ group.attr('transform', d3.event.transform);
269
+ });
270
+
271
+ svg.call(zoom);
272
+
273
+ this.d3 = d3;
274
+ this.dagreD3 = dagreD3;
275
+ this.graph = g;
276
+ this.render = render;
277
+ this.group = group;
278
+ this.zoom = zoom;
279
+ },
280
+
281
+ updateGraph() {
282
+ // @TODO diff nodes/edges, remove unexpected and add missing ones
283
+ console.log('Updating...'); // eslint-disable-line no-console
284
+
285
+ const e = escapeHtml;
286
+ const g = this.graph;
287
+
288
+ const seenNamespaces = {};
289
+
290
+ for ( const node of this.displayNodes ) {
291
+ const nsId = ensureNamespace(node.namespace);
292
+ const id = nodeIdFor(node);
293
+
294
+ node.label = `${ node.app }@${ node.version }`;
295
+
296
+ let p99 = node.stats.p99ms;
297
+ let unit = 'ms';
298
+
299
+ if ( p99 > 1000 ) {
300
+ p99 /= 1000;
301
+ unit = 's';
302
+ }
303
+
304
+ const html = `
305
+ <div class="version">
306
+ <h4>${ e(node.app) }@${ e(node.version) }</h4>
307
+ <div class="row">
308
+ <div class="col span-4 sr">
309
+ <span>${ round3Digits(node.stats.successRate * 100) }</span><span class="unit">%</span>
310
+ </div>
311
+ <div class="col span-4 rps">
312
+ <span>${ round3Digits(node.stats.rps) }</span>
313
+ </div>
314
+ <div class="col span-4 p99">
315
+ <span>${ round3Digits(p99) }</span><span class="unit">${ unit }</span>
316
+ </div>
317
+ </div>
318
+ </div>
319
+ `;
320
+
321
+ g.setNode(id, {
322
+ labelType: 'html',
323
+ label: html,
324
+ width: 158,
325
+ height: 80,
326
+ rx: RADIUS,
327
+ ry: RADIUS,
328
+ });
329
+ g.setParent(id, nsId);
330
+ }
331
+
332
+ const rpses = this.displayEdges.map((x) => x.stats.rps);
333
+ const min = Math.min(...rpses);
334
+ const max = Math.max(...rpses);
335
+
336
+ for ( const edge of this.displayEdges ) {
337
+ ensureNamespace(edge.fromNamespace);
338
+ ensureNamespace(edge.toNamespace);
339
+ const weight = Math.floor(4 * (edge.stats.rps - min) / (max - min)) + 1;
340
+
341
+ g.setEdge(fromId(edge), toId(edge), {
342
+ arrowhead: 'smaller',
343
+ arrowheadClass: 'arrowhead',
344
+ class: `weight${ weight }`,
345
+ curve: this.d3.curveBasis,
346
+ weight,
347
+ });
348
+ }
349
+
350
+ function ensureNamespace(name) {
351
+ const id = `ns:${ name }`;
352
+
353
+ if ( !seenNamespaces[name] ) {
354
+ seenNamespaces[name] = true;
355
+ g.setNode(id, {
356
+ label: `Namespace: ${ name }`,
357
+ clusterLabelPos: 'top',
358
+ rx: RADIUS,
359
+ ry: RADIUS
360
+ });
361
+ }
362
+
363
+ return id;
364
+ }
365
+ },
366
+
367
+ renderGraph() {
368
+ console.log('Rendering...'); // eslint-disable-line no-console
369
+
370
+ const d3 = this.d3;
371
+ const svg = this.d3.select(this.$refs.mesh);
372
+ const group = this.group;
373
+ const g = this.graph;
374
+ const render = this.render;
375
+ const zoom = this.zoom;
376
+
377
+ svg.call(zoom.transform, d3.zoomIdentity.translate(0, 0).scale(1));
378
+
379
+ // Run the renderer. This is what draws the final graph.
380
+ render(group, g);
381
+
382
+ const graphWidth = g.graph().width;
383
+ const graphHeight = g.graph().height;
384
+ const width = parseInt(svg.style('width').replace(/px/, ''));
385
+ const height = parseInt(svg.style('height').replace(/px/, ''));
386
+ const scale = Math.min(width / graphWidth, height / graphHeight);
387
+ const dX = (width / 2) - ((graphWidth * scale) / 2);
388
+ const dY = (height / 2) - ((graphHeight * scale) / 2);
389
+
390
+ console.log('render'); // eslint-disable-line no-console
391
+ if ( this.lastZoom ) {
392
+ svg.call(zoom.transform, d3.zoomIdentity.translate(this.lastZoom.x, this.lastZoom.y).scale(this.lastZoom.k));
393
+ } else {
394
+ svg.call(zoom.transform, d3.zoomIdentity.translate(dX, dY).scale(scale));
395
+ }
396
+
397
+ this.loading = false;
398
+ },
399
+
400
+ clicked(event) {
401
+ const path = event.target.closest('.edgePath');
402
+
403
+ console.log(path); // eslint-disable-line no-console
404
+ }
405
+ },
406
+ };
407
+ </script>
408
+ <template>
409
+ <div class="mesh">
410
+ <header>
411
+ <h1>App Mesh</h1>
412
+ </header>
413
+
414
+ <svg
415
+ id="mesh"
416
+ ref="mesh"
417
+ @click="clicked"
418
+ />
419
+ </div>
420
+ </template>
421
+
422
+ <style lang="scss">
423
+ #mesh {
424
+ width: 100%;
425
+ height: calc(100vh - 165px);
426
+
427
+ .version {
428
+ width: 158px;
429
+ height: 80px;
430
+ color: #b6b6c2;
431
+ text-align: center;
432
+
433
+ .row {
434
+ margin: 0;
435
+ }
436
+
437
+ H4 {
438
+ color: #b6b6c2;
439
+ display: block;
440
+ border-bottom: 1px solid #555;
441
+ text-align: left;
442
+ padding-bottom: 5px;
443
+ margin-bottom: 5px;
444
+ }
445
+
446
+ .sr, .rps, .p99 {
447
+ font-size: 20px;
448
+
449
+ .unit {
450
+ font-size: 12px;
451
+ }
452
+ }
453
+
454
+ .sr:before, .rps:before, .p99:before {
455
+ color: white;
456
+ font-weight: bold;
457
+ font-size: 15px;
458
+ display: block;
459
+ }
460
+
461
+ .sr:before {
462
+ content: 'SR';
463
+ }
464
+
465
+ .rps:before {
466
+ content: 'RPS';
467
+ }
468
+
469
+ .p99:before {
470
+ content: '99%';
471
+ }
472
+
473
+ }
474
+
475
+ .clusters .label text {
476
+ fill: #b6b6c2;
477
+ font-weight: bold;
478
+ }
479
+
480
+ .clusters RECT {
481
+ fill: #222;
482
+ stroke: #555;
483
+ }
484
+
485
+ .arrowhead {
486
+ fill: #6c6c76;
487
+ }
488
+
489
+ .node RECT {
490
+ fill: #111;
491
+ stroke: #555;
492
+ }
493
+
494
+ PATH {
495
+ stroke: #6c6c76;
496
+ }
497
+
498
+ .edgePath {
499
+ cursor: pointer;
500
+ }
501
+
502
+ .weight1 { stroke-width: 2px; }
503
+ .weight2 { stroke-width: 3px; }
504
+ .weight3 { stroke-width: 4px; }
505
+ .weight4 { stroke-width: 5px; }
506
+ .weight5 { stroke-width: 6px; }
507
+ }
508
+ </style>
@@ -10,6 +10,7 @@ import { isRancherPrime } from '@shell/config/version';
10
10
  import { hasCspAdapter } from 'mixins/brand';
11
11
 
12
12
  export default {
13
+ layout: 'home',
13
14
 
14
15
  components: {
15
16
  BannerGraphic,
@@ -81,8 +82,13 @@ export default {
81
82
  },
82
83
 
83
84
  serverUrl() {
84
- // Client-side rendered: use the current window location
85
- return window.location.origin;
85
+ if (process.client) {
86
+ // Client-side rendered: use the current window location
87
+ return window.location.origin;
88
+ }
89
+
90
+ // Server-side rendered
91
+ return this.serverSetting?.value || '';
86
92
  },
87
93
 
88
94
  supportConfigLink() {
@@ -1,6 +1,6 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
- const contextFolders = ['chart', 'cloud-credential', 'content', 'detail', 'edit', 'list', 'machine-config', 'models', 'promptRemove', 'l10n', 'windowComponents', 'dialog', 'formatters', 'login'];
3
+ const contextFolders = ['chart', 'cloud-credential', 'content', 'detail', 'edit', 'layouts', 'list', 'machine-config', 'models', 'promptRemove', 'l10n', 'windowComponents', 'dialog', 'formatters', 'login'];
4
4
  const contextMap = contextFolders.reduce((map, obj) => {
5
5
  map[obj] = true;
6
6
 
package/plugins/axios.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import https from 'https';
2
2
  import { CSRF } from '@shell/config/cookies';
3
+ import { parse as setCookieParser } from 'set-cookie-parser';
4
+ import pkg from '../package.json';
3
5
 
4
6
  export default function({
5
7
  $axios, $cookies, isDev, req
@@ -13,8 +15,42 @@ export default function({
13
15
  if ( csrf ) {
14
16
  config.headers['x-api-csrf'] = csrf;
15
17
  }
18
+
19
+ if ( process.server ) {
20
+ config.headers.common['access-control-expose-headers'] = `set-cookie`;
21
+ config.headers.common['user-agent'] = `Dashboard (Mozilla) v${ pkg.version }`;
22
+
23
+ if ( req.headers.cookie ) {
24
+ config.headers.common['cookies'] = req.headers.cookie;
25
+ }
26
+
27
+ if ( config.url.startsWith('/') ) {
28
+ config.baseURL = `${ req.protocol || 'https' }://${ req.headers.host }`;
29
+ }
30
+ }
16
31
  });
17
32
 
33
+ if ( process.server ) {
34
+ $axios.onResponse((res) => {
35
+ const parsed = setCookieParser(res.headers['set-cookie'] || []);
36
+
37
+ for ( const opt of parsed ) {
38
+ const key = opt.name;
39
+ const value = opt.value;
40
+
41
+ delete opt.name;
42
+ delete opt.value;
43
+
44
+ opt.encode = (x) => x;
45
+ opt.sameSite = true;
46
+ opt.path = '/';
47
+ opt.secure = true;
48
+
49
+ $cookies.set(key, value, opt);
50
+ }
51
+ });
52
+ }
53
+
18
54
  if ( isDev ) {
19
55
  // https://github.com/nuxt-community/axios-module/blob/dev/lib/module.js#L78
20
56
  // forces localhost to http, for no obvious reason.
@@ -1,3 +1,5 @@
1
- window.addEventListener('popstate', () => {
2
- window._popStateDetected = true;
3
- });
1
+ if ( process.client ) {
2
+ window.addEventListener('popstate', () => {
3
+ window._popStateDetected = true;
4
+ });
5
+ }
@@ -1,5 +1,23 @@
1
1
  import Vue from 'vue';
2
- import { purifyHTML } from './clean-html';
2
+ import DOMPurify from 'dompurify';
3
+
4
+ const ALLOWED_TAGS = [
5
+ 'code',
6
+ 'li',
7
+ 'a',
8
+ 'p',
9
+ 'b',
10
+ 'br',
11
+ 'ul',
12
+ 'pre',
13
+ 'span',
14
+ 'div',
15
+ 'i',
16
+ 'em',
17
+ 'strong',
18
+ ];
19
+
20
+ export const purifyHTML = (value) => DOMPurify.sanitize(value, { ALLOWED_TAGS });
3
21
 
4
22
  export const cleanHtmlDirective = {
5
23
  inserted(el, binding) {
@@ -1,6 +1,6 @@
1
1
  import Vue from 'vue';
2
2
  import { VTooltip } from 'v-tooltip';
3
- import { purifyHTML } from './clean-html';
3
+ import { purifyHTML } from './clean-html-directive';
4
4
 
5
5
  function purifyContent(value) {
6
6
  const type = typeof value;
@@ -1,5 +1,5 @@
1
1
  // Share codemirror with plugins
2
2
 
3
- if ( !window.__codeMirrorLoader ) {
3
+ if ( process.client && !window.__codeMirrorLoader ) {
4
4
  window.__codeMirrorLoader = () => import(/* webpackChunkName: "codemirror" */ '@shell/plugins/codemirror');
5
5
  }
@@ -125,47 +125,6 @@ CodeMirror.defineExtension('foldLinesMatching', function(regex) {
125
125
  });
126
126
  });
127
127
 
128
- function countSpaces(line) {
129
- for (let i = 0; i < line.length; i++) {
130
- if (line[i] !== ' ') {
131
- return i;
132
- }
133
- }
134
-
135
- return line.length;
136
- }
137
-
138
- CodeMirror.defineExtension('foldYaml', function(path) {
139
- this.operation(() => {
140
- let elements = [];
141
-
142
- for (let i = this.firstLine(), e = this.lastLine(); i <= e; i++) {
143
- const line = this.getLine(i);
144
- const index = countSpaces(line);
145
- const trimmed = line.trim();
146
-
147
- if (trimmed.endsWith(':') || trimmed.endsWith(': >-')) {
148
- const name = trimmed.split(':')[0].substr(0, trimmed.length - 1);
149
-
150
- // Remove all elements of the same are greater index
151
- elements = elements.filter((e) => e.index < index);
152
-
153
- // Add on this one
154
- elements.push({
155
- index,
156
- name
157
- });
158
-
159
- const currentPath = elements.map((e) => e.name).join('.');
160
-
161
- if (currentPath === path) {
162
- this.foldCode(CodeMirror.Pos(i, 0), null, 'fold');
163
- }
164
- }
165
- }
166
- });
167
- });
168
-
169
128
  CodeMirror.registerHelper('fold', 'yamlcomments', (cm, start) => {
170
129
  if ( !isLineComment(cm, start.line) ) {
171
130
  return;
@@ -1,4 +1,4 @@
1
- import { batchChanges } from '@shell/plugins/dashboard-store/mutations.js';
1
+ import { batchChanges } from '@shell/plugins/dashboard-store/mutations';
2
2
  import { POD, WORKLOAD_TYPES } from '@shell/config/types';
3
3
  import Resource from '@shell/plugins/dashboard-store/resource-class';
4
4