pmcf 6.1.1 → 6.1.3

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/README.md CHANGED
@@ -64,42 +64,43 @@ generates config packages for:
64
64
  * [isTemplate](#istemplate)
65
65
  * [expand](#expand)
66
66
  * [Parameters](#parameters-9)
67
- * [PortEndpoint](#portendpoint)
67
+ * [serviceEndpoints](#serviceendpoints)
68
68
  * [Parameters](#parameters-10)
69
+ * [PortEndpoint](#portendpoint)
70
+ * [Parameters](#parameters-11)
69
71
  * [port](#port)
70
72
  * [socketAddress](#socketaddress)
71
73
  * [HTTPEndpoint](#httpendpoint)
72
- * [Parameters](#parameters-11)
74
+ * [Parameters](#parameters-12)
73
75
  * [port](#port-1)
74
76
  * [id](#id)
75
77
  * [domainNames](#domainnames)
76
78
  * [InitializationContext](#initializationcontext)
77
- * [Parameters](#parameters-12)
79
+ * [Parameters](#parameters-13)
78
80
  * [SkeletonNetworkInterface](#skeletonnetworkinterface)
79
81
  * [networkAddresses](#networkaddresses)
80
- * [Parameters](#parameters-13)
82
+ * [Parameters](#parameters-14)
81
83
  * [SystemdJournalRemoteService](#systemdjournalremoteservice)
82
84
  * [Properties](#properties)
83
85
  * [systemdConfigs](#systemdconfigs)
84
- * [Parameters](#parameters-14)
86
+ * [Parameters](#parameters-15)
85
87
  * [SystemdJournalUploadService](#systemdjournaluploadservice)
86
88
  * [Properties](#properties-1)
87
89
  * [systemdConfigs](#systemdconfigs-1)
88
- * [Parameters](#parameters-15)
90
+ * [Parameters](#parameters-16)
89
91
  * [NetworkAddress](#networkaddress)
90
- * [Parameters](#parameters-16)
92
+ * [Parameters](#parameters-17)
91
93
  * [subnet](#subnet)
92
94
  * [networkInterface](#networkinterface)
93
95
  * [address](#address)
94
96
  * [addresses](#addresses)
95
- * [Parameters](#parameters-17)
96
- * [cidrAddresses](#cidraddresses)
97
97
  * [Parameters](#parameters-18)
98
+ * [cidrAddresses](#cidraddresses)
99
+ * [Parameters](#parameters-19)
100
+ * [families](#families)
98
101
  * [secretName](#secretname)
99
102
  * [directHosts](#directhosts)
100
103
  * [subnetForAddress](#subnetforaddress)
101
- * [Parameters](#parameters-19)
102
- * [serviceEndpoints](#serviceendpoints)
103
104
  * [Parameters](#parameters-20)
104
105
  * [domainName](#domainname)
105
106
  * [Parameters](#parameters-21)
@@ -219,6 +220,21 @@ Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
219
220
 
220
221
  Returns **any** 
221
222
 
223
+ ## serviceEndpoints
224
+
225
+ ### Parameters
226
+
227
+ * `sources` **any** 
228
+ * `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** (optional, default `{}`)
229
+
230
+ * `options.services` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** filter for services
231
+ * `options.endpoints` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** filter for endpoints
232
+ * `options.select` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** mapper from Endpoint into result
233
+ * `options.limit` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** upper limit of # result items
234
+ * `options.join` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** join result(s) into a string
235
+
236
+ Returns **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | any)** 
237
+
222
238
  ## PortEndpoint
223
239
 
224
240
  **Extends BaseEndpoint**
@@ -284,7 +300,7 @@ Returns **Iterable<[NetworkAddress](#networkaddress)>**&#x20;
284
300
 
285
301
  ## SystemdJournalRemoteService
286
302
 
287
- **Extends Service**
303
+ **Extends CoreService**
288
304
 
289
305
  ### Properties
290
306
 
@@ -301,7 +317,7 @@ Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/G
301
317
 
302
318
  ## SystemdJournalUploadService
303
319
 
304
- **Extends Service**
320
+ **Extends CoreService**
305
321
 
306
322
  ### Properties
307
323
 
@@ -357,6 +373,10 @@ Returns **Iterable<[string](https://developer.mozilla.org/docs/Web/JavaScript/Re
357
373
 
358
374
  Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>**&#x20;
359
375
 
376
+ ## families
377
+
378
+ Returns **[Set](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Set)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>**&#x20;
379
+
360
380
  ## secretName
361
381
 
362
382
  Returns **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**&#x20;
@@ -373,21 +393,6 @@ hosts we own direcly.
373
393
 
374
394
  Returns **Subnet?**&#x20;
375
395
 
376
- ## serviceEndpoints
377
-
378
- ### Parameters
379
-
380
- * `sources` **any**&#x20;
381
- * `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** (optional, default `{}`)
382
-
383
- * `options.services` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** filter for services
384
- * `options.endpoints` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** filter for endpoints
385
- * `options.select` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** mapper from Endpoint into result
386
- * `options.limit` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** upper limit of # result items
387
- * `options.join` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** join result(s) into a string
388
-
389
- Returns **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | any)**&#x20;
390
-
391
396
  ## domainName
392
397
 
393
398
  Appends default domain if name does not already have a domain.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmcf",
3
- "version": "6.1.1",
3
+ "version": "6.1.3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/src/cluster.mjs CHANGED
@@ -220,7 +220,7 @@ export class Cluster extends Host {
220
220
 
221
221
  await writeLines(
222
222
  join(packageStagingDir, "/usr/lib/systemd/system/keepalived.d"),
223
- `use-credentials.conf`,
223
+ "credentials.conf",
224
224
  [
225
225
  "[Service]",
226
226
  ...credentials.map(
@@ -0,0 +1,381 @@
1
+ import { FAMILY_IPV4, FAMILY_IPV6 } from "ip-utilties";
2
+ import {
3
+ string_attribute_writable,
4
+ number_attribute_writable,
5
+ string_set_attribute,
6
+ default_collection_attribute_writable,
7
+ boolean_attribute_false,
8
+ port_attribute_writable,
9
+ type_attribute_writable,
10
+ priority_attribute
11
+ } from "pacc";
12
+ import {
13
+ Base,
14
+ Host,
15
+ Endpoint,
16
+ DomainNameEndpoint,
17
+ HTTPEndpoint,
18
+ UnixEndpoint,
19
+ addType
20
+ } from "pmcf";
21
+ import { asArray } from "./utils.mjs";
22
+ import { networkAddressAttributes } from "./common-attributes.mjs";
23
+ import {
24
+ serviceTypeEndpoints,
25
+ serviceTypes,
26
+ ServiceTypes
27
+ } from "./service-types.mjs";
28
+ import {
29
+ DNSRecord,
30
+ dnsFullName,
31
+ dnsFormatParameters,
32
+ dnsMergeParameters,
33
+ dnsPriority
34
+ } from "./dns-utils.mjs";
35
+
36
+ export const endpointAttributes = {
37
+ port: port_attribute_writable,
38
+ protocol: {
39
+ ...string_attribute_writable,
40
+ name: "protocol",
41
+ values: new Set(["tcp", "udp", "quic"])
42
+ },
43
+ type: type_attribute_writable,
44
+ types: { ...string_set_attribute, name: "types" },
45
+ tls: { ...boolean_attribute_false, name: "tls" }
46
+ };
47
+
48
+ export class CoreService extends Base {
49
+ static name = "core-service";
50
+ static priority = 1.1;
51
+ static owners = [Host, "cluster", "network_interface"];
52
+ static specializationOf = CoreService;
53
+ static specializations = {};
54
+ static factoryFor(owner, value) {
55
+ const type = value.type ?? value.name;
56
+ const st = this.specializations[type];
57
+
58
+ if (st) {
59
+ delete value.type;
60
+ return st;
61
+ }
62
+
63
+ return baseServiceClass;
64
+ }
65
+ static attributes = {
66
+ ...networkAddressAttributes,
67
+ ...endpointAttributes,
68
+ extends: {
69
+ ...default_collection_attribute_writable,
70
+ name: "extends",
71
+ type: CoreService
72
+ },
73
+ alias: { ...string_attribute_writable, name: "alias" },
74
+ priority: priority_attribute,
75
+ weight: { ...number_attribute_writable, name: "weight" /*default: 1*/ },
76
+ systemdService: { ...string_attribute_writable, name: "systemdService" }
77
+ };
78
+
79
+ static {
80
+ addType(this);
81
+ }
82
+
83
+ _alias;
84
+ _weight;
85
+ _port;
86
+ _systemdService;
87
+
88
+ toString() {
89
+ return `${this.fullName}(${this.type})`;
90
+ }
91
+
92
+ get network() {
93
+ return this.host.network;
94
+ }
95
+
96
+ get host() {
97
+ if (this.owner instanceof Host) {
98
+ return this.owner;
99
+ }
100
+ }
101
+
102
+ get hosts() {
103
+ return this.owner.hosts;
104
+ }
105
+
106
+ get domainName() {
107
+ return this.host?.domainName;
108
+ }
109
+
110
+ get networks() {
111
+ return this.host.networks;
112
+ }
113
+
114
+ get subnets() {
115
+ return this.host.subnets;
116
+ }
117
+
118
+ get url() {
119
+ return this.endpoint()?.url;
120
+ }
121
+
122
+ get serviceTypeEndpoints() {
123
+ return serviceTypeEndpoints(ServiceTypes[this.type]);
124
+ }
125
+
126
+ endpoints(filter) {
127
+ const data = serviceTypeEndpoints(ServiceTypes[this.type]);
128
+ if (!data) {
129
+ return [];
130
+ }
131
+
132
+ const result = [];
133
+
134
+ const domainNames = new Set([undefined]);
135
+
136
+ for (const e of data) {
137
+ switch (e.family) {
138
+ case "unix":
139
+ result.push(new UnixEndpoint(this, e.path, e));
140
+ break;
141
+
142
+ case undefined:
143
+ case "dns":
144
+ case FAMILY_IPV4:
145
+ case FAMILY_IPV6:
146
+ const options =
147
+ this._port === undefined ? { ...e } : { ...e, port: this._port };
148
+ delete options.kind;
149
+
150
+ for (const na of this.host.networkAddresses()) {
151
+ if (e.kind && e.kind !== na.networkInterface.kind) {
152
+ continue;
153
+ }
154
+
155
+ if (e.pathname) {
156
+ result.push(new HTTPEndpoint(this, na, options));
157
+ } else {
158
+ if (e.family === na.family) {
159
+ result.push(new Endpoint(this, na, options));
160
+ }
161
+ }
162
+ }
163
+
164
+ if (!domainNames.has(this.domainName)) {
165
+ domainNames.add(this.domainName);
166
+ result.push(new DomainNameEndpoint(this, this.domainName, options));
167
+ }
168
+
169
+ break;
170
+ }
171
+ }
172
+
173
+ switch (typeof filter) {
174
+ case "string":
175
+ return result.filter(endpoint => endpoint.type === filter);
176
+
177
+ case "undefined":
178
+ return result;
179
+
180
+ default:
181
+ return result.filter(filter);
182
+ }
183
+ }
184
+
185
+ endpoint(filter) {
186
+ return this.endpoints(filter)[0];
187
+ }
188
+
189
+ address(
190
+ options = {
191
+ endpoints: e =>
192
+ e.networkInterface && e.networkInterface.kind !== "loopbak",
193
+ select: e => e.domainName || e.address,
194
+ limit: 1,
195
+ join: ""
196
+ }
197
+ ) {
198
+ const all = this.endpoints(options.endpoints);
199
+ const res = [...new Set(options.select ? all.map(options.select) : all)];
200
+
201
+ if (options.limit < res.length) {
202
+ res.length = options.limit;
203
+ }
204
+
205
+ return options.join !== undefined ? res.join(options.join) : res;
206
+ }
207
+
208
+ set alias(value) {
209
+ this._alias = value;
210
+ }
211
+
212
+ get alias() {
213
+ return this.attribute("_alias");
214
+ }
215
+
216
+ set port(value) {
217
+ this._port = value;
218
+ }
219
+
220
+ get port() {
221
+ return (
222
+ this.attribute("_port") ??
223
+ serviceTypeEndpoints(ServiceTypes[this.type])[0]?.port
224
+ );
225
+ }
226
+
227
+ set priority(value) {
228
+ this._priority = value;
229
+ }
230
+
231
+ get priority() {
232
+ return this.attribute("_priority") ?? this.owner?.priority ?? 1;
233
+ }
234
+
235
+ set weight(value) {
236
+ this._weight = value;
237
+ }
238
+
239
+ get weight() {
240
+ return this.attribute("_weight") ?? this.owner.weight ?? 1;
241
+ }
242
+
243
+ get type() {
244
+ return this.constructor.name;
245
+ }
246
+
247
+ get types() {
248
+ return serviceTypes(ServiceTypes[this.type]);
249
+ }
250
+
251
+ get systemdService() {
252
+ return (
253
+ this.attribute("_systemdService") ??
254
+ ServiceTypes[this.type]?.systemdService
255
+ );
256
+ }
257
+
258
+ get packageData() {
259
+ const packageData = super.packageData;
260
+ const name = `${this.owner.name}-${this.host.name}`;
261
+ packageData.properties.name = `${this.type}-${name}`;
262
+ packageData.properties.description = `${this.type} service definitions for ${this.fullName}`;
263
+ packageData.properties.groups.push("service-config", name);
264
+ return packageData;
265
+ }
266
+
267
+ async *preparePackages(dir) {
268
+ const pd = this.packageData;
269
+ pd.sources = await Array.fromAsync(this.templateContent());
270
+ if (pd.sources.length) {
271
+ yield pd;
272
+ }
273
+ }
274
+
275
+ dnsRecordsForDomainName(domainName, hasSVRRecords) {
276
+ const records = [];
277
+ if (this.priority >= 390 && this.alias) {
278
+ records.push(DNSRecord(this.alias, "CNAME", dnsFullName(domainName)));
279
+ }
280
+
281
+ if (hasSVRRecords) {
282
+ for (const ep of this.endpoints(
283
+ e =>
284
+ e.protocol &&
285
+ e.networkInterface &&
286
+ e.networkInterface.kind !== "loopback"
287
+ )) {
288
+ records.push(
289
+ DNSRecord(
290
+ dnsFullName(`_${this.type}._${ep.protocol}.${domainName}`),
291
+ "SRV",
292
+ dnsPriority(this.priority),
293
+ this.weight,
294
+ ep.port,
295
+ dnsFullName(this.domainName)
296
+ )
297
+ );
298
+ break; // TODO only one ?
299
+ }
300
+ }
301
+
302
+ const dnsRecord = ServiceTypes[this.type]?.dnsRecord;
303
+ if (dnsRecord) {
304
+ let parameters = dnsRecord.parameters;
305
+
306
+ if (parameters) {
307
+ for (const service of this.services) {
308
+ if (service !== this) {
309
+ const serviceType = ServiceTypes[service.type];
310
+ /*if(!serviceType) {
311
+ throw new Error(`Unknown service '${service.type}'`);
312
+ }*/
313
+ const r = serviceType?.dnsRecord;
314
+
315
+ if (r?.type === dnsRecord.type) {
316
+ parameters = dnsMergeParameters(parameters, r.parameters);
317
+ }
318
+ }
319
+ }
320
+
321
+ records.push(
322
+ DNSRecord(
323
+ dnsFullName(domainName),
324
+ dnsRecord.type,
325
+ dnsPriority(this.priority),
326
+ ".",
327
+ dnsFormatParameters(parameters)
328
+ )
329
+ );
330
+ } else {
331
+ records.push(
332
+ DNSRecord(
333
+ "@",
334
+ dnsRecord.type,
335
+ dnsPriority(this.priority),
336
+ dnsFullName(domainName)
337
+ )
338
+ );
339
+ }
340
+ }
341
+
342
+ return records;
343
+ }
344
+ }
345
+
346
+ export let baseServiceClass = CoreService;
347
+
348
+ export function setBaseService(value) {
349
+ baseServiceClass = value;
350
+ }
351
+
352
+ export const sortAscendingByPriority = (a, b) => a.priority - b.priority;
353
+ export const sortDescendingByPriority = (a, b) => b.priority - a.priority;
354
+
355
+ /**
356
+ *
357
+ * @param {*} sources
358
+ * @param {Object} [options]
359
+ * @param {Function} [options.services] filter for services
360
+ * @param {Function} [options.endpoints] filter for endpoints
361
+ * @param {Function} [options.select] mapper from Endpoint into result
362
+ * @param {number} [options.limit] upper limit of # result items
363
+ * @param {string} [options.join] join result(s) into a string
364
+ * @returns {string|any}
365
+ */
366
+ export function serviceEndpoints(sources, options = {}) {
367
+ const all = asArray(sources)
368
+ .map(source => Array.from(source.expression(options.services)))
369
+ .flat()
370
+ .sort(sortDescendingByPriority)
371
+ .map(service => service.endpoints(options.endpoints))
372
+ .flat();
373
+
374
+ const res = [...new Set(options.select ? all.map(options.select) : all)];
375
+
376
+ if (options.limit < res.length) {
377
+ res.length = options.limit;
378
+ }
379
+
380
+ return options.join ? res.join(options.join) : res;
381
+ }
package/src/endpoint.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  import { FAMILY_IPV6 } from "ip-utilties";
2
2
  import { addType } from "pmcf";
3
- import { endpointAttributes, Service } from "./service.mjs";
3
+ import { endpointAttributes, CoreService } from "./core-service.mjs";
4
4
 
5
5
  class BaseEndpoint {
6
6
  static name = "endpoint";
7
7
  static priority = 1.1;
8
- static owners = [Service, "network_interface"];
8
+ static owners = [CoreService, "network_interface"];
9
9
  static key = "type";
10
10
  attributes = endpointAttributes;
11
11
 
@@ -1,11 +1,10 @@
1
1
  import { AggregatedMap } from "aggregated-map";
2
2
  import { default_collection_attribute_writable, addType } from "pacc";
3
- import { Service } from "./service.mjs";
3
+ import { CoreService } from "./core-service.mjs";
4
4
  import { networkAddressType } from "pmcf";
5
5
 
6
- export class ExtraSourceService extends Service {
6
+ export class ExtraSourceService extends CoreService {
7
7
  static name = "extra-source-service";
8
-
9
8
  static attributes = {
10
9
  source: {
11
10
  ...default_collection_attribute_writable,
@@ -20,10 +19,6 @@ export class ExtraSourceService extends Service {
20
19
 
21
20
  source = [];
22
21
 
23
- get type() {
24
- return this.constructor.name;
25
- }
26
-
27
22
  get services() {
28
23
  return new AggregatedMap([
29
24
  this.owner.owner.services,
package/src/host.mjs CHANGED
@@ -8,7 +8,6 @@ import {
8
8
  string_attribute_writable,
9
9
  string_set_attribute_writable,
10
10
  number_attribute_writable,
11
- boolean_attribute_false,
12
11
  priority_attribute
13
12
  } from "pacc";
14
13
  import { addresses, addType, assign } from "pmcf";
package/src/module.mjs CHANGED
@@ -16,6 +16,7 @@ export * from "./network-interfaces/wlan.mjs";
16
16
  export * from "./network-interfaces/wireguard.mjs";
17
17
  export * from "./network-interfaces/tun.mjs";
18
18
  export * from "./service-types.mjs";
19
+ export * from "./core-service.mjs";
19
20
  export * from "./service.mjs";
20
21
  export * from "./extra-source-service.mjs";
21
22
  export * from "./endpoint.mjs";
package/src/service.mjs CHANGED
@@ -1,244 +1,21 @@
1
- import { FAMILY_IPV4, FAMILY_IPV6 } from "ip-utilties";
2
- import {
3
- string_attribute_writable,
4
- number_attribute_writable,
5
- string_set_attribute,
6
- default_collection_attribute_writable,
7
- boolean_attribute_false,
8
- port_attribute_writable,
9
- type_attribute_writable,
10
- priority_attribute
11
- } from "pacc";
12
- import {
13
- Base,
14
- Host,
15
- Endpoint,
16
- DomainNameEndpoint,
17
- HTTPEndpoint,
18
- UnixEndpoint,
19
- addType
20
- } from "pmcf";
21
- import { asArray } from "./utils.mjs";
22
- import { networkAddressAttributes } from "./common-attributes.mjs";
23
- import {
24
- serviceTypeEndpoints,
25
- serviceTypes,
26
- ServiceTypes
27
- } from "./service-types.mjs";
28
- import {
29
- DNSRecord,
30
- dnsFullName,
31
- dnsFormatParameters,
32
- dnsMergeParameters,
33
- dnsPriority
34
- } from "./dns-utils.mjs";
1
+ import { string_attribute_writable } from "pacc";
2
+ import { setBaseService, CoreService, addType } from "pmcf";
35
3
 
36
- export const endpointAttributes = {
37
- port: port_attribute_writable,
38
- protocol: {
39
- ...string_attribute_writable,
40
- name: "protocol",
41
- values: new Set(["tcp", "udp", "quic"])
42
- },
43
- type: type_attribute_writable,
44
- types: { ...string_set_attribute, name: "types" },
45
- tls: { ...boolean_attribute_false, name: "tls" }
46
- };
47
-
48
- export class Service extends Base {
4
+ export class Service extends CoreService {
49
5
  static name = "service";
50
- static priority = 1.1;
51
- static owners = [Host, "cluster", "network_interface"];
52
- static specializationOf = Service;
53
- static specializations = {};
54
- static factoryFor(owner, value) {
55
- const type = value.type ?? value.name;
56
- const st = this.specializations[type];
57
-
58
- if (st) {
59
- delete value.type;
60
- return st;
61
- }
62
-
63
- return Service;
64
- }
65
6
  static attributes = {
66
- ...networkAddressAttributes,
67
- ...endpointAttributes,
68
- extends: {
69
- ...default_collection_attribute_writable,
70
- name: "extends",
71
- type: Service
72
- },
73
- alias: { ...string_attribute_writable, name: "alias" },
74
- priority: priority_attribute,
75
- weight: { ...number_attribute_writable, name: "weight" /*default: 1*/ },
76
- systemdService: { ...string_attribute_writable, name: "systemdService" }
7
+ type: { ...string_attribute_writable, name: "type" }
77
8
  };
78
-
79
9
  static {
80
10
  addType(this);
81
- }
82
-
83
- _alias;
84
- _weight;
85
- _type;
86
- _port;
87
- _systemdService;
88
-
89
- toString() {
90
- return `${this.fullName}(${this.type})`;
91
- }
92
-
93
- get network() {
94
- return this.host.network;
95
- }
96
-
97
- get host() {
98
- if (this.owner instanceof Host) {
99
- return this.owner;
100
- }
101
- }
102
-
103
- get hosts() {
104
- return this.owner.hosts;
105
- }
106
-
107
- get domainName() {
108
- return this.host?.domainName;
109
- }
110
-
111
- get networks() {
112
- return this.host.networks;
113
- }
114
-
115
- get subnets() {
116
- return this.host.subnets;
117
- }
118
-
119
- get url() {
120
- return this.endpoint()?.url;
121
- }
122
-
123
- get serviceTypeEndpoints() {
124
- return serviceTypeEndpoints(ServiceTypes[this.type]);
125
- }
126
-
127
- endpoints(filter) {
128
- const data = serviceTypeEndpoints(ServiceTypes[this.type]);
129
- if (!data) {
130
- return [];
131
- }
132
-
133
- const result = [];
134
-
135
- const domainNames = new Set([undefined]);
136
-
137
- for (const e of data) {
138
- switch (e.family) {
139
- case "unix":
140
- result.push(new UnixEndpoint(this, e.path, e));
141
- break;
142
-
143
- case undefined:
144
- case "dns":
145
- case FAMILY_IPV4:
146
- case FAMILY_IPV6:
147
- const options =
148
- this._port === undefined ? { ...e } : { ...e, port: this._port };
149
- delete options.kind;
150
-
151
- for (const na of this.host.networkAddresses()) {
152
- if (e.kind && e.kind !== na.networkInterface.kind) {
153
- continue;
154
- }
155
-
156
- if (e.pathname) {
157
- result.push(new HTTPEndpoint(this, na, options));
158
- } else {
159
- if (e.family === na.family) {
160
- result.push(new Endpoint(this, na, options));
161
- }
162
- }
163
- }
164
-
165
- if (!domainNames.has(this.domainName)) {
166
- domainNames.add(this.domainName);
167
- result.push(new DomainNameEndpoint(this, this.domainName, options));
168
- }
169
-
170
- break;
171
- }
172
- }
173
-
174
- switch (typeof filter) {
175
- case "string":
176
- return result.filter(endpoint => endpoint.type === filter);
177
-
178
- case "undefined":
179
- return result;
180
-
181
- default:
182
- return result.filter(filter);
183
- }
184
- }
185
-
186
- endpoint(filter) {
187
- return this.endpoints(filter)[0];
188
- }
189
11
 
190
- address(
191
- options = {
192
- endpoints: e =>
193
- e.networkInterface && e.networkInterface.kind !== "loopbak",
194
- select: e => e.domainName || e.address,
195
- limit: 1,
196
- join: ""
197
- }
198
- ) {
199
- const all = this.endpoints(options.endpoints);
200
- const res = [...new Set(options.select ? all.map(options.select) : all)];
201
-
202
- if (options.limit < res.length) {
203
- res.length = options.limit;
204
- }
205
-
206
- return options.join !== undefined ? res.join(options.join) : res;
207
- }
208
-
209
- set alias(value) {
210
- this._alias = value;
211
- }
212
-
213
- get alias() {
214
- return this.attribute("_alias");
12
+ setBaseService(this);
215
13
  }
216
14
 
217
- set port(value) {
218
- this._port = value;
219
- }
220
-
221
- get port() {
222
- return (
223
- this.attribute("_port") ??
224
- serviceTypeEndpoints(ServiceTypes[this.type])[0]?.port
225
- );
226
- }
227
-
228
- set priority(value) {
229
- this._priority = value;
230
- }
231
-
232
- get priority() {
233
- return this.attribute("_priority") ?? this.owner?.priority ?? 1;
234
- }
235
-
236
- set weight(value) {
237
- this._weight = value;
238
- }
15
+ _type;
239
16
 
240
- get weight() {
241
- return this.attribute("_weight") ?? this.owner.weight ?? 1;
17
+ set type(value) {
18
+ this._type = value;
242
19
  }
243
20
 
244
21
  set type(value) {
@@ -248,133 +25,4 @@ export class Service extends Base {
248
25
  get type() {
249
26
  return this.attribute("_type") ?? this.name;
250
27
  }
251
-
252
- get types() {
253
- return serviceTypes(ServiceTypes[this.type]);
254
- }
255
-
256
- get systemdService() {
257
- return (
258
- this.attribute("_systemdService") ??
259
- ServiceTypes[this.type]?.systemdService
260
- );
261
- }
262
-
263
- get packageData() {
264
- const packageData = super.packageData;
265
- const name = `${this.owner.name}-${this.host.name}`;
266
- packageData.properties.name = `${this.type}-${name}`;
267
- packageData.properties.description = `${this.type} service definitions for ${this.fullName}`;
268
- packageData.properties.groups.push("service-config", name);
269
- return packageData;
270
- }
271
-
272
- async *preparePackages(dir) {
273
- const pd = this.packageData;
274
- pd.sources = await Array.fromAsync(this.templateContent());
275
- if (pd.sources.length) {
276
- yield pd;
277
- }
278
- }
279
-
280
- dnsRecordsForDomainName(domainName, hasSVRRecords) {
281
- const records = [];
282
- if (this.priority >= 390 && this.alias) {
283
- records.push(DNSRecord(this.alias, "CNAME", dnsFullName(domainName)));
284
- }
285
-
286
- if (hasSVRRecords) {
287
- for (const ep of this.endpoints(
288
- e =>
289
- e.protocol &&
290
- e.networkInterface &&
291
- e.networkInterface.kind !== "loopback"
292
- )) {
293
- records.push(
294
- DNSRecord(
295
- dnsFullName(`_${this.type}._${ep.protocol}.${domainName}`),
296
- "SRV",
297
- dnsPriority(this.priority),
298
- this.weight,
299
- ep.port,
300
- dnsFullName(this.domainName)
301
- )
302
- );
303
- break; // TODO only one ?
304
- }
305
- }
306
-
307
- const dnsRecord = ServiceTypes[this.type]?.dnsRecord;
308
- if (dnsRecord) {
309
- let parameters = dnsRecord.parameters;
310
-
311
- if (parameters) {
312
- for (const service of this.services) {
313
- if (service !== this) {
314
- const serviceType = ServiceTypes[service.type];
315
- /*if(!serviceType) {
316
- throw new Error(`Unknown service '${service.type}'`);
317
- }*/
318
- const r = serviceType?.dnsRecord;
319
-
320
- if (r?.type === dnsRecord.type) {
321
- parameters = dnsMergeParameters(parameters, r.parameters);
322
- }
323
- }
324
- }
325
-
326
- records.push(
327
- DNSRecord(
328
- dnsFullName(domainName),
329
- dnsRecord.type,
330
- dnsPriority(this.priority),
331
- ".",
332
- dnsFormatParameters(parameters)
333
- )
334
- );
335
- } else {
336
- records.push(
337
- DNSRecord(
338
- "@",
339
- dnsRecord.type,
340
- dnsPriority(this.priority),
341
- dnsFullName(domainName)
342
- )
343
- );
344
- }
345
- }
346
-
347
- return records;
348
- }
349
- }
350
-
351
- export const sortAscendingByPriority = (a, b) => a.priority - b.priority;
352
- export const sortDescendingByPriority = (a, b) => b.priority - a.priority;
353
-
354
- /**
355
- *
356
- * @param {*} sources
357
- * @param {Object} [options]
358
- * @param {Function} [options.services] filter for services
359
- * @param {Function} [options.endpoints] filter for endpoints
360
- * @param {Function} [options.select] mapper from Endpoint into result
361
- * @param {number} [options.limit] upper limit of # result items
362
- * @param {string} [options.join] join result(s) into a string
363
- * @returns {string|any}
364
- */
365
- export function serviceEndpoints(sources, options = {}) {
366
- const all = asArray(sources)
367
- .map(source => Array.from(source.expression(options.services)))
368
- .flat()
369
- .sort(sortDescendingByPriority)
370
- .map(service => service.endpoints(options.endpoints))
371
- .flat();
372
-
373
- const res = [...new Set(options.select ? all.map(options.select) : all)];
374
-
375
- if (options.limit < res.length) {
376
- res.length = options.limit;
377
- }
378
-
379
- return options.join ? res.join(options.join) : res;
380
28
  }
@@ -4,7 +4,7 @@ import {
4
4
  string_attribute_writable,
5
5
  string_set_attribute_writable
6
6
  } from "pacc";
7
- import { addType, Service, Base } from "pmcf";
7
+ import { addType, CoreService, Base } from "pmcf";
8
8
  import { owner_attribute } from "../common-attributes.mjs";
9
9
 
10
10
  class alpm_repository extends Base {
@@ -22,7 +22,7 @@ class alpm_repository extends Base {
22
22
  architectures = new Set();
23
23
  }
24
24
 
25
- export class alpm extends Service {
25
+ export class alpm extends CoreService {
26
26
  static attributes = {
27
27
  repositories: {
28
28
  ...default_collection_attribute_writable,
@@ -1,7 +1,7 @@
1
1
  import { FAMILY_IPV4 } from "ip-utilties";
2
- import { Service, addType } from "pmcf";
2
+ import { CoreService, addType } from "pmcf";
3
3
 
4
- export class headscale extends Service {
4
+ export class headscale extends CoreService {
5
5
  static service = {
6
6
  endpoints: [
7
7
  {
@@ -2,14 +2,14 @@ import { join } from "node:path";
2
2
  import { FAMILY_IPV4, FAMILY_IPV6 } from "ip-utilties";
3
3
  import { FileContentProvider } from "npm-pkgbuild";
4
4
  import { boolean_attribute_writable_true } from "pacc";
5
- import { Service, addType } from "pmcf";
5
+ import { CoreService, addType } from "pmcf";
6
6
  import {
7
7
  writeLines,
8
8
  setionLinesFromPropertyIterator,
9
9
  filterConfigurable
10
10
  } from "../utils.mjs";
11
11
 
12
- export class influxdb extends Service {
12
+ export class influxdb extends CoreService {
13
13
  static attributes = {
14
14
  metricsDisabled: {
15
15
  ...boolean_attribute_writable_true,
@@ -13,7 +13,7 @@ import {
13
13
  } from "pacc";
14
14
  import {
15
15
  addType,
16
- Service,
16
+ CoreService,
17
17
  sortDescendingByPriority,
18
18
  serviceEndpoints,
19
19
  SUBNET_LOCALHOST_IPV4,
@@ -23,7 +23,7 @@ import { writeLines } from "../utils.mjs";
23
23
 
24
24
  const keaVersion = "3.0.1";
25
25
 
26
- export class kea extends Service {
26
+ export class kea extends CoreService {
27
27
  static attributes = {
28
28
  "ddns-send-updates": {
29
29
  ...boolean_attribute_writable_true,
@@ -1,7 +1,7 @@
1
1
  import { port_attribute, string_attribute_writable } from "pacc";
2
- import { Service, addType } from "pmcf";
2
+ import { CoreService, addType } from "pmcf";
3
3
 
4
- export class mosquitto extends Service {
4
+ export class mosquitto extends CoreService {
5
5
  static attributes = {
6
6
  listener: {
7
7
  ...port_attribute,
@@ -1,7 +1,7 @@
1
1
  import { string_attribute_writable } from "pacc";
2
- import { Service, addType } from "pmcf";
2
+ import { CoreService, addType } from "pmcf";
3
3
 
4
- export class openldap extends Service {
4
+ export class openldap extends CoreService {
5
5
  static attributes = {
6
6
  base: { ...string_attribute_writable, name: "base" },
7
7
  uri: { ...string_attribute_writable, name: "uri" }
@@ -1,6 +1,6 @@
1
- import { Service, addType } from "pmcf";
1
+ import { CoreService, addType } from "pmcf";
2
2
 
3
- export class postfix extends Service {
3
+ export class postfix extends CoreService {
4
4
  static service = {
5
5
  systemdService: "postfix.service",
6
6
  extends: ["smtp", "lmtp", "submission"],
@@ -5,16 +5,15 @@ import {
5
5
  boolean_attribute_writable,
6
6
  integer_attribute_writable
7
7
  } from "pacc";
8
- import { Service, addType } from "pmcf";
8
+ import { CoreService, addType } from "pmcf";
9
9
  import { filterConfigurable, sectionLines } from "../utils.mjs";
10
10
 
11
11
  /**
12
12
  * @property {string} ServerCertificateFile
13
13
  * @property {string} ServerKeyFile
14
14
  */
15
- export class SystemdJournalRemoteService extends Service {
15
+ export class SystemdJournalRemoteService extends CoreService {
16
16
  static name = "systemd-journal-remote";
17
-
18
17
  static attributes = {
19
18
  Seal: {
20
19
  ...boolean_attribute_writable,
@@ -96,10 +95,6 @@ export class SystemdJournalRemoteService extends Service {
96
95
  addType(this);
97
96
  }
98
97
 
99
- get type() {
100
- return this.constructor.name;
101
- }
102
-
103
98
  /**
104
99
  *
105
100
  * @param {string} name
@@ -3,7 +3,7 @@ import {
3
3
  string_collection_attribute_writable,
4
4
  boolean_attribute_writable
5
5
  } from "pacc";
6
- import { Service, addType } from "pmcf";
6
+ import { CoreService, addType } from "pmcf";
7
7
  import { filterConfigurable, sectionLines } from "../utils.mjs";
8
8
 
9
9
  /**
@@ -11,7 +11,7 @@ import { filterConfigurable, sectionLines } from "../utils.mjs";
11
11
  * @property {string} ServerCertificateFile
12
12
  * @property {string} ServerKeyFile
13
13
  */
14
- export class SystemdJournalUploadService extends Service {
14
+ export class SystemdJournalUploadService extends CoreService {
15
15
  static name = "systemd-journal-upload";
16
16
  static attributes = {
17
17
  URL: { ...string_attribute_writable, name: "URL", configurable: true },
@@ -53,10 +53,6 @@ export class SystemdJournalUploadService extends Service {
53
53
  addType(this);
54
54
  }
55
55
 
56
- get type() {
57
- return this.constructor.name;
58
- }
59
-
60
56
  /**
61
57
  *
62
58
  * @param {string} name
@@ -1,8 +1,8 @@
1
1
  import { string_attribute_writable, duration_attribute_writable } from "pacc";
2
- import { Service, addType } from "pmcf";
2
+ import { CoreService, addType } from "pmcf";
3
3
  import { filterConfigurable, sectionLines } from "../utils.mjs";
4
4
 
5
- export class SystemdJournaldService extends Service {
5
+ export class SystemdJournaldService extends CoreService {
6
6
  static name = "systemd-journald";
7
7
  static attributes = {
8
8
  Storage: {
@@ -128,10 +128,6 @@ export class SystemdJournaldService extends Service {
128
128
  addType(this);
129
129
  }
130
130
 
131
- get type() {
132
- return this.constructor.name;
133
- }
134
-
135
131
  systemdConfigs(name) {
136
132
  return {
137
133
  serviceName: this.systemdService,
@@ -1,7 +1,7 @@
1
1
  import { FAMILY_IPV4 } from "ip-utilties";
2
- import { Service, addType } from "pmcf";
2
+ import { CoreService, addType } from "pmcf";
3
3
 
4
- export class tailscale extends Service {
4
+ export class tailscale extends CoreService {
5
5
  static service = {
6
6
  endpoints: [
7
7
  {