Skip to content

Commit 0a7782d

Browse files
committed
feat(Tracing): Support tracing devices and their interconnections
1 parent 4b0222a commit 0a7782d

File tree

11 files changed

+96
-10
lines changed

11 files changed

+96
-10
lines changed

schemas/IPAM.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"$schema":"http://json-schema.org/draft-07/schema#","definitions":{"community":{"type":"object","additionalProperties":false,"$id":"#community","description":"Community","properties":{"contact":{"type":"string","description":"Community Contact ID"},"name":{"type":"string","description":"Community Friendly Name"},"id":{"type":"string","description":"Short form community code","examples":["sxl"]},"sites":{"type":"array","items":{"$ref":"#/definitions/communitySite"}}},"required":["name","id","sites"]},"communitySite":{"type":"object","additionalProperties":false,"description":"Community Site","properties":{"id":{"type":"string","description":"Site short id"},"name":{"type":"string"},"devices":{"type":"array","items":{"$ref":"#/definitions/device"}}},"required":["id","name"]},"contact":{"type":"object","additionalProperties":false,"$id":"#contact","description":"Community Contact","properties":{"id":{"type":"string","description":"Unique contact ID"},"name":{"type":"string","description":"Contact Full Name"}},"required":["id","name"]},"device":{"type":"object","additionalProperties":false,"$id":"#device","description":"Network Device","properties":{"id":{"type":"string","description":"Chained ID"},"name":{"type":"string","description":"Friendly name"},"type":{"$ref":"#/definitions/networkDeviceType"}},"required":["id","name"]},"networkcircuit":{"type":"object","additionalProperties":false,"description":"NetworkCircuit","properties":{"id":{"type":"string","description":"Circuit Id"},"speed":{"type":"string","description":"Circuit Speed"}},"required":["id"]},"networkDeviceLink":{"type":"object","additionalProperties":false,"description":"Link a Network to a device","properties":{"id":{"type":"string","description":"Device id"},"interface":{"type":"string","description":"Device interface"}},"required":["id"]},"circuitLocation":{"type":"object","description":"Traditional external circuits","additionalProperties":false,"properties":{"id":{"type":"string","description":"External circuit id"},"provider":{"type":"string","description":"External circuit provider"},"communuity":{"type":"string","description":"Community ID"},"address":{"type":"string","description":"Address provided to external provider"},"demarcSpeed":{"type":"string","enum":["10M","100M","200M","300M","500M","1G","5G","10G"]}}},"circuit":{"type":"object","description":"Community Circuit","additionalProperties":false,"properties":{"id":{"type":"string","description":"Circuit ID"},"sideA":{"$ref":"#/definitions/circuitSide"},"sideZ":{"$ref":"#/definitions/circuitSide"},"speed":{"type":"string"}},"required":["id","sideA","sideZ"]},"circuitSide":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","description":"Circuit Location Id"}},"required":["id"]},"network":{"type":"object","additionalProperties":false,"description":"Network","properties":{"prefix":{"type":"string","description":"Network Prefix"},"description":{"type":"string"},"circuit":{"$ref":"#/definitions/networkcircuit"},"nsServers":{"type":"array","items":{"type":"string","description":"Reverse DNS NS Server","format":"hostname"}},"contactId":{"type":"string","description":"Contact ID"},"hosts":{"type":"array","items":{"$ref":"#/definitions/networkHost"}},"ranges":{"type":"array","items":{"$ref":"#/definitions/networkRange"}},"networks":{"type":"array","items":{"$ref":"#/definitions/network"},"uniqueItems":true,"description":"Children Networks"}}},"networkHost":{"type":"object","additionalProperties":false,"description":"Indivual Network host","properties":{"ip":{"type":"string","description":"Host IP Address","format":"ipv4"},"hostname":{"type":"string","description":"Hostname for reverse DNS creation","format":"hostname"},"description":{"type":"string"},"device":{"$ref":"#/definitions/networkDeviceLink"}},"required":["ip"]},"networkRange":{"type":"object","additionalProperties":false,"description":"Network Range","properties":{"start":{"type":"string","description":"Start IP for the range","format":"ipv4"},"end":{"type":"string","description":"End IP for the range","format":"ipv4"},"description":{"type":"string"},"type":{"type":"string","enum":["DHCP","RESERVED","STATIC"]}},"required":["start","end"]},"networkDeviceType":{"type":"string","enum":["router","switch","access-point","server","modem","firewall","UPS"]},"networkDeviceInterfaceType":{"type":"string","enum":["FastEthernet","GigabitEthernet","TenGigabitEthernet"]}},"type":"object","additionalProperties":false,"description":"IPAM Configuration File","properties":{"communities":{"type":"array","items":{"$ref":"#/definitions/community"}},"circuits":{"type":"array","items":{"$ref":"#/definitions/circuit"},"uniqueItems":true,"description":"Circuits"},"circuitLocations":{"type":"array","items":{"$ref":"#/definitions/circuitLocation"},"uniqueItems":true,"description":"External Circuits"},"contacts":{"type":"array","items":{"$ref":"#/definitions/contact"},"uniqueItems":true,"description":"Contact Information"},"networks":{"type":"array","items":{"$ref":"#/definitions/network"},"uniqueItems":true,"description":"Networks"}},"required":["communities","circuits","circuitLocations","contacts","networks"]}
1+
{"$schema":"http://json-schema.org/draft-07/schema#","definitions":{"community":{"type":"object","additionalProperties":false,"$id":"#community","description":"Community","properties":{"contact":{"type":"string","description":"Community Contact ID"},"name":{"type":"string","description":"Community Friendly Name"},"id":{"type":"string","description":"Short form community code","examples":["sxl"]},"sites":{"type":"array","items":{"$ref":"#/definitions/communitySite"}}},"required":["name","id","sites"]},"communitySite":{"type":"object","additionalProperties":false,"description":"Community Site","properties":{"id":{"type":"string","description":"Site short id"},"name":{"type":"string"},"devices":{"type":"array","items":{"$ref":"#/definitions/device"}}},"required":["id","name"]},"contact":{"type":"object","additionalProperties":false,"$id":"#contact","description":"Community Contact","properties":{"id":{"type":"string","description":"Unique contact ID"},"name":{"type":"string","description":"Contact Full Name"}},"required":["id","name"]},"device":{"type":"object","additionalProperties":false,"$id":"#device","description":"Network Device","properties":{"id":{"type":"string","description":"Chained ID"},"name":{"type":"string","description":"Friendly name"},"type":{"$ref":"#/definitions/networkDeviceType"}},"required":["id","name"]},"networkcircuit":{"type":"object","additionalProperties":false,"description":"NetworkCircuit","properties":{"id":{"type":"string","description":"Circuit Id"},"speed":{"type":"string","description":"Circuit Speed"}},"required":["id"]},"networkDeviceLink":{"type":"object","additionalProperties":false,"description":"Link a Network to a device","properties":{"id":{"type":"string","description":"Device id"},"interface":{"type":"string","description":"Device interface"}},"required":["id"]},"circuitLocation":{"type":"object","description":"Traditional external circuits","additionalProperties":false,"properties":{"id":{"type":"string","description":"External circuit id"},"provider":{"type":"string","description":"External circuit provider"},"communuity":{"type":"string","description":"Community ID"},"address":{"type":"string","description":"Address provided to external provider"},"demarcSpeed":{"type":"string","enum":["10M","100M","200M","300M","500M","1G","5G","10G"]}}},"circuit":{"type":"object","description":"Community Circuit","additionalProperties":false,"properties":{"id":{"type":"string","description":"Circuit ID"},"sideA":{"$ref":"#/definitions/circuitSide"},"sideZ":{"$ref":"#/definitions/circuitSide"},"speed":{"type":"string"}},"required":["id","sideA","sideZ"]},"circuitSide":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","description":"Circuit Location Id"}},"required":["id"]},"network":{"type":"object","additionalProperties":false,"description":"Network","properties":{"prefix":{"type":"string","description":"Network Prefix"},"description":{"type":"string"},"circuit":{"$ref":"#/definitions/networkcircuit"},"nsServers":{"type":"array","items":{"type":"string","description":"Reverse DNS NS Server","format":"hostname"}},"type":{"type":"string","description":"Network Type","enum":["UNALLOCATED","EXTERNAL"]},"contactId":{"type":"string","description":"Contact ID"},"hosts":{"type":"array","items":{"$ref":"#/definitions/networkHost"}},"ranges":{"type":"array","items":{"$ref":"#/definitions/networkRange"}},"networks":{"type":"array","items":{"$ref":"#/definitions/network"},"uniqueItems":true,"description":"Children Networks"}}},"networkHost":{"type":"object","additionalProperties":false,"description":"Indivual Network host","properties":{"ip":{"type":"string","description":"Host IP Address","format":"ipv4"},"hostname":{"type":"string","description":"Hostname for reverse DNS creation","format":"hostname"},"description":{"type":"string"},"device":{"$ref":"#/definitions/networkDeviceLink"}},"required":["ip"]},"networkRange":{"type":"object","additionalProperties":false,"description":"Network Range","properties":{"start":{"type":"string","description":"Start IP for the range","format":"ipv4"},"end":{"type":"string","description":"End IP for the range","format":"ipv4"},"description":{"type":"string"},"type":{"type":"string","enum":["DHCP","RESERVED","STATIC","FREE","unallocated"]}},"required":["start","end"]},"networkDeviceType":{"type":"string","enum":["router","switch","access-point","server","modem","firewall","UPS"]},"networkDeviceInterfaceType":{"type":"string","enum":["FastEthernet","GigabitEthernet","TenGigabitEthernet"]}},"type":"object","additionalProperties":false,"description":"IPAM Configuration File","properties":{"communities":{"type":"array","items":{"$ref":"#/definitions/community"}},"circuits":{"type":"array","items":{"$ref":"#/definitions/circuit"},"uniqueItems":true,"description":"Circuits"},"circuitLocations":{"type":"array","items":{"$ref":"#/definitions/circuitLocation"},"uniqueItems":true,"description":"External Circuits"},"contacts":{"type":"array","items":{"$ref":"#/definitions/contact"},"uniqueItems":true,"description":"Contact Information"},"networks":{"type":"array","items":{"$ref":"#/definitions/network"},"uniqueItems":true,"description":"Networks"}},"required":["communities","circuits","circuitLocations","contacts","networks"]}

src/Modules/IPAM/IPAMConfig.gen.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ export interface Network {
136136
description?: string;
137137
circuit?: Networkcircuit;
138138
nsServers?: string[];
139+
/**
140+
* Network Type
141+
*/
142+
type?: "UNALLOCATED" | "EXTERNAL";
139143
/**
140144
* Contact ID
141145
*/
@@ -201,5 +205,5 @@ export interface NetworkRange {
201205
*/
202206
end: string;
203207
description?: string;
204-
type?: "DHCP" | "RESERVED" | "STATIC";
208+
type?: "DHCP" | "RESERVED" | "STATIC" | "FREE" | "unallocated";
205209
}

src/Modules/IPAM/IPAMConfigController.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,21 @@ export class IPAMConfigController {
9999
});
100100
}
101101

102-
public processNetworkHosts(networkHosts: IPAMNetworkHost[]): NetworkHost[] {
102+
public processNetworkHosts(
103+
networkHosts: IPAMNetworkHost[],
104+
parentNetwork: Network,
105+
): NetworkHost[] {
103106
return networkHosts.map((networkHostValue) => {
104-
const networkHost = new NetworkHost(networkHostValue);
107+
const networkHost = new NetworkHost({
108+
...networkHostValue,
109+
parentNetworkId: parentNetwork.prefix,
110+
});
111+
112+
Container.set({
113+
id: `networkHost-${parentNetwork.prefix}`,
114+
multiple: true,
115+
value: networkHost,
116+
});
105117

106118
setContainer('NETWORK_HOST', networkHost.ip, networkHost);
107119

@@ -121,15 +133,17 @@ export class IPAMConfigController {
121133
? this.processNetworks(subNetworksValues)
122134
: [];
123135

124-
const hosts = hostsValue ? this.processNetworkHosts(hostsValue) : [];
125-
126136
const network = new Network({
127137
circuitId: circuit?.id,
128138
networks: subNetworks,
129-
hosts,
130139
...networkValues,
131140
});
132141

142+
const hosts = hostsValue
143+
? this.processNetworkHosts(hostsValue, network)
144+
: [];
145+
logger.log(LogMode.DEBUG, 'hosts', hosts);
146+
133147
setContainer('NETWORK', network.prefix, network);
134148

135149
return [network, ...subNetworks];

src/Modules/NetworkDevices/NetworkDevice.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
// src/Modules/NetworkDevices/NetworkDevice.ts
2-
import { Service } from 'typedi';
2+
import Container, { Service } from 'typedi';
33
import {
44
Device as IPAMDevice,
55
NetworkDeviceType,
66
} from '../IPAM/IPAMConfig.gen';
7+
import { NetworkHost } from '../Networks/NetworkHost';
78

89
@Service()
910
export class NetworkDevice implements IPAMDevice {
@@ -13,6 +14,25 @@ export class NetworkDevice implements IPAMDevice {
1314

1415
public type: NetworkDeviceType;
1516

17+
private deviceHosts: NetworkHost[];
18+
19+
public getDeviceHosts(): NetworkHost[] {
20+
if (!this.deviceHosts) {
21+
const deviceHosts = Container.getMany<NetworkHost>('NETWORK_HOST');
22+
this.deviceHosts = deviceHosts.filter(
23+
(deviceHost) => deviceHost.device?.id === this.id,
24+
);
25+
}
26+
27+
return this.deviceHosts;
28+
}
29+
30+
public getAllIPs(): string[] {
31+
return this.getDeviceHosts()
32+
.map(({ device, ip }) => (device?.id === this.id ? ip : undefined))
33+
.filter(Boolean) as string[];
34+
}
35+
1636
public constructor(options: Partial<NetworkDevice>) {
1737
Object.assign(this, options);
1838
}

src/Modules/Networks/Network.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@ export class Network implements IPAMNetwork {
2121

2222
public networks?: Network[];
2323

24-
public hosts: NetworkHost[];
24+
public get hosts(): NetworkHost[] {
25+
return Container.getMany(`networkHost-${this.prefix}`);
26+
}
2527

2628
public contactId?: string;
2729

30+
public free?: boolean;
31+
2832
public get contact(): Contact | undefined {
2933
if (this.contactId) {
3034
return Container.get(createContainerName('CONTACT', this.contactId));

src/Modules/Networks/NetworkHost.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
NetworkHost as IPAMNetworkHost,
77
} from '../IPAM/IPAMConfig.gen';
88
import { NetworkDevice } from '../NetworkDevices/NetworkDevice';
9+
import { Network } from './Network';
910

1011
@Service()
1112
export class NetworkHost implements IPAMNetworkHost {
@@ -17,6 +18,12 @@ export class NetworkHost implements IPAMNetworkHost {
1718

1819
public hostname?: string;
1920

21+
public parentNetworkId: string;
22+
23+
public get parentNetwork(): Network {
24+
return Container.get(createContainerName('NETWORK', this.parentNetworkId));
25+
}
26+
2027
public get coreDevice(): NetworkDevice | undefined {
2128
if (this.device?.id) {
2229
return Container.get(createContainerName('SITE_DEVICE', this.device.id));

src/Modules/Networks/NetworkRangeType.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ export enum NetworkRangeType {
33
DHCP = 'DHCP',
44
RESERVED = 'RESERVED',
55
STATIC = 'STATIC',
6+
FREE = 'FREE',
7+
UNALLOCATED = 'unallocated',
68
}

src/Modules/Networks/NetworkSchema.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// src/Modues/Network/NetworkSchema.ts
22
import jsonSchema from 'fluent-json-schema';
3+
import { NetworkType } from './NetworkType';
34

45
export const networkSchema = jsonSchema
56
.object()
@@ -19,6 +20,13 @@ export const networkSchema = jsonSchema
1920
.format(jsonSchema.FORMATS.HOSTNAME),
2021
),
2122
)
23+
.prop(
24+
'type',
25+
jsonSchema
26+
.string()
27+
.description(`Network Type`)
28+
.enum(Object.values(NetworkType)),
29+
)
2230
.prop('contactId', jsonSchema.string().description('Contact ID'))
2331
.prop(
2432
'hosts',
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// src/Modules/Networks/NetworkType.ts
2+
export enum NetworkType {
3+
UNALLOCATED = 'UNALLOCATED',
4+
EXTERNAL = 'EXTERNAL',
5+
}

src/Utils/Containers.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,13 @@ export function setContainer<T extends keyof typeof ContainerKeys>(
4242
value: ValueTypes[T],
4343
container = Container,
4444
): void {
45+
if (key === 'NETWORK_HOST') {
46+
container.set({
47+
id: key,
48+
value,
49+
multiple: true,
50+
});
51+
}
52+
4553
container.set(createContainerName(key, id), value);
4654
}

0 commit comments

Comments
 (0)