Skip to content

Commit

Permalink
Volsync in DR dashboard reports operator degraded
Browse files Browse the repository at this point in the history
Signed-off-by: Gowtham Shanmugasundaram <[email protected]>
  • Loading branch information
GowthamShanmugam committed Jan 13, 2025
1 parent eef8b28 commit 29bd0c7
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import {
} from '../../../../utils';
import { getLastSyncPerClusterQuery } from '../../queries';
import {
CSVStatusesContext,
OperatorStatusesContext,
DRResourcesContext,
} from '../dr-dashboard-context';
import {
Expand Down Expand Up @@ -171,6 +171,7 @@ const ClusterWiseCard: React.FC<ClusterWiseCardProps> = ({
protectedPVCData,
csvData,
clusterResources,
podData,
}) => {
const [mirrorPeers] = useK8sWatchResource<MirrorPeerKind[]>({
kind: referenceForModel(MirrorPeerModel),
Expand All @@ -188,6 +189,7 @@ const ClusterWiseCard: React.FC<ClusterWiseCardProps> = ({
clusterResources={clusterResources}
csvData={csvData}
clusterName={clusterName}
podData={podData}
/>
</GridItem>
<GridItem lg={9} rowSpan={8} sm={12}>
Expand Down Expand Up @@ -291,13 +293,18 @@ export const ClusterAppCard: React.FC = () => {
basePath: usePrometheusBasePath(),
});

const { csvData, csvError, csvLoading } =
React.useContext(CSVStatusesContext);
const {
csvStatus: { data: csvData, error: csvError, loading: csvLoading },
podStatus: { data: podData, error: podError, loading: podLoading },
} = React.useContext(OperatorStatusesContext);

const { drClusterAppsMap, loaded, loadError } =
React.useContext(DRResourcesContext);

const allLoaded = loaded && !csvLoading && !lastSyncTimeLoading && mcvsLoaded;
const anyError = lastSyncTimeError || csvError || loadError || mcvsLoadError;
const allLoaded =
loaded && !csvLoading && !lastSyncTimeLoading && mcvsLoaded && !podLoading;
const anyError =
lastSyncTimeError || csvError || loadError || mcvsLoadError || podError;

const selectedApplication: ProtectedAppsMap = React.useMemo(() => {
const { name, namespace } = application || {};
Expand Down Expand Up @@ -359,6 +366,7 @@ export const ClusterAppCard: React.FC = () => {
lastSyncTimeData={lastSyncTimeData}
protectedPVCData={protectedPVCData}
csvData={csvData}
podData={podData}
clusterResources={drClusterAppsMap}
/>
) : (
Expand Down Expand Up @@ -387,6 +395,7 @@ type ClusterWiseCardProps = {
lastSyncTimeData: PrometheusResponse;
protectedPVCData: ProtectedPVCData[];
csvData: PrometheusResponse;
podData: PrometheusResponse;
clusterResources: DRClusterAppsMap;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const checkKubeObjBackupHealth = (
};

const OperatorsHealthPopUp: React.FC<OperatorsHealthPopUpProps> = ({
clusterCSVStatus,
clusterOperatorStatus,
}) => {
const { t } = useCustomTranslation();

Expand All @@ -110,13 +110,13 @@ const OperatorsHealthPopUp: React.FC<OperatorsHealthPopUpProps> = ({
<Status
icon={
healthStateMapping[
clusterCSVStatus?.[ODR_CLUSTER_OPERATOR] !== '1'
clusterOperatorStatus?.[ODR_CLUSTER_OPERATOR] !== '1'
? HealthState.ERROR
: HealthState.OK
].icon
}
value={
clusterCSVStatus?.[ODR_CLUSTER_OPERATOR] !== '1'
clusterOperatorStatus?.[ODR_CLUSTER_OPERATOR] !== '1'
? t('Degraded')
: t('Healthy')
}
Expand All @@ -126,13 +126,13 @@ const OperatorsHealthPopUp: React.FC<OperatorsHealthPopUpProps> = ({
<Status
icon={
healthStateMapping[
clusterCSVStatus?.[VOL_SYNC] !== '1'
clusterOperatorStatus?.[VOL_SYNC] !== '1'
? HealthState.ERROR
: HealthState.OK
].icon
}
value={
clusterCSVStatus?.[VOL_SYNC] !== '1'
clusterOperatorStatus?.[VOL_SYNC] !== '1'
? t('Degraded')
: t('Healthy')
}
Expand All @@ -149,22 +149,26 @@ export const HealthSection: React.FC<HealthSectionProps> = ({
clusterResources,
csvData,
clusterName,
podData,
}) => {
const { t } = useCustomTranslation();

const clusterCSVStatus = React.useMemo(
() =>
csvData?.data?.result?.reduce((acc, item: PrometheusResult) => {
if (item?.metric.cluster === clusterName) {
item?.metric.name.startsWith(ODR_CLUSTER_OPERATOR) &&
(acc[ODR_CLUSTER_OPERATOR] = item?.value[1]);
item?.metric.name.startsWith(VOL_SYNC) &&
(acc[VOL_SYNC] = item?.value[1]);
}
return acc;
}, {} as ClusterCSVStatus) || ({} as ClusterCSVStatus),
[csvData, clusterName]
);
const clusterOperatorStatus = React.useMemo(() => {
const operatorStatus = {};
csvData?.data?.result?.forEach((item: PrometheusResult) => {
if (item?.metric.cluster === clusterName) {
item?.metric.name.startsWith(ODR_CLUSTER_OPERATOR) &&
(operatorStatus[ODR_CLUSTER_OPERATOR] = item?.value[1]);
}
});
podData?.data?.result?.forEach((item: PrometheusResult) => {
if (item?.metric.cluster === clusterName) {
item?.metric.pod.startsWith(VOL_SYNC) &&
(operatorStatus[VOL_SYNC] = item?.value[1]);
}
});
return operatorStatus as ClusterOperatorStatus;
}, [csvData, clusterName, podData]);

return (
<div className="mco-cluster-app__cluster-health-section">
Expand All @@ -184,13 +188,13 @@ export const HealthSection: React.FC<HealthSectionProps> = ({
title={t('Operators health')}
// for csv status metrics, '1' means healthy
state={
clusterCSVStatus?.[ODR_CLUSTER_OPERATOR] !== '1' ||
clusterCSVStatus?.[VOL_SYNC] !== '1'
clusterOperatorStatus?.[ODR_CLUSTER_OPERATOR] !== '1' ||
clusterOperatorStatus?.[VOL_SYNC] !== '1'
? HealthState.ERROR
: HealthState.OK
}
>
<OperatorsHealthPopUp clusterCSVStatus={clusterCSVStatus} />
<OperatorsHealthPopUp clusterOperatorStatus={clusterOperatorStatus} />
</HealthItem>
</div>
);
Expand Down Expand Up @@ -425,19 +429,20 @@ export const UtilizationCard: React.FC<UtilizationCardProps> = ({
);
};

type ClusterCSVStatus = {
type ClusterOperatorStatus = {
[ODR_CLUSTER_OPERATOR]: string;
[VOL_SYNC]: string;
};

type OperatorsHealthPopUpProps = {
clusterCSVStatus: ClusterCSVStatus;
clusterOperatorStatus: ClusterOperatorStatus;
};

type HealthSectionProps = {
clusterResources: DRClusterAppsMap;
csvData: PrometheusResponse;
clusterName: string;
podData: PrometheusResponse;
};

type PeerConnectionSectionProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,25 @@ import * as React from 'react';
import { DRClusterAppsMap } from '@odf/mco/types';
import { PrometheusResponse } from '@openshift-console/dynamic-plugin-sdk';

export const CSVStatusesContext = React.createContext<CSVStatusesContextType>(
{} as CSVStatusesContextType
);
export const OperatorStatusesContext =
React.createContext<OperatorStatusesContextType>(
{} as OperatorStatusesContextType
);

export const DRResourcesContext = React.createContext<DRResourcesContextType>(
{} as DRResourcesContextType
);

type CSVStatusesContextType = {
csvData: PrometheusResponse;
csvError: any;
csvLoading: boolean;
type StatusesContextType = {
data: PrometheusResponse;
error: any;
loading: boolean;
};

type OperatorStatusesContextType = {
csvStatus: StatusesContextType;
// Alternate way for non CSV operator status monitoring
podStatus: StatusesContextType;
};

type DRResourcesContextType = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import { getManagedClusterResourceObj } from '../../../hooks';
import { StorageDashboard, STATUS_QUERIES } from '../queries';
import { AlertsCard } from './alert-card/alert-card';
import { ClusterAppCard } from './cluster-app-card/cluster-app-card';
import { CSVStatusesContext, DRResourcesContext } from './dr-dashboard-context';
import {
OperatorStatusesContext,
DRResourcesContext,
} from './dr-dashboard-context';
import { GettingStartedCard } from './getting-started-card';
import { useApplicationSetParser } from './parsers/applicationset-parser';
import { useDiscoveredParser } from './parsers/discovered-parser';
Expand Down Expand Up @@ -79,6 +82,13 @@ const MonitoringDashboard: React.FC = () => {
cluster: HUB_CLUSTER_NAME,
});

const [podData, podError, podLoading] = useCustomPrometheusPoll({
endpoint: 'api/v1/query' as any,
query: STATUS_QUERIES[StorageDashboard.POD_STATUS_ALL_WHITELISTED],
basePath: ACM_ENDPOINT,
cluster: HUB_CLUSTER_NAME,
});

const [managedClusters, managedClusterLoaded, managedClusterLoadError] =
useK8sWatchResource<ACMManagedClusterKind[]>(
getManagedClusterResourceObj()
Expand Down Expand Up @@ -124,18 +134,21 @@ const MonitoringDashboard: React.FC = () => {
};
}, [aggregatedAppsMap, loaded, loadError]);

const csvContextData = React.useMemo(() => {
return { csvData, csvError, csvLoading };
}, [csvData, csvError, csvLoading]);
const operatorStatusContextData = React.useMemo(() => {
return {
csvStatus: { data: csvData, error: csvError, loading: csvLoading },
podStatus: { data: podData, error: podError, loading: podLoading },
};
}, [csvData, csvError, csvLoading, podData, podError, podLoading]);

// ToDo(Sanjal): combime multiple Context together to make it scalable
// refer: https://javascript.plainenglish.io/how-to-combine-context-providers-for-cleaner-react-code-9ed24f20225e
return (
<CSVStatusesContext.Provider value={csvContextData}>
<OperatorStatusesContext.Provider value={operatorStatusContextData}>
<DRResourcesContext.Provider value={dRResourcesContext}>
<UpperSection />
</DRResourcesContext.Provider>
</CSVStatusesContext.Provider>
</OperatorStatusesContext.Provider>
);
};

Expand Down
Loading

0 comments on commit 29bd0c7

Please sign in to comment.