Skip to content

Commit

Permalink
Merge pull request #950 from yaacov/migrations-tabls-to-plans-details
Browse files Browse the repository at this point in the history
🐾 Add a migrations section to plans details tab
  • Loading branch information
yaacov authored Feb 23, 2024
2 parents e565908 + d32d703 commit 3918e84
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"Close": "Close",
"Cluster": "Cluster",
"Clusters": "Clusters",
"Completed at": "Completed at",
"Concern": "Concern",
"Concerns": "Concerns",
"Conditions": "Conditions",
Expand Down Expand Up @@ -203,6 +204,7 @@
"Metrics": "Metrics",
"Migrate": "Migrate",
"Migrate without validating a CA certificate": "Migrate without validating a CA certificate",
"Migration": "Migration",
"Migration networks maps are used to map network interfaces between source and target workloads.": "Migration networks maps are used to map network interfaces between source and target workloads.",
"Migration plans are used to plan migration or virtualization workloads from source providers to target providers.": "Migration plans are used to plan migration or virtualization workloads from source providers to target providers.",
"Migration started": "Migration started",
Expand All @@ -212,6 +214,7 @@
"Migrations (last 31 days)": "Migrations (last 31 days)",
"Migrations (last 7 days)": "Migrations (last 7 days)",
"Migrations for virtualization": "Migrations for virtualization",
"Migrations not found": "Migrations not found",
"MTU": "MTU",
"Multiple NICs mapped to Pod Networking ": "Multiple NICs mapped to Pod Networking ",
"Multiple NICs on the same network": "Multiple NICs on the same network",
Expand Down Expand Up @@ -303,6 +306,7 @@
"Pod": "Pod",
"Pod network": "Pod network",
"Pods": "Pods",
"Pods not found": "Pods not found",
"Power state": "Power state",
"Powered off": "Powered off",
"Powered on": "Powered on",
Expand Down Expand Up @@ -370,6 +374,7 @@
"Specifies the duration for retaining 'must gather' reports before they are automatically deleted. The default value is -1, which implies automatic cleanup is disabled.": "Specifies the duration for retaining 'must gather' reports before they are automatically deleted. The default value is -1, which implies automatic cleanup is disabled.",
"Specify the type of source provider. Allowed values are ova, ovirt, vsphere,\n openshift, and openstack. This label is needed to verify the credentials are correct when the remote system is accessible and, for RHV, to retrieve the Manager CA certificate when\n a third-party certificate is specified.": "Specify the type of source provider. Allowed values are ova, ovirt, vsphere,\n openshift, and openstack. This label is needed to verify the credentials are correct when the remote system is accessible and, for RHV, to retrieve the Manager CA certificate when\n a third-party certificate is specified.",
"Staging": "Staging",
"Started at": "Started at",
"Status": "Status",
"Storage": "Storage",
"Storage classes": "Storage classes",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,19 @@ import { useForkliftTranslation } from 'src/utils/i18n';

import { IoK8sApiCoreV1Pod } from '@kubev2v/types';
import { ResourceLink, Timestamp } from '@openshift-console/dynamic-plugin-sdk';
import { Split, SplitItem } from '@patternfly/react-core';
import { HelperText, HelperTextItem, Split, SplitItem } from '@patternfly/react-core';
import { TableComposable, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table';

export const PodsTable: React.FC<PodsTableProps> = ({ pods, showOwner }) => {
const { t } = useForkliftTranslation();

if (!pods) {
return <></>;
}

const getStatusLabel = (phase: string) => {
return (
<Split>
<SplitItem className="forklift-overview__controller-card__status-icon">
<StatusIcon phase={phase} />
</SplitItem>
<SplitItem>{phase}</SplitItem>
</Split>
<HelperText>
<HelperTextItem>{t('Pods not found')}</HelperTextItem>
</HelperText>
);
};
}

return (
<TableComposable aria-label="Expandable table" variant="compact">
Expand Down Expand Up @@ -69,6 +62,17 @@ export const PodsTable: React.FC<PodsTableProps> = ({ pods, showOwner }) => {
);
};

const getStatusLabel = (phase: string) => {
return (
<Split>
<SplitItem className="forklift-overview__controller-card__status-icon">
<StatusIcon phase={phase} />
</SplitItem>
<SplitItem>{phase}</SplitItem>
</Split>
);
};

export type PodsTableProps = {
pods: IoK8sApiCoreV1Pod[];
showOwner?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,8 @@

.forklift-network-map__details-tab--update-button {
margin-bottom: var(--pf-global--spacer--md);
}
}

.forklift-overview__controller-card__status-icon {
padding-right: var(--pf-global--spacer--sm);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';

import { MigrationModelGroupVersionKind, V1beta1Migration, V1beta1Plan } from '@kubev2v/types';
import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';

import { Suspend } from '../Suspend';

import { MigrationsTable } from './components';

export const MigrationsSection: React.FC<MigrationsSectionProps> = ({ obj }) => {
const [migrations, loaded, loadError] = useK8sWatchResource<V1beta1Migration[]>({
groupVersionKind: MigrationModelGroupVersionKind,
namespaced: true,
isList: true,
namespace: obj?.metadata?.namespace,
});

const ownedMigrations = migrations.filter(
(m) => m?.metadata?.ownerReferences?.[0]?.uid === obj.metadata.uid,
);

return (
<Suspend obj={ownedMigrations} loaded={loaded} loadError={loadError}>
<MigrationsTable migrations={ownedMigrations} />
</Suspend>
);
};

export type MigrationsSectionProps = {
obj: V1beta1Plan;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React from 'react';
import StatusIcon from 'src/components/status/StatusIcon';
import { useForkliftTranslation } from 'src/utils/i18n';

import {
MigrationModelGroupVersionKind,
PlanModelGroupVersionKind,
V1beta1Migration,
V1beta1MigrationStatusConditions,
} from '@kubev2v/types';
import { ResourceLink, Timestamp } from '@openshift-console/dynamic-plugin-sdk';
import { HelperText, HelperTextItem, Split, SplitItem } from '@patternfly/react-core';
import { TableComposable, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table';

export const MigrationsTable: React.FC<MigrationTableProps> = ({ migrations, showOwner }) => {
const { t } = useForkliftTranslation();

if (!migrations || migrations.length < 1) {
return (
<HelperText>
<HelperTextItem>{t('Migrations not found')}</HelperTextItem>
</HelperText>
);
}

return (
<TableComposable aria-label="Expandable table" variant="compact">
<Thead>
<Tr>
<Th width={20}>{t('Migration')}</Th>
{showOwner && <Th width={20}>{t('Owner')}</Th>}
<Th width={10}>{t('Status')}</Th>
<Th width={10}>{t('VMs')}</Th>
<Th width={15}>{t('Started at')}</Th>
<Th width={15}>{t('Completed at')}</Th>
</Tr>
</Thead>
<Tbody>
{migrations.map((migration) => (
<Tr key={migration?.metadata?.uid}>
<Td>
<ResourceLink
groupVersionKind={MigrationModelGroupVersionKind}
name={migration?.metadata?.name}
namespace={migration?.metadata?.namespace}
/>
</Td>
{showOwner && (
<Td>
{migration?.metadata?.ownerReferences?.[0] ? (
<ResourceLink
groupVersionKind={PlanModelGroupVersionKind}
name={migration?.metadata?.ownerReferences?.[0]?.name}
namespace={migration?.metadata?.namespace}
/>
) : (
''
)}
</Td>
)}
<Td>{getStatusLabel(migration?.status?.conditions)}</Td>
<Td>{migration?.status?.vms?.length || '-'}</Td>
<Td>
<Timestamp timestamp={migration?.status?.started} />
</Td>
<Td>
<Timestamp timestamp={migration?.status?.completed} />
</Td>
</Tr>
))}
</Tbody>
</TableComposable>
);
};

const getStatusLabel = (conditions: V1beta1MigrationStatusConditions[]) => {
let phase: string;

const phases = ['Ready', 'Running', 'Succeeded', 'Failed'];

// Look for a condition indicating a migration phase
phases.forEach((p) => {
const condition = conditions.find((c) => c.type === p && c.status === 'True');
if (condition) {
phase = p;
}
});

return (
<Split>
<SplitItem className="forklift-overview__controller-card__status-icon">
<StatusIcon phase={phase} />
</SplitItem>
<SplitItem>{phase}</SplitItem>
</Split>
);
};

export type MigrationTableProps = {
migrations: V1beta1Migration[];
showOwner?: boolean;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @index(['./*', /style/g], f => `export * from '${f.path}';`)
export * from './MigrationsTable';
// @endindex
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// @index(['./*', /style/g], f => `export * from '${f.path}';`)
export * from './components';
export * from './MigrationsSection';
// @endindex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
export * from './ConditionsSection';
export * from './DetailsSection';
export * from './Loading';
export * from './MigrationsSection';
export * from './ProvidersSection';
export * from './Suspend';
// @endindex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import { useForkliftTranslation } from 'src/utils/i18n';

import { PageSection } from '@patternfly/react-core';

import { ConditionsSection, DetailsSection, ProvidersSection, Suspend } from '../../components';
import {
ConditionsSection,
DetailsSection,
MigrationsSection,
ProvidersSection,
Suspend,
} from '../../components';
import { PlanDetailsTabProps } from '../../PlanDetailsPage';

export const PlanDetails: React.FC<PlanDetailsTabProps> = ({ plan, loaded, loadError }) => {
Expand All @@ -22,6 +28,11 @@ export const PlanDetails: React.FC<PlanDetailsTabProps> = ({ plan, loaded, loadE
<ProvidersSection obj={plan} />
</PageSection>

<PageSection variant="light" className="forklift-page-section">
<SectionHeading text={t('Migrations')} />
<MigrationsSection obj={plan} />
</PageSection>

<PageSection variant="light" className="forklift-page-section">
<SectionHeading text={t('Conditions')} />
<ConditionsSection conditions={plan?.status?.conditions} />
Expand Down

0 comments on commit 3918e84

Please sign in to comment.