pmcf 1.5.3 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -74,7 +74,7 @@ async function generateNamedDefs(location, targetDir) {
74
74
  };
75
75
  zones.push(zone);
76
76
 
77
- for await (const subnet of location.subnets()) {
77
+ for (const subnet of location.subnets()) {
78
78
  if (subnet.address) {
79
79
  const reverse = reverseAddress(subnet.address);
80
80
  const reverseArpa = reverseArpaAddress(subnet.address);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmcf",
3
- "version": "1.5.3",
3
+ "version": "1.6.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/src/model.mjs CHANGED
@@ -101,7 +101,7 @@ export class Base {
101
101
  }
102
102
 
103
103
  toString() {
104
- return this.typeName + ":" + this.owner.name + "/" + this.name;
104
+ return this.typeName + ":" + (this.owner?.name || "") + "/" + this.name;
105
105
  }
106
106
 
107
107
  get propertyNames() {
@@ -114,9 +114,96 @@ export class Base {
114
114
  }
115
115
 
116
116
  export class Owner extends Base {
117
- addHost(host) {}
118
- addNetwork(network) {}
119
- async network(name) {}
117
+ #hosts = new Map();
118
+ #networks = new Map();
119
+ #subnets = new Map();
120
+ #bridges = new Set();
121
+
122
+ async *hosts() {
123
+ for (const host of this.#hosts.values()) {
124
+ yield host;
125
+ }
126
+ }
127
+
128
+ addHost(host) {
129
+ this.#hosts.set(host.name, host);
130
+ }
131
+
132
+ network(name) {
133
+ return this.#networks.get(name);
134
+ }
135
+
136
+ async *networks() {
137
+ for (const network of this.#networks.values()) {
138
+ yield network;
139
+ }
140
+ }
141
+
142
+ addNetwork(network) {
143
+ this.#networks.set(network.name, network);
144
+ }
145
+
146
+ addBridge(network, destinationNetworks) {
147
+ console.log(
148
+ "BRIDGE",
149
+ network.name,
150
+ destinationNetworks.map(n => (this.network(n) ? n : `(${n})`))
151
+ );
152
+
153
+ let bridge;
154
+
155
+ for (bridge of this.#bridges) {
156
+ if (bridge.has(network.name)) {
157
+ bridge.delete(network.name);
158
+ bridge.add(network);
159
+
160
+ console.log(
161
+ "REPLACE",
162
+ network.name,
163
+ [...bridge].map(n => n.name||`(${n})`)
164
+ );
165
+
166
+ break;
167
+ }
168
+
169
+ if (bridge.has(network)) {
170
+ break;
171
+ }
172
+ }
173
+
174
+ if (!bridge) {
175
+ bridge = new Set([network]);
176
+ this.#bridges.add(bridge);
177
+ }
178
+
179
+ for (const name of destinationNetworks) {
180
+ bridge.add(this.network(name) || name);
181
+ }
182
+
183
+ return bridge;
184
+ }
185
+
186
+ addSubnet(subnet) {
187
+ this.#subnets.set(subnet.name, subnet);
188
+ }
189
+
190
+ subnet(name) {
191
+ return this.#subnets.get(name);
192
+ }
193
+
194
+ subnets() {
195
+ return this.#subnets.values();
196
+ }
197
+
198
+ toJSON() {
199
+ return {
200
+ ...super.toJSON(),
201
+ networks: [...this.#networks.keys()].sort(),
202
+ subnets: [...this.#subnets.keys()].sort(),
203
+ bridges: [...this.#bridges.keys()].sort(),
204
+ hosts: [...this.#hosts.keys()].sort()
205
+ };
206
+ }
120
207
  }
121
208
 
122
209
  export class World extends Owner {
@@ -237,9 +324,6 @@ export class Location extends Owner {
237
324
  domain;
238
325
  dns;
239
326
  #administratorEmail;
240
- #hosts = new Map();
241
- #networks = new Map();
242
- #subnets = new Map();
243
327
 
244
328
  static get typeName() {
245
329
  return "location";
@@ -253,23 +337,9 @@ export class Location extends Owner {
253
337
  Object.assign(this, data);
254
338
 
255
339
  if (networks) {
256
- for (const [name, network] of Object.entries(networks)) {
257
- network.name = name;
258
- this.addNetwork(network);
259
- }
260
-
261
- for (const network of this.#networks.values()) {
262
- if (network.bridges) {
263
- network.bridges = new Set(
264
- network.bridges.map(b => {
265
- const n = this.network(b);
266
- if (!n) {
267
- console.error(`No network named ${b}`);
268
- }
269
- return n;
270
- })
271
- );
272
- }
340
+ for (const [name, data] of Object.entries(networks)) {
341
+ data.name = name;
342
+ new Network(this, data);
273
343
  }
274
344
  }
275
345
  }
@@ -316,67 +386,6 @@ export class Location extends Owner {
316
386
  }
317
387
  }
318
388
 
319
- async network(name) {
320
- return this.#networks.get(name);
321
- }
322
-
323
- async *networks() {
324
- for (const network of this.#networks.values()) {
325
- yield network;
326
- }
327
- }
328
-
329
- async *subnets() {
330
- for (const subnet of this.#subnets.values()) {
331
- yield subnet;
332
- }
333
- }
334
-
335
- addNetwork(data) {
336
- if (!data?.name) {
337
- return undefined;
338
- }
339
-
340
- let network = this.#networks.get(data.name);
341
- if (network) {
342
- return network;
343
- }
344
-
345
- if (data instanceof Network) {
346
- this.#networks.set(data.name, data);
347
- return data;
348
- }
349
-
350
- network = new Network(this, data);
351
- this.#networks.set(data.name, network);
352
-
353
- const subnetAddress = network.subnetAddress;
354
-
355
- if (subnetAddress) {
356
- let subnet = this.#subnets.get(subnetAddress);
357
- if (!subnet) {
358
- subnet = new Subnet(this, subnetAddress);
359
- this.#subnets.set(subnetAddress, subnet);
360
- }
361
- network.subnet = subnet;
362
- subnet.networks.add(network);
363
- }
364
- return network;
365
- }
366
-
367
- addHost(host) {
368
- this.#hosts.set(host.name, host);
369
-
370
- for (const [name, iface] of Object.entries(host.networkInterfaces)) {
371
- const network = this.addNetwork({ name: iface.network });
372
- if (!network) {
373
- console.error("Missing network", host.name, name);
374
- } else {
375
- network.addHost(host);
376
- }
377
- }
378
- }
379
-
380
389
  get dnsAllowedUpdates() {
381
390
  return this.dns?.allowedUpdates || [];
382
391
  }
@@ -392,23 +401,15 @@ export class Location extends Owner {
392
401
  get propertyNames() {
393
402
  return [...super.propertyNames, "domain" /*, "hosts"*/];
394
403
  }
395
-
396
- toJSON() {
397
- return {
398
- ...super.toJSON(),
399
- hosts: [...this.#hosts.keys()].sort()
400
- };
401
- }
402
404
  }
403
405
 
404
- export class Network extends Base {
405
- #hosts = new Map();
406
+ export class Network extends Owner {
406
407
  kind;
407
408
  scope;
408
409
  metric;
409
410
  ipv4;
410
- ipv4_netmask;
411
411
  subnet;
412
+ bridge;
412
413
 
413
414
  static get typeName() {
414
415
  return "network";
@@ -417,16 +418,38 @@ export class Network extends Base {
417
418
  constructor(owner, data) {
418
419
  super(owner, data);
419
420
 
421
+ let bridges;
422
+ if (data.bridges) {
423
+ bridges = data.bridges;
424
+ delete data.bridges;
425
+ }
426
+
420
427
  Object.assign(this, data);
421
428
 
422
- if (this.ipv4) {
423
- const m = this.ipv4.match(/\/(\d+)$/);
424
- if (m) {
425
- this.ipv4_netmask = m[1];
429
+ const subnetAddress = this.subnetAddress;
430
+
431
+ if (subnetAddress) {
432
+ let subnet = owner.subnet(subnetAddress);
433
+ if (!subnet) {
434
+ subnet = new Subnet(owner, { name: subnetAddress });
426
435
  }
436
+
437
+ this.subnet = subnet;
438
+ subnet.networks.add(this);
427
439
  }
428
440
 
429
441
  owner.addNetwork(this);
442
+
443
+ if (bridges) {
444
+ this.bridge = owner.addBridge(this, bridges);
445
+ }
446
+ }
447
+
448
+ get ipv4_netmask() {
449
+ const m = this.ipv4?.match(/\/(\d+)$/);
450
+ if (m) {
451
+ return m[1];
452
+ }
430
453
  }
431
454
 
432
455
  get subnetAddress() {
@@ -437,18 +460,15 @@ export class Network extends Base {
437
460
  }
438
461
  }
439
462
 
440
- async *hosts() {
441
- for (const host of this.#hosts.values()) {
442
- yield host;
443
- }
444
- }
445
-
446
- addHost(host) {
447
- this.#hosts.set(host.name, host);
448
- }
449
-
450
463
  get propertyNames() {
451
- return [...super.propertyNames, "kind", "ipv4", "scope", "metric"];
464
+ return [
465
+ ...super.propertyNames,
466
+ "kind",
467
+ "ipv4",
468
+ "scope",
469
+ "metric",
470
+ "bridge"
471
+ ];
452
472
  }
453
473
  }
454
474
 
@@ -535,7 +555,14 @@ export class Host extends Base {
535
555
  iface.host = this;
536
556
  iface.name = name;
537
557
  if (iface.network) {
538
- iface.network = this.network(iface.network);
558
+ const network = owner.network(iface.network);
559
+
560
+ if (!network) {
561
+ console.error(`${this.toString()}: Missing network`, iface.network);
562
+ } else {
563
+ iface.network = network;
564
+ network.addHost(this);
565
+ }
539
566
  }
540
567
  }
541
568
 
@@ -664,7 +691,6 @@ export class Host extends Base {
664
691
 
665
692
  export class Model extends Host {}
666
693
 
667
-
668
694
  export class Subnet extends Base {
669
695
  networks = new Set();
670
696
 
@@ -672,8 +698,12 @@ export class Subnet extends Base {
672
698
  return "subnet";
673
699
  }
674
700
 
675
- constructor(owner, address) {
676
- super(owner, { name: address });
701
+ constructor(owner, data) {
702
+ super(owner, data);
703
+
704
+ Object.assign(this, data);
705
+
706
+ owner.addSubnet(this);
677
707
  }
678
708
 
679
709
  get address() {
package/types/model.d.mts CHANGED
@@ -24,9 +24,22 @@ export class Base {
24
24
  #private;
25
25
  }
26
26
  export class Owner extends Base {
27
+ hosts(): AsyncGenerator<any, void, unknown>;
27
28
  addHost(host: any): void;
29
+ network(name: any): any;
30
+ networks(): AsyncGenerator<any, void, unknown>;
28
31
  addNetwork(network: any): void;
29
- network(name: any): Promise<void>;
32
+ addBridge(network: any, destinationNetworks: any): any;
33
+ addSubnet(subnet: any): void;
34
+ subnet(name: any): any;
35
+ subnets(): MapIterator<any>;
36
+ toJSON(): {
37
+ networks: any[];
38
+ subnets: any[];
39
+ bridges: any[];
40
+ hosts: any[];
41
+ };
42
+ #private;
30
43
  }
31
44
  export class World extends Owner {
32
45
  static get types(): {
@@ -52,33 +65,23 @@ export class World extends Owner {
52
65
  export class Location extends Owner {
53
66
  domain: any;
54
67
  dns: any;
55
- hosts(): AsyncGenerator<any, void, unknown>;
56
68
  service(filter: any): Promise<any>;
57
69
  services(filter: any): AsyncGenerator<any, void, unknown>;
58
70
  networkAddresses(): AsyncGenerator<any, void, unknown>;
59
- network(name: any): Promise<any>;
60
- networks(): AsyncGenerator<any, void, unknown>;
61
- subnets(): AsyncGenerator<any, void, unknown>;
62
- addNetwork(data: any): any;
63
71
  get dnsAllowedUpdates(): any;
64
72
  get dnsRecordTTL(): any;
65
73
  get administratorEmail(): any;
66
- toJSON(): {
67
- hosts: any[];
68
- };
69
74
  #private;
70
75
  }
71
- export class Network extends Base {
76
+ export class Network extends Owner {
72
77
  kind: any;
73
78
  scope: any;
74
79
  metric: any;
75
80
  ipv4: any;
76
- ipv4_netmask: any;
77
81
  subnet: any;
82
+ bridge: any;
83
+ get ipv4_netmask(): any;
78
84
  get subnetAddress(): any;
79
- hosts(): AsyncGenerator<any, void, unknown>;
80
- addHost(host: any): void;
81
- #private;
82
85
  }
83
86
  export class Host extends Base {
84
87
  static prepareData(world: any, data: any): Promise<typeof Host>;