Skip to content

Commit

Permalink
Merge pull request #1260 from GowthamShanmugam/cleanup_status
Browse files Browse the repository at this point in the history
Displaying cleanup event for discovered app failover
  • Loading branch information
openshift-merge-bot[bot] authored Mar 25, 2024
2 parents 22bb055 + fa6fed2 commit 36e6be2
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 60 deletions.
14 changes: 8 additions & 6 deletions locales/en/plugin__odf-console.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,14 @@
"Loading Empty Page": "Loading Empty Page",
"You are not authorized to complete this action. See your cluster administrator for role-based access control information.": "You are not authorized to complete this action. See your cluster administrator for role-based access control information.",
"Not Authorized": "Not Authorized",
"{{ currentStatus }} to cluster {{ preferredCluster }}": "{{ currentStatus }} to cluster {{ preferredCluster }}",
"{{ currentStatus }} to cluster {{ failoverCluster }}": "{{ currentStatus }} to cluster {{ failoverCluster }}",
"Relocating to cluster {{ preferredCluster }}": "Relocating to cluster {{ preferredCluster }}",
"In Progress": "In Progress",
"Relocated to cluster {{ preferredCluster }}": "Relocated to cluster {{ preferredCluster }}",
"Completed": "Completed",
"FailingOver to cluster {{ failoverCluster }}": "FailingOver to cluster {{ failoverCluster }}",
"Cleanup of resources requires user attention. Finish cleanup to restart replication.": "Cleanup of resources requires user attention. Finish cleanup to restart replication.",
"Pending": "Pending",
"FailedOver to cluster {{ failoverCluster }}": "FailedOver to cluster {{ failoverCluster }}",
"Unknown": "Unknown",
"Namespaces": "Namespaces",
"Volume snapshot": "Volume snapshot",
Expand Down Expand Up @@ -221,8 +227,6 @@
"cluster name search": "cluster name search",
"cluster name search button": "cluster name search button",
"Capacity Card": "Capacity Card",
"Completed": "Completed",
"In Progress": "In Progress",
"Last synced {{lastSync}}": "Last synced {{lastSync}}",
"{{drPolicy}}, sync every {{syncInterval}}": "{{drPolicy}}, sync every {{syncInterval}}",
"Sync status: {{lastSync}}": "Sync status: {{lastSync}}",
Expand Down Expand Up @@ -380,7 +384,6 @@
"No protected applications found": "No protected applications found",
"No protected applications": "No protected applications",
"You do not have any protected applications yet, to add disaster recovery protection to your applications start by clicking on the <2>Enroll application</2> button.": "You do not have any protected applications yet, to add disaster recovery protection to your applications start by clicking on the <2>Enroll application</2> button.",
"In progress": "In progress",
"Activity description": "Activity description",
"Application volumes (PVCs)": "Application volumes (PVCs)",
"Kubernetes objects": "Kubernetes objects",
Expand Down Expand Up @@ -1213,7 +1216,6 @@
"{{formattedProgress, number}}%": "{{formattedProgress, number}}%",
"Current": "Current",
"Loading {{title}} status": "Loading {{title}} status",
"Pending": "Pending",
"Updating": "Updating",
"Loading": "Loading",
"Upgrade available": "Upgrade available",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ describe('Test review step', () => {
await waitFor(async () => {
expect(
JSON.stringify(drpcObj) ===
'{"apiVersion":"ramendr.openshift.io/v1alpha1","kind":"DRPlacementControl","metadata":{"generateName":"drpc-","namespace":"ramen-protected-apps"},"spec":{"preferredCluster":"east-1","eligibleForProtectionNamespaces":["namespace-1","namespace-2"],"pvcSelector":{},"kubeObjectProtection":{"captureInterval":"5m","recipeRef":{"name":"mock-recipe-1","namespace":"namespace-1"}},"drPolicyRef":{"name":"mock-policy-1","apiVersion":"ramendr.openshift.io/v1alpha1","kind":"DRPolicy"}}}'
'{"apiVersion":"ramendr.openshift.io/v1alpha1","kind":"DRPlacementControl","metadata":{"name":"my-name","namespace":"ramen-protected-apps"},"spec":{"preferredCluster":"east-1","eligibleForProtectionNamespaces":["namespace-1","namespace-2"],"pvcSelector":{},"kubeObjectProtection":{"captureInterval":"5m","recipeRef":{"name":"mock-recipe-1","namespace":"namespace-1"}},"drPolicyRef":{"name":"mock-policy-1","apiVersion":"ramendr.openshift.io/v1alpha1","kind":"DRPolicy"}}}'
).toBeTruthy();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from './reducer';

export const getDRPCKindObj = (props: {
name: string;
preferredCluster: string;
namespaces: string[];
protectionMethod: ProtectionMethodType;
Expand All @@ -26,8 +27,7 @@ export const getDRPCKindObj = (props: {
apiVersion: getAPIVersionForModel(DRPlacementControlModel),
kind: DRPlacementControlModel.kind,
metadata: {
// ToDo: Dummy name, need to change: https://github.com/red-hat-storage/odf-console/pull/1240
generateName: `drpc-`,
name: props.name,
namespace: RAMEN_PROTECTED_APPS_NAMESPACE,
},
spec: {
Expand Down Expand Up @@ -66,7 +66,7 @@ export const getDRPCKindObj = (props: {

export const createPromise = (state: EnrollDiscoveredApplicationState) => {
const { namespace, configuration, replication } = state;
const { clusterName, namespaces } = namespace;
const { clusterName, namespaces, name } = namespace;
const { protectionMethod, recipe, resourceLabels } = configuration;
const { recipeName, recipeNamespace } = recipe;
const { k8sResourceLabelExpressions, pvcLabelExpressions } = resourceLabels;
Expand All @@ -76,6 +76,7 @@ export const createPromise = (state: EnrollDiscoveredApplicationState) => {
return k8sCreate({
model: DRPlacementControlModel,
data: getDRPCKindObj({
name,
preferredCluster: clusterName,
namespaces: namespaceList,
protectionMethod,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getDRStatus } from '@odf/mco/utils';
import { formatTime } from '@odf/shared/details-page/datetime';
import { fromNow } from '@odf/shared/details-page/datetime';
import { useScheduler } from '@odf/shared/hooks';
import { GrayUnknownIcon, GreenCheckCircleIcon } from '@odf/shared/status';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { getPageRange } from '@odf/shared/utils';
import {
Expand All @@ -27,6 +28,7 @@ import {
Text,
TextVariants,
} from '@patternfly/react-core';
import { InProgressIcon, PendingIcon } from '@patternfly/react-icons';
import { sortable } from '@patternfly/react-table';
import { StatusText } from './common';

Expand Down Expand Up @@ -54,28 +56,57 @@ export const getCurrentActivity = (
currentStatus: string,
failoverCluster: string,
preferredCluster: string,
t: TFunction
) => {
if (
[DRPC_STATUS.Relocating, DRPC_STATUS.Relocated].includes(
currentStatus as DRPC_STATUS
)
) {
return t('{{ currentStatus }} to cluster {{ preferredCluster }}', {
currentStatus,
preferredCluster,
});
} else if (
[DRPC_STATUS.FailingOver, DRPC_STATUS.FailedOver].includes(
currentStatus as DRPC_STATUS
)
) {
return t('{{ currentStatus }} to cluster {{ failoverCluster }}', {
currentStatus,
failoverCluster,
});
t: TFunction,
isCleanupPending?: boolean
): { description: string; status: string; icon: JSX.Element } => {
const status = currentStatus as DRPC_STATUS;

if (status === DRPC_STATUS.Relocating) {
return {
description: t('Relocating to cluster {{ preferredCluster }}', {
preferredCluster,
}),
status: t('In Progress'),
icon: <InProgressIcon />,
};
} else if (status === DRPC_STATUS.Relocated) {
return {
description: t('Relocated to cluster {{ preferredCluster }}', {
preferredCluster,
}),
status: t('Completed'),
icon: <GreenCheckCircleIcon />,
};
} else if (status === DRPC_STATUS.FailingOver) {
return {
description: t('FailingOver to cluster {{ failoverCluster }}', {
failoverCluster,
}),
status: t('In Progress'),
icon: <InProgressIcon />,
};
} else if (status === DRPC_STATUS.FailedOver) {
return isCleanupPending
? {
description: t(
'Cleanup of resources requires user attention. Finish cleanup to restart replication.'
),
status: t('Pending'),
icon: <PendingIcon />,
}
: {
description: t('FailedOver to cluster {{ failoverCluster }}', {
failoverCluster,
}),
status: t('Completed'),
icon: <GreenCheckCircleIcon />,
};
} else {
return t('Unknown');
return {
description: t('Unknown'),
status: t('Unknown'),
icon: <GrayUnknownIcon />,
};
}
};

Expand Down Expand Up @@ -125,12 +156,14 @@ export const ActivitySection: React.FC<CommonProps> = ({
<StatusText>{t('Activity')}</StatusText>
<StatusIconAndText
icon={getDRStatus({ currentStatus, t }).icon}
title={getCurrentActivity(
currentStatus,
failoverCluster,
preferredCluster,
t
)}
title={
getCurrentActivity(
currentStatus,
failoverCluster,
preferredCluster,
t
).description
}
className="text-muted"
/>
</div>
Expand Down Expand Up @@ -218,7 +251,10 @@ const SubscriptionRow: React.FC<
{...subscriptionTableColumnProps[1]}
activeColumnIDs={activeColumnIDs}
>
{getCurrentActivity(activity, failoverCluster, preferredCluster, t)}
{
getCurrentActivity(activity, failoverCluster, preferredCluster, t)
.description
}
</TableData>
<TableData
{...subscriptionTableColumnProps[2]}
Expand Down
33 changes: 15 additions & 18 deletions packages/mco/components/protected-applications/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DataUnavailableError } from '@odf/shared/generic/Error';
import { NamespaceModel } from '@odf/shared/models';
import { ResourceNameWIcon } from '@odf/shared/resource-link/resource-link';
import { PopoverStatus } from '@odf/shared/status';
import { StatusIconAndText } from '@odf/shared/status';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import { referenceForModel } from '@odf/shared/utils';
import { useModal } from '@openshift-console/dynamic-plugin-sdk';
Expand All @@ -26,10 +27,7 @@ import {
DescriptionListDescription,
PopoverPosition,
} from '@patternfly/react-core';
import {
InProgressIcon,
OutlinedQuestionCircleIcon,
} from '@patternfly/react-icons';
import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons';
import { ENROLLED_APP_QUERY_PARAMS_KEY, DR_BASE_ROUTE } from '../../constants';
import { DRPlacementControlModel } from '../../models';
import { DRPlacementControlKind } from '../../types';
Expand All @@ -42,6 +40,7 @@ import {
SyncStatusInfo,
EnrollApplicationTypes,
getEnrollDropdownItems,
isCleanupPending,
} from './utils';
import './protected-apps.scss';

Expand Down Expand Up @@ -324,30 +323,28 @@ export const EventsDetails: React.FC<ExpandableComponentProps> = ({
application,
}) => {
const { t } = useCustomTranslation();
const anyOnGoingEvent =
isFailingOrRelocating(application) || isCleanupPending(application);

// ToDo: Add clean-up activity event as well
const activity = [
getCurrentActivity(
application?.status?.phase,
application.spec?.failoverCluster,
application.spec?.preferredCluster,
t
),
];
const activity = getCurrentActivity(
application?.status?.phase,
application.spec?.failoverCluster,
application.spec?.preferredCluster,
t,
isCleanupPending(application)
);
const status = [
<>
<InProgressIcon /> {t('In progress')}
</>,
<StatusIconAndText icon={activity.icon} title={activity.status} />,
];
return (
<>
{!isFailingOrRelocating(application) ? (
{!anyOnGoingEvent ? (
<DataUnavailableError className="pf-v5-u-pt-xl pf-v5-u-pb-xl" />
) : (
<DescriptionList_ columnModifier={'2Col'}>
<Description
term={t('Activity description')}
descriptions={activity}
descriptions={[activity.description]}
/>
<Description term={t('Status')} descriptions={status} />
</DescriptionList_>
Expand Down
9 changes: 6 additions & 3 deletions packages/mco/components/protected-applications/list-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import {
getAppWorstSyncStatus,
SyncStatusInfo,
drpcDetailsPageRoute,
isCleanupPending,
} from './utils';
import './protected-apps.scss';

Expand Down Expand Up @@ -93,11 +94,13 @@ const ProtectedAppsTableRow: React.FC<
const enrolledNamespaces: string[] =
application.spec?.eligibleForProtectionNamespaces || [];

// ToDo: Add clean-up activity event as well
// Failover/Relocate/Cleanup event details
const anyOnGoingEvent =
isFailingOrRelocating(application) || isCleanupPending(application);
const showEventsDetails: boolean =
isFailingOrRelocating(application) ||
anyOnGoingEvent ||
expandableComponentType === EXPANDABLE_COMPONENT_TYPE.EVENTS;
const eventsCount: number = isFailingOrRelocating(application) ? 1 : 0;
const eventsCount: number = anyOnGoingEvent ? 1 : 0;

// Overall sync status details (replication health)
const syncStatusInfo: SyncStatusInfo =
Expand Down
11 changes: 10 additions & 1 deletion packages/mco/components/protected-applications/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ import {
} from '../../constants';
import { DRPlacementControlModel } from '../../models';
import { DRPlacementControlKind } from '../../types';
import { getVolumeReplicationHealth } from '../../utils';
import {
getVolumeReplicationHealth,
isDRPCAvailable,
isPeerReady,
} from '../../utils';
import { DiscoveredApplicationParser as DiscoveredApplicationModal } from '../modals/app-failover-relocate/parser/discovered-application-parser';

export const drpcDetailsPageRoute = (drpc: DRPlacementControlKind) =>
Expand Down Expand Up @@ -77,6 +81,11 @@ export const isFailingOrRelocating = (
application?.status?.phase as DRPC_STATUS
);

export const isCleanupPending = (drpc: DRPlacementControlKind): boolean =>
drpc?.status?.phase === DRPC_STATUS.FailedOver &&
!isPeerReady(drpc) &&
isDRPCAvailable(drpc);

export const getReplicationHealth = (
lastSyncTime: string,
schedulingInterval: string
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/dropdown/multiselectdropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const MultiSelectDropdown: React.FC<MultiSelectDropdownProps> = ({
noResultsFoundText={t('No results found')}
isCheckboxSelectionBadgeHidden
onCreateOption={(isCreatable && onCreateOption) || undefined}
isCreatable={isCreatable}
{...rest}
>
{allOptions || items}
Expand Down

0 comments on commit 36e6be2

Please sign in to comment.