Skip to content

Commit

Permalink
Add virtctl to overview
Browse files Browse the repository at this point in the history
  • Loading branch information
pcbailey committed Jul 11, 2022
1 parent a2ceb64 commit b6b8ac2
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 18 deletions.
11 changes: 11 additions & 0 deletions console-extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@
}
}
},
{
"type": "console.flag/model",
"properties": {
"flag": "CONSOLE_CLI_DOWNLOAD",
"model": {
"group": "console.openshift.io",
"version": "v1",
"kind": "ConsoleCLIDownload"
}
}
},
{
"type": "console.navigation/section",
"properties": {
Expand Down
3 changes: 3 additions & 0 deletions locales/en/plugin__kubevirt-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@
"Documentation": "Documentation",
"Domain": "Domain",
"Download the MSI from ": "Download the MSI from ",
"Download the virtctl command-line utility": "Download the virtctl command-line utility",
"Download virtctl": "Download virtctl",
"Drag and drop an image or upload one": "Drag and drop an image or upload one",
"Drive": "Drive",
"Drivers": "Drivers",
Expand Down Expand Up @@ -732,6 +734,7 @@
"The following information regarding how the disks are partitioned is provided by the guest agent.": "The following information regarding how the disks are partitioned is provided by the guest agent.",
"The following resources will be deleted along with this VirtualMachine. Unchecked items will not be deleted.": "The following resources will be deleted along with this VirtualMachine. Unchecked items will not be deleted.",
"The guest OS needs to have the cloud-init service running.": "The guest OS needs to have the cloud-init service running.",
"The virtctl client is a supplemental command-line utility for managing virtualization resources from the command line.": "The virtctl client is a supplemental command-line utility for managing virtualization resources from the command line.",
"The VirtualMachine {{vmName}} is still running. It will be powered off while cloning.": "The VirtualMachine {{vmName}} is still running. It will be powered off while cloning.",
"The VirtualMachine will be bridged to the selected network, ideal for L2 devices": "The VirtualMachine will be bridged to the selected network, ideal for L2 devices",
"The VirtualMachine you are creating does not have an available boot source. We recommended that you select a boot source to create the VirtualMachine.": "The VirtualMachine you are creating does not have an available boot source. We recommended that you select a boot source to create the VirtualMachine.",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
},
"devDependencies": {
"@cypress/webpack-preprocessor": "^5.11.0",
"@kubevirt-ui/kubevirt-api": "^0.0.44",
"@kubevirt-ui/kubevirt-api": "^0.0.45",
"@openshift-console/dynamic-plugin-sdk": "0.0.11",
"@openshift-console/dynamic-plugin-sdk-internal": "0.0.10",
"@openshift-console/dynamic-plugin-sdk-webpack": "0.0.7",
Expand Down
1 change: 1 addition & 0 deletions src/utils/flags/consts.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const FLAG_KUBEVIRT_DYNAMIC = 'KUBEVIRT_DYNAMIC';
export const FLAG_KUBEVIRT_CDI = 'KUBEVIRT_CDI';
export const FLAG_CONSOLE_CLI_DOWNLOAD = 'CONSOLE_CLI_DOWNLOAD';
10 changes: 8 additions & 2 deletions src/views/clusteroverview/ClusterOverviewPage.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import * as React from 'react';
import { Helmet } from 'react-helmet';

import { FLAG_CONSOLE_CLI_DOWNLOAD } from '@kubevirt-utils/flags/consts';
import { useIsAdmin } from '@kubevirt-utils/hooks/useIsAdmin';
import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
import { HorizontalNav, NavPage } from '@openshift-console/dynamic-plugin-sdk';
import { HorizontalNav, NavPage, useFlag } from '@openshift-console/dynamic-plugin-sdk';

import MonitoringTab from './MonitoringTab/MonitoringTab';
import OverviewTab from './OverviewTab/OverviewTab';
import SettingsTab from './SettingsTab/SettingsTab';
import { KUBEVIRT_QUICK_START_USER_SETTINGS_KEY } from './utils/constants';
import PageHeader from './utils/PageHeader';
import RestoreGettingStartedButton from './utils/RestoreGettingStartedButton';
import VirtctlPopup from './utils/VirtctlPopup';

const ClusterOverviewPage: React.FC = () => {
const { t } = useKubevirtTranslation();
const title = t('Virtualization');
const isAdmin = useIsAdmin();
const hasConsoleTools = useFlag(FLAG_CONSOLE_CLI_DOWNLOAD);

const badge = (
<RestoreGettingStartedButton userSettingsKey={KUBEVIRT_QUICK_START_USER_SETTINGS_KEY} />
);
Expand Down Expand Up @@ -43,7 +47,9 @@ const ClusterOverviewPage: React.FC = () => {
<Helmet>
<title>{title}</title>
</Helmet>
<PageHeader title={title} badge={badge} />
<PageHeader title={title} badge={badge}>
{hasConsoleTools && <VirtctlPopup />}
</PageHeader>
{isAdmin ? <HorizontalNav pages={overviewTabs} /> : <OverviewTab />}
</>
);
Expand Down
29 changes: 18 additions & 11 deletions src/views/clusteroverview/utils/PageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,26 @@ import * as React from 'react';
type PageHeaderProps = {
badge?: React.ReactNode;
title?: string | JSX.Element;
children?: React.ReactNode;
};

const PageHeader: React.FC<PageHeaderProps> = ({ badge, title }) => (
<div className="co-m-nav-title">
<h1 className="co-m-pane__heading">
<div className="co-m-pane__name co-resource-item">
<span data-test-id="resource-title" className="co-resource-item__resource-name">
{title}
const PageHeader: React.FC<PageHeaderProps> = (props) => {
const { badge, title, children } = props;
return (
<div className="co-m-nav-title">
<h1 className="co-m-pane__heading">
<div className="co-m-pane__name co-resource-item">
<span data-test-id="resource-title" className="co-resource-item__resource-name">
{title}
</span>
</div>
<span>
{children}
<span className="co-m-pane__heading-badge">{badge}</span>
</span>
</div>
<span className="co-m-pane__heading-badge">{badge}</span>
</h1>
</div>
);
</h1>
</div>
);
};

export default PageHeader;
9 changes: 9 additions & 0 deletions src/views/clusteroverview/utils/VirtctlPopup.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.virtctl-popup {
&__body--message {
margin-bottom: var(--pf-global--spacer--md);
}

&__button {
padding-right: 0;
}
}
66 changes: 66 additions & 0 deletions src/views/clusteroverview/utils/VirtctlPopup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as React from 'react';

import { ConsoleCLIDownloadModelGroupVersionKind } from '@kubevirt-ui/kubevirt-api/console';
import ExternalLink from '@kubevirt-utils/components/ExternalLink/ExternalLink';
import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
import { Button, Popover, PopoverPosition } from '@patternfly/react-core';

import { VIRTCTL_DOWNLOADS } from './constants';
import { K8sResourceKind } from './types';

import './VirtctlPopup.scss';

const VirtctlPopup: React.FC = () => {
const { t } = useKubevirtTranslation();
const [cliTools] = useK8sWatchResource<K8sResourceKind>({
groupVersionKind: ConsoleCLIDownloadModelGroupVersionKind,
isList: true,
namespaced: false,
});

const tools = Array.isArray(cliTools) ? cliTools : [cliTools];
const virtctlObj = tools?.find((tool) => tool?.metadata?.name === VIRTCTL_DOWNLOADS);

const { displayName, links } = virtctlObj?.spec || {};

const bodyContent = (
<>
<div className="virtctl-popup__body--message">
{t(
'The virtctl client is a supplemental command-line utility for managing virtualization resources from the command line.',
)}
</div>
<div>
{links?.length > 1 && (
<ul>
{links.map((link) => (
<li key={`${link?.text}-${link?.href}`}>
<ExternalLink href={link?.href} text={link?.text || displayName} />
</li>
))}
</ul>
)}
</div>
</>
);

return (
<Popover
position={PopoverPosition.left}
headerContent={<>{t('Download the virtctl command-line utility')}</>}
bodyContent={bodyContent}
maxWidth="350px"
>
<Button
id="virtctl-download-links"
className="pf-m-link--align-left virtctl-popup__button"
variant="link"
>
{t('Download virtctl')}
</Button>
</Popover>
);
};

export default VirtctlPopup;
2 changes: 2 additions & 0 deletions src/views/clusteroverview/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ export enum GETTING_STARTED_SHOW_STATE {
}

export const KUBEVIRT_QUICK_START_USER_SETTINGS_KEY = 'kubevirt.quickstart';

export const VIRTCTL_DOWNLOADS = 'virtctl-clidownloads-kubevirt-hyperconverged';
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -643,10 +643,10 @@
resolved "https://registry.yarnpkg.com/@kubevirt-ui/kubevirt-api/-/kubevirt-api-0.0.35.tgz#9a567ea287b647cd37a47d70b87fbd75d4994a89"
integrity sha512-3S374M9I8nHP+9lnBhL+Z3gMVssNk4vyK7uPI3lkAjal/X6zjR0+E9fWQEPv36K45KxRoUX9w/4pMGWQvVlDcQ==

"@kubevirt-ui/kubevirt-api@^0.0.44":
version "0.0.44"
resolved "https://registry.yarnpkg.com/@kubevirt-ui/kubevirt-api/-/kubevirt-api-0.0.44.tgz#79e2ddb65ed67fde5f103b7ffd983aa0b3449c80"
integrity sha512-Z2whpwLKUJdvXysFm/5qtplKeCeMORY0dEXLFTjT2JVDl6voq2D24vX/cm/Q5G1m3ze0HHXH0kGcnnhWt2oyVA==
"@kubevirt-ui/kubevirt-api@^0.0.45":
version "0.0.45"
resolved "https://registry.yarnpkg.com/@kubevirt-ui/kubevirt-api/-/kubevirt-api-0.0.45.tgz#582d968dd464329bfcae4643b4a3f84f6864392c"
integrity sha512-12Wsff9cMuzesYzx2BbuGdE9hW98F6DxrN09RUZf75gds/2tmfNm2qnUjNDwN1yn1lm6Iq7FWEx2cK3pJ629jw==

"@leichtgewicht/ip-codec@^2.0.1":
version "2.0.4"
Expand Down

0 comments on commit b6b8ac2

Please sign in to comment.