Skip to content

Commit

Permalink
feat(Code): Begin work on TypeScript side of loading and dep injection
Browse files Browse the repository at this point in the history
  • Loading branch information
EntraptaJ committed Jan 23, 2021
1 parent 01c8a49 commit a01f613
Show file tree
Hide file tree
Showing 18 changed files with 245 additions and 112 deletions.
2 changes: 1 addition & 1 deletion nodemon.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"watch": ["src"],
"watch": ["src", "IPAM.yaml"],
"ext": "ts",
"ignore": ["src/**/*.test.ts"],
"exec": "npm run start:debug"
Expand Down
2 changes: 1 addition & 1 deletion schemas/IPAM.json
Original file line number Diff line number Diff line change
@@ -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":{"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"]}}},"required":["name","id","sites"]},"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","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","properties":{"id":{"type":"string","description":"Circuit ID"},"sideA":{"type":"object","properties":{"id":{"type":"string","description":"Circuit Location Id"}}},"sideZ":{"type":"object","properties":{"id":{"type":"string","description":"Circuit Location Id"}}},"speed":{"type":"string"}},"required":["id"]},"network":{"type":"object","additionalProperties":false,"description":"Network","properties":{"prefix":{"type":"string","description":"Network Prefix"},"description":{"type":"string"},"circuit":{"$ref":"#/definitions/networkcircuit"},"contact":{"type":"string","description":"Contact ID"},"hosts":{"type":"array","items":{"type":"object","additionalProperties":false,"description":"Indivual Network host","properties":{"ip":{"type":"string","description":"Host IP Address"},"hostname":{"type":"string","description":"Hostname for reverse DNS creation"},"description":{"type":"string"},"device":{"$ref":"#/definitions/networkDeviceLink"}},"required":["ip"]}},"ranges":{"type":"array","items":{"type":"object","additionalProperties":false,"description":"Network Range","properties":{"start":{"type":"string"},"end":{"type":"string"},"description":{"type":"string"},"type":{"type":"string","enum":["DHCP","RESERVED","STATIC"]}},"required":["start","end"]}},"networks":{"type":"array","items":{"$ref":"#/definitions/network"},"uniqueItems":true,"description":"Children Networks"}}},"networkDeviceType":{"type":"string","enum":["router","switch","access-point","server","modem","firewall"]},"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"]}
{"$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","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","properties":{"id":{"type":"string","description":"Circuit ID"},"sideA":{"type":"object","properties":{"id":{"type":"string","description":"Circuit Location Id"}}},"sideZ":{"type":"object","properties":{"id":{"type":"string","description":"Circuit Location Id"}}},"speed":{"type":"string"}},"required":["id"]},"network":{"type":"object","additionalProperties":false,"description":"Network","properties":{"prefix":{"type":"string","description":"Network Prefix"},"description":{"type":"string"},"circuit":{"$ref":"#/definitions/networkcircuit"},"contact":{"type":"string","description":"Contact ID"},"hosts":{"type":"array","items":{"type":"object","additionalProperties":false,"description":"Indivual Network host","properties":{"ip":{"type":"string","description":"Host IP Address"},"hostname":{"type":"string","description":"Hostname for reverse DNS creation"},"description":{"type":"string"},"device":{"$ref":"#/definitions/networkDeviceLink"}},"required":["ip"]}},"ranges":{"type":"array","items":{"type":"object","additionalProperties":false,"description":"Network Range","properties":{"start":{"type":"string"},"end":{"type":"string"},"description":{"type":"string"},"type":{"type":"string","enum":["DHCP","RESERVED","STATIC"]}},"required":["start","end"]}},"networks":{"type":"array","items":{"$ref":"#/definitions/network"},"uniqueItems":true,"description":"Children Networks"}}},"networkDeviceType":{"type":"string","enum":["router","switch","access-point","server","modem","firewall"]},"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"]}
28 changes: 28 additions & 0 deletions src/Modules/Communities/CommunitySchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// src/Modules/Communities/CommunitySchema.ts
import jsonSchema from 'fluent-json-schema';

export const communitySchema = jsonSchema
.object()
.additionalProperties(false)
.id('#community')
.description('Community')
.prop('contact', jsonSchema.string().description('Community Contact ID'))
.prop(
'name',
jsonSchema.string().description('Community Friendly Name').required(),
)
.prop(
'id',
jsonSchema
.string()
.description('Short form community code')
.examples(['sxl'])
.required(),
)
.prop(
'sites',
jsonSchema
.array()
.items(jsonSchema.ref('#/definitions/communitySite'))
.required(),
);
17 changes: 17 additions & 0 deletions src/Modules/Communities/CommunitySite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// src/Modules/Communities/CommunitySite.ts
import { Inject, InjectMany, Service } from 'typedi';
import { CommunitySite as IPAMCommunitySite } from '../IPAM/IPAMConfig.gen';
import { NetworkDevice } from '../NetworkDevices/NetworkDevice';

@Service()
export class CommunitySite implements IPAMCommunitySite {
public id: string;

public name: string;

public devices: NetworkDevice[];

public constructor(options: Partial<CommunitySite>) {
Object.assign(this, options);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// src/Modules/CommunitySites/CommunitySiteConfigSchema.ts
// src/Modules/Communities/CommunitySiteSchema.ts
import jsonSchema from 'fluent-json-schema';

export const communitySiteConfigSchema = jsonSchema
export const communitySiteSchema = jsonSchema
.object()
.additionalProperties(false)
.description('Community Site')
Expand Down
12 changes: 12 additions & 0 deletions src/Modules/CommunityContacts/CommunityContact.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// src/Modules/CommunityContacts/CommunityContact.ts
import { Contact as IPAMContact } from '../IPAM/IPAMConfig.gen';

export class Contact implements IPAMContact {
public id: string;

public name: string;

public constructor(options: Partial<Contact>) {
Object.assign(this, options);
}
}
4 changes: 0 additions & 4 deletions src/Modules/CommunitySites/CommunitySiteConfig.ts

This file was deleted.

13 changes: 12 additions & 1 deletion src/Modules/IPAM/Community.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
// src/Modules/Communities/Community.ts
import { Token } from 'typedi';
import Container, { Service, Token } from 'typedi';
import { CommunitySite } from '../Communities/CommunitySite';
import { Contact } from '../CommunityContacts/CommunityContact';

export const CommunitiesToken = new Token<string>('communities');

@Service()
export class Community {
public name: string;

public contactId: string;

public sites: CommunitySite[];

public get contact(): Contact {
return Container.get(`contact-${this.contactId}`);
}

public constructor(options: Partial<Community>) {
Object.assign(this, options);
}
Expand Down
16 changes: 0 additions & 16 deletions src/Modules/IPAM/CommunityConfig.ts

This file was deleted.

42 changes: 0 additions & 42 deletions src/Modules/IPAM/CommunityConfigController.ts

This file was deleted.

16 changes: 16 additions & 0 deletions src/Modules/IPAM/IPAM.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// src/Modules/IPAM/IPAM.ts

import { Service } from 'typedi';
import { Contact } from '../CommunityContacts/CommunityContact';
import { Community } from './Community';

@Service()
export class IPAM {
public contacts: Contact[];

public communities: Community[];

public constructor(options: Partial<IPAM>) {
Object.assign(this, options);
}
}
20 changes: 12 additions & 8 deletions src/Modules/IPAM/IPAMConfig.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,18 @@ export interface Community {
* Short form community code
*/
id: string;
sites: {
/**
* Site short id
*/
id: string;
name: string;
devices?: Device[];
}[];
sites: CommunitySite[];
}
/**
* Community Site
*/
export interface CommunitySite {
/**
* Site short id
*/
id: string;
name: string;
devices?: Device[];
}
/**
* Network Device
Expand Down
114 changes: 114 additions & 0 deletions src/Modules/IPAM/IPAMConfigController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// src/Modules/Communities/CommunityConfigController.ts
import { PathLike } from 'fs';
import { readFile } from 'fs/promises';
import { load } from 'js-yaml';
import Container, { Service } from 'typedi';
import { logger, LogMode } from '../../Library/Logger';
import { isObjectType } from '../../Utils/isTypes';
import { CommunitySite } from '../Communities/CommunitySite';
import { Contact } from '../CommunityContacts/CommunityContact';
import { NetworkDevice } from '../NetworkDevices/NetworkDevice';
import { Community } from './Community';
import {
IPAM,
Community as IPAMCommunity,
Contact as IPAMContact,
CommunitySite as IPAMCommunitySite,
Device as IPAMDevice,
} from './IPAMConfig.gen';

@Service()
export class IPAMConfigController {
public processContacts(contacts: IPAMContact[]): Contact[] {
return contacts.map((contactValues) => {
const contact = new Contact(contactValues);

Container.set(`contact-${contact.id}`, contact);

return contact;
});
}

public processSiteDevices(devices: IPAMDevice[]): NetworkDevice[] {
return devices.map((deviceValues) => {
const device = new NetworkDevice(deviceValues);

Container.set(`networkDevice-${device.id}`, device);

return device;
});
}

public processSites(sites: IPAMCommunitySite[]): CommunitySite[] {
return sites.map((communitySiteValues) => {
const communitySite = new CommunitySite({
...communitySiteValues,
devices:
typeof communitySiteValues.devices !== 'undefined'
? this.processSiteDevices(communitySiteValues.devices)
: [],
});

Container.set(`communitySite-${communitySite.id}`, communitySite);

return communitySite;
});
}

public processCommunities(communities: IPAMCommunity[]): Community[] {
return communities.map((communityValue) => {
const community = new Community({
contactId: communityValue.contact,
name: communityValue.name,
sites: this.processSites(communityValue.sites),
});

return community;
});
}

/**
* Load the configured firewalls configuration file from disk, parse the YAML and load into the class
*/
public async loadFile(filePath?: PathLike): Promise<void> {
const ipamConfigFilePath = filePath || 'ipam.yml';

const ipamFile = await readFile(ipamConfigFilePath);

const ipamConfigFile = load(ipamFile.toString());

if (isObjectType<IPAM>(ipamConfigFile, 'communities')) {
logger.log(
LogMode.INFO,
'Loaded Communities Configuration File',
ipamConfigFilePath,
);

logger.log(LogMode.DEBUG, `IPAMConfig: `, ipamConfigFile);

const contacts = this.processContacts(ipamConfigFile.contacts);
const communities = this.processCommunities(ipamConfigFile.communities);

const torontoCommunity = communities.find(
({ name }) => name === 'Toronto',
);

if (torontoCommunity) {
const device = torontoCommunity.sites[0].devices[0];

logger.log(
LogMode.DEBUG,
'Toronto: ',
device,
Container.get(`networkDevice-${device.id}`),
);
}

return;
}

throw new Error('Invlaid Firewalls configuration file');
}
}

export const ipamConfigController = new IPAMConfigController();
29 changes: 4 additions & 25 deletions src/Modules/IPAM/IPAMConfigSchema.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,23 @@
// src/Modules/Communities/CommunityConfigSchema.ts
import jsonSchema from 'fluent-json-schema';
import { circuitLocationSchema } from '../CommunityCircuits/CircuitLocationSchema';
import { communityCircuitConfigSchema } from '../CommunityCircuits/CommunityCircuitConfigSchema';
import { communityCircuitConfigSchema } from '../Communities/CommunityCircuitConfigSchema';
import { communityContactConfigSchema } from '../CommunityContacts/CommunityContactConfigSchema';
import { communitySiteConfigSchema } from '../CommunitySites/CommunitySiteConfigSchema';
import { communitySiteSchema } from '../Communities/CommunitySiteSchema';
import { networkCircuitSchema } from '../Networks/NetworkCircuitSchema';
import { networkSchema } from '../Networks/NetworkSchema';
import { networkDeviceConfigSchema } from '../NetworkDevices/NetworkDeviceConfigSchema';
import { NetworkDeviceInterfaceType } from '../NetworkDevices/NetworkDeviceInterfaceType';
import { networkDeviceLinkSchema } from '../NetworkDevices/NetworkDeviceLinkSchema';
import { NetworkDeviceType } from '../NetworkDevices/NetworkDeviceType';

const communitySchema = jsonSchema
.object()
.additionalProperties(false)
.id('#community')
.description('Community')
.prop('contact', jsonSchema.string().description('Community Contact ID'))
.prop(
'name',
jsonSchema.string().description('Community Friendly Name').required(),
)
.prop(
'id',
jsonSchema
.string()
.description('Short form community code')
.examples(['sxl'])
.required(),
)
.prop(
'sites',
jsonSchema.array().items(communitySiteConfigSchema).required(),
);
import { communitySchema } from '../Communities/CommunitySchema';

export const communityConfigSchema = jsonSchema
.object()
.additionalProperties(false)
.description('IPAM Configuration File')
.definition('community', communitySchema)
.definition('communitySite', communitySiteSchema)
.definition('contact', communityContactConfigSchema)
.definition('device', networkDeviceConfigSchema)
.definition('networkcircuit', networkCircuitSchema)
Expand Down
Loading

0 comments on commit a01f613

Please sign in to comment.