pmcf 4.19.1 → 4.20.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 (82) hide show
  1. package/README.md +93 -72
  2. package/bin/pmcf-diagram +1 -1
  3. package/package.json +19 -19
  4. package/src/base.mjs +24 -237
  5. package/src/cli.mjs +4 -4
  6. package/src/cluster.mjs +15 -13
  7. package/src/extra-source-service.mjs +7 -10
  8. package/src/host.mjs +30 -44
  9. package/src/initialization-context.mjs +324 -0
  10. package/src/location.mjs +4 -14
  11. package/src/module.mjs +1 -0
  12. package/src/network-interfaces/ethernet.mjs +3 -5
  13. package/src/network-interfaces/loopback.mjs +2 -4
  14. package/src/network-interfaces/network-interface.mjs +3 -5
  15. package/src/network-interfaces/skeleton.mjs +9 -3
  16. package/src/network-interfaces/tun.mjs +2 -4
  17. package/src/network-interfaces/wireguard.mjs +3 -5
  18. package/src/network-interfaces/wlan.mjs +4 -7
  19. package/src/network.mjs +10 -8
  20. package/src/owner.mjs +8 -32
  21. package/src/root.mjs +4 -73
  22. package/src/service-owner.mjs +19 -18
  23. package/src/service.mjs +13 -18
  24. package/src/services/alpm.mjs +4 -9
  25. package/src/services/bind.mjs +424 -388
  26. package/src/services/chrony.mjs +3 -5
  27. package/src/services/headscale.mjs +2 -4
  28. package/src/services/influxdb.mjs +2 -4
  29. package/src/services/kea.mjs +6 -10
  30. package/src/services/mosquitto.mjs +2 -4
  31. package/src/services/openldap.mjs +2 -4
  32. package/src/services/postfix.mjs +2 -4
  33. package/src/services/systemd-journal-remote.mjs +2 -4
  34. package/src/services/systemd-journal-upload.mjs +9 -10
  35. package/src/services/systemd-journald.mjs +2 -4
  36. package/src/services/systemd-resolved.mjs +42 -42
  37. package/src/services/systemd-timesyncd.mjs +9 -13
  38. package/src/services/tailscale.mjs +5 -2
  39. package/src/subnet.mjs +9 -5
  40. package/types/base.d.mts +0 -179
  41. package/types/cli.d.mts +0 -10
  42. package/types/cluster.d.mts +0 -507
  43. package/types/dns-utils.d.mts +0 -14
  44. package/types/endpoint.d.mts +0 -79
  45. package/types/extra-source-service.d.mts +0 -1033
  46. package/types/hooks.d.mts +0 -2
  47. package/types/host-utils.d.mts +0 -1
  48. package/types/host.d.mts +0 -285
  49. package/types/location.d.mts +0 -379
  50. package/types/module.d.mts +0 -36
  51. package/types/network-address.d.mts +0 -41
  52. package/types/network-interfaces/ethernet.d.mts +0 -1189
  53. package/types/network-interfaces/loopback.d.mts +0 -1140
  54. package/types/network-interfaces/network-interface.d.mts +0 -1158
  55. package/types/network-interfaces/skeleton.d.mts +0 -30
  56. package/types/network-interfaces/tun.d.mts +0 -1131
  57. package/types/network-interfaces/wireguard.d.mts +0 -1131
  58. package/types/network-interfaces/wlan.d.mts +0 -1734
  59. package/types/network-support.d.mts +0 -193
  60. package/types/network.d.mts +0 -702
  61. package/types/owner.d.mts +0 -235
  62. package/types/root.d.mts +0 -10
  63. package/types/service-owner.d.mts +0 -14
  64. package/types/service-types.d.mts +0 -246
  65. package/types/service.d.mts +0 -689
  66. package/types/services/alpm.d.mts +0 -805
  67. package/types/services/bind.d.mts +0 -1574
  68. package/types/services/chrony.d.mts +0 -1310
  69. package/types/services/headscale.d.mts +0 -801
  70. package/types/services/influxdb.d.mts +0 -812
  71. package/types/services/kea.d.mts +0 -945
  72. package/types/services/mosquitto.d.mts +0 -876
  73. package/types/services/openldap.d.mts +0 -793
  74. package/types/services/postfix.d.mts +0 -784
  75. package/types/services/systemd-journal-remote.d.mts +0 -1030
  76. package/types/services/systemd-journal-upload.d.mts +0 -932
  77. package/types/services/systemd-journald.d.mts +0 -1317
  78. package/types/services/systemd-resolved.d.mts +0 -1644
  79. package/types/services/systemd-timesyncd.d.mts +0 -1459
  80. package/types/services/tailscale.d.mts +0 -781
  81. package/types/subnet.d.mts +0 -57
  82. package/types/utils.d.mts +0 -37
@@ -11,14 +11,12 @@ const TUNdNetworkInterfaceTypeDefinition = {
11
11
  };
12
12
 
13
13
  export class TUNNetworkInterface extends NetworkInterface {
14
+ static typeDefinition = TUNdNetworkInterfaceTypeDefinition;
15
+
14
16
  static {
15
17
  addType(this);
16
18
  }
17
19
 
18
- static get typeDefinition() {
19
- return TUNdNetworkInterfaceTypeDefinition;
20
- }
21
-
22
20
  get kind() {
23
21
  return TUNdNetworkInterfaceTypeDefinition.name;
24
22
  }
@@ -11,14 +11,12 @@ const WireguardNetworkInterfaceTypeDefinition = {
11
11
  };
12
12
 
13
13
  export class WireguardNetworkInterface extends SkeletonNetworkInterface {
14
+ static typeDefinition = WireguardNetworkInterfaceTypeDefinition;
15
+
14
16
  static {
15
17
  addType(this);
16
18
  }
17
-
18
- static get typeDefinition() {
19
- return WireguardNetworkInterfaceTypeDefinition;
20
- }
21
-
19
+
22
20
  get kind() {
23
21
  return WireguardNetworkInterfaceTypeDefinition.name;
24
22
  }
@@ -26,9 +26,7 @@ const WLANNetworkInterfaceTypeDefinition = {
26
26
  };
27
27
 
28
28
  export class WLANNetworkInterface extends EthernetNetworkInterface {
29
- _ssid;
30
- _psk;
31
- _secretName;
29
+ static typeDefinition = WLANNetworkInterfaceTypeDefinition;
32
30
 
33
31
  static {
34
32
  addType(this);
@@ -38,10 +36,9 @@ export class WLANNetworkInterface extends EthernetNetworkInterface {
38
36
  return name.match(/^wlan\d+$/);
39
37
  }
40
38
 
41
- static get typeDefinition() {
42
- return WLANNetworkInterfaceTypeDefinition;
43
- }
44
-
39
+ _ssid;
40
+ _psk;
41
+ _secretName;
45
42
  get kind() {
46
43
  return WLANNetworkInterfaceTypeDefinition.name;
47
44
  }
package/src/network.mjs CHANGED
@@ -5,6 +5,7 @@ import { networkAttributes } from "./network-support.mjs";
5
5
 
6
6
  export const NetworkTypeDefinition = {
7
7
  name: "network",
8
+ priority: 2,
8
9
  owners: ["location", "owner", "root"],
9
10
  extends: Owner.typeDefinition,
10
11
  key: "name",
@@ -20,19 +21,17 @@ export const NetworkTypeDefinition = {
20
21
  };
21
22
 
22
23
  export class Network extends Owner {
23
- kind;
24
- scope;
25
- metric;
26
- gateway;
27
- _bridge;
24
+ static typeDefinition = NetworkTypeDefinition;
28
25
 
29
26
  static {
30
27
  addType(this);
31
28
  }
32
29
 
33
- static get typeDefinition() {
34
- return NetworkTypeDefinition;
35
- }
30
+ kind;
31
+ scope;
32
+ metric;
33
+ gateway;
34
+ _bridge;
36
35
 
37
36
  get network() {
38
37
  return this;
@@ -83,6 +82,9 @@ export class Network extends Owner {
83
82
  this._secretName = value;
84
83
  }
85
84
 
85
+ /**
86
+ * @return {string}
87
+ */
86
88
  get secretName() {
87
89
  return this._secretName ?? `${this.name}.password`;
88
90
  }
package/src/owner.mjs CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  default_attribute_writable,
4
4
  string_set_attribute_writable,
5
5
  string_attribute_writable,
6
- boolean_attribute_writable_false,
6
+ boolean_attribute_writable,
7
7
  email_attribute,
8
8
  addType,
9
9
  types
@@ -15,6 +15,7 @@ import { networks_attribute } from "./network-support.mjs";
15
15
 
16
16
  const OwnerTypeDefinition = {
17
17
  name: "owner",
18
+ priority: 2,
18
19
  owners: ["location", "owner", "root"],
19
20
  extends: Base.typeDefinition,
20
21
  key: "name",
@@ -38,23 +39,21 @@ const OwnerTypeDefinition = {
38
39
  architectures: string_set_attribute_writable,
39
40
  locales: string_set_attribute_writable,
40
41
  administratorEmail: { ...email_attribute, writable: true },
41
- template: { ...boolean_attribute_writable_false, private: true }
42
+ template: { ...boolean_attribute_writable, private: true }
42
43
  }
43
44
  };
44
45
 
45
46
  const EMPTY = new Map();
46
47
 
47
48
  export class Owner extends Base {
48
- _membersByType = new Map();
49
- _bridges = new Set();
49
+ static typeDefinition = OwnerTypeDefinition;
50
50
 
51
51
  static {
52
52
  addType(this);
53
53
  }
54
54
 
55
- static get typeDefinition() {
56
- return OwnerTypeDefinition;
57
- }
55
+ _membersByType = new Map();
56
+ _bridges = new Set();
58
57
 
59
58
  /**
60
59
  * @return {boolean}
@@ -127,22 +126,13 @@ export class Owner extends Base {
127
126
  return super.typeNamed(typeName, name);
128
127
  }
129
128
 
130
- typeObject(typeName) {
131
- return this._membersByType.get(typeName);
132
- }
133
-
134
129
  typeList(typeName) {
135
130
  const typeSlot = this._membersByType.get(typeName);
136
131
  return (typeSlot || EMPTY).values();
137
132
  }
138
133
 
139
134
  addTypeObject(typeName, name, object) {
140
- let typeSlot = this._membersByType.get(typeName);
141
- if (!typeSlot) {
142
- typeSlot = new Map();
143
- this._membersByType.set(typeName, typeSlot);
144
- }
145
-
135
+ const typeSlot = this._membersByType.getOrInsertComputed(typeName, () => new Map());
146
136
  typeSlot.set(name, object);
147
137
  }
148
138
 
@@ -164,16 +154,6 @@ export class Owner extends Base {
164
154
  return [...this.hosts].map(host=>host.services).flat();
165
155
  }
166
156
 
167
- *findServices(filter) {
168
- for (const host of this.hosts) {
169
- yield* host.findServices(filter);
170
- }
171
- }
172
-
173
- locationNamed(name) {
174
- return this.typeNamed("location", name);
175
- }
176
-
177
157
  get locations() {
178
158
  return this.typeList("location");
179
159
  }
@@ -254,11 +234,7 @@ export class Owner extends Base {
254
234
  }
255
235
  }
256
236
 
257
- clusterNamed(name) {
258
- return this.typeNamed("cluster", name);
259
- }
260
-
261
- clusters() {
237
+ get clusters() {
262
238
  return this.typeList("cluster");
263
239
  }
264
240
 
package/src/root.mjs CHANGED
@@ -1,21 +1,16 @@
1
- import { readFile, glob } from "node:fs/promises";
2
- import { join } from "node:path";
3
- import { typeFactory, addType, types, resolveTypeLinks } from "pacc";
1
+ import { addType } from "pacc";
4
2
  import { Location } from "./location.mjs";
5
3
 
6
4
  export class Root extends Location {
7
5
  static name = "root";
8
-
9
- static get typeDefinition() {
10
- return this;
11
- }
12
-
6
+ static priority = 3;
7
+ static typeDefinition = this;
8
+
13
9
  static {
14
10
  addType(this);
15
11
  }
16
12
 
17
13
  constructor(directory) {
18
- resolveTypeLinks();
19
14
  super(undefined, "");
20
15
  this.directory = directory;
21
16
  this.addObject(this);
@@ -28,68 +23,4 @@ export class Root extends Location {
28
23
  get root() {
29
24
  return this;
30
25
  }
31
-
32
- async _load(name, type) {
33
- const data = JSON.parse(
34
- await readFile(
35
- join(this.directory, name, type.clazz.typeFileName),
36
- "utf8"
37
- )
38
- );
39
-
40
- const parentName = name.replace(/\/[^\/]+$/, "");
41
- const owner = name === parentName ? this.root : await this.load(parentName);
42
-
43
- const fullName = this.fullName + "/" + name;
44
- data.name = fullName.substring(owner.fullName.length + 1);
45
-
46
- const object = typeFactory(type, owner, data);
47
- this.addTypeObject(type.clazz.typeName, name, object);
48
- return object;
49
- }
50
-
51
- async load(name, options) {
52
- name = name.replace(/\/?([^\/]+\.json)?$/, "");
53
-
54
- const object = this.named(name);
55
- if (object) {
56
- return object;
57
- }
58
-
59
- if (options?.type) {
60
- return this._load(name, options.type);
61
- } else {
62
- for (const type of Object.values(types)) {
63
- try {
64
- return await this._load(name, type);
65
- } catch {}
66
- }
67
- }
68
-
69
- const parentName = name.replace(/\/[^\/]$/, "");
70
- return name === parentName ? this.root : this.load(parentName, options);
71
- }
72
-
73
- async loadAll() {
74
- for (const type of Object.values(types).sort(
75
- (a, b) => (b.priority || 1.0) - (a.priority || 1.0)
76
- )) {
77
- if (type.clazz?.typeFileName) {
78
- for await (const name of glob("**/" + type.clazz.typeFileName, {
79
- cwd: this.directory
80
- })) {
81
- if (type === this.constructor) {
82
- const data = JSON.parse(
83
- await readFile(join(this.directory, name), "utf8")
84
- );
85
- this._properties = data.properties;
86
- } else {
87
- await this.load(name, { type });
88
- }
89
- }
90
- }
91
- }
92
-
93
- this.execFinalize();
94
- }
95
26
  }
@@ -3,19 +3,30 @@ import { Base, Service } from "pmcf";
3
3
  export class ServiceOwner extends Base {
4
4
  services = [];
5
5
 
6
- _applyExtends(owner) {
7
- super._applyExtends(owner);
6
+ materializeExtends() {
7
+ super.materializeExtends();
8
8
 
9
- for (const service of owner.services) {
10
- const present = this.services.find(s => s.name === service.name);
9
+ for (const serviceOwner of this.walkDirections(["extends"])) {
10
+ /*console.log(
11
+ "ServiceOwner materializeExtends",
12
+ this.fullName,
13
+ serviceOwner.fullName
14
+ );*/
11
15
 
12
- if (present && service.isTemplate) {
13
- if (present.extends.indexOf(service) < 0) {
16
+ for (const service of serviceOwner.services) {
17
+ const present = this.services.find(s => s.name === service.name);
18
+
19
+ if (present) {
20
+ //console.log("LINK", present.fullName, service.fullName);
14
21
  present.extends.push(service);
22
+ } else {
23
+ this.services.push(service.forOwner(this));
15
24
  }
16
- } else {
17
- this.services.push(service.forOwner(this));
18
25
  }
26
+
27
+ /*for (const service of this.services) {
28
+ service.materializeExtends();
29
+ }*/
19
30
  }
20
31
  }
21
32
 
@@ -30,16 +41,6 @@ export class ServiceOwner extends Base {
30
41
  return false;
31
42
  }
32
43
 
33
- *findServices(filter) {
34
- const services = filter
35
- ? this.expression(`services[${filter}]`)
36
- : this.services;
37
-
38
- for (const service of services) {
39
- yield service;
40
- }
41
- }
42
-
43
44
  typeNamed(typeName, name) {
44
45
  if (typeName === "service") {
45
46
  const service = this.services.find(s => s.name === name);
package/src/service.mjs CHANGED
@@ -41,6 +41,7 @@ export const endpointAttributes = {
41
41
 
42
42
  export const EndpointTypeDefinition = {
43
43
  name: "endpoint",
44
+ priority: 1.1,
44
45
  owners: ["service", "network_interface"],
45
46
  specializations: {},
46
47
  key: "type",
@@ -49,6 +50,7 @@ export const EndpointTypeDefinition = {
49
50
 
50
51
  export const ServiceTypeDefinition = {
51
52
  name: "service",
53
+ priority: 1.1,
52
54
  owners: [Host.typeDefinition, "cluster", "network_interface"],
53
55
  extends: Base.typeDefinition,
54
56
  specializations: {},
@@ -74,19 +76,17 @@ export const ServiceTypeDefinition = {
74
76
  };
75
77
 
76
78
  export class Service extends Base {
77
- _alias;
78
- _weight;
79
- _type;
80
- _port;
81
- _systemdService;
79
+ static typeDefinition = ServiceTypeDefinition;
82
80
 
83
81
  static {
84
82
  addType(this);
85
83
  }
86
84
 
87
- static get typeDefinition() {
88
- return ServiceTypeDefinition;
89
- }
85
+ _alias;
86
+ _weight;
87
+ _type;
88
+ _port;
89
+ _systemdService;
90
90
 
91
91
  toString() {
92
92
  return `${this.fullName}(${this.type})`;
@@ -102,8 +102,7 @@ export class Service extends Base {
102
102
  }
103
103
  }
104
104
 
105
- get hosts()
106
- {
105
+ get hosts() {
107
106
  return this.owner.hosts;
108
107
  }
109
108
 
@@ -123,10 +122,6 @@ export class Service extends Base {
123
122
  return this.endpoint()?.url;
124
123
  }
125
124
 
126
- get services() {
127
- return [this];
128
- }
129
-
130
125
  get serviceTypeEndpoints() {
131
126
  return serviceTypeEndpoints(ServiceTypes[this.type]);
132
127
  }
@@ -242,7 +237,7 @@ export class Service extends Base {
242
237
  }
243
238
 
244
239
  get type() {
245
- return this._type ?? this.name;
240
+ return this.extendedAttribute("_type") ?? this.name;
246
241
  }
247
242
 
248
243
  get types() {
@@ -260,7 +255,7 @@ export class Service extends Base {
260
255
  const packageData = super.packageData;
261
256
  const location = `${this.location.name}-${this.host.name}`;
262
257
  packageData.properties.name = `${this.type}-${location}`;
263
- packageData.properties.description =`${this.type} service definitions for ${this.fullName}`;
258
+ packageData.properties.description = `${this.type} service definitions for ${this.fullName}`;
264
259
  packageData.properties.groups.push("service-config", location);
265
260
  return packageData;
266
261
  }
@@ -305,7 +300,7 @@ export class Service extends Base {
305
300
  let parameters = dnsRecord.parameters;
306
301
 
307
302
  if (parameters) {
308
- for (const service of this.findServices()) {
303
+ for (const service of this.services) {
309
304
  if (service !== this) {
310
305
  const serviceType = ServiceTypes[service.type];
311
306
  /*if(!serviceType) {
@@ -360,7 +355,7 @@ export const sortDescendingByPriority = (a, b) => b.priority - a.priority;
360
355
  */
361
356
  export function serviceEndpoints(sources, options = {}) {
362
357
  const all = asArray(sources)
363
- .map(ft => Array.from(ft.findServices(options.services)))
358
+ .map(source => Array.from(source.expression(options.services)))
364
359
  .flat()
365
360
  .sort(sortDescendingByPriority)
366
361
  .map(service => service.endpoints(options.endpoints))
@@ -20,17 +20,15 @@ const ALPMRepositoryTypeDefinition = {
20
20
  };
21
21
 
22
22
  class ALPMRepository extends Base {
23
+ static typeDefinition = ALPMRepositoryTypeDefinition;
23
24
  static {
24
25
  addType(this);
25
26
  }
26
-
27
- static get typeDefinition() {
28
- return ALPMRepositoryTypeDefinition;
29
- }
30
27
  }
31
28
 
32
29
  const ALPMServiceTypeDefinition = {
33
30
  name: "alpm",
31
+ priority: 1,
34
32
  extends: ServiceTypeDefinition,
35
33
  specializationOf: ServiceTypeDefinition,
36
34
  owners: ServiceTypeDefinition.owners,
@@ -43,20 +41,17 @@ const ALPMServiceTypeDefinition = {
43
41
  },
44
42
 
45
43
  service: {
46
- extends: ["https"]
44
+ extends: ["https", "http"]
47
45
  }
48
46
  };
49
47
 
50
48
  export class ALPMService extends Service {
49
+ static typeDefinition = ALPMServiceTypeDefinition;
51
50
  static {
52
51
  addType(this);
53
52
  addServiceType(this.typeDefinition.service, this.typeDefinition.name);
54
53
  }
55
54
 
56
- static get typeDefinition() {
57
- return ALPMServiceTypeDefinition;
58
- }
59
-
60
55
  repositories = new Map();
61
56
 
62
57
  typeNamed(type, name) {