@takodotid/circuit 0.34.2 → 0.35.0
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/README.md +13 -14
- package/dist/chunks/index-20kcjxjg.js +174 -0
- package/dist/chunks/index-2r4bbhac.js +977 -0
- package/dist/chunks/index-n7w3tg5y.js +149 -0
- package/dist/chunks/new-w3zys5y4.js +172 -0
- package/dist/chunks/server-gzsf5me5.js +259 -0
- package/dist/cli/index.js +11347 -9018
- package/dist/helpers/index.js +594 -0
- package/dist/index.js +9 -28
- package/dist/types/core/{addresses.d.ts → address-space.d.ts} +23 -7
- package/dist/types/core/address.d.ts +44 -0
- package/dist/types/core/cabling.d.ts +41 -0
- package/dist/types/core/cross-checks.d.ts +28 -0
- package/dist/types/core/define.d.ts +25 -3
- package/dist/types/core/project-files.d.ts +12 -0
- package/dist/types/core/schema-docs.d.ts +13 -4
- package/dist/types/core/secrets.d.ts +62 -21
- package/dist/types/core/{graph.d.ts → topology.d.ts} +32 -12
- package/dist/types/core/utils.d.ts +8 -0
- package/dist/types/core/validator.d.ts +19 -0
- package/dist/types/helpers/bgp.d.ts +97 -0
- package/dist/types/helpers/checks.d.ts +32 -0
- package/dist/types/helpers/exchange.d.ts +49 -0
- package/dist/types/helpers/filters.d.ts +51 -0
- package/dist/types/helpers/index.d.ts +10 -0
- package/dist/types/helpers/route-server.d.ts +52 -0
- package/dist/types/index.d.ts +5 -3
- package/dist/types/integrations/librenms.d.ts +60 -0
- package/dist/types/integrations/netbox.d.ts +89 -0
- package/dist/types/integrations/peeringdb.d.ts +24 -0
- package/dist/types/integrations/prometheus.d.ts +24 -0
- package/dist/types/integrations/registries.d.ts +8 -0
- package/dist/types/platforms/bgp-wait.d.ts +18 -0
- package/dist/types/platforms/catalog.d.ts +109 -0
- package/dist/types/platforms/derive.d.ts +17 -0
- package/dist/types/platforms/fortios/firewall.d.ts +45 -0
- package/dist/types/platforms/fortios/index.d.ts +134 -0
- package/dist/types/platforms/fortios/names.d.ts +52 -0
- package/dist/types/platforms/fortios/plan.d.ts +104 -0
- package/dist/types/platforms/fortios/render.d.ts +75 -0
- package/dist/types/platforms/fortios/routing.d.ts +56 -0
- package/dist/types/platforms/fortios/tree.d.ts +37 -0
- package/dist/types/platforms/index.d.ts +13 -0
- package/dist/types/platforms/junos/bgp.d.ts +44 -0
- package/dist/types/platforms/junos/index.d.ts +114 -0
- package/dist/types/platforms/junos/render.d.ts +154 -0
- package/dist/types/platforms/line-diff.d.ts +67 -0
- package/dist/types/platforms/platform.d.ts +120 -0
- package/dist/types/platforms/raisecom-ros/index.d.ts +71 -0
- package/dist/types/platforms/raisecom-ros/render.d.ts +41 -0
- package/dist/types/platforms/routeros/export.d.ts +59 -0
- package/dist/types/platforms/routeros/index.d.ts +96 -0
- package/dist/types/{adapters/devices → platforms}/routeros/models.d.ts +4 -0
- package/dist/types/platforms/routeros/plan.d.ts +54 -0
- package/dist/types/platforms/routeros/render.d.ts +240 -0
- package/dist/types/platforms/vrp/index.d.ts +83 -0
- package/dist/types/platforms/vrp/render.d.ts +96 -0
- package/dist/types/schema/common.d.ts +12 -6
- package/dist/types/schema/index.d.ts +1 -0
- package/dist/types/schema/interfaces.d.ts +14 -6
- package/dist/types/schema/policy.d.ts +18 -10
- package/dist/types/schema/routing.d.ts +14 -1
- package/dist/types/schema/system.d.ts +16 -6
- package/dist/types/schema/time-zones.d.ts +2 -0
- package/dist/types/transport/console.d.ts +79 -23
- package/dist/types/transport/path-check.d.ts +32 -0
- package/dist/types/transport/ssh.d.ts +17 -15
- package/package.json +17 -11
- package/src/cli/graph-format.ts +91 -0
- package/src/cli/index.ts +1074 -484
- package/src/cli/new.ts +208 -175
- package/src/cli/rename.ts +97 -91
- package/src/core/address-space.ts +320 -0
- package/src/core/address.ts +202 -0
- package/src/core/cabling.ts +154 -0
- package/src/core/cross-checks.ts +364 -0
- package/src/core/define.ts +26 -3
- package/src/core/project-files.ts +35 -0
- package/src/core/schema-docs.ts +138 -130
- package/src/core/secrets.ts +170 -76
- package/src/core/topology.ts +656 -0
- package/src/core/utils.ts +37 -0
- package/src/core/validator.ts +407 -0
- package/src/helpers/bgp.ts +301 -0
- package/src/helpers/checks.ts +178 -0
- package/src/helpers/exchange.ts +117 -0
- package/src/helpers/filters.ts +107 -0
- package/src/helpers/index.ts +12 -0
- package/src/helpers/route-server.ts +212 -0
- package/src/index.ts +6 -3
- package/src/integrations/librenms.ts +291 -0
- package/src/integrations/netbox.ts +620 -0
- package/src/integrations/peeringdb.ts +173 -0
- package/src/integrations/prometheus.ts +90 -0
- package/src/integrations/registries.ts +25 -0
- package/src/platforms/bgp-wait.ts +41 -0
- package/src/platforms/catalog.ts +69 -0
- package/src/platforms/derive.ts +117 -0
- package/src/{adapters/devices → platforms}/fortios/TRAPS.md +6 -0
- package/src/platforms/fortios/firewall.ts +377 -0
- package/src/platforms/fortios/index.ts +1060 -0
- package/src/platforms/fortios/names.ts +130 -0
- package/src/platforms/fortios/plan.ts +929 -0
- package/src/platforms/fortios/render.ts +779 -0
- package/src/platforms/fortios/routing.ts +476 -0
- package/src/platforms/fortios/tree.ts +129 -0
- package/src/platforms/index.ts +36 -0
- package/src/{adapters/devices → platforms}/junos/TRAPS.md +8 -0
- package/src/platforms/junos/bgp.ts +293 -0
- package/src/platforms/junos/index.ts +1006 -0
- package/src/platforms/junos/render.ts +967 -0
- package/src/platforms/line-diff.ts +244 -0
- package/src/platforms/platform.ts +122 -0
- package/src/platforms/raisecom-ros/TRAPS.md +40 -0
- package/src/platforms/raisecom-ros/index.ts +731 -0
- package/src/platforms/raisecom-ros/render.ts +328 -0
- package/src/{adapters/devices → platforms}/routeros/TRAPS.md +16 -2
- package/src/platforms/routeros/export.ts +342 -0
- package/src/platforms/routeros/index.ts +636 -0
- package/src/{adapters/devices → platforms}/routeros/models.ts +2 -0
- package/src/platforms/routeros/plan.ts +444 -0
- package/src/platforms/routeros/render.ts +1483 -0
- package/src/platforms/vrp/TRAPS.md +45 -0
- package/src/platforms/vrp/index.ts +652 -0
- package/src/platforms/vrp/render.ts +615 -0
- package/src/schema/common.ts +15 -6
- package/src/schema/index.ts +1 -0
- package/src/schema/interfaces.ts +15 -5
- package/src/schema/policy.ts +22 -10
- package/src/schema/routing.ts +16 -1
- package/src/schema/system.ts +16 -6
- package/src/schema/time-zones.ts +482 -0
- package/src/studio/data.ts +172 -168
- package/src/studio/git.ts +95 -90
- package/src/studio/public/app.js +161 -150
- package/src/studio/public/compare.js +219 -212
- package/src/studio/public/diff.js +77 -75
- package/src/studio/public/dom.js +118 -108
- package/src/studio/public/evaluate.js +584 -545
- package/src/studio/public/export.js +120 -118
- package/src/studio/public/graph.js +1343 -1266
- package/src/studio/public/net.js +115 -109
- package/src/studio/public/tables.js +1135 -1083
- package/src/studio/public/tools.js +561 -529
- package/src/studio/server.ts +202 -196
- package/src/transport/console.ts +363 -271
- package/src/transport/path-check.ts +91 -0
- package/src/transport/ssh.ts +98 -94
- package/templates/colocation/checks.ts +11 -6
- package/templates/colocation/edge-01.ts +9 -9
- package/templates/colocation/routing.ts +2 -2
- package/templates/colocation/tenancy.ts +3 -3
- package/templates/colocation/tor-01.ts +3 -3
- package/templates/edge-router/checks.ts +4 -4
- package/templates/edge-router/edge-01.ts +5 -5
- package/templates/edge-router/routing.ts +2 -2
- package/templates/project/AGENTS.md +5 -1
- package/templates/single-site/checks.ts +2 -2
- package/dist/chunks/index-47debt16.js +0 -956
- package/dist/chunks/index-v8zgr7wm.js +0 -128
- package/dist/chunks/new-ny89s7y7.js +0 -166
- package/dist/chunks/server-tjbb3rqc.js +0 -251
- package/dist/presets/index.js +0 -394
- package/dist/types/adapters/devices/catalog.d.ts +0 -86
- package/dist/types/adapters/devices/derive.d.ts +0 -7
- package/dist/types/adapters/devices/fortios/firewall.d.ts +0 -23
- package/dist/types/adapters/devices/fortios/index.d.ts +0 -58
- package/dist/types/adapters/devices/fortios/names.d.ts +0 -48
- package/dist/types/adapters/devices/fortios/plan.d.ts +0 -28
- package/dist/types/adapters/devices/fortios/render.d.ts +0 -38
- package/dist/types/adapters/devices/fortios/routing.d.ts +0 -32
- package/dist/types/adapters/devices/fortios/tree.d.ts +0 -33
- package/dist/types/adapters/devices/index.d.ts +0 -3
- package/dist/types/adapters/devices/junos/bgp.d.ts +0 -11
- package/dist/types/adapters/devices/junos/index.d.ts +0 -42
- package/dist/types/adapters/devices/junos/render.d.ts +0 -52
- package/dist/types/adapters/devices/lines.d.ts +0 -56
- package/dist/types/adapters/devices/raisecom-ros/index.d.ts +0 -28
- package/dist/types/adapters/devices/routeros/export.d.ts +0 -39
- package/dist/types/adapters/devices/routeros/index.d.ts +0 -30
- package/dist/types/adapters/devices/routeros/plan.d.ts +0 -4
- package/dist/types/adapters/devices/routeros/render.d.ts +0 -100
- package/dist/types/adapters/devices/types.d.ts +0 -40
- package/dist/types/adapters/devices/vrp/index.d.ts +0 -27
- package/dist/types/adapters/registries/index.d.ts +0 -3
- package/dist/types/adapters/registries/librenms.d.ts +0 -15
- package/dist/types/adapters/registries/peeringdb.d.ts +0 -16
- package/dist/types/adapters/registries/prometheus.d.ts +0 -16
- package/dist/types/core/across.d.ts +0 -4
- package/dist/types/core/addr.d.ts +0 -34
- package/dist/types/core/files.d.ts +0 -6
- package/dist/types/core/merge.d.ts +0 -4
- package/dist/types/core/time.d.ts +0 -2
- package/dist/types/core/validate.d.ts +0 -2
- package/dist/types/presets/index.d.ts +0 -183
- package/src/adapters/devices/catalog.ts +0 -41
- package/src/adapters/devices/derive.ts +0 -59
- package/src/adapters/devices/fortios/firewall.ts +0 -362
- package/src/adapters/devices/fortios/index.ts +0 -923
- package/src/adapters/devices/fortios/names.ts +0 -115
- package/src/adapters/devices/fortios/plan.ts +0 -888
- package/src/adapters/devices/fortios/render.ts +0 -768
- package/src/adapters/devices/fortios/routing.ts +0 -444
- package/src/adapters/devices/fortios/tree.ts +0 -121
- package/src/adapters/devices/index.ts +0 -9
- package/src/adapters/devices/junos/bgp.ts +0 -269
- package/src/adapters/devices/junos/index.ts +0 -862
- package/src/adapters/devices/junos/render.ts +0 -872
- package/src/adapters/devices/lines.ts +0 -212
- package/src/adapters/devices/raisecom-ros/TRAPS.md +0 -25
- package/src/adapters/devices/raisecom-ros/index.ts +0 -693
- package/src/adapters/devices/routeros/export.ts +0 -321
- package/src/adapters/devices/routeros/index.ts +0 -346
- package/src/adapters/devices/routeros/plan.ts +0 -398
- package/src/adapters/devices/routeros/render.ts +0 -1490
- package/src/adapters/devices/types.ts +0 -38
- package/src/adapters/devices/vrp/TRAPS.md +0 -26
- package/src/adapters/devices/vrp/index.ts +0 -865
- package/src/adapters/registries/index.ts +0 -19
- package/src/adapters/registries/librenms.ts +0 -92
- package/src/adapters/registries/peeringdb.ts +0 -169
- package/src/adapters/registries/prometheus.ts +0 -71
- package/src/cli/graph.ts +0 -89
- package/src/core/across.ts +0 -350
- package/src/core/addr.ts +0 -174
- package/src/core/addresses.ts +0 -316
- package/src/core/files.ts +0 -32
- package/src/core/graph.ts +0 -640
- package/src/core/merge.ts +0 -19
- package/src/core/time.ts +0 -15
- package/src/core/validate.ts +0 -348
- package/src/presets/index.ts +0 -579
- /package/dist/types/{adapters/devices → platforms}/fortios/models.d.ts +0 -0
- /package/dist/types/{adapters/devices → platforms}/junos/models.d.ts +0 -0
- /package/dist/types/{adapters/devices → platforms}/raisecom-ros/models.d.ts +0 -0
- /package/dist/types/{adapters/devices → platforms}/vrp/models.d.ts +0 -0
- /package/src/{adapters/devices → platforms}/fortios/models.ts +0 -0
- /package/src/{adapters/devices → platforms}/junos/models.ts +0 -0
- /package/src/{adapters/devices → platforms}/raisecom-ros/models.ts +0 -0
- /package/src/{adapters/devices → platforms}/vrp/models.ts +0 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { Device, Interface, Port, Vrrp } from "../../schema";
|
|
2
|
+
type AnyPort = Port<string, string, string, string>;
|
|
3
|
+
type AnyInterface = Interface<string, string>;
|
|
4
|
+
type LagInterface = Extract<AnyInterface, {
|
|
5
|
+
type: "lag";
|
|
6
|
+
}>;
|
|
7
|
+
type Switched = AnyPort | LagInterface;
|
|
8
|
+
/** Collects `set` statements, and comments the plan reads. */
|
|
9
|
+
export declare class JunosStatements {
|
|
10
|
+
private readonly lines;
|
|
11
|
+
private readonly notes;
|
|
12
|
+
set(...words: (string | number)[]): void;
|
|
13
|
+
note(comment: string): void;
|
|
14
|
+
/** The statements as the device prints them: each once, and none that another one extends, because the platform prints only the longest. */
|
|
15
|
+
text(): string;
|
|
16
|
+
}
|
|
17
|
+
/** What the platform calls a port, a LAG, a VLAN interface or a loopback. */
|
|
18
|
+
export declare class JunosNames {
|
|
19
|
+
private readonly device;
|
|
20
|
+
readonly lags: Map<string, number>;
|
|
21
|
+
readonly loopbacks: Map<string, number>;
|
|
22
|
+
readonly tunnels: Map<string, number>;
|
|
23
|
+
constructor(device: Device);
|
|
24
|
+
/** A physical port. A 10G cage holding a 1G optic is `ge-`, not `xe-`. */
|
|
25
|
+
port(port: string): string;
|
|
26
|
+
/** The physical interface a port or a LAG is: `xe-0/0/1`, `ae1`. */
|
|
27
|
+
physical(name: string): string;
|
|
28
|
+
/** The logical interface that holds addresses: `xe-0/0/1.0`, `ae1.0`, `irb.10`, `lo0.0`. */
|
|
29
|
+
unit(name: string): string;
|
|
30
|
+
/** The physical ports behind a port or a LAG. */
|
|
31
|
+
members(name: string): string[];
|
|
32
|
+
}
|
|
33
|
+
/** The whole configuration of one device, built section by section into one set of statements. */
|
|
34
|
+
export declare class JunosRender {
|
|
35
|
+
private readonly device;
|
|
36
|
+
/** The class each role logs in with. */
|
|
37
|
+
private static readonly USER_CLASS;
|
|
38
|
+
/** The statement each kind of public key is written under, by the key's own prefix. */
|
|
39
|
+
static readonly KEY_STATEMENT: Record<string, string>;
|
|
40
|
+
private static readonly SNMP_AUTH;
|
|
41
|
+
private static readonly SNMP_PRIVACY;
|
|
42
|
+
/** The SNMPv3 group every user joins, with read access to everything. */
|
|
43
|
+
private static readonly SNMP_GROUP;
|
|
44
|
+
/** A severity as the platform names it. It has no debug; `any` takes everything. */
|
|
45
|
+
private static readonly LEVEL;
|
|
46
|
+
/** The filters that decide who reaches the device's own services, one per family. A filter name is unique across families. */
|
|
47
|
+
private static readonly SERVICES_FILTER;
|
|
48
|
+
/** The policy OSPF announces other routes with. */
|
|
49
|
+
private static readonly OSPF_EXPORT;
|
|
50
|
+
/** Strong ciphers, MACs and key exchanges, offered unless `weak_crypto`. */
|
|
51
|
+
private static readonly SSH_CIPHERS;
|
|
52
|
+
private static readonly SSH_MACS;
|
|
53
|
+
private static readonly SSH_KEY_EXCHANGES;
|
|
54
|
+
/** The transport and port each management service listens on. */
|
|
55
|
+
private static readonly SERVICE_PORTS;
|
|
56
|
+
/** Kinds of frame as `ether-type` names them, in the order the render writes them. */
|
|
57
|
+
private static readonly ETHERTYPES;
|
|
58
|
+
/** Detection under a second: three missed packets 300 ms apart. The platform has no interval of its own, and 3 is its multiplier. */
|
|
59
|
+
static readonly BFD_INTERVAL = 300;
|
|
60
|
+
/** Kinds of flooded traffic, with the statement that leaves each out of a storm-control profile. */
|
|
61
|
+
private static readonly STORM_KINDS;
|
|
62
|
+
private readonly out;
|
|
63
|
+
private readonly names;
|
|
64
|
+
private constructor();
|
|
65
|
+
/** The whole configuration the device should run, as `set` statements. */
|
|
66
|
+
static of(device: Device): string;
|
|
67
|
+
/** BFD under a statement: `routing.bfd`'s timers, or every 300 ms when it has none. */
|
|
68
|
+
static bfd(out: JunosStatements, statement: string, device: Device): void;
|
|
69
|
+
/** Quote a value unless it is a plain word. Quoting more than the platform would is harmless: the comparison ignores quotes. */
|
|
70
|
+
static quote(value: string): string;
|
|
71
|
+
/** The address a VRRP group sits on: the one whose network holds the virtual address. */
|
|
72
|
+
static vrrpAddress(addresses: readonly string[], group: Vrrp): string | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* The storm-control profile a port or LAG names. A profile holds one threshold for every kind it limits, so a port's kinds must share one in percent; `unsupported()` refuses any other.
|
|
75
|
+
*/
|
|
76
|
+
static stormProfile(settings: Switched): {
|
|
77
|
+
name: string;
|
|
78
|
+
percent: number;
|
|
79
|
+
left: string[];
|
|
80
|
+
} | undefined;
|
|
81
|
+
/** The size a port's frames may reach for an IP MTU: the Ethernet header, and a VLAN tag when the port switches. */
|
|
82
|
+
private static frameSize;
|
|
83
|
+
/** `2g`, a rate as a policer takes it. */
|
|
84
|
+
private static bandwidth;
|
|
85
|
+
/** Bytes a policer lets through at once: 10 ms at its rate, and never less than one full frame. */
|
|
86
|
+
private static burstOf;
|
|
87
|
+
/** Each port or range as the platform writes it: `53`, `1000-2000`. */
|
|
88
|
+
private static eachPort;
|
|
89
|
+
/** The family a hardware ACL rule is limited to, by its family or its addresses. */
|
|
90
|
+
private static aclFamily;
|
|
91
|
+
/** The protocol as an IPv6 header names it. */
|
|
92
|
+
private static nextHeader;
|
|
93
|
+
/** A rule's term name: its place, then its description so a reader sees it on the device. */
|
|
94
|
+
private static ruleName;
|
|
95
|
+
private system;
|
|
96
|
+
/** Every user but root logs in with a class. Root is the platform's own account and takes only its password and keys. */
|
|
97
|
+
private users;
|
|
98
|
+
private services;
|
|
99
|
+
/** SNMP version 2c with one read community, version 3 with users in one read-only group, or both. */
|
|
100
|
+
private snmp;
|
|
101
|
+
private vlans;
|
|
102
|
+
/** Layer 2 membership of a port or LAG. The native VLAN is a member too, or its untagged frames are dropped. */
|
|
103
|
+
private switching;
|
|
104
|
+
/** The filter that lets only these kinds of frame in, named after them: `circuit-ethertypes-ipv4-ipv6-arp`. */
|
|
105
|
+
private static ethertypeFilter;
|
|
106
|
+
/** One filter for each set of kinds a port or LAG lets in: those kinds, then nothing else. */
|
|
107
|
+
private ethertypeFilters;
|
|
108
|
+
/** Addresses and VRRP groups of a logical interface such as `irb.10`. */
|
|
109
|
+
private addressing;
|
|
110
|
+
/** Every port the model has. One the config does not declare is turned off, and so is a 10G cage's name for the optic it does not hold. */
|
|
111
|
+
private ports;
|
|
112
|
+
private lags;
|
|
113
|
+
/** VLAN interfaces, loopbacks and GRE tunnels: a description, a tunnel's ends, addresses and VRRP, and an MTU per family. */
|
|
114
|
+
private routedInterfaces;
|
|
115
|
+
/** One profile per threshold the ports and LAGs name. */
|
|
116
|
+
private stormProfiles;
|
|
117
|
+
/**
|
|
118
|
+
* Who reaches the device's own services: each guarded service from its sources only, time answered only to the servers the device keeps time from, and everything else as it was.
|
|
119
|
+
*
|
|
120
|
+
* The filter sits on every loopback unit and on each management port with an address, so it applies whichever routing table or port a packet arrives on.
|
|
121
|
+
*/
|
|
122
|
+
private servicesFilter;
|
|
123
|
+
/** A VRF is a virtual router: its own table, holding its interfaces. */
|
|
124
|
+
private vrfs;
|
|
125
|
+
/** A route with a distance names its next hop as qualified, so two routes to one prefix can each have their own. */
|
|
126
|
+
private staticRoutes;
|
|
127
|
+
/** Spanning tree on every switched port and LAG, each with its own settings. RSTP when no mode is given. */
|
|
128
|
+
private spanningTree;
|
|
129
|
+
/**
|
|
130
|
+
* LLDP on every port or on those listed, a port's own setting over the device's. LLDP runs on a LAG's member ports.
|
|
131
|
+
*
|
|
132
|
+
* The device sends a port's SNMP index as its port ID unless told to send its name, so a neighbor sees `et-0/0/52` rather than `520`.
|
|
133
|
+
*/
|
|
134
|
+
private lldp;
|
|
135
|
+
/** OSPF for IPv4 and OSPFv3 for IPv6, with the same areas and interfaces. */
|
|
136
|
+
private ospf;
|
|
137
|
+
/** Each relay is a group of servers and the interface it listens on, in the table that interface routes in. */
|
|
138
|
+
private dhcpRelay;
|
|
139
|
+
/** sFlow from the management address, to each collector, on every declared port or those listed. A LAG is observed on its member ports. */
|
|
140
|
+
private sflow;
|
|
141
|
+
/**
|
|
142
|
+
* Hardware ACLs. A switched port takes a filter of the switching family, which matches IPv4 and IPv6 under `ip-version`; a routed port takes one filter per family. Each ends by accepting what no rule matched.
|
|
143
|
+
*/
|
|
144
|
+
private acls;
|
|
145
|
+
/** A rule's decision, through a policer when it has a rate. */
|
|
146
|
+
private aclThen;
|
|
147
|
+
private switchingFilter;
|
|
148
|
+
private routedFilter;
|
|
149
|
+
/** A DHCP server is an address pool with its network, range, options and reservations, served on its interface. */
|
|
150
|
+
private dhcpServers;
|
|
151
|
+
/** Router advertisements announce each IPv6 network of the interface. */
|
|
152
|
+
private routerAdvertisements;
|
|
153
|
+
}
|
|
154
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Plan } from "./platform";
|
|
2
|
+
export type Dialect = {
|
|
3
|
+
/** A line at the margin that opens a block, for platforms that do not indent a block's lines. */
|
|
4
|
+
block: RegExp;
|
|
5
|
+
/** Whether a block's lines are indented under it. When they are, any line followed by deeper lines opens a block. */
|
|
6
|
+
indented: boolean;
|
|
7
|
+
/** A line at the margin that closes every open block. */
|
|
8
|
+
terminator: string;
|
|
9
|
+
/** Lines that describe the device rather than configure it, or that the platform prints whatever is set. */
|
|
10
|
+
ignore: (line: string) => boolean;
|
|
11
|
+
/** The command that removes a line. */
|
|
12
|
+
undo: (line: string) => string;
|
|
13
|
+
/** Leaves one level of block. */
|
|
14
|
+
leave: string;
|
|
15
|
+
/** Lines sent before the undos of their block, because the platform refuses an undo until they are in place. */
|
|
16
|
+
first?: RegExp;
|
|
17
|
+
/** A line in the form both sides compare in, for example a secret the device prints as a cipher. */
|
|
18
|
+
canon?: (line: string) => string;
|
|
19
|
+
/** Where a block is sent among the others, lowest first, so that nothing is referenced before it exists. In the order they differ when absent. */
|
|
20
|
+
order?: (path: string[]) => number;
|
|
21
|
+
};
|
|
22
|
+
/** One line, with the blocks it sits in, outermost first. */
|
|
23
|
+
export type Entry = {
|
|
24
|
+
path: string[];
|
|
25
|
+
line: string;
|
|
26
|
+
};
|
|
27
|
+
/** What changes inside one block. */
|
|
28
|
+
export type Group = {
|
|
29
|
+
path: string[];
|
|
30
|
+
remove: string[];
|
|
31
|
+
add: string[];
|
|
32
|
+
};
|
|
33
|
+
/** Commands a platform needs around one group, such as releasing a binding before a change and restoring it after. */
|
|
34
|
+
export type Around = (group: Group) => {
|
|
35
|
+
before: string[];
|
|
36
|
+
after: string[];
|
|
37
|
+
};
|
|
38
|
+
export declare class LineDiff {
|
|
39
|
+
/** What a switch prints in place of a secret: the cipher of a password, a community or an SNMPv3 key, and a Raisecom community in clear. Never an algorithm list such as `ssh server cipher`. */
|
|
40
|
+
private static readonly STORED_CREDENTIAL;
|
|
41
|
+
/** How deep a line is indented. */
|
|
42
|
+
private static indentOf;
|
|
43
|
+
static entries(text: string, dialect: Dialect): Entry[];
|
|
44
|
+
/** The part of a line that names what it sets: `rule 5`, a free-text keyword, or the line up to its value. Two lines with one head are one setting with two values. */
|
|
45
|
+
static head(line: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* What differs, by block.
|
|
48
|
+
*
|
|
49
|
+
* A device line replaced by a desired line with the same head is not undone; sending the new one is enough. A block the render does not hold goes with its header, and its lines with it.
|
|
50
|
+
*/
|
|
51
|
+
static compare(desired: string, current: string, dialect: Dialect): Group[];
|
|
52
|
+
/**
|
|
53
|
+
* Send every line that holds a secret again, for `apply --secrets`. A device prints a secret as a cipher, so a line whose secret changed compares equal and is otherwise never sent.
|
|
54
|
+
*/
|
|
55
|
+
static withSecrets(groups: Group[], desired: string, dialect: Dialect): Group[];
|
|
56
|
+
/**
|
|
57
|
+
* Replace a changed VLAN list line with only what changed.
|
|
58
|
+
*
|
|
59
|
+
* A platform keeps its VLANs as one line, such as `vlan batch 10 20 to 30`. Undoing the old line would delete VLANs still in use, so the plan adds the new IDs and removes the gone ones instead.
|
|
60
|
+
*/
|
|
61
|
+
static vlanListChange(groups: Group[], prefix: string, parse: (line: string) => number[], format: (ids: number[]) => string[], removal: (ids: number[]) => string[]): void;
|
|
62
|
+
private static nothingAround;
|
|
63
|
+
/** The steps for the groups: enter each block of the path, undo, add, then leave each level. */
|
|
64
|
+
static steps(groups: Group[], dialect: Dialect, around?: Around): Plan["steps"];
|
|
65
|
+
/** A device prints stored credentials as ciphers. They never leave the read. */
|
|
66
|
+
static scrub(text: string): string;
|
|
67
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { Neighbor } from "../core/cabling";
|
|
2
|
+
import type { Device, Family } from "../schema";
|
|
3
|
+
import type { ConsoleDialect } from "../transport/console";
|
|
4
|
+
import type { WaitLimits } from "./bgp-wait";
|
|
5
|
+
import type { PlatformName } from "./catalog";
|
|
6
|
+
/** One part of a plan: what a reviewer reads, and what is sent. */
|
|
7
|
+
export type Step = {
|
|
8
|
+
title: string;
|
|
9
|
+
show: string[];
|
|
10
|
+
send: string[];
|
|
11
|
+
};
|
|
12
|
+
/** The commands that turn what a device runs into what its config says. `problems` blocks an apply: something the adapter cannot converge. */
|
|
13
|
+
export type Plan = {
|
|
14
|
+
steps: Step[];
|
|
15
|
+
problems: string[];
|
|
16
|
+
};
|
|
17
|
+
export type ApplyOptions = {
|
|
18
|
+
/** Also send every secret, so a rotated value reaches the device. Secrets cannot be read back, so they are otherwise only sent when the object holding them is new. */
|
|
19
|
+
secrets: boolean;
|
|
20
|
+
/** Minutes before a platform that can restore itself does so, if the run does not prove access survived. */
|
|
21
|
+
rollback: number;
|
|
22
|
+
/** Reach the device through its serial console, `connection.console`, instead of SSH to its management address. */
|
|
23
|
+
console?: boolean;
|
|
24
|
+
};
|
|
25
|
+
/** How a device is read. */
|
|
26
|
+
export type ReadOptions = Pick<ApplyOptions, "console">;
|
|
27
|
+
/** A login on a device for commands that only read, as `circuit show` runs them. */
|
|
28
|
+
export type ReadSession = {
|
|
29
|
+
/**
|
|
30
|
+
* Run one command and return what it printed, without its echo or the prompt.
|
|
31
|
+
*
|
|
32
|
+
* At `timeout` milliseconds, a command run on its own over SSH is left, and what it printed so far is returned. In a shell or on a console, where it would hold up every command after it, the run fails instead.
|
|
33
|
+
*/
|
|
34
|
+
run(command: string, timeout?: number): Promise<string>;
|
|
35
|
+
/** Log out. */
|
|
36
|
+
close(): void;
|
|
37
|
+
};
|
|
38
|
+
/** How the checks after an apply reach the device, and how long they wait. */
|
|
39
|
+
export type HealthOptions = ReadOptions & {
|
|
40
|
+
/** How long BGP sessions established before the apply have to be established again. `BgpWait.AFTER_APPLY` when absent. */
|
|
41
|
+
bgp?: WaitLimits;
|
|
42
|
+
};
|
|
43
|
+
/** The checks after an apply, holding what they compare against, which was read before the plan was sent. */
|
|
44
|
+
export type HealthCheck = {
|
|
45
|
+
/** Run the checks. Gives one line per problem, each saying what to do; none when the device is healthy. */
|
|
46
|
+
run(): Promise<string[]>;
|
|
47
|
+
};
|
|
48
|
+
/** A BGP neighbor in the config and its live session, as `circuit bgp` shows it. A neighbor with no session is not established. */
|
|
49
|
+
export type BgpSession = {
|
|
50
|
+
/** The neighbor's name in the config. */
|
|
51
|
+
neighbor: string;
|
|
52
|
+
/** The session's remote address, or `-` when there is no session. */
|
|
53
|
+
remote: string;
|
|
54
|
+
/** Whether the session is established. */
|
|
55
|
+
established: boolean;
|
|
56
|
+
/** How many prefixes it received, as the device prints it, or `-`. */
|
|
57
|
+
prefixes: string;
|
|
58
|
+
/** How long it has been up, as the device prints it, or `no session`. */
|
|
59
|
+
uptime: string;
|
|
60
|
+
};
|
|
61
|
+
/** One BGP log line: when, as the device printed it, such as `2026-10-24 03:12:44`, and the rest of the line. */
|
|
62
|
+
export type BgpLogLine = {
|
|
63
|
+
at: string;
|
|
64
|
+
message: string;
|
|
65
|
+
};
|
|
66
|
+
/** The operating system a platform runs, and the versions it is proved on. */
|
|
67
|
+
export type OsSupport = {
|
|
68
|
+
/** Its name in full, such as `MikroTik RouterOS`. */
|
|
69
|
+
name: string;
|
|
70
|
+
/** The versions the adapter renders for, such as `7`. */
|
|
71
|
+
versions: string;
|
|
72
|
+
/** The device and version it was proved on, such as `CCR2216-1G-12XS-2XQ, RouterOS 7.23`. */
|
|
73
|
+
provedOn: string;
|
|
74
|
+
/** Whether a read or an apply refuses a device on another version. */
|
|
75
|
+
checked: boolean;
|
|
76
|
+
};
|
|
77
|
+
/** The switch rules a render makes from a device's hardware ACLs, counted. */
|
|
78
|
+
export type SwitchRules = {
|
|
79
|
+
/** How many rules there are. */
|
|
80
|
+
count: number;
|
|
81
|
+
/** How many distinct port ranges they use, such as `0-1023`. */
|
|
82
|
+
ranges: number;
|
|
83
|
+
};
|
|
84
|
+
export declare abstract class Platform {
|
|
85
|
+
/** The name a device's `platform` field takes. */
|
|
86
|
+
abstract readonly name: PlatformName;
|
|
87
|
+
abstract readonly os: OsSupport;
|
|
88
|
+
/** File extension of a saved snapshot, for syntax highlighting. */
|
|
89
|
+
abstract readonly extension: string;
|
|
90
|
+
/** How the platform's serial console asks for a login and shows its prompt. Present when the platform can be read and applied through a console, `--console`, and opened with `circuit console`. */
|
|
91
|
+
readonly console: ConsoleDialect | undefined;
|
|
92
|
+
/** Fields this platform cannot express. Validation fails on any of them, so nothing is skipped silently. */
|
|
93
|
+
abstract unsupported(device: Device): string[];
|
|
94
|
+
/** The switch rules the render makes from the device's hardware ACLs, so `validate` can hold them to the model's limits. Absent on a platform whose rules are not counted. */
|
|
95
|
+
switchRules?(device: Device): SwitchRules;
|
|
96
|
+
/** The whole configuration the device should run. Secrets appear as markers, never values. */
|
|
97
|
+
abstract render(device: Device): string;
|
|
98
|
+
/** What the device runs now, secrets removed, in the form `render` produces where the platform allows. */
|
|
99
|
+
abstract read(device: Device, network: readonly Device[], options?: ReadOptions): Promise<string>;
|
|
100
|
+
/** The LLDP neighbors the device sees, by Circuit's port names, for `snapshot` to save. Absent on a platform whose LLDP command and its output are not proved on a device yet. */
|
|
101
|
+
neighbors?(device: Device, network: readonly Device[], options?: ReadOptions): Promise<Neighbor[]>;
|
|
102
|
+
/** What it takes to go from `current` to `desired`. */
|
|
103
|
+
abstract plan(desired: string, current: string, options: ApplyOptions): Plan;
|
|
104
|
+
/** Replace the contents of a prefix set fetched from a registry. Absent on a platform that cannot hold one. */
|
|
105
|
+
fill?(device: Device, network: readonly Device[], set: string, family: Family, prefixes: string[]): Promise<void>;
|
|
106
|
+
/** Send a plan, keeping the device reachable or restoring it. */
|
|
107
|
+
abstract apply(device: Device, network: readonly Device[], plan: Plan, options: ApplyOptions): Promise<void>;
|
|
108
|
+
/** Whether a command only reads on this platform, so `circuit show` may send it. Anything not known to only read is refused. */
|
|
109
|
+
abstract readOnly(command: string): boolean;
|
|
110
|
+
/** Log in for commands that only read, over SSH or on the console, the way the platform's read logs in. */
|
|
111
|
+
abstract session(device: Device, options?: ReadOptions): Promise<ReadSession>;
|
|
112
|
+
/** Each BGP neighbor in the config, in its order, with its live session, read over a `session()`. Absent on a platform `circuit bgp` does not support yet. */
|
|
113
|
+
bgpSessions?(device: Device, session: ReadSession): Promise<BgpSession[]>;
|
|
114
|
+
/** The device's BGP log lines from the last `minutes`, by the device's own clock, read over a `session()`. */
|
|
115
|
+
bgpLog?(session: ReadSession, minutes: number): Promise<BgpLogLine[]>;
|
|
116
|
+
/**
|
|
117
|
+
* Checks that the device is healthy after an apply, not only that it took the commands. Called before the plan is sent, to read what the checks compare against; the CLI runs them after the apply and the snapshot. Absent on a platform with no checks yet.
|
|
118
|
+
*/
|
|
119
|
+
health?(device: Device, plan: Plan, options?: HealthOptions): Promise<HealthCheck>;
|
|
120
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { ClientChannel } from "ssh2";
|
|
2
|
+
import type { Neighbor } from "../../core/cabling";
|
|
3
|
+
import type { Device } from "../../schema";
|
|
4
|
+
import { type ConsoleDialect } from "../../transport/console";
|
|
5
|
+
import { type ApplyOptions, type OsSupport, type Plan, type ReadOptions, type ReadSession, Platform } from "../platform";
|
|
6
|
+
/** A session, and how to prove access in a fresh login: a new SSH session, or logging out and in again on the console. */
|
|
7
|
+
export type Session = {
|
|
8
|
+
channel: ClientChannel;
|
|
9
|
+
close: () => void;
|
|
10
|
+
fresh: () => Promise<Session>;
|
|
11
|
+
};
|
|
12
|
+
export declare class RaisecomRos extends Platform {
|
|
13
|
+
/** How the console asks for a login and shows its prompt. Not yet proved on a device: the RAX721's console was never cabled to a jump host. */
|
|
14
|
+
static readonly CONSOLE: ConsoleDialect;
|
|
15
|
+
/** Lines the device prints whatever is configured, or that are part of moving around the CLI. */
|
|
16
|
+
private static readonly DEVICE_FACTS;
|
|
17
|
+
/** Lines whose opposite is not `no` and the line. */
|
|
18
|
+
private static readonly OPPOSITES;
|
|
19
|
+
/** Lines whose removal takes only their keyword, not their value. */
|
|
20
|
+
private static readonly UNDO_BY_KEYWORD;
|
|
21
|
+
private static readonly DIALECT;
|
|
22
|
+
/** The firmware offers only an `ssh-rsa` host key, so that one is allowed for this platform alone. Key exchange, cipher and MAC still negotiate modern ones. */
|
|
23
|
+
private static readonly HOST_KEYS;
|
|
24
|
+
/** How long a dump may go quiet before the prompt, as on a lossy path where a retransmit stalls it for seconds, and how long it may take in all. */
|
|
25
|
+
private static readonly DUMP_QUIET;
|
|
26
|
+
private static readonly DUMP_LIMIT;
|
|
27
|
+
/** What the device prints when it refuses a line. */
|
|
28
|
+
private static readonly REFUSED;
|
|
29
|
+
/** Lines that ask for `y` and do nothing without it. */
|
|
30
|
+
private static readonly CONFIRM;
|
|
31
|
+
/** A service letting go of an access-list, so the list can change. */
|
|
32
|
+
private static readonly RELEASE;
|
|
33
|
+
/** Lines that each add one more of a kind rather than set a value: `snmp-server access-list 1001` beside `1000` binds both. */
|
|
34
|
+
private static readonly STANDALONE;
|
|
35
|
+
/** Commands that only read. A `?` sent by a script is run, so a line with one is refused. */
|
|
36
|
+
private static readonly READS;
|
|
37
|
+
readonly name = "raisecom-ros";
|
|
38
|
+
readonly os: OsSupport;
|
|
39
|
+
readonly extension = ".txt";
|
|
40
|
+
readonly console: ConsoleDialect;
|
|
41
|
+
unsupported(device: Device): string[];
|
|
42
|
+
render(device: Device): string;
|
|
43
|
+
/** What the device runs, credentials scrubbed. */
|
|
44
|
+
read(device: Device, _network: readonly Device[], options?: ReadOptions): Promise<string>;
|
|
45
|
+
/** Read `show running-config` until it ends at the prompt, or until it goes quiet for too long or takes too long in all. */
|
|
46
|
+
private static dump;
|
|
47
|
+
/** The LLDP neighbors from `show lldp remote detail`, which spells each port in full. The short form abbreviates ports (`TGE1/3/3`) and pads columns, so a name with a space cannot be told apart there. */
|
|
48
|
+
neighbors(device: Device, _network: readonly Device[], options?: ReadOptions): Promise<Neighbor[]>;
|
|
49
|
+
/**
|
|
50
|
+
* The neighbors in `show lldp remote detail`: a `<port> has N remotes:` line per port, then a block per remote of `Key: value` lines. A long value wraps onto lines that start with spaces, cut mid-word.
|
|
51
|
+
*
|
|
52
|
+
* A remote without a system name is named by its chassis ID. A port the catalog does not have, such as the out-of-band port, is left out.
|
|
53
|
+
*/
|
|
54
|
+
static lldpRemotes(text: string, device: Device): Neighbor[];
|
|
55
|
+
plan(desired: string, current: string, options: ApplyOptions): Plan;
|
|
56
|
+
apply(device: Device, _network: readonly Device[], plan: Plan, options: ApplyOptions): Promise<void>;
|
|
57
|
+
readOnly(command: string): boolean;
|
|
58
|
+
/** One shell for every command, as the platform takes commands only there. */
|
|
59
|
+
session(device: Device, options?: ReadOptions): Promise<ReadSession>;
|
|
60
|
+
private static undo;
|
|
61
|
+
/** An interactive shell, paging off, over SSH or on the console. A session that does not answer as ROS is refused, so nothing meant for it can reach another shell. */
|
|
62
|
+
private static open;
|
|
63
|
+
private static sshShell;
|
|
64
|
+
private static consoleShell;
|
|
65
|
+
/** The ports, by their `interface` line, that filter what they take in with an access-list. */
|
|
66
|
+
private static filteredPorts;
|
|
67
|
+
/** Services holding an access-list. It cannot change while any of them does. */
|
|
68
|
+
private static holders;
|
|
69
|
+
/** The VLAN IDs of a `create vlan 10,20-30 active` line. */
|
|
70
|
+
private static createdIds;
|
|
71
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Device, SnmpUser } from "../../schema";
|
|
2
|
+
/** The configuration a Raisecom ROS device should run. */
|
|
3
|
+
export declare class RaisecomRosRender {
|
|
4
|
+
/** The access-list that guards every management service. */
|
|
5
|
+
static readonly MANAGEMENT_ACL = 1000;
|
|
6
|
+
/** The access-list that guards SNMP when it has sources of its own. */
|
|
7
|
+
static readonly SNMP_ACL = 1001;
|
|
8
|
+
/** A log level as the platform prints it, a number. It takes the names too (`warnings`), but prints the number. */
|
|
9
|
+
private static readonly LOG_LEVELS;
|
|
10
|
+
/** The most MAC addresses port security takes on a port, and its default. */
|
|
11
|
+
static readonly MAC_LIMIT_MAX = 1024;
|
|
12
|
+
/** A kind of frame as a MAC access-list rule matches it, in the form the device prints. It takes a type as hex without `0x`, and names IPv4 and ARP. */
|
|
13
|
+
private static readonly ETHERTYPES;
|
|
14
|
+
/** The log level and UDP port a log host has unless told otherwise. Neither prints. */
|
|
15
|
+
private static readonly LOG_DEFAULTS;
|
|
16
|
+
/** The SNMPv3 authentication each `auth` takes on this platform. One missing here cannot be expressed. */
|
|
17
|
+
static readonly SNMP_AUTH: Partial<Record<SnmpUser["auth"], string>>;
|
|
18
|
+
/** The OSPF process number. */
|
|
19
|
+
private static readonly OSPF_PROCESS;
|
|
20
|
+
/** The SNMPv3 access group every user belongs to, read-only on the whole tree. */
|
|
21
|
+
private static readonly SNMP_GROUP;
|
|
22
|
+
/** `99,200-201,999`, the platform's compression of a VLAN list. */
|
|
23
|
+
static vlanList(ids: number[]): string;
|
|
24
|
+
/** The whole configuration of a device. */
|
|
25
|
+
static of(device: Device): string;
|
|
26
|
+
/** An access-list permitting `sources`, then denying the rest. Its description takes one word. */
|
|
27
|
+
private static accessList;
|
|
28
|
+
/** Access or trunk membership, for a port or a LAG. */
|
|
29
|
+
private static switching;
|
|
30
|
+
/** A VRRP group. The platform enables a group once it has an address, and preempts unless told not to. */
|
|
31
|
+
private static vrrp;
|
|
32
|
+
/** A port the config does not declare is shut down. A LAG member holds its membership and description; the LAG holds the rest. */
|
|
33
|
+
private static physicalPort;
|
|
34
|
+
/** The MAC access-list of the port at `index` in the catalog, for its `ethertypes`. MAC access-lists are 3000 and up. */
|
|
35
|
+
/** The BFD session for each next hop a static route watches, numbered from 1 in the order the routes come, with the VLAN its interface is on. A next hop on no VLAN interface's network has none. */
|
|
36
|
+
static bfdSessions(device: Device): Map<string, {
|
|
37
|
+
id: number;
|
|
38
|
+
vlan: string;
|
|
39
|
+
}>;
|
|
40
|
+
static ethertypeAcl(index: number): number;
|
|
41
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export type Command = {
|
|
2
|
+
/** The menu the command belongs to, such as `/ip address`. */
|
|
3
|
+
menu: string;
|
|
4
|
+
verb: "add" | "set";
|
|
5
|
+
/** What a `set` addresses: `[ find default-name=ether1 ]`, `ftp`, `1`, or nothing for a menu of one. */
|
|
6
|
+
selector: string;
|
|
7
|
+
/** Words without a value, such as `blackhole`. */
|
|
8
|
+
flags: string[];
|
|
9
|
+
/** Properties, unquoted and unescaped. */
|
|
10
|
+
attrs: Record<string, string>;
|
|
11
|
+
};
|
|
12
|
+
export type Parsed = {
|
|
13
|
+
commands: Command[];
|
|
14
|
+
/** Address lists whose entries are filled by `refresh`, not by the render. */
|
|
15
|
+
generated: Set<string>;
|
|
16
|
+
};
|
|
17
|
+
export declare class RouterOsExport {
|
|
18
|
+
/**
|
|
19
|
+
* Values the platform holds when nothing was set, per menu, and under `*` for every menu.
|
|
20
|
+
*
|
|
21
|
+
* A property at its default is dropped from both sides of a comparison, and this is the value a property the config does not state is reset to. A property the device holds that is not here cannot be reset, which the plan reports as a problem.
|
|
22
|
+
*/
|
|
23
|
+
private static readonly DEFAULTS;
|
|
24
|
+
/** Whether each `/ip service` ships disabled. */
|
|
25
|
+
private static readonly SERVICE_DISABLED;
|
|
26
|
+
/** Helpers of `/ip firewall service-port` that ship disabled. The rest ship enabled. */
|
|
27
|
+
private static readonly HELPER_DISABLED;
|
|
28
|
+
/** A property the device stops printing once another returns to its default. Resetting that other one clears it, so it is never reset on its own. */
|
|
29
|
+
static readonly CLEARED_WITH: Record<string, Record<string, string>>;
|
|
30
|
+
/** Properties whose value cannot be read back from the device. They are compared only by the presence of what holds them. */
|
|
31
|
+
static readonly SECRET_KEYS: Set<string>;
|
|
32
|
+
/** Properties that tell two `add` entries of a menu apart. `name` where the menu is not listed. */
|
|
33
|
+
private static readonly IDENTITY;
|
|
34
|
+
/** Menus whose entries are an ordered list without names. They are rewritten whole, in the order the render gives. */
|
|
35
|
+
static readonly ORDERED: Set<string>;
|
|
36
|
+
/** Undo the line wrapping an export applies: a backslash at the end of a line continues it. */
|
|
37
|
+
private static unwrap;
|
|
38
|
+
/** A quoted value without its quotes and escapes. `\_` is an escaped space. */
|
|
39
|
+
private static unquote;
|
|
40
|
+
/** Split a command into words, keeping quoted values and bracketed selectors whole. */
|
|
41
|
+
private static words;
|
|
42
|
+
/** One `add` or `set` line into a command. */
|
|
43
|
+
private static parseLine;
|
|
44
|
+
static parse(text: string): Parsed;
|
|
45
|
+
/** The default of one property of a command, or undefined when it is not known. */
|
|
46
|
+
static defaultOf(command: Command, property: string): string | undefined;
|
|
47
|
+
/** How the renderer writes a secret. */
|
|
48
|
+
static isSecretMarker(value: string): boolean;
|
|
49
|
+
/** A filter rule as the platform prints it, with its own spacing, squeezed so that only a real change survives. */
|
|
50
|
+
private static canonicalRule;
|
|
51
|
+
/** One property value in the form both sides compare in. */
|
|
52
|
+
private static normalValue;
|
|
53
|
+
/** A command's properties without defaults or secrets, in the form both sides compare in. */
|
|
54
|
+
static normal(command: Command): Record<string, string>;
|
|
55
|
+
/** What identifies an `add` entry, so that the same entry is found on both sides. */
|
|
56
|
+
static identity(command: Command): Record<string, string>;
|
|
57
|
+
/** One command as a string that is equal for equal commands. */
|
|
58
|
+
static canonical(command: Command): string;
|
|
59
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { Neighbor } from "../../core/cabling";
|
|
2
|
+
import type { Device, Family } from "../../schema";
|
|
3
|
+
import { type ConsoleDialect } from "../../transport/console";
|
|
4
|
+
import { type ApplyOptions, type BgpLogLine, type BgpSession, type HealthCheck, type HealthOptions, type OsSupport, type Plan, type ReadOptions, type ReadSession, type SwitchRules, Platform } from "../platform";
|
|
5
|
+
export declare class RouterOs extends Platform {
|
|
6
|
+
/** How the RouterOS console asks for a login. The flags after the user turn off colours and terminal detection, without which the console redraws every line. */
|
|
7
|
+
static readonly CONSOLE: ConsoleDialect;
|
|
8
|
+
/** Why a MAC limit is refused: neither a bridge port nor a switch port has a learning limit on 7.23.5. */
|
|
9
|
+
private static readonly NO_MAC_LIMIT;
|
|
10
|
+
/** The major version this adapter renders for. Version 6 has a different BGP and filter language altogether. */
|
|
11
|
+
private static readonly SUPPORTED_MAJOR;
|
|
12
|
+
/** Both dumps stamp the time they were taken. Without the stamp, an unchanged device reads the same twice. */
|
|
13
|
+
private static readonly EXPORT_TIMESTAMP;
|
|
14
|
+
/** Lists certificates in the form the renderer writes them, since an export does not include them. One line, because a script sent over exec runs as one. */
|
|
15
|
+
private static readonly LIST_CERTIFICATES;
|
|
16
|
+
/** Every BGP session, one line each: name, remote address, established, prefixes received, uptime. One line, because a script sent over exec runs as one. */
|
|
17
|
+
private static readonly LIST_BGP_SESSIONS;
|
|
18
|
+
/**
|
|
19
|
+
* Every LLDP neighbor, one line each: our interfaces, the port first and then the LAG and bridge it is in, the far system name, and the far port as LLDP reports it. `:tostr` keeps the interface list one value; joined to a string as it is, a list repeats the whole line for each of its items. One line, because a script sent over exec runs as one.
|
|
20
|
+
*/
|
|
21
|
+
private static readonly LIST_NEIGHBORS;
|
|
22
|
+
/** BGP log lines, without the `connection ...` lines a session that cannot connect repeats. */
|
|
23
|
+
private static readonly BGP_LOG;
|
|
24
|
+
/** The device's date and time, in the form its log prints: `2026-10-24 03:12:44`. */
|
|
25
|
+
private static readonly CLOCK;
|
|
26
|
+
/** The switch chip's rules. A rule it cannot hold is invalid, and so is every rule after it, with no log line (TRAPS.md). */
|
|
27
|
+
private static readonly SWITCH_RULES;
|
|
28
|
+
private static readonly COUNT_INVALID_SWITCH_RULES;
|
|
29
|
+
private static readonly ROLLBACK_SCHEDULER;
|
|
30
|
+
/** Commands that only read: print, monitor, ping, traceroute, torch, profile, sniffer quick, an AS-path regex test, export, and `:put`, `:foreach` or `:delay` scripts. */
|
|
31
|
+
private static readonly READS;
|
|
32
|
+
/** Words that change something, or print secrets. A command with any of them is refused, whatever else it holds. */
|
|
33
|
+
private static readonly WRITES;
|
|
34
|
+
/** Flags after the user over SSH: no colours, no terminal detection, 300 columns, so output is plain and lines are not cut. */
|
|
35
|
+
private static readonly PLAIN_OUTPUT;
|
|
36
|
+
readonly name = "routeros";
|
|
37
|
+
readonly os: OsSupport;
|
|
38
|
+
readonly extension = ".rsc";
|
|
39
|
+
readonly console: ConsoleDialect;
|
|
40
|
+
unsupported(device: Device): string[];
|
|
41
|
+
render(device: Device): string;
|
|
42
|
+
switchRules(device: Device): SwitchRules;
|
|
43
|
+
/**
|
|
44
|
+
* What the device runs: its export, its users, and its certificates. Secrets are not part of an export.
|
|
45
|
+
*/
|
|
46
|
+
read(device: Device, _network?: readonly Device[], options?: ReadOptions): Promise<string>;
|
|
47
|
+
plan(desired: string, current: string, options: ApplyOptions): Plan;
|
|
48
|
+
apply(device: Device, _network: readonly Device[], changes: Plan, options: ApplyOptions): Promise<void>;
|
|
49
|
+
readOnly(command: string): boolean;
|
|
50
|
+
/** Over SSH, each command runs on its own. */
|
|
51
|
+
session(device: Device, options?: ReadOptions): Promise<ReadSession>;
|
|
52
|
+
/**
|
|
53
|
+
* A session is named `<connection>-<n>`, but a renamed connection keeps its session's old name until the session restarts. So a neighbor is matched by its address first, then by name.
|
|
54
|
+
*/
|
|
55
|
+
bgpSessions(device: Device, session: ReadSession): Promise<BgpSession[]>;
|
|
56
|
+
/** A `time>` filter in `/log print` does not filter, so the lines are kept here by comparing each one's time with the device's clock. */
|
|
57
|
+
bgpLog(session: ReadSession, minutes: number): Promise<BgpLogLine[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Two checks after an apply. When the plan touched switch rules, none may be invalid. BGP sessions established before the apply must be established again, within `BgpWait.AFTER_APPLY`.
|
|
60
|
+
*/
|
|
61
|
+
health(device: Device, plan: Plan, options?: HealthOptions): Promise<HealthCheck>;
|
|
62
|
+
/** The LLDP neighbors the device sees, by Circuit's port names. */
|
|
63
|
+
neighbors(device: Device, network: readonly Device[], options?: ReadOptions): Promise<Neighbor[]>;
|
|
64
|
+
/** One line of `LIST_NEIGHBORS` as a neighbor. Our port is the first interface, by Circuit's name when it is a port. */
|
|
65
|
+
private static neighbor;
|
|
66
|
+
/**
|
|
67
|
+
* RouterOS reports the far port's description, where it has one, not its name (TRAPS.md). When it is the description of exactly one port of that device in the network, that port is the far port, by Circuit's name; otherwise the report stays as it is.
|
|
68
|
+
*/
|
|
69
|
+
private static farPort;
|
|
70
|
+
/** Replace a list's entries in batches, so each command stays a sane length. */
|
|
71
|
+
fill(device: Device, _network: readonly Device[], set: string, family: Family, prefixes: string[]): Promise<void>;
|
|
72
|
+
/** The names of the configured neighbors whose session is established now. None, without logging in, on a device without BGP neighbors. */
|
|
73
|
+
private establishedSessions;
|
|
74
|
+
/** Wait until every one of these neighbors is established again, and give a problem for each that is not when time runs out. */
|
|
75
|
+
private bgpBack;
|
|
76
|
+
/** A problem when any switch rule is invalid, saying what to do. */
|
|
77
|
+
private static invalidSwitchRules;
|
|
78
|
+
/** Log in over SSH. `flags` go after the user, as RouterOS reads them: `+ct300w`. */
|
|
79
|
+
private static login;
|
|
80
|
+
private static sshSession;
|
|
81
|
+
/** Log in on the console. `settle` is the quiet after the prompt a command waits for, as `ConsoleShell` takes it. */
|
|
82
|
+
private static consoleSession;
|
|
83
|
+
/** Log in over SSH, or on the console when asked. */
|
|
84
|
+
private static open;
|
|
85
|
+
/** Refuse a device on a version this adapter does not render for, before anything is read or sent. */
|
|
86
|
+
private static checkVersion;
|
|
87
|
+
/** A time as the clock and the log print it, `2026-10-24 03:12:44`, in milliseconds. Both are read the same way, so the computer's time zone does not matter. Not a number when the text is not such a time. */
|
|
88
|
+
private static logTime;
|
|
89
|
+
private static withoutTimestamp;
|
|
90
|
+
/** Escape a command so it can sit inside a quoted string on the device. */
|
|
91
|
+
private static escapeForString;
|
|
92
|
+
/** Compile a command on the device without running it. Returns why it was refused, or undefined. */
|
|
93
|
+
private static refusal;
|
|
94
|
+
/** Upload a certificate and its key, import both under one name, and delete the files. */
|
|
95
|
+
private static installCertificate;
|
|
96
|
+
}
|