Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RHSTOR-5133] Adds Provider Mode support #1115

Merged
merged 1 commit into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions locales/en/plugin__odf-console.json
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,9 @@
"Storage Systems": "Storage Systems",
"External object provider used capacity": "External object provider used capacity",
"Performance Card": "Performance Card",
"Storage Clients": "Storage Clients",
"0 connected": "0 connected",
"{{connected}} / {{total}} connected": "{{connected}} / {{total}} connected",
"System raw capacity": "System raw capacity",
"No data available": "No data available",
"Provider details": "Provider details",
Expand All @@ -942,6 +945,17 @@
"NamespaceStore details": "NamespaceStore details",
"Target Blob Container": "Target Blob Container",
"Num Volumes": "Num Volumes",
"Cluster ID": "Cluster ID",
"Openshift version": "Openshift version",
"Data Foundation version": "Data Foundation version",
"Last heartbeat": "Last heartbeat",
"ago": "ago",
"Client version is out of date": "Client version is out of date",
"Due to the mismatch in the client and provider version this provider cluster cannot be upgraded.": "Due to the mismatch in the client and provider version this provider cluster cannot be upgraded.",
"Storage clients": "Storage clients",
"Generate client onboarding token": "Generate client onboarding token",
"Data Foundation version sync": "Data Foundation version sync",
"Client onboarding token": "Client onboarding token",
"Raw Capacity": "Raw Capacity",
"Add Capacity": "Add Capacity",
"External": "External",
Expand Down
16 changes: 13 additions & 3 deletions packages/ocs/dashboards/odf-system-dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { referenceForModel } from '@odf/shared/utils';
import Tabs, { TabPage } from '@odf/shared/utils/Tabs';
import { useFlag } from '@openshift-console/dynamic-plugin-sdk';
import { useParams } from 'react-router-dom-v5-compat';
import { CEPH_FLAG, OCS_INDEPENDENT_FLAG } from '../../odf/features';
import {
CEPH_FLAG,
OCS_INDEPENDENT_FLAG,
PROVIDER_MODE,
} from '../../odf/features';
import { BlockPoolListPage } from '../block-pool/BlockPoolListPage';
import { CephBlockPoolModel } from '../models';
import OCSSystemDashboard from './ocs-system-dashboard';
Expand Down Expand Up @@ -36,10 +40,16 @@ const ODFSystemDashboard: React.FC<{}> = ({}) => {
]);
const isCephAvailable = useFlag(CEPH_FLAG);
const isExternal = useFlag(OCS_INDEPENDENT_FLAG);
const isProviderMode = useFlag(PROVIDER_MODE);

React.useEffect(() => {
const isBlockPoolAdded = pages.find((page) => page.href === blockPoolHref);
if (isCephAvailable && !isBlockPoolAdded && !isExternal) {
if (
isCephAvailable &&
!isBlockPoolAdded &&
!isExternal &&
!isProviderMode
) {
setPages((p) => [
...p,
{
Expand All @@ -52,7 +62,7 @@ const ODFSystemDashboard: React.FC<{}> = ({}) => {
if (isBlockPoolAdded && isExternal) {
setPages((p) => p.filter((page) => page.href !== blockPoolHref));
}
}, [isExternal, isCephAvailable, pages, setPages, t]);
}, [isExternal, isCephAvailable, isProviderMode, pages, setPages, t]);

const arePagesLoaded = pages.length > 0;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.odf-storageSystemPopup__item--margin {
.odf-status-card__popup--margin {
// Overriding PF default margin for FlexItem
margin-bottom: 0 !important;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import Status, { StatusPopupSection } from '@odf/shared/popup/status-popup';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { HealthState } from '@openshift-console/dynamic-plugin-sdk';
import { Link } from 'react-router-dom-v5-compat';
import { Flex, FlexItem } from '@patternfly/react-core';
Expand All @@ -9,17 +8,19 @@ import {
ExclamationCircleIcon,
ExclamationTriangleIcon,
} from '@patternfly/react-icons';
import './storage-system-popup.scss';
import './status-card-popover.scss';

type SystemHealthMap = {
systemName: string;
export type ResourceHealthMap = {
itemName: string;
healthState: HealthState;
link: string;
link?: string;
extraTexts?: string[];
};

type StorageSystemPopopProps = {
systemHealthMap: SystemHealthMap[];
type StatusCardPopoverProps = {
resourceHealthMap: ResourceHealthMap[];
firstColumnName: string;
secondColumnName: string;
};

const healthStateToIcon = {
Expand All @@ -34,27 +35,32 @@ const healthStateToIcon = {
),
};

const StorageSystemPopup: React.FC<StorageSystemPopopProps> = ({
systemHealthMap,
const StatusCardPopover: React.FC<StatusCardPopoverProps> = ({
resourceHealthMap,
firstColumnName,
secondColumnName,
}) => {
const { t } = useCustomTranslation();
return (
<StatusPopupSection
firstColumn={t('Storage System')}
secondColumn={t('Health')}
firstColumn={firstColumnName}
secondColumn={secondColumnName}
>
{systemHealthMap.map((system) => (
{resourceHealthMap.map((resource) => (
<Status
key={system.systemName}
icon={healthStateToIcon[system.healthState]}
key={resource.itemName}
icon={healthStateToIcon[resource.healthState]}
>
<Flex direction={{ default: 'column' }}>
<FlexItem className="odf-storageSystemPopup__item--margin">
<Link to={system.link}>{system.systemName}</Link>
<FlexItem className="odf-status-card__popup--margin">
{resource.link ? (
<Link to={resource.link}>{resource.itemName}</Link>
) : (
<>{resource.itemName}</>
)}
</FlexItem>
{!!system.extraTexts && (
{!!resource.extraTexts && (
<FlexItem>
{system.extraTexts.map((extraText, i) => (
{resource.extraTexts.map((extraText, i) => (
<div className="text-muted" key={i}>
{extraText}
</div>
Expand All @@ -68,4 +74,4 @@ const StorageSystemPopup: React.FC<StorageSystemPopopProps> = ({
);
};

export default StorageSystemPopup;
export default StatusCardPopover;
52 changes: 48 additions & 4 deletions packages/odf/components/odf-dashboard/status-card/status-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react';
import { useSafeK8sWatchResource } from '@odf/core/hooks';
import { K8sResourceObj } from '@odf/core/types';
import { useGetOCSHealth } from '@odf/ocs/hooks';
import { StorageConsumerKind } from '@odf/shared';
import { ODF_OPERATOR } from '@odf/shared/constants';
import HealthItem from '@odf/shared/dashboards/status-card/HealthItem';
import { healthStateMap } from '@odf/shared/dashboards/status-card/states';
Expand All @@ -21,8 +22,13 @@ import {
referenceForGroupVersionKind,
getOperatorHealthState,
} from '@odf/shared/utils';
import { HealthState } from '@openshift-console/dynamic-plugin-sdk';
import {
HealthState,
useFlag,
useK8sWatchResource,
} from '@openshift-console/dynamic-plugin-sdk';
import { HealthBody } from '@openshift-console/dynamic-plugin-sdk-internal';
import { useHistory } from 'react-router';
import {
Gallery,
GalleryItem,
Expand All @@ -32,9 +38,12 @@ import {
CardHeader,
CardTitle,
} from '@patternfly/react-core';
import { PROVIDER_MODE } from '../../../features';
import { StorageConsumerModel } from '../../../models';
import { getVendorDashboardLinkFromMetrics } from '../../utils';
import { StorageDashboard, STATUS_QUERIES } from '../queries';
import StorageSystemPopup from './storage-system-popup';
import StatusCardPopover from './status-card-popover';
import { getAggregateClientHealthState, getClientText } from './utils';
import './status-card.scss';

const operatorResource: K8sResourceObj = (ns) => ({
Expand Down Expand Up @@ -129,6 +138,23 @@ export const StatusCard: React.FC = () => {
csvLoadError
);

const isProviderMode = useFlag(PROVIDER_MODE);

const [clients, clientsLoaded, clientsLoadError] = useK8sWatchResource<
StorageConsumerKind[]
>({
kind: referenceForModel(StorageConsumerModel),
isList: true,
});

const clientAggregateHealth = getAggregateClientHealthState(clients);
SanjalKatiyar marked this conversation as resolved.
Show resolved Hide resolved

const history = useHistory();

const redirectToListPage = React.useCallback(() => {
history.push('/odf/storage-clients');
}, [history]);

return (
<Card className="odfDashboard-card--height">
<CardHeader>
Expand All @@ -149,7 +175,11 @@ export const StatusCard: React.FC = () => {
title={pluralize(healthySystems.length, 'Storage System')}
state={HealthState.OK}
>
<StorageSystemPopup systemHealthMap={healthySystems} />
<StatusCardPopover
resourceHealthMap={healthySystems}
firstColumnName={t('Storage System')}
secondColumnName={t('Health')}
/>
</HealthItem>
</GalleryItem>
)}
Expand All @@ -160,10 +190,24 @@ export const StatusCard: React.FC = () => {
state={HealthState.ERROR}
maxWidth="35rem"
>
<StorageSystemPopup systemHealthMap={unHealthySystems} />
<StatusCardPopover
resourceHealthMap={unHealthySystems}
firstColumnName={t('Storage System')}
secondColumnName={t('Health')}
/>
</HealthItem>
</GalleryItem>
)}
{isProviderMode && clientsLoaded && !clientsLoadError && (
<GalleryItem>
<HealthItem
title={t('Storage Clients')}
state={clientAggregateHealth}
onClick={redirectToListPage}
details={getClientText(clients, t)}
/>
</GalleryItem>
)}
</Gallery>
</HealthBody>
</CardBody>
Expand Down
48 changes: 48 additions & 0 deletions packages/odf/components/odf-dashboard/status-card/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { StorageConsumerKind, StorageConsumerState } from '@odf/shared';
import { getTimeDifferenceInSeconds } from '@odf/shared/details-page/datetime';
import { HealthState } from '@openshift-console/dynamic-plugin-sdk';
import { TFunction } from 'i18next';

const getHealthAndTotalClientCounts = (clients: StorageConsumerKind[]) => {
const connectedClients = clients.filter(
(client) => client.status.state === StorageConsumerState.Ready
);

const healthyClients = connectedClients.filter(
(client) => getTimeDifferenceInSeconds(client.status.lastHeartbeat) < 120
);
const healthyClientsCount = healthyClients.length;
const totalClientsCount = clients.length;

return [healthyClientsCount, totalClientsCount];
};

export const getAggregateClientHealthState = (
clients: StorageConsumerKind[] = []
) => {
const [healthyClientsCount, totalClientsCount] =
getHealthAndTotalClientCounts(clients);
if (totalClientsCount === healthyClientsCount && totalClientsCount > 0) {
return HealthState.OK;
}
if (totalClientsCount > healthyClientsCount) {
return HealthState.ERROR;
}
if (totalClientsCount === 0) {
return HealthState.NOT_AVAILABLE;
}
return HealthState.UNKNOWN;
};

export const getClientText = (clients: StorageConsumerKind[], t: TFunction) => {
const [healthyClientsCount, totalClientsCount] =
getHealthAndTotalClientCounts(clients);
if (totalClientsCount === 0) {
return t('0 connected');
} else {
return t('{{connected}} / {{total}} connected', {
connected: healthyClientsCount,
total: totalClientsCount,
});
}
};
Loading