pmcf 1.81.0 → 1.82.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmcf",
3
- "version": "1.81.0",
3
+ "version": "1.82.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/src/dns-utils.mjs CHANGED
@@ -5,7 +5,11 @@ export function dnsFullName(name) {
5
5
  }
6
6
 
7
7
  export function DNSRecord(key, type, ...values) {
8
- values = values.map(v => (typeof v === "number" ? String(v).padStart(3) : v));
8
+ const pad = type === "MX" ? " " : "";
9
+
10
+ values = values.map(v =>
11
+ typeof v === "number" ? String(v).padStart(3) + pad : v
12
+ );
9
13
 
10
14
  return {
11
15
  key,
@@ -23,7 +27,8 @@ export function dnsFormatParameters(parameters) {
23
27
  value !== undefined && [...asIterator(value)].length > 0
24
28
  ? `${name}="${[...asIterator(value)].join(",")}"`
25
29
  : name
26
- ).sort((a,b)=>a[0].localeCompare(b[0]))
30
+ )
31
+ .sort((a, b) => a[0].localeCompare(b[0]))
27
32
  .join(" ");
28
33
  }
29
34
 
package/src/dns.mjs CHANGED
@@ -184,74 +184,86 @@ export class DNSService extends Base {
184
184
  async function generateZoneDefs(dns, targetDir) {
185
185
  const ttl = dns.recordTTL;
186
186
  const updates = [Math.ceil(Date.now() / 1000), ...dns.soaUpdates].join(" ");
187
+ const nameService = dns.findService(DNS_SERVICE_FILTER);
188
+ const rname = dns.administratorEmail.replace(/@/, ".");
189
+
190
+ const SOARecord = DNSRecord(
191
+ "@",
192
+ "SOA",
193
+ dnsFullName(nameService.domainName),
194
+ dnsFullName(rname),
195
+ `(${updates})`
196
+ );
187
197
 
188
- for (const domain of dns.domains) {
189
- const isLocalDomain = dns.localDomains.has(domain);
190
-
191
- const ownerName = isLocalDomain ? dns.owner.name : "FOREIGN";
192
- const zones = [];
193
- const records = new Set();
194
-
195
- const nameService = dns.findService(DNS_SERVICE_FILTER);
196
- const rname = dns.administratorEmail.replace(/@/, ".");
197
-
198
- let maxKeyLength;
198
+ const NSRecord = DNSRecord(
199
+ "@",
200
+ "NS",
201
+ dnsFullName(nameService.ipAddressOrDomainName)
202
+ );
199
203
 
200
- if (isLocalDomain) {
201
- for (const mail of dns.owner.findServices({
202
- type: "smtp",
203
- priority: "<10"
204
- })) {
205
- records.add(
206
- DNSRecord("@", "MX", mail.priority, dnsFullName(mail.domainName))
204
+ console.log(`${nameService}`, nameService.ipAddressOrDomainName);
205
+
206
+ const configs = [];
207
+
208
+ for (const host of dns.owner.hosts()) {
209
+ for (const domain of host.foreignDomainNames) {
210
+ const zone = {
211
+ id: domain,
212
+ file: `FOREIGN/${domain}.zone`,
213
+ records: new Set([SOARecord, NSRecord])
214
+ };
215
+ const config = {
216
+ name: `${domain}.zone.conf`,
217
+ zones: [zone]
218
+ };
219
+ configs.push(config);
220
+
221
+ for (const address of host.rawAddresses) {
222
+ zone.records.add(
223
+ DNSRecord(
224
+ "@",
225
+ isIPv6Address(address) ? "AAAA" : "A",
226
+ normalizeIPAddress(address)
227
+ )
207
228
  );
208
229
  }
209
230
  }
231
+ }
210
232
 
211
- console.log(`${nameService} ${domain}`, nameService.ipAddressOrDomainName);
212
- //console.log(dns.owner.fullName, domain, nameService.domainName, rname);
233
+ for (const domain of dns.localDomains) {
234
+ const ownerName = dns.owner.name;
213
235
  const reverseZones = new Map();
214
236
 
215
- const SOARecord = DNSRecord(
216
- "@",
217
- "SOA",
218
- dnsFullName(nameService.domainName),
219
- dnsFullName(rname),
220
- `(${updates})`
221
- );
222
-
223
- const NSRecord = DNSRecord(
224
- "@",
225
- "NS",
226
- dnsFullName(nameService.ipAddressOrDomainName)
227
- );
237
+ const config = {
238
+ name: `${domain}.zone.conf`,
239
+ zones: []
240
+ };
241
+ configs.push(config);
228
242
 
229
243
  const zone = {
230
244
  id: domain,
231
- type: "plain",
232
245
  file: `${ownerName}/${domain}.zone`,
233
- records: new Set([SOARecord, NSRecord, ...records])
246
+ records: new Set([SOARecord, NSRecord])
234
247
  };
235
- zones.push(zone);
236
-
237
- const catalogZone = {
238
- id: `catalog.${domain}`,
239
- type: "catalog",
240
- file: `${ownerName}/catalog.${domain}.zone`,
241
- records: new Set([
242
- SOARecord,
243
- NSRecord,
244
- DNSRecord(dnsFullName(`version.catalog.${domain}`), "TXT", '"1"')
245
- ])
246
- };
247
-
248
- const configs = {
249
- plain: { name: `${domain}.zone.conf`, content: [] }
250
- };
251
-
252
- if (isLocalDomain && dns.hasCatalog) {
253
- zones.push(catalogZone);
254
- configs.catalog = { name: `catalog.${domain}.zone.conf`, content: [] };
248
+ config.zones.push(zone);
249
+
250
+ if (dns.hasCatalog) {
251
+ const catalogConfig = {
252
+ name: `catalog.${domain}.zone.conf`,
253
+ zones: []
254
+ };
255
+ configs.push(catalogConfig);
256
+
257
+ zone.catalogZone = {
258
+ id: `catalog.${domain}`,
259
+ file: `${ownerName}/catalog.${domain}.zone`,
260
+ records: new Set([
261
+ SOARecord,
262
+ NSRecord,
263
+ DNSRecord(dnsFullName(`version.catalog.${domain}`), "TXT", '"1"')
264
+ ])
265
+ };
266
+ catalogConfig.zones.push(zone.catalogZone);
255
267
  }
256
268
 
257
269
  const hosts = new Set();
@@ -290,7 +302,7 @@ async function generateZoneDefs(dns, targetDir) {
290
302
  file: `${ownerName}/${reverseArpa}.zone`,
291
303
  records: new Set([SOARecord, NSRecord])
292
304
  };
293
- zones.push(reverseZone);
305
+ config.zones.push(reverseZone);
294
306
  reverseZones.set(subnet.address, reverseZone);
295
307
  }
296
308
 
@@ -306,7 +318,7 @@ async function generateZoneDefs(dns, targetDir) {
306
318
  }
307
319
  }
308
320
 
309
- if (isLocalDomain && !hosts.has(host)) {
321
+ if (!hosts.has(host)) {
310
322
  hosts.add(host);
311
323
  for (const service of host.findServices()) {
312
324
  for (const record of service.dnsRecordsForDomainName(
@@ -319,15 +331,20 @@ async function generateZoneDefs(dns, targetDir) {
319
331
  }
320
332
  }
321
333
  }
334
+ }
335
+
336
+ for (const config of configs) {
337
+ console.log(`config: ${config.name}`);
322
338
 
323
- for (const zone of zones) {
324
- const content = configs[zone.type].content;
339
+ const content = [];
340
+ for (const zone of config.zones) {
341
+ console.log(` zone: ${zone.id}`);
325
342
 
326
- if (zone.type !== "catalog") {
343
+ if (zone.catalogZone) {
327
344
  const hash = createHmac("md5", zone.id).digest("hex");
328
- catalogZone.records.add(
345
+ zone.catalogZone.records.add(
329
346
  DNSRecord(
330
- `${hash}.zones.catalog.${domain}.`,
347
+ `${hash}.zones.catalog.${zone.id}.`,
331
348
  "PTR",
332
349
  dnsFullName(zone.id)
333
350
  )
@@ -347,7 +364,7 @@ async function generateZoneDefs(dns, targetDir) {
347
364
  content.push(`};`);
348
365
  content.push("");
349
366
 
350
- maxKeyLength = 0;
367
+ let maxKeyLength = 0;
351
368
  for (const r of zone.records) {
352
369
  if (r.key.length > maxKeyLength) {
353
370
  maxKeyLength = r.key.length;
@@ -361,13 +378,11 @@ async function generateZoneDefs(dns, targetDir) {
361
378
  );
362
379
  }
363
380
 
364
- for (const cfg of Object.values(configs)) {
365
- await writeLines(
366
- join(targetDir, "etc/named.d/zones"),
367
- cfg.name,
368
- cfg.content
369
- );
370
- }
381
+ await writeLines(
382
+ join(targetDir, "etc/named.d/zones"),
383
+ config.name,
384
+ content
385
+ );
371
386
  }
372
387
  }
373
388
 
package/src/host.mjs CHANGED
@@ -254,10 +254,18 @@ export class Host extends Base {
254
254
  return parts[parts.length - 1];
255
255
  }
256
256
 
257
- get domains() {
257
+ get foreignDomainNames() {
258
+ return [...this.aliases].filter(n => n.split(".").length > 1);
259
+ }
260
+
261
+ get foreignDomains() {
258
262
  return new Set(
259
263
  [...this.aliases].map(n => domainFromDominName(n, this.domain))
260
- ).union(this.localDomains);
264
+ );
265
+ }
266
+
267
+ get domains() {
268
+ return this.foreignDomains.union(this.localDomains);
261
269
  }
262
270
 
263
271
  get domainNames() {
package/src/service.mjs CHANGED
@@ -21,8 +21,8 @@ const ServiceTypes = {
21
21
  dnsRecord: { type: "HTTPS", parameters: { alpn: "h2" } }
22
22
  },
23
23
  http3: {
24
- protocol: "tcp",
25
24
  type: "https",
25
+ protocol: "tcp",
26
26
  port: 443,
27
27
  tls: true,
28
28
  dnsRecord: {
@@ -31,7 +31,7 @@ const ServiceTypes = {
31
31
  }
32
32
  },
33
33
  rtsp: { protocol: "tcp", port: 554, tls: false },
34
- smtp: { protocol: "tcp", port: 25, tls: false },
34
+ smtp: { protocol: "tcp", port: 25, tls: false, dnsRecord: { type: "MX" } },
35
35
  ssh: { protocol: "tcp", port: 22, tls: false },
36
36
  imap: { protocol: "tcp", port: 143, tls: false },
37
37
  imaps: { protocol: "tcp", port: 993, tls: true },
@@ -221,25 +221,31 @@ export class Service extends Base {
221
221
  if (dnsRecord) {
222
222
  let parameters = dnsRecord.parameters;
223
223
 
224
- for (const service of this.findServices()) {
225
- if (service !== this) {
226
- const r = ServiceTypes[service.type]?.dnsRecord;
224
+ if (parameters) {
225
+ for (const service of this.findServices()) {
226
+ if (service !== this) {
227
+ const r = ServiceTypes[service.type]?.dnsRecord;
227
228
 
228
- if (r?.type === dnsRecord.type) {
229
- parameters = dnsMergeParameters(parameters, r.parameters);
229
+ if (r?.type === dnsRecord.type) {
230
+ parameters = dnsMergeParameters(parameters, r.parameters);
231
+ }
230
232
  }
231
233
  }
232
- }
233
234
 
234
- records.push(
235
- DNSRecord(
236
- dnsFullName(domainName),
237
- dnsRecord.type,
238
- this.priority,
239
- ".",
240
- dnsFormatParameters(parameters)
241
- )
242
- );
235
+ records.push(
236
+ DNSRecord(
237
+ dnsFullName(domainName),
238
+ dnsRecord.type,
239
+ this.priority,
240
+ ".",
241
+ dnsFormatParameters(parameters)
242
+ )
243
+ );
244
+ } else {
245
+ records.push(
246
+ DNSRecord("@", dnsRecord.type, this.priority, dnsFullName(domainName))
247
+ );
248
+ }
243
249
  }
244
250
 
245
251
  return records;
package/types/host.d.mts CHANGED
@@ -185,6 +185,8 @@ export class Host extends Base {
185
185
  get distribution(): any;
186
186
  get modelName(): any;
187
187
  get hostName(): string;
188
+ get foreignDomainNames(): any[];
189
+ get foreignDomains(): Set<any>;
188
190
  get domains(): Set<any>;
189
191
  get domainNames(): any[];
190
192
  get domainName(): any;