From 9523cd77033b9ab2332cffa84bc4cac2b2a9eaad Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 4 Feb 2025 14:17:51 +1000 Subject: [PATCH 1/5] Add missing IOS router settings in node configurator --- src/app/cartography/models/node.ts | 31 +++- .../ios/configurator-ios.component.html | 146 +++++++++++++++++- .../ios/configurator-ios.component.ts | 63 +++++++- src/app/services/ios-configuration.service.ts | 97 +++++++++++- 4 files changed, 329 insertions(+), 8 deletions(-) diff --git a/src/app/cartography/models/node.ts b/src/app/cartography/models/node.ts index b7adb8ca..7b5cfbdb 100644 --- a/src/app/cartography/models/node.ts +++ b/src/app/cartography/models/node.ts @@ -14,10 +14,12 @@ export class Properties { headless: boolean; linked_clone: boolean; on_close: string; - aux_type: boolean; - aux: number; ram: number; + system_id: string; + npe?: string; + midplane?: string; nvram: number; + image: string; usage: string; use_any_adapter: boolean; vmname: string; @@ -48,8 +50,20 @@ export class Properties { kernel_image: string; kernel_image_md5sum?: any; mac_address: string; + mac_addr: string; options: string; platform: string; + chassis?: string; + iomem?: number; + disk0: number; + disk1: number; + idlepc: string; + idlemax: number; + idlesleep: number; + exec_area: number; + mmap: boolean; + sparsemem: boolean; + auto_delete_disks: boolean; process_priority: string; qemu_path: string; environment: string; @@ -58,6 +72,17 @@ export class Properties { memory: number; tpm: boolean; uefi: boolean; + slot0?: string; + slot1?: string; + slot2?: string; + slot3?: string; + slot4?: string; + slot5?: string; + slot6?: string; + slot7?: string; + wic0?: string; + wic1?: string; + wic2?: string; } export class Node { @@ -67,6 +92,8 @@ export class Node { console_auto_start: boolean; console_host: string; console_type: string; + aux: number; + aux_type: boolean; custom_adapters?: any[]; ethernet_adapters?: any; serial_adapters?: any; diff --git a/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.html b/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.html index 456b11a6..0e119bef 100644 --- a/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.html +++ b/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.html @@ -7,11 +7,31 @@

Configurator for IOS router {{ name }}


+ Platform: {{ node.properties.platform }} + (chassis: {{ node.properties.chassis }}) +

+ + +
+ + + + {{ type }} + + + + + + + {{ type }} + + + @@ -36,23 +56,145 @@

Configurator for IOS router {{ name }}

- MB + MiB
- MB + MiB + + + % + + + + MiB + + + + MiB + + Automatically delete NVRAM and disk files
+
+ + +
+
Adapters
+
+
+ + + {{ "" }} + + + {{ option }} + + +
+
+
+
+
WICs
+
+
+ + + {{ "" }} + + + {{ option }} + + +
+
+
+
+ + + + + System + + + + +
+ + + +
+
+
+ + + Optimizations + +
+ + + +
+ + + + + + ms + + + + MiB + + Enable mmap support
+ Enable sparse memory support
+
+
diff --git a/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.ts b/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.ts index 0d14c702..187e666d 100644 --- a/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.ts +++ b/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.ts @@ -18,7 +18,14 @@ export class ConfiguratorDialogIosComponent implements OnInit { name: string; generalSettingsForm: UntypedFormGroup; memoryForm: UntypedFormGroup; + advancedSettingsForm: UntypedFormGroup; consoleTypes: string[] = []; + NPETypes: string[] = []; + MidplaneTypes: string[] = []; + networkAdaptersForNode: string[] = []; + wicsForNode: string[] = []; + adapterMatrix = {}; + wicMatrix = {}; constructor( public dialogRef: MatDialogRef, @@ -29,12 +36,20 @@ export class ConfiguratorDialogIosComponent implements OnInit { ) { this.generalSettingsForm = this.formBuilder.group({ name: new UntypedFormControl('', Validators.required), + path: new UntypedFormControl('', Validators.required), }); this.memoryForm = this.formBuilder.group({ ram: new UntypedFormControl('', Validators.required), nvram: new UntypedFormControl('', Validators.required), }); + + const mac_regex = /^([0-9a-fA-F]{4}\.){2}[0-9a-fA-F]{4}$|^$/ + const idlepc_regex = /^(0x[0-9a-fA-F]+)?$|^$/; + this.advancedSettingsForm = this.formBuilder.group({ + mac_addr: new UntypedFormControl('', Validators.pattern(mac_regex)), + idlepc: new UntypedFormControl('', Validators.pattern(idlepc_regex)), + }); } ngOnInit() { @@ -42,15 +57,61 @@ export class ConfiguratorDialogIosComponent implements OnInit { this.node = node; this.name = node.name; this.getConfiguration(); + this.fillSlotsData(); }); } getConfiguration() { this.consoleTypes = this.configurationService.getConsoleTypes(); + this.NPETypes = this.configurationService.getNPETypes(); + this.MidplaneTypes = this.configurationService.getMidplaneTypes(); + this.adapterMatrix = this.configurationService.getAdapterMatrix(); + this.wicMatrix = this.configurationService.getWicMatrix(); + } + + fillSlotsData() { + + // load network adapters + for (let i = 0; i <= 6; i++) { + if (this.node.properties[`slot${i}`]) { + this.networkAdaptersForNode[i] = this.node.properties[`slot${i}`]; + } + } + + // load WICs + for (let i = 0; i <= 3; i++) { + if (this.node.properties[`wic${i}`]) { + this.wicsForNode[i] = this.node.properties[`wic${i}`]; + } + } + } + + saveSlotsData() { + + // save network adapters + for (let i = 0; i <= 6; i++) { + if (this.adapterMatrix[this.node.properties.platform][this.node.properties.chassis || ''][i]) { + if (this.networkAdaptersForNode[i] === undefined) + this.node.properties[`slot${i}`] = "" + else + this.node.properties[`slot${i}`] = this.networkAdaptersForNode[i]; + } + } + + // save WICs + for (let i = 0; i <= 3; i++) { + if (this.wicMatrix[this.node.properties.platform][i]) { + if (this.wicsForNode[i] === undefined) + this.node.properties[`wic${i}`] = "" + else + this.node.properties[`wic${i}`] = this.wicsForNode[i]; + } + } } onSaveClick() { - if (this.generalSettingsForm.valid && this.memoryForm.valid) { + if (this.generalSettingsForm.valid && this.memoryForm.valid && this.advancedSettingsForm.valid) { + this.saveSlotsData(); this.nodeService.updateNode(this.controller, this.node).subscribe(() => { this.toasterService.success(`Node ${this.node.name} updated.`); this.onCancelClick(); diff --git a/src/app/services/ios-configuration.service.ts b/src/app/services/ios-configuration.service.ts index 145cf924..3013cea2 100644 --- a/src/app/services/ios-configuration.service.ts +++ b/src/app/services/ios-configuration.service.ts @@ -2,9 +2,6 @@ import { Injectable } from '@angular/core'; @Injectable() export class IosConfigurationService { - c1700_wics = ['WIC-1T', 'WIC-2T', 'WIC-1ENET']; - c2600_wics = ['WIC-1T', 'WIC-2T']; - c3700_wics = ['WIC-1T', 'WIC-2T']; c2600_nms = ['NM-1FE-TX', 'NM-1E', 'NM-4E', 'NM-16ESW']; c3600_nms = ['NM-1FE-TX', 'NM-1E', 'NM-4E', 'NM-16ESW', 'NM-4T']; @@ -12,6 +9,10 @@ export class IosConfigurationService { c7200_pas = ['PA-A1', 'PA-FE-TX', 'PA-2FE-TX', 'PA-GE', 'PA-4T+', 'PA-8T', 'PA-4E', 'PA-8E', 'PA-POS-OC3']; c7200_io = ['C7200-IO-FE', 'C7200-IO-2FE', 'C7200-IO-GE-E']; + c1700_wics = ['WIC-1T', 'WIC-2T', 'WIC-1ENET']; + c2600_wics = ['WIC-1T', 'WIC-2T']; + c3700_wics = ['WIC-1T', 'WIC-2T']; + getConsoleTypes() { return ['telnet', 'none']; } @@ -91,6 +92,96 @@ export class IosConfigurationService { }; } + getNPETypes() { + return ['npe-100', 'npe-150', 'npe-175', 'npe-200', 'npe-225', 'npe-300', 'npe-400', 'npe-g2']; + } + + getMidplaneTypes() { + return ['std', 'vxr']; + } + + getAdapterMatrix() { + + let adapter_matrix: any = {}; + for (let platform of ["c1700", "c2600", "c2691", "c3725", "c3745", "c3600", "c7200"]) { + adapter_matrix[platform] = {}; + } + + // 1700s have one interface on the MB, 2 sub-slots for WICs, and no NM slots + for (let chassis of ["1720", "1721", "1750", "1751", "1760"]) { + adapter_matrix["c1700"][chassis] = { 0: ["C1700-MB-1FE"] }; + } + + // Add a fake NM in slot 1 on 1751s and 1760s to provide two WIC slots + for (let chassis of ["1751", "1760"]) { + adapter_matrix["c1700"][chassis][1] = ["C1700-MB-WIC1"]; + } + + // 2600s have one or more interfaces on the MB, 2 subslots for WICs, and an available NM slot 1 + for (let chassis of ["2620", "2610XM", "2620XM", "2650XM"]) { + adapter_matrix["c2600"][chassis] = { 0: ["C2600-MB-1FE"], 1: this.c2600_nms }; + } + + for (let chassis of ["2621", "2611XM", "2621XM", "2651XM"]) { + adapter_matrix["c2600"][chassis] = { 0: ["C2600-MB-2FE"], 1: this.c2600_nms }; + } + + adapter_matrix["c2600"]["2610"] = { 0: ["C2600-MB-1E"], 1: this.c2600_nms }; + adapter_matrix["c2600"]["2611"] = { 0: ["C2600-MB-2E"], 1: this.c2600_nms }; + + // 2691s have two FEs on the motherboard and one NM slot + adapter_matrix["c2691"][""] = { 0: ["GT96100-FE"], 1: this.c3700_nms }; + + // 3620s have two generic NM slots + adapter_matrix["c3600"]["3620"] = {}; + for (let slot = 0; slot < 2; slot++) { + adapter_matrix["c3600"]["3620"][slot] = this.c3600_nms; + } + + // 3640s have four generic NM slots + adapter_matrix["c3600"]["3640"] = {}; + for (let slot = 0; slot < 4; slot++) { + adapter_matrix["c3600"]["3640"][slot] = this.c3600_nms; + } + + // 3660s have 2 FEs on the motherboard and 6 generic NM slots + adapter_matrix["c3600"]["3660"] = { 0: ["Leopard-2FE"] }; + for (let slot = 1; slot < 7; slot++) { + adapter_matrix["c3600"]["3660"][slot] = this.c3600_nms; + } + + // 3725s have 2 FEs on the motherboard and 2 generic NM slots + adapter_matrix["c3725"][""] = { 0: ["GT96100-FE"] }; + for (let slot = 1; slot < 3; slot++) { + adapter_matrix["c3725"][""][slot] = this.c3700_nms; + } + + // 3745s have 2 FEs on the motherboard and 4 generic NM slots + adapter_matrix["c3745"][""] = { 0: ["GT96100-FE"] }; + for (let slot = 1; slot < 5; slot++) { + adapter_matrix["c3745"][""][slot] = this.c3700_nms; + } + + // 7206s allow an IO controller in slot 0, and a generic PA in slots 1-6 + adapter_matrix["c7200"][""] = { 0: ["IO_C7200"] }; + for (let slot = 1; slot < 7; slot++) { + adapter_matrix["c7200"][""][slot] = this.c7200_pas; + } + + return adapter_matrix; + } + + getWicMatrix() { + let wic_matrix: any = {}; + + wic_matrix["c1700"] = { 0: this.c1700_wics, 1: this.c1700_wics }; + wic_matrix["c2600"] = { 0: this.c2600_wics, 1: this.c2600_wics, 2: this.c2600_wics }; + wic_matrix["c2691"] = { 0: this.c3700_wics, 1: this.c3700_wics, 2: this.c3700_wics }; + wic_matrix["c3725"] = { 0: this.c3700_wics, 1: this.c3700_wics, 2: this.c3700_wics }; + wic_matrix["c3745"] = { 0: this.c3700_wics, 1: this.c3700_wics, 2: this.c3700_wics }; + return wic_matrix; + } + getNetworkModules() { return { c1700: { From 80884a79290291006d0e716a5e2d1117d132e518 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 4 Feb 2025 14:23:32 +1000 Subject: [PATCH 2/5] Fix aux and aux_type usage --- src/app/cartography/models/node.ts | 4 ++-- .../configurator/ios/configurator-ios.component.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/cartography/models/node.ts b/src/app/cartography/models/node.ts index 7b5cfbdb..a92c836f 100644 --- a/src/app/cartography/models/node.ts +++ b/src/app/cartography/models/node.ts @@ -14,6 +14,8 @@ export class Properties { headless: boolean; linked_clone: boolean; on_close: string; + aux: number; + aux_type: boolean; ram: number; system_id: string; npe?: string; @@ -92,8 +94,6 @@ export class Node { console_auto_start: boolean; console_host: string; console_type: string; - aux: number; - aux_type: boolean; custom_adapters?: any[]; ethernet_adapters?: any; serial_adapters?: any; diff --git a/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.html b/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.html index 0e119bef..296f8acf 100644 --- a/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.html +++ b/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.html @@ -40,7 +40,7 @@

Configurator for IOS router {{ name }}

- + {{ type }} From 86db2e208c30aaf405ce2e08fb05193e198e237e Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 4 Feb 2025 21:00:20 +1000 Subject: [PATCH 3/5] Fix and improve IOS template configuration --- .../add-ios-template.component.html | 76 ++++---- .../add-ios-template.component.ts | 102 +++++----- .../ios-template-details.component.html | 79 ++++---- .../ios-template-details.component.ts | 76 +++++--- .../ios/configurator-ios.component.html | 61 +++--- .../ios/configurator-ios.component.ts | 6 +- src/app/services/ios-configuration.service.ts | 174 +----------------- 7 files changed, 203 insertions(+), 371 deletions(-) diff --git a/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.html b/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.html index 10e77a28..59b44551 100644 --- a/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.html +++ b/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.html @@ -109,32 +109,24 @@

New IOS router template

- -
-
+
+
+ {{ "" }} + + {{ option }} @@ -144,33 +136,33 @@

New IOS router template

- -
-
- +
+ + + {{ "" }} + + - - {{ option }} - - -
+ {{ option }} + +
- - - +
+ + + +
diff --git a/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.ts b/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.ts index c43e91eb..7fc7bc80 100644 --- a/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.ts +++ b/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.ts @@ -32,11 +32,8 @@ export class AddIosTemplateComponent implements OnInit, OnDestroy { iosImageForm: UntypedFormGroup; iosNameForm: UntypedFormGroup; iosMemoryForm: UntypedFormGroup; + iosIdlePCForm: UntypedFormGroup; selectedPlatform: string; - - networkAdaptersForTemplate: string[] = []; - networkModulesForTemplate: string[] = []; - iosImages: IosImage[] = []; platforms: string[] = []; platformsWithEtherSwitchRouterOption = {}; @@ -44,9 +41,10 @@ export class AddIosTemplateComponent implements OnInit, OnDestroy { chassis = {}; defaultRam = {}; defaultNvram = {}; - networkAdapters = {}; - networkAdaptersForPlatform = {}; - networkModules = {}; + networkAdaptersForTemplate: string[] = []; + wicsForTemplate: string[] = []; + adapterMatrix = {}; + wicMatrix = {}; ciscoUrl: string = 'https://cfn.cloudapps.cisco.com/ITDIT/CFN/jsp/SearchBySoftware.jsp'; uploader: FileUploader; @@ -82,6 +80,10 @@ export class AddIosTemplateComponent implements OnInit, OnDestroy { this.iosMemoryForm = this.formBuilder.group({ memory: new UntypedFormControl(null, [Validators.required]), }); + + this.iosIdlePCForm = this.formBuilder.group({ + idlepc: new UntypedFormControl(null, [Validators.pattern(this.iosConfigurationService.getIdlepcRegex())]), + }); } ngOnInit() { @@ -120,19 +122,31 @@ export class AddIosTemplateComponent implements OnInit, OnDestroy { this.templateMocksService.getIosTemplate().subscribe((iosTemplate: IosTemplate) => { this.iosTemplate = iosTemplate; - - this.networkModules = this.iosConfigurationService.getNetworkModules(); - this.networkAdaptersForPlatform = this.iosConfigurationService.getNetworkAdaptersForPlatform(); - this.networkAdapters = this.iosConfigurationService.getNetworkAdapters(); this.platforms = this.iosConfigurationService.getAvailablePlatforms(); this.platformsWithEtherSwitchRouterOption = this.iosConfigurationService.getPlatformsWithEtherSwitchRouterOption(); this.platformsWithChassis = this.iosConfigurationService.getPlatformsWithChassis(); this.chassis = this.iosConfigurationService.getChassis(); this.defaultRam = this.iosConfigurationService.getDefaultRamSettings(); + this.adapterMatrix = this.iosConfigurationService.getAdapterMatrix(); + this.wicMatrix = this.iosConfigurationService.getWicMatrix(); }); }); } + fillDefaultSlots() { + + console.log("Fill default slots"); + if (this.iosNameForm.get('platform').value) { + for (let i = 0; i <= 6; i++) { + let adapters = this.adapterMatrix[this.iosNameForm.get('platform').value][this.iosNameForm.get('chassis').value || ''][i]; + if (adapters && (adapters.length === 1 || adapters[0].startsWith('C7200'))) { + console.log("Set default adapter for slot" + i + " to " + adapters[0]); + this.networkAdaptersForTemplate[i] = adapters[0]; + } + } + } + } + setControllerType(controllerType: string) { if (controllerType === 'local') { this.isLocalComputerChosen = true; @@ -166,6 +180,7 @@ export class AddIosTemplateComponent implements OnInit, OnDestroy { if ( !this.iosImageForm.invalid && !this.iosMemoryForm.invalid && + !this.iosIdlePCForm.invalid && this.iosNameForm.get('templateName').value && this.iosNameForm.get('platform').value ) { @@ -184,7 +199,7 @@ export class AddIosTemplateComponent implements OnInit, OnDestroy { } if (this.networkAdaptersForTemplate.length > 0) this.completeAdaptersData(); - if (this.networkModulesForTemplate.length > 0) this.completeModulesData(); + if (this.wicsForTemplate.length > 0) this.completeWicsData(); this.iosTemplate.compute_id = 'local'; this.iosService.addTemplate(this.controller, this.iosTemplate).subscribe((template: IosTemplate) => { @@ -196,44 +211,25 @@ export class AddIosTemplateComponent implements OnInit, OnDestroy { } completeAdaptersData() { - if (this.chassis[this.iosTemplate.platform]) { - if (Object.keys(this.networkAdapters[this.iosTemplate.chassis])) { - for (let i = 0; i < Object.keys(this.networkAdapters[this.iosTemplate.chassis]).length; i++) { - if (!this.networkAdaptersForTemplate[i]) this.networkAdaptersForTemplate[i] = ''; - } - } - } else { - if (this.networkAdaptersForPlatform[this.iosNameForm.get('platform').value]) { - for ( - let i = 0; - i < Object.keys(this.networkAdaptersForPlatform[this.iosNameForm.get('platform').value]).length; - i++ - ) { - if (!this.networkAdaptersForTemplate[i]) this.networkAdaptersForTemplate[i] = ''; - } + for (let i = 0; i <= 6; i++) { + if (this.adapterMatrix[this.iosTemplate.platform][this.iosTemplate.chassis || ''][i]) { + if (this.networkAdaptersForTemplate[i] === undefined) + this.iosTemplate[`slot${i}`] = "" + else + this.iosTemplate[`slot${i}`] = this.networkAdaptersForTemplate[i]; } } - - if (this.networkAdaptersForTemplate[0]) this.iosTemplate.slot0 = this.networkAdaptersForTemplate[0]; - if (this.networkAdaptersForTemplate[1]) this.iosTemplate.slot1 = this.networkAdaptersForTemplate[1]; - if (this.networkAdaptersForTemplate[2]) this.iosTemplate.slot2 = this.networkAdaptersForTemplate[2]; - if (this.networkAdaptersForTemplate[3]) this.iosTemplate.slot3 = this.networkAdaptersForTemplate[3]; - if (this.networkAdaptersForTemplate[4]) this.iosTemplate.slot4 = this.networkAdaptersForTemplate[4]; - if (this.networkAdaptersForTemplate[5]) this.iosTemplate.slot5 = this.networkAdaptersForTemplate[5]; - if (this.networkAdaptersForTemplate[6]) this.iosTemplate.slot6 = this.networkAdaptersForTemplate[6]; - if (this.networkAdaptersForTemplate[7]) this.iosTemplate.slot7 = this.networkAdaptersForTemplate[7]; } - completeModulesData() { - if (Object.keys(this.networkModules[this.iosTemplate.platform])) { - for (let i = 0; i < Object.keys(this.networkModules[this.iosTemplate.platform]).length; i++) { - if (!this.networkModulesForTemplate[i]) this.networkModulesForTemplate[i] = ''; + completeWicsData() { + for (let i = 0; i <= 3; i++) { + if (this.wicMatrix[this.iosTemplate.platform][i]) { + if (this.wicsForTemplate[i] === undefined) + this.iosTemplate[`wic${i}`] = "" + else + this.iosTemplate[`wic${i}`] = this.wicsForTemplate[i]; } } - - if (this.networkModulesForTemplate[0]) this.iosTemplate.wic0 = this.networkModulesForTemplate[0]; - if (this.networkModulesForTemplate[1]) this.iosTemplate.wic1 = this.networkModulesForTemplate[1]; - if (this.networkModulesForTemplate[2]) this.iosTemplate.wic2 = this.networkModulesForTemplate[2]; } goBack() { @@ -252,25 +248,31 @@ export class AddIosTemplateComponent implements OnInit, OnDestroy { this.selectedPlatform = name; } - if (name === 'c1700') { - this.iosNameForm.controls['chassis'].setValue('1720'); + if (name === 'c3620' || name === 'c3640' || name === 'c3660') + this.iosNameForm.controls['chassis'].setValue(name.substring(1)); + else if (name === 'c1700') { + this.iosNameForm.controls['chassis'].setValue('1760'); } else if (name === 'c2600') { - this.iosNameForm.controls['chassis'].setValue('2610'); + this.iosNameForm.controls['chassis'].setValue('2651XM'); } else { this.iosNameForm.controls['chassis'].setValue(''); } - - this.iosMemoryForm.controls['memory'].setValue(this.defaultRam[name]); + this.iosMemoryForm.controls['memory'].setValue(this.defaultRam[this.selectedPlatform]); + this.fillDefaultSlots(); } onPlatformChosen() { this.iosTemplate.chassis = ''; this.networkAdaptersForTemplate = []; - this.networkModulesForTemplate = []; + this.wicsForTemplate = []; + if (!this.chassis[this.iosNameForm.get('platform').value]) + this.fillDefaultSlots(); } onChassisChosen() { this.networkAdaptersForTemplate = []; + if (this.chassis[this.iosNameForm.get('platform').value]) + this.fillDefaultSlots(); } cancelUploading() { diff --git a/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.html b/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.html index aba53f1d..34de0eba 100644 --- a/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.html +++ b/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.html @@ -169,60 +169,47 @@

IOS router template configuration

Slots
Adapters
-
-
- + + - - {{ option }} - - -
+ {{ "" }} + + + {{ option }} + +
-
-
+
+
+
WICs
+
- + + {{ "" }} + + {{ option }}
-

-
WICs
-
- - - {{ option }} - - -
-
- - - {{ option }} - - -
-
- - - {{ option }} - - -
@@ -240,8 +227,8 @@
WICs
WICs { this.iosTemplate = iosTemplate; - - this.fillAdaptersData(); + this.fillSlotsData(); }); }); } getConfiguration() { - this.networkModules = this.iosConfigurationService.getNetworkModules(); - this.networkAdaptersForPlatform = this.iosConfigurationService.getNetworkAdaptersForPlatform(); - this.networkAdapters = this.iosConfigurationService.getNetworkAdapters(); this.platforms = this.iosConfigurationService.getAvailablePlatforms(); this.platformsWithEtherSwitchRouterOption = this.iosConfigurationService.getPlatformsWithEtherSwitchRouterOption(); this.platformsWithChassis = this.iosConfigurationService.getPlatformsWithChassis(); @@ -95,35 +91,55 @@ export class IosTemplateDetailsComponent implements OnInit { this.defaultRam = this.iosConfigurationService.getDefaultRamSettings(); this.consoleTypes = this.iosConfigurationService.getConsoleTypes(); this.categories = this.iosConfigurationService.getCategories(); + this.adapterMatrix = this.iosConfigurationService.getAdapterMatrix(); + this.wicMatrix = this.iosConfigurationService.getWicMatrix(); } - fillAdaptersData() { - if (this.iosTemplate.slot0) this.networkAdaptersForTemplate[0] = this.iosTemplate.slot0; - if (this.iosTemplate.slot1) this.networkAdaptersForTemplate[1] = this.iosTemplate.slot1; - if (this.iosTemplate.slot2) this.networkAdaptersForTemplate[2] = this.iosTemplate.slot2; - if (this.iosTemplate.slot3) this.networkAdaptersForTemplate[3] = this.iosTemplate.slot3; - if (this.iosTemplate.slot4) this.networkAdaptersForTemplate[4] = this.iosTemplate.slot4; - if (this.iosTemplate.slot5) this.networkAdaptersForTemplate[5] = this.iosTemplate.slot5; - if (this.iosTemplate.slot6) this.networkAdaptersForTemplate[6] = this.iosTemplate.slot6; - if (this.iosTemplate.slot7) this.networkAdaptersForTemplate[7] = this.iosTemplate.slot7; + fillSlotsData() { + + // load network adapters + for (let i = 0; i <= 6; i++) { + if (this.iosTemplate[`slot${i}`]) { + this.networkAdaptersForTemplate[i] = this.iosTemplate[`slot${i}`]; + } + } + + // load WICs + for (let i = 0; i <= 3; i++) { + if (this.iosTemplate[`wic${i}`]) { + this.wicsForTemplate[i] = this.iosTemplate[`wic${i}`]; + } + } } - completeAdaptersData() { - if (this.networkAdaptersForTemplate[0]) this.iosTemplate.slot0 = this.networkAdaptersForTemplate[0]; - if (this.networkAdaptersForTemplate[1]) this.iosTemplate.slot1 = this.networkAdaptersForTemplate[1]; - if (this.networkAdaptersForTemplate[2]) this.iosTemplate.slot2 = this.networkAdaptersForTemplate[2]; - if (this.networkAdaptersForTemplate[3]) this.iosTemplate.slot3 = this.networkAdaptersForTemplate[3]; - if (this.networkAdaptersForTemplate[4]) this.iosTemplate.slot4 = this.networkAdaptersForTemplate[4]; - if (this.networkAdaptersForTemplate[5]) this.iosTemplate.slot5 = this.networkAdaptersForTemplate[5]; - if (this.networkAdaptersForTemplate[6]) this.iosTemplate.slot6 = this.networkAdaptersForTemplate[6]; - if (this.networkAdaptersForTemplate[7]) this.iosTemplate.slot7 = this.networkAdaptersForTemplate[7]; + saveSlotsData() { + + // save network adapters + for (let i = 0; i <= 6; i++) { + if (this.adapterMatrix[this.iosTemplate.platform][this.iosTemplate.chassis || ''][i]) { + if (this.networkAdaptersForTemplate[i] === undefined) + this.iosTemplate[`slot${i}`] = "" + else + this.iosTemplate[`slot${i}`] = this.networkAdaptersForTemplate[i]; + } + } + + // save WICs + for (let i = 0; i <= 3; i++) { + if (this.wicMatrix[this.iosTemplate.platform][i]) { + if (this.wicsForTemplate[i] === undefined) + this.iosTemplate[`wic${i}`] = "" + else + this.iosTemplate[`wic${i}`] = this.wicsForTemplate[i]; + } + } } onSave() { if (this.generalSettingsForm.invalid || this.memoryForm.invalid || this.advancedForm.invalid) { this.toasterService.error(`Fill all required fields`); } else { - this.completeAdaptersData(); + this.saveSlotsData(); this.iosService.saveTemplate(this.controller, this.iosTemplate).subscribe((iosTemplate: IosTemplate) => { this.toasterService.success('Changes saved'); diff --git a/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.html b/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.html index 296f8acf..2a4fcddd 100644 --- a/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.html +++ b/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.html @@ -113,47 +113,46 @@

Configurator for IOS router {{ name }}


Adapters
-
+ + + {{ "" }} + + + {{ option }} + + +
+
+
+
WICs
+
- + {{ "" }} - + {{ option }}
-
-
-
WICs
-
-
- - - {{ "" }} - - - {{ option }} - - -
-
-
diff --git a/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.ts b/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.ts index 187e666d..9821a486 100644 --- a/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.ts +++ b/src/app/components/project-map/node-editors/configurator/ios/configurator-ios.component.ts @@ -44,11 +44,9 @@ export class ConfiguratorDialogIosComponent implements OnInit { nvram: new UntypedFormControl('', Validators.required), }); - const mac_regex = /^([0-9a-fA-F]{4}\.){2}[0-9a-fA-F]{4}$|^$/ - const idlepc_regex = /^(0x[0-9a-fA-F]+)?$|^$/; this.advancedSettingsForm = this.formBuilder.group({ - mac_addr: new UntypedFormControl('', Validators.pattern(mac_regex)), - idlepc: new UntypedFormControl('', Validators.pattern(idlepc_regex)), + mac_addr: new UntypedFormControl('', Validators.pattern(this.configurationService.getMacAddrRegex())), + idlepc: new UntypedFormControl('', Validators.pattern(this.configurationService.getIdlepcRegex())), }); } diff --git a/src/app/services/ios-configuration.service.ts b/src/app/services/ios-configuration.service.ts index 3013cea2..a5fd0231 100644 --- a/src/app/services/ios-configuration.service.ts +++ b/src/app/services/ios-configuration.service.ts @@ -46,10 +46,7 @@ export class IosConfigurationService { c1700: 128, c2600: 128, c2691: 256, - c3600: 192, - c3620: 192, - c3640: 192, - c3660: 192, + c3600: 256, c3725: 256, c3745: 256, c7200: 512, @@ -163,7 +160,7 @@ export class IosConfigurationService { } // 7206s allow an IO controller in slot 0, and a generic PA in slots 1-6 - adapter_matrix["c7200"][""] = { 0: ["IO_C7200"] }; + adapter_matrix["c7200"][""] = { 0: this.c7200_io }; for (let slot = 1; slot < 7; slot++) { adapter_matrix["c7200"][""][slot] = this.c7200_pas; } @@ -182,170 +179,11 @@ export class IosConfigurationService { return wic_matrix; } - getNetworkModules() { - return { - c1700: { - 0: this.c1700_wics, - 1: this.c1700_wics, - }, - c2600: { - 0: this.c2600_wics, - 1: this.c2600_wics, - 2: this.c2600_wics, - }, - c2691: { - 0: this.c3700_wics, - 1: this.c3700_wics, - 2: this.c3700_wics, - }, - c3725: { - 0: this.c3700_wics, - 1: this.c3700_wics, - 2: this.c3700_wics, - }, - c3745: { - 0: this.c3700_wics, - 1: this.c3700_wics, - 2: this.c3700_wics, - }, - }; - } - - getNetworkAdapters() { - return { - '1720': { - 0: ['C1700-MB-1FE'], - }, - '1721': { - 0: ['C1700-MB-1FE'], - }, - '1750': { - 0: ['C1700-MB-1FE'], - }, - '1751': { - 0: ['C1700-MB-1FE'], - 1: ['C1700-MB-WIC1'], - }, - '1760': { - 0: ['C1700-MB-1FE'], - 1: ['C1700-MB-WIC1'], - }, - '2610': { - 0: ['C2600-MB-1E'], - 1: this.c2600_nms, - }, - '2611': { - 0: ['C2600-MB-2E'], - 1: this.c2600_nms, - }, - '2620': { - 0: ['C2600-MB-1FE'], - 1: this.c2600_nms, - }, - '2621': { - 0: ['C2600-MB-2FE'], - 1: this.c2600_nms, - }, - '2610XM': { - 0: ['C2600-MB-1FE'], - 1: this.c2600_nms, - }, - '2611XM': { - 0: ['C2600-MB-2FE'], - 1: this.c2600_nms, - }, - '2620XM': { - 0: ['C2600-MB-1FE'], - 1: this.c2600_nms, - }, - '2621XM': { - 0: ['C2600-MB-2FE'], - 1: this.c2600_nms, - }, - '2650XM': { - 0: ['C2600-MB-1FE'], - 1: this.c2600_nms, - }, - '2651XM': { - 0: ['C2600-MB-2FE'], - 1: this.c2600_nms, - }, - '3620': { - 0: this.c3600_nms, - 1: this.c3600_nms, - }, - '3640': { - 0: this.c3600_nms, - 1: this.c3600_nms, - 2: this.c3600_nms, - 3: this.c3600_nms, - }, - '3660': { - 0: ['Leopard-2FE'], - 1: this.c3600_nms, - 2: this.c3600_nms, - 3: this.c3600_nms, - 4: this.c3600_nms, - 5: this.c3600_nms, - 6: this.c3600_nms, - }, - }; + getIdlepcRegex() { + return /^(0x[0-9a-fA-F]+)?$|^$/; } - getNetworkAdaptersForPlatform() { - let networkAdaptersForPlatform = {}; - networkAdaptersForPlatform['c2691'] = { - 0: ['GT96100-FE'], - 1: this.c3700_nms, - }; - networkAdaptersForPlatform['c3725'] = { - 0: ['GT96100-FE'], - 1: this.c3700_nms, - 2: this.c3700_nms, - }; - networkAdaptersForPlatform['c3745'] = { - 0: ['GT96100-FE'], - 1: this.c3700_nms, - 2: this.c3700_nms, - 3: this.c3700_nms, - 4: this.c3700_nms, - }; - networkAdaptersForPlatform['c7200'] = { - 0: this.c7200_io, - 1: this.c7200_pas, - 2: this.c7200_pas, - 3: this.c7200_pas, - 4: this.c7200_pas, - 5: this.c7200_pas, - 6: this.c7200_pas, - }; - - return { - c2691: { - 0: ['GT96100-FE'], - 1: this.c3700_nms, - }, - c3725: { - 0: ['GT96100-FE'], - 1: this.c3700_nms, - 2: this.c3700_nms, - }, - c3745: { - 0: ['GT96100-FE'], - 1: this.c3700_nms, - 2: this.c3700_nms, - 3: this.c3700_nms, - 4: this.c3700_nms, - }, - c7200: { - 0: this.c7200_io, - 1: this.c7200_pas, - 2: this.c7200_pas, - 3: this.c7200_pas, - 4: this.c7200_pas, - 5: this.c7200_pas, - 6: this.c7200_pas, - }, - }; + getMacAddrRegex() { + return /^([0-9a-fA-F]{4}\.){2}[0-9a-fA-F]{4}$|^$/; } } From 10c1461d93197569d2fa89a9142220bb46fc8e53 Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 4 Feb 2025 21:45:22 +1000 Subject: [PATCH 4/5] Fix tests --- .../ios-template-details.component.spec.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.spec.ts b/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.spec.ts index 9e6e4743..bed948fb 100644 --- a/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.spec.ts +++ b/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.spec.ts @@ -94,9 +94,10 @@ describe('IosTemplateDetailsComponent', () => { component.advancedForm.controls['idlemax'].setValue('0'); component.advancedForm.controls['idlesleep'].setValue('0'); component.advancedForm.controls['execarea'].setValue('0'); - + component.advancedForm.controls['idlepc'].setValue('0x0'); + component.advancedForm.controls['mac_addr'].setValue(''); + spyOn(component, 'saveSlotsData').and.returnValue(); component.onSave(); - expect(mockedIosService.saveTemplate).toHaveBeenCalled(); }); }); From 55bc69389d8bdf0f40e5fb5480d8f7f84a73e264 Mon Sep 17 00:00:00 2001 From: grossmj Date: Wed, 5 Feb 2025 20:02:58 +1000 Subject: [PATCH 5/5] Add missing adapter and mac address settings for Qemu and Docker nodes --- src/app/cartography/models/node.ts | 1 + .../docker/configurator-docker.component.html | 20 ++++++--- .../docker/configurator-docker.component.ts | 1 + .../qemu/configurator-qemu.component.html | 42 +++++++++++++++---- .../qemu/configurator-qemu.component.ts | 25 ++++++----- .../services/docker-configuration.service.ts | 4 ++ .../services/qemu-configuration.service.ts | 32 ++------------ 7 files changed, 75 insertions(+), 50 deletions(-) diff --git a/src/app/cartography/models/node.ts b/src/app/cartography/models/node.ts index a92c836f..bad991c8 100644 --- a/src/app/cartography/models/node.ts +++ b/src/app/cartography/models/node.ts @@ -70,6 +70,7 @@ export class Properties { qemu_path: string; environment: string; extra_hosts: string; + start_command: string; replicate_network_connection_state: boolean; memory: number; tpm: boolean; diff --git a/src/app/components/project-map/node-editors/configurator/docker/configurator-docker.component.html b/src/app/components/project-map/node-editors/configurator/docker/configurator-docker.component.html index 7be22add..bcb467f1 100644 --- a/src/app/components/project-map/node-editors/configurator/docker/configurator-docker.component.html +++ b/src/app/components/project-map/node-editors/configurator/docker/configurator-docker.component.html @@ -33,17 +33,27 @@

Configurator for node {{ name }}

- + + + + + MB - + - + + + Configurator for Qemu VM {{ name }}

-
+ + + +
+ + + +
+ + + {{ type.name }} ({{ type.value }}) + + + + + +

Replicate network connection state - + + + + + +
diff --git a/src/app/components/project-map/node-editors/configurator/qemu/configurator-qemu.component.ts b/src/app/components/project-map/node-editors/configurator/qemu/configurator-qemu.component.ts index 130904f4..4a17f44a 100644 --- a/src/app/components/project-map/node-editors/configurator/qemu/configurator-qemu.component.ts +++ b/src/app/components/project-map/node-editors/configurator/qemu/configurator-qemu.component.ts @@ -22,6 +22,7 @@ export class ConfiguratorDialogQemuComponent implements OnInit { node: Node; name: string; generalSettingsForm: UntypedFormGroup; + networkSettingsForm: UntypedFormGroup; consoleTypes: string[] = []; onCloseOptions = []; bootPriorities = []; @@ -54,6 +55,10 @@ export class ConfiguratorDialogQemuComponent implements OnInit { name: new UntypedFormControl('', Validators.required), ram: new UntypedFormControl('', Validators.required), }); + + this.networkSettingsForm = this.formBuilder.group({ + mac_address: new UntypedFormControl('', Validators.pattern(this.qemuConfigurationService.getMacAddrRegex())), + }); } ngOnInit() { @@ -103,16 +108,16 @@ export class ConfiguratorDialogQemuComponent implements OnInit { } onSaveClick() { - if (this.generalSettingsForm.valid) { - this.node.custom_adapters = []; - this.customAdapters.adapters.forEach((n) => { - this.node.custom_adapters.push({ - adapter_number: n.adapter_number, - adapter_type: n.adapter_type, - }); - }); - - this.node.properties.adapters = this.node.custom_adapters.length; + if (this.generalSettingsForm.valid && this.networkSettingsForm.valid) { + // this.node.custom_adapters = []; + // this.customAdapters.adapters.forEach((n) => { + // this.node.custom_adapters.push({ + // adapter_number: n.adapter_number, + // adapter_type: n.adapter_type, + // }); + // }); + // + // this.node.properties.adapters = this.node.custom_adapters.length; this.nodeService.updateNodeWithCustomAdapters(this.controller, this.node).subscribe(() => { this.toasterService.success(`Node ${this.node.name} updated.`); diff --git a/src/app/services/docker-configuration.service.ts b/src/app/services/docker-configuration.service.ts index c6059350..9cd5cb58 100644 --- a/src/app/services/docker-configuration.service.ts +++ b/src/app/services/docker-configuration.service.ts @@ -27,4 +27,8 @@ export class DockerConfigurationService { return consoleResolutions; } + + getMacAddrRegex() { + return /^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$/; + } } diff --git a/src/app/services/qemu-configuration.service.ts b/src/app/services/qemu-configuration.service.ts index c975acbe..706b7013 100644 --- a/src/app/services/qemu-configuration.service.ts +++ b/src/app/services/qemu-configuration.service.ts @@ -76,34 +76,6 @@ export class QemuConfigurationService { { value: 'vmxnet3', name: 'VMWare Paravirtualized Ethernet v3' }, ]; - // let networkTypes = [ - // 'e1000', - // 'e1000-82544gc', - // 'e1000-82545em', - // 'e1000e', - // 'rocker', - // 'Intel Gigabit Ethernet', - // 'i82550', - // 'i82551', - // 'i82557a', - // 'i82557b', - // 'i82557c', - // 'i82558a', - // 'i82558b', - // 'i82559a', - // 'i82559b', - // 'i82559c', - // 'i82559er', - // 'i82562', - // 'i82801', - // 'ne2k_pci', - // 'pcnet', - // 'rtl8139', - // 'virtio', - // 'virtio-net-pci', - // 'vmxnet3', - // ]; - return networkTypes; } @@ -146,4 +118,8 @@ export class QemuConfigurationService { return priorities; } + + getMacAddrRegex() { + return /^([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})$/; + } }