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 +5 -0
- package/package.json +1 -1
- package/src/core-service.mjs +381 -0
- package/src/endpoint.mjs +2 -2
- package/src/extra-source-service.mjs +2 -7
- package/src/host.mjs +0 -1
- package/src/module.mjs +1 -0
- package/src/service.mjs +8 -360
- package/src/services/alpm.mjs +2 -2
- package/src/services/headscale.mjs +2 -2
- package/src/services/influxdb.mjs +2 -2
- package/src/services/kea.mjs +2 -2
- package/src/services/mosquitto.mjs +2 -2
- package/src/services/openldap.mjs +2 -2
- package/src/services/postfix.mjs +2 -2
- package/src/services/systemd-journal-remote.mjs +2 -7
- package/src/services/systemd-journal-upload.mjs +2 -6
- package/src/services/systemd-journald.mjs +2 -6
- package/src/services/tailscale.mjs +2 -2
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)>** 
|
|
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)>** 
|
|
364
|
+
|
|
360
365
|
## secretName
|
|
361
366
|
|
|
362
367
|
Returns **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
|
package/package.json
CHANGED
|
@@ -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,
|
|
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 = [
|
|
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 {
|
|
3
|
+
import { CoreService } from "./core-service.mjs";
|
|
4
4
|
import { networkAddressType } from "pmcf";
|
|
5
5
|
|
|
6
|
-
export class ExtraSourceService extends
|
|
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
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 {
|
|
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
|
|
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
|
-
...
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
241
|
-
|
|
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
|
}
|
package/src/services/alpm.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
string_attribute_writable,
|
|
5
5
|
string_set_attribute_writable
|
|
6
6
|
} from "pacc";
|
|
7
|
-
import { addType,
|
|
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
|
|
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 {
|
|
2
|
+
import { CoreService, addType } from "pmcf";
|
|
3
3
|
|
|
4
|
-
export class headscale extends
|
|
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 {
|
|
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
|
|
12
|
+
export class influxdb extends CoreService {
|
|
13
13
|
static attributes = {
|
|
14
14
|
metricsDisabled: {
|
|
15
15
|
...boolean_attribute_writable_true,
|
package/src/services/kea.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "pacc";
|
|
14
14
|
import {
|
|
15
15
|
addType,
|
|
16
|
-
|
|
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
|
|
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 {
|
|
2
|
+
import { CoreService, addType } from "pmcf";
|
|
3
3
|
|
|
4
|
-
export class mosquitto extends
|
|
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 {
|
|
2
|
+
import { CoreService, addType } from "pmcf";
|
|
3
3
|
|
|
4
|
-
export class openldap extends
|
|
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" }
|
package/src/services/postfix.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CoreService, addType } from "pmcf";
|
|
2
2
|
|
|
3
|
-
export class postfix extends
|
|
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 {
|
|
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
|
|
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 {
|
|
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
|
|
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 {
|
|
2
|
+
import { CoreService, addType } from "pmcf";
|
|
3
3
|
import { filterConfigurable, sectionLines } from "../utils.mjs";
|
|
4
4
|
|
|
5
|
-
export class SystemdJournaldService extends
|
|
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 {
|
|
2
|
+
import { CoreService, addType } from "pmcf";
|
|
3
3
|
|
|
4
|
-
export class tailscale extends
|
|
4
|
+
export class tailscale extends CoreService {
|
|
5
5
|
static service = {
|
|
6
6
|
endpoints: [
|
|
7
7
|
{
|