pmcf 1.9.1 → 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.
- package/bin/pmcf-location-defs +2 -2
- package/bin/pmcf-named-defs +3 -3
- package/package.json +1 -1
- package/src/model.mjs +127 -48
- package/types/model.d.mts +19 -6
package/bin/pmcf-location-defs
CHANGED
|
@@ -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.
|
|
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.
|
|
54
|
+
NTP: location.ntp.servers.join(" "),
|
|
55
55
|
PollIntervalMinSec: 60,
|
|
56
56
|
SaveIntervalSec: 3600
|
|
57
57
|
})
|
package/bin/pmcf-named-defs
CHANGED
|
@@ -106,7 +106,7 @@ async function generateNamedDefs(location, targetDir) {
|
|
|
106
106
|
} ${normalizeIPAddress(address)}`
|
|
107
107
|
);
|
|
108
108
|
|
|
109
|
-
for (const service of
|
|
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.
|
|
118
|
+
if (service.srvPrefix) {
|
|
119
119
|
zone.records.add(
|
|
120
|
-
`${`${service.
|
|
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
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
|
-
|
|
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
|
-
|
|
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
|
|
435
|
-
|
|
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
|
-
#
|
|
576
|
+
#services = [];
|
|
544
577
|
#extends = [];
|
|
545
578
|
#provides = new Set();
|
|
546
579
|
#replaces = new Set();
|
|
@@ -572,11 +605,6 @@ export class Host extends Base {
|
|
|
572
605
|
constructor(owner, data) {
|
|
573
606
|
super(owner, data);
|
|
574
607
|
|
|
575
|
-
if (data.model) {
|
|
576
|
-
this.#isModel = true;
|
|
577
|
-
delete data.model;
|
|
578
|
-
}
|
|
579
|
-
|
|
580
608
|
if (data.location !== undefined) {
|
|
581
609
|
this.#location = data.location;
|
|
582
610
|
delete data.location;
|
|
@@ -623,7 +651,21 @@ export class Host extends Base {
|
|
|
623
651
|
delete data.provides;
|
|
624
652
|
}
|
|
625
653
|
|
|
626
|
-
|
|
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);
|
|
627
669
|
|
|
628
670
|
owner.addHost(this);
|
|
629
671
|
|
|
@@ -631,13 +673,6 @@ export class Host extends Base {
|
|
|
631
673
|
iface.name = name;
|
|
632
674
|
this.networkInterfaces[name] = new NetworkInterface(this, iface);
|
|
633
675
|
}
|
|
634
|
-
|
|
635
|
-
for (const [name, data] of Object.entries(
|
|
636
|
-
Object.assign({}, ...this.extends.map(e => e.services), this.services)
|
|
637
|
-
)) {
|
|
638
|
-
data.name = name;
|
|
639
|
-
this.services[name] = new Service(this, data);
|
|
640
|
-
}
|
|
641
676
|
}
|
|
642
677
|
|
|
643
678
|
get deployment() {
|
|
@@ -652,6 +687,14 @@ export class Host extends Base {
|
|
|
652
687
|
return this.#vendor || this.extends.find(e => e.vendor)?.vendor;
|
|
653
688
|
}
|
|
654
689
|
|
|
690
|
+
get isModel() {
|
|
691
|
+
return this.#vendor || this.#chassis ? true : false;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
get model() {
|
|
695
|
+
return this.extends.find(h => h.isModel);
|
|
696
|
+
}
|
|
697
|
+
|
|
655
698
|
get extends() {
|
|
656
699
|
return this.#extends.map(e => this.expand(e));
|
|
657
700
|
}
|
|
@@ -694,14 +737,6 @@ export class Host extends Base {
|
|
|
694
737
|
return this.#distribution || this.extends.find(e => e.distribution);
|
|
695
738
|
}
|
|
696
739
|
|
|
697
|
-
get isModel() {
|
|
698
|
-
return this.#isModel;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
get model() {
|
|
702
|
-
return this.extends.find(h => h.isModel);
|
|
703
|
-
}
|
|
704
|
-
|
|
705
740
|
get domain() {
|
|
706
741
|
return this.location?.domain;
|
|
707
742
|
}
|
|
@@ -719,6 +754,23 @@ export class Host extends Base {
|
|
|
719
754
|
return this.hostName + "." + this.domain;
|
|
720
755
|
}
|
|
721
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
|
+
|
|
722
774
|
*networkAddresses() {
|
|
723
775
|
for (const [name, networkInterface] of Object.entries(
|
|
724
776
|
this.networkInterfaces
|
|
@@ -761,7 +813,7 @@ export class Host extends Base {
|
|
|
761
813
|
...super.toJSON(),
|
|
762
814
|
extends: this.extends.map(host => host.name),
|
|
763
815
|
services: Object.fromEntries(
|
|
764
|
-
|
|
816
|
+
[...this.services()].map(s => [s.name, s.toJSON()])
|
|
765
817
|
)
|
|
766
818
|
};
|
|
767
819
|
}
|
|
@@ -815,15 +867,15 @@ export class Subnet extends Base {
|
|
|
815
867
|
}
|
|
816
868
|
|
|
817
869
|
const ServiceTypes = {
|
|
818
|
-
dns: {
|
|
819
|
-
ldap: {
|
|
820
|
-
http: {
|
|
821
|
-
https: {
|
|
822
|
-
rtsp: {
|
|
823
|
-
smtp: {
|
|
824
|
-
ssh: {
|
|
825
|
-
imap: {
|
|
826
|
-
imaps: {
|
|
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 },
|
|
827
879
|
dhcp: {}
|
|
828
880
|
};
|
|
829
881
|
|
|
@@ -863,11 +915,38 @@ export class Service extends Base {
|
|
|
863
915
|
}
|
|
864
916
|
|
|
865
917
|
Object.assign(this, data);
|
|
918
|
+
|
|
866
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;
|
|
867
946
|
}
|
|
868
947
|
|
|
869
|
-
get
|
|
870
|
-
return ServiceTypes[this.type]?.
|
|
948
|
+
get srvPrefix() {
|
|
949
|
+
return ServiceTypes[this.type]?.srvPrefix;
|
|
871
950
|
}
|
|
872
951
|
|
|
873
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():
|
|
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
|
-
|
|
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,11 +97,12 @@ 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;
|
|
99
103
|
get vendor(): any;
|
|
104
|
+
get isModel(): boolean;
|
|
105
|
+
get model(): any;
|
|
100
106
|
get extends(): any[];
|
|
101
107
|
get provides(): Set<any>;
|
|
102
108
|
get replaces(): Set<any>;
|
|
@@ -105,12 +111,12 @@ export class Host extends Base {
|
|
|
105
111
|
get master(): boolean;
|
|
106
112
|
get os(): any;
|
|
107
113
|
get distribution(): any;
|
|
108
|
-
get isModel(): boolean;
|
|
109
|
-
get model(): any;
|
|
110
114
|
get domain(): any;
|
|
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
|
|
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 {};
|