import React, { FC, useState } from 'react'; import { useAccessReview, useFlag } from '@openshift-console/dynamic-plugin-sdk'; import { PageSection } from '@patternfly/react-core'; import ListErrorState from '@utils/components/ListEmptyState/ListErrorState'; import Loading from '@utils/components/Loading/Loading'; import { ALL_NAMESPACES } from '@utils/constants'; import { FLAG_KUBEVIRT, FLAG_NMSTATE, FLAG_NMSTATE_CRDS } from '@utils/flags/consts'; import { useNetworkingTranslation } from '@utils/hooks/useNetworkingTranslation'; import NMStateGuidance from './components/NMStateGuidance'; import PhysicalNetworksEmptyState from './components/PhysicalNetworksEmptyState'; import PhysicalNetworksPageHeader from './components/PhysicalNetworksPageHeader'; import SourceStateAlerts from './components/SourceStateAlerts'; import ConfigurationDrawer from './details/ConfigurationDrawer'; import usePhysicalNetworks from './hooks/usePhysicalNetworks'; import ConsumersModal from './list/components/ConsumersModal'; import ScopeSelect from './list/components/ScopeSelect'; import PhysicalNetworksList from './list/PhysicalNetworksList'; import { isNMStateSimulatedAbsent } from './utils/simulation'; import { ConfigurationDetails, ConsumersSelection, SourceAvailability } from './utils/types'; const PhysicalNetworksPage: FC = () => { const { t } = useNetworkingTranslation(); const [scope, setScope] = useState(ALL_NAMESPACES); const [selectedConfiguration, setSelectedConfiguration] = useState(); const [consumersSelection, setConsumersSelection] = useState(); const { consumersAvailability, networks, sources } = usePhysicalNetworks( scope === ALL_NAMESPACES ? undefined : scope, ); const kubevirtEnabled = useFlag(FLAG_KUBEVIRT); const nmstateSimulatedAbsent = isNMStateSimulatedAbsent(); const nmstateFrontendAvailable = useFlag(FLAG_NMSTATE) && !nmstateSimulatedAbsent; const nmstateCrdsPresent = useFlag(FLAG_NMSTATE_CRDS); const [canConfigure] = useAccessReview({ group: 'nmstate.io', resource: 'nodenetworkconfigurationpolicies', verb: 'create', }); const [canInstallOperators] = useAccessReview({ group: 'operators.coreos.com', namespace: 'openshift-operators', resource: 'subscriptions', verb: 'create', }); const showGuidance = sources.nncps.availability !== SourceAvailability.Forbidden && (sources.nncps.availability === SourceAvailability.Absent || !nmstateCrdsPresent); const actionsEnabled = { configure: !!nmstateFrontendAvailable && canConfigure, createVMNetwork: !!kubevirtEnabled, }; const sourceStates = Object.values(sources); const isLoading = sourceStates.some( ({ availability }) => availability === SourceAvailability.Loading, ); const hasReadableSource = sourceStates.some( ({ availability }) => availability === SourceAvailability.Available, ); const consumers = consumersSelection ? networks.find(({ name }) => name === consumersSelection.networkName)?.consumersByNAD[ `${consumersSelection.nad.namespace}/${consumersSelection.nad.name}` ] || [] : []; return ( 0} />
{scope !== ALL_NAMESPACES && (

{t( 'Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.', { project: scope }, )}

)} {showGuidance && } {isLoading && } {!isLoading && networks.length === 0 && !hasReadableSource && ( )} {!isLoading && networks.length === 0 && hasReadableSource && ( )} {!isLoading && networks.length > 0 && ( setConsumersSelection({ nad, networkName })} setSelectedConfiguration={setSelectedConfiguration} sources={sources} /> )} setSelectedConfiguration(undefined)} selectedConfiguration={selectedConfiguration} /> setConsumersSelection(undefined)} />
); }; export default PhysicalNetworksPage;