ciscollm-cli 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +242 -242
- package/dist/core/agent/AutoHealer.js +23 -23
- package/dist/core/agent/HierarchicalAgentManager.d.ts +1 -1
- package/dist/core/agent/HierarchicalAgentManager.js +21 -5
- package/dist/core/agent/HierarchicalAgentManager.js.map +1 -1
- package/dist/core/agent/PromptEngine.js +68 -67
- package/dist/core/agent/PromptEngine.js.map +1 -1
- package/dist/core/guardrails/AuditLogger.js +4 -4
- package/dist/core/guardrails/CommandFirewall.js +15 -0
- package/dist/core/guardrails/CommandFirewall.js.map +1 -1
- package/dist/infrastructure/protocols/PlinkSerial.js +1 -1
- package/dist/infrastructure/protocols/PlinkSerial.js.map +1 -1
- package/dist/server/dashboard.js +1033 -1033
- package/dist/server/index.js +8 -8
- package/dist/server/shell-simulator.d.ts +17 -1
- package/dist/server/shell-simulator.js +253 -69
- package/dist/server/shell-simulator.js.map +1 -1
- package/dist/server/ssh.js +20 -20
- package/package.json +54 -54
package/dist/server/index.js
CHANGED
|
@@ -20,14 +20,14 @@ function getTimestamp() {
|
|
|
20
20
|
}
|
|
21
21
|
function printDashboard(httpPort) {
|
|
22
22
|
console.clear();
|
|
23
|
-
console.log(chalk_1.default.bold.cyan(`
|
|
24
|
-
::::::::: :::::::: :::::::: :::::::: :::::::: :::: :::: :::: ::::
|
|
25
|
-
:+: :+: :+: :+: :+: :+: :+: :+: :+: :+: +:+:+: :+:+:+ +:+ +:+:+:
|
|
26
|
-
+:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+:+ +:+ +:+ +:+
|
|
27
|
-
+#++:++#+ +#+ +:+ +#++:++#++ +#++:++#++ +#+ +:+ +#+ +:+ +#+ +#+ +#++:++#+
|
|
28
|
-
+#+ +#+ +:+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+
|
|
29
|
-
#+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+#
|
|
30
|
-
### ######## ######## ######## ######## ### ### ######### ###
|
|
23
|
+
console.log(chalk_1.default.bold.cyan(`
|
|
24
|
+
::::::::: :::::::: :::::::: :::::::: :::::::: :::: :::: :::: ::::
|
|
25
|
+
:+: :+: :+: :+: :+: :+: :+: :+: :+: :+: +:+:+: :+:+:+ +:+ +:+:+:
|
|
26
|
+
+:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+:+ +:+ +:+ +:+
|
|
27
|
+
+#++:++#+ +#+ +:+ +#++:++#++ +#++:++#++ +#+ +:+ +#+ +:+ +#+ +#+ +#++:++#+
|
|
28
|
+
+#+ +#+ +:+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+
|
|
29
|
+
#+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+#
|
|
30
|
+
### ######## ######## ######## ######## ### ### ######### ###
|
|
31
31
|
`));
|
|
32
32
|
console.log(chalk_1.default.bold.yellow(' Cisco IOS Multi-Protocol Test Simulator \n'));
|
|
33
33
|
console.log(chalk_1.default.cyan('┌─────────────────────────────────────────────────────────────────────────────┐'));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
2
|
export declare const simulatorEvents: EventEmitter<[never]>;
|
|
3
|
-
export type CliMode = 'USER_EXEC' | 'PRIVILEGED_EXEC' | 'GLOBAL_CONFIG' | 'INTERFACE_CONFIG' | 'OSPF_CONFIG' | 'RIP_CONFIG' | 'BGP_CONFIG' | 'EIGRP_CONFIG' | 'DHCP_CONFIG' | 'ACL_CONFIG' | 'VLAN_CONFIG';
|
|
3
|
+
export type CliMode = 'USER_EXEC' | 'PRIVILEGED_EXEC' | 'GLOBAL_CONFIG' | 'INTERFACE_CONFIG' | 'OSPF_CONFIG' | 'RIP_CONFIG' | 'BGP_CONFIG' | 'EIGRP_CONFIG' | 'DHCP_CONFIG' | 'ACL_CONFIG' | 'VLAN_CONFIG' | 'VPC_CONFIG' | 'VRF_CONFIG' | 'VRF_AF_CONFIG';
|
|
4
4
|
export interface InterfaceState {
|
|
5
5
|
name: string;
|
|
6
6
|
ip: string | null;
|
|
@@ -12,6 +12,12 @@ export interface InterfaceState {
|
|
|
12
12
|
switchportMode?: 'access' | 'trunk';
|
|
13
13
|
vlan?: number;
|
|
14
14
|
natType?: 'inside' | 'outside';
|
|
15
|
+
vpcMemberId?: number;
|
|
16
|
+
sourceInterface?: string;
|
|
17
|
+
memberVnis?: Map<number, {
|
|
18
|
+
mcastGroup?: string;
|
|
19
|
+
associateVrf?: boolean;
|
|
20
|
+
}>;
|
|
15
21
|
}
|
|
16
22
|
export interface RouteState {
|
|
17
23
|
network: string;
|
|
@@ -60,6 +66,16 @@ export declare class ShellSimulator {
|
|
|
60
66
|
natRules: string[];
|
|
61
67
|
acls: Map<string, string[]>;
|
|
62
68
|
ipRoutingEnabled: boolean;
|
|
69
|
+
featuresEnabled: Set<string>;
|
|
70
|
+
vpcDomainId: number | null;
|
|
71
|
+
vpcPeerKeepalive: string | null;
|
|
72
|
+
vnSegments: Map<number, number>;
|
|
73
|
+
vrfs: Map<string, {
|
|
74
|
+
vni?: number;
|
|
75
|
+
rd?: string;
|
|
76
|
+
routeTargets: string[];
|
|
77
|
+
}>;
|
|
78
|
+
activeVrf: string | null;
|
|
63
79
|
flashFiles: Set<string>;
|
|
64
80
|
private pendingCopyDest;
|
|
65
81
|
private backupState;
|
|
@@ -69,6 +69,12 @@ class ShellSimulator {
|
|
|
69
69
|
natRules = [];
|
|
70
70
|
acls = new Map();
|
|
71
71
|
ipRoutingEnabled = true;
|
|
72
|
+
featuresEnabled = new Set();
|
|
73
|
+
vpcDomainId = null;
|
|
74
|
+
vpcPeerKeepalive = null;
|
|
75
|
+
vnSegments = new Map();
|
|
76
|
+
vrfs = new Map();
|
|
77
|
+
activeVrf = null;
|
|
72
78
|
flashFiles = new Set(['c2960-lanbasek9-mz.150-2.SE4.bin']);
|
|
73
79
|
pendingCopyDest = null;
|
|
74
80
|
backupState = null;
|
|
@@ -123,6 +129,12 @@ class ShellSimulator {
|
|
|
123
129
|
return `${this.hostname}(config-ext-nacl)# `;
|
|
124
130
|
case 'VLAN_CONFIG':
|
|
125
131
|
return `${this.hostname}(config-vlan)# `;
|
|
132
|
+
case 'VPC_CONFIG':
|
|
133
|
+
return `${this.hostname}(config-vpc-domain)# `;
|
|
134
|
+
case 'VRF_CONFIG':
|
|
135
|
+
return `${this.hostname}(config-vrf)# `;
|
|
136
|
+
case 'VRF_AF_CONFIG':
|
|
137
|
+
return `${this.hostname}(config-vrf-af-ipv4)# `;
|
|
126
138
|
default:
|
|
127
139
|
return `${this.hostname}# `;
|
|
128
140
|
}
|
|
@@ -164,56 +176,57 @@ class ShellSimulator {
|
|
|
164
176
|
}
|
|
165
177
|
const args = commandToExecute.split(/\s+/);
|
|
166
178
|
const cmd = args[0].toLowerCase();
|
|
179
|
+
const isShow = cmd === 'show' || cmd === 'sh' || (cmd === 'do' && (args[1]?.toLowerCase() === 'show' || args[1]?.toLowerCase() === 'sh'));
|
|
167
180
|
if (cmd === '?' || cmd === 'help') {
|
|
168
181
|
if (cmd === 'help') {
|
|
169
|
-
return `Help may be requested at any point in a command by entering
|
|
170
|
-
a question mark '?'. If nothing matches, the help list will
|
|
182
|
+
return `Help may be requested at any point in a command by entering
|
|
183
|
+
a question mark '?'. If nothing matches, the help list will
|
|
171
184
|
show the available options.`;
|
|
172
185
|
}
|
|
173
186
|
if (this.mode === 'USER_EXEC') {
|
|
174
|
-
return `Exec commands:
|
|
175
|
-
disable Turn off privileged commands
|
|
176
|
-
enable Turn on privileged commands
|
|
177
|
-
exit Exit from the EXEC
|
|
178
|
-
ping Send echo messages
|
|
187
|
+
return `Exec commands:
|
|
188
|
+
disable Turn off privileged commands
|
|
189
|
+
enable Turn on privileged commands
|
|
190
|
+
exit Exit from the EXEC
|
|
191
|
+
ping Send echo messages
|
|
179
192
|
show Show running system information`;
|
|
180
193
|
}
|
|
181
194
|
else if (this.mode === 'PRIVILEGED_EXEC') {
|
|
182
|
-
return `Exec commands:
|
|
183
|
-
clear Reset functions
|
|
184
|
-
configure Enter configuration mode
|
|
185
|
-
copy Copy from one file to another
|
|
186
|
-
dir List files on a filesystem
|
|
187
|
-
disable Turn off privileged commands
|
|
188
|
-
enable Turn on privileged commands
|
|
189
|
-
exit Exit from the EXEC
|
|
190
|
-
ping Send echo messages
|
|
191
|
-
show Show running system information
|
|
195
|
+
return `Exec commands:
|
|
196
|
+
clear Reset functions
|
|
197
|
+
configure Enter configuration mode
|
|
198
|
+
copy Copy from one file to another
|
|
199
|
+
dir List files on a filesystem
|
|
200
|
+
disable Turn off privileged commands
|
|
201
|
+
enable Turn on privileged commands
|
|
202
|
+
exit Exit from the EXEC
|
|
203
|
+
ping Send echo messages
|
|
204
|
+
show Show running system information
|
|
192
205
|
write Write running configuration to memory or terminal`;
|
|
193
206
|
}
|
|
194
207
|
else if (this.mode === 'GLOBAL_CONFIG') {
|
|
195
|
-
return `Configure commands:
|
|
196
|
-
do To run EXEC commands in config mode
|
|
197
|
-
end Exit from configure mode
|
|
198
|
-
exit Exit from configure mode
|
|
199
|
-
hostname Set system's network name
|
|
200
|
-
interface Select an interface to configure
|
|
201
|
-
ip Global IP configuration subcommands
|
|
202
|
-
no Negate a command or set defaults
|
|
203
|
-
router Enable a routing process
|
|
208
|
+
return `Configure commands:
|
|
209
|
+
do To run EXEC commands in config mode
|
|
210
|
+
end Exit from configure mode
|
|
211
|
+
exit Exit from configure mode
|
|
212
|
+
hostname Set system's network name
|
|
213
|
+
interface Select an interface to configure
|
|
214
|
+
ip Global IP configuration subcommands
|
|
215
|
+
no Negate a command or set defaults
|
|
216
|
+
router Enable a routing process
|
|
204
217
|
vlan Vlan configuration commands`;
|
|
205
218
|
}
|
|
206
219
|
else if (this.mode === 'INTERFACE_CONFIG') {
|
|
207
|
-
return `Interface configuration commands:
|
|
208
|
-
description Detailed description of this interface
|
|
209
|
-
exit Exit from interface configuration mode
|
|
210
|
-
ip IP interface configuration subcommands
|
|
211
|
-
no Negate a command or set defaults
|
|
220
|
+
return `Interface configuration commands:
|
|
221
|
+
description Detailed description of this interface
|
|
222
|
+
exit Exit from interface configuration mode
|
|
223
|
+
ip IP interface configuration subcommands
|
|
224
|
+
no Negate a command or set defaults
|
|
212
225
|
shutdown Shutdown this interface`;
|
|
213
226
|
}
|
|
214
227
|
else {
|
|
215
|
-
return `Commands:
|
|
216
|
-
exit Exit current mode
|
|
228
|
+
return `Commands:
|
|
229
|
+
exit Exit current mode
|
|
217
230
|
end Exit to privileged EXEC mode`;
|
|
218
231
|
}
|
|
219
232
|
}
|
|
@@ -224,10 +237,15 @@ show the available options.`;
|
|
|
224
237
|
return `% Incomplete command.`;
|
|
225
238
|
}
|
|
226
239
|
if (cmd === 'exit') {
|
|
227
|
-
if (this.mode === 'INTERFACE_CONFIG' || this.mode === 'OSPF_CONFIG' || this.mode === 'RIP_CONFIG' || this.mode === 'BGP_CONFIG' || this.mode === 'EIGRP_CONFIG' || this.mode === 'DHCP_CONFIG' || this.mode === 'ACL_CONFIG' || this.mode === 'VLAN_CONFIG') {
|
|
240
|
+
if (this.mode === 'INTERFACE_CONFIG' || this.mode === 'OSPF_CONFIG' || this.mode === 'RIP_CONFIG' || this.mode === 'BGP_CONFIG' || this.mode === 'EIGRP_CONFIG' || this.mode === 'DHCP_CONFIG' || this.mode === 'ACL_CONFIG' || this.mode === 'VLAN_CONFIG' || this.mode === 'VPC_CONFIG' || this.mode === 'VRF_CONFIG') {
|
|
228
241
|
this.mode = 'GLOBAL_CONFIG';
|
|
229
242
|
this.activeInterface = null;
|
|
230
243
|
this.activeVlan = null;
|
|
244
|
+
this.activeVrf = null;
|
|
245
|
+
return '';
|
|
246
|
+
}
|
|
247
|
+
else if (this.mode === 'VRF_AF_CONFIG') {
|
|
248
|
+
this.mode = 'VRF_CONFIG';
|
|
231
249
|
return '';
|
|
232
250
|
}
|
|
233
251
|
else if (this.mode === 'GLOBAL_CONFIG') {
|
|
@@ -247,6 +265,7 @@ show the available options.`;
|
|
|
247
265
|
this.mode = 'PRIVILEGED_EXEC';
|
|
248
266
|
this.activeInterface = null;
|
|
249
267
|
this.activeVlan = null;
|
|
268
|
+
this.activeVrf = null;
|
|
250
269
|
return '';
|
|
251
270
|
}
|
|
252
271
|
}
|
|
@@ -290,7 +309,35 @@ show the available options.`;
|
|
|
290
309
|
this.shellEnabled = true;
|
|
291
310
|
return '';
|
|
292
311
|
}
|
|
293
|
-
|
|
312
|
+
const isGeneralCommand = isShow || cmd === 'ping' || cmd === 'write' || cmd === 'wr' || cmd === 'copy' || cmd === 'dir' || cmd === 'test';
|
|
313
|
+
if (this.mode === 'GLOBAL_CONFIG' && !isGeneralCommand) {
|
|
314
|
+
if (cmd === 'feature' && args[1]) {
|
|
315
|
+
const featureName = args.slice(1).join(' ').toLowerCase();
|
|
316
|
+
this.featuresEnabled.add(featureName);
|
|
317
|
+
return '';
|
|
318
|
+
}
|
|
319
|
+
if (cmd === 'no' && args[1] === 'feature' && args[2]) {
|
|
320
|
+
const featureName = args.slice(2).join(' ').toLowerCase();
|
|
321
|
+
this.featuresEnabled.delete(featureName);
|
|
322
|
+
return '';
|
|
323
|
+
}
|
|
324
|
+
if (cmd === 'vpc' && args[1] === 'domain' && args[2]) {
|
|
325
|
+
const domainId = parseInt(args[2], 10);
|
|
326
|
+
if (!isNaN(domainId)) {
|
|
327
|
+
this.vpcDomainId = domainId;
|
|
328
|
+
this.mode = 'VPC_CONFIG';
|
|
329
|
+
return '';
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (cmd === 'vrf' && args[1] === 'context' && args[2]) {
|
|
333
|
+
const vrfName = args[2];
|
|
334
|
+
this.activeVrf = vrfName;
|
|
335
|
+
if (!this.vrfs.has(vrfName)) {
|
|
336
|
+
this.vrfs.set(vrfName, { routeTargets: [] });
|
|
337
|
+
}
|
|
338
|
+
this.mode = 'VRF_CONFIG';
|
|
339
|
+
return '';
|
|
340
|
+
}
|
|
294
341
|
if (cmd === 'hostname' && args[1]) {
|
|
295
342
|
this.hostname = args[1];
|
|
296
343
|
return '';
|
|
@@ -457,7 +504,7 @@ show the available options.`;
|
|
|
457
504
|
}
|
|
458
505
|
return `% Invalid input detected at '^' marker.`;
|
|
459
506
|
}
|
|
460
|
-
if (this.mode === 'VLAN_CONFIG' && this.activeVlan !== null) {
|
|
507
|
+
if (this.mode === 'VLAN_CONFIG' && this.activeVlan !== null && !isGeneralCommand) {
|
|
461
508
|
if (cmd === 'name' && args[1]) {
|
|
462
509
|
this.vlanNames.set(this.activeVlan, args.slice(1).join(' '));
|
|
463
510
|
return '';
|
|
@@ -466,10 +513,40 @@ show the available options.`;
|
|
|
466
513
|
this.vlanNames.set(this.activeVlan, `VLAN${this.activeVlan.toString().padStart(4, '0')}`);
|
|
467
514
|
return '';
|
|
468
515
|
}
|
|
516
|
+
if (cmd === 'vn-segment' && args[1]) {
|
|
517
|
+
const vni = parseInt(args[1], 10);
|
|
518
|
+
if (!isNaN(vni)) {
|
|
519
|
+
this.vnSegments.set(this.activeVlan, vni);
|
|
520
|
+
return '';
|
|
521
|
+
}
|
|
522
|
+
}
|
|
469
523
|
return `% Invalid input detected at '^' marker.`;
|
|
470
524
|
}
|
|
471
|
-
if (this.mode === 'INTERFACE_CONFIG' && this.activeInterface) {
|
|
525
|
+
if (this.mode === 'INTERFACE_CONFIG' && this.activeInterface && !isGeneralCommand) {
|
|
472
526
|
const iface = this.interfaces.get(this.activeInterface);
|
|
527
|
+
if (cmd === 'vpc' && args[1]) {
|
|
528
|
+
const vpcId = parseInt(args[1], 10);
|
|
529
|
+
if (!isNaN(vpcId)) {
|
|
530
|
+
iface.vpcMemberId = vpcId;
|
|
531
|
+
return '';
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
if (cmd === 'source-interface' && args[1]) {
|
|
535
|
+
iface.sourceInterface = args[1];
|
|
536
|
+
return '';
|
|
537
|
+
}
|
|
538
|
+
if (cmd === 'member' && args[1] === 'vni' && args[2]) {
|
|
539
|
+
const vni = parseInt(args[2], 10);
|
|
540
|
+
if (!isNaN(vni)) {
|
|
541
|
+
if (!iface.memberVnis) {
|
|
542
|
+
iface.memberVnis = new Map();
|
|
543
|
+
}
|
|
544
|
+
const mcastGroup = args[3] === 'mcast-group' ? args[4] : undefined;
|
|
545
|
+
const associateVrf = args.includes('associate-vrf');
|
|
546
|
+
iface.memberVnis.set(vni, { mcastGroup, associateVrf });
|
|
547
|
+
return '';
|
|
548
|
+
}
|
|
549
|
+
}
|
|
473
550
|
if (cmd === 'shutdown') {
|
|
474
551
|
iface.adminShutdown = true;
|
|
475
552
|
iface.lineProtocolUp = false;
|
|
@@ -599,7 +676,7 @@ show the available options.`;
|
|
|
599
676
|
}
|
|
600
677
|
return `% Invalid input detected at '^' marker.`;
|
|
601
678
|
}
|
|
602
|
-
if (this.mode === 'OSPF_CONFIG') {
|
|
679
|
+
if (this.mode === 'OSPF_CONFIG' && !isGeneralCommand) {
|
|
603
680
|
if (cmd === 'network' || cmd === 'router-id') {
|
|
604
681
|
return '';
|
|
605
682
|
}
|
|
@@ -608,7 +685,7 @@ show the available options.`;
|
|
|
608
685
|
}
|
|
609
686
|
return `% Invalid input detected at '^' marker.`;
|
|
610
687
|
}
|
|
611
|
-
if (this.mode === 'RIP_CONFIG') {
|
|
688
|
+
if (this.mode === 'RIP_CONFIG' && !isGeneralCommand) {
|
|
612
689
|
if (cmd === 'version' && (args[1] === '1' || args[1] === '2')) {
|
|
613
690
|
this.ripVersion = parseInt(args[1], 10);
|
|
614
691
|
return '';
|
|
@@ -629,7 +706,7 @@ show the available options.`;
|
|
|
629
706
|
}
|
|
630
707
|
return `% Invalid input detected at '^' marker.`;
|
|
631
708
|
}
|
|
632
|
-
if (this.mode === 'BGP_CONFIG') {
|
|
709
|
+
if (this.mode === 'BGP_CONFIG' && !isGeneralCommand) {
|
|
633
710
|
if (cmd === 'neighbor' && args[1]) {
|
|
634
711
|
return '';
|
|
635
712
|
}
|
|
@@ -645,9 +722,49 @@ show the available options.`;
|
|
|
645
722
|
if (cmd === 'auto-summary') {
|
|
646
723
|
return '';
|
|
647
724
|
}
|
|
725
|
+
if (cmd === 'address-family' && args[1] === 'l2vpn' && args[2] === 'evpn') {
|
|
726
|
+
return '';
|
|
727
|
+
}
|
|
728
|
+
if (cmd === 'send-community') {
|
|
729
|
+
return '';
|
|
730
|
+
}
|
|
731
|
+
return `% Invalid input detected at '^' marker.`;
|
|
732
|
+
}
|
|
733
|
+
if (this.mode === 'VPC_CONFIG' && !isGeneralCommand) {
|
|
734
|
+
if (cmd === 'peer-keepalive' && args[1] === 'destination') {
|
|
735
|
+
this.vpcPeerKeepalive = commandToExecute;
|
|
736
|
+
return '';
|
|
737
|
+
}
|
|
738
|
+
if (cmd === 'system-priority' || cmd === 'role' || cmd === 'peer-gateway' || cmd === 'peer-switch') {
|
|
739
|
+
return '';
|
|
740
|
+
}
|
|
741
|
+
return `% Invalid input detected at '^' marker.`;
|
|
742
|
+
}
|
|
743
|
+
if (this.mode === 'VRF_CONFIG' && this.activeVrf && !isGeneralCommand) {
|
|
744
|
+
const vrf = this.vrfs.get(this.activeVrf);
|
|
745
|
+
if (cmd === 'vni' && args[1]) {
|
|
746
|
+
vrf.vni = parseInt(args[1], 10);
|
|
747
|
+
return '';
|
|
748
|
+
}
|
|
749
|
+
if (cmd === 'rd' && args[1]) {
|
|
750
|
+
vrf.rd = args.slice(1).join(' ');
|
|
751
|
+
return '';
|
|
752
|
+
}
|
|
753
|
+
if (cmd === 'address-family' && args[1] === 'ipv4' && args[2] === 'unicast') {
|
|
754
|
+
this.mode = 'VRF_AF_CONFIG';
|
|
755
|
+
return '';
|
|
756
|
+
}
|
|
757
|
+
return `% Invalid input detected at '^' marker.`;
|
|
758
|
+
}
|
|
759
|
+
if (this.mode === 'VRF_AF_CONFIG' && this.activeVrf && !isGeneralCommand) {
|
|
760
|
+
const vrf = this.vrfs.get(this.activeVrf);
|
|
761
|
+
if (cmd === 'route-target' && args[1] === 'both' && args[2]) {
|
|
762
|
+
vrf.routeTargets.push(args.slice(1).join(' '));
|
|
763
|
+
return '';
|
|
764
|
+
}
|
|
648
765
|
return `% Invalid input detected at '^' marker.`;
|
|
649
766
|
}
|
|
650
|
-
if (this.mode === 'EIGRP_CONFIG') {
|
|
767
|
+
if (this.mode === 'EIGRP_CONFIG' && !isGeneralCommand) {
|
|
651
768
|
if (cmd === 'network' && args[1]) {
|
|
652
769
|
return '';
|
|
653
770
|
}
|
|
@@ -662,36 +779,85 @@ show the available options.`;
|
|
|
662
779
|
}
|
|
663
780
|
return `% Invalid input detected at '^' marker.`;
|
|
664
781
|
}
|
|
665
|
-
if (this.mode === 'DHCP_CONFIG') {
|
|
782
|
+
if (this.mode === 'DHCP_CONFIG' && !isGeneralCommand) {
|
|
666
783
|
if (cmd === 'network' || cmd === 'default-router' || cmd === 'dns-server') {
|
|
667
784
|
return '';
|
|
668
785
|
}
|
|
669
786
|
return `% Invalid input detected at '^' marker.`;
|
|
670
787
|
}
|
|
671
|
-
if (this.mode === 'ACL_CONFIG') {
|
|
788
|
+
if (this.mode === 'ACL_CONFIG' && !isGeneralCommand) {
|
|
672
789
|
if (cmd === 'permit' || cmd === 'deny') {
|
|
673
790
|
return '';
|
|
674
791
|
}
|
|
675
792
|
return `% Invalid input detected at '^' marker.`;
|
|
676
793
|
}
|
|
677
|
-
const isShow = cmd === 'show' || cmd === 'sh' || (cmd === 'do' && (args[1]?.toLowerCase() === 'show' || args[1]?.toLowerCase() === 'sh'));
|
|
678
794
|
if (isShow) {
|
|
679
795
|
const showArgs = cmd === 'do' ? args.slice(2) : args.slice(1);
|
|
680
796
|
const showCmd = showArgs[0]?.toLowerCase();
|
|
797
|
+
if (showCmd === 'vpc') {
|
|
798
|
+
const domainId = this.vpcDomainId || 10;
|
|
799
|
+
const peerStatus = this.vpcPeerKeepalive ? 'peer adjacency formed ok' : 'peer link not configured';
|
|
800
|
+
const keepaliveStatus = this.vpcPeerKeepalive ? 'peer is alive' : 'peer keep-alive not configured';
|
|
801
|
+
return `Legend:
|
|
802
|
+
(*) - local vPC is down, dynamic backup loop preventer
|
|
803
|
+
|
|
804
|
+
vPC domain id : ${domainId}
|
|
805
|
+
Peer status : ${peerStatus}
|
|
806
|
+
vPC keep-alive status : ${keepaliveStatus}
|
|
807
|
+
Configuration-consistency status : success
|
|
808
|
+
Per-vlan consistency status : success
|
|
809
|
+
Type-2 consistency status : success
|
|
810
|
+
vPC role : primary
|
|
811
|
+
Number of vPCs configured : ${Array.from(this.interfaces.values()).filter(i => i.vpcMemberId !== undefined).length}
|
|
812
|
+
Peer Gateway : Enabled
|
|
813
|
+
`;
|
|
814
|
+
}
|
|
815
|
+
if (showCmd === 'nve' && showArgs[1] === 'interface') {
|
|
816
|
+
const nveIface = Array.from(this.interfaces.values()).find(i => i.name.toLowerCase().startsWith('nve'));
|
|
817
|
+
if (!nveIface) {
|
|
818
|
+
return '% NVE interface is not configured';
|
|
819
|
+
}
|
|
820
|
+
const sourceInt = nveIface.sourceInterface || 'Loopback0';
|
|
821
|
+
return `Interface: ${nveIface.name}, State: Up, Encapsulation: VXLAN
|
|
822
|
+
Source-Interface: ${sourceInt} (10.0.0.1)
|
|
823
|
+
`;
|
|
824
|
+
}
|
|
825
|
+
if (showCmd === 'nve' && showArgs[1] === 'vni') {
|
|
826
|
+
const nveIface = Array.from(this.interfaces.values()).find(i => i.name.toLowerCase().startsWith('nve'));
|
|
827
|
+
if (!nveIface || !nveIface.memberVnis) {
|
|
828
|
+
return `Interface VNI Multicast-group State Mode vPC Dev\n` +
|
|
829
|
+
`--------- -------- ----------------- ----- ---- -------\n`;
|
|
830
|
+
}
|
|
831
|
+
let out = `Interface VNI Multicast-group State Mode vPC Dev\n` +
|
|
832
|
+
`--------- -------- ----------------- ----- ---- -------\n`;
|
|
833
|
+
for (const [vni, details] of nveIface.memberVnis.entries()) {
|
|
834
|
+
const mcast = details.mcastGroup || 'n/a';
|
|
835
|
+
out += `${nveIface.name.padEnd(9)} ${vni.toString().padEnd(8)} ${mcast.padEnd(17)} Up CP n/a\n`;
|
|
836
|
+
}
|
|
837
|
+
return out;
|
|
838
|
+
}
|
|
839
|
+
if (showCmd === 'bgp' && showArgs[1] === 'l2vpn' && showArgs[2] === 'evpn' && showArgs[3] === 'summary') {
|
|
840
|
+
const bgpAs = this.bgpAsn || '65000';
|
|
841
|
+
return `BGP summary information for VRF default, address family L2VPN EVPN
|
|
842
|
+
BGP router identifier 10.0.0.1, local AS number ${bgpAs}
|
|
843
|
+
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
|
|
844
|
+
10.0.0.2 4 ${bgpAs} 120 125 47 0 0 01:24:55 2
|
|
845
|
+
`;
|
|
846
|
+
}
|
|
681
847
|
if (showCmd === 'version' || showCmd === 'ver') {
|
|
682
|
-
return `Cisco IOS Software, C2960 Software (C2960-LANBASEK9-M), Version 15.0(2)SE4, RELEASE SOFTWARE (fc1)
|
|
683
|
-
Technical Support: http://www.cisco.com/techsupport
|
|
684
|
-
Copyright (c) 1986-2013 by Cisco Systems, Inc.
|
|
685
|
-
Compiled Wed 26-Jun-13 02:49 by prod_rel_team
|
|
686
|
-
|
|
687
|
-
ROM: Bootstrap program is 12.2(44)SE Version
|
|
688
|
-
BOOTLDR: C2960 Boot Loader (C2960-HBOOT-M) Version 12.2(44)SE, RELEASE SOFTWARE (fc1)
|
|
689
|
-
|
|
690
|
-
Switch1 uptime is 2 hours, 15 minutes
|
|
691
|
-
System returned to ROM by power-on
|
|
692
|
-
System image file is "flash:/c2960-lanbasek9-mz.150-2.SE4.bin"
|
|
693
|
-
|
|
694
|
-
This product contains cryptographic features and is subject to Y...
|
|
848
|
+
return `Cisco IOS Software, C2960 Software (C2960-LANBASEK9-M), Version 15.0(2)SE4, RELEASE SOFTWARE (fc1)
|
|
849
|
+
Technical Support: http://www.cisco.com/techsupport
|
|
850
|
+
Copyright (c) 1986-2013 by Cisco Systems, Inc.
|
|
851
|
+
Compiled Wed 26-Jun-13 02:49 by prod_rel_team
|
|
852
|
+
|
|
853
|
+
ROM: Bootstrap program is 12.2(44)SE Version
|
|
854
|
+
BOOTLDR: C2960 Boot Loader (C2960-HBOOT-M) Version 12.2(44)SE, RELEASE SOFTWARE (fc1)
|
|
855
|
+
|
|
856
|
+
Switch1 uptime is 2 hours, 15 minutes
|
|
857
|
+
System returned to ROM by power-on
|
|
858
|
+
System image file is "flash:/c2960-lanbasek9-mz.150-2.SE4.bin"
|
|
859
|
+
|
|
860
|
+
This product contains cryptographic features and is subject to Y...
|
|
695
861
|
`;
|
|
696
862
|
}
|
|
697
863
|
if (showCmd === 'ip' && showArgs[1]?.startsWith('int') && showArgs[2]?.startsWith('br')) {
|
|
@@ -842,11 +1008,11 @@ This product contains cryptographic features and is subject to Y...
|
|
|
842
1008
|
return out;
|
|
843
1009
|
}
|
|
844
1010
|
if (showCmd === 'cdp' && showArgs[1]?.startsWith('ne')) {
|
|
845
|
-
return `Capability Codes: R - Router, T - Trans Bridge, B - Source Route Bridge
|
|
846
|
-
S - Switch, H - Host, I - IGMP, r - Repeater, P - Phone
|
|
847
|
-
|
|
848
|
-
Device ID Local Intrfce Holdtme Capability Platform Port ID
|
|
849
|
-
Switch2 Gig 0/1 125 S I WS-C2960- Gig 0/1
|
|
1011
|
+
return `Capability Codes: R - Router, T - Trans Bridge, B - Source Route Bridge
|
|
1012
|
+
S - Switch, H - Host, I - IGMP, r - Repeater, P - Phone
|
|
1013
|
+
|
|
1014
|
+
Device ID Local Intrfce Holdtme Capability Platform Port ID
|
|
1015
|
+
Switch2 Gig 0/1 125 S I WS-C2960- Gig 0/1
|
|
850
1016
|
`;
|
|
851
1017
|
}
|
|
852
1018
|
if (showCmd === 'vtp' && showArgs[1] === 'status') {
|
|
@@ -912,9 +1078,9 @@ Switch2 Gig 0/1 125 S I WS-C2960- Gig 0/1
|
|
|
912
1078
|
return out;
|
|
913
1079
|
}
|
|
914
1080
|
if (showCmd === 'lldp' && showArgs[1]?.startsWith('ne')) {
|
|
915
|
-
return `Device ID Local Intf Hold-time Capability Port ID
|
|
916
|
-
Switch2 Gi0/1 120 S Gi0/1
|
|
917
|
-
Total entries displayed: 1
|
|
1081
|
+
return `Device ID Local Intf Hold-time Capability Port ID
|
|
1082
|
+
Switch2 Gi0/1 120 S Gi0/1
|
|
1083
|
+
Total entries displayed: 1
|
|
918
1084
|
`;
|
|
919
1085
|
}
|
|
920
1086
|
return `% Unrecognized show command: show ${showArgs.join(' ')}`;
|
|
@@ -955,9 +1121,9 @@ Total entries displayed: 1
|
|
|
955
1121
|
}
|
|
956
1122
|
if (cmd === 'ping' && args[1]) {
|
|
957
1123
|
const ip = args[1];
|
|
958
|
-
return `Sending 5, 100-byte ICMP Echos to ${ip}, timeout is 2 seconds:
|
|
959
|
-
!!!!!
|
|
960
|
-
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/4 ms
|
|
1124
|
+
return `Sending 5, 100-byte ICMP Echos to ${ip}, timeout is 2 seconds:
|
|
1125
|
+
!!!!!
|
|
1126
|
+
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/4 ms
|
|
961
1127
|
`;
|
|
962
1128
|
}
|
|
963
1129
|
if (cmd === 'test' && args[1] === 'trigger-syslog') {
|
|
@@ -1005,6 +1171,21 @@ Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/4 ms
|
|
|
1005
1171
|
if (lower.startsWith('vl')) {
|
|
1006
1172
|
return 'Vlan' + name.substring(2);
|
|
1007
1173
|
}
|
|
1174
|
+
if (lower.startsWith('ethernet')) {
|
|
1175
|
+
return 'Ethernet' + name.substring(8);
|
|
1176
|
+
}
|
|
1177
|
+
if (lower.startsWith('eth')) {
|
|
1178
|
+
return 'Ethernet' + name.substring(3);
|
|
1179
|
+
}
|
|
1180
|
+
if (lower.startsWith('port-channel')) {
|
|
1181
|
+
return 'Port-channel' + name.substring(12);
|
|
1182
|
+
}
|
|
1183
|
+
if (lower.startsWith('po')) {
|
|
1184
|
+
return 'Port-channel' + name.substring(2);
|
|
1185
|
+
}
|
|
1186
|
+
if (lower.startsWith('nve')) {
|
|
1187
|
+
return 'Nve' + name.substring(3);
|
|
1188
|
+
}
|
|
1008
1189
|
return name;
|
|
1009
1190
|
}
|
|
1010
1191
|
shortenInterfaceName(name) {
|
|
@@ -1012,7 +1193,10 @@ Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/4 ms
|
|
|
1012
1193
|
.replace('GigabitEthernet', 'Gi')
|
|
1013
1194
|
.replace('FastEthernet', 'Fa')
|
|
1014
1195
|
.replace('TenGigabitEthernet', 'Te')
|
|
1015
|
-
.replace('Loopback', 'Lo')
|
|
1196
|
+
.replace('Loopback', 'Lo')
|
|
1197
|
+
.replace('Ethernet', 'Eth')
|
|
1198
|
+
.replace('Port-channel', 'Po')
|
|
1199
|
+
.replace('Nve', 'Nve');
|
|
1016
1200
|
}
|
|
1017
1201
|
getPrefixLength(mask) {
|
|
1018
1202
|
const parts = mask.split('.').map(Number);
|