@rancher/shell 3.0.12-rc.5 → 3.0.12-rc.7
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/apis/intf/resources-api/resource-base.ts +42 -2
- package/apis/intf/resources-api/resource-instance.ts +101 -0
- package/apis/intf/resources-api/resources-api.ts +177 -23
- package/apis/intf/resources.ts +8 -6
- package/apis/intf/shell-api/slide-in.ts +46 -17
- package/apis/resources/__tests__/resources-api-class.test.ts +309 -28
- package/apis/resources/resources-api-class.ts +232 -43
- package/apis/shell/__tests__/slide-in.test.ts +83 -2
- package/apis/shell/slide-in.ts +20 -0
- package/assets/images/providers/traefik.png +0 -0
- package/assets/translations/en-us.yaml +10 -4
- package/chart/__tests__/rancher-monitoring-dashboards-index.test.ts +269 -0
- package/chart/rancher-monitoring-dashboards/index.vue +155 -0
- package/cloud-credential/__tests__/generic.test.ts +132 -0
- package/cloud-credential/generic.vue +33 -3
- package/components/EtcdInfoBanner.vue +2 -12
- package/components/ExplorerProjectsNamespaces.vue +2 -2
- package/components/GrafanaDashboard.vue +2 -8
- package/components/Resource/Detail/Masthead/__tests__/index.test.ts +68 -14
- package/components/Resource/Detail/Masthead/index.vue +8 -3
- package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +9 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +5 -1
- package/components/SlideInPanelManager.vue +103 -25
- package/components/__tests__/SlideInPanelManager.spec.ts +153 -10
- package/components/auth/AuthBanner.vue +1 -1
- package/components/form/Security.vue +1 -1
- package/components/formatter/Translate.vue +22 -1
- package/components/nav/Group.vue +5 -10
- package/components/nav/TopLevelMenu.vue +1 -30
- package/components/nav/__tests__/Group.test.ts +61 -0
- package/config/labels-annotations.js +1 -0
- package/config/table-headers.js +5 -2
- package/core/__tests__/plugin-products-apply.test.ts +787 -0
- package/core/__tests__/plugin-products-extend.test.ts +189 -0
- package/core/__tests__/plugin-products-helpers.test.ts +81 -78
- package/core/__tests__/plugin-products-new.test.ts +389 -0
- package/core/__tests__/plugin-products-scenarios.test.ts +980 -0
- package/core/__tests__/plugin-products-side-menu.test.ts +1935 -0
- package/core/plugin-products-base.ts +201 -93
- package/core/plugin-products-extending.ts +1 -1
- package/core/plugin-products-external.ts +380 -0
- package/core/plugin-products-helpers.ts +28 -24
- package/core/plugin-products-internal.ts +207 -0
- package/core/plugin-products-top-level.ts +10 -5
- package/core/plugin-products-type-guards.ts +17 -6
- package/core/plugin-products.ts +5 -7
- package/core/plugin-types.ts +1 -389
- package/core/plugin.ts +10 -11
- package/core/plugins-loader.js +2 -0
- package/core/types.ts +6 -202
- package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +52 -0
- package/detail/pod.vue +1 -1
- package/detail/provisioning.cattle.io.cluster.vue +0 -2
- package/edit/auth/AuthProviderWarningBanners.vue +12 -0
- package/edit/auth/__tests__/AuthProviderWarningBanners.test.ts +10 -1
- package/edit/auth/__tests__/azuread.test.ts +1 -0
- package/edit/auth/__tests__/github.test.ts +1 -0
- package/edit/auth/__tests__/oidc.test.ts +1 -0
- package/edit/auth/__tests__/saml.test.ts +1 -0
- package/edit/auth/ldap/__tests__/index.test.ts +1 -0
- package/edit/provisioning.cattle.io.cluster/index.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/rke2.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +2 -2
- package/list/management.cattle.io.user.vue +24 -5
- package/list/utils/management.cattle.io.cluster.utils.ts +1 -1
- package/machine-config/__tests__/generic.test.ts +163 -0
- package/machine-config/components/EC2Networking.vue +31 -7
- package/machine-config/components/__tests__/EC2Networking.test.ts +38 -15
- package/machine-config/generic.vue +32 -5
- package/mixins/resource-fetch.js +1 -1
- package/models/__tests__/namespace.test.ts +133 -8
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +57 -1
- package/models/__tests__/rke-machine.cattle.io.vmwarevspheremachinetemplate.test.ts +22 -0
- package/models/namespace.js +34 -2
- package/models/pod.js +12 -10
- package/models/provisioning.cattle.io.cluster.js +20 -13
- package/models/rke-machine.cattle.io.vmwarevspheremachinetemplate.js +9 -0
- package/package.json +1 -1
- package/pages/auth/login.vue +1 -1
- package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +110 -0
- package/pages/c/_cluster/apps/charts/install.vue +29 -0
- package/pages/c/_cluster/auth/config/index.vue +11 -4
- package/pages/c/_cluster/explorer/workload-dashboard/__tests__/composable.test.ts +136 -1
- package/pages/c/_cluster/explorer/workload-dashboard/composable.ts +69 -1
- package/pages/c/_cluster/fleet/index.vue +5 -9
- package/pages/c/_cluster/monitoring/index.vue +6 -1
- package/pkg/vue.config.js +4 -3
- package/plugins/codemirror.js +2 -0
- package/plugins/dashboard-store/resource-class.js +13 -9
- package/plugins/steve/__tests__/steve-class-resource-api.test.ts +147 -0
- package/plugins/steve/steve-class.js +43 -0
- package/plugins/steve/subscribe.js +11 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +115 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +83 -3
- package/store/__tests__/action-menu.test.ts +622 -0
- package/store/__tests__/auth.test.ts +18 -0
- package/store/__tests__/notifications.test.ts +466 -1
- package/store/__tests__/slideInPanel.test.ts +143 -43
- package/store/__tests__/ui-context.test.ts +255 -0
- package/store/__tests__/wm.test.ts +503 -0
- package/store/auth.js +11 -1
- package/store/aws.js +19 -4
- package/store/features.js +1 -0
- package/store/plugins.js +6 -0
- package/store/slideInPanel.ts +15 -3
- package/types/rancher/steve.api.ts +2 -2
- package/types/shell/index.d.ts +84 -2
- package/types/store/dashboard-store.types.ts +2 -2
- package/types/store/type-map.ts +262 -1
- package/utils/__tests__/fleet-appco.test.ts +23 -0
- package/utils/async.ts +2 -0
- package/utils/fleet-appco.ts +6 -1
- package/utils/grafana.js +2 -17
- package/utils/monitoring.js +38 -1
- package/utils/sort.js +1 -1
- package/core/__tests__/plugin-products.test.ts +0 -4694
package/types/shell/index.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export const IMPORTED_CLUSTER_VERSION_MANAGEMENT: "rancher.io/imported-cluster-v
|
|
|
28
28
|
export const UI_PROJECT_SECRET: "management.cattle.io/project-scoped-secret";
|
|
29
29
|
export const UI_PROJECT_SECRET_COPY: "management.cattle.io/project-scoped-secret-copy";
|
|
30
30
|
export const SERVICE_LINKS: "ui.rancher/service-links";
|
|
31
|
+
export const NODE_DRIVER_FIELD_HINTS: "io.cattle.nodedriver/ui-field-hints";
|
|
31
32
|
export namespace KUBERNETES {
|
|
32
33
|
let SERVICE_ACCOUNT_UID: string;
|
|
33
34
|
let SERVICE_ACCOUNT_NAME: string;
|
|
@@ -199,6 +200,7 @@ export const IMPORTED_CLUSTER_VERSION_MANAGEMENT: "rancher.io/imported-cluster-v
|
|
|
199
200
|
export const UI_PROJECT_SECRET: "management.cattle.io/project-scoped-secret";
|
|
200
201
|
export const UI_PROJECT_SECRET_COPY: "management.cattle.io/project-scoped-secret-copy";
|
|
201
202
|
export const SERVICE_LINKS: "ui.rancher/service-links";
|
|
203
|
+
export const NODE_DRIVER_FIELD_HINTS: "io.cattle.nodedriver/ui-field-hints";
|
|
202
204
|
export namespace KUBERNETES {
|
|
203
205
|
let SERVICE_ACCOUNT_UID: string;
|
|
204
206
|
let SERVICE_ACCOUNT_NAME: string;
|
|
@@ -2369,6 +2371,7 @@ export namespace FEATURE_DESCRIPTION {
|
|
|
2369
2371
|
export { formatter_65 as formatter };
|
|
2370
2372
|
export namespace formatterOpts_16 {
|
|
2371
2373
|
let prefix: string;
|
|
2374
|
+
let fallbackPath: string;
|
|
2372
2375
|
}
|
|
2373
2376
|
export { formatterOpts_16 as formatterOpts };
|
|
2374
2377
|
}
|
|
@@ -4166,6 +4169,7 @@ export namespace FEATURE_DESCRIPTION {
|
|
|
4166
4169
|
export { formatter_65 as formatter };
|
|
4167
4170
|
export namespace formatterOpts_16 {
|
|
4168
4171
|
let prefix: string;
|
|
4172
|
+
let fallbackPath: string;
|
|
4169
4173
|
}
|
|
4170
4174
|
export { formatterOpts_16 as formatterOpts };
|
|
4171
4175
|
}
|
|
@@ -5979,13 +5983,25 @@ export default class Namespace {
|
|
|
5979
5983
|
get confirmRemove(): boolean;
|
|
5980
5984
|
get listLocation(): {
|
|
5981
5985
|
name: string;
|
|
5986
|
+
params: {
|
|
5987
|
+
cluster: any;
|
|
5988
|
+
product: any;
|
|
5989
|
+
};
|
|
5982
5990
|
};
|
|
5983
5991
|
get _detailLocation(): any;
|
|
5984
5992
|
get parentLocationOverride(): {
|
|
5985
5993
|
name: string;
|
|
5994
|
+
params: {
|
|
5995
|
+
cluster: any;
|
|
5996
|
+
product: any;
|
|
5997
|
+
};
|
|
5986
5998
|
};
|
|
5987
5999
|
get doneOverride(): {
|
|
5988
6000
|
name: string;
|
|
6001
|
+
params: {
|
|
6002
|
+
cluster: any;
|
|
6003
|
+
product: any;
|
|
6004
|
+
};
|
|
5989
6005
|
};
|
|
5990
6006
|
set resourceQuota(value: any);
|
|
5991
6007
|
get resourceQuota(): any;
|
|
@@ -6043,13 +6059,25 @@ export default class Namespace {
|
|
|
6043
6059
|
get confirmRemove(): boolean;
|
|
6044
6060
|
get listLocation(): {
|
|
6045
6061
|
name: string;
|
|
6062
|
+
params: {
|
|
6063
|
+
cluster: any;
|
|
6064
|
+
product: any;
|
|
6065
|
+
};
|
|
6046
6066
|
};
|
|
6047
6067
|
get _detailLocation(): any;
|
|
6048
6068
|
get parentLocationOverride(): {
|
|
6049
6069
|
name: string;
|
|
6070
|
+
params: {
|
|
6071
|
+
cluster: any;
|
|
6072
|
+
product: any;
|
|
6073
|
+
};
|
|
6050
6074
|
};
|
|
6051
6075
|
get doneOverride(): {
|
|
6052
6076
|
name: string;
|
|
6077
|
+
params: {
|
|
6078
|
+
cluster: any;
|
|
6079
|
+
product: any;
|
|
6080
|
+
};
|
|
6053
6081
|
};
|
|
6054
6082
|
set resourceQuota(value: any);
|
|
6055
6083
|
get resourceQuota(): any;
|
|
@@ -7870,6 +7898,18 @@ export default class SteveModel extends HybridModel {
|
|
|
7870
7898
|
* @param {*} res
|
|
7871
7899
|
*/
|
|
7872
7900
|
processSaveResponse(res: any, opt?: {}): void;
|
|
7901
|
+
/**
|
|
7902
|
+
* RESOURCES API - ResourceInstance update method to send a PATCH request
|
|
7903
|
+
*/
|
|
7904
|
+
update(data: any): Promise<this>;
|
|
7905
|
+
/**
|
|
7906
|
+
* RESOURCES API - ResourceInstance update method to send a PUT request
|
|
7907
|
+
*/
|
|
7908
|
+
replace(): Promise<this>;
|
|
7909
|
+
/**
|
|
7910
|
+
* RESOURCES API - ResourceInstance delete method to send a DELETE request
|
|
7911
|
+
*/
|
|
7912
|
+
delete(): Promise<void>;
|
|
7873
7913
|
}
|
|
7874
7914
|
import HybridModel from './hybrid-class';
|
|
7875
7915
|
}
|
|
@@ -7899,6 +7939,18 @@ export default class SteveModel extends HybridModel {
|
|
|
7899
7939
|
* @param {*} res
|
|
7900
7940
|
*/
|
|
7901
7941
|
processSaveResponse(res: any, opt?: {}): void;
|
|
7942
|
+
/**
|
|
7943
|
+
* RESOURCES API - ResourceInstance update method to send a PATCH request
|
|
7944
|
+
*/
|
|
7945
|
+
update(data: any): Promise<this>;
|
|
7946
|
+
/**
|
|
7947
|
+
* RESOURCES API - ResourceInstance update method to send a PUT request
|
|
7948
|
+
*/
|
|
7949
|
+
replace(): Promise<this>;
|
|
7950
|
+
/**
|
|
7951
|
+
* RESOURCES API - ResourceInstance delete method to send a DELETE request
|
|
7952
|
+
*/
|
|
7953
|
+
delete(): Promise<void>;
|
|
7902
7954
|
}
|
|
7903
7955
|
import HybridModel from './hybrid-class';
|
|
7904
7956
|
}
|
|
@@ -7928,6 +7980,7 @@ export const AUTOSCALER: any;
|
|
|
7928
7980
|
export const CLUSTER_SHELL: any;
|
|
7929
7981
|
export const NODE_SHELL: any;
|
|
7930
7982
|
export const POD_SHELL: any;
|
|
7983
|
+
export const HIDE_LOCAL_AUTH_PROVIDER: any;
|
|
7931
7984
|
export namespace getters {
|
|
7932
7985
|
function get(state: any, getters: any, rootState: any, rootGetters: any): (name: any) => any;
|
|
7933
7986
|
}
|
|
@@ -7964,6 +8017,7 @@ export const AUTOSCALER: any;
|
|
|
7964
8017
|
export const CLUSTER_SHELL: any;
|
|
7965
8018
|
export const NODE_SHELL: any;
|
|
7966
8019
|
export const POD_SHELL: any;
|
|
8020
|
+
export const HIDE_LOCAL_AUTH_PROVIDER: any;
|
|
7967
8021
|
export namespace getters {
|
|
7968
8022
|
function get(state: any, getters: any, rootState: any, rootGetters: any): (name: any) => any;
|
|
7969
8023
|
}
|
|
@@ -7988,6 +8042,12 @@ export const fullFields: any[];
|
|
|
7988
8042
|
export const prefixFields: any[];
|
|
7989
8043
|
export const suffixFields: any[];
|
|
7990
8044
|
export function state(): {};
|
|
8045
|
+
export namespace actions {
|
|
8046
|
+
function mapDriver(ctx: any, { name, to }: {
|
|
8047
|
+
name: any;
|
|
8048
|
+
to: any;
|
|
8049
|
+
}): void;
|
|
8050
|
+
}
|
|
7991
8051
|
export namespace getters {
|
|
7992
8052
|
function credentialOptions(): (name: any) => any;
|
|
7993
8053
|
function credentialDriverFor(): (name: any) => any;
|
|
@@ -8013,6 +8073,12 @@ export const fullFields: any[];
|
|
|
8013
8073
|
export const prefixFields: any[];
|
|
8014
8074
|
export const suffixFields: any[];
|
|
8015
8075
|
export function state(): {};
|
|
8076
|
+
export namespace actions {
|
|
8077
|
+
function mapDriver(ctx: any, { name, to }: {
|
|
8078
|
+
name: any;
|
|
8079
|
+
to: any;
|
|
8080
|
+
}): void;
|
|
8081
|
+
}
|
|
8016
8082
|
export namespace getters {
|
|
8017
8083
|
function credentialOptions(): (name: any) => any;
|
|
8018
8084
|
function credentialDriverFor(): (name: any) => any;
|
|
@@ -9526,6 +9592,14 @@ export function monitoringStatus(): {
|
|
|
9526
9592
|
};
|
|
9527
9593
|
};
|
|
9528
9594
|
export function haveV2Monitoring(getters: any): boolean;
|
|
9595
|
+
/**
|
|
9596
|
+
* Look up the installed Rancher monitoring app, preferring the new
|
|
9597
|
+
* `rancher-monitoring-dashboards` chart and falling back to the legacy
|
|
9598
|
+
* `rancher-monitoring`. Returns null if the user lacks permission, neither
|
|
9599
|
+
* chart is installed, or any lookup fails.
|
|
9600
|
+
*/
|
|
9601
|
+
export function fetchMonitoringApp(store: any, storeName: any): Promise<any>;
|
|
9602
|
+
export function fetchMonitoringVersion(store: any, storeName: any): Promise<any>;
|
|
9529
9603
|
export function canViewGrafanaLink(store: any): Promise<boolean>;
|
|
9530
9604
|
export function canViewAlertManagerLink(store: any): Promise<boolean>;
|
|
9531
9605
|
export function canViewPrometheusLink(store: any): Promise<boolean>;
|
|
@@ -9541,6 +9615,14 @@ export function monitoringStatus(): {
|
|
|
9541
9615
|
};
|
|
9542
9616
|
};
|
|
9543
9617
|
export function haveV2Monitoring(getters: any): boolean;
|
|
9618
|
+
/**
|
|
9619
|
+
* Look up the installed Rancher monitoring app, preferring the new
|
|
9620
|
+
* `rancher-monitoring-dashboards` chart and falling back to the legacy
|
|
9621
|
+
* `rancher-monitoring`. Returns null if the user lacks permission, neither
|
|
9622
|
+
* chart is installed, or any lookup fails.
|
|
9623
|
+
*/
|
|
9624
|
+
export function fetchMonitoringApp(store: any, storeName: any): Promise<any>;
|
|
9625
|
+
export function fetchMonitoringVersion(store: any, storeName: any): Promise<any>;
|
|
9544
9626
|
export function canViewGrafanaLink(store: any): Promise<boolean>;
|
|
9545
9627
|
export function canViewAlertManagerLink(store: any): Promise<boolean>;
|
|
9546
9628
|
export function canViewPrometheusLink(store: any): Promise<boolean>;
|
|
@@ -10511,7 +10593,7 @@ export function parseField(str: any): {
|
|
|
10511
10593
|
field: any;
|
|
10512
10594
|
reverse: boolean;
|
|
10513
10595
|
};
|
|
10514
|
-
export function sortBy(ary: any, keys: any, desc
|
|
10596
|
+
export function sortBy(ary: any, keys: any, desc?: boolean): any;
|
|
10515
10597
|
export function sortableNumericSuffix(str: any): any;
|
|
10516
10598
|
export function isNumeric(num: any): boolean;
|
|
10517
10599
|
}
|
|
@@ -10576,7 +10658,7 @@ export function parseField(str: any): {
|
|
|
10576
10658
|
field: any;
|
|
10577
10659
|
reverse: boolean;
|
|
10578
10660
|
};
|
|
10579
|
-
export function sortBy(ary: any, keys: any, desc
|
|
10661
|
+
export function sortBy(ary: any, keys: any, desc?: boolean): any;
|
|
10580
10662
|
export function sortableNumericSuffix(str: any): any;
|
|
10581
10663
|
export function isNumeric(num: any): boolean;
|
|
10582
10664
|
}
|
|
@@ -180,7 +180,7 @@ export type ActionFindPageTransientResponse<T = any> = {
|
|
|
180
180
|
*
|
|
181
181
|
* If the request was not transient this will just be the array of resources
|
|
182
182
|
*/
|
|
183
|
-
export type ActionFindPageResponse<T = any
|
|
183
|
+
export type ActionFindPageResponse<T = Record<string, any>> = ActionFindPageTransientResponse<T> | T[];
|
|
184
184
|
|
|
185
185
|
/**
|
|
186
186
|
* Args used for findMatching action
|
|
@@ -221,7 +221,7 @@ export interface ActionFindMatchingArgs extends ActionCoreFindOptions {
|
|
|
221
221
|
* @internal
|
|
222
222
|
* Response to the findMatching action
|
|
223
223
|
*/
|
|
224
|
-
export type ActionFindMatchingResponse<T = any> =
|
|
224
|
+
export type ActionFindMatchingResponse<T = any> = T[]
|
|
225
225
|
|
|
226
226
|
/**
|
|
227
227
|
* @internal
|
package/types/store/type-map.ts
CHANGED
|
@@ -1,3 +1,264 @@
|
|
|
1
|
+
import { PluginRouteRecordRaw } from '@shell/core/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The product as seen by the type-map
|
|
5
|
+
*/
|
|
6
|
+
export interface TypeMapProduct {
|
|
7
|
+
/**
|
|
8
|
+
* The category this product belongs under. i.e. 'config'
|
|
9
|
+
*/
|
|
10
|
+
category?: string;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Hide the Copy KubeConfig button in the header
|
|
14
|
+
*/
|
|
15
|
+
hideCopyConfig?: boolean;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Hide the Download KubeConfig button in the header
|
|
19
|
+
*/
|
|
20
|
+
hideKubeConfig?: boolean;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Hide the Kubectl Shell button in the header
|
|
24
|
+
*/
|
|
25
|
+
hideKubeShell?: boolean;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Hide the Namespace location
|
|
29
|
+
*/
|
|
30
|
+
hideNamespaceLocation?: boolean;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Hide the system resources
|
|
34
|
+
*/
|
|
35
|
+
hideSystemResources?: boolean;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The icon that should be displayed beside this item in the navigation.
|
|
39
|
+
*/
|
|
40
|
+
icon?: string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Alternative to the icon property. Uses require
|
|
44
|
+
*/
|
|
45
|
+
svg?: Function;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Only load the product if the feature is present
|
|
49
|
+
*/
|
|
50
|
+
ifFeature?: string | RegExp;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Only load the product if the type is present
|
|
54
|
+
*/
|
|
55
|
+
ifHave?: string;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Only load the product if the group is present
|
|
59
|
+
*/
|
|
60
|
+
ifHaveGroup?: string | RegExp;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Only load the product if the type is present
|
|
64
|
+
*/
|
|
65
|
+
ifHaveType?: string | RegExp;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Hide the product if the type is present (opposite of ifHaveType)
|
|
69
|
+
*/
|
|
70
|
+
ifNotHaveType?: string | RegExp;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The vuex store that this product should use by default i.e. 'management'
|
|
74
|
+
*/
|
|
75
|
+
inStore?: string;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Show the cluster switcher in the navigation
|
|
79
|
+
*/
|
|
80
|
+
showClusterSwitcher?: boolean;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Indicates whether UI Extensions can add pages to this product
|
|
84
|
+
*/
|
|
85
|
+
extendable?: boolean;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Show the namespace filter in the header
|
|
89
|
+
*/
|
|
90
|
+
showNamespaceFilter?: boolean;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* A number used to determine where in navigation this item will be placed. The highest number will be at the top of the list.
|
|
94
|
+
*/
|
|
95
|
+
weight?: number;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The route that the product will lead to if click on in navigation.
|
|
99
|
+
*/
|
|
100
|
+
to?: PluginRouteRecordRaw;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Product name
|
|
104
|
+
*
|
|
105
|
+
* Defaults to the DSL fn product arg
|
|
106
|
+
*/
|
|
107
|
+
name?: string;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
*
|
|
111
|
+
*/
|
|
112
|
+
label?: string;
|
|
113
|
+
|
|
114
|
+
labelKey?: string;
|
|
115
|
+
|
|
116
|
+
iconHeader?: string;
|
|
117
|
+
|
|
118
|
+
// Do not use - internal use only
|
|
119
|
+
version?: number;
|
|
120
|
+
|
|
121
|
+
renameGroups?: {
|
|
122
|
+
/** String or regex to match against group internal IDs */
|
|
123
|
+
groupSelector: RegExp | string;
|
|
124
|
+
/** Display name to use for matching groups */
|
|
125
|
+
newName: string;
|
|
126
|
+
}[];
|
|
127
|
+
|
|
128
|
+
moveToGroup?: {
|
|
129
|
+
/** Page identifier — the resource `type` string or the custom page `name` */
|
|
130
|
+
entryId: string;
|
|
131
|
+
/** Target group name as defined in your group config (`name` property) */
|
|
132
|
+
groupName: string;
|
|
133
|
+
/** Ordering weight for the mapping (default: 5). Higher weight takes precedence when multiple rules match */
|
|
134
|
+
weight?: number;
|
|
135
|
+
}[];
|
|
136
|
+
|
|
137
|
+
ignoreGroups?: {
|
|
138
|
+
/** String or regex to match against group names */
|
|
139
|
+
groupSelector: string | RegExp;
|
|
140
|
+
/** Optional conditional function that accepts the root Dashboard Vuex store getters and returns true if the group should be ignored */
|
|
141
|
+
condition?: (getters: any) => boolean;
|
|
142
|
+
}[];
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Whether the product can be removed by users (default: false — products are built-in/not removable unless explicitly set to true)
|
|
146
|
+
*/
|
|
147
|
+
removable?: boolean;
|
|
148
|
+
/**
|
|
149
|
+
* controls whether a workspace switcher dropdown appears in the header (instead of the namespace filter) if set to true
|
|
150
|
+
*/
|
|
151
|
+
showWorkspaceSwitcher?: boolean;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Leaving these here for completeness but I don't think these should be advertised as useable to plugin creators.
|
|
155
|
+
*/
|
|
156
|
+
// ifHaveVerb: string | RegExp;
|
|
157
|
+
// supportRoute: string;
|
|
158
|
+
// typeStoreMap: string;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Used by type-map configureType
|
|
163
|
+
*/
|
|
164
|
+
export interface TypeMapConfigureType {
|
|
165
|
+
/** Override for the name displayed */
|
|
166
|
+
displayName?: string;
|
|
167
|
+
/** Override for the create button string on a list view */
|
|
168
|
+
listCreateButtonLabelKey?: string;
|
|
169
|
+
/** If false, disable create even if schema says it's allowed */
|
|
170
|
+
isCreatable?: boolean;
|
|
171
|
+
/** If false, disable for edit */
|
|
172
|
+
isEditable?: boolean;
|
|
173
|
+
/** If false, disable for remove/delete */
|
|
174
|
+
isRemovable?: boolean;
|
|
175
|
+
/** If false, hide state in columns and masthead */
|
|
176
|
+
showState?: boolean;
|
|
177
|
+
/** If false, hide age in columns and masthead */
|
|
178
|
+
showAge?: boolean;
|
|
179
|
+
/** If false, hide masthead config button in view mode */
|
|
180
|
+
showConfigView?: boolean;
|
|
181
|
+
/** If false, hide masthead in list view */
|
|
182
|
+
showListMasthead?: boolean;
|
|
183
|
+
/** If false, cannot edit or show yaml */
|
|
184
|
+
canYaml?: boolean;
|
|
185
|
+
/** Show the Masthead in the edit resource component */
|
|
186
|
+
resourceEditMasthead?: boolean;
|
|
187
|
+
/** Entry route definition for this resource page */
|
|
188
|
+
customRoute?: PluginRouteRecordRaw | Object;
|
|
189
|
+
/** Hide this type from the nav/search bar on downstream clusters (will only show in "local" cluster) */
|
|
190
|
+
localOnly?: boolean;
|
|
191
|
+
// resource: undefined; // Use this resource in ResourceDetails instead
|
|
192
|
+
// resourceDetail: undefined; // Use this resource specifically for ResourceDetail's detail component
|
|
193
|
+
// resourceEdit: undefined; // Use this resource specifically for ResourceDetail's edit component
|
|
194
|
+
/**
|
|
195
|
+
* Use this to depaginate requests for this type
|
|
196
|
+
*/
|
|
197
|
+
depaginate?: undefined;
|
|
198
|
+
// notFilterNamespace: undefined; // Define namespaces that do not need to be filtered
|
|
199
|
+
// used in configureType options, to be typed later if needed
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Whether this custom page has list groups (definition for grouping items in the list view)
|
|
203
|
+
*/
|
|
204
|
+
listGroups?: {
|
|
205
|
+
/** Icon for the group (relates to icons in rancher-icons */
|
|
206
|
+
icon?: string;
|
|
207
|
+
/** Value for the group (used for grouping items in the list view) */
|
|
208
|
+
value?: string;
|
|
209
|
+
/** Field for the group (used for grouping items in the list view) */
|
|
210
|
+
field?: string;
|
|
211
|
+
/** Column to hide when this group is active */
|
|
212
|
+
hideColumn?: string;
|
|
213
|
+
/** Tooltip key for the group */
|
|
214
|
+
tooltipKey?: string;
|
|
215
|
+
}[];
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Whether the provided list groups will override the default grouping options (e.g. group by namespace, group by cluster, etc.) or be added to them
|
|
219
|
+
*/
|
|
220
|
+
listGroupsWillOverride?: boolean;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Use this to configure subtypes that should be shown in the list view for this type (e.g. show "pods" and "deployments" in the list view for "workloads")
|
|
224
|
+
*/
|
|
225
|
+
subTypes?: string[];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Used by type-map virtualType
|
|
230
|
+
*/
|
|
231
|
+
export interface TypeMapVirtualType {
|
|
232
|
+
/** Display only if condition is met (relates to IF_HAVE in shell/store/type-map) */
|
|
233
|
+
ifHave?: boolean;
|
|
234
|
+
/** Display only if feature is present (relates to shell/store/features) */
|
|
235
|
+
ifFeature?: string;
|
|
236
|
+
/** Display only if resource type exists */
|
|
237
|
+
ifHaveType?: string;
|
|
238
|
+
/** Used in conjunction with "ifHaveType", display only if resource type allows this verb (GET, POST, PUT, DELETE) */
|
|
239
|
+
ifHaveVerb?: string;
|
|
240
|
+
/** Display label for the custom page */
|
|
241
|
+
label?: string;
|
|
242
|
+
/** Translation key for the label */
|
|
243
|
+
labelKey?: string;
|
|
244
|
+
name: string;
|
|
245
|
+
// /** Name of the page (unique identifier) */
|
|
246
|
+
// name?: string;
|
|
247
|
+
/** Entry route definition for this custom page */
|
|
248
|
+
route?: PluginRouteRecordRaw | Object;
|
|
249
|
+
/** Icon for the custom page (relates to icons in https://github.com/rancher/icons) */
|
|
250
|
+
icon?: 'compass';
|
|
251
|
+
/** Whether this custom page is namespaced or not */
|
|
252
|
+
namespaced?: boolean;
|
|
253
|
+
/** Ordering weight for the custom page */
|
|
254
|
+
weight?: number;
|
|
255
|
+
/** Whether this custom page is exact match */
|
|
256
|
+
exact?: boolean;
|
|
257
|
+
/** Whether this custom page will act as an overview page */
|
|
258
|
+
overview?: boolean;
|
|
259
|
+
/** Whether this custom page has an exact path match */
|
|
260
|
+
'exact-path'?: boolean;
|
|
261
|
+
}
|
|
1
262
|
|
|
2
263
|
/**
|
|
3
264
|
* interface for type-map's' definition for table headers/columns
|
|
@@ -11,7 +272,7 @@ export interface TableColumn {
|
|
|
11
272
|
formatterOpts?: any,
|
|
12
273
|
width?: number,
|
|
13
274
|
tooltip?: string,
|
|
14
|
-
search?: string | boolean,
|
|
275
|
+
search?: string | string[] | boolean,
|
|
15
276
|
}
|
|
16
277
|
|
|
17
278
|
export const COLUMN_BREAKPOINTS = {
|
|
@@ -100,6 +100,29 @@ describe('fleet-appco utils', () => {
|
|
|
100
100
|
expect(onStateChange).toHaveBeenCalledWith(expect.objectContaining({ repoName: 'my-repo', error: false }));
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
+
it('should wait for the repo using a 10 minute timeout and 3s interval (#14627)', async() => {
|
|
104
|
+
// A cold OCI pull can take minutes; the wait must not give up early.
|
|
105
|
+
const waitForTestFn = jest.fn((fn: () => boolean) => {
|
|
106
|
+
fn();
|
|
107
|
+
|
|
108
|
+
return Promise.resolve();
|
|
109
|
+
});
|
|
110
|
+
const repo = buildRepo({
|
|
111
|
+
status: { conditions: [{ type: 'OCIDownloaded', status: 'True' }] },
|
|
112
|
+
waitForTestFn,
|
|
113
|
+
});
|
|
114
|
+
const store = buildStore(repo);
|
|
115
|
+
|
|
116
|
+
await fetchAppCoCharts(store as any, 'my-repo');
|
|
117
|
+
|
|
118
|
+
expect(waitForTestFn).toHaveBeenCalledWith(
|
|
119
|
+
expect.any(Function),
|
|
120
|
+
expect.stringContaining('my-repo'),
|
|
121
|
+
600000,
|
|
122
|
+
3000,
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
|
|
103
126
|
it('should return no entries and an error state when the repo reports an error', async() => {
|
|
104
127
|
const repo = buildRepo({ metadata: { state: { error: true, message: 'boom' } } });
|
|
105
128
|
const store = buildStore(repo);
|
package/utils/async.ts
CHANGED
|
@@ -5,6 +5,8 @@ export const waitFor = (testFn: Function, msg = '', timeoutMs = 3000000, interva
|
|
|
5
5
|
if (testFn()) {
|
|
6
6
|
gatedLog('Wait for', msg || 'unknown', 'done immediately');
|
|
7
7
|
resolve(this);
|
|
8
|
+
|
|
9
|
+
return;
|
|
8
10
|
}
|
|
9
11
|
const timeout = setTimeout(() => {
|
|
10
12
|
gatedLog('Wait for', msg, 'timed out');
|
package/utils/fleet-appco.ts
CHANGED
|
@@ -198,7 +198,12 @@ export async function ensureAppCoResources(
|
|
|
198
198
|
return true;
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
|
|
201
|
+
// Cold/first OCI pulls of the AppCo catalog can take several minutes to download,
|
|
202
|
+
// so we allow a generous window before giving up. Genuine repo/OCI errors still
|
|
203
|
+
// short-circuit early via the `hasError` path below, so this only bounds how long
|
|
204
|
+
// we tolerate a repo that is still downloading. Added as 10 minutes to consider
|
|
205
|
+
// future increases on the size of the AppCo catalog.
|
|
206
|
+
const REPO_WAIT_TIMEOUT_MS = 600000; // 10 minutes
|
|
202
207
|
const REPO_WAIT_INTERVAL_MS = 3000;
|
|
203
208
|
|
|
204
209
|
function getRepoState(repo: any, repoName: string): { state: RepoState; isReady: boolean; hasError: boolean } {
|
package/utils/grafana.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { haveV2Monitoring } from '@shell/utils/monitoring';
|
|
1
|
+
import { haveV2Monitoring, fetchMonitoringVersion } from '@shell/utils/monitoring';
|
|
2
2
|
import { parse as parseUrl, addParam } from '@shell/utils/url';
|
|
3
|
-
import { CATALOG } from '@shell/config/types';
|
|
4
3
|
|
|
5
4
|
// these two versions of monitoring included a bug fix attempt that required the local cluster to use a different url
|
|
6
5
|
// the solution going forward doesn't require this, see https://github.com/rancher/dashboard/issues/8885
|
|
@@ -60,21 +59,7 @@ export async function dashboardExists(monitoringVersion, store, clusterId, embed
|
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
export async function allDashboardsExist(store, clusterId, embeddedUrls, storeName = 'cluster', projectId = null) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
let monitoringVersion = '';
|
|
66
|
-
|
|
67
|
-
if (!projectId && store.getters[`${ storeName }/canList`](CATALOG.APP)) {
|
|
68
|
-
try {
|
|
69
|
-
res = await store.dispatch(`${ storeName }/find`, {
|
|
70
|
-
type: CATALOG.APP,
|
|
71
|
-
id: 'cattle-monitoring-system/rancher-monitoring'
|
|
72
|
-
});
|
|
73
|
-
} catch (err) {
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
monitoringVersion = res?.currentVersion;
|
|
77
|
-
}
|
|
62
|
+
const monitoringVersion = projectId ? '' : await fetchMonitoringVersion(store, storeName);
|
|
78
63
|
|
|
79
64
|
const existPromises = embeddedUrls.map((url) => dashboardExists(monitoringVersion, store, clusterId, url, storeName, projectId));
|
|
80
65
|
|
package/utils/monitoring.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Helpers for determining if V2 or v1 Monitoring are installed
|
|
2
2
|
|
|
3
|
-
import { SCHEMA, MONITORING, ENDPOINTS } from '@shell/config/types';
|
|
3
|
+
import { SCHEMA, MONITORING, ENDPOINTS, CATALOG } from '@shell/config/types';
|
|
4
4
|
import { normalizeType } from '@shell/plugins/dashboard-store/normalize';
|
|
5
5
|
import { findBy } from '@shell/utils/array';
|
|
6
6
|
import { isEmpty } from '@shell/utils/object';
|
|
@@ -30,6 +30,43 @@ export function haveV2Monitoring(getters) {
|
|
|
30
30
|
|
|
31
31
|
export const CATTLE_MONITORING_NAMESPACE = 'cattle-monitoring-system';
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Look up the installed Rancher monitoring app, preferring the new
|
|
35
|
+
* `rancher-monitoring-dashboards` chart and falling back to the legacy
|
|
36
|
+
* `rancher-monitoring`. Returns null if the user lacks permission, neither
|
|
37
|
+
* chart is installed, or any lookup fails.
|
|
38
|
+
*/
|
|
39
|
+
export async function fetchMonitoringApp(store, storeName) {
|
|
40
|
+
if (!store.getters[`${ storeName }/canList`](CATALOG.APP)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const ids = [
|
|
45
|
+
`${ CATTLE_MONITORING_NAMESPACE }/rancher-monitoring-dashboards`,
|
|
46
|
+
`${ CATTLE_MONITORING_NAMESPACE }/rancher-monitoring`,
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
for (const id of ids) {
|
|
50
|
+
try {
|
|
51
|
+
const res = await store.dispatch(`${ storeName }/find`, { type: CATALOG.APP, id });
|
|
52
|
+
|
|
53
|
+
if (res) {
|
|
54
|
+
return res;
|
|
55
|
+
}
|
|
56
|
+
} catch (err) {
|
|
57
|
+
// Try the next id; both failing means nothing is installed.
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function fetchMonitoringVersion(store, storeName) {
|
|
65
|
+
const app = await fetchMonitoringApp(store, storeName);
|
|
66
|
+
|
|
67
|
+
return app?.currentVersion || '';
|
|
68
|
+
}
|
|
69
|
+
|
|
33
70
|
async function hasEndpointSubsets(store, id) {
|
|
34
71
|
if (store.getters['cluster/schemaFor'](ENDPOINTS)) {
|
|
35
72
|
const endpoints = await store.dispatch('cluster/findAll', { type: ENDPOINTS }) || [];
|