Skip to content

Commit 34d65eb

Browse files
committed
Clean TS flow format code; remove field/label distinction
The Label/Field hard distinction in the frontend isn't necessary to keep, and could become misleading as this is now configurable
1 parent ff0630c commit 34d65eb

File tree

7 files changed

+60
-141
lines changed

7 files changed

+60
-141
lines changed

Makefile

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,6 @@ else
136136
cd -
137137
endif
138138

139-
.PHONY: generate-doc
140-
generate-doc: ## Generate documentation of the flows JSON format
141-
cd web && npm run generate-doc
142-
143139
.PHONY: update-config
144140
update-config: ## Update sample config from operator repo
145141
./scripts/update-config.sh

web/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@
2525
"lint": "./node_modules/.bin/eslint \"./src/**/*.{ts,tsx}\"",
2626
"format": "pretty-quick --branch main",
2727
"format-all": "prettier --write \"./src/**/*.{ts,tsx}\" && npm run fix-imports",
28-
"fix-imports": "eslint --no-eslintrc --no-inline-config --parser '@typescript-eslint/parser' --plugin 'unused-imports' --plugin 'react-hooks' --rule 'unused-imports/no-unused-imports:error' --fix \"./src/**/*.{ts,tsx}\"",
29-
"generate-doc": "typedoc --sort source-order --categorizeByGroup false --githubPages false --readme none --disableSources --out docs src/api/ipfix.ts --hideBreadcrumbs true --hideInPageTOC true"
28+
"fix-imports": "eslint --no-eslintrc --no-inline-config --parser '@typescript-eslint/parser' --plugin 'unused-imports' --plugin 'react-hooks' --rule 'unused-imports/no-unused-imports:error' --fix \"./src/**/*.{ts,tsx}\""
3029
},
3130
"devDependencies": {
3231
"@babel/core": "^7.17.12",

web/src/api/ipfix.ts

Lines changed: 35 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -2,195 +2,117 @@
22
import { TFunction } from 'i18next';
33
import { RecordType } from '../model/flow-query';
44

5-
// Please keep this file documented: it is used in doc generation
6-
// To regenerate doc, run `make generate-doc` - and also check this page:
7-
// https://github.com/netobserv/network-observability-operator/blob/main/docs/GeneratingAsciidocAPI.md#generate-asciidoc-for-flows-json-format-reference
8-
95
export interface Record {
10-
labels: Labels;
6+
labels: Flow;
117
key: number;
12-
fields: Fields;
8+
fields: Flow;
139
}
1410

15-
export const getRecordValue = (record: Record, fieldOrLabel: string, defaultValue?: string | number) => {
11+
export const getRecordValue = (record: Record, field: Field, defaultValue?: string | number) => {
1612
/* TODO: fix following behavior:
1713
* Check if field exists first since /flow endpoint return fields as labels when using filters
1814
* This is mandatory to ensure fields types
1915
*/
20-
if (record.fields[fieldOrLabel as keyof Fields] !== undefined) {
21-
return record.fields[fieldOrLabel as keyof Fields];
16+
if (record.fields[field] !== undefined) {
17+
return record.fields[field];
2218
}
2319
// check if label exists
24-
if (record.labels[fieldOrLabel as keyof Labels] !== undefined) {
25-
return record.labels[fieldOrLabel as keyof Labels];
20+
if (record.labels[field] !== undefined) {
21+
return record.labels[field];
2622
}
2723
// fallback on default
2824
return defaultValue;
2925
};
3026

31-
export interface Labels {
32-
/** Source namespace */
27+
export type Field = keyof Flow;
28+
29+
export interface Flow {
3330
SrcK8S_Namespace?: string;
34-
/** Destination namespace */
3531
DstK8S_Namespace?: string;
36-
/** Source owner, such as Deployment, StatefulSet, etc. */
37-
SrcK8S_OwnerName?: string;
38-
/** Destination owner, such as Deployment, StatefulSet, etc. */
39-
DstK8S_OwnerName?: string;
40-
/** Kind of the source matched Kubernetes object, such as Pod, Service, etc. */
4132
SrcK8S_Type?: string;
42-
/** Kind of the destination matched Kubernetes object, such as Pod name, Service name, etc. */
4333
DstK8S_Type?: string;
44-
/** Flow direction from the node observation point*/
4534
FlowDirection?: FlowDirection;
46-
/** Type of record: 'flowLog' for regular flow logs, or 'allConnections',
47-
* 'newConnection', 'heartbeat', 'endConnection' for conversation tracking */
4835
_RecordType?: RecordType;
49-
}
50-
51-
export enum FlowDirection {
52-
/** Incoming traffic, from the node observation point */
53-
Ingress = '0',
54-
/** Outgoing traffic, from the node observation point */
55-
Egress = '1',
56-
/** Inner traffic, with the same source and destination node */
57-
Inner = '2',
58-
/** Both traffic (for Interface direction only), flow seen on both Ingress and Egress */
59-
Both = '3'
60-
}
61-
62-
export const getDirectionDisplayString = (value: FlowDirection, t: TFunction) => {
63-
return value === FlowDirection.Ingress
64-
? t('Ingress')
65-
: value === FlowDirection.Egress
66-
? t('Egress')
67-
: value === FlowDirection.Inner
68-
? t('Inner')
69-
: value === FlowDirection.Both
70-
? t('Both')
71-
: t('n/a');
72-
};
73-
74-
export enum IfDirection {
75-
/** Incoming traffic, from the network interface observation point */
76-
Ingress = '0',
77-
/** Outgoing traffic, from the network interface observation point */
78-
Egress = '1'
79-
}
80-
81-
export interface Fields {
82-
/** Source IP address (ipv4 or ipv6) */
8336
SrcAddr?: string;
84-
/** Destination IP address (ipv4 or ipv6) */
8537
DstAddr?: string;
86-
/** Source MAC address */
8738
SrcMac?: string;
88-
/** Destination MAC address */
8939
DstMac?: string;
90-
/** Name of the source matched Kubernetes object, such as Pod name, Service name, etc. */
9140
SrcK8S_Name?: string;
92-
/** Name of the destination matched Kubernetes object, such as Pod name, Service name, etc. */
9341
DstK8S_Name?: string;
94-
/** Source port */
9542
SrcPort?: number;
96-
/** Destination port */
9743
DstPort?: number;
98-
/** Kind of the source Kubernetes owner, such as Deployment, StatefulSet, etc. */
44+
SrcK8S_OwnerName?: string;
45+
DstK8S_OwnerName?: string;
9946
SrcK8S_OwnerType?: string;
100-
/** Kind of the destination Kubernetes owner, such as Deployment, StatefulSet, etc. */
10147
DstK8S_OwnerType?: string;
102-
/** Source node IP */
10348
SrcK8S_HostIP?: string;
104-
/** Destination node IP */
10549
DstK8S_HostIP?: string;
106-
/** Source node name */
10750
SrcK8S_HostName?: string;
108-
/** Destination node name */
10951
DstK8S_HostName?: string;
110-
/** Source zone */
11152
SrcK8S_Zone?: string;
112-
/** Destination zone */
11353
DstK8S_Zone?: string;
114-
/** Source network name (e.g. secondary networks or UDN) */
11554
SrcK8S_NetworkName?: string;
116-
/** Destination network name (e.g. secondary networks or UDN) */
11755
DstK8S_NetworkName?: string;
118-
/** Cluster name */
11956
K8S_ClusterName?: string;
120-
/** L4 protocol */
12157
Proto?: number;
122-
/** Network interface array */
12358
Interfaces?: string[];
124-
/** Flow direction array from the network interface observation point */
12559
IfDirections?: IfDirection[];
126-
/** UDNs labels array */
12760
Udns?: string[];
128-
/** Network Events */
12961
NetworkEvents?: string[];
130-
/** Logical OR combination of unique TCP flags comprised in the flow, as per RFC-9293, with additional custom flags to represent the following per-packet combinations: SYN+ACK (0x100), FIN+ACK (0x200) and RST+ACK (0x400). */
13162
Flags?: string[];
132-
/** Number of packets */
13363
Packets?: number;
134-
/** In conversation tracking, A to B packets counter per conversation */
13564
Packets_AB?: number;
136-
/** In conversation tracking, B to A packets counter per conversation */
13765
Packets_BA?: number;
138-
/** Number of bytes */
13966
Bytes?: number;
140-
/** In conversation tracking, A to B bytes counter per conversation */
14167
Bytes_AB?: number;
142-
/** In conversation tracking, B to A bytes counter per conversation */
14368
Bytes_BA?: number;
144-
/** Differentiated Services Code Point Value */
14569
Dscp?: number;
146-
/** ICMP type */
14770
IcmpType?: number;
148-
/** ICMP code */
14971
IcmpCode?: number;
150-
/** Pkt TCP state for drops */
15172
PktDropLatestState?: string;
152-
/** Pkt cause for drops */
15373
PktDropLatestDropCause?: string;
154-
/** Pkt TCP flags for drops */
15574
PktDropLatestFlags?: number;
156-
/** Number of packets dropped by the kernel */
15775
PktDropPackets?: number;
158-
/** In conversation tracking, A to B packets dropped counter per conversation */
15976
PktDropPackets_AB?: number;
160-
/** In conversation tracking, B to A packets dropped counter per conversation */
16177
PktDropPackets_BA?: number;
162-
/** Number of bytes dropped by the kernel */
16378
PktDropBytes?: number;
164-
/** In conversation tracking, A to B bytes dropped counter per conversation */
16579
PktDropBytes_AB?: number;
166-
/** In conversation tracking, B to A bytes dropped counter per conversation */
16780
PktDropBytes_BA?: number;
168-
/** DNS record id */
16981
DnsId?: number;
170-
/** DNS flags for DNS record */
17182
DnsFlags?: number;
172-
/** Parsed DNS header RCODEs name */
17383
DnsFlagsResponseCode?: string;
174-
/** Calculated time between response and request, in milliseconds */
17584
DnsLatencyMs?: number;
176-
/** Error number returned from DNS tracker ebpf hook function */
17785
DnsErrno?: number;
178-
/** Start timestamp of this flow, in milliseconds */
17986
TimeFlowStartMs?: number;
180-
/** End timestamp of this flow, in milliseconds */
18187
TimeFlowEndMs?: number;
182-
/** Timestamp when this flow was received and processed by the flow collector, in seconds */
18388
TimeReceived?: number;
184-
/** TCP smoothed Round Trip Time (sRTT) in nanoseconds */
18589
TimeFlowRttNs?: number;
186-
/** In conversation tracking, the conversation identifier */
18790
_HashId?: string;
188-
/** In conversation tracking, a flag identifying the first flow */
18991
_IsFirst?: string;
190-
/** In conversation tracking, a counter of flow logs per conversation */
19192
numFlowLogs?: number;
192-
/** User Defined Network identifier */
19393
UdnId?: string;
19494
}
19595

196-
export type Field = keyof Fields | keyof Labels;
96+
export enum FlowDirection {
97+
Ingress = '0',
98+
Egress = '1',
99+
Inner = '2',
100+
Both = '3'
101+
}
102+
103+
export const getDirectionDisplayString = (value: FlowDirection, t: TFunction) => {
104+
return value === FlowDirection.Ingress
105+
? t('Ingress')
106+
: value === FlowDirection.Egress
107+
? t('Egress')
108+
: value === FlowDirection.Inner
109+
? t('Inner')
110+
: value === FlowDirection.Both
111+
? t('Both')
112+
: t('n/a');
113+
};
114+
115+
export enum IfDirection {
116+
Ingress = '0',
117+
Egress = '1'
118+
}

web/src/api/loki.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { FlowScope, MetricType, StatFunction } from '../model/flow-query';
22
import { cyrb53 } from '../utils/hash';
33
import { getFunctionFromId, getRateFunctionFromId } from '../utils/overview-panels';
4-
import { Field, Fields, Labels, Record } from './ipfix';
4+
import { Field, Flow, Record } from './ipfix';
55

66
export interface AggregatedQueryResponse {
77
resultType: string;
@@ -39,16 +39,16 @@ export class GenericMetricsResult {
3939

4040
export const parseStream = (raw: StreamResult): Record[] => {
4141
return raw.values.map(v => {
42-
const fields = JSON.parse(v[1]) as Fields;
42+
const fields = JSON.parse(v[1]) as Flow;
4343
return {
44-
labels: raw.stream as unknown as Labels,
44+
labels: raw.stream as Flow,
4545
key: cyrb53(v.join(',')),
4646
fields: fields
4747
};
4848
});
4949
};
5050

51-
export interface RawTopologyMetric extends Fields, Labels {}
51+
export type RawTopologyMetric = Flow;
5252

5353
export interface RawTopologyMetrics {
5454
metric: RawTopologyMetric;

web/src/utils/__tests__/flows.spec.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Fields, FlowDirection, IfDirection, Record } from '../../api/ipfix';
1+
import { FlowDirection, IfDirection, Record } from '../../api/ipfix';
22
import { mergeFlowReporters } from '../flows';
33

44
describe('mergeFlowReporters', () => {
@@ -9,57 +9,57 @@ describe('mergeFlowReporters', () => {
99
const flows: Record[] = [
1010
{
1111
key: 1,
12-
fields: { SrcAddr: '10.0.0.1', DstAddr: '10.0.0.2' } as Fields,
12+
fields: { SrcAddr: '10.0.0.1', DstAddr: '10.0.0.2' },
1313
labels: { FlowDirection: FlowDirection.Ingress }
1414
},
1515
{
1616
key: 2,
17-
fields: { SrcAddr: '10.0.0.1', DstAddr: '10.0.0.2' } as Fields,
17+
fields: { SrcAddr: '10.0.0.1', DstAddr: '10.0.0.2' },
1818
labels: { FlowDirection: FlowDirection.Egress }
1919
},
2020
{
2121
key: 3,
22-
fields: { SrcAddr: '10.0.0.2', DstAddr: '10.0.0.1' } as Fields,
22+
fields: { SrcAddr: '10.0.0.2', DstAddr: '10.0.0.1' },
2323
labels: { FlowDirection: FlowDirection.Ingress }
2424
},
2525
{
2626
key: 4,
27-
fields: { SrcAddr: '10.0.0.2', DstAddr: '10.0.0.1' } as Fields,
27+
fields: { SrcAddr: '10.0.0.2', DstAddr: '10.0.0.1' },
2828
labels: { FlowDirection: FlowDirection.Egress }
2929
},
3030
{
3131
key: 5,
32-
fields: { SrcAddr: '10.0.0.1', DstAddr: '10.0.0.2' } as Fields,
32+
fields: { SrcAddr: '10.0.0.1', DstAddr: '10.0.0.2' },
3333
labels: { FlowDirection: FlowDirection.Ingress }
3434
},
3535
{
3636
key: 6,
37-
fields: { SrcAddr: '10.0.0.1', DstAddr: '10.0.0.2' } as Fields,
37+
fields: { SrcAddr: '10.0.0.1', DstAddr: '10.0.0.2' },
3838
labels: { FlowDirection: FlowDirection.Egress }
3939
},
4040
{
4141
key: 7,
42-
fields: { SrcAddr: '10.0.0.1', DstAddr: '43.75.13.32' } as Fields,
42+
fields: { SrcAddr: '10.0.0.1', DstAddr: '43.75.13.32' },
4343
labels: { FlowDirection: FlowDirection.Egress }
4444
},
4545
{
4646
key: 8,
47-
fields: { SrcAddr: '43.75.13.32', DstAddr: '10.0.0.1' } as Fields,
47+
fields: { SrcAddr: '43.75.13.32', DstAddr: '10.0.0.1' },
4848
labels: { FlowDirection: FlowDirection.Ingress }
4949
},
5050
{
5151
key: 9,
52-
fields: { SrcAddr: '10.0.0.1', DstAddr: '43.75.13.32' } as Fields,
52+
fields: { SrcAddr: '10.0.0.1', DstAddr: '43.75.13.32' },
5353
labels: { FlowDirection: FlowDirection.Egress }
5454
},
5555
{
5656
key: 10,
57-
fields: { SrcAddr: '10.0.0.1', DstAddr: '10.0.0.2', SrcPort: 8080 } as Fields,
57+
fields: { SrcAddr: '10.0.0.1', DstAddr: '10.0.0.2', SrcPort: 8080 },
5858
labels: { FlowDirection: FlowDirection.Ingress }
5959
},
6060
{
6161
key: 11,
62-
fields: { SrcAddr: '10.0.0.1', DstAddr: '10.0.0.2', SrcPort: 8080 } as Fields,
62+
fields: { SrcAddr: '10.0.0.1', DstAddr: '10.0.0.2', SrcPort: 8080 },
6363
labels: { FlowDirection: FlowDirection.Egress }
6464
}
6565
];
@@ -78,7 +78,7 @@ describe('mergeFlowReporters', () => {
7878
IfDirections: [IfDirection.Ingress, IfDirection.Egress],
7979
Interfaces: ['eth0', 'abcd'],
8080
Udns: ['udn1', 'udn2']
81-
} as Fields,
81+
},
8282
labels: { FlowDirection: FlowDirection.Ingress }
8383
},
8484
{
@@ -89,7 +89,7 @@ describe('mergeFlowReporters', () => {
8989
IfDirections: [IfDirection.Ingress],
9090
Interfaces: ['genev'],
9191
Udns: ['udn3']
92-
} as Fields,
92+
},
9393
labels: { FlowDirection: FlowDirection.Egress }
9494
}
9595
];
@@ -103,7 +103,7 @@ describe('mergeFlowReporters', () => {
103103
IfDirections: [IfDirection.Ingress, IfDirection.Egress, IfDirection.Ingress],
104104
Interfaces: ['eth0', 'abcd', 'genev'],
105105
Udns: ['udn1', 'udn2', 'udn3']
106-
} as Fields,
106+
},
107107
labels: { FlowDirection: FlowDirection.Ingress }
108108
});
109109
});

web/src/utils/column-parser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getRecordValue, Record } from '../api/ipfix';
1+
import { Field, getRecordValue, Record } from '../api/ipfix';
22
import { Column, ColumnConfigDef, ColumnsId, ColValue } from './columns';
33
import { FieldConfig, FieldType } from './fields';
44

@@ -19,7 +19,7 @@ const getColumnOrRecordValue = (
1919
}
2020
return defaultValue;
2121
}
22-
return getRecordValue(record, arg, defaultValue);
22+
return getRecordValue(record, arg as Field, defaultValue);
2323
};
2424

2525
const funcs: { [name: string]: (columns: Column[], record: Record, args: string[]) => ColValue } = {

0 commit comments

Comments
 (0)