Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,13 @@ export type MetricStats = {

export type GetPodMetricStats = (metrics: NamespaceMetrics, podData: PodRCData) => MetricStats;

export type GetTopologyResourceObject = (topologyObject: TopologyDataObject) => K8sResourceKind;
export type GetTopologyResourceObject = (
topologyObject: TopologyDataObject,
) => K8sResourceKind | null;

export type GetResource = <T extends K8sResourceKind = K8sResourceKind>(node: GraphElement) => T;
export type GetResource = <T extends K8sResourceKind = K8sResourceKind>(
node: GraphElement,
) => T | null;

export type GetTopologyEdgeItems = (
resource: K8sResourceKind,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,33 @@ export type BuildConfigData = {
buildConfigs: BuildConfigOverviewItem[];
};

export const useBuildConfigsWatcher = (resource: K8sResourceKind): BuildConfigData => {
const { namespace } = resource.metadata;
export const useBuildConfigsWatcher = (resource: K8sResourceKind | null): BuildConfigData => {
const namespace = resource?.metadata?.namespace;
const watchedResources = useMemo(
() => ({
buildConfigs: {
isList: true,
kind: 'BuildConfig',
namespace,
},
builds: {
isList: true,
kind: 'Build',
namespace,
},
}),
() =>
namespace
? {
buildConfigs: {
isList: true,
kind: 'BuildConfig',
namespace,
},
builds: {
isList: true,
kind: 'Build',
namespace,
},
}
: {},
[namespace],
);

const resources = useK8sWatchResources(watchedResources);

const result = useMemo(() => {
if (!resource) {
return { loaded: true, loadError: null, buildConfigs: null };
}
const resourceWithLoadError = Object.values(resources).find((r) => r.loadError);
if (resourceWithLoadError) {
return { loaded: false, loadError: resourceWithLoadError.loadError, buildConfigs: null };
Expand Down
2 changes: 1 addition & 1 deletion frontend/packages/helm-plugin/src/actions/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const useHelmActionProviderForTopology = (element: GraphElement) => {
const nodeType = element.getType();
if (nodeType !== TYPE_HELM_RELEASE) return undefined;
const releaseName = element.getLabel();
if (!resource?.metadata) return null;
if (!resource?.metadata?.labels) return null;
const {
namespace,
labels: { version },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const EventingPubSubLink: FC<EventingPubSubLinkProps> = ({ element, children, ..
const resourceSourceObj = getTopologyResourceObject(element.getSource().getData());
const edgeObj = getTopologyResourceObject(element.getData());
const edgeHasFilter =
resourceSourceObj.kind === EventingBrokerModel.kind &&
resourceSourceObj?.kind === EventingBrokerModel.kind &&
Object.keys(edgeObj?.spec?.filter?.attributes ?? {}).length > 0;

let filterMarker: JSX.Element;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ const KnativeService: FC<KnativeServiceProps & { children?: ReactNode }> = ({
const { element } = props;
const { data } = element.getData();
const resourceObj = getResource(props.element);
const resourceModel = modelFor(referenceFor(resourceObj));
const resourceModel = resourceObj ? modelFor(referenceFor(resourceObj)) : undefined;
const editAccess = useAccessReview({
group: resourceModel.apiGroup,
group: resourceModel?.apiGroup,
verb: 'patch',
resource: resourceModel.plural,
name: resourceObj.metadata.name,
namespace: resourceObj.metadata.namespace,
resource: resourceModel?.plural,
name: resourceObj?.metadata?.name,
namespace: resourceObj?.metadata?.namespace,
});
const { kindAbbr, kindStr, kindColor } = getKindStringAndAbbreviation(data.kind);
const badgeClassName = css('odc-resource-icon', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const EventingPubSubNode: FC<EventingPubSubNodeProps> = ({
<Tooltip
triggerRef={ref}
content={t('Move sink to {{resourceObjKind}}', {
resourceObjKind: resourceObj.kind,
resourceObjKind: resourceObj?.kind,
})}
trigger="manual"
isVisible={dropTarget && canDrop}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const RevisionNode: FC<ComponentProps<typeof WorkloadPodsNode>> = (props) => {
const { element } = props;
const resource = getTopologyResourceObject(element.getData());
const { loaded, loadError, pods } = usePodsForRevisions(
resource.metadata.uid,
resource.metadata.namespace,
resource?.metadata?.uid,
resource?.metadata?.namespace,
);
const donutStatus = useMemo(() => {
if (loaded && !loadError) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1368,17 +1368,20 @@ export const isOperatorBackedKnSinkService = (

export const createSinkConnection = (source: Node, target: Node): Promise<K8sResourceKind> => {
if (!source || !target || source === target) {
return Promise.reject();
return Promise.reject(new Error('Invalid source or target node'));
}
const sourceObj = getResource(source);
const targetObj = getResource(target);
if (!sourceObj || !targetObj) {
return Promise.reject(new Error('Source or target resource not found'));
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

return createKnativeEventSourceSink(sourceObj, targetObj);
};

const createEventingPubSubSink = (subObj: K8sResourceKind, target: K8sResourceKind) => {
if (!subObj || !target) {
return Promise.reject();
return Promise.reject(new Error('Subscription or target resource not found'));
}
const subscriptionObj = _.omit(subObj, 'status');
const sink = {
Expand All @@ -1405,6 +1408,9 @@ export const createEventSourceKafkaConnection = (
}
const sourceObj = getResource(source);
const targetObj = getResource(target);
if (!sourceObj || !targetObj) {
return Promise.reject(new Error('Source or target resource not found'));
}
const mkcBoostrapServer = targetObj?.status?.bootstrapServerHost;
const mkcServiceAccountSecretName = targetObj?.spec?.credentials?.serviceAccountSecretName;
const knKafkaSourceObj = _.omit(sourceObj, 'status');
Expand Down Expand Up @@ -1447,6 +1453,9 @@ export const createSinkPubSubConnection = (
return Promise.reject();
}
const targetObj = getTopologyResourceObject(target);
if (!targetObj) {
return Promise.reject();
}
return createEventingPubSubSink(resources.obj, targetObj);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ const ObservedKnativeRevisionListViewNode: FC<KnativeRevisionListViewNodeProps>
}) => {
const resource = getTopologyResourceObject(item.getData());
const metrics = useOverviewMetrics();
const { loaded, pods } = usePodsForRevisions(resource.metadata.uid, resource.metadata.namespace);
const { loaded, pods } = usePodsForRevisions(
resource?.metadata?.uid,
resource?.metadata?.namespace,
);
const podData = useMemo(() => {
if (!loaded) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export const getKnativeSidepanelPodsAdapterSection = (
): AdapterDataType<PodsAdapterDataType> => {
if (element.getType() === NodeType.KnService || element.getType() === NodeType.Revision) {
const resource = getResource(element);
if (!resource) return undefined;
return { resource, provider: usePodsAdapterForKnative };
}
return undefined;
Expand Down Expand Up @@ -126,6 +127,7 @@ export const useKnativeSidepanelRoutesSection: DetailsTabSectionExtensionHook =
if (element.getType() === NodeType.KnService || element.getType() === NodeType.Revision) {
const knObj = element.getData().resources;
const resource = getResource(element);
if (!resource) return [undefined, true, undefined];
const section = (
<TopologySideBarTabSection>
<KSRoutesOverviewList ksroutes={knObj.ksroutes} resource={resource} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ const usePodsForEventSource = (resource: K8sResourceKind, data) => {
export const getEventSinkPodsApdapter = (element: GraphElement) => {
if (element.getType() === NodeType.EventSink) {
const resource = getResource(element);
if (!resource) return undefined;
const { revisions, associatedDeployment } = element.getData()?.resources ?? {};
return {
resource,
Expand All @@ -157,6 +158,7 @@ export const getEventSinkPodsApdapter = (element: GraphElement) => {
export const getEventSourcePodsApdapter = (element: GraphElement) => {
if (element.getType() === NodeType.EventSource) {
const resource = getResource(element);
if (!resource) return undefined;
const { associatedDeployment } = element.getData()?.resources ?? {};
return {
resource,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const useKnativeSidepanelDeploymentSection: DetailsTabSectionExtensionHoo
return [undefined, true, undefined];
}
const resource = getResource(element);
if (!resource) return [undefined, true, undefined];
const section = (
<TopologySideBarTabSection>
<DeploymentOverviewList resource={resource} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const useKnativeSidepanelRevisionSection: DetailsTabSectionExtensionHook
}
const knObj = element.getData().resources;
const resource = getResource(element);
if (!resource) return [undefined, true, undefined];
const section = (
<TopologySideBarTabSection>
<RevisionsOverviewList revisions={knObj.revisions} service={resource} />
Expand All @@ -35,6 +36,7 @@ export const getKnativeSidepanelBuildAdapterSection = (
): AdapterDataType<BuildConfigData> | undefined => {
if (element.getType() !== NodeType.KnService) return undefined;
const resource = getResource(element);
if (!resource) return undefined;
return { resource, provider: useBuildConfigsWatcher };
};

Expand Down
37 changes: 20 additions & 17 deletions frontend/packages/knative-plugin/src/utils/usePodsForRevisions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,26 @@ export const usePodsForRevisions = (
const [pods, setPods] = useState<PodControllerOverviewItem[]>([]);
const revisions = useDeepCompareMemoize(Array.isArray(revisionIds) ? revisionIds : [revisionIds]);
const watchedResources = useMemo(
() => ({
deployments: {
isList: true,
kind: 'Deployment',
namespace,
},
replicaSets: {
isList: true,
kind: 'ReplicaSet',
namespace,
},
pods: {
isList: true,
kind: 'Pod',
namespace,
},
}),
() =>
namespace
? {
deployments: {
isList: true,
kind: 'Deployment',
namespace,
},
replicaSets: {
isList: true,
kind: 'ReplicaSet',
namespace,
},
pods: {
isList: true,
kind: 'Pod',
namespace,
},
}
: {},
[namespace],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ const BaseNodeComponent: FC<BaseNodeProps> = ({
const cx = width / 2;
const cy = height / 2;
const resourceObj = getTopologyResourceObject(element.getData());
const resourceModel = modelFor(referenceFor(resourceObj));
const resourceModel = resourceObj ? modelFor(referenceFor(resourceObj)) : undefined;
const iconRadius = innerRadius * 0.9;
const editAccess = useAccessReview({
group: resourceModel?.apiGroup,
verb: createConnectorAccessVerb,
resource: resourceModel?.plural,
name: resourceObj.metadata.name,
namespace: resourceObj.metadata.namespace,
name: resourceObj?.metadata?.name,
namespace: resourceObj?.metadata?.namespace,
});
const [filtered] = useSearchFilter(element.getLabel(), resourceObj?.metadata?.labels);
const showLabel = useShowLabel(isHovering);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const BindableNode: FC<BindableNodeProps> = ({
const iconRadius = Math.min(width, height) * 0.25;
const [dndDropProps, dndDropRef] = useDndDrop(spec, { element: nodeElement, ...rest });
const resourceObj = getTopologyResourceObject(element.getData());
const resourceModel = modelFor(referenceFor(resourceObj));
const resourceModel = resourceObj ? modelFor(referenceFor(resourceObj)) : undefined;
const iconData = element.getData()?.data?.icon || openshiftImg;
const kind = resourceModel && referenceForModel(resourceModel);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ const WorkloadNode: FC<WorkloadNodeProps> = observer(({ element, ...rest }) => {
const resource = getTopologyResourceObject(element.getData());
const { podData, loadError, loaded } = usePodsWatcher(
resource,
resource.kind,
resource.metadata.namespace,
resource?.kind,
resource?.metadata?.namespace,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
);
return (
<WorkloadPodsNode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const StatusCell: FC<StatusProps> = ({ item }) => {
return (
<DataListCell id={`${item.getId()}_status`}>
<div className="odc-topology-list-view__detail--status">
{loaded && !loadError ? (
{loaded && !loadError && resource ? (
<StatusCellResourceStatus obj={resource} podData={podData} />
) : null}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ const TopologyEdgeResourcesPanel: FC<TopologyEdgeResourcesPanelProps> = ({ edge
const target = getResource(edge.getTarget());
const data = edge.getData();
const resources = [source, target];
const {
metadata: { namespace },
} = resources[1];
const namespace = target?.metadata?.namespace;

return (
<div className="overview__sidebar-pane-body">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ export const useVpaSideBarTabSection: DetailsTabSectionExtensionHook = (element:
}

const resource = getResource(element);
if (!resource) {
return [undefined, true, undefined];
}
const verticalPodAutoscalers = getVerticalPodAutoscalersForResource(vpas, resource);

const section =
Expand Down
11 changes: 7 additions & 4 deletions frontend/packages/topology/src/utils/topology-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,13 @@ export const getResource: GetResource = <T = K8sResourceKind>(node: GraphElement
return (resource as T) || (getTopologyResourceObject(node?.getData()) as T);
};

export const getResourceKind = (node: Node): K8sResourceKindReference =>
node instanceof OdcBaseNode
? (node as OdcBaseNode).getResourceKind()
: referenceFor(getTopologyResourceObject(node?.getData()));
export const getResourceKind = (node: Node): K8sResourceKindReference => {
if (node instanceof OdcBaseNode) {
return (node as OdcBaseNode).getResourceKind();
}
const resource = getTopologyResourceObject(node?.getData());
return resource ? referenceFor(resource) : undefined;
};

export const updateTopologyResourceApplication = (
item: Node,
Expand Down
12 changes: 8 additions & 4 deletions frontend/packages/topology/src/utils/useMetricStats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ import { usePodsWatcher } from '@console/shared/src/hooks/usePodsWatcher';
import { getPodMetricStats } from './metricStats';
import { useOverviewMetrics } from './useOverviewMetrics';

export const useMetricStats = (resource: K8sResourceKind): MetricStats => {
export const useMetricStats = (resource: K8sResourceKind | null): MetricStats => {
const metrics = useOverviewMetrics();
const { podData, loaded } = usePodsWatcher(resource, resource.kind, resource.metadata.namespace);
const { podData, loaded } = usePodsWatcher(
resource,
resource?.kind,
resource?.metadata?.namespace,
);
const memoryStats = useMemo(() => {
if (_.isEmpty(metrics) || !loaded) {
if (!resource || _.isEmpty(metrics) || !loaded) {
return null;
}
return getPodMetricStats(metrics, podData);
}, [loaded, metrics, podData]);
}, [resource, loaded, metrics, podData]);

return memoryStats;
};
Loading