pmcf 3.10.26 → 3.11.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.
Files changed (64) hide show
  1. package/bin/pmcf-info +2 -1
  2. package/package.json +5 -5
  3. package/src/base.mjs +32 -29
  4. package/src/cluster.mjs +3 -2
  5. package/src/host.mjs +3 -5
  6. package/src/location.mjs +1 -0
  7. package/src/network-interfaces/ethernet.mjs +1 -0
  8. package/src/network-interfaces/loopback.mjs +4 -6
  9. package/src/network-interfaces/network-interface.mjs +11 -2
  10. package/src/network-interfaces/tun.mjs +1 -1
  11. package/src/network-interfaces/wireguard.mjs +1 -1
  12. package/src/network-interfaces/wlan.mjs +1 -0
  13. package/src/network-support.mjs +8 -3
  14. package/src/network.mjs +2 -1
  15. package/src/owner.mjs +3 -1
  16. package/src/root.mjs +1 -3
  17. package/src/service-owner.mjs +11 -3
  18. package/src/service.mjs +4 -2
  19. package/src/services/bind.mjs +6 -3
  20. package/src/services/chrony.mjs +4 -6
  21. package/src/services/headscale.mjs +1 -1
  22. package/src/services/influxdb.mjs +1 -0
  23. package/src/services/kea.mjs +14 -12
  24. package/src/services/mosquitto.mjs +1 -0
  25. package/src/services/openldap.mjs +1 -0
  26. package/src/services/systemd-journal-remote.mjs +1 -1
  27. package/src/services/systemd-journal-upload.mjs +1 -0
  28. package/src/services/systemd-journal.mjs +2 -2
  29. package/src/services/systemd-resolved.mjs +8 -6
  30. package/src/services/systemd-timesyncd.mjs +7 -7
  31. package/src/subnet.mjs +3 -1
  32. package/src/types.mjs +16 -38
  33. package/types/base.d.mts +5 -3
  34. package/types/cluster.d.mts +56 -10
  35. package/types/extra-source-service.d.mts +510 -9
  36. package/types/host.d.mts +20 -7
  37. package/types/location.d.mts +71 -6
  38. package/types/network-interfaces/ethernet.d.mts +630 -26
  39. package/types/network-interfaces/loopback.d.mts +629 -27
  40. package/types/network-interfaces/network-interface.d.mts +628 -26
  41. package/types/network-interfaces/tun.d.mts +629 -27
  42. package/types/network-interfaces/wireguard.d.mts +629 -27
  43. package/types/network-interfaces/wlan.d.mts +947 -40
  44. package/types/network-support.d.mts +54 -11
  45. package/types/network.d.mts +324 -8
  46. package/types/owner.d.mts +35 -3
  47. package/types/root.d.mts +71 -8
  48. package/types/service-owner.d.mts +1 -0
  49. package/types/service.d.mts +363 -13
  50. package/types/services/bind.d.mts +706 -23
  51. package/types/services/chrony.d.mts +689 -15
  52. package/types/services/headscale.d.mts +689 -15
  53. package/types/services/influxdb.d.mts +527 -14
  54. package/types/services/kea.d.mts +539 -18
  55. package/types/services/mosquitto.d.mts +530 -15
  56. package/types/services/openldap.d.mts +524 -13
  57. package/types/services/systemd-journal-remote.d.mts +524 -14
  58. package/types/services/systemd-journal-upload.d.mts +524 -13
  59. package/types/services/systemd-journal.d.mts +524 -14
  60. package/types/services/systemd-resolved.d.mts +689 -15
  61. package/types/services/systemd-timesyncd.d.mts +763 -90
  62. package/types/subnet.d.mts +14 -0
  63. package/src/filter.mjs +0 -91
  64. package/types/filter.d.mts +0 -1
package/bin/pmcf-info CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { prepare } from "../src/cli.mjs";
3
+
3
4
  const { root, args, options } = await prepare({
4
5
  service: {
5
6
  type: "string"
@@ -12,7 +13,7 @@ const { root, args, options } = await prepare({
12
13
  for (const name of args) {
13
14
  const object = await root.load(name);
14
15
  if (options.service) {
15
- for (const service of root.findServices({ type: options.service })) {
16
+ for (const service of root.findServices(`type="${options.service}"`)) {
16
17
  console.log(service.toString());
17
18
  }
18
19
  } else if (options.address) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmcf",
3
- "version": "3.10.26",
3
+ "version": "3.11.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -52,8 +52,8 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "ip-utilties": "^1.4.9",
55
- "npm-pkgbuild": "^18.3.0",
56
- "pacc": "^4.29.0",
55
+ "npm-pkgbuild": "^18.3.7",
56
+ "pacc": "^4.37.7",
57
57
  "package-directory": "^8.1.0"
58
58
  },
59
59
  "devDependencies": {
@@ -61,11 +61,11 @@
61
61
  "ava": "^6.4.1",
62
62
  "c8": "^10.1.3",
63
63
  "documentation": "^14.0.3",
64
- "semantic-release": "^24.2.8",
64
+ "semantic-release": "^24.2.9",
65
65
  "typescript": "^5.9.2"
66
66
  },
67
67
  "engines": {
68
- "node": ">=22.19.0"
68
+ "node": ">=22.20.0"
69
69
  },
70
70
  "repository": {
71
71
  "type": "git",
package/src/base.mjs CHANGED
@@ -3,7 +3,6 @@ import { allOutputs } from "npm-pkgbuild";
3
3
  import {
4
4
  parse,
5
5
  expand,
6
- baseTypes,
7
6
  attributeIterator,
8
7
  name_attribute_writable,
9
8
  string_attribute,
@@ -18,7 +17,7 @@ import { asArray } from "./utils.mjs";
18
17
 
19
18
  const BaseTypeDefinition = {
20
19
  name: "base",
21
- owners: [],
20
+ key: "name",
22
21
  attributes: {
23
22
  owner: { type: "base", collection: false, writable: false },
24
23
  type: string_attribute,
@@ -77,19 +76,21 @@ export class Base {
77
76
  }
78
77
  }
79
78
 
80
- ownerFor(property, data) {
81
- for (const type of property.type[0].owners) {
82
- if (this.typeName === type?.name) {
83
- return this;
79
+ ownerFor(attribute, data) {
80
+ const owners = attribute.type.owners;
81
+ if (owners) {
82
+ for (const type of owners) {
83
+ if (this.typeName === type?.name) {
84
+ return this;
85
+ }
84
86
  }
85
- }
86
- for (const type of property.type[0].owners) {
87
- const owner = this[type?.name];
88
- if (owner) {
89
- return owner;
87
+ for (const type of owners) {
88
+ const owner = this[type?.name];
89
+ if (owner) {
90
+ return owner;
91
+ }
90
92
  }
91
93
  }
92
-
93
94
  return this;
94
95
  }
95
96
 
@@ -145,7 +146,7 @@ export class Base {
145
146
  };
146
147
 
147
148
  const instantiateAndAssign = (name, attribute, value) => {
148
- if (baseTypes.has(attribute.type[0])) {
149
+ if (attribute.type.primitive) {
149
150
  assign(name, attribute, value);
150
151
  return;
151
152
  }
@@ -164,7 +165,7 @@ export class Base {
164
165
  {
165
166
  let object;
166
167
 
167
- for (const type of attribute.type) {
168
+ for (const type of attribute.type.members || [attribute.type]) {
168
169
  object = this.typeNamed(type.name, value);
169
170
  if (object) {
170
171
  break;
@@ -174,8 +175,8 @@ export class Base {
174
175
  if (object) {
175
176
  assign(name, attribute, object);
176
177
  } else {
177
- if (attribute.type[0].constructWithIdentifierOnly) {
178
- object = new attribute.type[0].clazz(
178
+ if (attribute.type.constructWithIdentifierOnly) {
179
+ object = new attribute.type.clazz(
179
180
  this.ownerFor(attribute, value),
180
181
  value
181
182
  );
@@ -185,7 +186,9 @@ export class Base {
185
186
  this.finalize(() => {
186
187
  value = this.expand(value);
187
188
 
188
- for (const type of attribute.type) {
189
+ for (const type of attribute.type.members || [
190
+ attribute.type
191
+ ]) {
189
192
  const object =
190
193
  this.typeNamed(type.name, value) ||
191
194
  this.owner.typeNamed(type.name, value) ||
@@ -209,14 +212,14 @@ export class Base {
209
212
  }
210
213
  break;
211
214
  case "object":
212
- if (value instanceof attribute.type[0].clazz) {
215
+ if (attribute.type.clazz && value instanceof attribute.type.clazz) {
213
216
  assign(name, attribute, value);
214
217
  } else {
215
218
  assign(
216
219
  name,
217
220
  attribute,
218
221
  typeFactory(
219
- attribute.type[0],
222
+ attribute.type,
220
223
  this.ownerFor(attribute, value),
221
224
  value
222
225
  )
@@ -247,7 +250,8 @@ export class Base {
247
250
  } else {
248
251
  for (const [objectName, objectData] of Object.entries(value)) {
249
252
  if (typeof objectData === "object") {
250
- objectData[type.identifier.name] = objectName;
253
+ //console.log("KEY", objectName, type.name, type.key);
254
+ objectData[attribute.type.key] = objectName;
251
255
  }
252
256
  instantiateAndAssign(name, attribute, objectData);
253
257
  }
@@ -404,7 +408,7 @@ export class Base {
404
408
  }
405
409
 
406
410
  get smtp() {
407
- return this.findService({ type: "smtp" });
411
+ return this.findService('type="smtp"');
408
412
  }
409
413
 
410
414
  expression(expression) {
@@ -428,9 +432,7 @@ export class Base {
428
432
  }
429
433
 
430
434
  *findServices(filter) {
431
- if (this.owner) {
432
- yield* this.owner.findServices(filter);
433
- }
435
+ yield* this.owner?.findServices(filter);
434
436
  }
435
437
 
436
438
  set directory(directory) {
@@ -587,12 +589,12 @@ export function extractFrom(
587
589
  return undefined;
588
590
  }
589
591
 
590
- if (typeDefinition?.identifier) {
592
+ if (typeDefinition?.key) {
591
593
  return Object.fromEntries(
592
594
  object.map(o => {
593
595
  o = extractFrom(o);
594
- const name = o[typeDefinition.identifier.name];
595
- delete o[typeDefinition.identifier.name];
596
+ const name = o[typeDefinition.key];
597
+ delete o[typeDefinition.key];
596
598
  return [name, o];
597
599
  })
598
600
  );
@@ -604,7 +606,8 @@ export function extractFrom(
604
606
  const json = {};
605
607
 
606
608
  do {
607
- for (const [name, def] of Object.entries(typeDefinition.attributes)) {
609
+ for (const [path, def] of attributeIterator(typeDefinition.attributes)) {
610
+ const name = path.join(".");
608
611
  let value = object[name];
609
612
 
610
613
  switch (typeof value) {
@@ -616,7 +619,7 @@ export function extractFrom(
616
619
  value = [...value];
617
620
  }
618
621
 
619
- value = extractFrom(value, def.type[0]);
622
+ value = extractFrom(value, def.type);
620
623
  if (value !== undefined) {
621
624
  json[name] = value;
622
625
  }
package/src/cluster.mjs CHANGED
@@ -12,6 +12,7 @@ const ClusterTypeDefinition = {
12
12
  owners: [Owner.typeDefinition, "network", "location", "root"],
13
13
  priority: 0.7,
14
14
  extends: Host.typeDefinition,
15
+ key: "name",
15
16
  attributes: {
16
17
  routerId: number_attribute_writable,
17
18
  masters: { type: "network_interface", collection: true, writable: true },
@@ -155,8 +156,8 @@ export class Cluster extends Host {
155
156
 
156
157
  for (const member of this.members) {
157
158
  const memberService =
158
- member.findService({ type: endpoint.type }) ||
159
- member.host.findService({ type: endpoint.type }); // TODO
159
+ member.findService(`type="${endpoint.type}"`) ||
160
+ member.host.findService(`type="${endpoint.type}"`); // TODO
160
161
 
161
162
  cfg.push(` real_server ${member.address} ${memberService.port} {`);
162
163
  cfg.push(` weight ${memberService.weight}`);
package/src/host.mjs CHANGED
@@ -6,7 +6,8 @@ import {
6
6
  string_attribute_writable,
7
7
  string_collection_attribute_writable,
8
8
  number_attribute_writable,
9
- boolean_attribute_false
9
+ boolean_attribute_false,
10
+ name_attribute
10
11
  } from "pacc";
11
12
  import { ServiceOwner, Base, addresses } from "pmcf";
12
13
  import { networkAddressAttributes } from "./network-support.mjs";
@@ -28,6 +29,7 @@ const HostTypeDefinition = {
28
29
  priority: 0.5,
29
30
  owners: ["owner", "network", "root"],
30
31
  extends: Base.typeDefinition,
32
+ key: "name",
31
33
  attributes: {
32
34
  ...networkAddressAttributes,
33
35
  networkInterfaces: {
@@ -457,10 +459,6 @@ export class Host extends ServiceOwner {
457
459
  { base: this.directory, pattern: "*_key" },
458
460
  { destination: "/etc/ssh/", mode: 0o600 }
459
461
  ),
460
- new FileContentProvider(
461
- { base: this.directory, pattern: "credential.secret" },
462
- { destination: "/var/lib/systemd/", mode: 0o400 }
463
- ),
464
462
  new FileContentProvider(dir + "/")
465
463
  ],
466
464
  outputs: this.outputs,
package/src/location.mjs CHANGED
@@ -9,6 +9,7 @@ const LocationTypeDefinition = {
9
9
  owners: [Owner.typeDefinition, "location", "root"],
10
10
  priority: 1.0,
11
11
  extends: Owner.typeDefinition,
12
+ key: "name",
12
13
  attributes: {
13
14
  locales: string_collection_attribute_writable
14
15
  }
@@ -10,6 +10,7 @@ export const EthernetNetworkInterfaceTypeDefinition = {
10
10
  owners: NetworkInterfaceTypeDefinition.owners,
11
11
  extends: NetworkInterfaceTypeDefinition,
12
12
  priority: 0.1,
13
+ key: "name",
13
14
  attributes: {
14
15
  arpbridge: { type: "network_interface", collection: true, writable: true }
15
16
  }
@@ -9,7 +9,7 @@ const LoopbackNetworkInterfaceTypeDefinition = {
9
9
  owners: NetworkInterfaceTypeDefinition.owners,
10
10
  extends: NetworkInterfaceTypeDefinition,
11
11
  priority: 0.1,
12
- attributes: {}
12
+ key: "name"
13
13
  };
14
14
 
15
15
  const _localAddresses = new Map([
@@ -28,8 +28,7 @@ export class LoopbackNetworkInterface extends SkeletonNetworkInterface {
28
28
  return LoopbackNetworkInterfaceTypeDefinition;
29
29
  }
30
30
 
31
- static isCommonName(name)
32
- {
31
+ static isCommonName(name) {
33
32
  return name.match(/lo\d+$/);
34
33
  }
35
34
 
@@ -58,10 +57,9 @@ export class LoopbackNetworkInterface extends SkeletonNetworkInterface {
58
57
  return _localAddresses;
59
58
  }
60
59
 
61
- set mtu(v) {}
60
+ set mtu(v) {}
62
61
 
63
- get mtu()
64
- {
62
+ get mtu() {
65
63
  return 16436;
66
64
  }
67
65
  }
@@ -9,6 +9,7 @@ import {
9
9
  import { asArray, writeLines, sectionLines } from "../utils.mjs";
10
10
  import { addType } from "../types.mjs";
11
11
  import { SkeletonNetworkInterface } from "./skeleton.mjs";
12
+ import { Network } from "../network.mjs";
12
13
 
13
14
  export const NetworkInterfaceTypeDefinition = {
14
15
  name: "network_interface",
@@ -19,6 +20,7 @@ export const NetworkInterfaceTypeDefinition = {
19
20
  factoryFor(owner, value) {
20
21
  let t = NetworkInterfaceTypeDefinition.specializations[value.kind];
21
22
 
23
+ //console.log("factoryFor", owner, value);
22
24
  if (!t) {
23
25
  for (t of Object.values(NetworkInterfaceTypeDefinition.specializations)) {
24
26
  if (t.clazz.isCommonName && t.clazz.isCommonName(value.name)) {
@@ -35,6 +37,7 @@ export const NetworkInterfaceTypeDefinition = {
35
37
 
36
38
  return NetworkInterface;
37
39
  },
40
+ key: "name",
38
41
  attributes: {
39
42
  ...networkAttributes,
40
43
  ...networkAddressAttributes,
@@ -43,7 +46,11 @@ export const NetworkInterfaceTypeDefinition = {
43
46
  hostName: { ...hostname_attribute, writable: true },
44
47
  ipAddresses: { ...string_attribute_writable },
45
48
  hwaddr: { ...string_attribute_writable },
46
- network: { type: "network", collection: false, writable: true },
49
+ network: {
50
+ type: Network.typeDefinition,
51
+ collection: false,
52
+ writable: true
53
+ },
47
54
  destination: { ...string_attribute_writable }
48
55
  }
49
56
  };
@@ -211,7 +218,9 @@ export class NetworkInterface extends SkeletonNetworkInterface {
211
218
 
212
219
  const routeSectionExtra = this.destination
213
220
  ? { Destination: this.destination }
214
- : this.gateway ? { Gateway: this.gatewayAddress } : {};
221
+ : this.gateway
222
+ ? { Gateway: this.gatewayAddress }
223
+ : {};
215
224
 
216
225
  const networkSectionExtra = this.arpbridge
217
226
  ? {
@@ -8,7 +8,7 @@ const TUNdNetworkInterfaceTypeDefinition = {
8
8
  owners: NetworkInterfaceTypeDefinition.owners,
9
9
  extends: NetworkInterfaceTypeDefinition,
10
10
  priority: 0.1,
11
- attributes: {}
11
+ key: "name"
12
12
  };
13
13
 
14
14
  export class TUNNetworkInterface extends NetworkInterface {
@@ -8,7 +8,7 @@ const WireguardNetworkInterfaceTypeDefinition = {
8
8
  owners: NetworkInterfaceTypeDefinition.owners,
9
9
  extends: NetworkInterfaceTypeDefinition,
10
10
  priority: 0.1,
11
- attributes: {}
11
+ key: "name"
12
12
  };
13
13
 
14
14
  export class WireguardNetworkInterface extends SkeletonNetworkInterface {
@@ -15,6 +15,7 @@ const WLANNetworkInterfaceTypeDefinition = {
15
15
  owners: EthernetNetworkInterfaceTypeDefinition.owners,
16
16
  extends: EthernetNetworkInterfaceTypeDefinition,
17
17
  priority: 0.1,
18
+ key: "name",
18
19
  attributes: {
19
20
  ssid: string_attribute_writable,
20
21
  psk: { ...secret_attribute, writable: true },
@@ -1,4 +1,6 @@
1
1
  import {
2
+ oneOfType,
3
+ default_attribute_writable,
2
4
  string_collection_attribute_writable,
3
5
  string_attribute_writable,
4
6
  number_attribute_writable,
@@ -6,7 +8,10 @@ import {
6
8
  boolean_attribute_writable
7
9
  } from "pacc";
8
10
 
9
- export const networkAddressType = ["network", "host", "network_interface"];
11
+ export const networkAddressType = oneOfType("network|host|network_interface");
12
+ //export const networkAddressType = oneOfType([NetworkTypeDefinition,"host","network_interface"]);
13
+
14
+ export const networks_attribute = { ...default_attribute_writable, type: "network", collection: true };
10
15
 
11
16
  export const networkAttributes = {
12
17
  scope: {
@@ -27,13 +32,13 @@ export const networkAttributes = {
27
32
  secretName: string_attribute_writable,
28
33
  metric: { ...number_attribute_writable /*default: 1004*/ },
29
34
  mtu: { ...number_attribute_writable, default: 1500 },
30
- gateway: { type: "host", collection: false, writable: true },
35
+ gateway: { ...default_attribute_writable, type: "host" },
31
36
  multicastDNS: boolean_attribute_writable
32
37
  };
33
38
 
34
39
  export const networkAddressAttributes = {
35
40
  hostName: { ...hostname_attribute, writable: true },
36
- cidrAddresses: string_collection_attribute_writable ,
41
+ cidrAddresses: string_collection_attribute_writable,
37
42
  cidrAddress: string_attribute_writable,
38
43
  addresses: string_collection_attribute_writable,
39
44
  address: string_attribute_writable
package/src/network.mjs CHANGED
@@ -4,11 +4,12 @@ import { Subnet } from "./subnet.mjs";
4
4
  import { addType } from "./types.mjs";
5
5
  import { networkAttributes } from "./network-support.mjs";
6
6
 
7
- const NetworkTypeDefinition = {
7
+ export const NetworkTypeDefinition = {
8
8
  name: "network",
9
9
  owners: ["location", "owner", "root"],
10
10
  priority: 0.8,
11
11
  extends: Owner.typeDefinition,
12
+ key: "name",
12
13
  attributes: {
13
14
  ...networkAttributes,
14
15
  bridge: {
package/src/owner.mjs CHANGED
@@ -8,14 +8,16 @@ import { asIterator } from "./utils.mjs";
8
8
  import { Base } from "./base.mjs";
9
9
  import { Subnet, SUBNET_GLOBAL_IPV4, SUBNET_GLOBAL_IPV6 } from "./subnet.mjs";
10
10
  import { addType, types } from "./types.mjs";
11
+ import { networks_attribute } from "./network-support.mjs";
11
12
 
12
13
  const OwnerTypeDefinition = {
13
14
  name: "owner",
14
15
  owners: ["location", "owner", "root"],
15
16
  priority: 0.9,
16
17
  extends: Base.typeDefinition,
18
+ key: "name",
17
19
  attributes: {
18
- networks: { type: "network", collection: true, writable: true },
20
+ networks: networks_attribute,
19
21
  hosts: { type: "host", collection: true, writable: true },
20
22
  clusters: { type: "cluster", collection: true, writable: true },
21
23
  subnets: { type: Subnet.typeDefinition, collection: true, writable: true },
package/src/root.mjs CHANGED
@@ -5,10 +5,8 @@ import { addType, types, resolveTypeLinks, typeFactory } from "./types.mjs";
5
5
 
6
6
  const RootTypeDefinition = {
7
7
  name: "root",
8
- owners: [],
9
8
  priority: 1000,
10
- extends: Location.typeDefinition,
11
- attributes: {}
9
+ extends: Location.typeDefinition
12
10
  };
13
11
 
14
12
  export class Root extends Location {
@@ -1,6 +1,4 @@
1
1
  import { Base } from "pmcf";
2
- import { objectFilter } from "./filter.mjs";
3
- import { types } from "./types.mjs";
4
2
 
5
3
  export class ServiceOwner extends Base {
6
4
  _services = [];
@@ -18,7 +16,13 @@ export class ServiceOwner extends Base {
18
16
  }
19
17
 
20
18
  *findServices(filter) {
21
- yield* objectFilter(types.service, this._services, filter);
19
+ const services = filter
20
+ ? this.expression(`services[${filter}]`)
21
+ : this.services;
22
+
23
+ for (const service of services) {
24
+ yield service;
25
+ }
22
26
  }
23
27
 
24
28
  _traverse(...args) {
@@ -40,6 +44,10 @@ export class ServiceOwner extends Base {
40
44
  }
41
45
  }
42
46
 
47
+ if (typeName === "number") {
48
+ throw new Error("invalidType");
49
+ }
50
+ //console.log("TN***",typeName, name);
43
51
  return super.typeNamed(typeName, name);
44
52
  }
45
53
 
package/src/service.mjs CHANGED
@@ -41,12 +41,13 @@ export const EndpointTypeDefinition = {
41
41
  owners: ["service", "network_interface"],
42
42
  priority: 0.4,
43
43
  specializations: {},
44
+ key: "type",
44
45
  attributes: endpointAttributes
45
46
  };
46
47
 
47
48
  export const ServiceTypeDefinition = {
48
49
  name: "service",
49
- owners: ["host", "cluster", "network_interface"],
50
+ owners: [Host.typeDefinition, "cluster", "network_interface"],
50
51
  priority: 0.4,
51
52
  extends: Base.typeDefinition,
52
53
  specializations: {},
@@ -61,6 +62,7 @@ export const ServiceTypeDefinition = {
61
62
 
62
63
  return Service;
63
64
  },
65
+ key: "name",
64
66
  attributes: {
65
67
  ...networkAddressAttributes,
66
68
  ...endpointAttributes,
@@ -193,7 +195,7 @@ export class Service extends Base {
193
195
 
194
196
  address(
195
197
  options = {
196
- endpoints: e => e.networkInterface?.kind !== "loopbak",
198
+ endpoints: e => e.networkInterface && e.networkInterface.kind !== "loopbak",
197
199
  select: e => e.domainName || e.address,
198
200
  limit: 1,
199
201
  join: ""
@@ -3,6 +3,7 @@ import { createHmac } from "node:crypto";
3
3
  import { FileContentProvider } from "npm-pkgbuild";
4
4
  import { isLinkLocal, reverseArpa } from "ip-utilties";
5
5
  import {
6
+ oneOfType,
6
7
  string_attribute_writable,
7
8
  boolean_attribute_writable_true,
8
9
  boolean_attribute_writable_false,
@@ -33,9 +34,10 @@ const BindServiceTypeDefinition = {
33
34
  owners: ServiceTypeDefinition.owners,
34
35
  extends: ExtraSourceServiceTypeDefinition,
35
36
  priority: 0.1,
37
+ key: "name",
36
38
  attributes: {
37
39
  zones: {
38
- type: [...networkAddressType, "location", "owner"],
40
+ type: oneOfType([networkAddressType, "location", "owner"]),
39
41
  collection: true,
40
42
  writable: true
41
43
  },
@@ -226,7 +228,8 @@ export class BindService extends ExtraSourceService {
226
228
  };
227
229
 
228
230
  const forwarders = serviceEndpoints(this.source, {
229
- services: { types: "dns", priority: ">=300" },
231
+ services: 'type="dns" && priority>=100 && priority<200',
232
+ endpoints: endpoint => endpoint.family !== "dns",
230
233
  select: e => e.address,
231
234
  limit: 5
232
235
  });
@@ -540,7 +543,7 @@ export class BindService extends ExtraSourceService {
540
543
  }
541
544
 
542
545
  get defaultRecords() {
543
- const nameService = this.findService({ types: "dns", priority: ">=300" });
546
+ const nameService = this.findService('(type="dns" || type="bind") && priority>=300'); // TODO bind = dns ?
544
547
 
545
548
  const SOARecord = DNSRecord(
546
549
  "@",
@@ -19,7 +19,7 @@ const ChronyServiceTypeDefinition = {
19
19
  owners: ServiceTypeDefinition.owners,
20
20
  extends: ExtraSourceServiceTypeDefinition,
21
21
  priority: 0.1,
22
- attributes: {},
22
+ key: "name",
23
23
  service: {
24
24
  extends: ["ntp"],
25
25
  services: {
@@ -87,15 +87,13 @@ export class ChronyService extends ExtraSourceService {
87
87
 
88
88
  const lines = [
89
89
  ...serviceEndpoints(this, {
90
- services: {
91
- types: "ntp",
92
- priority: ">=100"
93
- },
90
+ services: 'type="ntp" && priority>=100',
94
91
  endpoints: e =>
95
92
  e.type === "ntp" &&
96
93
  !isLinkLocal(e.address) &&
97
94
  e.service.host !== host &&
98
- e.networkInterface?.kind !== "loopback",
95
+ e.networkInterface &&
96
+ e.networkInterface.kind !== "loopback",
99
97
 
100
98
  select: endpoint => {
101
99
  const options = [
@@ -11,7 +11,7 @@ const HeadscaleServiceTypeDefinition = {
11
11
  owners: ServiceTypeDefinition.owners,
12
12
  extends: ExtraSourceServiceTypeDefinition,
13
13
  priority: 0.1,
14
- attributes: {},
14
+ key: "name",
15
15
  service: {
16
16
  endpoints: [
17
17
  {
@@ -11,6 +11,7 @@ const InfluxdbServiceTypeDefinition = {
11
11
  owners: ServiceTypeDefinition.owners,
12
12
  extends: ServiceTypeDefinition,
13
13
  priority: 0.1,
14
+ key: "name",
14
15
  attributes: {
15
16
  "metrics-disabled": {
16
17
  ...boolean_attribute_writable_true,