@takodotid/circuit 0.43.1 → 1.0.0-rc.2
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 +115 -37
- package/package.json +21 -58
- package/src/checks/across.ts +402 -0
- package/src/checks/built-in.ts +256 -0
- package/src/checks/device.ts +436 -0
- package/src/checks/index.ts +53 -0
- package/src/cli/advisories.ts +108 -0
- package/src/cli/app.ts +71 -0
- package/src/cli/editor-types.generated.ts +30 -0
- package/src/cli/editor-types.ts +69 -0
- package/src/cli/format.ts +124 -0
- package/src/cli/git-hooks.ts +79 -0
- package/src/cli/index.ts +350 -1170
- package/src/cli/migrate.ts +554 -0
- package/src/cli/project-commands.ts +656 -0
- package/src/cli/releases.ts +374 -0
- package/src/cli/remember.ts +339 -0
- package/src/cli/rename.ts +27 -33
- package/src/cli/secrets-password.ts +60 -0
- package/src/cli/secrets.ts +258 -0
- package/src/cli/setup.ts +300 -0
- package/src/cli/signing.ts +23 -0
- package/src/cli/text-editor.ts +268 -0
- package/src/cli/ui.ts +298 -0
- package/src/cli/version.ts +2 -0
- package/src/cli/versions.ts +158 -0
- package/src/config/address.ts +102 -0
- package/src/config/circuit.d.ts +30 -0
- package/src/config/common.ts +65 -0
- package/src/config/communities.ts +479 -0
- package/src/config/define.ts +684 -0
- package/src/config/device.ts +164 -0
- package/src/config/firewall.ts +150 -0
- package/src/config/index.ts +22 -0
- package/src/{schema → config}/interfaces.ts +121 -85
- package/src/config/keys.ts +434 -0
- package/src/config/management.ts +61 -0
- package/src/config/merge.ts +335 -0
- package/src/config/models.ts +70 -0
- package/src/config/monitoring.ts +64 -0
- package/src/config/network.ts +180 -0
- package/src/config/presets.ts +149 -0
- package/src/config/routing.ts +401 -0
- package/src/config/services.ts +51 -0
- package/src/config/switching.ts +84 -0
- package/src/config/system.ts +103 -0
- package/src/{schema → config}/time-zones.ts +1 -1
- package/src/core/address.ts +1 -1
- package/src/core/cabling.ts +8 -43
- package/src/core/graph.ts +40 -0
- package/src/{integrations → core}/registries.ts +5 -3
- package/src/core/secrets-file.ts +539 -0
- package/src/core/secrets.ts +83 -64
- package/src/core/topology.ts +103 -146
- package/src/core/utils.ts +12 -1
- package/src/model.ts +83 -0
- package/src/platforms/derive.ts +64 -37
- package/src/platforms/finding.ts +9 -0
- package/src/platforms/fortios/firewall.ts +76 -64
- package/src/platforms/fortios/index.ts +189 -125
- package/src/platforms/fortios/names.ts +51 -18
- package/src/platforms/fortios/render.ts +69 -62
- package/src/platforms/fortios/routing.ts +89 -58
- package/src/platforms/fortios/vdoms.ts +47 -16
- package/src/platforms/junos/TRAPS.md +2 -2
- package/src/platforms/junos/bgp.ts +63 -42
- package/src/platforms/junos/index.ts +122 -89
- package/src/platforms/junos/render.ts +139 -104
- package/src/platforms/platform.ts +10 -8
- package/src/platforms/raisecom-ros/TRAPS.md +1 -1
- package/src/platforms/raisecom-ros/index.ts +89 -70
- package/src/platforms/raisecom-ros/render.ts +49 -45
- package/src/platforms/routeros/TRAPS.md +3 -3
- package/src/platforms/routeros/index.ts +121 -60
- package/src/platforms/routeros/render.ts +214 -195
- package/src/platforms/vrp/TRAPS.md +1 -1
- package/src/platforms/vrp/index.ts +74 -50
- package/src/platforms/vrp/render.ts +67 -56
- package/src/project/project.ts +725 -0
- package/src/studio/app/env.d.ts +9 -0
- package/src/studio/app/index.html +18 -0
- package/src/studio/app/src/App.vue +95 -0
- package/src/studio/app/src/components/AddressesView.vue +38 -0
- package/src/studio/app/src/components/CablesView.vue +29 -0
- package/src/studio/app/src/components/CompareView.vue +160 -0
- package/src/studio/app/src/components/DataTable.vue +49 -0
- package/src/studio/app/src/components/DeviceView.vue +237 -0
- package/src/studio/app/src/components/DevicesView.vue +32 -0
- package/src/studio/app/src/components/Faceplate.vue +75 -0
- package/src/studio/app/src/components/GraphView.vue +282 -0
- package/src/studio/app/src/components/LineDiff.vue +24 -0
- package/src/studio/app/src/components/ProblemsView.vue +42 -0
- package/src/studio/app/src/components/SearchView.vue +72 -0
- package/src/studio/app/src/components/SecretsView.vue +112 -0
- package/src/studio/app/src/components/SessionsView.vue +35 -0
- package/src/studio/app/src/components/Settings.vue +95 -0
- package/src/studio/app/src/components/ToolsView.vue +118 -0
- package/src/studio/app/src/components/VlansView.vue +50 -0
- package/src/studio/app/src/lib/csv.ts +19 -0
- package/src/studio/{public/diff.js → app/src/lib/diff.ts} +40 -35
- package/src/studio/app/src/lib/format.ts +38 -0
- package/src/studio/app/src/lib/net.ts +68 -0
- package/src/studio/app/src/lib/secrets-crypto.ts +35 -0
- package/src/studio/app/src/lib/store.ts +71 -0
- package/src/studio/app/src/lib/tools.ts +217 -0
- package/src/studio/app/src/main.ts +9 -0
- package/src/studio/{public → app/src}/style.css +14 -4
- package/src/studio/app/tsconfig.json +17 -0
- package/src/studio/app/vite.config.ts +16 -0
- package/src/studio/assets.generated.ts +3 -0
- package/src/studio/data.ts +96 -188
- package/src/studio/git.ts +27 -43
- package/src/studio/server.ts +196 -107
- package/src/studio/types.ts +141 -0
- package/src/transport/console.ts +3 -3
- package/src/transport/ssh.ts +1 -1
- package/dist/chunks/index-3b343xva.js +0 -177
- package/dist/chunks/index-6wb41q67.js +0 -62
- package/dist/chunks/index-n7w3tg5y.js +0 -149
- package/dist/chunks/index-yzw86rc8.js +0 -921
- package/dist/chunks/new-w3zys5y4.js +0 -172
- package/dist/chunks/server-cxr9ynxc.js +0 -259
- package/dist/cli/index.js +0 -12922
- package/dist/helpers/index.js +0 -881
- package/dist/index.js +0 -28
- package/dist/types/core/address-space.d.ts +0 -62
- package/dist/types/core/address.d.ts +0 -44
- package/dist/types/core/cabling.d.ts +0 -41
- package/dist/types/core/cross-checks.d.ts +0 -28
- package/dist/types/core/define.d.ts +0 -79
- package/dist/types/core/project-files.d.ts +0 -12
- package/dist/types/core/schema-docs.d.ts +0 -25
- package/dist/types/core/secrets.d.ts +0 -62
- package/dist/types/core/topology.d.ts +0 -96
- package/dist/types/core/utils.d.ts +0 -10
- package/dist/types/core/validator.d.ts +0 -23
- package/dist/types/helpers/bgp.d.ts +0 -195
- package/dist/types/helpers/cables.d.ts +0 -69
- package/dist/types/helpers/checks.d.ts +0 -36
- package/dist/types/helpers/exchange.d.ts +0 -55
- package/dist/types/helpers/filters.d.ts +0 -51
- package/dist/types/helpers/index.d.ts +0 -14
- package/dist/types/helpers/route-server.d.ts +0 -52
- package/dist/types/helpers/upstreams.d.ts +0 -192
- package/dist/types/index.d.ts +0 -10
- package/dist/types/integrations/librenms.d.ts +0 -60
- package/dist/types/integrations/netbox.d.ts +0 -89
- package/dist/types/integrations/peeringdb.d.ts +0 -24
- package/dist/types/integrations/prometheus.d.ts +0 -24
- package/dist/types/integrations/registries.d.ts +0 -8
- package/dist/types/platforms/bgp-wait.d.ts +0 -24
- package/dist/types/platforms/catalog.d.ts +0 -109
- package/dist/types/platforms/derive.d.ts +0 -17
- package/dist/types/platforms/fortios/firewall.d.ts +0 -47
- package/dist/types/platforms/fortios/index.d.ts +0 -140
- package/dist/types/platforms/fortios/models.d.ts +0 -14
- package/dist/types/platforms/fortios/names.d.ts +0 -52
- package/dist/types/platforms/fortios/plan.d.ts +0 -114
- package/dist/types/platforms/fortios/render.d.ts +0 -77
- package/dist/types/platforms/fortios/routing.d.ts +0 -56
- package/dist/types/platforms/fortios/tree.d.ts +0 -37
- package/dist/types/platforms/fortios/vdoms.d.ts +0 -50
- package/dist/types/platforms/index.d.ts +0 -13
- package/dist/types/platforms/junos/bgp.d.ts +0 -44
- package/dist/types/platforms/junos/index.d.ts +0 -114
- package/dist/types/platforms/junos/models.d.ts +0 -14
- package/dist/types/platforms/junos/render.d.ts +0 -154
- package/dist/types/platforms/line-diff.d.ts +0 -67
- package/dist/types/platforms/platform.d.ts +0 -135
- package/dist/types/platforms/raisecom-ros/index.d.ts +0 -71
- package/dist/types/platforms/raisecom-ros/models.d.ts +0 -14
- package/dist/types/platforms/raisecom-ros/render.d.ts +0 -41
- package/dist/types/platforms/routeros/export.d.ts +0 -59
- package/dist/types/platforms/routeros/index.d.ts +0 -116
- package/dist/types/platforms/routeros/models.d.ts +0 -18
- package/dist/types/platforms/routeros/plan.d.ts +0 -58
- package/dist/types/platforms/routeros/render.d.ts +0 -250
- package/dist/types/platforms/vrp/index.d.ts +0 -83
- package/dist/types/platforms/vrp/models.d.ts +0 -12
- package/dist/types/platforms/vrp/render.d.ts +0 -96
- package/dist/types/schema/common.d.ts +0 -30
- package/dist/types/schema/device.d.ts +0 -126
- package/dist/types/schema/firewall.d.ts +0 -131
- package/dist/types/schema/index.d.ts +0 -8
- package/dist/types/schema/interfaces.d.ts +0 -205
- package/dist/types/schema/policy.d.ts +0 -107
- package/dist/types/schema/routing.d.ts +0 -161
- package/dist/types/schema/system.d.ts +0 -198
- package/dist/types/schema/time-zones.d.ts +0 -2
- package/dist/types/transport/console.d.ts +0 -115
- package/dist/types/transport/path-check.d.ts +0 -32
- package/dist/types/transport/ssh.d.ts +0 -27
- package/src/cli/graph-format.ts +0 -91
- package/src/cli/new.ts +0 -234
- package/src/core/address-space.ts +0 -320
- package/src/core/cross-checks.ts +0 -369
- package/src/core/define.ts +0 -124
- package/src/core/project-files.ts +0 -35
- package/src/core/schema-docs.ts +0 -174
- package/src/core/validator.ts +0 -508
- package/src/helpers/bgp.ts +0 -473
- package/src/helpers/cables.ts +0 -74
- package/src/helpers/checks.ts +0 -201
- package/src/helpers/exchange.ts +0 -123
- package/src/helpers/filters.ts +0 -107
- package/src/helpers/index.ts +0 -25
- package/src/helpers/route-server.ts +0 -212
- package/src/helpers/upstreams.ts +0 -369
- package/src/index.ts +0 -13
- package/src/integrations/librenms.ts +0 -291
- package/src/integrations/netbox.ts +0 -620
- package/src/integrations/peeringdb.ts +0 -173
- package/src/integrations/prometheus.ts +0 -90
- package/src/schema/common.ts +0 -41
- package/src/schema/device.ts +0 -145
- package/src/schema/firewall.ts +0 -140
- package/src/schema/index.ts +0 -8
- package/src/schema/policy.ts +0 -115
- package/src/schema/routing.ts +0 -173
- package/src/schema/system.ts +0 -203
- package/src/studio/public/app.js +0 -186
- package/src/studio/public/compare.js +0 -250
- package/src/studio/public/dom.js +0 -138
- package/src/studio/public/evaluate.js +0 -687
- package/src/studio/public/export.js +0 -130
- package/src/studio/public/graph.js +0 -1541
- package/src/studio/public/index.html +0 -83
- package/src/studio/public/net.js +0 -134
- package/src/studio/public/tables.js +0 -1289
- package/src/studio/public/tools.js +0 -610
- package/templates/colocation/checks.ts +0 -53
- package/templates/colocation/circuit.config.ts +0 -9
- package/templates/colocation/edge-01.ts +0 -133
- package/templates/colocation/routing.ts +0 -13
- package/templates/colocation/tenancy.ts +0 -76
- package/templates/colocation/tenants/acme.ts +0 -19
- package/templates/colocation/tenants/index.ts +0 -6
- package/templates/colocation/tor-01.ts +0 -33
- package/templates/edge-router/checks.ts +0 -20
- package/templates/edge-router/circuit.config.ts +0 -8
- package/templates/edge-router/edge-01.ts +0 -110
- package/templates/edge-router/routing.ts +0 -13
- package/templates/project/AGENTS.md +0 -51
- package/templates/project/CLAUDE.md +0 -1
- package/templates/project/README.md +0 -16
- package/templates/project/gitignore +0 -5
- package/templates/project/tsconfig.json +0 -13
- package/templates/single-site/checks.ts +0 -26
- package/templates/single-site/circuit.config.ts +0 -8
- package/templates/single-site/router.ts +0 -86
- package/templates/single-site/site.ts +0 -18
- package/templates/single-site/switch.ts +0 -34
- /package/src/studio/{public → app/public}/favicon.svg +0 -0
- /package/src/studio/{public → app/public}/special-gothic-latin-ext.woff2 +0 -0
- /package/src/studio/{public → app/public}/special-gothic-latin.woff2 +0 -0
- /package/src/studio/{public → app/public}/special-gothic-license.txt +0 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// One device: its name, where it is, what it is, how Circuit logs in, and its groups. A part of a device, written in another file and given to it by a source.
|
|
2
|
+
|
|
3
|
+
import type { IP, Secret } from "./common";
|
|
4
|
+
import type { Firewall } from "./firewall";
|
|
5
|
+
import type { Interfaces, Port } from "./interfaces";
|
|
6
|
+
import type { Management } from "./management";
|
|
7
|
+
import type { Monitoring } from "./monitoring";
|
|
8
|
+
import type { AnyFacts, NetworkFacts } from "./network";
|
|
9
|
+
import type { Routing } from "./routing";
|
|
10
|
+
import type { Services } from "./services";
|
|
11
|
+
import type { Switching } from "./switching";
|
|
12
|
+
import type { System } from "./system";
|
|
13
|
+
|
|
14
|
+
/** A computer with SSH that holds the serial consoles of devices, such as a laptop beside the rack. It runs Python 3. */
|
|
15
|
+
export type Jump = {
|
|
16
|
+
/** Its address or name. */
|
|
17
|
+
host: string;
|
|
18
|
+
/** The user Circuit logs in as. It must be allowed to open the serial ports. */
|
|
19
|
+
user: string;
|
|
20
|
+
/** The user's password. */
|
|
21
|
+
password: Secret;
|
|
22
|
+
/** SSH port. 22 when absent. */
|
|
23
|
+
port?: number;
|
|
24
|
+
/** The jump host is reached through a Cloudflare Tunnel, so Circuit connects with `cloudflared access ssh`, which must be installed. */
|
|
25
|
+
cloudflared?: true;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** A serial console, on a jump host or on the computer Circuit runs on. */
|
|
29
|
+
export type Console = {
|
|
30
|
+
/** The jump host the console cable is plugged into. When absent, the cable is plugged into the computer Circuit runs on. */
|
|
31
|
+
jump?: Jump;
|
|
32
|
+
/** The serial port: on Linux or macOS a path under `/dev`, where a path under `/dev/serial/by-path/` stays the same when two adapters swap names; on Windows a COM port, such as `COM3`. */
|
|
33
|
+
port: string;
|
|
34
|
+
/** Line speed in bits per second, such as 9600 or 115200. */
|
|
35
|
+
baud: number;
|
|
36
|
+
/** The console asks only for a password, with no name first. Circuit then types no name; `connection.user` still picks the password. */
|
|
37
|
+
password_only?: true;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/** How Circuit itself logs in. `U` is the device's user names. */
|
|
41
|
+
export type Connection<U extends string> = {
|
|
42
|
+
/** Management address. Absent for a device reached only through its console. Its own value, apart from any interface's address. */
|
|
43
|
+
host?: IP;
|
|
44
|
+
/** One of `system.users`. Its password is the login. */
|
|
45
|
+
user: U;
|
|
46
|
+
/** SSH port. 22 when absent. */
|
|
47
|
+
port?: number;
|
|
48
|
+
/** The device's serial console, for `--console`: the way in before the device has a management address, or when its management network is down. */
|
|
49
|
+
console?: Console;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/** The names a device declares, by kind. A field that refers to a name takes only one of these. */
|
|
53
|
+
export type Names = {
|
|
54
|
+
/** Keys of `interfaces.ethernet`. */
|
|
55
|
+
port: string;
|
|
56
|
+
/** Keys of `interfaces.lag`. */
|
|
57
|
+
lag: string;
|
|
58
|
+
/** Keys of `interfaces.vlan_interface`. */
|
|
59
|
+
vlanInterface: string;
|
|
60
|
+
/** Keys of `interfaces.bridge`, `.loopback`, `.gre`, `.vxlan` and `.wireguard`. */
|
|
61
|
+
interface: string;
|
|
62
|
+
/** Keys of `switching.vlans`. */
|
|
63
|
+
vlan: string;
|
|
64
|
+
/** Keys of `switching.acls`. */
|
|
65
|
+
acl: string;
|
|
66
|
+
/** Keys of `routing.policies`. */
|
|
67
|
+
policy: string;
|
|
68
|
+
/** Keys of `routing.prefix_sets`. */
|
|
69
|
+
prefixSet: string;
|
|
70
|
+
/** Keys of `routing.bgp.neighbor_groups`. */
|
|
71
|
+
neighborGroup: string;
|
|
72
|
+
/** Keys of `routing.tables`. */
|
|
73
|
+
table: string;
|
|
74
|
+
/** Keys of `routing.vrfs`. */
|
|
75
|
+
vrf: string;
|
|
76
|
+
/** Keys of `firewall.address_sets`. */
|
|
77
|
+
addressSet: string;
|
|
78
|
+
/** Keys of `firewall.interface_sets`. */
|
|
79
|
+
interfaceSet: string;
|
|
80
|
+
/** Keys of `system.users`. */
|
|
81
|
+
user: string;
|
|
82
|
+
/** Keys of `system.certificates`. */
|
|
83
|
+
certificate: string;
|
|
84
|
+
/** Every port and interface: `port`, `lag`, `vlanInterface` and `interface` together. */
|
|
85
|
+
anyInterface: string;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The groups of a device, what a part may add to as well. `N` holds the names the device declares, `Ethernet` its ports. `Part` is true in a part, where BGP holds only what the part adds.
|
|
90
|
+
* `Net` is what the network writes: whether it turns on the check `untrusted_vlans`, and its `communities`.
|
|
91
|
+
*/
|
|
92
|
+
export type Groups<N extends Names, Ethernet, Part extends boolean = false, Net extends NetworkFacts = AnyFacts> = {
|
|
93
|
+
/** The box itself: banner, time, DNS it uses, users, certificates, logs kept on it, software, hardware. */
|
|
94
|
+
system?: System<N["user"], N["certificate"], NoInfer<N["anyInterface"]>>;
|
|
95
|
+
/** How people and tools log in: ssh, https, api, native protocol, console. */
|
|
96
|
+
management?: Management<NoInfer<N["anyInterface"]>, NoInfer<N["certificate"]>, NoInfer<N["addressSet"]>>;
|
|
97
|
+
/** What the box reports to collectors: snmp, syslog, flow export, optics. */
|
|
98
|
+
monitoring?: Monitoring<NoInfer<N["anyInterface"]>>;
|
|
99
|
+
/** Every port and interface, by kind: ethernet, lag, vlan_interface, bridge, loopback, gre, vxlan, wireguard. */
|
|
100
|
+
interfaces?: Interfaces<Ethernet, N["lag"], N["vlanInterface"], N["interface"], NoInfer<N["vlan"]>, NoInfer<N["vrf"]>>;
|
|
101
|
+
/** Layer 2 shared by ports: vlans, stp, lldp, acls. */
|
|
102
|
+
switching?: Switching<N["vlan"], N["acl"], NoInfer<N["anyInterface"]>, Net["untrusted"]>;
|
|
103
|
+
/** What the box serves to hosts: dhcp server, dhcp relay, dns server, ntp server. */
|
|
104
|
+
services?: Services<NoInfer<N["anyInterface"]>>;
|
|
105
|
+
/** Where packets go: tables, vrfs, policy routing, static routes, bgp, ospf, bfd, rpki, policies, prefix sets. */
|
|
106
|
+
routing?: Routing<N["policy"], N["prefixSet"], N["neighborGroup"], N["table"], N["vrf"], NoInfer<N["anyInterface"]>, Part, Net>;
|
|
107
|
+
/** Which packets pass and how they are rewritten: address sets, interface sets, filter, nat, untracked, conntrack helpers. */
|
|
108
|
+
firewall?: Firewall<N["addressSet"], NoInfer<N["anyInterface"]>, N["interfaceSet"]>;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Everything one device runs. What is not written here is removed from the device or returned to its default.
|
|
113
|
+
*
|
|
114
|
+
* `N` holds the names it declares, so a reference to a name it does not declare is an error. `Ethernet` is its ports, checked against the model.
|
|
115
|
+
* `Site` is the network's sites. `Net` is what the network writes: whether it turns on the check `untrusted_vlans`, and its `communities`.
|
|
116
|
+
*/
|
|
117
|
+
export type Device<
|
|
118
|
+
Platform extends string,
|
|
119
|
+
Model extends string,
|
|
120
|
+
Site extends string,
|
|
121
|
+
N extends Names,
|
|
122
|
+
Ethernet,
|
|
123
|
+
Name extends string = string,
|
|
124
|
+
Net extends NetworkFacts = AnyFacts,
|
|
125
|
+
> = {
|
|
126
|
+
/** Its hostname: its name in the network, and the key under which each source gives it a part. */
|
|
127
|
+
name: Name;
|
|
128
|
+
/** The site it is at, one of the network's `sites`. The NetBox site and LibreNMS group of that name. */
|
|
129
|
+
site: Site;
|
|
130
|
+
/** Its role in NetBox, such as `Core switch`. Circuit makes the role when NetBox has none of that name. */
|
|
131
|
+
role?: string;
|
|
132
|
+
/** Operating system. It decides which adapter renders and applies the device. */
|
|
133
|
+
platform: Platform;
|
|
134
|
+
/** Hardware model, one of the platform's. It decides which port names exist. */
|
|
135
|
+
model: Model;
|
|
136
|
+
/** How Circuit itself logs in. */
|
|
137
|
+
connection: Connection<NoInfer<N["user"]>>;
|
|
138
|
+
} & Groups<N, Ethernet, false, Net>;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* A part of a device, which a source gives it under its hostname: what an upstream, a tenant or a monitoring host adds to it. The names it refers to must be declared by the device or by one of its parts.
|
|
142
|
+
*/
|
|
143
|
+
export type Part<N extends Names, Ethernet, Net extends NetworkFacts = AnyFacts> = {
|
|
144
|
+
/** How Circuit itself logs in. In a part, only what the part adds, such as the console. */
|
|
145
|
+
connection?: Partial<Connection<NoInfer<N["user"]>>>;
|
|
146
|
+
} & Groups<N, Ethernet, true, Net>;
|
|
147
|
+
|
|
148
|
+
/** Any name: what a part, or a device seen from the network, holds. */
|
|
149
|
+
type AnyNames = { [K in keyof Names]: string };
|
|
150
|
+
|
|
151
|
+
/** A port as a part writes it, before the device it goes to checks its names. */
|
|
152
|
+
export type AnyPort = Port<string, string, string, string>;
|
|
153
|
+
|
|
154
|
+
/** Any device, as the network holds it. */
|
|
155
|
+
export type AnyDevice = Device<string, string, string, AnyNames, Record<string, AnyPort>>;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* A part of one or more devices, written apart from them and given to each device that carries it, under its hostname in a source: an upstream's VLAN, sessions and policies on the router, a tenant's ports on a switch, what every device sends to the monitoring hosts.
|
|
159
|
+
*
|
|
160
|
+
* It has a device's shape and docs. What only a whole device has (its site, platform, model) is not here, and what a part writes alone stays optional: a part can add BGP neighbors without the AS, or a console without the user.
|
|
161
|
+
*
|
|
162
|
+
* Names a part refers to (a VLAN, an interface, a policy) are checked once the part reaches a device: there they must be declared.
|
|
163
|
+
*/
|
|
164
|
+
export type DevicePart = Part<AnyNames, Record<string, AnyPort>>;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// Which packets pass and how they are rewritten: `firewall.address_sets`, `.interface_sets`, `.filter`, `.nat`, `.untracked`, `.conntrack_helpers`.
|
|
2
|
+
|
|
3
|
+
import type { Family, HostAddress, IP, Named, OneOrMore, Ordered, Prefix } from "./common";
|
|
4
|
+
|
|
5
|
+
/** An IP protocol. `icmp` means ICMPv6 in an IPv6 rule. */
|
|
6
|
+
export type Protocol = "tcp" | "udp" | "icmp" | "gre" | "esp" | "ah" | "ospf" | "vrrp";
|
|
7
|
+
|
|
8
|
+
/** The state connection tracking gives a packet. */
|
|
9
|
+
export type ConnectionState = "new" | "established" | "related" | "untracked" | "invalid";
|
|
10
|
+
|
|
11
|
+
/** Ports from `min` to `max`, both included. */
|
|
12
|
+
export type PortRange = {
|
|
13
|
+
/** The first port, 0 to 65535. */
|
|
14
|
+
min: number;
|
|
15
|
+
/** The last port, 0 to 65535, not below `min`. */
|
|
16
|
+
max: number;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/** A port, a range of ports, or any of several. */
|
|
20
|
+
export type Ports = number | PortRange | readonly (number | PortRange)[];
|
|
21
|
+
|
|
22
|
+
/** A TCP header flag. */
|
|
23
|
+
export type TcpFlag = "fin" | "syn" | "rst" | "psh" | "ack" | "urg";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Conditions on a packet. All must be true. A rule with addresses of one family applies to that family only. `I` is the device's
|
|
27
|
+
* ports and interfaces, `AS` its address sets, `IS` its interface sets.
|
|
28
|
+
*
|
|
29
|
+
* `src`, `dst`, `in_interface` and `out_interface` each take a list, and an interface set stands for its interfaces. Where the
|
|
30
|
+
* platform has no list, Circuit writes one rule per combination: the interface outermost (`in` before `out`), then `src`, then `dst`.
|
|
31
|
+
*/
|
|
32
|
+
export type FilterMatch<I extends string, AS extends string, IS extends string> = {
|
|
33
|
+
/** Only packets of this family. */
|
|
34
|
+
family?: Family;
|
|
35
|
+
/** IP protocol. */
|
|
36
|
+
protocol?: Protocol;
|
|
37
|
+
/** Source address or prefix, or any of several. */
|
|
38
|
+
src?: OneOrMore<Prefix>;
|
|
39
|
+
/** Destination address or prefix, or any of several. */
|
|
40
|
+
dst?: OneOrMore<Prefix>;
|
|
41
|
+
/** One of `firewall.address_sets`: the source is in it. */
|
|
42
|
+
src_address_set?: AS;
|
|
43
|
+
/** One of `firewall.address_sets`: the destination is in it. */
|
|
44
|
+
dst_address_set?: AS;
|
|
45
|
+
/** Source port, or any of several. TCP and UDP only. */
|
|
46
|
+
src_port?: Ports;
|
|
47
|
+
/** Destination port, or any of several. TCP and UDP only. */
|
|
48
|
+
dst_port?: Ports;
|
|
49
|
+
/** One of the device's ports or interfaces, or any of several: the packet arrived on it. */
|
|
50
|
+
in_interface?: OneOrMore<I>;
|
|
51
|
+
/** One of the device's ports or interfaces, or any of several: the packet leaves through it. */
|
|
52
|
+
out_interface?: OneOrMore<I>;
|
|
53
|
+
/** One of `firewall.interface_sets`: the packet arrived on one of its interfaces. Not with `in_interface`. */
|
|
54
|
+
in_interface_set?: IS;
|
|
55
|
+
/** One of `firewall.interface_sets`: the packet leaves through one of its interfaces. Not with `out_interface`. */
|
|
56
|
+
out_interface_set?: IS;
|
|
57
|
+
/** Connection tracking state, any of these. */
|
|
58
|
+
connection_state?: readonly ConnectionState[];
|
|
59
|
+
/** TCP flags that must be set, and flags that must not be. */
|
|
60
|
+
tcp_flags?: {
|
|
61
|
+
/** Flags that must be set. */
|
|
62
|
+
set?: readonly TcpFlag[];
|
|
63
|
+
/** Flags that must not be set. */
|
|
64
|
+
unset?: readonly TcpFlag[];
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* One firewall rule, the condition first: `{ if: { protocol: "icmp" }, then: "accept" }`. No `if`: every packet.
|
|
70
|
+
*/
|
|
71
|
+
export type FilterRule<I extends string, AS extends string, IS extends string> = {
|
|
72
|
+
/** Shown beside the rule on the device. */
|
|
73
|
+
description?: string;
|
|
74
|
+
/** Which packets the rule applies to. Every packet when absent. */
|
|
75
|
+
if?: FilterMatch<I, AS, IS>;
|
|
76
|
+
/** What happens to a matching packet. `reject` answers the sender, `drop` does not. */
|
|
77
|
+
then: "accept" | "drop" | "reject";
|
|
78
|
+
/** Send the rest of an accepted flow through the fast path, skipping the remaining rules. */
|
|
79
|
+
fast_path?: true;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/** Rules in order, the first match wins, then `default_action`. */
|
|
83
|
+
export type Chain<I extends string, AS extends string, IS extends string> = {
|
|
84
|
+
/** What happens to a packet no rule matched. Accept when absent. */
|
|
85
|
+
default_action?: "accept" | "drop";
|
|
86
|
+
/** Rules in order: the first runs first. Written whole in one place; `merge` places rules from other files in it. */
|
|
87
|
+
rules?: Ordered<FilterRule<I, AS, IS>>;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* One address translation, the condition first: `{ if: { src: "10.0.0.0/24", out_interface_set: "uplinks" }, then: "snat", to_address: "192.0.2.1" }`.
|
|
92
|
+
* No `if`: every packet.
|
|
93
|
+
*/
|
|
94
|
+
export type NatRule<I extends string, AS extends string, IS extends string> = {
|
|
95
|
+
/** Shown beside the rule on the device. */
|
|
96
|
+
description?: string;
|
|
97
|
+
/** Which packets are translated. Every packet when absent. */
|
|
98
|
+
if?: FilterMatch<I, AS, IS>;
|
|
99
|
+
} & (
|
|
100
|
+
| {
|
|
101
|
+
/** `masquerade` uses the address of the outgoing interface. */
|
|
102
|
+
then: "masquerade";
|
|
103
|
+
}
|
|
104
|
+
| {
|
|
105
|
+
/** `snat` rewrites the source, `dnat` the destination. */
|
|
106
|
+
then: "snat" | "dnat";
|
|
107
|
+
/** The address to rewrite to, alone or with its length. */
|
|
108
|
+
to_address: HostAddress;
|
|
109
|
+
/** The port to rewrite to. Unchanged when absent. */
|
|
110
|
+
to_port?: number;
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
/** Connection-tracking helpers that rewrite application payloads. None run unless listed. */
|
|
115
|
+
export type Helper = "ftp" | "tftp" | "sip" | "h323" | "pptp" | "rtsp" | "irc";
|
|
116
|
+
|
|
117
|
+
/** What the device filters and translates. `AS` is the device's address set names, `I` its ports and interfaces, `IS` its interface set names. */
|
|
118
|
+
export type Firewall<AS extends string, I extends string, IS extends string> = {
|
|
119
|
+
/** Named groups of addresses and prefixes, of either family, that rules match on with `src_address_set` and `dst_address_set`. */
|
|
120
|
+
address_sets?: Named<AS, readonly (IP | Prefix)[]>;
|
|
121
|
+
/**
|
|
122
|
+
* Named groups of the device's ports and interfaces, that rules match on with `in_interface_set` and `out_interface_set`, like a
|
|
123
|
+
* RouterOS interface list or a FortiOS zone. A list: each part adds its own, such as each upstream its interface to `uplinks`.
|
|
124
|
+
*/
|
|
125
|
+
interface_sets?: Named<IS, readonly I[]>;
|
|
126
|
+
/** Traffic to the device (`input`), through it (`forward`), and from it (`output`). */
|
|
127
|
+
filter?: {
|
|
128
|
+
/** Traffic to the device itself. */
|
|
129
|
+
input?: Chain<I, NoInfer<AS>, NoInfer<IS>>;
|
|
130
|
+
/** Traffic the device routes. */
|
|
131
|
+
forward?: Chain<I, NoInfer<AS>, NoInfer<IS>>;
|
|
132
|
+
/** Traffic the device itself sends. */
|
|
133
|
+
output?: Chain<I, NoInfer<AS>, NoInfer<IS>>;
|
|
134
|
+
};
|
|
135
|
+
/** Source translation on the way out, destination translation on the way in. Each is rules in order: the first runs first. */
|
|
136
|
+
nat?: {
|
|
137
|
+
/** Rewrites the source of traffic on the way out. */
|
|
138
|
+
source?: Ordered<NatRule<I, NoInfer<AS>, NoInfer<IS>>>;
|
|
139
|
+
/** Rewrites the destination of traffic on the way in. */
|
|
140
|
+
destination?: Ordered<NatRule<I, NoInfer<AS>, NoInfer<IS>>>;
|
|
141
|
+
};
|
|
142
|
+
/** Connection-tracking helpers that run. None when absent. */
|
|
143
|
+
conntrack_helpers?: readonly Helper[];
|
|
144
|
+
/**
|
|
145
|
+
* Traffic to and from these prefixes passes without connection tracking. A flood toward them cannot fill the connection table, and rules see its packets in the state `untracked`. Everything is tracked when absent.
|
|
146
|
+
*
|
|
147
|
+
* Each address NAT uses inside one of these prefixes (a source translation's `to_address`, a destination translation's `to_address` or matched `dst`) stays tracked: Circuit writes two accept rules for it, one for traffic to it and one for traffic from it, before the untracked rules. Without them, a reply to that address would skip tracking and never be translated back.
|
|
148
|
+
*/
|
|
149
|
+
untracked?: readonly Prefix[];
|
|
150
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Circuit v1 for a TypeScript project. Its values (functions, `presets` and `address`) are globals: circuit.d.ts declares them for the editor, and
|
|
2
|
+
// Circuit puts them on `globalThis` before it reads the project. A project never imports them. `lib/` may import the types:
|
|
3
|
+
// `import type { Prefix } from "circuit"`.
|
|
4
|
+
|
|
5
|
+
export { bgpNeighbors, circuit, literal, merge, part, secret, secretFile } from "./define";
|
|
6
|
+
export { presets } from "./presets";
|
|
7
|
+
export { address } from "./address";
|
|
8
|
+
export type * from "./address";
|
|
9
|
+
export type * from "./common";
|
|
10
|
+
export type * from "./communities";
|
|
11
|
+
export type * from "./device";
|
|
12
|
+
export type * from "./firewall";
|
|
13
|
+
export type * from "./interfaces";
|
|
14
|
+
export type * from "./management";
|
|
15
|
+
export type * from "./models";
|
|
16
|
+
export type * from "./monitoring";
|
|
17
|
+
export type * from "./network";
|
|
18
|
+
export type * from "./routing";
|
|
19
|
+
export type * from "./services";
|
|
20
|
+
export type * from "./switching";
|
|
21
|
+
export type * from "./system";
|
|
22
|
+
export type * from "./time-zones";
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
// Every port and interface, by kind: `interfaces.ethernet`, `.lag`, `.vlan_interface`, `.bridge`, `.loopback`, `.gre`, `.vxlan`, `.wireguard`.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
export type Vlan = {
|
|
5
|
-
/** The VLAN's number on the wire, 1 to 4094. */
|
|
6
|
-
id: number;
|
|
7
|
-
/** What the VLAN is for. */
|
|
8
|
-
description?: string;
|
|
9
|
-
};
|
|
3
|
+
import type { HostAddress, IP, InterfaceAddress, MacAddress, Named, Prefix, Secret } from "./common";
|
|
10
4
|
|
|
11
5
|
/** A storm-control threshold: packets per second, or percent of the link's speed. */
|
|
12
|
-
export type Threshold =
|
|
6
|
+
export type Threshold =
|
|
7
|
+
| {
|
|
8
|
+
/** Packets per second. */
|
|
9
|
+
pps: number;
|
|
10
|
+
}
|
|
11
|
+
| {
|
|
12
|
+
/** Percent of the link's speed, above 0 and up to 100. */
|
|
13
|
+
percent: number;
|
|
14
|
+
};
|
|
13
15
|
|
|
14
16
|
/** A kind of frame, by the ethertype in its header: `ipv4` is 0x0800, `ipv6` 0x86DD, `arp` 0x0806. */
|
|
15
17
|
export type Ethertype = "ipv4" | "ipv6" | "arp";
|
|
16
18
|
|
|
17
|
-
/** A virtual router address shared with other devices on the same segment, RFC
|
|
19
|
+
/** A virtual router address shared with other devices on the same segment, RFC 9568 (VRRPv3). */
|
|
18
20
|
export type Vrrp = {
|
|
19
21
|
/** Virtual router number, 1 to 255. The same on every device sharing the address. */
|
|
20
22
|
id: number;
|
|
@@ -28,22 +30,6 @@ export type Vrrp = {
|
|
|
28
30
|
interval?: number;
|
|
29
31
|
};
|
|
30
32
|
|
|
31
|
-
/** Layer 3 settings shared by every interface that can have an address. */
|
|
32
|
-
export type Routed<F extends string> = {
|
|
33
|
-
/** Addresses with their length. Use `{ address, peer }` for a point-to-point address whose far end is outside its own prefix. */
|
|
34
|
-
addresses?: readonly (InterfaceAddress | { address: InterfaceAddress; peer: IP })[];
|
|
35
|
-
/** Send IPv6 router advertisements on this interface. Off when absent. */
|
|
36
|
-
ipv6_ra?: boolean;
|
|
37
|
-
/** Overrides the device's `hardware_offload` for traffic routed through this interface. Software forwarding is what makes the firewall apply. */
|
|
38
|
-
hardware_offload?: boolean;
|
|
39
|
-
/** Virtual router addresses on this interface. */
|
|
40
|
-
vrrp?: readonly Vrrp[];
|
|
41
|
-
/** The VRF this interface routes in. The default table when absent. */
|
|
42
|
-
vrf?: F;
|
|
43
|
-
/** This interface is the network's presence at an internet exchange. Devices ignore it; `circuit peeringdb` publishes it. */
|
|
44
|
-
exchange?: Exchange;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
33
|
/** Presence at an internet exchange, as a registry lists it. The addresses are the interface's own. */
|
|
48
34
|
export type Exchange = {
|
|
49
35
|
/** The exchange's name, for output. */
|
|
@@ -54,6 +40,32 @@ export type Exchange = {
|
|
|
54
40
|
peeringdb_ixlan?: number;
|
|
55
41
|
};
|
|
56
42
|
|
|
43
|
+
/** An address with its length, or `{ address, peer_address }` for a point-to-point address whose far end is outside its own prefix. */
|
|
44
|
+
export type Address =
|
|
45
|
+
| InterfaceAddress
|
|
46
|
+
| {
|
|
47
|
+
/** Our address, with its length. */
|
|
48
|
+
address: InterfaceAddress;
|
|
49
|
+
/** The far end's address. */
|
|
50
|
+
peer_address: IP;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/** Layer 3 settings shared by every interface that can have an address. `Vrf` is the device's VRF names. */
|
|
54
|
+
export type Routed<Vrf extends string> = {
|
|
55
|
+
/** Addresses with their length. Use `{ address, peer_address }` for a point-to-point address whose far end is outside its own prefix. */
|
|
56
|
+
addresses?: readonly Address[];
|
|
57
|
+
/** Send IPv6 router advertisements on this interface. Off when absent. */
|
|
58
|
+
ipv6_ra?: boolean;
|
|
59
|
+
/** Overrides `system.hardware_offload` for traffic routed through this interface. Software forwarding is what makes the firewall apply. */
|
|
60
|
+
hardware_offload?: boolean;
|
|
61
|
+
/** Virtual router addresses on this interface. */
|
|
62
|
+
vrrp?: readonly Vrrp[];
|
|
63
|
+
/** One of `routing.vrfs`: the VRF this interface routes in. The main table when absent. */
|
|
64
|
+
vrf?: Vrf;
|
|
65
|
+
/** This interface is the network's presence at an internet exchange. Devices ignore it; `circuit peeringdb` publishes it. */
|
|
66
|
+
exchange?: Exchange;
|
|
67
|
+
};
|
|
68
|
+
|
|
57
69
|
/** Spanning tree settings for one port. */
|
|
58
70
|
export type PortStp = {
|
|
59
71
|
/** The port faces a host, never a switch, so it forwards at once. */
|
|
@@ -64,33 +76,43 @@ export type PortStp = {
|
|
|
64
76
|
priority?: number;
|
|
65
77
|
};
|
|
66
78
|
|
|
67
|
-
/**
|
|
68
|
-
export type
|
|
69
|
-
/**
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
/** Drop flooded traffic above these thresholds. */
|
|
80
|
+
export type StormControl = {
|
|
81
|
+
/** Frames to every host. */
|
|
82
|
+
broadcast?: Threshold;
|
|
83
|
+
/** Frames to a group. */
|
|
84
|
+
multicast?: Threshold;
|
|
85
|
+
/** Frames to a MAC address the switch has not learned. */
|
|
86
|
+
unknown_unicast?: Threshold;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/** Layer 2 membership. A port or LAG with none of these is routed. `Vlan` is the device's VLAN names. */
|
|
90
|
+
export type Switched<Vlan extends string> = {
|
|
91
|
+
/** One of `switching.vlans`: the one VLAN this port or LAG is in, untagged. */
|
|
92
|
+
access_vlan?: Vlan;
|
|
93
|
+
/** Some of `switching.vlans`: the VLANs this port or LAG carries, tagged. */
|
|
94
|
+
trunk_vlans?: readonly Vlan[];
|
|
95
|
+
/** One of `switching.vlans`: untagged frames on a trunk are in this VLAN. Only with `trunk_vlans`. */
|
|
96
|
+
native_vlan?: Vlan;
|
|
97
|
+
/** Overrides `switching.stp` for this port. `false` stops it sending or acting on BPDUs. */
|
|
76
98
|
stp?: boolean | PortStp;
|
|
77
99
|
/** Drop flooded traffic above these thresholds. */
|
|
78
|
-
storm_control?:
|
|
79
|
-
broadcast?: Threshold;
|
|
80
|
-
multicast?: Threshold;
|
|
81
|
-
unknown_unicast?: Threshold;
|
|
82
|
-
};
|
|
100
|
+
storm_control?: StormControl;
|
|
83
101
|
/** The most MAC addresses this port or LAG learns, 1 or more. Frames from any other source address are dropped. An exchange sets 1 on a member port, so each member sends from one router only. No limit when absent. */
|
|
84
102
|
mac_limit?: number;
|
|
85
103
|
/** The only kinds of frame this port or LAG takes in; any other kind is dropped. An exchange takes `ipv4`, `ipv6` and `arp` on a member port. Every kind when absent. */
|
|
86
104
|
ethertypes?: readonly Ethertype[];
|
|
87
105
|
};
|
|
88
106
|
|
|
89
|
-
/**
|
|
107
|
+
/**
|
|
108
|
+
* The other end of a cable: another of our devices and its port. Both ends must agree on how they are switched, and the far end must
|
|
109
|
+
* link back. The port's own `description` names that end, `<far device> <far port as printed there>`, such as `fw-01 port6`:
|
|
110
|
+
* Circuit warns when it doesn't, and never writes it.
|
|
111
|
+
*/
|
|
90
112
|
export type Link = {
|
|
91
|
-
/**
|
|
113
|
+
/** The device at the other end, by its key in `devices`. */
|
|
92
114
|
device: string;
|
|
93
|
-
/** The port on that device
|
|
115
|
+
/** The port on that device, such as `10g-2`. */
|
|
94
116
|
port: string;
|
|
95
117
|
/**
|
|
96
118
|
* What is between the two ends when the cable is not direct, such as a carrier's local loop or L2 transport: `"Carrier A local loop"`. LLDP then sees the carrier's switches, not the far end, so `validate` does not compare LLDP on this port. Both ends name the same carrier.
|
|
@@ -98,27 +120,27 @@ export type Link = {
|
|
|
98
120
|
through?: string;
|
|
99
121
|
};
|
|
100
122
|
|
|
101
|
-
/** A physical port
|
|
102
|
-
export type Port<
|
|
103
|
-
Switched<
|
|
104
|
-
/** What is plugged in. */
|
|
123
|
+
/** A physical port, by its key `<speed>-<position>`, such as `10g-4`. Ports a device does not declare are shut down. */
|
|
124
|
+
export type Port<Vlan extends string, Acl extends string, Lag extends string, Vrf extends string> = Routed<Vrf> &
|
|
125
|
+
Switched<Vlan> & {
|
|
126
|
+
/** What is plugged in. On a port with a `link`, the far end: `<far device> <far port as printed there>`. */
|
|
105
127
|
description?: string;
|
|
106
128
|
/** Largest IP packet, in bytes. 1500 when absent. */
|
|
107
129
|
mtu?: number;
|
|
108
130
|
/** Fixed speed, for an optic slower than the cage. Negotiated when absent. */
|
|
109
131
|
speed?: "100m" | "1g" | "10g" | "25g" | "40g" | "50g" | "100g";
|
|
110
|
-
/** Overrides
|
|
132
|
+
/** Overrides `switching.lldp` for this port. */
|
|
111
133
|
lldp?: boolean;
|
|
112
|
-
/**
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
|
|
116
|
-
/** Another of our devices at the other end of the cable. */
|
|
134
|
+
/** One of `switching.acls`: the hardware ACL applied to traffic arriving on this port. */
|
|
135
|
+
ingress_acl?: Acl;
|
|
136
|
+
/** One of `interfaces.lag`: the LAG this port is in. Every other setting goes on the LAG. */
|
|
137
|
+
in_lag?: Lag;
|
|
138
|
+
/** Another of our devices at the other end of the cable. Circuit checks that it links back, and warns when `description` doesn't name it. */
|
|
117
139
|
link?: Link;
|
|
118
140
|
};
|
|
119
141
|
|
|
120
142
|
/** Settings every interface that is not a physical port shares. */
|
|
121
|
-
type Base<
|
|
143
|
+
export type Base<Vrf extends string> = Routed<Vrf> & {
|
|
122
144
|
/** What the interface is for. */
|
|
123
145
|
description?: string;
|
|
124
146
|
/** Largest IP packet, in bytes. */
|
|
@@ -126,10 +148,9 @@ type Base<F extends string> = Routed<F> & {
|
|
|
126
148
|
};
|
|
127
149
|
|
|
128
150
|
/** A layer 3 interface on a VLAN. */
|
|
129
|
-
export type VlanInterface<
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
vlan: V;
|
|
151
|
+
export type VlanInterface<Vlan extends string, Vrf extends string> = Base<Vrf> & {
|
|
152
|
+
/** One of `switching.vlans`: the VLAN it is on. */
|
|
153
|
+
vlan: Vlan;
|
|
133
154
|
/**
|
|
134
155
|
* A MAC address of its own, instead of the one it shares with the device's other VLAN interfaces. A gateway in front of a transparent firewall needs one: frames to it come back on another VLAN, where the bridge would otherwise take a shared MAC for its own and keep them.
|
|
135
156
|
*/
|
|
@@ -137,12 +158,11 @@ export type VlanInterface<V extends string, F extends string> = Base<F> & {
|
|
|
137
158
|
};
|
|
138
159
|
|
|
139
160
|
/** An interface that is always up and is on no link, for addresses that must not depend on one. */
|
|
140
|
-
export type Loopback<
|
|
161
|
+
export type Loopback<Vrf extends string> = Base<Vrf>;
|
|
141
162
|
|
|
142
|
-
/** A link aggregation. Each member port points to it with `
|
|
143
|
-
export type Lag<
|
|
144
|
-
Switched<
|
|
145
|
-
type: "lag";
|
|
163
|
+
/** A link aggregation. Each member port points to it with `in_lag`. */
|
|
164
|
+
export type Lag<Vlan extends string, Vrf extends string> = Base<Vrf> &
|
|
165
|
+
Switched<Vlan> & {
|
|
146
166
|
/** LACP negotiates membership with the far end; `static` joins the ports without asking. LACP when absent. */
|
|
147
167
|
mode?: "lacp" | "static";
|
|
148
168
|
/** Number, on platforms where a LAG has a number instead of a name. Its position among the device's LAGs when absent. */
|
|
@@ -150,23 +170,21 @@ export type Lag<V extends string, F extends string> = Base<F> &
|
|
|
150
170
|
};
|
|
151
171
|
|
|
152
172
|
/** A GRE tunnel. */
|
|
153
|
-
export type Gre<
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
local: IP;
|
|
173
|
+
export type Gre<Vrf extends string> = Base<Vrf> & {
|
|
174
|
+
/** Our tunnel endpoint, alone or with its length. */
|
|
175
|
+
local_address: HostAddress;
|
|
157
176
|
/** The far tunnel endpoint. */
|
|
158
|
-
|
|
177
|
+
remote_address: IP;
|
|
159
178
|
};
|
|
160
179
|
|
|
161
180
|
/** A point-to-point VXLAN tunnel. */
|
|
162
|
-
export type Vxlan<
|
|
163
|
-
|
|
164
|
-
/** Segment identifier, the same on both ends. */
|
|
181
|
+
export type Vxlan<Vrf extends string> = Base<Vrf> & {
|
|
182
|
+
/** Segment identifier, the same on both ends, 1 to 16777215. */
|
|
165
183
|
vni: number;
|
|
166
|
-
/** Our tunnel endpoint. */
|
|
167
|
-
|
|
184
|
+
/** Our tunnel endpoint, alone or with its length. */
|
|
185
|
+
local_address: HostAddress;
|
|
168
186
|
/** The far tunnel endpoint. */
|
|
169
|
-
|
|
187
|
+
remote_address: IP;
|
|
170
188
|
/** UDP port. 4789 when absent. */
|
|
171
189
|
port?: number;
|
|
172
190
|
/** Fixed MAC address, so a rebuild keeps the one the far side learned. */
|
|
@@ -193,12 +211,11 @@ export type WireGuardPeer = {
|
|
|
193
211
|
};
|
|
194
212
|
|
|
195
213
|
/** A WireGuard interface. */
|
|
196
|
-
export type WireGuard<
|
|
197
|
-
type: "wireguard";
|
|
214
|
+
export type WireGuard<Vrf extends string> = Base<Vrf> & {
|
|
198
215
|
/** UDP port peers connect to. */
|
|
199
216
|
listen_port: number;
|
|
200
|
-
/** The address clients connect to, for generated client configs. */
|
|
201
|
-
endpoint?:
|
|
217
|
+
/** The address clients connect to, for generated client configs, alone or with its length. */
|
|
218
|
+
endpoint?: HostAddress;
|
|
202
219
|
/** This interface's private key. Its public key is derived from it. */
|
|
203
220
|
private_key: Secret;
|
|
204
221
|
/** Who may connect. */
|
|
@@ -208,12 +225,31 @@ export type WireGuard<F extends string> = Base<F> & {
|
|
|
208
225
|
/**
|
|
209
226
|
* A layer 2 bridge between VLAN interfaces, each keeping its own VLAN: a frame that comes in on one member leaves another with that member's tag. A firewall filters what crosses it, by the rules of its forward chain between the members, without routing it.
|
|
210
227
|
*/
|
|
211
|
-
export type Bridge<
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
members: readonly string[];
|
|
228
|
+
export type Bridge<VlanInterface extends string, Vrf extends string> = Base<Vrf> & {
|
|
229
|
+
/** Some of `interfaces.vlan_interface`: the VLAN interfaces it joins. Each has no address of its own. */
|
|
230
|
+
member_interfaces: readonly VlanInterface[];
|
|
215
231
|
};
|
|
216
232
|
|
|
217
|
-
/**
|
|
218
|
-
|
|
219
|
-
|
|
233
|
+
/**
|
|
234
|
+
* Every port and interface, by kind, each keyed by its name. A port's key is `<speed>-<position>` from the model.
|
|
235
|
+
*
|
|
236
|
+
* The type parameters are the names the device declares: `Ethernet` the ports, `L` LAGs, `VI` VLAN interfaces, `T` the other interfaces, `V` VLANs, `A` ACLs, `F` VRFs.
|
|
237
|
+
*/
|
|
238
|
+
export type Interfaces<Ethernet, L extends string, VI extends string, T extends string, V extends string, F extends string> = {
|
|
239
|
+
/** Physical ports, keyed by `<speed>-<position>` from the model, such as `10g-4`. Ports not listed are shut down. */
|
|
240
|
+
ethernet?: Ethernet;
|
|
241
|
+
/** Link aggregations, keyed by name. Each member port names one with `in_lag`. */
|
|
242
|
+
lag?: Named<L, Lag<V, F>>;
|
|
243
|
+
/** Layer 3 interfaces on a VLAN, keyed by name. Each names its VLAN in `vlan`. */
|
|
244
|
+
vlan_interface?: Named<VI, VlanInterface<V, F>>;
|
|
245
|
+
/** Layer 2 bridges between VLAN interfaces, keyed by name. */
|
|
246
|
+
bridge?: Named<T, Bridge<NoInfer<VI>, F>>;
|
|
247
|
+
/** Interfaces on no link, keyed by name. */
|
|
248
|
+
loopback?: Named<T, Loopback<F>>;
|
|
249
|
+
/** GRE tunnels, keyed by name. */
|
|
250
|
+
gre?: Named<T, Gre<F>>;
|
|
251
|
+
/** Point-to-point VXLAN tunnels, keyed by name. */
|
|
252
|
+
vxlan?: Named<T, Vxlan<F>>;
|
|
253
|
+
/** WireGuard interfaces, keyed by name. */
|
|
254
|
+
wireguard?: Named<T, WireGuard<F>>;
|
|
255
|
+
};
|