pmcf 1.46.4 → 1.47.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/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,71 @@ 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
+ // return this.#extends.map(e => this.expand(e));
144
+ }
145
+
146
+ set provides(value) {
147
+ if (value instanceof Set) {
148
+ this.#provides = this.#provides.union(value);
149
+ } else {
150
+ this.#provides.add(value);
151
+ }
157
152
  }
158
153
 
159
154
  get provides() {
160
- let provides = new Set(this.#provides);
161
- this.extends.forEach(h => (provides = provides.union(h.provides)));
162
- return provides;
155
+ return this.#provides;
156
+ }
157
+
158
+ set replaces(value) {
159
+ if (value instanceof Set) {
160
+ this.#replaces = this.#replaces.union(value);
161
+ } else {
162
+ this.#replaces.add(value);
163
+ }
163
164
  }
164
165
 
165
166
  get replaces() {
166
- let replaces = new Set(this.#replaces);
167
- this.extends.forEach(h => (replaces = replaces.union(h.replaces)));
168
- return replaces;
167
+ return this.#replaces;
169
168
  }
170
169
 
171
- get _depends() {
172
- let depends = this.#depends;
173
- this.extends.forEach(h => (depends = depends.union(h._depends)));
174
- return depends;
170
+ set depends(value) {
171
+ if (value instanceof Set) {
172
+ this.#depends = this.#depends.union(value);
173
+ } else {
174
+ this.#depends.add(value);
175
+ }
175
176
  }
176
177
 
177
178
  get depends() {
178
- return this.expand(this._depends);
179
+ return this.#depends;
180
+ }
181
+
182
+ set master(value) {
183
+ this.#master = value;
179
184
  }
180
185
 
181
186
  get master() {
182
187
  return this.#master || this.extends.find(e => e.master) ? true : false;
183
188
  }
184
189
 
190
+ set os(value) {
191
+ this.#os = value;
192
+ }
193
+
185
194
  get os() {
186
195
  return this.#os || this.extends.find(e => e.os);
187
196
  }
188
197
 
198
+ set distribution(value) {
199
+ this.#distribution = value;
200
+ }
201
+
189
202
  get distribution() {
190
203
  return this.#distribution || this.extends.find(e => e.distribution);
191
204
  }
@@ -213,15 +226,15 @@ export class Host extends Base {
213
226
  return this;
214
227
  }
215
228
 
216
- get network() {
217
- return this.owner.network;
229
+ get services() {
230
+ return this.#services;
218
231
  }
219
232
 
220
- addService(service) {
221
- this.#services.push(service);
233
+ set services(services) {
234
+ this.#services.push(services);
222
235
  }
223
236
 
224
- *services(filter) {
237
+ *findServices(filter) {
225
238
  for (const service of this.#services) {
226
239
  if (
227
240
  !filter ||
@@ -238,11 +251,7 @@ export class Host extends Base {
238
251
  return this.#networkInterfaces;
239
252
  }
240
253
 
241
- networkInterfaceNamed(name) {
242
- return this.#networkInterfaces.get(name);
243
- }
244
-
245
- addNetworkInterface(networkInterface) {
254
+ set networkInterfaces(networkInterface) {
246
255
  this.#networkInterfaces.set(networkInterface.name, networkInterface);
247
256
 
248
257
  if (networkInterface.network) {
@@ -250,6 +259,10 @@ export class Host extends Base {
250
259
  }
251
260
  }
252
261
 
262
+ networkInterfaceNamed(name) {
263
+ return this.#networkInterfaces.get(name);
264
+ }
265
+
253
266
  *networkAddresses() {
254
267
  for (const networkInterface of this.networkInterfaces.values()) {
255
268
  for (const [address, subnet] of networkInterface.ipAddresses) {
@@ -279,45 +292,32 @@ export class Host extends Base {
279
292
  async publicKey(type = "ed25519") {
280
293
  return readFile(join(this.directory, `ssh_host_${type}_key.pub`), "utf8");
281
294
  }
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
295
  }
296
296
 
297
+ const NetworkInterfaceTypeDefinition = {
298
+ name: "network_interface",
299
+ priority: 0.4,
300
+ owners: ["host"],
301
+ extends: Base.typeDefinition,
302
+ properties: {
303
+ ...networkProperties,
304
+ hwaddr: { type: "string", collection: false, writeable: true },
305
+ ipAddresses: { type: "string", collection: true, writeable: true },
306
+ cidrAddresses: { type: "string", collection: true, writeable: false },
307
+ rawAddresses: { type: "string", collection: true, writeable: false },
308
+ network: { type: "network", collection: false, writeable: true },
309
+ destination: { type: "host", collection: false, writeable: true },
310
+ arpbridge: { type: "host", collection: true, writeable: true }
311
+ }
312
+ };
313
+
297
314
  export class NetworkInterface extends Base {
298
315
  static {
299
316
  addType(this);
300
317
  }
301
318
 
302
319
  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
- };
320
+ return NetworkInterfaceTypeDefinition;
321
321
  }
322
322
 
323
323
  #ipAddresses = new Map();
@@ -332,48 +332,8 @@ export class NetworkInterface extends Base {
332
332
 
333
333
  constructor(owner, data) {
334
334
  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);
335
+ this.read(data, NetworkInterfaceTypeDefinition);
336
+ //owner.addNetworkInterface(this);
377
337
  }
378
338
 
379
339
  addSubnet(address) {
@@ -400,7 +360,7 @@ export class NetworkInterface extends Base {
400
360
  }
401
361
 
402
362
  get rawAddresses() {
403
- return [...this.#ipAddresses].map(([address, subnet]) => address);
363
+ return [...this.#ipAddresses].map(([address]) => address);
404
364
  }
405
365
 
406
366
  get cidrAddresses() {
@@ -411,14 +371,14 @@ export class NetworkInterface extends Base {
411
371
 
412
372
  get rawIPv4Addresses() {
413
373
  return [...this.ipAddresses]
414
- .filter(([address, subnet]) => isIPv4Address(address))
415
- .map(([address, subnet]) => address);
374
+ .filter(([address]) => isIPv4Address(address))
375
+ .map(([address]) => address);
416
376
  }
417
377
 
418
378
  get rawIPv6Addresses() {
419
379
  return [...this.ipAddresses]
420
- .filter(([address, subnet]) => isIPv6Address(address))
421
- .map(([address, subnet]) => address);
380
+ .filter(([address]) => isIPv6Address(address))
381
+ .map(([address]) => address);
422
382
  }
423
383
 
424
384
  subnetForAddress(address) {
@@ -448,37 +408,46 @@ export class NetworkInterface extends Base {
448
408
  return this.#network || this.host.network;
449
409
  }
450
410
 
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
- }
411
+ set network(network) {
412
+ this.#network = network;
413
+ }
462
414
 
463
- this.#network = networkOrName;
415
+ set scope(value) {
416
+ this.#scope = value;
464
417
  }
465
418
 
466
419
  get scope() {
467
420
  return this.#scope || this.network?.scope || "global";
468
421
  }
469
422
 
423
+ set metric(value) {
424
+ this.#metric = value;
425
+ }
426
+
470
427
  get metric() {
471
428
  return this.#metric || this.network?.metric || 1004;
472
429
  }
473
430
 
431
+ set ssid(value) {
432
+ this.#ssid = value;
433
+ }
434
+
474
435
  get ssid() {
475
436
  return this.#ssid || this.network?.ssid;
476
437
  }
477
438
 
439
+ set psk(value) {
440
+ this.#psk = value;
441
+ }
442
+
478
443
  get psk() {
479
444
  return this.#psk || this.network?.psk;
480
445
  }
481
446
 
447
+ set kind(value) {
448
+ this.#kind = value;
449
+ }
450
+
482
451
  get kind() {
483
452
  return this.#kind || this.network?.kind;
484
453
  }
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
  }