Skip to content

Commit fb0d8e2

Browse files
committed
NETOBSERV-631: show subnet labels in topology
1 parent 5f7a417 commit fb0d8e2

File tree

7 files changed

+47
-14
lines changed

7 files changed

+47
-14
lines changed

web/src/api/ipfix.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ export interface Flow {
5353
DstK8S_Zone?: string;
5454
SrcK8S_NetworkName?: string;
5555
DstK8S_NetworkName?: string;
56+
SrcSubnetLabel?: string;
57+
DstSubnetLabel?: string;
5658
K8S_ClusterName?: string;
5759
Proto?: number;
5860
Interfaces?: string[];

web/src/api/loki.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,13 @@ export interface TopologyMetricPeer {
6868
resourceKind?: string;
6969
isAmbiguous: boolean;
7070
getDisplayName: (inclNamespace: boolean, disambiguate: boolean) => string | undefined;
71-
// any FlowScope can appear here as optionnal field
71+
// any FlowScope can appear here as optional field
7272
[name: string]: unknown;
7373
namespace?: string;
7474
host?: string;
7575
cluster?: string;
7676
udn?: string;
77+
subnetLabel?: string;
7778
}
7879

7980
export type GenericMetric = {

web/src/components/drawer/element/element-fields.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ export const ElementFields: React.FC<ElementFieldsProps> = ({
8181
forceLabel = forceAsText = undefined;
8282
}
8383
});
84+
if (data.peer.subnetLabel) {
85+
fragments.push(
86+
<ElementField
87+
id={id + '-subnet-label'}
88+
key={id + '-subnet-label'}
89+
label={t('Subnet label')}
90+
activeFilters={activeFilters}
91+
filterType={'resource'}
92+
peer={createPeer({ subnetLabel: data.peer.subnetLabel })}
93+
setFilters={setFilters}
94+
filterDefinitions={filterDefinitions}
95+
/>
96+
);
97+
}
8498
if (data.peer.addr) {
8599
fragments.push(
86100
<ElementField

web/src/components/drawer/element/element-panel.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,11 @@ export const ElementPanel: React.FC<ElementPanelProps> = ({
7272
return <Text component={TextVariants.h2}>{t('Edge')}</Text>;
7373
} else {
7474
const data = element.getData();
75-
if (data?.nodeType === 'unknown') {
76-
return <Text component={TextVariants.h2}>{t('Unknown')}</Text>;
75+
const name = data?.peer.getDisplayName(false, false);
76+
if (data && name) {
77+
return <PeerResourceLink peer={data.peer} />
7778
}
78-
return <>{data && <PeerResourceLink peer={data.peer} />}</>;
79+
return <Text component={TextVariants.h2}>{t('Unknown')}</Text>;
7980
}
8081
}, [element, t]);
8182

web/src/components/tabs/netflow-topology/2d/styles/styleNode.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
ClusterIcon,
33
CubeIcon,
44
CubesIcon,
5+
ExternalLinkAltIcon,
56
NetworkIcon,
67
OutlinedHddIcon,
78
QuestionCircleIcon,
@@ -30,6 +31,7 @@ import * as React from 'react';
3031
import { Decorated, NodeData } from '../../../../../model/topology';
3132
import DefaultNode from '../components/node';
3233
import { NodeDecorators } from './styleDecorators';
34+
import { TopologyMetricPeer } from '../../../../../api/loki';
3335

3436
export enum DataTypes {
3537
Default
@@ -50,8 +52,8 @@ type StyleNodeProps = {
5052
WithSelectionProps;
5153

5254
// eslint-disable-next-line @typescript-eslint/no-explicit-any
53-
const getTypeIcon = (resourceKind?: string): React.ComponentClass<any, any> => {
54-
switch (resourceKind) {
55+
const getTypeIcon = (peer: TopologyMetricPeer): React.ComponentClass<any, any> => {
56+
switch (peer.resourceKind) {
5557
case 'Service':
5658
return ServiceIcon;
5759
case 'Pod':
@@ -72,9 +74,11 @@ const getTypeIcon = (resourceKind?: string): React.ComponentClass<any, any> => {
7274
case 'StatefulSet':
7375
case 'Job':
7476
return CubesIcon;
75-
default:
76-
return QuestionCircleIcon;
77+
}
78+
if (peer.addr || peer.subnetLabel) {
79+
return ExternalLinkAltIcon;
7780
}
81+
return QuestionCircleIcon;
7882
};
7983

8084
const renderIcon = (data: Decorated<NodeData>, element: NodePeer): React.ReactNode => {
@@ -83,7 +87,7 @@ const renderIcon = (data: Decorated<NodeData>, element: NodePeer): React.ReactNo
8387
const iconSize =
8488
(shape === NodeShape.trapezoid ? width : Math.min(width, height)) -
8589
(shape === NodeShape.stadium ? 5 : iconPadding) * 2;
86-
const Component = getTypeIcon(data.peer.resourceKind);
90+
const Component = getTypeIcon(data.peer);
8791

8892
return (
8993
<g transform={`translate(${(width - iconSize) / 2}, ${(height - iconSize) / 2})`}>

web/src/utils/ids.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ export const getPeerId = (fields: Partial<TopologyMetricPeer>): string => {
4141
parts.push('r=' + fields.resource.type + '.' + fields.resource.name);
4242
} else if (fields.addr) {
4343
parts.push('a=' + fields.addr);
44+
} else if (fields.subnetLabel) {
45+
parts.push('sl=' + fields.subnetLabel);
4446
}
4547
return parts.length > 0 ? parts.join(',') : idUnknown;
4648
};

web/src/utils/metrics.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ export const createPeer = (fields: Partial<TopologyMetricPeer>): TopologyMetricP
114114
addr: fields.addr,
115115
resource: fields.resource,
116116
owner: fields.owner,
117+
subnetLabel: fields.subnetLabel,
117118
isAmbiguous: false,
118119
getDisplayName: () => undefined
119120
};
@@ -146,9 +147,15 @@ export const createPeer = (fields: Partial<TopologyMetricPeer>): TopologyMetricP
146147
}
147148
});
148149

149-
// fallback on address if nothing else available
150-
if (!newPeer.resourceKind && fields.addr) {
151-
newPeer.getDisplayName = () => fields.addr;
150+
// fallback on address and/or subnet label if nothing else available
151+
if (!newPeer.resourceKind) {
152+
if (fields.subnetLabel && fields.addr) {
153+
newPeer.getDisplayName = () => `${fields.subnetLabel} (${fields.addr})`;
154+
} else if (fields.subnetLabel) {
155+
newPeer.getDisplayName = () => fields.subnetLabel;
156+
} else if (fields.addr) {
157+
newPeer.getDisplayName = () => fields.addr;
158+
}
152159
}
153160
return newPeer;
154161
};
@@ -173,15 +180,17 @@ const parseTopologyMetric = (
173180
owner:
174181
raw.metric.SrcK8S_Type !== raw.metric.SrcK8S_OwnerType
175182
? nameAndType(raw.metric.SrcK8S_OwnerName, raw.metric.SrcK8S_OwnerType)
176-
: undefined
183+
: undefined,
184+
subnetLabel: raw.metric.SrcSubnetLabel
177185
};
178186
const destFields: Partial<TopologyMetricPeer> = {
179187
addr: raw.metric.DstAddr,
180188
resource: nameAndType(raw.metric.DstK8S_Name, raw.metric.DstK8S_Type),
181189
owner:
182190
raw.metric.DstK8S_Type !== raw.metric.DstK8S_OwnerType
183191
? nameAndType(raw.metric.DstK8S_OwnerName, raw.metric.DstK8S_OwnerType)
184-
: undefined
192+
: undefined,
193+
subnetLabel: raw.metric.DstSubnetLabel
185194
};
186195
getCustomScopes().forEach(sc => {
187196
if (!sc.labels.length) {

0 commit comments

Comments
 (0)