@rancher/shell 0.3.16 → 0.3.18

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 (174) hide show
  1. package/assets/images/wechat-qr-code.jpg +0 -0
  2. package/assets/translations/en-us.yaml +75 -16
  3. package/assets/translations/zh-hans.yaml +151 -15
  4. package/chart/__tests__/S3.test.ts +50 -0
  5. package/chart/rancher-backup/S3.vue +21 -0
  6. package/chart/rancher-backup/index.vue +4 -0
  7. package/components/AsyncButton.vue +1 -1
  8. package/components/CommunityLinks.vue +1 -0
  9. package/components/FileDiff.vue +92 -85
  10. package/components/Inactivity.vue +10 -0
  11. package/components/LazyImage.vue +2 -2
  12. package/components/PromptRestore.vue +7 -5
  13. package/components/ResourceDetail/Masthead.vue +1 -1
  14. package/components/ResourceDetail/index.vue +8 -14
  15. package/components/ResourceList/index.vue +1 -1
  16. package/components/ResourceTable.vue +50 -2
  17. package/components/YamlEditor.vue +1 -0
  18. package/components/__tests__/PromptRestore.test.ts +72 -0
  19. package/components/auth/AzureWarning.vue +1 -1
  20. package/components/auth/RoleDetailEdit.vue +1 -0
  21. package/components/fleet/FleetResources.vue +3 -64
  22. package/components/form/FileImageSelector.vue +9 -0
  23. package/components/form/FileSelector.vue +2 -1
  24. package/components/form/MatchExpressions.vue +1 -3
  25. package/components/form/NameNsDescription.vue +28 -12
  26. package/components/form/NodeAffinity.vue +2 -2
  27. package/components/form/PodAffinity.vue +2 -2
  28. package/components/form/ResourceTabs/index.vue +8 -2
  29. package/components/form/Select.vue +16 -0
  30. package/components/form/__tests__/FileImageSelector.test.ts +42 -0
  31. package/components/form/__tests__/FileSelector.test.ts +76 -0
  32. package/components/form/__tests__/NodeAffinity.test.ts +38 -0
  33. package/components/form/__tests__/PodAffinity.test.ts +46 -0
  34. package/components/formatter/ClusterLink.vue +8 -4
  35. package/components/formatter/ClusterProvider.vue +3 -1
  36. package/components/formatter/ImageName.vue +23 -0
  37. package/components/formatter/PodImages.vue +7 -1
  38. package/components/formatter/__tests__/ClusterLink.test.ts +101 -0
  39. package/components/formatter/__tests__/ClusterProvider.test.ts +24 -0
  40. package/components/nav/Header.vue +2 -2
  41. package/components/nav/WindowManager/ContainerShell.vue +60 -36
  42. package/components/nav/WindowManager/__tests__/ContainerShell.test.ts +561 -0
  43. package/config/__test__/home-links.test.ts +62 -0
  44. package/config/home-links.js +15 -3
  45. package/config/labels-annotations.js +7 -2
  46. package/config/persistentVolume.ts +108 -0
  47. package/config/product/manager.js +5 -1
  48. package/config/router.js +0 -4
  49. package/config/settings.ts +4 -0
  50. package/config/table-headers.js +6 -5
  51. package/config/types.js +2 -0
  52. package/config/uiplugins.js +50 -5
  53. package/core/plugin-helpers.js +39 -15
  54. package/core/plugin.ts +9 -0
  55. package/core/plugins.js +1 -1
  56. package/core/types-provisioning.ts +253 -0
  57. package/core/types.ts +21 -3
  58. package/detail/autoscaling.horizontalpodautoscaler/index.vue +50 -1
  59. package/detail/fleet.cattle.io.gitrepo.vue +10 -2
  60. package/detail/node.vue +6 -6
  61. package/detail/pod.vue +38 -9
  62. package/detail/provisioning.cattle.io.cluster.vue +46 -7
  63. package/detail/workload/index.vue +49 -18
  64. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +62 -0
  65. package/edit/__tests__/ui.cattle.io.navlink.test.ts +110 -0
  66. package/edit/auth/github.vue +1 -0
  67. package/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue +130 -0
  68. package/edit/autoscaling.horizontalpodautoscaler/index.vue +79 -0
  69. package/edit/fleet.cattle.io.clustergroup.vue +14 -3
  70. package/edit/fleet.cattle.io.gitrepo.vue +18 -1
  71. package/edit/namespace.vue +9 -1
  72. package/edit/networking.k8s.io.ingress/RulePath.vue +0 -2
  73. package/edit/persistentvolume/__tests__/persistentvolume.test.ts +82 -0
  74. package/edit/persistentvolume/index.vue +2 -1
  75. package/edit/persistentvolume/plugins/csi.vue +3 -1
  76. package/edit/persistentvolume/plugins/longhorn.vue +12 -12
  77. package/edit/provisioning.cattle.io.cluster/AgentConfiguration.vue +1 -30
  78. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +15 -11
  79. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +79 -1
  80. package/edit/provisioning.cattle.io.cluster/index.vue +53 -1
  81. package/edit/provisioning.cattle.io.cluster/rke2.vue +335 -151
  82. package/edit/storage.k8s.io.storageclass/index.vue +1 -2
  83. package/edit/ui.cattle.io.navlink.vue +213 -186
  84. package/initialize/App.js +3 -13
  85. package/initialize/layouts.ts +26 -0
  86. package/layouts/default.vue +1 -1
  87. package/list/group.principal.vue +1 -1
  88. package/list/provisioning.cattle.io.cluster.vue +8 -1
  89. package/middleware/authenticated.js +101 -5
  90. package/mixins/brand.js +39 -3
  91. package/mixins/child-hook.js +2 -2
  92. package/mixins/create-edit-view/impl.js +4 -4
  93. package/models/chart.js +1 -1
  94. package/models/fleet.cattle.io.cluster.js +33 -4
  95. package/models/fleet.cattle.io.gitrepo.js +113 -38
  96. package/models/management.cattle.io.kontainerdriver.js +14 -0
  97. package/models/persistentvolume.js +2 -111
  98. package/models/pod.js +30 -0
  99. package/models/provisioning.cattle.io.cluster.js +9 -1
  100. package/models/rke.cattle.io.etcdsnapshot.js +10 -7
  101. package/package.json +2 -2
  102. package/pages/about.vue +8 -2
  103. package/pages/auth/login.vue +1 -1
  104. package/pages/auth/logout.vue +11 -3
  105. package/pages/c/_cluster/apps/charts/index.vue +5 -2
  106. package/pages/c/_cluster/apps/charts/install.vue +5 -0
  107. package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
  108. package/pages/c/_cluster/auth/roles/index.vue +1 -1
  109. package/pages/c/_cluster/explorer/index.vue +2 -11
  110. package/pages/c/_cluster/manager/cloudCredential/_id.vue +0 -1
  111. package/pages/c/_cluster/manager/cloudCredential/create.vue +0 -1
  112. package/pages/c/_cluster/settings/brand.vue +11 -8
  113. package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +177 -0
  114. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +19 -3
  115. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +90 -21
  116. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +107 -37
  117. package/pages/c/_cluster/uiplugins/index.vue +160 -44
  118. package/pages/docs/_doc.vue +9 -3
  119. package/pages/home.vue +6 -6
  120. package/pages/support/index.vue +10 -4
  121. package/pkg/auto-import.js +1 -1
  122. package/plugins/clean-tooltip-directive.js +1 -1
  123. package/plugins/dashboard-store/__tests__/actions.spec.ts +165 -0
  124. package/plugins/dashboard-store/__tests__/getters.spec.ts +100 -0
  125. package/plugins/dashboard-store/__tests__/{mutations.spec.js → mutations.spec.ts} +2 -2
  126. package/plugins/dashboard-store/actions.js +1 -1
  127. package/plugins/dashboard-store/resource-class.js +39 -2
  128. package/plugins/plugin.js +9 -1
  129. package/plugins/steve/__tests__/getters.spec.ts +93 -0
  130. package/plugins/steve/getters.js +21 -1
  131. package/plugins/steve/subscribe.js +1 -3
  132. package/rancher-components/BadgeState/BadgeState.vue +5 -1
  133. package/rancher-components/Banner/Banner.test.ts +51 -1
  134. package/rancher-components/Banner/Banner.vue +134 -53
  135. package/rancher-components/Card/Card.test.ts +37 -0
  136. package/rancher-components/Card/Card.vue +24 -7
  137. package/rancher-components/Form/Checkbox/Checkbox.test.ts +20 -29
  138. package/rancher-components/Form/Checkbox/Checkbox.vue +45 -20
  139. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +2 -8
  140. package/rancher-components/Form/LabeledInput/LabeledInput.vue +22 -10
  141. package/rancher-components/Form/Radio/RadioButton.test.ts +31 -0
  142. package/rancher-components/Form/Radio/RadioButton.vue +30 -13
  143. package/rancher-components/Form/Radio/RadioGroup.vue +26 -7
  144. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -6
  145. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +25 -38
  146. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +23 -11
  147. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +19 -5
  148. package/rancher-components/StringList/StringList.test.ts +453 -49
  149. package/rancher-components/StringList/StringList.vue +44 -26
  150. package/scripts/extension/publish +2 -2
  151. package/scripts/typegen.sh +11 -2
  152. package/server/server-middleware.js +4 -12
  153. package/store/index.js +14 -3
  154. package/store/prefs.js +0 -3
  155. package/store/store-types.js +2 -0
  156. package/store/type-map.js +17 -29
  157. package/types/api.d.ts +1 -0
  158. package/types/fleet.d.ts +1 -0
  159. package/types/shell/index.d.ts +931 -85
  160. package/types/userPreferences.d.ts +1 -1
  161. package/utils/__mocks__/socket.js +21 -0
  162. package/utils/grafana.js +23 -11
  163. package/utils/kube.js +9 -0
  164. package/utils/object.js +27 -0
  165. package/utils/selector.js +2 -1
  166. package/utils/settings.ts +2 -2
  167. package/utils/validators/formRules/index.ts +3 -3
  168. package/vue.config.js +3 -2
  169. package/components/.DS_Store +0 -0
  170. package/components/__tests__/.DS_Store +0 -0
  171. package/creators/pkg/package-lock.json +0 -37
  172. package/pages/safeMode.vue +0 -17
  173. package/plugins/steve/urloptions.js +0 -47
  174. package/yarn-error.log +0 -196
@@ -0,0 +1,253 @@
1
+ /**
2
+ * A function to run as part of the save cluster process
3
+ */
4
+ export type ClusterSaveHook = (cluster: any) => Promise<any>
5
+
6
+ /**
7
+ * Register a function to run as part of the save cluster process
8
+ *
9
+ * @param hook function to run
10
+ * @param name unique identifier
11
+ * @param priority higher numbers are lower priority
12
+ * @param fnContext the `this` context from inside the function. If left blank will be a Vue component (where this.value will be the cluster)
13
+ */
14
+ export type RegisterClusterSaveHook = (hook: ClusterSaveHook, name: string, priority?: number, fnContext?: any) => void;
15
+
16
+ /**
17
+ * Params used when constructing an instance of the cluster provisioner
18
+ */
19
+ export interface ClusterProvisionerContext {
20
+ /**
21
+ * Dispatch vuex actions
22
+ */
23
+ dispatch: any,
24
+ /**
25
+ * Get from vuex store
26
+ */
27
+ getters: any,
28
+ /**
29
+ * Used to make http requests
30
+ */
31
+ axios: any,
32
+ /**
33
+ * Definition of the extension
34
+ */
35
+ $plugin: any,
36
+ /**
37
+ * Function to retrieve a localised string
38
+ */
39
+ t: (key: string) => string,
40
+ /**
41
+ * Are we in the context of creating a cluster
42
+ */
43
+ isCreate: boolean
44
+ /**
45
+ * Are we in the context of editing an existing cluster
46
+ */
47
+ isEdit: boolean
48
+ /**
49
+ * Are we viewing an existing cluster
50
+ */
51
+ isView: boolean
52
+ }
53
+
54
+ /**
55
+ * Interface that a custom Cluster Provisioner should implement
56
+ *
57
+ * The majority of these hooks are used in shell/edit/provisioning.cattle.io.cluster/rke2.vue
58
+ */
59
+ export interface IClusterProvisioner {
60
+
61
+ /**
62
+ * Unique ID of the Cluster Provisioner
63
+ */
64
+ id: string;
65
+
66
+ /**
67
+ * Should the UI show a namespace selector when using this provisioner
68
+ */
69
+ namespaced?: boolean;
70
+
71
+ /* --------------------------------------------------------------------------------------
72
+ * Define how the cluster provider is presented in a card to the user
73
+ * --------------------------------------------------------------------------------------- */
74
+
75
+ /**
76
+ * If missing the `cluster.provider.<provider id>` translation will be used
77
+ *
78
+ * It is recommended to not hardcode anything that might be localised
79
+ */
80
+ label?: string;
81
+
82
+ /**
83
+ * The description will be shown when the user is selecting the type of cluster provider
84
+ *
85
+ * This isn't normally used.
86
+ */
87
+ description?: string;
88
+
89
+ /**
90
+ * Icon shown when the user is selecting the type of cluster provider
91
+ */
92
+ icon?: any;
93
+
94
+ /**
95
+ * Cluster providers are in groups
96
+ *
97
+ * `rke2` - default
98
+ * `kontainer`
99
+ * `custom2`
100
+ */
101
+ group?: string;
102
+
103
+ /**
104
+ * Disable the cluster provider card
105
+ */
106
+ disabled?: boolean;
107
+
108
+ /**
109
+ * Custom Dashboard route to navigate to when the cluster provider card is clicked
110
+ */
111
+ link?: string;
112
+
113
+ /**
114
+ * Text to show top right on the cluster provider card. For example `Experimental`
115
+ */
116
+ tag?: string;
117
+
118
+ /* --------------------------------------------------------------------------------------
119
+ * Custer Details View
120
+ * --------------------------------------------------------------------------------------- */
121
+
122
+ /**
123
+ * Existing tabs to show or hide in the cluster's detail view
124
+ *
125
+ * `plugin.addTab(TabLocation.RESOURCE_DETAIL... ` can be used to add additional tabs to the same view
126
+ */
127
+ detailTabs: {
128
+ /**
129
+ * RKE2 machine pool tabs
130
+ */
131
+ machines: boolean,
132
+ /**
133
+ * RKE2 provisioning logs
134
+ */
135
+ logs: boolean,
136
+ /**
137
+ * RKE2 registration commands
138
+ */
139
+ registration: boolean,
140
+ /**
141
+ * RKE2 snapshots
142
+ */
143
+ snapshots: boolean,
144
+ /**
145
+ * Kube resources related to the instance of provisioning.cattle.io.cluster
146
+ */
147
+ related: boolean,
148
+ /**
149
+ * Kube events associated with the instance of provisioning.cattle.io.cluster
150
+ */
151
+ events: boolean,
152
+ /**
153
+ * Kube conditions of the provisioning.cattle.io.cluster instance
154
+ */
155
+ conditions: boolean
156
+ };
157
+
158
+ /* --------------------------------------------------------------------------------------
159
+ * Getters / Functions for Managing Machine Configs
160
+ * --------------------------------------------------------------------------------------- */
161
+
162
+ /**
163
+ * Schema for machine config object. For example rke-machine-config.cattle.io.digitaloceanconfig
164
+ *
165
+ * The `id` should be in the format of `rke-machine-config.cattle.io.${ provider id }config`
166
+ *
167
+ * The `attributes: { kind: <value> }` should match the last part of the id
168
+ * The `attributes: { group: <value> }` should match the remaining parts of the id
169
+ */
170
+ machineConfigSchema?: { [key: string]: any };
171
+
172
+ /**
173
+ * Override the default method to create a machine config object that will be inserted into a new machine pool
174
+ *
175
+ * The machine config will be an instance related to the machine config schema
176
+ *
177
+ * This is usually used when the user has selected to add a machine pool when creating/editing the cluster.
178
+ *
179
+ * > If the user updates the cluster's namespace after pools have been created.... the machine config's will need updating later on
180
+ *
181
+ * @param idx Index of new pool
182
+ * @param pools Existing machine pools
183
+ * @param cluster The cluster (`provisioning.cattle.io.cluster`)
184
+ * @returns Instance of a machine config
185
+ */
186
+ createMachinePoolMachineConfig?(idx: number, pools: any[], cluster: any): Promise<{[key: string]: any}>;
187
+
188
+ /**
189
+ * Override the default process to save the machine config's associated with the machine pools
190
+ *
191
+ * If machine config's will be the pool's `config` property.
192
+ *
193
+ * The pool will have `create: true` if the pool is new or `update: true` if the pool already exists
194
+ *
195
+ * For information on proxying HTTP requests from the browser via Rancher https://rancher.github.io/dashboard/code-base-works/machine-drivers#api-calls
196
+ * These docs also cover how to reference a Cloud Credential and use it's properties in the proxy's request `Authorization` header
197
+ *
198
+ * @param pools Machine pools
199
+ * @param cluster The cluster (`provisioning.cattle.io.cluster`)
200
+ * @returns Content of async result / promise N/A, only the success / fail state
201
+ */
202
+ saveMachinePoolConfigs?(pools: any[], cluster: any): Promise<any>
203
+
204
+ /* --------------------------------------------------------------------------------------
205
+ * Optionally override parts of the cluster save process with
206
+ * - hooks that run before or after the cluster resource is saved
207
+ * - the actual save of the cluster resource
208
+ * --------------------------------------------------------------------------------------- */
209
+
210
+ /**
211
+ * Update the cluster before and or after the cluster is saved
212
+ *
213
+ * @param registerBeforeHook
214
+ * Call `registerBeforeHook` with a function. The function will be executed before the cluster is saved.
215
+ * This allows the model used in the API request to be updated before being sent
216
+ * @param registerAfterHook
217
+ * Call `registerAfterHook` with a function. The function will be executed after the cluster has been saved.
218
+ * This allows the model received in response to the API request to be updated
219
+ * @param cluster The cluster (`provisioning.cattle.io.cluster`)
220
+ */
221
+ registerSaveHooks?(registerBeforeHook: RegisterClusterSaveHook, registerAfterHook: RegisterClusterSaveHook, cluster: any): void;
222
+
223
+ /**
224
+ * Optionally override the save of the cluster resource itself.
225
+ *
226
+ * https://github.com/rancher/dashboard/blob/master/shell/mixins/create-edit-view/impl.js#L179
227
+ *
228
+ * This means a lot of the generic handling of cluster provisioning is not skipped (as per the `provision` method)
229
+ *
230
+ * @param cluster The cluster (`provisioning.cattle.io.cluster`)
231
+ * @returns Rejected promise / exception from `await` if failed to save
232
+ */
233
+ saveCluster?(cluster: any): Promise<any>
234
+
235
+ /* --------------------------------------------------------------------------------------
236
+ * Optionally override all of cluster save process
237
+ * --------------------------------------------------------------------------------------- */
238
+
239
+ /**
240
+ * Optionally override all of the ui's save cluster process (including hooks and saving the resource)
241
+ *
242
+ * https://github.com/rancher/dashboard/blob/master/shell/edit/provisioning.cattle.io.cluster/rke2.vue#L1420
243
+ *
244
+ * For information on proxying HTTP requests from the browser via Rancher https://rancher.github.io/dashboard/code-base-works/machine-drivers#api-calls
245
+ * These docs also cover how to reference a Cloud Credential and use it's properties in the proxy's request `Authorization` header
246
+ *
247
+ * @param pools Machine pools
248
+ * @param cluster The cluster (`provisioning.cattle.io.cluster`)
249
+ * @param isCreate True if the cluster is being created, false if an existing cluster being edited
250
+ * @returns Array of errors. If there are no errors the array will be empty
251
+ */
252
+ provision?(cluster: any, pools: any[]): Promise<any[]>;
253
+ }
package/core/types.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import { ProductFunction } from './plugin';
2
2
  import { RouteConfig, Location } from 'vue-router';
3
3
 
4
+ // Cluster Provisioning types
5
+ export * from './types-provisioning';
6
+
4
7
  // package.json metadata
5
8
  export interface PackageMetadata {
6
9
  name: string;
@@ -62,6 +65,7 @@ export enum PanelLocation {
62
65
  /** Enum regarding tab locations that are extensionable in the UI */
63
66
  export enum TabLocation {
64
67
  RESOURCE_DETAIL = 'tab', // eslint-disable-line no-unused-vars
68
+ CLUSTER_CREATE_RKE2 = 'cluster-create-rke2', // eslint-disable-line no-unused-vars
65
69
  }
66
70
 
67
71
  /** Enum regarding card locations that are extensionable in the UI */
@@ -97,7 +101,7 @@ export type Action = {
97
101
  svg?: Function;
98
102
  icon?: string;
99
103
  multiple?: boolean;
100
- enabled?: (ctx: any) => boolean;
104
+ enabled?: Function | boolean;
101
105
  invoke: (opts: ActionOpts, resources: any[]) => void | boolean | Promise<boolean>;
102
106
  };
103
107
 
@@ -134,7 +138,21 @@ export type LocationConfig = {
134
138
  namespace?: string[],
135
139
  cluster?: string[],
136
140
  id?: string[],
137
- mode?: string[]
141
+ mode?: string[],
142
+ /**
143
+ * path match from URL (excludes host address)
144
+ */
145
+ path?: { [key: string]: string | boolean}[],
146
+ /**
147
+ * Query Params from URL
148
+ */
149
+ queryParam?: { [key: string]: string},
150
+ /**
151
+ * Context specific params.
152
+ *
153
+ * Components can provide additional context specific params that this value must match
154
+ */
155
+ context?: { [key: string]: string},
138
156
  };
139
157
 
140
158
  export interface ProductOptions {
@@ -516,7 +534,7 @@ export interface IPlugin {
516
534
  * @param {String} name unique name of 'something'
517
535
  * @param {Function} fn function that dynamically loads the module for the thing being registered
518
536
  */
519
- register(type: string, name: string, fn: Function): void;
537
+ register(type: string, name: string, fn: Function | Boolean): void;
520
538
 
521
539
  /**
522
540
  * Will return all of the configuration functions used for creating a new product.
@@ -94,7 +94,7 @@ export default {
94
94
  name="metrics"
95
95
  :label="t('hpa.tabs.metrics')"
96
96
  class="bordered-table hpa-metrics-table"
97
- :weight="3"
97
+ :weight="4"
98
98
  >
99
99
  <div
100
100
  v-for="(metric, index) in mappedMetrics"
@@ -185,6 +185,55 @@ export default {
185
185
  </InfoBox>
186
186
  </div>
187
187
  </Tab>
188
+ <Tab
189
+ v-if="!!value.spec.behavior"
190
+ name="behavior"
191
+ :label="t('hpa.tabs.behavior')"
192
+ class="bordered-table hpa-behavior-table"
193
+ :weight="3"
194
+ >
195
+ <div
196
+ v-for="(type, i) in ['scaleDown', 'scaleUp']"
197
+ :key="`${i}`"
198
+ >
199
+ <InfoBox v-if="!!value.spec.behavior[type]">
200
+ <div class="row info-row">
201
+ <div class="col span-6 info-column">
202
+ <h4>
203
+ <t
204
+ :k="`hpa.${type}Rules.label`"
205
+ />
206
+ </h4>
207
+ </div>
208
+ </div>
209
+ <div class="row">
210
+ <div class="col span-6 info-column">
211
+ <label class="text-label"><t k="hpa.scalingRule.policyHeader" /></label>
212
+ <ul
213
+ v-for="(current, currentIndex) in value.spec.behavior[type].policies"
214
+ :key="`${currentIndex}`"
215
+ >
216
+ <li>
217
+ <span>{{ current.value }}</span>
218
+ <span>{{ current.type }}</span>
219
+ <span>(for {{ current.periodSeconds }}s)</span>
220
+ </li>
221
+ </ul>
222
+ </div>
223
+ <div class="col span-6">
224
+ <div class="mb-5">
225
+ <label class="text-label"><t k="hpa.scalingRule.selectPolicy" />: </label>
226
+ <span>{{ value.spec.behavior[type].selectPolicy }}</span>
227
+ </div>
228
+ <div class="mb-5">
229
+ <label class="text-label"><t k="hpa.scalingRule.stabilizationWindowSeconds" />: </label>
230
+ <span>{{ value.spec.behavior[type].stabilizationWindowSeconds }}s</span>
231
+ </div>
232
+ </div>
233
+ </div>
234
+ </InfoBox>
235
+ </div>
236
+ </Tab>
188
237
  </ResourceTabs>
189
238
  </template>
190
239
 
@@ -31,8 +31,9 @@ export default {
31
31
 
32
32
  data() {
33
33
  return {
34
- allFleet: [],
35
- allBundles: []
34
+ allFleet: [],
35
+ allBundles: [],
36
+ allBundleDeployments: [],
36
37
  };
37
38
  },
38
39
 
@@ -79,6 +80,12 @@ export default {
79
80
  inStoreType: 'management',
80
81
  type: FLEET.BUNDLE
81
82
  },
83
+
84
+ allBundleDeployments: {
85
+ inStoreType: 'management',
86
+ type: FLEET.BUNDLE_DEPLOYMENT
87
+ },
88
+
82
89
  allFleet: {
83
90
  inStoreType: 'management',
84
91
  type: FLEET.CLUSTER
@@ -89,6 +96,7 @@ export default {
89
96
  }
90
97
  }, this.$store);
91
98
 
99
+ this.allBundleDeployments = allDispatches.allBundleDeployments || [];
92
100
  this.allBundles = allDispatches.allBundles || [];
93
101
  this.allFleet = allDispatches.allFleet || [];
94
102
  },
package/detail/node.vue CHANGED
@@ -1,7 +1,7 @@
1
1
  <script>
2
2
  import ConsumptionGauge from '@shell/components/ConsumptionGauge';
3
3
  import Alert from '@shell/components/Alert';
4
- import SortableTable from '@shell/components/SortableTable';
4
+ import ResourceTable from '@shell/components/ResourceTable';
5
5
  import Tab from '@shell/components/Tabbed/Tab';
6
6
  import {
7
7
  EFFECT,
@@ -35,7 +35,7 @@ export default {
35
35
  Loading,
36
36
  ResourceTabs,
37
37
  Tab,
38
- SortableTable,
38
+ ResourceTable,
39
39
  EmberPage,
40
40
  },
41
41
 
@@ -252,7 +252,7 @@ export default {
252
252
  :label="t('node.detail.tab.pods')"
253
253
  :weight="4"
254
254
  >
255
- <SortableTable
255
+ <ResourceTable
256
256
  key-field="_key"
257
257
  :headers="podTableHeaders"
258
258
  :rows="value.pods"
@@ -283,7 +283,7 @@ export default {
283
283
  class="bordered-table"
284
284
  :weight="2"
285
285
  >
286
- <SortableTable
286
+ <ResourceTable
287
287
  key-field="_key"
288
288
  :headers="infoTableHeaders"
289
289
  :rows="infoTableRows"
@@ -298,7 +298,7 @@ export default {
298
298
  :label="t('node.detail.tab.images')"
299
299
  :weight="1"
300
300
  >
301
- <SortableTable
301
+ <ResourceTable
302
302
  key-field="_key"
303
303
  :headers="imageTableHeaders"
304
304
  :rows="imageTableRows"
@@ -311,7 +311,7 @@ export default {
311
311
  :label="t('node.detail.tab.taints')"
312
312
  :weight="0"
313
313
  >
314
- <SortableTable
314
+ <ResourceTable
315
315
  key-field="_key"
316
316
  :headers="taintTableHeaders"
317
317
  :rows="taintTableRows"
package/detail/pod.vue CHANGED
@@ -3,18 +3,19 @@ import CreateEditView from '@shell/mixins/create-edit-view';
3
3
  import Tab from '@shell/components/Tabbed/Tab';
4
4
  import ResourceTabs from '@shell/components/form/ResourceTabs';
5
5
  import SortableTable from '@shell/components/SortableTable';
6
- import { STATE, SIMPLE_NAME, IMAGE } from '@shell/config/table-headers';
6
+ import { STATE, SIMPLE_NAME, IMAGE_NAME } from '@shell/config/table-headers';
7
7
  import { sortableNumericSuffix } from '@shell/utils/sort';
8
8
  import { findBy } from '@shell/utils/array';
9
9
  import DashboardMetrics from '@shell/components/DashboardMetrics';
10
10
  import V1WorkloadMetrics from '@shell/mixins/v1-workload-metrics';
11
11
  import { mapGetters } from 'vuex';
12
12
  import { allDashboardsExist } from '@shell/utils/grafana';
13
- import Loading from '@shell/components/Loading';
14
13
  import LabeledSelect from '@shell/components/form/LabeledSelect';
15
14
  import day from 'dayjs';
16
15
  import { DATE_FORMAT, TIME_FORMAT } from '@shell/store/prefs';
17
16
  import { escapeHtml } from '@shell/utils/string';
17
+ import { NAMESPACE } from '@shell/config/types';
18
+ import { PROJECT } from '@shell/config/labels-annotations';
18
19
 
19
20
  const POD_METRICS_DETAIL_URL = '/api/v1/namespaces/cattle-monitoring-system/services/http:rancher-monitoring-grafana:80/proxy/d/rancher-pod-containers-1/rancher-pod-containers?orgId=1';
20
21
  const POD_METRICS_SUMMARY_URL = '/api/v1/namespaces/cattle-monitoring-system/services/http:rancher-monitoring-grafana:80/proxy/d/rancher-pod-1/rancher-pod?orgId=1';
@@ -24,7 +25,6 @@ export default {
24
25
 
25
26
  components: {
26
27
  DashboardMetrics,
27
- Loading,
28
28
  ResourceTabs,
29
29
  Tab,
30
30
  SortableTable,
@@ -35,6 +35,18 @@ export default {
35
35
 
36
36
  async fetch() {
37
37
  this.showMetrics = await allDashboardsExist(this.$store, this.currentCluster.id, [POD_METRICS_DETAIL_URL, POD_METRICS_SUMMARY_URL]);
38
+ if (!this.showMetrics) {
39
+ const namespace = await this.$store.dispatch('cluster/find', { type: NAMESPACE, id: this.value.metadata.namespace });
40
+
41
+ const projectId = namespace?.metadata?.labels[PROJECT];
42
+
43
+ if (projectId) {
44
+ this.POD_PROJECT_METRICS_DETAIL_URL = `/api/v1/namespaces/cattle-project-${ projectId }-monitoring/services/http:cattle-project-${ projectId }-monitoring-grafana:80/proxy/d/rancher-pod-containers-1/rancher-pod-containers?orgId=1'`;
45
+ this.POD_PROJECT_METRICS_SUMMARY_URL = `/api/v1/namespaces/cattle-project-${ projectId }-monitoring/services/http:cattle-project-${ projectId }-monitoring-grafana:80/proxy/d/rancher-pod-1/rancher-pod?orgId=1`;
46
+
47
+ this.showProjectMetrics = await allDashboardsExist(this.$store, this.currentCluster.id, [this.POD_PROJECT_METRICS_DETAIL_URL, this.POD_PROJECT_METRICS_SUMMARY_URL], 'cluster', projectId);
48
+ }
49
+ }
38
50
  },
39
51
 
40
52
  data() {
@@ -47,10 +59,13 @@ export default {
47
59
  return {
48
60
  POD_METRICS_DETAIL_URL,
49
61
  POD_METRICS_SUMMARY_URL,
62
+ POD_PROJECT_METRICS_DETAIL_URL: '',
63
+ POD_PROJECT_METRICS_SUMMARY_URL: '',
50
64
  POD_OPTION,
51
- showMetrics: false,
52
- selection: POD_OPTION,
53
- metricsID: null,
65
+ showMetrics: false,
66
+ showProjectMetrics: false,
67
+ selection: POD_OPTION,
68
+ metricsID: null,
54
69
  };
55
70
  },
56
71
 
@@ -142,7 +157,7 @@ export default {
142
157
  ...SIMPLE_NAME,
143
158
  value: 'name'
144
159
  },
145
- IMAGE,
160
+ IMAGE_NAME,
146
161
  {
147
162
  name: 'isInit',
148
163
  labelKey: 'workload.container.init',
@@ -224,9 +239,7 @@ export default {
224
239
  </script>
225
240
 
226
241
  <template>
227
- <Loading v-if="$fetchState.pending" />
228
242
  <ResourceTabs
229
- v-else
230
243
  mode="view"
231
244
  class="mt-20"
232
245
  :value="value"
@@ -282,6 +295,22 @@ export default {
282
295
  />
283
296
  </template>
284
297
  </Tab>
298
+ <Tab
299
+ v-if="showProjectMetrics"
300
+ :label="t('workload.container.titles.metrics')"
301
+ name="pod-metrics"
302
+ :weight="2.5"
303
+ >
304
+ <template #default="props">
305
+ <DashboardMetrics
306
+ v-if="props.active"
307
+ :detail-url="POD_PROJECT_METRICS_DETAIL_URL"
308
+ :summary-url="POD_PROJECT_METRICS_SUMMARY_URL"
309
+ :vars="graphVars"
310
+ graph-height="550px"
311
+ />
312
+ </template>
313
+ </Tab>
285
314
  </ResourceTabs>
286
315
  </template>
287
316
  <style scoped>
@@ -81,6 +81,24 @@ export default {
81
81
 
82
82
  async fetch() {
83
83
  await this.value.waitForProvisioner();
84
+
85
+ const extClass = this.$plugin.getDynamic('provisioner', this.value.machineProvider);
86
+
87
+ if (extClass) {
88
+ this.extProvider = new extClass({
89
+ dispatch: this.$store.dispatch,
90
+ getters: this.$store.getters,
91
+ axios: this.$store.$axios,
92
+ $plugin: this.$store.app.$plugin,
93
+ $t: this.t
94
+ });
95
+ this.extDetailTabs = {
96
+ ...this.extDetailTabs,
97
+ ...this.extProvider.detailTabs
98
+ };
99
+ this.extCustomParams = { provider: this.value.machineProvider };
100
+ }
101
+
84
102
  const fetchOne = {};
85
103
 
86
104
  if ( this.$store.getters['management/canList'](CAPI.MACHINE_DEPLOYMENT) ) {
@@ -206,6 +224,18 @@ export default {
206
224
  logSocket: null,
207
225
  logs: [],
208
226
 
227
+ extProvider: null,
228
+ extCustomParams: null,
229
+ extDetailTabs: {
230
+ machines: true, // in this component
231
+ logs: true, // in this component
232
+ registration: true, // in this component
233
+ snapshots: true, // in this component
234
+ related: true, // in ResourceTabs
235
+ events: true, // in ResourceTabs
236
+ conditions: true, // in ResourceTabs
237
+ },
238
+
209
239
  showWindowsWarning: false
210
240
  };
211
241
  },
@@ -336,7 +366,9 @@ export default {
336
366
  },
337
367
 
338
368
  showMachines() {
339
- return this.haveMachines && (this.value.isRke2 || !!this.machines.length);
369
+ const showMachines = this.haveMachines && (this.value.isRke2 || !!this.machines.length);
370
+
371
+ return showMachines && this.extDetailTabs.machines;
340
372
  },
341
373
 
342
374
  showNodes() {
@@ -345,9 +377,9 @@ export default {
345
377
 
346
378
  showSnapshots() {
347
379
  if (this.value.isRke1) {
348
- return this.$store.getters['rancher/canList'](NORMAN.ETCD_BACKUP);
380
+ return this.$store.getters['rancher/canList'](NORMAN.ETCD_BACKUP) && this.extDetailTabs.snapshots;
349
381
  } else if (this.value.isRke2) {
350
- return this.$store.getters['management/canList'](SNAPSHOT);
382
+ return this.$store.getters['management/canList'](SNAPSHOT) && this.extDetailTabs.snapshots;
351
383
  }
352
384
 
353
385
  return false;
@@ -476,15 +508,15 @@ export default {
476
508
  }
477
509
 
478
510
  if ( this.value.isImported ) {
479
- return !this.value.mgmt?.isReady;
511
+ return !this.value.mgmt?.isReady && this.extDetailTabs.registration;
480
512
  }
481
513
 
482
514
  if ( this.value.isCustom ) {
483
- return true;
515
+ return this.extDetailTabs.registration;
484
516
  }
485
517
 
486
518
  if ( this.value.isHostedKubernetesProvider && !this.isClusterReady ) {
487
- return true;
519
+ return this.extDetailTabs.registration;
488
520
  }
489
521
 
490
522
  return false;
@@ -495,7 +527,9 @@ export default {
495
527
  },
496
528
 
497
529
  showLog() {
498
- return this.value.mgmt?.hasLink('log');
530
+ const showLog = this.value.mgmt?.hasLink('log');
531
+
532
+ return showLog && this.extDetailTabs.logs;
499
533
  },
500
534
 
501
535
  dateTimeFormatStr() {
@@ -686,6 +720,10 @@ export default {
686
720
  v-model="value"
687
721
  :default-tab="defaultTab"
688
722
  :need-related="hasLocalAccess"
723
+ :extension-params="extCustomParams"
724
+ :needRelated="extDetailTabs.related"
725
+ :needEvents="extDetailTabs.events"
726
+ :needConditions="extDetailTabs.conditions"
689
727
  >
690
728
  <Tab
691
729
  v-if="showMachines"
@@ -773,6 +811,7 @@ export default {
773
811
  </template>
774
812
  </ResourceTable>
775
813
  </Tab>
814
+
776
815
  <Tab
777
816
  v-else-if="showNodes"
778
817
  name="node-pools"