@takodotid/circuit 0.34.1 → 0.34.3
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/dist/cli/index.js +13 -2
- package/package.json +1 -1
- package/src/adapters/devices/raisecom-ros/TRAPS.md +1 -0
- package/src/adapters/devices/raisecom-ros/index.ts +9 -2
- package/src/adapters/devices/routeros/TRAPS.md +1 -0
- package/src/adapters/devices/routeros/plan.ts +2 -0
- package/src/adapters/devices/vrp/TRAPS.md +1 -0
- package/src/adapters/devices/vrp/index.ts +4 -0
package/dist/cli/index.js
CHANGED
|
@@ -5601,7 +5601,15 @@ async function consoleShell(device) {
|
|
|
5601
5601
|
async function read3(device, _network = [], options = {}) {
|
|
5602
5602
|
const { channel, close } = await open(device, options);
|
|
5603
5603
|
try {
|
|
5604
|
-
|
|
5604
|
+
let dump = "";
|
|
5605
|
+
for (let attempt = 1;; attempt++) {
|
|
5606
|
+
dump = await send(channel, "show running-config", 150000, 6000);
|
|
5607
|
+
if (/[#>]\s*$/.test(dump.replace(/\r/g, "").trimEnd()))
|
|
5608
|
+
break;
|
|
5609
|
+
if (attempt === 3)
|
|
5610
|
+
throw new Error(`${device.name} returned an incomplete configuration three times`);
|
|
5611
|
+
await send(channel, "", 30000, 6000);
|
|
5612
|
+
}
|
|
5605
5613
|
const lines = dump.replace(/\r/g, "").split(`
|
|
5606
5614
|
`);
|
|
5607
5615
|
const start = lines.findIndex((line) => line.trim().startsWith("!ROS version"));
|
|
@@ -6139,6 +6147,7 @@ var ORDER = [
|
|
|
6139
6147
|
"/snmp",
|
|
6140
6148
|
"/tool",
|
|
6141
6149
|
"/user",
|
|
6150
|
+
"/system logging action",
|
|
6142
6151
|
"/system"
|
|
6143
6152
|
];
|
|
6144
6153
|
function rank(menu) {
|
|
@@ -7779,7 +7788,8 @@ var DEVICE_FACTS3 = [
|
|
|
7779
7788
|
"authorization-scheme default",
|
|
7780
7789
|
"accounting-scheme default",
|
|
7781
7790
|
"domain default",
|
|
7782
|
-
"Info:"
|
|
7791
|
+
"Info:",
|
|
7792
|
+
"snmp-agent local-engineid"
|
|
7783
7793
|
];
|
|
7784
7794
|
var UNDO_BY_KEYWORD2 = /^(description|name|port default vlan|port link-type|port trunk pvid vlan|set authentication password|eth-trunk|ip binding vpn-instance|ssh server cipher|ssh server hmac|ssh server key-exchange)\b/;
|
|
7785
7795
|
function undo2(line) {
|
|
@@ -8170,6 +8180,7 @@ function snmp4(config, device) {
|
|
|
8170
8180
|
config.line("snmp-agent mib-view included all iso");
|
|
8171
8181
|
config.line(`snmp-agent group v3 ${SNMP_GROUP3} privacy read-view all${guarded ? ` acl ${MANAGEMENT_ACL2}` : ""}`);
|
|
8172
8182
|
for (const [name, user] of Object.entries(snmp.users)) {
|
|
8183
|
+
config.line(`snmp-agent usm-user v3 ${name}`);
|
|
8173
8184
|
config.line(`snmp-agent usm-user v3 ${name} group ${SNMP_GROUP3}`);
|
|
8174
8185
|
config.line(`snmp-agent usm-user v3 ${name} authentication-mode ${SNMP_AUTH4[user.auth]} cipher ${marker(user.auth_password)}`);
|
|
8175
8186
|
config.line(`snmp-agent usm-user v3 ${name} privacy-mode ${SNMP_PRIVACY3[user.privacy]} cipher ${marker(user.privacy_password)}`);
|
package/package.json
CHANGED
|
@@ -23,3 +23,4 @@ Behaviour that looks like something else. Each one has been hit on a RAX721 runn
|
|
|
23
23
|
- OSPF settings for an interface sit on the interface, `ip ospf cost`, `ip ospf network ptp`, `ip ospf passive-interface enable`; passive is undone with `... disable`, not `no`.
|
|
24
24
|
- `create vlan <list> active` has every VLAN on one line. A change creates only the new VLANs and removes each one that is gone with `no vlan <id>`.
|
|
25
25
|
- An access-list rule is not replaced by one with the same number: the device answers `Set unsuccessfully.` and keeps the old rule. The old one is removed first. `no rule N` answers slowly, after a second or more.
|
|
26
|
+
- `show running-config` can stop partway even with paging off and six seconds of silence, with no error: on 2026-10-23 three reads of an RAX721 in a row gave plans of 62, 0 and 158 commands against an unchanged switch. A dump that does not end at the prompt is read again, and after three the read fails rather than planning against a part.
|
|
@@ -398,8 +398,15 @@ export async function read(device: Device, _network: readonly Device[] = [], opt
|
|
|
398
398
|
const { channel, close } = await open(device, options);
|
|
399
399
|
|
|
400
400
|
try {
|
|
401
|
-
// Without paging off and a long wait for silence, the dump stops halfway with no error.
|
|
402
|
-
|
|
401
|
+
// Without paging off and a long wait for silence, the dump stops halfway with no error. Even then a pause of the device's own can end it early: a complete dump ends at the prompt, and one that does not is read again rather than planned against.
|
|
402
|
+
let dump = "";
|
|
403
|
+
for (let attempt = 1; ; attempt++) {
|
|
404
|
+
dump = await send(channel, "show running-config", 150_000, 6000);
|
|
405
|
+
if (/[#>]\s*$/.test(dump.replace(/\r/g, "").trimEnd())) break;
|
|
406
|
+
if (attempt === 3) throw new Error(`${device.name} returned an incomplete configuration three times`);
|
|
407
|
+
// What the device still prints of the cut dump ends before the next one starts.
|
|
408
|
+
await send(channel, "", 30_000, 6000);
|
|
409
|
+
}
|
|
403
410
|
const lines = dump.replace(/\r/g, "").split("\n");
|
|
404
411
|
const start = lines.findIndex((line) => line.trim().startsWith("!ROS version"));
|
|
405
412
|
if (start < 0) throw new Error(`${device.name} returned no configuration`);
|
|
@@ -46,3 +46,4 @@ Behaviour that looks like something else. Each one has been hit on a real device
|
|
|
46
46
|
- A second VLAN interface with the same VLAN ID on the same interface is refused, `already have such vlan`, so a VLAN interface is known by its interface and VLAN ID, and a new name is a rename.
|
|
47
47
|
- A switch rule the chip cannot hold is flagged `I`, invalid, and every rule after it is invalid too, with no log line. On a CCR2216 (98DX8525, 7.23) it came at the sixth distinct `dst-port` range, with 66 rules in all, far below the 1,024 MikroTik lists: the amplifier drops toward every VLAN after it did nothing. Few distinct ranges, and check `print count-only where invalid` after an apply.
|
|
48
48
|
- A MACVLAN on a VLAN interface is not routed in the switch chip: its connected route never takes the `H` flag, even with `l3-hw-offloading=yes` on the VLAN under it.
|
|
49
|
+
- A `/system logging` rule naming an action that does not exist yet is refused, `input does not match any value of action`, and `:parse` does not catch it. The action is added first; seen on a CCR2216 on 7.23.5, where the refusal restored the backup.
|
|
@@ -23,3 +23,4 @@ Behaviour that looks like something else. Each one has been hit on a CE6855 runn
|
|
|
23
23
|
- A VLAN name is unique across VLANs: a new VLAN cannot take a name another still has. VLANs no longer used, and their VLAN interfaces, are removed first, in the same candidate.
|
|
24
24
|
- `undo ssh server key-exchange <algorithms>` is refused with "Too many parameters"; `undo ssh server key-exchange` takes none. `hmac` was proved the same way. `cipher` is undone the same way but was not proved on its own.
|
|
25
25
|
- A console on a password only (`passwordOnly`) shows `Please Press ENTER.` after a logout or a refused password, and `Error: The password is invalid.` for a wrong one.
|
|
26
|
+
- Once SNMP is on, the switch prints an engine ID of its own, `snmp-agent local-engineid`, derived from its MAC, and prints each SNMPv3 user as a bare `snmp-agent usm-user v3 <name>` line before its settings. Planning against either as unrendered would undo the user; seen on a CE6855 on V200R005C00SPC800.
|
|
@@ -33,6 +33,8 @@ const DEVICE_FACTS = [
|
|
|
33
33
|
"accounting-scheme default",
|
|
34
34
|
"domain default",
|
|
35
35
|
"Info:",
|
|
36
|
+
// Derived from the switch's MAC once SNMP is on.
|
|
37
|
+
"snmp-agent local-engineid",
|
|
36
38
|
];
|
|
37
39
|
|
|
38
40
|
/** Lines whose removal takes only their keyword, not their value. */
|
|
@@ -493,6 +495,8 @@ function snmp(config: Config, device: Device): void {
|
|
|
493
495
|
config.line(`snmp-agent group v3 ${SNMP_GROUP} privacy read-view all${guarded ? ` acl ${MANAGEMENT_ACL}` : ""}`);
|
|
494
496
|
|
|
495
497
|
for (const [name, user] of Object.entries(snmp.users)) {
|
|
498
|
+
// The switch prints a user's own line before its settings.
|
|
499
|
+
config.line(`snmp-agent usm-user v3 ${name}`);
|
|
496
500
|
config.line(`snmp-agent usm-user v3 ${name} group ${SNMP_GROUP}`);
|
|
497
501
|
config.line(`snmp-agent usm-user v3 ${name} authentication-mode ${SNMP_AUTH[user.auth]} cipher ${marker(user.auth_password)}`);
|
|
498
502
|
config.line(
|