@@ -101,9 +107,11 @@ export const ObjectServiceDetailsCard: React.FC<{}> = () => {
}
error={systemLoadError || dashboardLinkLoadError}
>
-
- {t('Multicloud Object Gateway')}
-
+ {hasMCG && (
+
+ {t('Multicloud Object Gateway')}
+
+ )}
{hasRGW && (
{
return providersList;
};
-const ResourceProviders: React.FC<{}> = () => {
- const { t } = useCustomTranslation();
-
+const ResourceProvidersBody_: React.FC = () => {
const [providersTypesQueryResult, providersTypesQueryResultError] =
useCustomPrometheusPoll({
query: RESOURCE_PROVIDERS_QUERY.PROVIDERS_TYPES,
@@ -79,6 +81,35 @@ const ResourceProviders: React.FC<{}> = () => {
const providerTypes = filterProviders(allProviders);
+ return (
+
+ {providerTypes.map((provider) => (
+
+ ))}
+
+ );
+};
+
+const ResourceProviders: React.FC<{}> = () => {
+ const { t } = useCustomTranslation();
+
+ const { namespace: clusterNs } = useParams();
+ const { systemFlags } = useODFSystemFlagsSelector();
+ const hasMCG = systemFlags[clusterNs]?.isNoobaaAvailable;
+
return (
@@ -90,24 +121,7 @@ const ResourceProviders: React.FC<{}> = () => {
-
- {providerTypes.map((provider) => (
-
- ))}
-
+ {hasMCG ? : }
);
diff --git a/packages/ocs/dashboards/object-service/status-card/status-card.tsx b/packages/ocs/dashboards/object-service/status-card/status-card.tsx
index d7bfd94bd..4cdcadfbc 100644
--- a/packages/ocs/dashboards/object-service/status-card/status-card.tsx
+++ b/packages/ocs/dashboards/object-service/status-card/status-card.tsx
@@ -1,9 +1,9 @@
import * as React from 'react';
-import { RGW_FLAG } from '@odf/core/features';
-import { useSafeK8sWatchResource } from '@odf/core/hooks';
import { CephObjectStoreModel } from '@odf/core/models';
import { NooBaaSystemModel } from '@odf/core/models';
+import { useODFSystemFlagsSelector } from '@odf/core/redux';
import { secretResource } from '@odf/core/resources';
+import { getResourceInNs } from '@odf/core/utils';
import {
useCustomPrometheusPoll,
usePrometheusBasePath,
@@ -17,10 +17,7 @@ import {
filterRGWAlerts,
} from '@odf/shared/utils';
import { referenceForModel } from '@odf/shared/utils';
-import {
- useK8sWatchResource,
- useFlag,
-} from '@openshift-console/dynamic-plugin-sdk';
+import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
import {
AlertsBody,
AlertItem,
@@ -28,6 +25,7 @@ import {
} from '@openshift-console/dynamic-plugin-sdk-internal';
import { SubsystemHealth } from '@openshift-console/dynamic-plugin-sdk/lib/extensions/dashboard-types';
import * as _ from 'lodash-es';
+import { useParams } from 'react-router-dom';
import {
Gallery,
GalleryItem,
@@ -42,6 +40,7 @@ import {
dataResiliencyQueryMap,
ObjectServiceDashboardQuery,
} from '../../../queries';
+import { ODFSystemParams } from '../../../types';
import { decodeRGWPrefix } from '../../../utils';
import { ObjectServiceStatus } from './object-service-health';
import { getNooBaaState, getRGWHealthState } from './statuses';
@@ -59,6 +58,8 @@ const cephObjectStoreResource = {
const ObjectStorageAlerts = () => {
const [alerts, loaded, loadError] = useAlerts();
+ // ToDo (epic 4422): Get StorageCluster name and namespace from the Alert object
+ // and filter Alerts based on that for a particular cluster.
const filteredAlerts =
loaded && !loadError && !_.isEmpty(alerts)
? [...filterNooBaaAlerts(alerts), ...filterRGWAlerts(alerts)]
@@ -79,16 +80,24 @@ const ObjectStorageAlerts = () => {
};
const StatusCard: React.FC<{}> = () => {
- const isRGWSupported = useFlag(RGW_FLAG);
+ const { namespace: clusterNs } = useParams();
+ const { systemFlags } = useODFSystemFlagsSelector();
+ const isRGWSupported = systemFlags[clusterNs]?.isRGWAvailable;
+ const isMCGSupported = systemFlags[clusterNs]?.isNoobaaAvailable;
+ const managedByOCS = systemFlags[clusterNs]?.ocsClusterName;
+
const { t } = useCustomTranslation();
const [secretData, secretLoaded, secretLoadError] =
- useSafeK8sWatchResource(secretResource);
- const [noobaa, noobaaLoaded, noobaaLoadError] =
+ useK8sWatchResource(secretResource(clusterNs));
+ const [noobaas, noobaaLoaded, noobaaLoadError] =
useK8sWatchResource(noobaaResource);
- const [rgw, rgwLoaded, rgwLoadError] = useK8sWatchResource(
- cephObjectStoreResource
- );
+ const [rgws, rgwLoaded, rgwLoadError] = useK8sWatchResource<
+ K8sResourceKind[]
+ >(cephObjectStoreResource);
+
+ const noobaa = getResourceInNs(noobaas, clusterNs);
+ const rgw = getResourceInNs(rgws, clusterNs);
const rgwPrefix = React.useMemo(
() =>
@@ -98,10 +107,9 @@ const StatusCard: React.FC<{}> = () => {
[secretData, secretLoaded, secretLoadError, isRGWSupported]
);
- const rgwResiliencyQuery =
- dataResiliencyQueryMap[
- ObjectServiceDashboardQuery.RGW_REBUILD_PROGRESS_QUERY
- ](rgwPrefix);
+ const rgwResiliencyQuery = dataResiliencyQueryMap[
+ ObjectServiceDashboardQuery.RGW_REBUILD_PROGRESS_QUERY
+ ](rgwPrefix, managedByOCS);
const [healthStatusResult, healthStatusError] = useCustomPrometheusPoll({
query: StatusCardQueries.HEALTH_QUERY,
@@ -130,7 +138,7 @@ const StatusCard: React.FC<{}> = () => {
);
const RGWState =
- !rgwLoadError && rgwLoaded ? getRGWHealthState(rgw[0]) : undefined;
+ !rgwLoadError && rgwLoaded ? getRGWHealthState(rgw) : undefined;
const dataResiliencyState: SubsystemHealth = getDataResiliencyState(
[{ response: progressResult, error: progressError }],
@@ -152,14 +160,14 @@ const StatusCard: React.FC<{}> = () => {
diff --git a/packages/ocs/dashboards/object-service/storage-efficiency-card/storage-efficiency-card.tsx b/packages/ocs/dashboards/object-service/storage-efficiency-card/storage-efficiency-card.tsx
index c24982965..5655dd2f1 100644
--- a/packages/ocs/dashboards/object-service/storage-efficiency-card/storage-efficiency-card.tsx
+++ b/packages/ocs/dashboards/object-service/storage-efficiency-card/storage-efficiency-card.tsx
@@ -1,6 +1,8 @@
import * as React from 'react';
+import { useODFSystemFlagsSelector } from '@odf/core/redux';
import { ObjectStorageEfficiencyQueries } from '@odf/ocs/queries';
import { EfficiencyItemBody } from '@odf/shared/dashboards/storage-efficiency/storage-efficiency-card-item';
+import { DataUnavailableError } from '@odf/shared/generic';
import {
useCustomPrometheusPoll,
usePrometheusBasePath,
@@ -8,9 +10,11 @@ import {
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { humanizeBinaryBytes, humanizePercentage } from '@odf/shared/utils';
import { getGaugeValue } from '@odf/shared/utils';
+import { useParams } from 'react-router-dom';
import { Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core';
+import { ODFSystemParams } from '../../../types';
-const StorageEfficiencyCard: React.FC<{}> = () => {
+const EfficiencyItemBody_: React.FC = () => {
const { t } = useCustomTranslation();
const [compressionQueryResult, compressionQueryResultError] =
@@ -84,14 +88,28 @@ const StorageEfficiencyCard: React.FC<{}> = () => {
getStats: savingStats,
};
+ return (
+ <>
+
+
+ >
+ );
+};
+
+const StorageEfficiencyCard: React.FC<{}> = () => {
+ const { t } = useCustomTranslation();
+
+ const { namespace: clusterNs } = useParams();
+ const { systemFlags } = useODFSystemFlagsSelector();
+ const hasMCG = systemFlags[clusterNs]?.isNoobaaAvailable;
+
return (
{t('Storage efficiency')}
-
-
+ {hasMCG ? : }
);
diff --git a/packages/ocs/dashboards/ocs-system-dashboard.tsx b/packages/ocs/dashboards/ocs-system-dashboard.tsx
index 2b9d6ee13..d7c8ec14a 100644
--- a/packages/ocs/dashboards/ocs-system-dashboard.tsx
+++ b/packages/ocs/dashboards/ocs-system-dashboard.tsx
@@ -6,12 +6,7 @@
*/
import * as React from 'react';
-import {
- OCS_INDEPENDENT_FLAG,
- MCG_FLAG,
- CEPH_FLAG,
- OCS_NFS_ENABLED,
-} from '@odf/core/features';
+import { useODFSystemFlagsSelector } from '@odf/core/redux';
import { LoadingBox } from '@odf/shared/generic/status-box';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import Tabs, { TabPage } from '@odf/shared/utils/Tabs';
@@ -19,10 +14,10 @@ import {
Overview,
OverviewGrid,
OverviewGridCard,
- useFlag,
} from '@openshift-console/dynamic-plugin-sdk';
import { TFunction } from 'i18next';
-import { RouteComponentProps } from 'react-router-dom';
+import { RouteComponentProps, useParams } from 'react-router-dom';
+import { ODFSystemParams } from '../types';
import { StatusCard as NFSStatusCard } from './network-file-system/status-card/status-card';
import { ThroughputCard } from './network-file-system/throughput-card/throughput-card';
import { TopClientsCard } from './network-file-system/top-clients-card/top-clients-card';
@@ -185,10 +180,15 @@ const nfsPage = (t: TFunction): TabPage => {
const OCSSystemDashboard: React.FC = () => {
const { t } = useCustomTranslation();
- const isIndependent = useFlag(OCS_INDEPENDENT_FLAG);
- const isObjectServiceAvailable = useFlag(MCG_FLAG);
- const isCephAvailable = useFlag(CEPH_FLAG);
- const isNFSEnabled = useFlag(OCS_NFS_ENABLED);
+ const { namespace: clusterNs } = useParams();
+ const { systemFlags } = useODFSystemFlagsSelector();
+
+ const isIndependent = systemFlags[clusterNs]?.isExternalMode;
+ const isMCGAvailable = systemFlags[clusterNs]?.isNoobaaAvailable;
+ const isRGWAvailable = systemFlags[clusterNs]?.isRGWAvailable;
+ const isObjectServiceAvailable = isMCGAvailable || isRGWAvailable;
+ const isCephAvailable = systemFlags[clusterNs]?.isCephAvailable;
+ const isNFSEnabled = systemFlags[clusterNs]?.isNFSEnabled;
const showInternalDashboard = !isIndependent && isCephAvailable;
const showNFSDashboard = !isIndependent && isNFSEnabled;
diff --git a/packages/ocs/dashboards/odf-system-dashboard.tsx b/packages/ocs/dashboards/odf-system-dashboard.tsx
index c59b27b5c..8736188c0 100644
--- a/packages/ocs/dashboards/odf-system-dashboard.tsx
+++ b/packages/ocs/dashboards/odf-system-dashboard.tsx
@@ -1,15 +1,15 @@
import * as React from 'react';
import NamespaceSafetyBox from '@odf/core/components/utils/safety-box';
+import { useODFSystemFlagsSelector } from '@odf/core/redux';
import PageHeading from '@odf/shared/heading/page-heading';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { referenceForModel } from '@odf/shared/utils';
import Tabs, { TabPage } from '@odf/shared/utils/Tabs';
-import { useFlag } from '@openshift-console/dynamic-plugin-sdk';
import { RouteComponentProps } from 'react-router';
-import { match as Match } from 'react-router-dom';
-import { CEPH_FLAG, OCS_INDEPENDENT_FLAG } from '../../odf/features';
+import { match as Match, useParams } from 'react-router-dom';
import { BlockPoolListPage } from '../block-pool/BlockPoolListPage';
import { CephBlockPoolModel } from '../models';
+import { ODFSystemParams } from '../types';
import OCSSystemDashboard from './ocs-system-dashboard';
export type DashboardsPageProps = RouteComponentProps;
@@ -24,6 +24,11 @@ const ODFSystemDashboard: React.FC = ({
match,
}) => {
const { t } = useCustomTranslation();
+
+ const { namespace: clusterNs } = useParams();
+ const { systemFlags, areFlagsLoaded, flagsLoadError } =
+ useODFSystemFlagsSelector();
+
const breadcrumbs = [
{
name: t('StorageSystems'),
@@ -42,8 +47,8 @@ const ODFSystemDashboard: React.FC = ({
component: OCSSystemDashboard,
},
]);
- const isCephAvailable = useFlag(CEPH_FLAG);
- const isExternal = useFlag(OCS_INDEPENDENT_FLAG);
+ const isCephAvailable = systemFlags[clusterNs]?.isCephAvailable;
+ const isExternal = systemFlags[clusterNs]?.isExternalMode;
React.useEffect(() => {
const isBlockPoolAdded = pages.find((page) => page.href === blockPoolHref);
@@ -63,12 +68,15 @@ const ODFSystemDashboard: React.FC = ({
}, [isExternal, isCephAvailable, pages, setPages, t]);
const title = match.params.systemName;
- const arePagesLoaded = pages.length > 0;
+ const loaded = pages.length > 0 && areFlagsLoaded;
return (
<>
-
+
>
diff --git a/packages/ocs/dashboards/persistent-external/breakdown-card.tsx b/packages/ocs/dashboards/persistent-external/breakdown-card.tsx
index c2c4fe1b5..bf5e97040 100644
--- a/packages/ocs/dashboards/persistent-external/breakdown-card.tsx
+++ b/packages/ocs/dashboards/persistent-external/breakdown-card.tsx
@@ -1,5 +1,8 @@
import * as React from 'react';
-import { useODFNamespaceSelector } from '@odf/core/redux';
+import {
+ useODFNamespaceSelector,
+ useODFSystemFlagsSelector,
+} from '@odf/core/redux';
import { BreakdownCardBody } from '@odf/shared/dashboards/breakdown-card/breakdown-body';
import { getSelectOptions } from '@odf/shared/dashboards/breakdown-card/breakdown-dropdown';
import {
@@ -16,6 +19,7 @@ import {
getInstantVectorStats,
sortInstantVectorStats,
} from '@odf/shared/utils';
+import { useParams } from 'react-router-dom';
import {
Select,
SelectProps,
@@ -25,6 +29,7 @@ import {
CardTitle,
} from '@patternfly/react-core';
import { getBreakdownMetricsQuery } from '../../queries';
+import { ODFSystemParams } from '../../types';
import { getStackChartStats } from '../../utils/metrics';
import {
NamespaceDropdown,
@@ -41,10 +46,16 @@ export const BreakdownCard: React.FC = () => {
const [isOpenBreakdownSelect, setBreakdownSelect] = React.useState(false);
const [pvcNamespace, setPVCNamespace] = React.useState('');
+ const { namespace: clusterNs } = useParams();
const { odfNamespace } = useODFNamespaceSelector();
+ const { systemFlags } = useODFSystemFlagsSelector();
+
+ // name of created StorageClasses are prefix by StorageCluster name
+ const storageClassNamePrefix = systemFlags[clusterNs]?.ocsClusterName;
const { queries, model, metric } = getBreakdownMetricsQuery(
metricType,
+ storageClassNamePrefix,
pvcNamespace,
true
);
diff --git a/packages/ocs/dashboards/persistent-external/details-card.tsx b/packages/ocs/dashboards/persistent-external/details-card.tsx
index 4ee8de349..5f844c224 100644
--- a/packages/ocs/dashboards/persistent-external/details-card.tsx
+++ b/packages/ocs/dashboards/persistent-external/details-card.tsx
@@ -1,23 +1,32 @@
import * as React from 'react';
import { CEPH_BRAND_NAME, OCS_OPERATOR } from '@odf/core/constants';
import { ODF_MODEL_FLAG } from '@odf/core/features';
-import { useSafeK8sWatchResources } from '@odf/core/hooks';
import { useODFNamespaceSelector } from '@odf/core/redux';
import { getOperatorVersion } from '@odf/core/utils';
+import { getStorageClusterInNs } from '@odf/core/utils';
import { ODF_OPERATOR } from '@odf/shared/constants';
import { useFetchCsv } from '@odf/shared/hooks/use-fetch-csv';
import { SecretModel } from '@odf/shared/models';
import { getName } from '@odf/shared/selectors';
-import { SecretKind, K8sResourceKind } from '@odf/shared/types';
+import {
+ SecretKind,
+ K8sResourceKind,
+ StorageClusterKind,
+} from '@odf/shared/types';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { referenceForModel } from '@odf/shared/utils';
import { ExternalLink } from '@odf/shared/utils/link';
-import { useFlag } from '@openshift-console/dynamic-plugin-sdk';
+import {
+ useFlag,
+ useK8sWatchResources,
+} from '@openshift-console/dynamic-plugin-sdk';
import { DetailsBody } from '@openshift-console/dynamic-plugin-sdk-internal';
import { OverviewDetailItem as DetailItem } from '@openshift-console/plugin-shared';
import { Base64 } from 'js-base64';
+import { useParams } from 'react-router-dom';
import { Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core';
import { StorageClusterModel } from '../../models';
+import { ODFSystemParams } from '../../types';
import { getNetworkEncryption } from '../../utils';
const getCephLink = (secret: SecretKind): string => {
@@ -33,16 +42,14 @@ type ResourcesObject = {
};
};
-const k8sResources = (ns: string) => ({
+const k8sResources = (clusterNs: string) => ({
ocs: {
kind: referenceForModel(StorageClusterModel),
- namespaced: true,
isList: true,
- namespace: ns,
},
secret: {
kind: SecretModel.kind,
- namespace: ns,
+ namespace: clusterNs,
name: 'rook-ceph-dashboard-link',
},
});
@@ -52,15 +59,19 @@ export const DetailsCard: React.FC = () => {
const isODF = useFlag(ODF_MODEL_FLAG);
const { odfNamespace, isNsSafe } = useODFNamespaceSelector();
+ const { namespace: clusterNs } = useParams();
- const resourcesObj: ResourcesObject = useSafeK8sWatchResources(k8sResources);
- const inTransitEncryptionStatus = getNetworkEncryption(
- resourcesObj['ocs'].data?.[0]
- )
+ const resourcesObj: ResourcesObject = useK8sWatchResources(
+ k8sResources(clusterNs)
+ );
+ const ocsCluster = getStorageClusterInNs(
+ resourcesObj['ocs'].data as StorageClusterKind[],
+ clusterNs
+ );
+ const inTransitEncryptionStatus = getNetworkEncryption(ocsCluster)
? t('Enabled')
: t('Disabled');
-
- const ocsName = getName(resourcesObj['ocs'].data?.[0]);
+ const ocsName = getName(ocsCluster);
const [csv, csvLoaded, csvError] = useFetchCsv({
specName: !isODF ? OCS_OPERATOR : ODF_OPERATOR,
diff --git a/packages/ocs/dashboards/persistent-external/status-card.tsx b/packages/ocs/dashboards/persistent-external/status-card.tsx
index 24ca11c3f..ce6e2f907 100644
--- a/packages/ocs/dashboards/persistent-external/status-card.tsx
+++ b/packages/ocs/dashboards/persistent-external/status-card.tsx
@@ -1,12 +1,15 @@
import * as React from 'react';
import { cephClusterResource } from '@odf/core/resources';
-import { K8sResourceKind } from '@odf/shared/types';
+import { getResourceInNs as getCephClusterInNs } from '@odf/core/utils';
+import { getCephHealthState } from '@odf/ocs/utils';
+import { K8sResourceKind, CephClusterKind } from '@odf/shared/types';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
import {
HealthBody,
HealthItem,
} from '@openshift-console/dynamic-plugin-sdk-internal';
+import { useParams } from 'react-router-dom';
import {
GalleryItem,
Gallery,
@@ -14,15 +17,23 @@ import {
CardHeader,
CardTitle,
} from '@patternfly/react-core';
-import { getCephHealthState } from '../persistent-internal/status-card/utils';
+import { ODFSystemParams } from '../../types';
export const StatusCard: React.FC = () => {
const { t } = useCustomTranslation();
const [data, loaded, loadError] =
useK8sWatchResource(cephClusterResource);
+ const { namespace: clusterNs } = useParams();
+
const cephHealth = getCephHealthState(
- { ceph: { data, loaded, loadError } },
+ {
+ ceph: {
+ data: getCephClusterInNs(data as CephClusterKind[], clusterNs),
+ loaded,
+ loadError,
+ },
+ },
t
);
diff --git a/packages/ocs/dashboards/persistent-external/utilization-card.tsx b/packages/ocs/dashboards/persistent-external/utilization-card.tsx
index 508761468..f334636e8 100644
--- a/packages/ocs/dashboards/persistent-external/utilization-card.tsx
+++ b/packages/ocs/dashboards/persistent-external/utilization-card.tsx
@@ -1,4 +1,5 @@
import * as React from 'react';
+import { useODFSystemFlagsSelector } from '@odf/core/redux';
import { PrometheusUtilizationItem } from '@odf/shared/dashboards/utilization-card/prometheus-utilization-item';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { humanizeBinaryBytes } from '@odf/shared/utils';
@@ -7,6 +8,7 @@ import {
UtilizationBody,
} from '@openshift-console/dynamic-plugin-sdk-internal';
import { ByteDataTypes } from '@openshift-console/dynamic-plugin-sdk/lib/api/internal-types';
+import { useParams } from 'react-router-dom';
import {
Card,
CardActions,
@@ -18,16 +20,25 @@ import {
StorageDashboardQuery,
INDEPENDENT_UTILIZATION_QUERIES,
} from '../../queries';
+import { ODFSystemParams } from '../../types';
export const UtilizationContent: React.FC = () => {
const { t } = useCustomTranslation();
+ const { namespace: clusterNs } = useParams();
+ const { systemFlags } = useODFSystemFlagsSelector();
+
+ // name of created StorageClasses are prefix by StorageCluster name
+ const storageClassNamePrefix = systemFlags[clusterNs]?.ocsClusterName;
+
return (
{
{
- const { odfNamespace } = useODFNamespaceSelector();
+ const { namespace: clusterNs } = useParams();
const [pvcs, pvcLoaded] =
useK8sWatchResource(pvcResource);
@@ -81,8 +85,8 @@ const RecentEvent: React.FC = () => {
const memoizedPVCNames = useDeepCompareMemoize(validPVC, true);
const ocsEventsFilter = React.useCallback(
- () => isPersistentStorageEvent(memoizedPVCNames, odfNamespace),
- [memoizedPVCNames, odfNamespace]
+ () => isPersistentStorageEvent(memoizedPVCNames, clusterNs),
+ [memoizedPVCNames, clusterNs]
);
const eventObject = {
@@ -98,29 +102,39 @@ const RecentEvent: React.FC = () => {
export const subscriptionResource = {
isList: true,
kind: referenceForModel(SubscriptionModel),
- namespaced: false,
};
export const storageClusterResource = {
isList: true,
kind: referenceForModel(StorageClusterModel),
- namespaced: false,
};
const OngoingActivity = () => {
+ const { namespace: clusterNs } = useParams();
+ const { systemFlags } = useODFSystemFlagsSelector();
+ const managedByOCS = systemFlags[clusterNs]?.ocsClusterName;
+
const [subscriptions, subLoaded] =
useK8sWatchResource(subscriptionResource);
- const [cluster, clusterLoaded] = useK8sWatchResource(storageClusterResource);
+ const [clusters, clusterLoaded] = useK8sWatchResource(
+ storageClusterResource
+ );
const [resiliencyMetric, , metricsLoading] = useCustomPrometheusPoll({
- query: DATA_RESILIENCY_QUERY[StorageDashboardQuery.RESILIENCY_PROGRESS],
+ query:
+ DATA_RESILIENCY_QUERY(managedByOCS)[
+ StorageDashboardQuery.RESILIENCY_PROGRESS
+ ],
endpoint: 'api/v1/query' as any,
basePath: usePrometheusBasePath(),
});
const ocsSubscription: SubscriptionKind = getOCSSubscription(subscriptions);
- const ocsCluster: K8sResourceKind = cluster?.[0];
+ const ocsCluster: K8sResourceKind = getStorageClusterInNs(
+ clusters,
+ clusterNs
+ );
const prometheusActivities = [];
const resourceActivities = [];
diff --git a/packages/ocs/dashboards/persistent-internal/capacity-breakdown-card/capacity-breakdown-card.tsx b/packages/ocs/dashboards/persistent-internal/capacity-breakdown-card/capacity-breakdown-card.tsx
index 28652125a..4028d8b5e 100644
--- a/packages/ocs/dashboards/persistent-internal/capacity-breakdown-card/capacity-breakdown-card.tsx
+++ b/packages/ocs/dashboards/persistent-internal/capacity-breakdown-card/capacity-breakdown-card.tsx
@@ -1,5 +1,8 @@
import * as React from 'react';
-import { useODFNamespaceSelector } from '@odf/core/redux';
+import {
+ useODFNamespaceSelector,
+ useODFSystemFlagsSelector,
+} from '@odf/core/redux';
import { namespaceResource } from '@odf/core/resources';
import { BreakdownCardBody } from '@odf/shared/dashboards/breakdown-card/breakdown-body';
import { getSelectOptions } from '@odf/shared/dashboards/breakdown-card/breakdown-dropdown';
@@ -22,6 +25,7 @@ import {
sortInstantVectorStats,
} from '@odf/shared/utils';
import { K8sResourceCommon } from '@openshift-console/dynamic-plugin-sdk';
+import { useParams } from 'react-router-dom';
import {
Select,
SelectProps,
@@ -35,6 +39,7 @@ import {
CEPH_CAPACITY_BREAKDOWN_QUERIES,
StorageDashboardQuery,
} from '../../../queries/ceph-storage';
+import { ODFSystemParams } from '../../../types';
import { getStackChartStats } from '../../../utils/metrics';
import './capacity-breakdown-card.scss';
@@ -130,9 +135,19 @@ const BreakdownCard: React.FC = () => {
const [isOpenBreakdownSelect, setBreakdownSelect] = React.useState(false);
const [pvcNamespace, setPVCNamespace] = React.useState('');
+ const { namespace: clusterNs } = useParams();
+ const { systemFlags } = useODFSystemFlagsSelector();
+
+ // name of the created StorageClasses are prefix by StorageCluster name,
+ // it is also the value of the "managedBy" label in the metrics.
+ const ocsCluster = systemFlags[clusterNs]?.ocsClusterName;
+
const { queries, model, metric } = getBreakdownMetricsQuery(
metricType,
- pvcNamespace
+ ocsCluster,
+ pvcNamespace,
+ false,
+ ocsCluster
);
const { odfNamespace } = useODFNamespaceSelector();
@@ -150,8 +165,9 @@ const BreakdownCard: React.FC = () => {
basePath: usePrometheusBasePath(),
});
const [cephUsedMetric, cephError, cephLoading] = useCustomPrometheusPoll({
- query:
- CEPH_CAPACITY_BREAKDOWN_QUERIES[StorageDashboardQuery.CEPH_CAPACITY_USED],
+ query: CEPH_CAPACITY_BREAKDOWN_QUERIES(ocsCluster, ocsCluster)[
+ StorageDashboardQuery.CEPH_CAPACITY_USED
+ ],
endpoint: 'api/v1/query' as any,
basePath: usePrometheusBasePath(),
});
diff --git a/packages/ocs/dashboards/persistent-internal/details-card.tsx b/packages/ocs/dashboards/persistent-internal/details-card.tsx
index e257287ad..514db6a11 100644
--- a/packages/ocs/dashboards/persistent-internal/details-card.tsx
+++ b/packages/ocs/dashboards/persistent-internal/details-card.tsx
@@ -1,7 +1,7 @@
import * as React from 'react';
-import { useSafeK8sList } from '@odf/core/hooks';
import { useODFNamespaceSelector } from '@odf/core/redux';
import { getOperatorVersion } from '@odf/core/utils';
+import { getStorageClusterInNs } from '@odf/core/utils';
import { ODF_OPERATOR } from '@odf/shared/constants';
import { useK8sGet } from '@odf/shared/hooks/k8s-get-hook';
import { useFetchCsv } from '@odf/shared/hooks/use-fetch-csv';
@@ -15,34 +15,43 @@ import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import {
getInfrastructurePlatform,
resourcePathFromModel,
+ referenceForModel,
} from '@odf/shared/utils';
+import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
import { DetailsBody } from '@openshift-console/dynamic-plugin-sdk-internal';
import { OverviewDetailItem as DetailItem } from '@openshift-console/plugin-shared';
-import { Link } from 'react-router-dom';
+import { Link, useParams } from 'react-router-dom';
import { Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core';
import { StorageClusterModel } from '../../models';
+import { ODFSystemParams } from '../../types';
import { getNetworkEncryption } from '../../utils';
+const storageClusterResource = {
+ kind: referenceForModel(StorageClusterModel),
+ isList: true,
+};
+
const DetailsCard: React.FC = () => {
const { t } = useCustomTranslation();
+ const { namespace: ocsNs } = useParams();
const { odfNamespace, isNsSafe } = useODFNamespaceSelector();
const [infrastructure, infrastructureLoaded, infrastructureError] =
useK8sGet(InfrastructureModel, 'cluster');
- const [ocsData, ocsLoaded, ocsError] = useSafeK8sList(
- StorageClusterModel,
- odfNamespace
- );
+
+ const [ocsData, ocsLoaded, ocsError] = useK8sWatchResource<
+ StorageClusterKind[]
+ >(storageClusterResource);
+
const [csv, csvLoaded, csvError] = useFetchCsv({
specName: ODF_OPERATOR,
namespace: odfNamespace,
startPollingInstantly: isNsSafe,
});
+
const infrastructurePlatform = getInfrastructurePlatform(infrastructure);
- const cluster: StorageClusterKind = ocsData?.find(
- (item: StorageClusterKind) => item.status.phase !== 'Ignored'
- );
+ const cluster: StorageClusterKind = getStorageClusterInNs(ocsData, ocsNs);
const ocsName = getName(cluster);
const inTransitEncryptionStatus = getNetworkEncryption(cluster)
? t('Enabled')
diff --git a/packages/ocs/dashboards/persistent-internal/inventory-card.tsx b/packages/ocs/dashboards/persistent-internal/inventory-card.tsx
index aa8d8882e..34dd9dacc 100644
--- a/packages/ocs/dashboards/persistent-internal/inventory-card.tsx
+++ b/packages/ocs/dashboards/persistent-internal/inventory-card.tsx
@@ -1,6 +1,5 @@
import * as React from 'react';
import { cephStorageLabel } from '@odf/core/constants';
-import { useODFNamespaceSelector } from '@odf/core/redux';
import {
NodeModel,
PersistentVolumeClaimModel,
@@ -18,7 +17,9 @@ import { NodeKind } from '@odf/shared/types';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { useK8sWatchResources } from '@openshift-console/dynamic-plugin-sdk';
import { ResourceInventoryItem } from '@openshift-console/dynamic-plugin-sdk-internal';
+import { useParams } from 'react-router-dom';
import { Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core';
+import { ODFSystemParams } from '../../types';
import {
getCephNodes,
getCephPVCs,
@@ -47,7 +48,7 @@ const watchResources = {
const InventoryCard: React.FC = () => {
const { t } = useCustomTranslation();
- const { odfNamespace } = useODFNamespaceSelector();
+ const { namespace: clusterNs } = useParams();
const resources = useK8sWatchResources(watchResources);
@@ -79,7 +80,7 @@ const InventoryCard: React.FC = () => {
isLoading={!nodesLoaded}
error={!!nodesLoadError}
kind={NodeModel as any}
- resources={getCephNodes(nodesData, odfNamespace)}
+ resources={getCephNodes(nodesData, clusterNs)}
mapper={getNodeStatusGroups}
basePath={ocsNodesHref}
/>
diff --git a/packages/ocs/dashboards/persistent-internal/raw-capacity-card/raw-capacity-card.tsx b/packages/ocs/dashboards/persistent-internal/raw-capacity-card/raw-capacity-card.tsx
index 02e753da5..de76cb6d6 100644
--- a/packages/ocs/dashboards/persistent-internal/raw-capacity-card/raw-capacity-card.tsx
+++ b/packages/ocs/dashboards/persistent-internal/raw-capacity-card/raw-capacity-card.tsx
@@ -1,15 +1,18 @@
import * as React from 'react';
+import { useODFSystemFlagsSelector } from '@odf/core/redux';
import {
useCustomPrometheusPoll,
usePrometheusBasePath,
} from '@odf/shared/hooks/custom-prometheus-poll';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { getInstantVectorStats } from '@odf/shared/utils';
+import { useParams } from 'react-router-dom';
import { compose } from 'redux';
import {
CAPACITY_INFO_QUERIES,
StorageDashboardQuery,
} from '../../../queries/ceph-storage';
+import { ODFSystemParams } from '../../../types';
import {
CapacityCard,
CapacityCardProps,
@@ -21,13 +24,23 @@ const parser = compose((val) => val?.[0]?.y, getInstantVectorStats);
const RawCapacityCard: React.FC = () => {
const { t } = useCustomTranslation();
+ const { namespace: clusterNs } = useParams();
+ const { systemFlags } = useODFSystemFlagsSelector();
+ const managedByOCS = systemFlags[clusterNs]?.ocsClusterName;
+
const [totalCapacity, totalError, totalLoading] = useCustomPrometheusPoll({
- query: CAPACITY_INFO_QUERIES[StorageDashboardQuery.RAW_CAPACITY_TOTAL],
+ query:
+ CAPACITY_INFO_QUERIES(managedByOCS)[
+ StorageDashboardQuery.RAW_CAPACITY_TOTAL
+ ],
endpoint: 'api/v1/query' as any,
basePath: usePrometheusBasePath(),
});
const [usedCapacity, usedError, usedLoading] = useCustomPrometheusPoll({
- query: CAPACITY_INFO_QUERIES[StorageDashboardQuery.RAW_CAPACITY_USED],
+ query:
+ CAPACITY_INFO_QUERIES(managedByOCS)[
+ StorageDashboardQuery.RAW_CAPACITY_USED
+ ],
endpoint: 'api/v1/query' as any,
basePath: usePrometheusBasePath(),
});
diff --git a/packages/ocs/dashboards/persistent-internal/status-card/status-card.tsx b/packages/ocs/dashboards/persistent-internal/status-card/status-card.tsx
index 5d361afba..7fe119951 100644
--- a/packages/ocs/dashboards/persistent-internal/status-card/status-card.tsx
+++ b/packages/ocs/dashboards/persistent-internal/status-card/status-card.tsx
@@ -1,4 +1,7 @@
import * as React from 'react';
+import { useODFSystemFlagsSelector } from '@odf/core/redux';
+import { getResourceInNs as getCephClusterInNs } from '@odf/core/utils';
+import { getCephHealthState } from '@odf/ocs/utils';
import { healthStateMapping } from '@odf/shared/dashboards/status-card/states';
import {
useCustomPrometheusPoll,
@@ -22,6 +25,7 @@ import {
} from '@openshift-console/dynamic-plugin-sdk-internal';
import { SubsystemHealth } from '@openshift-console/dynamic-plugin-sdk/lib/extensions/dashboard-types';
import * as _ from 'lodash-es';
+import { useParams } from 'react-router-dom';
import {
Gallery,
GalleryItem,
@@ -34,12 +38,15 @@ import {
import { CephClusterModel } from '../../../models';
import { DATA_RESILIENCY_QUERY, StorageDashboardQuery } from '../../../queries';
import { OSDMigrationProgress } from './osd-migration/osd-migration-progress';
-import { getCephHealthState, getDataResiliencyState } from './utils';
+import { ODFSystemParams } from '../../../types';
+import { getDataResiliencyState } from './utils';
import { whitelistedHealthChecksRef } from './whitelisted-health-checks';
import './healthchecks.scss';
-const resiliencyProgressQuery =
- DATA_RESILIENCY_QUERY[StorageDashboardQuery.RESILIENCY_PROGRESS];
+const resiliencyProgressQuery = (managedByOCS: string) =>
+ DATA_RESILIENCY_QUERY(managedByOCS)[
+ StorageDashboardQuery.RESILIENCY_PROGRESS
+ ];
const generateDocumentationLink = (alert: Alert): string => {
return `https://access.redhat.com/documentation/en-us/red_hat_openshift_data_foundation/4.12/html-single/troubleshooting_openshift_data_foundation/index#${_.toLower(
@@ -60,6 +67,8 @@ const getDocumentationLink = (alert: Alert): string => {
export const CephAlerts: React.FC = () => {
const [alerts, loaded, error] = useAlerts();
+ // ToDo (epic 4422): Get StorageCluster name and namespace from the Alert object
+ // and filter Alerts based on that for a particular cluster.
const filteredAlerts =
loaded && !error && !_.isEmpty(alerts) ? filterCephAlerts(alerts) : [];
@@ -112,7 +121,6 @@ const CephHealthCheck: React.FC = ({
export const cephClusterResource = {
kind: referenceForModel(CephClusterModel),
- namespaced: false,
isList: true,
};
@@ -121,16 +129,22 @@ export const StatusCard: React.FC = () => {
const [data, loaded, loadError] =
useK8sWatchResource(cephClusterResource);
+ const { namespace: clusterNs } = useParams();
+ const { systemFlags } = useODFSystemFlagsSelector();
+ const managedByOCS = systemFlags[clusterNs]?.ocsClusterName;
+
const [resiliencyProgress, resiliencyProgressError] = useCustomPrometheusPoll(
{
- query: resiliencyProgressQuery,
+ query: resiliencyProgressQuery(managedByOCS),
endpoint: 'api/v1/query' as any,
basePath: usePrometheusBasePath(),
}
);
+ const cephCluster = getCephClusterInNs(data, clusterNs);
+
const cephHealthState = getCephHealthState(
- { ceph: { data, loaded, loadError } },
+ { ceph: { data: cephCluster, loaded, loadError } },
t
);
const dataResiliencyState = getDataResiliencyState(
@@ -140,7 +154,7 @@ export const StatusCard: React.FC = () => {
const pattern = /[A-Z]+_*|error/g;
const healthChecks: CephHealthCheckType[] = [];
- const cephDetails = data?.[0]?.status?.ceph?.details;
+ const cephDetails = cephCluster?.status?.ceph?.details;
for (const key in cephDetails) {
if (pattern.test(key)) {
const healthCheckObject: CephHealthCheckType = {
@@ -184,7 +198,7 @@ export const StatusCard: React.FC = () => {
-
+