@takodotid/circuit 0.30.0 → 0.31.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.
@@ -122,6 +122,7 @@ var vlansOf = (port) => [port.access_vlan, ...port.trunk_vlans ?? []].filter((vl
122
122
  var trustBoundary = (boundary) => (devices) => {
123
123
  const untrusted = new Set(boundary.untrusted);
124
124
  const routers = new Set(boundary.routers);
125
+ const extended = (a, b) => (boundary.extended ?? []).some(([x, y]) => x === a && y === b || x === b && y === a);
125
126
  const findings = [];
126
127
  for (const device of devices) {
127
128
  const isRouter = routers.has(device.name);
@@ -143,7 +144,8 @@ var trustBoundary = (boundary) => (devices) => {
143
144
  for (const { what, carried, faces } of carriers) {
144
145
  const mixes = carried.some((vlan) => untrusted.has(vlan)) && carried.some((vlan) => !untrusted.has(vlan));
145
146
  const facesRouter = isRouter || faces.some((name) => routers.has(name));
146
- if (mixes && !facesRouter) {
147
+ const isExtension = faces.length > 0 && faces.every((name) => extended(device.name, name));
148
+ if (mixes && !facesRouter && !isExtension) {
147
149
  findings.push({
148
150
  level: "error",
149
151
  device: device.name,
@@ -83,6 +83,10 @@ export type TrustBoundary = {
83
83
  untrusted: readonly string[];
84
84
  /** The devices that filter: the only ones that may give an untrusted VLAN an address, and the only ones a port carrying both kinds may face. */
85
85
  routers: readonly string[];
86
+ /**
87
+ * Links between two switches that may carry both kinds, each named by its two devices: a site's switch extended to another building, with an exchange's VLAN and its own management on one cable. Neither end gives an untrusted VLAN an address.
88
+ */
89
+ extended?: readonly (readonly [string, string])[];
86
90
  };
87
91
  /** A check: traffic from outside reaches your own VLANs only through a router. A port or LAG carrying an untrusted VLAN beside any other is on a router or faces one, and only a router gives an untrusted VLAN an address. */
88
92
  export declare const trustBoundary: (boundary: TrustBoundary) => Check;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takodotid/circuit",
3
- "version": "0.30.0",
3
+ "version": "0.31.0",
4
4
  "description": "Declarative, vendor-neutral network configuration: describe each device in TypeScript, and Circuit makes the device match. Alpha.",
5
5
  "keywords": [
6
6
  "network",
@@ -186,6 +186,10 @@ export type TrustBoundary = {
186
186
  untrusted: readonly string[];
187
187
  /** The devices that filter: the only ones that may give an untrusted VLAN an address, and the only ones a port carrying both kinds may face. */
188
188
  routers: readonly string[];
189
+ /**
190
+ * Links between two switches that may carry both kinds, each named by its two devices: a site's switch extended to another building, with an exchange's VLAN and its own management on one cable. Neither end gives an untrusted VLAN an address.
191
+ */
192
+ extended?: readonly (readonly [string, string])[];
189
193
  };
190
194
 
191
195
  /** A check: traffic from outside reaches your own VLANs only through a router. A port or LAG carrying an untrusted VLAN beside any other is on a router or faces one, and only a router gives an untrusted VLAN an address. */
@@ -194,6 +198,7 @@ export const trustBoundary =
194
198
  (devices) => {
195
199
  const untrusted = new Set(boundary.untrusted);
196
200
  const routers = new Set(boundary.routers);
201
+ const extended = (a: string, b: string) => (boundary.extended ?? []).some(([x, y]) => (x === a && y === b) || (x === b && y === a));
197
202
  const findings: Finding[] = [];
198
203
 
199
204
  for (const device of devices) {
@@ -225,8 +230,9 @@ export const trustBoundary =
225
230
  for (const { what, carried, faces } of carriers) {
226
231
  const mixes = carried.some((vlan) => untrusted.has(vlan)) && carried.some((vlan) => !untrusted.has(vlan));
227
232
  const facesRouter = isRouter || faces.some((name) => routers.has(name));
233
+ const isExtension = faces.length > 0 && faces.every((name) => extended(device.name, name));
228
234
 
229
- if (mixes && !facesRouter) {
235
+ if (mixes && !facesRouter && !isExtension) {
230
236
  findings.push({
231
237
  level: "error",
232
238
  device: device.name,