Skip to content

Commit

Permalink
Merge pull request #1159 from sgratch/add-openshift-ui-link
Browse files Browse the repository at this point in the history
🐾 Provide the OCP UI URL as part of the remote OCP provider detais page
  • Loading branch information
yaacov authored May 22, 2024
2 parents ff777ab + 40c12b3 commit 89f3c99
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"Issuer": "Issuer",
"Kubernetes name of the new migration Plan resource": "Kubernetes name of the new migration Plan resource",
"Label": "Label",
"Link for OpenShift Virtualization web console UI. For example, https://console-openshift-console.apps.openshift-domain.com.": "Link for OpenShift Virtualization web console UI. For example, https://console-openshift-console.apps.openshift-domain.com.",
"Link for the OpenStack dashboard. For example, https://identity_service.com/dashboard.": "Link for the OpenStack dashboard. For example, https://identity_service.com/dashboard.",
"Link for the Red Hat Virtualization Manager landing page. For example, https://rhv-host-example.com/ovirt-engine.": "Link for the Red Hat Virtualization Manager landing page. For example, https://rhv-host-example.com/ovirt-engine.",
"Link for the VMware vSphere UI. For example, https://vSphere-host-example.com/ui.": "Link for the VMware vSphere UI. For example, https://vSphere-host-example.com/ui.",
Expand Down Expand Up @@ -296,6 +297,7 @@
"Number of virtual machines in OVA files": "Number of virtual machines in OVA files",
"Off": "Off",
"On": "On",
"OpenShift web console UI": "OpenShift web console UI",
"OpenStack application credential ID needed for the application credential authentication.": "OpenStack application credential ID needed for the application credential authentication.",
"OpenStack application credential name needed for application credential authentication.": "OpenStack application credential name needed for application credential authentication.",
"OpenStack application credential Secret needed for the application credential authentication.": "OpenStack application credential Secret needed for the application credential authentication.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { K8sModel } from '@openshift-console/dynamic-plugin-sdk/lib/api/core-api

import { EditModalProps } from '../EditModal';

import { OpenshiftEditUIModal } from './OpenshiftEditUIModal';
import { OpenstackEditUIModal } from './OpenstackEditUIModal';
import { OvirtEditUIModal } from './OvirtEditUIModal';
import { VSphereEditUIModal } from './VSphereEditUIModal';
Expand All @@ -28,6 +29,7 @@ export const EditProviderUIModal: React.FC<EditProviderUIModalProps> = (props) =
case 'ovirt':
return <OvirtEditUIModal {...props} />;
case 'openshift':
return <OpenshiftEditUIModal {...props} />;
case 'openstack':
return <OpenstackEditUIModal {...props} />;
default:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import { ForkliftTrans, useForkliftTranslation } from 'src/utils/i18n';

import { ProviderModel } from '@kubev2v/types';
import { ModalVariant } from '@patternfly/react-core';

import { validateOpenshiftUILink } from '../../utils';
import { EditModal } from '../EditModal';

import { patchProviderUI } from './utils/patchProviderUI';
import { EditProviderUIModalProps } from './EditProviderUIModal';

export const OpenshiftEditUIModal: React.FC<EditProviderUIModalProps> = (props) => {
const { t } = useForkliftTranslation();

const ModalBody = (
<ForkliftTrans>
<p>Link for the OpenShift Virtualization web console UI.</p>
<p>
Use this link to access the user interface for the provider&apos;s virtualization
management.
</p>
<p>If no link value is specify then a default auto calculated or an empty value is set.</p>
</ForkliftTrans>
);

return (
<EditModal
{...props}
jsonPath={['metadata', 'annotations', 'forklift.konveyor.io/providerUI']}
title={props?.title || t('Edit provider web UI link')}
label={props?.label || t('Provider web UI link')}
model={ProviderModel}
variant={ModalVariant.large}
body={ModalBody}
helperText={t(
'Link for OpenShift Virtualization web console UI. For example, https://console-openshift-console.apps.openshift-domain.com.',
)}
onConfirmHook={patchProviderUI}
validationHook={validateOpenshiftUILink}
/>
);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @index('./*.tsx', f => `export * from '${f.path}';`)
export * from './EditProviderUIModal';
export * from './OpenshiftEditUIModal';
export * from './OpenstackEditUIModal';
export * from './OvirtEditUIModal';
export * from './VSphereEditUIModal';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
export * from './openshiftProviderValidator';
export * from './openshiftSecretFieldValidator';
export * from './openshiftSecretValidator';
export * from './validateOpenshiftUILink';
export * from './validateOpenshiftURL';
// @endindex
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { validateURL, ValidationMsg } from '../../common';

export const validateOpenshiftUILink = (uiLink: string | number): ValidationMsg => {
// For a newly opened form where the field is not set yet, set the validation type to default.
if (uiLink === undefined) {
return {
type: 'default',
msg: 'The link for OpenShift Virtualization web console UI. For example, https://console-openshift-console.apps.openshift-domain.com.',
};
}

// Sanity check
if (typeof uiLink !== 'string') {
return {
type: 'error',
msg: 'The link for the OpenShift Virtualization web console UI is not a string',
};
}

const trimmedUrl: string = uiLink.trim();
const isValidURL = validateURL(trimmedUrl);

if (trimmedUrl === '') {
return {
type: 'warning',
msg: 'The link for the OpenShift Virtualization web console UI is empty. A default or an empty value will be used.',
};
}

if (!isValidURL) {
return {
type: 'error',
msg: 'The link for the OpenShift Virtualization web console UI invalid. It should include the schema and path, for example: https://console-openshift-console.apps.openshift-domain.com.',
};
}

return {
type: 'success',
msg: 'The link for OpenShift Virtualization web console UI. For example, https://console-openshift-console.apps.openshift-domain.com.',
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { DetailsItem } from '../../../../utils';
import {
CreatedAtDetailsItem,
CredentialsDetailsItem,
ExternalManagementLinkDetailsItem,
NameDetailsItem,
NamespaceDetailsItem,
OwnerDetailsItem,
Expand All @@ -16,11 +17,13 @@ import {
URLDetailsItem,
} from './components';
import { DetailsSectionProps } from './DetailsSection';
import { getOpenshiftProviderWebUILink } from './utils';

export const OpenshiftDetailsSection: React.FC<DetailsSectionProps> = ({ data }) => {
const { t } = useForkliftTranslation();

const { provider, permissions } = data;
const webUILink = getOpenshiftProviderWebUILink(provider);

return (
<DescriptionList
Expand All @@ -30,7 +33,17 @@ export const OpenshiftDetailsSection: React.FC<DetailsSectionProps> = ({ data })
>
<TypeDetailsItem resource={provider} />

<DetailsItem title={''} content={''} />
{/* Avoid displaying the external web ui link for the local cluster */}
{provider?.spec?.url ? (
<ExternalManagementLinkDetailsItem
resource={provider}
canPatch={permissions.canPatch}
webUILinkText={t(`OpenShift web console UI`)}
webUILink={webUILink}
/>
) : (
<DetailsItem title={''} content={''} />
)}

<NameDetailsItem resource={provider} />

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { V1beta1Provider } from '@kubev2v/types';

import { getProviderUIAnnotation } from './getProviderUIAnnotation';

/**
* A function for auto calculating the Openshift UI link.
* It extracts the provider's Openshift UI link, E.g. https://console-openshift-console.apps.example.com
* from the Openshift URL, E.g. https://api.example.com:6443
*
* returns the calculated web ui link or an empty string if calculation is avoided
*/
export const getOpenshiftProviderWebUILink = (provider: V1beta1Provider): string => {
// Check for custom link
const customLink = getProviderUIAnnotation(provider);
if (customLink) {
return customLink;
}

const url = provider?.spec?.url;
if (!url) {
return '';
}
const urlObj = new URL(url);

// remove the port
urlObj.port = '';

// replace the host prefix of 'api.' with 'console-openshift-console.apps.'
if (urlObj.host.startsWith('api.')) {
const newHostName = 'console-openshift-console.apps.' + urlObj.host.slice(4);
urlObj.host = newHostName;

return urlObj.toString();
} else {
return '';
}
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// @index(['./*', /style/g], f => `export * from '${f.path}';`)
export * from './getOpenshiftProviderWebUILink';
export * from './getOpenstackProviderWebUILink';
export * from './getOvirtProviderWebUILink';
export * from './getProviderUIAnnotation';
Expand Down

0 comments on commit 89f3c99

Please sign in to comment.