@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.
- package/assets/images/wechat-qr-code.jpg +0 -0
- package/assets/translations/en-us.yaml +75 -16
- package/assets/translations/zh-hans.yaml +151 -15
- package/chart/__tests__/S3.test.ts +50 -0
- package/chart/rancher-backup/S3.vue +21 -0
- package/chart/rancher-backup/index.vue +4 -0
- package/components/AsyncButton.vue +1 -1
- package/components/CommunityLinks.vue +1 -0
- package/components/FileDiff.vue +92 -85
- package/components/Inactivity.vue +10 -0
- package/components/LazyImage.vue +2 -2
- package/components/PromptRestore.vue +7 -5
- package/components/ResourceDetail/Masthead.vue +1 -1
- package/components/ResourceDetail/index.vue +8 -14
- package/components/ResourceList/index.vue +1 -1
- package/components/ResourceTable.vue +50 -2
- package/components/YamlEditor.vue +1 -0
- package/components/__tests__/PromptRestore.test.ts +72 -0
- package/components/auth/AzureWarning.vue +1 -1
- package/components/auth/RoleDetailEdit.vue +1 -0
- package/components/fleet/FleetResources.vue +3 -64
- package/components/form/FileImageSelector.vue +9 -0
- package/components/form/FileSelector.vue +2 -1
- package/components/form/MatchExpressions.vue +1 -3
- package/components/form/NameNsDescription.vue +28 -12
- package/components/form/NodeAffinity.vue +2 -2
- package/components/form/PodAffinity.vue +2 -2
- package/components/form/ResourceTabs/index.vue +8 -2
- package/components/form/Select.vue +16 -0
- package/components/form/__tests__/FileImageSelector.test.ts +42 -0
- package/components/form/__tests__/FileSelector.test.ts +76 -0
- package/components/form/__tests__/NodeAffinity.test.ts +38 -0
- package/components/form/__tests__/PodAffinity.test.ts +46 -0
- package/components/formatter/ClusterLink.vue +8 -4
- package/components/formatter/ClusterProvider.vue +3 -1
- package/components/formatter/ImageName.vue +23 -0
- package/components/formatter/PodImages.vue +7 -1
- package/components/formatter/__tests__/ClusterLink.test.ts +101 -0
- package/components/formatter/__tests__/ClusterProvider.test.ts +24 -0
- package/components/nav/Header.vue +2 -2
- package/components/nav/WindowManager/ContainerShell.vue +60 -36
- package/components/nav/WindowManager/__tests__/ContainerShell.test.ts +561 -0
- package/config/__test__/home-links.test.ts +62 -0
- package/config/home-links.js +15 -3
- package/config/labels-annotations.js +7 -2
- package/config/persistentVolume.ts +108 -0
- package/config/product/manager.js +5 -1
- package/config/router.js +0 -4
- package/config/settings.ts +4 -0
- package/config/table-headers.js +6 -5
- package/config/types.js +2 -0
- package/config/uiplugins.js +50 -5
- package/core/plugin-helpers.js +39 -15
- package/core/plugin.ts +9 -0
- package/core/plugins.js +1 -1
- package/core/types-provisioning.ts +253 -0
- package/core/types.ts +21 -3
- package/detail/autoscaling.horizontalpodautoscaler/index.vue +50 -1
- package/detail/fleet.cattle.io.gitrepo.vue +10 -2
- package/detail/node.vue +6 -6
- package/detail/pod.vue +38 -9
- package/detail/provisioning.cattle.io.cluster.vue +46 -7
- package/detail/workload/index.vue +49 -18
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +62 -0
- package/edit/__tests__/ui.cattle.io.navlink.test.ts +110 -0
- package/edit/auth/github.vue +1 -0
- package/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue +130 -0
- package/edit/autoscaling.horizontalpodautoscaler/index.vue +79 -0
- package/edit/fleet.cattle.io.clustergroup.vue +14 -3
- package/edit/fleet.cattle.io.gitrepo.vue +18 -1
- package/edit/namespace.vue +9 -1
- package/edit/networking.k8s.io.ingress/RulePath.vue +0 -2
- package/edit/persistentvolume/__tests__/persistentvolume.test.ts +82 -0
- package/edit/persistentvolume/index.vue +2 -1
- package/edit/persistentvolume/plugins/csi.vue +3 -1
- package/edit/persistentvolume/plugins/longhorn.vue +12 -12
- package/edit/provisioning.cattle.io.cluster/AgentConfiguration.vue +1 -30
- package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +15 -11
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +79 -1
- package/edit/provisioning.cattle.io.cluster/index.vue +53 -1
- package/edit/provisioning.cattle.io.cluster/rke2.vue +335 -151
- package/edit/storage.k8s.io.storageclass/index.vue +1 -2
- package/edit/ui.cattle.io.navlink.vue +213 -186
- package/initialize/App.js +3 -13
- package/initialize/layouts.ts +26 -0
- package/layouts/default.vue +1 -1
- package/list/group.principal.vue +1 -1
- package/list/provisioning.cattle.io.cluster.vue +8 -1
- package/middleware/authenticated.js +101 -5
- package/mixins/brand.js +39 -3
- package/mixins/child-hook.js +2 -2
- package/mixins/create-edit-view/impl.js +4 -4
- package/models/chart.js +1 -1
- package/models/fleet.cattle.io.cluster.js +33 -4
- package/models/fleet.cattle.io.gitrepo.js +113 -38
- package/models/management.cattle.io.kontainerdriver.js +14 -0
- package/models/persistentvolume.js +2 -111
- package/models/pod.js +30 -0
- package/models/provisioning.cattle.io.cluster.js +9 -1
- package/models/rke.cattle.io.etcdsnapshot.js +10 -7
- package/package.json +2 -2
- package/pages/about.vue +8 -2
- package/pages/auth/login.vue +1 -1
- package/pages/auth/logout.vue +11 -3
- package/pages/c/_cluster/apps/charts/index.vue +5 -2
- package/pages/c/_cluster/apps/charts/install.vue +5 -0
- package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
- package/pages/c/_cluster/auth/roles/index.vue +1 -1
- package/pages/c/_cluster/explorer/index.vue +2 -11
- package/pages/c/_cluster/manager/cloudCredential/_id.vue +0 -1
- package/pages/c/_cluster/manager/cloudCredential/create.vue +0 -1
- package/pages/c/_cluster/settings/brand.vue +11 -8
- package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +177 -0
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +19 -3
- package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +90 -21
- package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +107 -37
- package/pages/c/_cluster/uiplugins/index.vue +160 -44
- package/pages/docs/_doc.vue +9 -3
- package/pages/home.vue +6 -6
- package/pages/support/index.vue +10 -4
- package/pkg/auto-import.js +1 -1
- package/plugins/clean-tooltip-directive.js +1 -1
- package/plugins/dashboard-store/__tests__/actions.spec.ts +165 -0
- package/plugins/dashboard-store/__tests__/getters.spec.ts +100 -0
- package/plugins/dashboard-store/__tests__/{mutations.spec.js → mutations.spec.ts} +2 -2
- package/plugins/dashboard-store/actions.js +1 -1
- package/plugins/dashboard-store/resource-class.js +39 -2
- package/plugins/plugin.js +9 -1
- package/plugins/steve/__tests__/getters.spec.ts +93 -0
- package/plugins/steve/getters.js +21 -1
- package/plugins/steve/subscribe.js +1 -3
- package/rancher-components/BadgeState/BadgeState.vue +5 -1
- package/rancher-components/Banner/Banner.test.ts +51 -1
- package/rancher-components/Banner/Banner.vue +134 -53
- package/rancher-components/Card/Card.test.ts +37 -0
- package/rancher-components/Card/Card.vue +24 -7
- package/rancher-components/Form/Checkbox/Checkbox.test.ts +20 -29
- package/rancher-components/Form/Checkbox/Checkbox.vue +45 -20
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +2 -8
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +22 -10
- package/rancher-components/Form/Radio/RadioButton.test.ts +31 -0
- package/rancher-components/Form/Radio/RadioButton.vue +30 -13
- package/rancher-components/Form/Radio/RadioGroup.vue +26 -7
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -6
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +25 -38
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +23 -11
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +19 -5
- package/rancher-components/StringList/StringList.test.ts +453 -49
- package/rancher-components/StringList/StringList.vue +44 -26
- package/scripts/extension/publish +2 -2
- package/scripts/typegen.sh +11 -2
- package/server/server-middleware.js +4 -12
- package/store/index.js +14 -3
- package/store/prefs.js +0 -3
- package/store/store-types.js +2 -0
- package/store/type-map.js +17 -29
- package/types/api.d.ts +1 -0
- package/types/fleet.d.ts +1 -0
- package/types/shell/index.d.ts +931 -85
- package/types/userPreferences.d.ts +1 -1
- package/utils/__mocks__/socket.js +21 -0
- package/utils/grafana.js +23 -11
- package/utils/kube.js +9 -0
- package/utils/object.js +27 -0
- package/utils/selector.js +2 -1
- package/utils/settings.ts +2 -2
- package/utils/validators/formRules/index.ts +3 -3
- package/vue.config.js +3 -2
- package/components/.DS_Store +0 -0
- package/components/__tests__/.DS_Store +0 -0
- package/creators/pkg/package-lock.json +0 -37
- package/pages/safeMode.vue +0 -17
- package/plugins/steve/urloptions.js +0 -47
- 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?:
|
|
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="
|
|
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
|
|
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
|
-
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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,
|
|
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:
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
515
|
+
return this.extDetailTabs.registration;
|
|
484
516
|
}
|
|
485
517
|
|
|
486
518
|
if ( this.value.isHostedKubernetesProvider && !this.isClusterReady ) {
|
|
487
|
-
return
|
|
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
|
-
|
|
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"
|