pmcf 6.1.1 → 6.1.2

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
@@ -95,6 +95,7 @@ generates config packages for:
95
95
  * [Parameters](#parameters-17)
96
96
  * [cidrAddresses](#cidraddresses)
97
97
  * [Parameters](#parameters-18)
98
+ * [families](#families)
98
99
  * [secretName](#secretname)
99
100
  * [directHosts](#directhosts)
100
101
  * [subnetForAddress](#subnetforaddress)
@@ -357,6 +358,10 @@ Returns **Iterable<[string](https://developer.mozilla.org/docs/Web/JavaScript/Re
357
358
 
358
359
  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
360
 
361
+ ## families
362
+
363
+ 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;
364
+
360
365
  ## secretName
361
366
 
362
367
  Returns **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**&#x20;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmcf",
3
- "version": "6.1.1",
3
+ "version": "6.1.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -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
  {