pmcf 1.9.2 → 1.10.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.
@@ -21,7 +21,7 @@ console.log("replaces", `mf-location-${location.name}`);
21
21
  console.log("description", `location definitions for ${location.name}`);
22
22
 
23
23
  async function generateLocationDefs(location, dir) {
24
- const sl = location.dns_servers;
24
+ const sl = (await Array.fromAsync(location.dns.services())).map(s=>s.ipAddress);
25
25
  const s1 = sl.shift();
26
26
 
27
27
  await writeLines(
@@ -51,7 +51,7 @@ async function generateLocationDefs(location, dir) {
51
51
  join(dir, "etc/systemd/timesyncd.conf.d"),
52
52
  `${location.name}.conf`,
53
53
  sectionLines("Time", {
54
- NTP: location.ntp_servers.join(" "),
54
+ NTP: location.ntp.servers.join(" "),
55
55
  PollIntervalMinSec: 60,
56
56
  SaveIntervalSec: 3600
57
57
  })
@@ -106,7 +106,7 @@ async function generateNamedDefs(location, targetDir) {
106
106
  } ${normalizeIPAddress(address)}`
107
107
  );
108
108
 
109
- for (const service of Object.values(host.services)) {
109
+ for (const service of host.services()) {
110
110
  if (service.master && service.alias) {
111
111
  zone.records.add(
112
112
  `${service.alias.padEnd(NAME_LEN, " ")} ${ttl} IN CNAME ${
@@ -115,9 +115,9 @@ async function generateNamedDefs(location, targetDir) {
115
115
  );
116
116
  }
117
117
 
118
- if (service.prefix) {
118
+ if (service.srvPrefix) {
119
119
  zone.records.add(
120
- `${`${service.prefix}.${host.domainName}.`.padEnd(
120
+ `${`${service.srvPrefix}.${host.domainName}.`.padEnd(
121
121
  NAME_LEN,
122
122
  " "
123
123
  )} ${ttl} IN SRV ${String(service.priority).padStart(4)} ${String(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmcf",
3
- "version": "1.9.2",
3
+ "version": "1.10.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/src/model.mjs CHANGED
@@ -41,6 +41,14 @@ export class Base {
41
41
  }
42
42
  }
43
43
 
44
+ withOwner(owner) {
45
+ if (this.owner !== owner) {
46
+ return new this.constructor(owner, this);
47
+ }
48
+
49
+ return this;
50
+ }
51
+
44
52
  get typeName() {
45
53
  return this.constructor.typeName;
46
54
  }
@@ -77,7 +85,7 @@ export class Base {
77
85
  }
78
86
 
79
87
  get fullName() {
80
- return join(this.owner.fullName, this.name);
88
+ return this.owner ? join(this.owner.fullName, this.name) : this.name;
81
89
  }
82
90
 
83
91
  expand(object) {
@@ -192,7 +200,7 @@ export class Owner extends Base {
192
200
 
193
201
  _resolveBridges() {
194
202
  for (const bridge of this.#bridges) {
195
- console.log(bridgeToJSON(bridge));
203
+ this.info(bridgeToJSON(bridge));
196
204
  for (const network of bridge) {
197
205
  if (typeof network === "string") {
198
206
  const other = this.network(network);
@@ -201,7 +209,7 @@ export class Owner extends Base {
201
209
  bridge.delete(network);
202
210
  bridge.add(other);
203
211
  other.bridge = bridge;
204
- console.log("RESOLVE", network, other, bridgeToJSON(bridge));
212
+ this.info("RESOLVE", network, other, bridgeToJSON(bridge));
205
213
  } else {
206
214
  this.error(`Unresolvabale bridge network`, network);
207
215
  }
@@ -386,9 +394,31 @@ export class World extends Owner {
386
394
  }
387
395
  }
388
396
 
397
+ class DNSService {
398
+ owner;
399
+ forwardsTo = [];
400
+ constructor(owner, data) {
401
+ this.owner = owner;
402
+ Object.assign(this, data);
403
+ }
404
+
405
+ async *services() {
406
+ const filter = { type: "dns" };
407
+
408
+ yield* this.owner.services(filter);
409
+
410
+ for (const s of this.forwardsTo) {
411
+ const host = await this.owner.world.load(s);
412
+
413
+ yield* host.services(filter);
414
+ }
415
+ }
416
+ }
417
+
389
418
  export class Location extends Owner {
390
419
  domain;
391
- dns;
420
+ #dns;
421
+ ntp = { servers: [] };
392
422
  #administratorEmail;
393
423
 
394
424
  static get typeName() {
@@ -398,6 +428,13 @@ export class Location extends Owner {
398
428
  constructor(owner, data) {
399
429
  super(owner, data);
400
430
 
431
+ let dns;
432
+ if (data.dns) {
433
+ dns = data.dns;
434
+ delete data.dns;
435
+ }
436
+
437
+ this.#dns = new DNSService(this, dns);
401
438
  const networks = data.networks;
402
439
  delete data.networks;
403
440
  Object.assign(this, data);
@@ -418,6 +455,10 @@ export class Location extends Owner {
418
455
  }
419
456
  }
420
457
 
458
+ get dns() {
459
+ return this.#dns;
460
+ }
461
+
421
462
  async service(filter) {
422
463
  let best;
423
464
  for await (const service of this.services(filter)) {
@@ -431,15 +472,8 @@ export class Location extends Owner {
431
472
 
432
473
  async *services(filter) {
433
474
  for await (const host of this.hosts()) {
434
- for (const service of Object.values(host.services)) {
435
- if (
436
- !filter ||
437
- filter.type === "*" ||
438
- filter.type === service.type ||
439
- filter.name === service.name
440
- ) {
441
- yield service;
442
- }
475
+ for await (const service of host.services(filter)) {
476
+ yield service;
443
477
  }
444
478
  }
445
479
  }
@@ -538,9 +572,8 @@ export class Network extends Owner {
538
572
 
539
573
  export class Host extends Base {
540
574
  networkInterfaces = {};
541
- services = {};
542
575
  postinstall = [];
543
- #isModel = false;
576
+ #services = [];
544
577
  #extends = [];
545
578
  #provides = new Set();
546
579
  #replaces = new Set();
@@ -618,7 +651,21 @@ export class Host extends Base {
618
651
  delete data.provides;
619
652
  }
620
653
 
621
- Object.assign(this, { services: {}, networkInterfaces: {} }, data);
654
+ if (data.services) {
655
+ for (const [name, sd] of Object.entries(data.services)) {
656
+ sd.name = name;
657
+ new Service(this, sd);
658
+ }
659
+ delete data.services;
660
+ }
661
+
662
+ for (const host of this.extends) {
663
+ for (const service of host.services()) {
664
+ service.withOwner(this);
665
+ }
666
+ }
667
+
668
+ Object.assign(this, { networkInterfaces: {} }, data);
622
669
 
623
670
  owner.addHost(this);
624
671
 
@@ -626,13 +673,6 @@ export class Host extends Base {
626
673
  iface.name = name;
627
674
  this.networkInterfaces[name] = new NetworkInterface(this, iface);
628
675
  }
629
-
630
- for (const [name, data] of Object.entries(
631
- Object.assign({}, ...this.extends.map(e => e.services), this.services)
632
- )) {
633
- data.name = name;
634
- this.services[name] = new Service(this, data);
635
- }
636
676
  }
637
677
 
638
678
  get deployment() {
@@ -648,7 +688,7 @@ export class Host extends Base {
648
688
  }
649
689
 
650
690
  get isModel() {
651
- return (this.#vendor || this.#chassis) ? true : false;
691
+ return this.#vendor || this.#chassis ? true : false;
652
692
  }
653
693
 
654
694
  get model() {
@@ -714,6 +754,23 @@ export class Host extends Base {
714
754
  return this.hostName + "." + this.domain;
715
755
  }
716
756
 
757
+ addService(service) {
758
+ this.#services.push(service);
759
+ }
760
+
761
+ *services(filter) {
762
+ for (const service of this.#services) {
763
+ if (
764
+ !filter ||
765
+ filter.type === "*" ||
766
+ filter.type === service.type ||
767
+ filter.name === service.name
768
+ ) {
769
+ yield service;
770
+ }
771
+ }
772
+ }
773
+
717
774
  *networkAddresses() {
718
775
  for (const [name, networkInterface] of Object.entries(
719
776
  this.networkInterfaces
@@ -756,7 +813,7 @@ export class Host extends Base {
756
813
  ...super.toJSON(),
757
814
  extends: this.extends.map(host => host.name),
758
815
  services: Object.fromEntries(
759
- Object.values(this.services).map(s => [s.name, s.toJSON()])
816
+ [...this.services()].map(s => [s.name, s.toJSON()])
760
817
  )
761
818
  };
762
819
  }
@@ -810,15 +867,15 @@ export class Subnet extends Base {
810
867
  }
811
868
 
812
869
  const ServiceTypes = {
813
- dns: { prefix: "_dns._udp", port: 53 },
814
- ldap: { prefix: "_ldap._tcp", port: 389 },
815
- http: { prefix: "_http._tcp", port: 80 },
816
- https: { prefix: "_http._tcp", port: 443 },
817
- rtsp: { prefix: "_rtsp._tcp", port: 554 },
818
- smtp: { prefix: "_smtp._tcp", port: 25 },
819
- ssh: { prefix: "_ssh._tcp", port: 22 },
820
- imap: { prefix: "_imap._tcp", port: 143 },
821
- imaps: { prefix: "_imaps._tcp", port: 993 },
870
+ dns: { srvPrefix: "_dns._udp", port: 53 },
871
+ ldap: { srvPrefix: "_ldap._tcp", port: 389 },
872
+ http: { srvPrefix: "_http._tcp", port: 80 },
873
+ https: { srvPrefix: "_http._tcp", port: 443 },
874
+ rtsp: { srvPrefix: "_rtsp._tcp", port: 554 },
875
+ smtp: { srvPrefix: "_smtp._tcp", port: 25 },
876
+ ssh: { srvPrefix: "_ssh._tcp", port: 22 },
877
+ imap: { srvPrefix: "_imap._tcp", port: 143 },
878
+ imaps: { srvPrefix: "_imaps._tcp", port: 993 },
822
879
  dhcp: {}
823
880
  };
824
881
 
@@ -858,11 +915,38 @@ export class Service extends Base {
858
915
  }
859
916
 
860
917
  Object.assign(this, data);
918
+
861
919
  this.owner = owner;
920
+
921
+ owner.addService(this);
922
+ }
923
+
924
+ withOwner(owner) {
925
+ if (this.owner !== owner) {
926
+ const data = { name: this.name };
927
+ if (this.alias) {
928
+ data.alias = this.alias;
929
+ }
930
+ if (this.#type) {
931
+ data.type = this.#type;
932
+ }
933
+ if (this.#weight) {
934
+ data.weight = this.#weight;
935
+ }
936
+ if (this.#port) {
937
+ data.port = this.#port;
938
+ }
939
+ if (this.#ipAddress) {
940
+ data.ipAddress = this.#ipAddress;
941
+ }
942
+ return new this.constructor(owner, data);
943
+ }
944
+
945
+ return this;
862
946
  }
863
947
 
864
- get prefix() {
865
- return ServiceTypes[this.type]?.prefix;
948
+ get srvPrefix() {
949
+ return ServiceTypes[this.type]?.srvPrefix;
866
950
  }
867
951
 
868
952
  get ipAddress() {
package/types/model.d.mts CHANGED
@@ -10,6 +10,7 @@ export class Base {
10
10
  owner: any;
11
11
  name: any;
12
12
  description: any;
13
+ withOwner(owner: any): any;
13
14
  get typeName(): any;
14
15
  get world(): any;
15
16
  get location(): any;
@@ -17,7 +18,7 @@ export class Base {
17
18
  network(name: any): Promise<any>;
18
19
  set directory(directory: any);
19
20
  get directory(): any;
20
- get fullName(): string;
21
+ get fullName(): any;
21
22
  expand(object: any): any;
22
23
  error(...args: any[]): void;
23
24
  info(...args: any[]): void;
@@ -53,6 +54,7 @@ export class World extends Owner {
53
54
  [k: string]: typeof Location | typeof Host | typeof Network | typeof Subnet | typeof Service;
54
55
  };
55
56
  constructor(directory: any);
57
+ get fullName(): string;
56
58
  get world(): this;
57
59
  load(name: any, options: any): any;
58
60
  loadAll(): Promise<void>;
@@ -70,7 +72,10 @@ export class World extends Owner {
70
72
  }
71
73
  export class Location extends Owner {
72
74
  domain: any;
73
- dns: any;
75
+ ntp: {
76
+ servers: any[];
77
+ };
78
+ get dns(): DNSService;
74
79
  service(filter: any): Promise<any>;
75
80
  services(filter: any): AsyncGenerator<any, void, unknown>;
76
81
  networkAddresses(): AsyncGenerator<any, void, unknown>;
@@ -92,7 +97,6 @@ export class Network extends Owner {
92
97
  export class Host extends Base {
93
98
  static prepareData(world: any, data: any): Promise<typeof Host>;
94
99
  networkInterfaces: {};
95
- services: {};
96
100
  postinstall: any[];
97
101
  get deployment(): any;
98
102
  get chassis(): any;
@@ -111,6 +115,8 @@ export class Host extends Base {
111
115
  get modelName(): any;
112
116
  get hostName(): any;
113
117
  get domainName(): string;
118
+ addService(service: any): void;
119
+ services(filter: any): Generator<any, void, unknown>;
114
120
  networkAddresses(): Generator<{
115
121
  address: any;
116
122
  networkInterface: any;
@@ -131,7 +137,7 @@ export class Subnet extends Base {
131
137
  }
132
138
  export class Service extends Base {
133
139
  alias: any;
134
- get prefix(): any;
140
+ get srvPrefix(): any;
135
141
  get ipAddress(): any;
136
142
  get port(): any;
137
143
  get priority(): any;
@@ -140,3 +146,10 @@ export class Service extends Base {
140
146
  get type(): any;
141
147
  #private;
142
148
  }
149
+ declare class DNSService {
150
+ constructor(owner: any, data: any);
151
+ owner: any;
152
+ forwardsTo: any[];
153
+ services(): AsyncGenerator<any, void, any>;
154
+ }
155
+ export {};