pmcf 1.46.4 → 1.47.1

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/src/host.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Base } from "./base.mjs";
2
- import { Network } from "./network.mjs";
3
- import { Service } from "./service.mjs";
2
+ import { networkProperties } from "./network-support.mjs";
4
3
  import {
5
4
  asArray,
6
5
  isIPv4Address,
@@ -11,8 +10,41 @@ import {
11
10
  } from "./utils.mjs";
12
11
  import { addType } from "./types.mjs";
13
12
 
13
+ const HostTypeDefinition = {
14
+ name: "host",
15
+ priority: 0.5,
16
+ owners: ["owner", "network", "root"],
17
+ extends: Base.typeDefinition,
18
+ properties: {
19
+ networkInterfaces: {
20
+ type: "network_interface",
21
+ collection: true,
22
+ writeable: true
23
+ },
24
+ services: { type: "service", collection: true, writeable: true },
25
+ os: { type: "string", collection: false, writeable: true },
26
+ distribution: { type: "string", collection: false, writeable: true },
27
+ deployment: { type: "string", collection: false, writeable: true },
28
+ master: { type: "boolean", collection: false, writeable: true },
29
+ model: { type: "string", collection: false, writeable: false },
30
+ serial: { type: "string", collection: false, writeable: true },
31
+ vendor: { type: "string", collection: false, writeable: true },
32
+ chassis: { type: "string", collection: false, writeable: true },
33
+ isModel: { type: "boolean", collection: false, writeable: false },
34
+ priority: { type: "number", collection: false, writeable: true },
35
+ replaces: { type: "string", collection: true, writeable: true },
36
+ depends: { type: "string", collection: true, writeable: true },
37
+ provides: { type: "string", collection: true, writeable: true },
38
+ extends: { type: "host", collection: true, writeable: true },
39
+ cidrAddresses: { type: "string", collection: true, writeable: false },
40
+ rawAddresses: { type: "string", collection: true, writeable: false },
41
+ rawAddress: { type: "string", collection: false, writeable: false }
42
+ }
43
+ };
44
+
14
45
  export class Host extends Base {
15
46
  postinstall = [];
47
+ serial;
16
48
  #services = [];
17
49
  #extends = [];
18
50
  #networkInterfaces = new Map();
@@ -31,91 +63,29 @@ export class Host extends Base {
31
63
  }
32
64
 
33
65
  static get typeDefinition() {
34
- return {
35
- name: "host",
36
- extends: Base,
37
- properties: {
38
- networkInterfaces: { type: "network_interface", collection: true },
39
- services: { type: Service, collection: true },
40
- os: { type: "string" },
41
- distribution: { type: "string" },
42
- deployment: { type: "string" },
43
- master: { type: "boolean" },
44
- model: { type: "string" },
45
- replaces: { type: "string" },
46
- depends: { type: "string" },
47
- cidrAddresses: { type: "string", collection: true, writeable: false },
48
- rawAddresses: { type: "string", collection: true, writeable: false },
49
- rawAddress: { type: "string", writeable: false }
50
- }
51
- };
52
- }
53
-
54
- static async prepareData(root, data) {
55
- if (data.extends) {
56
- data.extends = await Promise.all(
57
- asArray(data.extends).map(e => root.load(e, { type: Host }))
58
- );
59
- }
60
-
61
- return this;
66
+ return HostTypeDefinition;
62
67
  }
63
68
 
64
69
  constructor(owner, data) {
65
70
  super(owner, data);
66
71
 
67
- if (data.deployment !== undefined) {
68
- this.#deployment = data.deployment;
69
- delete data.deployment;
70
- }
71
- if (data.chassis !== undefined) {
72
- this.#chassis = data.chassis;
73
- delete data.chassis;
74
- }
75
- if (data.vendor !== undefined) {
76
- this.#vendor = data.vendor;
77
- delete data.vendor;
78
- }
79
- if (data.extends !== undefined) {
80
- this.#extends = data.extends;
81
- delete data.extends;
82
- }
83
- if (data.os !== undefined) {
84
- this.#os = data.os;
85
- delete data.os;
86
- }
87
- if (data.distribution !== undefined) {
88
- this.#distribution = data.distribution;
89
- delete data.distribution;
90
- }
91
- if (data.master !== undefined) {
92
- this.#master = data.master;
93
- delete data.master;
94
- }
95
- if (data.depends !== undefined) {
96
- this.#depends = new Set(asArray(data.depends));
97
- delete data.depends;
98
- }
99
- if (data.replaces !== undefined) {
100
- this.#replaces = new Set(asArray(data.replaces));
101
- delete data.replaces;
102
- }
103
- if (data.provides !== undefined) {
104
- this.#provides = new Set(asArray(data.provides));
105
- delete data.provides;
106
- }
107
-
108
- for (const host of this.extends) {
109
- for (const service of host.services()) {
110
- service.forOwner(this);
111
- }
112
- }
113
-
114
- this.read(data);
115
-
116
- Object.assign(this, data);
72
+ this.read(data, HostTypeDefinition);
117
73
 
118
74
  owner.addObject(this);
75
+
76
+ if (data.extends) {
77
+ this.finalize(() => {
78
+ for (const host of this.extends) {
79
+ this.depends = host.depends;
80
+ this.provides = host.provides;
81
+ this.replaces = host.replaces;
82
+
83
+ for (const service of host.findServices()) {
84
+ this.services = service.forOwner(this);
85
+ }
86
+ }
87
+ });
88
+ }
119
89
  }
120
90
 
121
91
  _traverse(...args) {
@@ -123,7 +93,7 @@ export class Host extends Base {
123
93
  for (const ni of this.networkInterfaces.values()) {
124
94
  ni._traverse(...args);
125
95
  }
126
- for (const service of this.services()) {
96
+ for (const service of this.findServices()) {
127
97
  service._traverse(...args);
128
98
  }
129
99
 
@@ -132,14 +102,26 @@ export class Host extends Base {
132
102
  return false;
133
103
  }
134
104
 
105
+ set deployment(value) {
106
+ this.#deployment = value;
107
+ }
108
+
135
109
  get deployment() {
136
110
  return this.#deployment || this.extends.find(e => e.deployment)?.deployment;
137
111
  }
138
112
 
113
+ set chassis(value) {
114
+ this.#chassis = value;
115
+ }
116
+
139
117
  get chassis() {
140
118
  return this.#chassis || this.extends.find(e => e.chassis)?.chassis;
141
119
  }
142
120
 
121
+ set vendor(value) {
122
+ this.#vendor = value;
123
+ }
124
+
143
125
  get vendor() {
144
126
  return this.#vendor || this.extends.find(e => e.vendor)?.vendor;
145
127
  }
@@ -152,40 +134,70 @@ export class Host extends Base {
152
134
  return this.extends.find(h => h.isModel);
153
135
  }
154
136
 
137
+ set extends(value) {
138
+ this.#extends.push(value);
139
+ }
140
+
155
141
  get extends() {
156
- return this.#extends.map(e => this.expand(e));
142
+ return this.#extends;
143
+ }
144
+
145
+ set provides(value) {
146
+ if (value instanceof Set) {
147
+ this.#provides = this.#provides.union(value);
148
+ } else {
149
+ this.#provides.add(value);
150
+ }
157
151
  }
158
152
 
159
153
  get provides() {
160
- let provides = new Set(this.#provides);
161
- this.extends.forEach(h => (provides = provides.union(h.provides)));
162
- return provides;
154
+ return this.#provides;
155
+ }
156
+
157
+ set replaces(value) {
158
+ if (value instanceof Set) {
159
+ this.#replaces = this.#replaces.union(value);
160
+ } else {
161
+ this.#replaces.add(value);
162
+ }
163
163
  }
164
164
 
165
165
  get replaces() {
166
- let replaces = new Set(this.#replaces);
167
- this.extends.forEach(h => (replaces = replaces.union(h.replaces)));
168
- return replaces;
166
+ return this.#replaces;
169
167
  }
170
168
 
171
- get _depends() {
172
- let depends = this.#depends;
173
- this.extends.forEach(h => (depends = depends.union(h._depends)));
174
- return depends;
169
+ set depends(value) {
170
+ if (value instanceof Set) {
171
+ this.#depends = this.#depends.union(value);
172
+ } else {
173
+ this.#depends.add(value);
174
+ }
175
175
  }
176
176
 
177
177
  get depends() {
178
- return this.expand(this._depends);
178
+ return this.#depends;
179
+ }
180
+
181
+ set master(value) {
182
+ this.#master = value;
179
183
  }
180
184
 
181
185
  get master() {
182
186
  return this.#master || this.extends.find(e => e.master) ? true : false;
183
187
  }
184
188
 
189
+ set os(value) {
190
+ this.#os = value;
191
+ }
192
+
185
193
  get os() {
186
194
  return this.#os || this.extends.find(e => e.os);
187
195
  }
188
196
 
197
+ set distribution(value) {
198
+ this.#distribution = value;
199
+ }
200
+
189
201
  get distribution() {
190
202
  return this.#distribution || this.extends.find(e => e.distribution);
191
203
  }
@@ -213,15 +225,15 @@ export class Host extends Base {
213
225
  return this;
214
226
  }
215
227
 
216
- get network() {
217
- return this.owner.network;
228
+ get services() {
229
+ return this.#services;
218
230
  }
219
231
 
220
- addService(service) {
221
- this.#services.push(service);
232
+ set services(services) {
233
+ this.#services.push(services);
222
234
  }
223
235
 
224
- *services(filter) {
236
+ *findServices(filter) {
225
237
  for (const service of this.#services) {
226
238
  if (
227
239
  !filter ||
@@ -234,20 +246,24 @@ export class Host extends Base {
234
246
  }
235
247
  }
236
248
 
237
- get networkInterfaces() {
238
- return this.#networkInterfaces;
249
+ typeNamed(typeName, name) {
250
+ if (typeName === NetworkInterfaceTypeDefinition.name) {
251
+ const ni = this.#networkInterfaces.get(name);
252
+ if (ni) {
253
+ return ni;
254
+ }
255
+ }
256
+
257
+ return super.typeNamed(typeName, name);
239
258
  }
240
259
 
241
- networkInterfaceNamed(name) {
242
- return this.#networkInterfaces.get(name);
260
+ get networkInterfaces() {
261
+ return this.#networkInterfaces;
243
262
  }
244
263
 
245
- addNetworkInterface(networkInterface) {
264
+ set networkInterfaces(networkInterface) {
246
265
  this.#networkInterfaces.set(networkInterface.name, networkInterface);
247
-
248
- if (networkInterface.network) {
249
- networkInterface.network.addObject(this);
250
- }
266
+ networkInterface.network?.addObject(this);
251
267
  }
252
268
 
253
269
  *networkAddresses() {
@@ -279,45 +295,32 @@ export class Host extends Base {
279
295
  async publicKey(type = "ed25519") {
280
296
  return readFile(join(this.directory, `ssh_host_${type}_key.pub`), "utf8");
281
297
  }
282
-
283
- toJSON() {
284
- return {
285
- ...super.toJSON(),
286
- extends: this.extends.map(host => host.name),
287
- networkInterfaces: Object.fromEntries(
288
- [...this.networkInterfaces.values()].map(ni => [ni.name, ni.toJSON()])
289
- ),
290
- services: Object.fromEntries(
291
- [...this.services()].map(s => [s.name, s.toJSON()])
292
- )
293
- };
294
- }
295
298
  }
296
299
 
300
+ const NetworkInterfaceTypeDefinition = {
301
+ name: "network_interface",
302
+ priority: 0.4,
303
+ owners: ["host"],
304
+ extends: Base.typeDefinition,
305
+ properties: {
306
+ ...networkProperties,
307
+ hwaddr: { type: "string", collection: false, writeable: true },
308
+ ipAddresses: { type: "string", collection: true, writeable: true },
309
+ cidrAddresses: { type: "string", collection: true, writeable: false },
310
+ rawAddresses: { type: "string", collection: true, writeable: false },
311
+ network: { type: "network", collection: false, writeable: true },
312
+ destination: { type: "string", collection: false, writeable: true },
313
+ arpbridge: { type: "network_interface", collection: true, writeable: true }
314
+ }
315
+ };
316
+
297
317
  export class NetworkInterface extends Base {
298
318
  static {
299
319
  addType(this);
300
320
  }
301
321
 
302
322
  static get typeDefinition() {
303
- return {
304
- name: "network_interface",
305
- extends: Base,
306
- properties: {
307
- hwaddr: { type: "string" },
308
- scope: { type: "string" },
309
- kind: { type: "string" },
310
- ssid: { type: "string" },
311
- psk: { type: "string" },
312
- metric: { type: "number" },
313
- MTU: { type: "number" },
314
- cidrAddresses: { type: "string", collection: true, writeable: false },
315
- rawAddresses: { type: "string", collection: true, writeable: false },
316
- network: { type: "network" },
317
- gateway: {},
318
- arpbridge: {}
319
- }
320
- };
323
+ return NetworkInterfaceTypeDefinition;
321
324
  }
322
325
 
323
326
  #ipAddresses = new Map();
@@ -332,48 +335,7 @@ export class NetworkInterface extends Base {
332
335
 
333
336
  constructor(owner, data) {
334
337
  super(owner, data);
335
-
336
- if (data.ssid) {
337
- this.#ssid = data.ssid;
338
- delete data.ssid;
339
- }
340
- if (data.psk) {
341
- this.#psk = data.psk;
342
- delete data.psk;
343
- }
344
- if (data.scope) {
345
- this.#psk = data.scope;
346
- delete data.scope;
347
- }
348
- if (data.metric) {
349
- this.#metric = data.metric;
350
- delete data.metric;
351
- }
352
- if (data.kind) {
353
- this.#kind = data.kind;
354
- delete data.kind;
355
- }
356
-
357
- if (data.network) {
358
- let network = owner.owner.networkNamed(data.network);
359
-
360
- if (network) {
361
- this.network = network;
362
- } else {
363
- network = data.network;
364
- this.finalize(() => (this.network = network));
365
- }
366
-
367
- delete data.network;
368
- } else if (owner.owner instanceof Network) {
369
- this.network = owner.owner;
370
- }
371
-
372
- Object.assign(this, data);
373
-
374
- owner.addNetworkInterface(this);
375
-
376
- //this.arpbridge = owner.addARPBridge(this, data.arpbridge);
338
+ this.read(data, NetworkInterfaceTypeDefinition);
377
339
  }
378
340
 
379
341
  addSubnet(address) {
@@ -400,7 +362,7 @@ export class NetworkInterface extends Base {
400
362
  }
401
363
 
402
364
  get rawAddresses() {
403
- return [...this.#ipAddresses].map(([address, subnet]) => address);
365
+ return [...this.#ipAddresses].map(([address]) => address);
404
366
  }
405
367
 
406
368
  get cidrAddresses() {
@@ -411,14 +373,14 @@ export class NetworkInterface extends Base {
411
373
 
412
374
  get rawIPv4Addresses() {
413
375
  return [...this.ipAddresses]
414
- .filter(([address, subnet]) => isIPv4Address(address))
415
- .map(([address, subnet]) => address);
376
+ .filter(([address]) => isIPv4Address(address))
377
+ .map(([address]) => address);
416
378
  }
417
379
 
418
380
  get rawIPv6Addresses() {
419
381
  return [...this.ipAddresses]
420
- .filter(([address, subnet]) => isIPv6Address(address))
421
- .map(([address, subnet]) => address);
382
+ .filter(([address]) => isIPv6Address(address))
383
+ .map(([address]) => address);
422
384
  }
423
385
 
424
386
  subnetForAddress(address) {
@@ -444,41 +406,54 @@ export class NetworkInterface extends Base {
444
406
  return this.owner;
445
407
  }
446
408
 
409
+ get network_interface() {
410
+ return this;
411
+ }
412
+
447
413
  get network() {
448
414
  return this.#network || this.host.network;
449
415
  }
450
416
 
451
- set network(networkOrName) {
452
- if (!(networkOrName instanceof Network)) {
453
- let network = this.host.owner.networkNamed(networkOrName);
454
-
455
- if (network) {
456
- this.#network = network;
457
- return;
458
- } else {
459
- this.error("Unknown network", networkOrName);
460
- }
461
- }
417
+ set network(network) {
418
+ this.#network = network;
419
+ }
462
420
 
463
- this.#network = networkOrName;
421
+ set scope(value) {
422
+ this.#scope = value;
464
423
  }
465
424
 
466
425
  get scope() {
467
426
  return this.#scope || this.network?.scope || "global";
468
427
  }
469
428
 
429
+ set metric(value) {
430
+ this.#metric = value;
431
+ }
432
+
470
433
  get metric() {
471
434
  return this.#metric || this.network?.metric || 1004;
472
435
  }
473
436
 
437
+ set ssid(value) {
438
+ this.#ssid = value;
439
+ }
440
+
474
441
  get ssid() {
475
442
  return this.#ssid || this.network?.ssid;
476
443
  }
477
444
 
445
+ set psk(value) {
446
+ this.#psk = value;
447
+ }
448
+
478
449
  get psk() {
479
450
  return this.#psk || this.network?.psk;
480
451
  }
481
452
 
453
+ set kind(value) {
454
+ this.#kind = value;
455
+ }
456
+
482
457
  get kind() {
483
458
  return this.#kind || this.network?.kind;
484
459
  }
package/src/location.mjs CHANGED
@@ -1,38 +1,38 @@
1
1
  import { Owner } from "./owner.mjs";
2
- import { Network } from "./network.mjs";
3
- import { Subnet } from "./subnet.mjs";
4
- import { Host } from "./host.mjs";
5
- import { DNSService } from "./dns.mjs";
6
- import { Cluster } from "./cluster.mjs";
7
2
  import { addType } from "./types.mjs";
8
3
 
4
+ const LocationTypeDefinition = {
5
+ name: "location",
6
+ owners: [Owner.typeDefinition, "location", "root"],
7
+ priority: 1.0,
8
+ extends: Owner.typeDefinition,
9
+ properties: {
10
+ country: { type: "string", writeable: true },
11
+ locales: { type: "string", collection: true, writeable: true }
12
+ }
13
+ };
14
+
9
15
  export class Location extends Owner {
10
16
  static {
11
17
  addType(this);
12
18
  }
13
19
 
14
20
  static get typeDefinition() {
15
- return {
16
- name: "location",
17
- extends: Owner,
18
- properties: {
19
- networks: { type: Network, collection: true },
20
- hosts: { type: Host, collection: true },
21
- clusters: { type: Cluster, collection: true },
22
- subnets: { type: Subnet, collection: true },
23
- dns: { type: DNSService },
24
- country: { type: "string" },
25
- locales: { type: "string", collection: true }
26
- }
27
- };
21
+ return LocationTypeDefinition;
22
+ }
23
+
24
+ constructor(owner, data) {
25
+ super(owner, data);
26
+ this.read(data, LocationTypeDefinition);
28
27
  }
29
28
 
30
29
  get location() {
31
30
  return this;
32
31
  }
33
32
 
33
+
34
34
  locationNamed(name) {
35
- if (this.fullName === name) {
35
+ if (this.isNamed(name)) {
36
36
  return this;
37
37
  }
38
38
 
@@ -0,0 +1,9 @@
1
+ export const networkProperties = {
2
+ scope: { type: "string", collection: false, writeable: true },
3
+ kind: { type: "string", collection: false, writeable: true },
4
+ ssid: { type: "string", collection: false, writeable: true },
5
+ psk: { type: "string", collection: false, writeable: true },
6
+ metric: { type: "number", collection: false, writeable: true },
7
+ MTU: { type: "number", collection: false, writeable: true },
8
+ gateway: { type: "host", collection: false, writeable: true }
9
+ };
package/src/network.mjs CHANGED
@@ -1,8 +1,19 @@
1
1
  import { Owner } from "./owner.mjs";
2
2
  import { Subnet } from "./subnet.mjs";
3
- import { Host } from "./host.mjs";
4
- import { DNSService } from "./dns.mjs";
5
3
  import { addType } from "./types.mjs";
4
+ import { networkProperties } from "./network-support.mjs";
5
+
6
+ const NetworkTypeDefinition = {
7
+ name: "network",
8
+ owners: ["location", "cluster", "owner", "root"],
9
+ priority: 0.8,
10
+ extends: Owner.typeDefinition,
11
+ properties: {
12
+ ...networkProperties,
13
+ bridge: { type: "network", collection: true, writeable: true },
14
+ gateway: { type: "host", collection: false, writeable: true }
15
+ }
16
+ };
6
17
 
7
18
  export class Network extends Owner {
8
19
  kind;
@@ -16,39 +27,12 @@ export class Network extends Owner {
16
27
  }
17
28
 
18
29
  static get typeDefinition() {
19
- return {
20
- name: "network",
21
- extends: Owner,
22
- properties: {
23
- networks: { type: "network", collection: true },
24
- hosts: { type: Host, collection: true },
25
- clusters: { type: "cluster", collection: true },
26
- subnets: { type: Subnet, collection: true },
27
- dns: { type: DNSService, collection: false }
28
- //metric: { type: "number" }
29
- /*kind: { type: "string" },
30
- scope: { type: "string" },
31
- /*bridge: {},
32
- gateway: {}*/
33
- }
34
- };
30
+ return NetworkTypeDefinition;
35
31
  }
36
32
 
37
33
  constructor(owner, data) {
38
34
  super(owner, data);
39
-
40
- if (data.bridge) {
41
- this.bridge = owner.addBridge(this, data.bridge);
42
- delete data.bridge;
43
- }
44
-
45
- //this.read(data);
46
-
47
- Object.assign(this, data);
48
-
49
- if (typeof this.gateway === "string") {
50
- this.finalize(() => (this.gateway = this.owner.hostNamed(this.gateway)));
51
- }
35
+ this.read(data, NetworkTypeDefinition);
52
36
  }
53
37
 
54
38
  get network() {
@@ -56,7 +40,7 @@ export class Network extends Owner {
56
40
  }
57
41
 
58
42
  networkNamed(name) {
59
- if (this.fullName === name) {
43
+ if (this.isNamed(name)) {
60
44
  return this;
61
45
  }
62
46
  return super.networkNamed(name);
@@ -73,7 +57,8 @@ export class Network extends Owner {
73
57
  return this.#bridge;
74
58
  }
75
59
 
76
- set bridge(bridge) {
77
- this.#bridge = bridge;
60
+ set bridge(network) {
61
+ this.#bridge = this.owner.addBridge(this, network);
62
+ network.bridge = this.bridge; // TODO should happen in addBridge
78
63
  }
79
64
  }