pmcf 1.23.3 → 1.23.5

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.
@@ -2,13 +2,12 @@
2
2
 
3
3
  import { join } from "node:path";
4
4
  import { createHmac } from "node:crypto";
5
- import { Location } from "pmcf";
6
5
  import { writeLines, isIPv4Address } from "../src/utils.mjs";
7
6
  import { prepare } from "../src/cmd.mjs";
8
7
 
9
8
  const { world, args, options } = prepare();
10
9
 
11
- const location = await world.load(args[0], { type: Location });
10
+ const owner = await world.load(args[0]);
12
11
  const updates = [
13
12
  Math.ceil(Date.now() / 1000),
14
13
  36000,
@@ -17,79 +16,76 @@ const updates = [
17
16
  60000
18
17
  ].join(" ");
19
18
 
20
- const NAME_LEN = 35;
21
-
22
- await generateNamedDefs(location, options.output);
19
+ await generateNamedDefs(owner, options.output);
23
20
 
24
21
  console.log("depends", "mf-named");
25
22
  console.log("replaces", "mf-named-zones");
26
- console.log("description", `named defintions for ${location.name}`);
27
-
28
- /*for await (const location of world.locations()) {
29
- await generateNamedDefs(location, targetDir);
30
- }*/
23
+ console.log("description", `named defintions for ${owner.name}`);
31
24
 
32
- async function generateNamedDefs(location, targetDir) {
33
- const dns = location.dns;
25
+ async function generateNamedDefs(owner, targetDir) {
26
+ const dns = owner.dns;
34
27
  const ttl = dns.recordTTL;
35
28
 
36
29
  for (const domain of dns.domains) {
37
30
  const zones = [];
38
31
  const records = new Set();
39
32
 
40
- const nameserver = (await location.service({ type: "dns" }))?.owner;
41
- const rname = location.administratorEmail.replace(/@/, ".");
33
+ const nameserver = (await owner.service({ type: "dns" }))?.owner;
34
+ const rname = dns.administratorEmail.replace(/@/, ".");
42
35
 
43
- for await (const mail of location.services({ type: "smtp" })) {
36
+ let maxKeyLength;
37
+
38
+ const createRecord = (key, type, value) => {
39
+ return {
40
+ key,
41
+ type,
42
+ value,
43
+ toString: () =>
44
+ `${key.padEnd(maxKeyLength, " ")} ${ttl} IN ${type.padEnd(5, " ")} ${value}`
45
+ };
46
+ };
47
+
48
+ for await (const mail of owner.services({ type: "smtp" })) {
44
49
  records.add(
45
- `${"@".padEnd(NAME_LEN, " ")} ${ttl} IN MX ${mail.priority} ${
46
- mail.owner.domainName
47
- }.`
50
+ createRecord("@", "MX", `${mail.priority} ${mail.owner.domainName}.`)
48
51
  );
49
52
  }
50
53
 
51
- console.log(location.name, domain, nameserver?.hostName, rname);
54
+ console.log(owner.name, domain, nameserver?.hostName, rname);
55
+
56
+ const SOARecord = createRecord(
57
+ "@",
58
+ "SOA",
59
+ `${nameserver?.domainName}. ${rname}. (${updates})`
60
+ );
61
+
62
+ const NSRecord = createRecord("@", "NS", `${nameserver?.ipAddress}.`);
52
63
 
53
64
  const catalogZone = {
54
65
  id: `catalog.${domain}`,
55
66
  file: `catalog.${domain}.zone`,
56
67
  records: new Set([
57
- `${"@".padEnd(NAME_LEN, " ")} ${ttl} IN SOA ${
58
- nameserver.domainName
59
- }. ${rname}. (${updates})`,
60
- `${"@".padEnd(NAME_LEN, " ")} ${ttl} IN NS ${nameserver.ipAddress}.`,
61
- `${("version." + domain + ".").padEnd(NAME_LEN, " ")} IN TXT "2"`
68
+ SOARecord,
69
+ NSRecord,
70
+ createRecord(`version.${domain}.`, "TXT", '"2"')
62
71
  ])
63
72
  };
64
73
 
65
74
  const zone = {
66
75
  id: domain,
67
76
  file: `${domain}.zone`,
68
- records: new Set([
69
- `${"@".padEnd(NAME_LEN, " ")} ${ttl} IN SOA ${
70
- nameserver.domainName
71
- }. ${rname}. (${updates})`,
72
- `${"@".padEnd(NAME_LEN, " ")} ${ttl} IN NS ${nameserver.ipAddress}.`,
73
- ...records
74
- ])
77
+ records: new Set([SOARecord, NSRecord, ...records])
75
78
  };
76
79
  zones.push(zone);
77
80
 
78
- for (const subnet of location.subnets()) {
81
+ for (const subnet of owner.subnets()) {
79
82
  if (subnet.address) {
80
83
  const reverse = reverseAddress(subnet.address);
81
84
  const reverseArpa = reverseArpaAddress(subnet.address);
82
85
  const zone = {
83
86
  id: reverseArpa,
84
87
  file: `${reverse}.zone`,
85
- records: new Set([
86
- `${"@".padEnd(NAME_LEN, " ")} ${ttl} IN SOA ${
87
- nameserver.domainName
88
- }. ${rname}. (${updates})`,
89
- `${(reverseArpa + ".").padEnd(NAME_LEN, " ")} ${ttl} IN NS ${
90
- nameserver.domainName
91
- }.`
92
- ])
88
+ records: new Set([SOARecord, NSRecord])
93
89
  };
94
90
  zones.push(zone);
95
91
  subnet.reverseZone = zone;
@@ -99,33 +95,34 @@ async function generateNamedDefs(location, targetDir) {
99
95
  for await (const {
100
96
  address,
101
97
  networkInterface
102
- } of location.networkAddresses()) {
98
+ } of owner.networkAddresses()) {
103
99
  const host = networkInterface.host;
104
100
  zone.records.add(
105
- `${host.hostName.padEnd(NAME_LEN, " ")} ${ttl} IN ${
106
- isIPv4Address(address) ? "A " : "AAAA"
107
- } ${normalizeIPAddress(address)}`
101
+ createRecord(
102
+ host.hostName,
103
+ isIPv4Address(address) ? "A " : "AAAA",
104
+ normalizeIPAddress(address)
105
+ )
108
106
  );
109
107
 
110
108
  for (const service of host.services()) {
111
109
  if (service.master && service.alias) {
112
110
  zone.records.add(
113
- `${service.alias.padEnd(NAME_LEN, " ")} ${ttl} IN CNAME ${
114
- host.domainName
115
- }.`
111
+ createRecord(service.alias, "CNAME", `${host.domainName}.`)
116
112
  );
117
113
  }
118
114
 
119
115
  if (service.srvPrefix) {
120
116
  zone.records.add(
121
- `${`${service.srvPrefix}.${host.domainName}.`.padEnd(
122
- NAME_LEN,
123
- " "
124
- )} ${ttl} IN SRV ${String(service.priority).padStart(4)} ${String(
125
- service.weight
126
- ).padStart(3)} ${String(service.port).padStart(5)} ${
127
- host.domainName
128
- }.`
117
+ createRecord(
118
+ `${service.srvPrefix}.${host.domainName}.`,
119
+ "SRV",
120
+ `${String(service.priority).padStart(4)} ${String(
121
+ service.weight
122
+ ).padStart(3)} ${String(service.port).padStart(5)} ${
123
+ host.domainName
124
+ }.`
125
+ )
129
126
  );
130
127
  }
131
128
  }
@@ -134,10 +131,11 @@ async function generateNamedDefs(location, targetDir) {
134
131
 
135
132
  if (reverseZone && isIPv4Address(address)) {
136
133
  reverseZone.records.add(
137
- `${(reverseArpaAddress(address) + ".").padEnd(
138
- NAME_LEN,
139
- " "
140
- )} ${ttl} IN PTR ${networkInterface.host.domainName}.`
134
+ createRecord(
135
+ reverseArpaAddress(address) + ".",
136
+ "PTR",
137
+ `${networkInterface.host.domainName}.`
138
+ )
141
139
  );
142
140
  }
143
141
  }
@@ -150,7 +148,7 @@ async function generateNamedDefs(location, targetDir) {
150
148
  if (zone !== catalogZone) {
151
149
  const hash = createHmac("md5", zone.id).digest("hex");
152
150
  catalogZone.records.add(
153
- `${hash}.zones.${domain}. IN PTR ${zone.id}.`
151
+ createRecord(`${hash}.zones.${domain}.`, "PTR", `${zone.id}.`)
154
152
  );
155
153
  }
156
154
 
@@ -167,6 +165,13 @@ async function generateNamedDefs(location, targetDir) {
167
165
  zoneConfig.push(`};`);
168
166
  zoneConfig.push("");
169
167
 
168
+ maxKeyLength = 0;
169
+ for (const r of zone.records) {
170
+ if (r.key.length > maxKeyLength) {
171
+ maxKeyLength = r.key.length;
172
+ }
173
+ }
174
+
170
175
  writeLines(join(targetDir, "var/lib/named"), zone.file, zone.records);
171
176
  }
172
177
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmcf",
3
- "version": "1.23.3",
3
+ "version": "1.23.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/src/base.mjs CHANGED
@@ -69,6 +69,10 @@ export class Base {
69
69
  return this.owner?.network;
70
70
  }
71
71
 
72
+ get administratorEmail() {
73
+ return this.owner?.administratorEmail;
74
+ }
75
+
72
76
  #directory;
73
77
  set directory(directory) {
74
78
  this.#directory = directory;
package/src/model.mjs CHANGED
@@ -938,7 +938,7 @@ export class Service extends Base {
938
938
 
939
939
  get srvPrefix() {
940
940
  const st = ServiceTypes[this.type];
941
- if (st) {
941
+ if (st?.protocol) {
942
942
  return `_${this.type}._${st.protocol}`;
943
943
  }
944
944
  }
package/types/base.d.mts CHANGED
@@ -15,6 +15,7 @@ export class Base {
15
15
  get location(): any;
16
16
  get host(): any;
17
17
  get network(): any;
18
+ get administratorEmail(): any;
18
19
  set directory(directory: any);
19
20
  get directory(): any;
20
21
  get fullName(): any;
package/types/model.d.mts CHANGED
@@ -18,7 +18,6 @@ export class Owner extends Base {
18
18
  addSubnet(subnet: any): void;
19
19
  subnet(name: any): any;
20
20
  subnets(): MapIterator<any>;
21
- get administratorEmail(): any;
22
21
  toJSON(): {
23
22
  networks: any[];
24
23
  subnets: any[];