diff --git a/frontend/packages/console-shared/src/components/status/GenericStatus.tsx b/frontend/packages/console-shared/src/components/status/GenericStatus.tsx index 100f93a653f..142cdedd4e8 100644 --- a/frontend/packages/console-shared/src/components/status/GenericStatus.tsx +++ b/frontend/packages/console-shared/src/components/status/GenericStatus.tsx @@ -5,8 +5,8 @@ import StatusIconAndText from './StatusIconAndText'; const GenericStatus: React.FC = (props) => { const { Icon, children, ...restProps } = props; - return children ? ( - }> + return React.Children.toArray(children).length ? ( + } />}> {children} ) : ( diff --git a/frontend/packages/console-shared/src/components/status/PopoverStatus.tsx b/frontend/packages/console-shared/src/components/status/PopoverStatus.tsx index a5730de30ff..cb384aa64e1 100644 --- a/frontend/packages/console-shared/src/components/status/PopoverStatus.tsx +++ b/frontend/packages/console-shared/src/components/status/PopoverStatus.tsx @@ -1,22 +1,17 @@ import * as React from 'react'; import { Button, Popover, PopoverPosition } from '@patternfly/react-core'; import { Instance as TippyInstance } from 'tippy.js'; -import StatusIconAndText from './StatusIconAndText'; const PopoverStatus: React.FC = ({ - title, hideHeader, - icon, - activeIcon, children, isVisible = null, shouldClose = null, - ...other + statusBody, + title, + onHide, + onShow, }) => { - const [isActive, setActive] = React.useState(false); - const onHide = React.useCallback(() => setActive(false), [setActive]); - const onShow = React.useCallback(() => setActive(true), [setActive]); - return ( = ({ shouldClose={shouldClose} > ); }; -type PopoverStatusProps = React.ComponentProps & { - activeIcon?: React.ReactElement; +type PopoverStatusProps = { + statusBody: React.ReactNode; + onHide?: () => void; + onShow?: () => void; + title?: string; hideHeader?: boolean; isVisible?: boolean; shouldClose?: (tip: TippyInstance) => void; diff --git a/frontend/packages/console-shared/src/components/status/statuses.tsx b/frontend/packages/console-shared/src/components/status/statuses.tsx index 2e99365c00e..5e1b87ff304 100644 --- a/frontend/packages/console-shared/src/components/status/statuses.tsx +++ b/frontend/packages/console-shared/src/components/status/statuses.tsx @@ -1,9 +1,10 @@ import * as React from 'react'; -import { InfoCircleIcon, HourglassHalfIcon, InProgressIcon } from '@patternfly/react-icons'; +import { HourglassHalfIcon, InProgressIcon } from '@patternfly/react-icons'; import { RedExclamationCircleIcon, GreenCheckCircleIcon, YellowExclamationTriangleIcon, + BlueInfoCircleIcon, } from './icons'; import GenericStatus from './GenericStatus'; import { StatusComponentProps } from './types'; @@ -14,7 +15,7 @@ export const ErrorStatus: React.FC = (props) => ( ErrorStatus.displayName = 'ErrorStatus'; export const InfoStatus: React.FC = (props) => ( - + ); InfoStatus.displayName = 'InfoStatus'; diff --git a/frontend/packages/kubevirt-plugin/src/components/form/form-row.tsx b/frontend/packages/kubevirt-plugin/src/components/form/form-row.tsx index dc2c33f01e5..09858df947b 100644 --- a/frontend/packages/kubevirt-plugin/src/components/form/form-row.tsx +++ b/frontend/packages/kubevirt-plugin/src/components/form/form-row.tsx @@ -1,8 +1,9 @@ import * as React from 'react'; import { FormGroup } from '@patternfly/react-core'; import { HelpIcon } from '@patternfly/react-icons'; +import * as classnames from 'classnames'; import { LoadingInline } from '@console/internal/components/utils'; -import { PopoverStatus, ValidationErrorType } from '@console/shared'; +import { PopoverStatus, ValidationErrorType, StatusIconAndText } from '@console/shared'; import './form-row.scss'; export const FormRow: React.FC = ({ @@ -18,6 +19,9 @@ export const FormRow: React.FC = ({ children, className, }) => { + const [isActive, setActive] = React.useState(false); + const onHide = React.useCallback(() => setActive(false), [setActive]); + const onShow = React.useCallback(() => setActive(true), [setActive]); if (isHidden) { return null; } @@ -39,11 +43,21 @@ export const FormRow: React.FC = ({ {help && ( } - activeIcon={} title={`${fieldId} help`} - iconOnly hideHeader + onHide={onHide} + onShow={onShow} + statusBody={ + + } + /> + } > {help} diff --git a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostDetails.tsx b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostDetails.tsx index bcc2dd47919..87c93f60a28 100644 --- a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostDetails.tsx +++ b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostDetails.tsx @@ -23,6 +23,7 @@ import { StatusIconAndText, DetailPropertyList, DetailPropertyListItem, + SecondaryStatus, } from '@console/shared'; import { getHostStatus } from '../../status/host-status'; import { @@ -41,13 +42,14 @@ import { getHostProvisioningState, getHostBootMACAddress, isHostScheduledForRestart, + hasPowerManagement, } from '../../selectors'; import { BareMetalHostKind } from '../../types'; import { HOST_REGISTERING_STATES } from '../../constants/bare-metal-host'; import MachineLink from './MachineLink'; import BareMetalHostPowerStatusIcon from './BareMetalHostPowerStatusIcon'; import BareMetalHostStatus from './BareMetalHostStatus'; -import { HOST_SCHEDULED_FOR_RESTART } from './BareMetalHostSecondaryStatus'; +import { HOST_SCHEDULED_FOR_RESTART, HOST_NO_POWER_MGMT } from './BareMetalHostSecondaryStatus'; type BareMetalHostDetailsProps = { obj: BareMetalHostKind; @@ -147,15 +149,21 @@ const BareMetalHostDetails: React.FC = ({ <>
Power Status
- } - /> - {isHostScheduledForRestart(host) && ( - } - /> + {!hasPowerManagement(host) ? ( + + ) : ( + <> + } + /> + {isHostScheduledForRestart(host) && ( + } + /> + )} + )}
diff --git a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostSecondaryStatus.tsx b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostSecondaryStatus.tsx index ab28b55c838..e0f52d052c3 100644 --- a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostSecondaryStatus.tsx +++ b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostSecondaryStatus.tsx @@ -5,6 +5,7 @@ import { getHostPowerStatus, getHostProvisioningState, isHostScheduledForRestart, + hasPowerManagement, } from '../../selectors'; import { HOST_POWER_STATUS_POWERED_ON, HOST_REGISTERING_STATES } from '../../constants'; @@ -13,14 +14,17 @@ type BareMetalHostSecondaryStatusProps = { }; export const HOST_SCHEDULED_FOR_RESTART = 'Restart pending'; +export const HOST_NO_POWER_MGMT = 'No power management'; const BareMetalHostSecondaryStatus: React.FC = ({ host }) => { const powerStatus = getHostPowerStatus(host); const provisioningState = getHostProvisioningState(host); const status = []; - // don't show power status when host registration/inspection hasn't finished - if (!HOST_REGISTERING_STATES.includes(provisioningState)) { + if (!hasPowerManagement(host)) { + status.push(HOST_NO_POWER_MGMT); + // don't show power status when host registration/inspection hasn't finished + } else if (!HOST_REGISTERING_STATES.includes(provisioningState)) { if (isHostScheduledForRestart(host)) { status.push(HOST_SCHEDULED_FOR_RESTART); } diff --git a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostStatus.tsx b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostStatus.tsx index 7cee26ab2ab..3a404227e47 100644 --- a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostStatus.tsx +++ b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostStatus.tsx @@ -1,45 +1,45 @@ import * as React from 'react'; -import { Button } from 'patternfly-react'; -import { AddCircleOIcon } from '@patternfly/react-icons'; +import { Link } from 'react-router-dom'; +import { resourcePathFromModel } from '@console/internal/components/utils'; import { ProgressStatus, SuccessStatus, ErrorStatus, Status, - StatusIconAndText, - getNamespace, + PopoverStatus, + InfoStatus, } from '@console/shared'; -import { RequireCreatePermission } from '@console/internal/components/utils'; +import { K8sResourceKind } from '@console/internal/module/k8s'; import { - HOST_STATUS_DISCOVERED, HOST_PROGRESS_STATES, HOST_ERROR_STATES, HOST_SUCCESS_STATES, NODE_STATUS_UNDER_MAINTENANCE, NODE_STATUS_STARTING_MAINTENANCE, NODE_STATUS_STOPPING_MAINTENANCE, + HOST_STATUS_UNMANAGED, + HOST_INFO_STATES, } from '../../constants'; -import { BareMetalHostModel } from '../../models'; import { getHostErrorMessage } from '../../selectors'; import { StatusProps } from '../types'; import MaintenancePopover from '../maintenance/MaintenancePopover'; import { BareMetalHostKind } from '../../types'; -import { K8sResourceKind } from '@console/internal/module/k8s'; - -// TODO(jtomasek): Update this with onClick handler once add discovered host functionality -// is available -export const AddDiscoveredHostButton: React.FC<{ host: BareMetalHostKind }> = ( - { host }, // eslint-disable-line @typescript-eslint/no-unused-vars -) => { - const namespace = getNamespace(host); +import { BareMetalHostModel } from '../../models'; - return ( - - - - ); +export const HOST_STATUS_ACTIONS = { + [HOST_STATUS_UNMANAGED]: (host: BareMetalHostKind) => ( +

+ + Add credentials + +

+ ), }; const BareMetalHostStatus: React.FC = ({ @@ -50,24 +50,51 @@ const BareMetalHostStatus: React.FC = ({ nodeMaintenance, }) => { const statusTitle = title || status; + const action = HOST_STATUS_ACTIONS[status]?.(host); switch (true) { - case status === HOST_STATUS_DISCOVERED: - return ; case [NODE_STATUS_STARTING_MAINTENANCE, NODE_STATUS_UNDER_MAINTENANCE].includes(status): return ; case [NODE_STATUS_STOPPING_MAINTENANCE, ...HOST_PROGRESS_STATES].includes(status): - return {description}; + return ( + + {description} + {action} + + ); case HOST_ERROR_STATES.includes(status): return (

{description}

{getHostErrorMessage(host)}

+ {action}
); case HOST_SUCCESS_STATES.includes(status): - return {description}; - default: - return ; + return ( + + {description} + {action} + + ); + case HOST_INFO_STATES.includes(status): + return ( + + {description} + {action} + + ); + default: { + const statusBody = ; + + return description || action ? ( + + {description} + {action} + + ) : ( + statusBody + ); + } } }; diff --git a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/dashboard/DetailsCard.tsx b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/dashboard/DetailsCard.tsx index ae160731fdf..2b70c960949 100644 --- a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/dashboard/DetailsCard.tsx +++ b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/dashboard/DetailsCard.tsx @@ -6,10 +6,6 @@ import DashboardCardTitle from '@console/shared/src/components/dashboard/dashboa import DetailsBody from '@console/shared/src/components/dashboard/details-card/DetailsBody'; import DetailItem from '@console/shared/src/components/dashboard/details-card/DetailItem'; import DashboardCardLink from '@console/shared/src/components/dashboard/dashboard-card/DashboardCardLink'; -import { - DashboardItemProps, - withDashboardResources, -} from '@console/internal/components/dashboard/with-dashboard-resources'; import { getName, getNamespace } from '@console/shared'; import { MachineKind, NodeKind } from '@console/internal/module/k8s'; import { resourcePathFromModel } from '@console/internal/components/utils'; @@ -56,9 +52,9 @@ const DetailsCard: React.FC = () => { ); }; -export default withDashboardResources(DetailsCard); +export default DetailsCard; -type DetailsCardProps = DashboardItemProps & { +type DetailsCardProps = { obj: BareMetalHostKind; machines: MachineKind[]; nodes: NodeKind[]; diff --git a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/dashboard/StatusCard.tsx b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/dashboard/StatusCard.tsx index 9bfa4a7729e..4c44dc5671a 100644 --- a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/dashboard/StatusCard.tsx +++ b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/dashboard/StatusCard.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import * as _ from 'lodash'; import { Gallery, GalleryItem } from '@patternfly/react-core'; +import { Link } from 'react-router-dom'; import { DashboardItemProps, withDashboardResources, @@ -13,18 +14,26 @@ import HealthBody from '@console/shared/src/components/dashboard/status-card/Hea import HealthItem from '@console/shared/src/components/dashboard/status-card/HealthItem'; import { HealthState } from '@console/shared/src/components/dashboard/status-card/states'; import AlertsBody from '@console/shared/src/components/dashboard/status-card/AlertsBody'; -import AlertItem from '@console/shared/src/components/dashboard/status-card/AlertItem'; import { Alert } from '@console/internal/components/monitoring/types'; import { alertURL } from '@console/internal/components/monitoring/utils'; +import { BlueInfoCircleIcon } from '@console/shared'; +import AlertItem, { + StatusItem, +} from '@console/shared/src/components/dashboard/status-card/AlertItem'; +import { resourcePathFromModel } from '@console/internal/components/utils'; import { getBareMetalHostStatus } from '../../../status/host-status'; import { + HOST_STATUS_DESCRIPTIONS, HOST_SUCCESS_STATES, HOST_ERROR_STATES, HOST_PROGRESS_STATES, HOST_HARDWARE_ERROR_STATES, + HOST_STATUS_UNMANAGED, } from '../../../constants'; import { BareMetalHostKind } from '../../../types'; import { BareMetalHostDashboardContext } from './BareMetalHostDashboardContext'; +import { BareMetalHostModel } from '../../../models'; +import { hasPowerManagement } from '../../../selectors'; const getHostHealthState = (obj: BareMetalHostKind): HostHealthState => { const { status, title } = getBareMetalHostStatus(obj); @@ -92,7 +101,7 @@ const HealthCard: React.FC = ({ - + @@ -100,6 +109,22 @@ const HealthCard: React.FC = ({ + {!hasPowerManagement(obj) && ( + + + Add credentials + + + )} {loaded && alerts.length !== 0 ? alerts.map((alert) => ( diff --git a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/host-menu-actions.tsx b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/host-menu-actions.tsx index 35845a0ad62..1591dbfcc81 100644 --- a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/host-menu-actions.tsx +++ b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/host-menu-actions.tsx @@ -22,6 +22,7 @@ import { getHostMachine, getHostPowerStatus, isHostScheduledForRestart, + hasPowerManagement, } from '../../selectors'; import { BareMetalHostModel, NodeMaintenanceModel } from '../../models'; import { getHostStatus } from '../../status/host-status'; @@ -31,7 +32,7 @@ import { HOST_POWER_STATUS_POWERING_OFF, HOST_POWER_STATUS_POWERING_ON, HOST_STATUS_AVAILABLE, - HOST_STATUS_DISCOVERED, + HOST_STATUS_UNMANAGED, HOST_STATUS_READY, HOST_ERROR_STATES, HOST_STATUS_UNKNOWN, @@ -85,9 +86,10 @@ export const RemoveNodeMaintenance = ( export const PowerOn = (kindObj: K8sKind, host: BareMetalHostKind): KebabOption => { const title = 'Power On'; return { - hidden: [HOST_POWER_STATUS_POWERED_ON, HOST_POWER_STATUS_POWERING_ON].includes( - getHostPowerStatus(host), - ), + hidden: + [HOST_POWER_STATUS_POWERED_ON, HOST_POWER_STATUS_POWERING_ON].includes( + getHostPowerStatus(host), + ) || !hasPowerManagement(host), label: title, callback: () => { k8sPatch(BareMetalHostModel, host, [{ op: 'replace', path: '/spec/online', value: true }]); @@ -132,9 +134,10 @@ export const PowerOff = ( host: BareMetalHostKind, { nodeName, status }: ActionArgs, ) => ({ - hidden: [HOST_POWER_STATUS_POWERED_OFF, HOST_POWER_STATUS_POWERING_OFF].includes( - getHostPowerStatus(host), - ), + hidden: + [HOST_POWER_STATUS_POWERED_OFF, HOST_POWER_STATUS_POWERING_OFF].includes( + getHostPowerStatus(host), + ) || !hasPowerManagement(host), label: 'Power Off', callback: () => powerOffHostModal({ host, nodeName, status }), accessReview: host && asAccessReview(BareMetalHostModel, host, 'update'), @@ -144,7 +147,9 @@ export const Restart = (kindObj: K8sKind, host: BareMetalHostKind, { nodeName }: hidden: [HOST_POWER_STATUS_POWERED_OFF, HOST_POWER_STATUS_POWERING_OFF].includes( getHostPowerStatus(host), - ) || isHostScheduledForRestart(host), + ) || + isHostScheduledForRestart(host) || + !hasPowerManagement(host), label: 'Restart', callback: () => restartHostModal({ host, nodeName }), accessReview: host && asAccessReview(BareMetalHostModel, host, 'update'), @@ -161,7 +166,7 @@ export const Delete = ( HOST_STATUS_UNKNOWN, HOST_STATUS_READY, HOST_STATUS_AVAILABLE, - HOST_STATUS_DISCOVERED, + HOST_STATUS_UNMANAGED, ...HOST_ERROR_STATES, ].includes(status.status), label: title, diff --git a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/table-filters.ts b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/table-filters.ts index c8dcb0d8308..de7e8584c58 100644 --- a/frontend/packages/metal3-plugin/src/components/baremetal-hosts/table-filters.ts +++ b/frontend/packages/metal3-plugin/src/components/baremetal-hosts/table-filters.ts @@ -10,6 +10,7 @@ import { HOST_STATUS_EXTERNALLY_PROVISIONED, NODE_STATUS_TITLES, HOST_STATUS_AVAILABLE, + HOST_STATUS_UNMANAGED, } from '../../constants'; import { BareMetalHostBundle } from '../types'; @@ -38,6 +39,10 @@ const hostStatesToFilterMap = Object.freeze({ title: 'Maintenance', states: Object.keys(NODE_STATUS_TITLES), }, + unmanaged: { + title: 'Unmanaged', + states: [HOST_STATUS_UNMANAGED], + }, other: { title: 'Other', states: Object.keys(HOST_STATUS_TITLES), diff --git a/frontend/packages/metal3-plugin/src/components/maintenance/MaintenancePopover.tsx b/frontend/packages/metal3-plugin/src/components/maintenance/MaintenancePopover.tsx index 13a00878ab4..c8a454b7e91 100644 --- a/frontend/packages/metal3-plugin/src/components/maintenance/MaintenancePopover.tsx +++ b/frontend/packages/metal3-plugin/src/components/maintenance/MaintenancePopover.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { K8sResourceKind } from '@console/internal/module/k8s'; -import { PopoverStatus } from '@console/shared'; +import { PopoverStatus, StatusIconAndText } from '@console/shared'; import { InProgressIcon, MaintenanceIcon } from '@patternfly/react-icons'; import { getNodeMaintenancePhase } from '../../selectors'; import UnderMaintenancePopoverContent from './UnderMaintenancePopoverContent'; @@ -16,20 +16,27 @@ const MaintenancePopover: React.FC = ({ title, nodeMaintenance, className, + children, }) => { const phase = getNodeMaintenancePhase(nodeMaintenance); return ( : } title={title} - className={className} + statusBody={ + : } + className={className} + /> + } > {phase === 'Succeeded' ? ( ) : ( )} + {children} ); }; diff --git a/frontend/packages/metal3-plugin/src/constants/bare-metal-host.ts b/frontend/packages/metal3-plugin/src/constants/bare-metal-host.ts index 787d7545118..8e215a807c5 100644 --- a/frontend/packages/metal3-plugin/src/constants/bare-metal-host.ts +++ b/frontend/packages/metal3-plugin/src/constants/bare-metal-host.ts @@ -2,7 +2,7 @@ // once 'ready' status is replaced with 'available' in BMO export const HOST_STATUS_READY = 'ready'; export const HOST_STATUS_AVAILABLE = 'available'; -export const HOST_STATUS_DISCOVERED = 'discovered'; +export const HOST_STATUS_UNMANAGED = 'unmanaged'; export const HOST_STATUS_OK = 'OK'; export const HOST_STATUS_ERROR = 'error'; export const HOST_STATUS_UNKNOWN = 'Unknown'; @@ -28,7 +28,6 @@ export const HOST_POWER_STATUS_POWERING_ON = 'Powering on'; export const HOST_STATUS_TITLES = { [HOST_STATUS_READY]: 'Available', [HOST_STATUS_AVAILABLE]: 'Available', - [HOST_STATUS_DISCOVERED]: 'Discovered', [HOST_STATUS_OK]: 'OK', [HOST_STATUS_ERROR]: 'Error', [HOST_STATUS_PROVISIONED]: 'Provisioned', @@ -45,6 +44,7 @@ export const HOST_STATUS_TITLES = { [HOST_STATUS_MATCH_PROFILE]: 'Matching profile', [HOST_STATUS_DELETING]: 'Deleting', [HOST_STATUS_UNKNOWN]: 'Unknown', + [HOST_STATUS_UNMANAGED]: 'Unmanaged', }; export const HOST_STATUS_DESCRIPTIONS = { @@ -62,6 +62,10 @@ export const HOST_STATUS_DESCRIPTIONS = { [HOST_STATUS_PROVISIONING_ERROR]: 'The image could not be written to the host.', [HOST_STATUS_POWER_MANAGEMENT_ERROR]: 'An error was found while trying to power the host either on or off.', + [HOST_STATUS_EXTERNALLY_PROVISIONED]: + 'This host was provisioned outside of this cluster and added manually.', + [HOST_STATUS_UNMANAGED]: + 'Power operations cannot be performed on this host until Baseboard Management Controller (BMC) credentials are provided.', }; export const HOST_REGISTERING_STATES = [ @@ -94,13 +98,14 @@ export const HOST_PROGRESS_STATES = [ export const HOST_SUCCESS_STATES = [ HOST_STATUS_READY, HOST_STATUS_AVAILABLE, - HOST_STATUS_DISCOVERED, HOST_STATUS_OK, HOST_STATUS_PROVISIONED, HOST_STATUS_EXTERNALLY_PROVISIONED, HOST_STATUS_DEPROVISIONED, ]; +export const HOST_INFO_STATES = [HOST_STATUS_UNMANAGED]; + export const HOST_HARDWARE_ERROR_STATES = [HOST_STATUS_POWER_MANAGEMENT_ERROR]; export const HOST_HEALTH_OK = 'Host is healthy'; diff --git a/frontend/packages/metal3-plugin/src/plugin.tsx b/frontend/packages/metal3-plugin/src/plugin.tsx index 793dfe4e854..23f2529d442 100644 --- a/frontend/packages/metal3-plugin/src/plugin.tsx +++ b/frontend/packages/metal3-plugin/src/plugin.tsx @@ -24,7 +24,7 @@ import { formatNamespacedRouteForResource } from '@console/shared/src/utils/name import { BareMetalHostModel, NodeMaintenanceModel } from './models'; import { getBMHStatusGroups } from './components/baremetal-hosts/dashboard/utils'; import { getBMNStatusGroups } from './components/baremetal-nodes/dashboard/utils'; -import { getHostPowerStatus } from './selectors'; +import { getHostPowerStatus, hasPowerManagement } from './selectors'; import { HOST_POWER_STATUS_POWERING_OFF, HOST_POWER_STATUS_POWERING_ON } from './constants'; import { BareMetalHostKind } from './types'; import { detectBaremetalPlatform, BAREMETAL_FLAG, NODE_MAINTENANCE_FLAG } from './features'; @@ -243,7 +243,7 @@ const plugin: Plugin = [ isActivity: (resource: BareMetalHostKind) => [HOST_POWER_STATUS_POWERING_OFF, HOST_POWER_STATUS_POWERING_ON].includes( getHostPowerStatus(resource), - ), + ) && hasPowerManagement(resource), loader: () => import( './components/baremetal-hosts/dashboard/BareMetalStatusActivity' /* webpackChunkName: "metal3-powering" */ diff --git a/frontend/packages/metal3-plugin/src/selectors/baremetal-hosts.ts b/frontend/packages/metal3-plugin/src/selectors/baremetal-hosts.ts index 58a1275978e..29a4dd6fdd2 100644 --- a/frontend/packages/metal3-plugin/src/selectors/baremetal-hosts.ts +++ b/frontend/packages/metal3-plugin/src/selectors/baremetal-hosts.ts @@ -14,6 +14,7 @@ import { HOST_POWER_STATUS_POWERING_OFF, HOST_POWER_STATUS_POWERING_ON, HOST_POWER_STATUS_POWERED_OFF, + HOST_STATUS_UNMANAGED, } from '../constants'; const ANNOTATION_HOST_RESTART = 'reboot.metal3.io'; @@ -76,3 +77,6 @@ export const getHostMachine = ( machines: MachineKind[] = [], ): MachineKind => machines.find((machine: MachineKind) => getHostMachineName(host) === getName(machine)); + +export const hasPowerManagement = (host: BareMetalHostKind): boolean => + getHostProvisioningState(host) !== HOST_STATUS_UNMANAGED; diff --git a/frontend/packages/metal3-plugin/src/status/host-status.ts b/frontend/packages/metal3-plugin/src/status/host-status.ts index e52920872d7..4f0e3cfb7c0 100644 --- a/frontend/packages/metal3-plugin/src/status/host-status.ts +++ b/frontend/packages/metal3-plugin/src/status/host-status.ts @@ -4,7 +4,6 @@ import { HOST_STATUS_TITLES, HOST_STATUS_DESCRIPTIONS, HOST_STATUS_ERROR, - HOST_STATUS_DISCOVERED, HOST_PROGRESS_STATES, HOST_STATUS_DEPROVISIONING, HOST_STATUS_UNKNOWN, @@ -18,7 +17,7 @@ export const getBareMetalHostStatus = (host: BareMetalHostKind): StatusProps => const provisioningState = getHostProvisioningState(host); const errorType = getHostErrorType(host); - let hostStatus; + let hostStatus: string; if (operationalStatus === HOST_STATUS_ERROR) { if (errorType) { @@ -26,8 +25,6 @@ export const getBareMetalHostStatus = (host: BareMetalHostKind): StatusProps => } else { hostStatus = HOST_STATUS_ERROR; } - } else if (operationalStatus === HOST_STATUS_DISCOVERED) { - hostStatus = HOST_STATUS_DISCOVERED; } else if (provisioningState) { hostStatus = provisioningState; } else { diff --git a/frontend/packages/metal3-plugin/src/types/host.ts b/frontend/packages/metal3-plugin/src/types/host.ts index c170127b864..f0141561b0c 100644 --- a/frontend/packages/metal3-plugin/src/types/host.ts +++ b/frontend/packages/metal3-plugin/src/types/host.ts @@ -1,4 +1,4 @@ -import { K8sResourceKind } from '@console/internal/module/k8s'; +import { K8sResourceCommon } from '@console/internal/module/k8s'; export type BareMetalHostNIC = { ip: string; @@ -59,6 +59,8 @@ export type BareMetalHostKind = { url: string; }; online: boolean; + externallyProvisioned?: boolean; + description?: string; }; status?: { hardwareProfile: string; @@ -86,4 +88,4 @@ export type BareMetalHostKind = { errorType?: string; errorMessage: string; }; -} & K8sResourceKind; +} & K8sResourceCommon; diff --git a/frontend/packages/operator-lifecycle-manager/src/components/catalog-source.tsx b/frontend/packages/operator-lifecycle-manager/src/components/catalog-source.tsx index 9a90e958305..0f7b8a31bcd 100644 --- a/frontend/packages/operator-lifecycle-manager/src/components/catalog-source.tsx +++ b/frontend/packages/operator-lifecycle-manager/src/components/catalog-source.tsx @@ -35,7 +35,7 @@ import { RowFunction, } from '@console/internal/components/factory'; import { ConfigMapModel } from '@console/internal/models'; -import { PopoverStatus } from '@console/shared'; +import { PopoverStatus, StatusIconAndText } from '@console/shared'; import { SubscriptionModel, CatalogSourceModel, @@ -394,10 +394,15 @@ const DisabledPopover: React.FC = ({ operatorHub, sourceNa [close, operatorHub, sourceName], ); return ( - + } + >

Operators provided by this source will not appear in OperatorHub and any operators installed - from this source will not receive updates unitl this source is re-enabled. + from this source will not receive updates until this source is re-enabled.