Skip to content

Commit ab3550c

Browse files
committed
CNV-69204: make checkups lists multicluster
1 parent 9c9240d commit ab3550c

14 files changed

+378
-192
lines changed

src/multicluster/extensions.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,21 @@ export const extensions: EncodedExtension[] = [
143143
},
144144
type: 'console.navigation/href',
145145
} as EncodedExtension<HrefNavItem>,
146+
{
147+
properties: {
148+
dataAttributes: {
149+
'data-border': 'no-border',
150+
'data-class': 'kv-plugin-virt-perspective-element',
151+
'data-quickstart-id': 'qs-nav-checkups',
152+
'data-test-id': 'checkups-nav-item',
153+
},
154+
href: `/k8s/all-clusters/all-namespaces/checkups`,
155+
id: 'checkups-virt-perspective',
156+
name: '%plugin__kubevirt-plugin~Checkups%',
157+
perspective: 'fleet-virtualization-perspective',
158+
},
159+
type: 'console.navigation/href',
160+
} as EncodedExtension<HrefNavItem>,
146161
{
147162
flags: {
148163
required: ['KUBEVIRT_DYNAMIC_ACM'],
@@ -344,6 +359,16 @@ export const extensions: EncodedExtension[] = [
344359
},
345360
type: 'acm.resource/route',
346361
} as EncodedExtension<ResourceRoute>,
362+
363+
{
364+
properties: {
365+
component: {
366+
$codeRef: 'Checkups',
367+
},
368+
path: ['/k8s/all-clusters/all-namespaces/checkups'],
369+
},
370+
type: 'console.page/route',
371+
} as EncodedExtension<RoutePage>,
347372
{
348373
properties: {
349374
handler: { $codeRef: 'urls.getFleetClusterResourceRoute' },
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const getNetworkCheckupURL = (name: string, namespace: string, cluster?: string) => {
2+
return cluster
3+
? `/k8s/cluster/${cluster}/ns/${namespace}/checkups/${name}`
4+
: `/k8s/ns/${namespace}/checkups/network/${name}`;
5+
};
6+
7+
export const getStorageCheckupURL = (name: string, namespace: string, cluster?: string) => {
8+
return cluster
9+
? `/k8s/cluster/${cluster}/ns/${namespace}/checkups/storage/${name}`
10+
: `/k8s/ns/${namespace}/checkups/storage/${name}`;
11+
};

src/views/checkups/network/hooks/useCheckupsNetworkData.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,27 @@ import {
77
} from '@kubevirt-ui/kubevirt-api/console';
88
import { IoK8sApiBatchV1Job, IoK8sApiCoreV1ConfigMap } from '@kubevirt-ui/kubevirt-api/kubernetes';
99
import { ALL_NAMESPACES_SESSION_KEY } from '@kubevirt-utils/hooks/constants';
10-
import { useActiveNamespace, useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
10+
import useKubevirtWatchResource from '@kubevirt-utils/hooks/useKubevirtWatchResource/useKubevirtWatchResource';
11+
import useListMulticlusterFilters from '@kubevirt-utils/hooks/useListMulticlusterFilters';
12+
import { useActiveNamespace } from '@openshift-console/dynamic-plugin-sdk';
1113

1214
import { KUBEVIRT_VM_LATENCY_LABEL } from '../../utils/utils';
1315
import { KUBEVIRT_VM_LATENCY_LABEL_VALUE } from '../utils/utils';
1416

1517
const useCheckupsNetworkData = () => {
1618
const [namespace] = useActiveNamespace();
19+
const multiclusterFilters = useListMulticlusterFilters();
20+
21+
const checkupsMulticlusterFilters = useMemo(
22+
() => [
23+
{
24+
property: 'label',
25+
values: [`${KUBEVIRT_VM_LATENCY_LABEL}=${KUBEVIRT_VM_LATENCY_LABEL_VALUE}`],
26+
},
27+
...multiclusterFilters,
28+
],
29+
[multiclusterFilters],
30+
);
1731

1832
const configMapWatchConfig = useMemo(
1933
() => ({
@@ -43,11 +57,16 @@ const useCheckupsNetworkData = () => {
4357
[namespace],
4458
);
4559

46-
const [configMaps, configMapsLoaded, loadErrorConfigMaps] =
47-
useK8sWatchResource<IoK8sApiCoreV1ConfigMap[]>(configMapWatchConfig);
60+
const [configMaps, configMapsLoaded, loadErrorConfigMaps] = useKubevirtWatchResource<
61+
IoK8sApiCoreV1ConfigMap[]
62+
>(configMapWatchConfig, null, checkupsMulticlusterFilters);
63+
64+
const [jobs, jobsLoaded, loadErrorJobs] = useKubevirtWatchResource<IoK8sApiBatchV1Job[]>(
65+
jobWatchConfig,
66+
null,
67+
checkupsMulticlusterFilters,
68+
);
4869

49-
const [jobs, jobsLoaded, loadErrorJobs] =
50-
useK8sWatchResource<IoK8sApiBatchV1Job[]>(jobWatchConfig);
5170
return {
5271
configMaps,
5372
error: loadErrorConfigMaps || loadErrorJobs,

src/views/checkups/network/hooks/useCheckupsNetworkFilters.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
import { useMemo } from 'react';
2+
13
import { IoK8sApiCoreV1ConfigMap } from '@kubevirt-ui/kubevirt-api/kubernetes';
4+
import { useClusterFilter } from '@kubevirt-utils/hooks/useClusterFilter';
5+
import { useProjectFilter } from '@kubevirt-utils/hooks/useProjectFilter';
6+
import useIsACMPage from '@multicluster/useIsACMPage';
27
import {
38
OnFilterChange,
49
RowFilter,
@@ -14,15 +19,29 @@ type UseCheckupsNetworkFilters = (
1419
dataFilter: IoK8sApiCoreV1ConfigMap[],
1520
onFilterChange: OnFilterChange,
1621
filters: RowFilter<IoK8sApiCoreV1ConfigMap>[],
22+
filtersWithSelect: RowFilter<IoK8sApiCoreV1ConfigMap>[],
1723
];
1824

1925
const useCheckupsNetworkFilters: UseCheckupsNetworkFilters = (data) => {
26+
const isACMPage = useIsACMPage();
27+
const clusterFilter = useClusterFilter();
28+
const projectFilter = useProjectFilter();
29+
30+
const filtersWithSelect = useMemo(
31+
() => (isACMPage ? [clusterFilter, projectFilter] : []),
32+
[clusterFilter, projectFilter, isACMPage],
33+
);
34+
35+
const allFilters = useMemo(() => {
36+
return [...filtersWithSelect, ...filters];
37+
}, [filtersWithSelect]);
38+
2039
const [unfilterData, dataFilters, onFilterChange] = useListPageFilter<
2140
IoK8sApiCoreV1ConfigMap,
2241
IoK8sApiCoreV1ConfigMap
23-
>(data, filters);
42+
>(data, allFilters);
2443

25-
return [unfilterData, dataFilters, onFilterChange, filters];
44+
return [unfilterData, dataFilters, onFilterChange, filters, filtersWithSelect];
2645
};
2746

2847
export default useCheckupsNetworkFilters;

src/views/checkups/network/hooks/useCheckupsNetworkListColumns.ts

Lines changed: 97 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import { useMemo } from 'react';
2+
13
import { IoK8sApiCoreV1ConfigMap } from '@kubevirt-ui/kubevirt-api/kubernetes';
24
import { ALL_NAMESPACES_SESSION_KEY } from '@kubevirt-utils/hooks/constants';
35
import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
46
import useKubevirtUserSettingsTableColumns from '@kubevirt-utils/hooks/useKubevirtUserSettings/useKubevirtUserSettingsTableColumns';
7+
import useIsACMPage from '@multicluster/useIsACMPage';
58
import { TableColumn, useActiveNamespace } from '@openshift-console/dynamic-plugin-sdk';
69
import { sortable } from '@patternfly/react-table';
710

@@ -28,87 +31,101 @@ const useCheckupsNetworkCheckupsListColumns = (): [
2831
] => {
2932
const [namespace] = useActiveNamespace();
3033
const { t } = useKubevirtTranslation();
34+
const isACMPage = useIsACMPage();
3135

32-
const columns: TableColumn<IoK8sApiCoreV1ConfigMap>[] = [
33-
{
34-
id: 'name',
35-
sort: 'metadata.name',
36-
title: t('Name'),
37-
transforms: [sortable],
38-
},
39-
...(namespace === ALL_NAMESPACES_SESSION_KEY
40-
? [
41-
{
42-
id: 'namespace',
43-
sort: 'metadata.namespace',
44-
title: t('Namespace'),
45-
transforms: [sortable],
46-
},
47-
]
48-
: []),
49-
{
50-
id: 'nad',
51-
sort: (data, sortDirection) => columnsSorting(data, sortDirection, CONFIG_PARAM_NAD_NAME),
52-
title: t('NetworkAttachmentDefinition'),
53-
transforms: [sortable],
54-
},
55-
{
56-
id: 'status',
57-
sort: (data, sortDirection) => columnsSorting(data, sortDirection, STATUS_SUCCEEDED),
58-
title: t('Status'),
59-
transforms: [sortable],
60-
},
61-
{
62-
id: 'latency',
63-
sort: (data, sortDirection) => columnsSorting(data, sortDirection, STATUS_MAX_LATENCY_NANO),
64-
title: t('Latency'),
65-
transforms: [sortable],
66-
},
67-
{
68-
additional: true,
69-
id: 'duration',
70-
sort: (data, sortDirection) =>
71-
columnsSorting(data, sortDirection, CONFIG_PARAM_SAMPLE_DURATION),
72-
title: t('Duration'),
73-
transforms: [sortable],
74-
},
75-
{
76-
additional: true,
77-
id: 'source-node',
78-
sort: (data, sortDirection) =>
79-
columnsSorting(data, sortDirection, STATUS_SOURCE_NODE, CONFIG_PARAM_SOURCE_NODE),
80-
title: t('Source node'),
81-
transforms: [sortable],
82-
},
83-
{
84-
additional: true,
85-
id: 'target-node',
86-
sort: (data, sortDirection) =>
87-
columnsSorting(data, sortDirection, STATUS_TARGET_NODE, CONFIG_PARAM_TARGET_NODE),
88-
title: t('Target node'),
89-
transforms: [sortable],
90-
},
91-
{
92-
additional: true,
93-
id: 'start-time',
94-
sort: (data, sortDirection) => columnsSorting(data, sortDirection, STATUS_START_TIME_STAMP),
95-
title: t('Start time'),
96-
transforms: [sortable],
97-
},
98-
{
99-
additional: true,
100-
id: 'complete-time',
101-
sort: (data, sortDirection) =>
102-
columnsSorting(data, sortDirection, STATUS_COMPLETION_TIME_STAMP),
103-
title: t('Complete time'),
104-
transforms: [sortable],
105-
},
106-
{
107-
id: '',
108-
props: { className: 'pf-v6-c-table__action' },
109-
title: '',
110-
},
111-
];
36+
const columns: TableColumn<IoK8sApiCoreV1ConfigMap>[] = useMemo(
37+
() => [
38+
{
39+
id: 'name',
40+
sort: 'metadata.name',
41+
title: t('Name'),
42+
transforms: [sortable],
43+
},
44+
...(isACMPage
45+
? [
46+
{
47+
id: 'cluster',
48+
sort: 'cluster',
49+
title: t('Cluster'),
50+
transforms: [sortable],
51+
},
52+
]
53+
: []),
54+
...(namespace === ALL_NAMESPACES_SESSION_KEY
55+
? [
56+
{
57+
id: 'namespace',
58+
sort: 'metadata.namespace',
59+
title: t('Namespace'),
60+
transforms: [sortable],
61+
},
62+
]
63+
: []),
64+
{
65+
id: 'nad',
66+
sort: (data, sortDirection) => columnsSorting(data, sortDirection, CONFIG_PARAM_NAD_NAME),
67+
title: t('NetworkAttachmentDefinition'),
68+
transforms: [sortable],
69+
},
70+
{
71+
id: 'status',
72+
sort: (data, sortDirection) => columnsSorting(data, sortDirection, STATUS_SUCCEEDED),
73+
title: t('Status'),
74+
transforms: [sortable],
75+
},
76+
{
77+
id: 'latency',
78+
sort: (data, sortDirection) => columnsSorting(data, sortDirection, STATUS_MAX_LATENCY_NANO),
79+
title: t('Latency'),
80+
transforms: [sortable],
81+
},
82+
{
83+
additional: true,
84+
id: 'duration',
85+
sort: (data, sortDirection) =>
86+
columnsSorting(data, sortDirection, CONFIG_PARAM_SAMPLE_DURATION),
87+
title: t('Duration'),
88+
transforms: [sortable],
89+
},
90+
{
91+
additional: true,
92+
id: 'source-node',
93+
sort: (data, sortDirection) =>
94+
columnsSorting(data, sortDirection, STATUS_SOURCE_NODE, CONFIG_PARAM_SOURCE_NODE),
95+
title: t('Source node'),
96+
transforms: [sortable],
97+
},
98+
{
99+
additional: true,
100+
id: 'target-node',
101+
sort: (data, sortDirection) =>
102+
columnsSorting(data, sortDirection, STATUS_TARGET_NODE, CONFIG_PARAM_TARGET_NODE),
103+
title: t('Target node'),
104+
transforms: [sortable],
105+
},
106+
{
107+
additional: true,
108+
id: 'start-time',
109+
sort: (data, sortDirection) => columnsSorting(data, sortDirection, STATUS_START_TIME_STAMP),
110+
title: t('Start time'),
111+
transforms: [sortable],
112+
},
113+
{
114+
additional: true,
115+
id: 'complete-time',
116+
sort: (data, sortDirection) =>
117+
columnsSorting(data, sortDirection, STATUS_COMPLETION_TIME_STAMP),
118+
title: t('Complete time'),
119+
transforms: [sortable],
120+
},
121+
{
122+
id: '',
123+
props: { className: 'pf-v6-c-table__action' },
124+
title: '',
125+
},
126+
],
127+
[t, isACMPage, namespace],
128+
);
112129

113130
const [activeColumns, , loadedColumns] =
114131
useKubevirtUserSettingsTableColumns<IoK8sApiCoreV1ConfigMap>({

src/views/checkups/network/hooks/useCheckupsNetworkPermissions.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import {
1111
IoK8sApiRbacV1ClusterRole,
1212
IoK8sApiRbacV1ClusterRoleBinding,
1313
} from '@kubevirt-ui/kubevirt-api/kubernetes';
14-
import { useActiveNamespace, useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
14+
import useKubevirtWatchResource from '@kubevirt-utils/hooks/useKubevirtWatchResource/useKubevirtWatchResource';
15+
import useListClusters from '@kubevirt-utils/hooks/useListClusters';
16+
import { useActiveNamespace } from '@openshift-console/dynamic-plugin-sdk';
17+
import { useHubClusterName } from '@stolostron/multicluster-sdk';
1518

1619
import { findObjectByName } from '../../utils/utils';
1720
import {
@@ -22,23 +25,29 @@ import {
2225

2326
const useCheckupsNetworkPermissions = (): { isPermitted: boolean; loading: boolean } => {
2427
const [namespace] = useActiveNamespace();
28+
const selectedClusters = useListClusters();
29+
const [hubClusterName] = useHubClusterName();
30+
const cluster = selectedClusters?.[0] || hubClusterName;
2531

26-
const [serviceAccounts, loadingServiceAccounts] = useK8sWatchResource<
32+
const [serviceAccounts, loadingServiceAccounts] = useKubevirtWatchResource<
2733
IoK8sApiCoreV1ServiceAccount[]
2834
>({
35+
cluster,
2936
groupVersionKind: modelToGroupVersionKind(ServiceAccountModel),
3037
isList: true,
3138
namespace,
3239
});
3340

34-
const [roles, loadingRoles] = useK8sWatchResource<IoK8sApiRbacV1ClusterRole[]>({
41+
const [roles, loadingRoles] = useKubevirtWatchResource<IoK8sApiRbacV1ClusterRole[]>({
42+
cluster,
3543
groupVersionKind: modelToGroupVersionKind(ClusterRoleModel),
3644
isList: true,
3745
});
3846

39-
const [roleBinding, loadingRolesBinding] = useK8sWatchResource<
47+
const [roleBinding, loadingRolesBinding] = useKubevirtWatchResource<
4048
IoK8sApiRbacV1ClusterRoleBinding[]
4149
>({
50+
cluster,
4251
groupVersionKind: modelToGroupVersionKind(ClusterRoleBindingModel),
4352
isList: true,
4453
});

0 commit comments

Comments
 (0)