pmcf 6.61.5 → 6.61.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmcf",
3
- "version": "6.61.5",
3
+ "version": "6.61.6",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/src/cluster.mjs CHANGED
@@ -1,14 +1,9 @@
1
- import { join } from "node:path";
2
- import { FAMILY_IPV4 } from "ip-utilties";
3
- import { duration_attribute_writable } from "pacc";
4
1
  import { host } from "./host.mjs";
5
- import { serviceEndpoints } from "./core-service.mjs";
6
2
  import { addType } from "./type.mjs";
7
3
  import {
8
4
  networkInterfaces_attribute,
9
5
  cluster_attribute
10
6
  } from "./common-attributes.mjs";
11
- import { writeLines } from "./utils.mjs";
12
7
 
13
8
  export class cluster extends host {
14
9
  static priority = 1.5;
@@ -26,11 +21,6 @@ export class cluster extends host {
26
21
  members: {
27
22
  ...networkInterfaces_attribute,
28
23
  name: "members"
29
- },
30
- checkInterval: {
31
- ...duration_attribute_writable,
32
- name: "checkInterval",
33
- default: 60
34
24
  }
35
25
  };
36
26
 
@@ -40,7 +30,6 @@ export class cluster extends host {
40
30
 
41
31
  masters = [];
42
32
  backups = [];
43
- checkInterval = 60;
44
33
 
45
34
  get members() {
46
35
  return new Set(this.masters).union(new Set(this.backups));
@@ -61,197 +50,4 @@ export class cluster extends host {
61
50
  get content() {
62
51
  return [...this.hosts.values()][0]?.content;
63
52
  }
64
-
65
- async *preparePackages(stagingDir) {
66
- for (const ni of [...this.owner.clusters.values()].reduce(
67
- (all, cluster) => all.union(cluster.members),
68
- new Set()
69
- )) {
70
- const host = ni.host;
71
-
72
- const packageStagingDir = join(stagingDir, host.name);
73
- const packageData = await host.preparePackage({ dir: packageStagingDir });
74
-
75
- const extra = [];
76
-
77
- const smtp = this.smtp;
78
-
79
- if (smtp) {
80
- extra.push(` smtp_server ${smtp.address()}`);
81
- }
82
-
83
- const cfg = [
84
- "global_defs {",
85
- " notification_email {",
86
- " " + this.administratorEmail,
87
- " }",
88
- ...extra,
89
- ` notification_email_from keepalived@${host.domainName}`,
90
- " enable_script_security",
91
- " script_user root",
92
- " max_auto_priority 20",
93
- "}",
94
- ""
95
- ];
96
-
97
- const credentials = new Map();
98
- for (const cluster of [...this.owner.clusters.values()].sort((a, b) =>
99
- a.name.localeCompare(b.name)
100
- )) {
101
- const name = cluster.name;
102
- cfg.push(`vrrp_instance ${name} {`);
103
- cfg.push(
104
- ` state ${cluster.masters.indexOf(ni) === 0 ? "MASTER" : "BACKUP"}`
105
- );
106
- cfg.push(` interface ${ni.name}`);
107
-
108
- for (const na of cluster.networkAddresses(
109
- na => na.networkInterface.kind !== "loopback"
110
- )) {
111
- cfg.push(
112
- ` ${
113
- na.family === FAMILY_IPV4
114
- ? "virtual_ipaddress"
115
- : "virtual_ipaddress_excluded"
116
- } {`
117
- );
118
- cfg.push(` ${na.cidrAddress} dev ${ni.name} label ${name}`);
119
- cfg.push(" }");
120
- }
121
-
122
- cfg.push(` virtual_router_id ${cluster.id}`);
123
-
124
- let reducedPrio = cluster.masters.indexOf(ni);
125
- if (reducedPrio < 0) {
126
- reducedPrio = cluster.backups.indexOf(ni) + 5;
127
- }
128
-
129
- const credential = name.toUpperCase() + "_PASSWORD";
130
- credentials.set(credential, name);
131
- cfg.push(` priority ${host.priority - reducedPrio}`);
132
- cfg.push(" smtp_alert");
133
- cfg.push(" advert_int 5");
134
- cfg.push(" authentication {");
135
- cfg.push(" auth_type PASS");
136
- cfg.push(" auth_pass pass1234");
137
- cfg.push(" # auth_pass ${_ENV " + credential + "}");
138
- cfg.push(" # auth_pass ${" + credential + "}");
139
- cfg.push(" }");
140
-
141
- cfg.push(
142
- ` notify_master "/usr/bin/systemctl start ${name}-master.target"`,
143
- ` notify_backup "/usr/bin/systemctl start ${name}-backup.target"`,
144
- ` notify_fault "/usr/bin/systemctl start ${name}-fault.target"`
145
- );
146
-
147
- cfg.push("}", "");
148
-
149
- for (const endpoint of serviceEndpoints(cluster, {
150
- services: "services[types[http]]",
151
- endpoints: e =>
152
- e.networkInterface && e.networkInterface.kind !== "loopback"
153
- })) {
154
- cfg.push(`virtual_server ${cluster.address} ${endpoint.port} {`);
155
- cfg.push(` delay_loop ${cluster.checkInterval}`);
156
- cfg.push(" lb_algo wlc");
157
- cfg.push(" persistence_timeout 600");
158
- cfg.push(` protocol ${endpoint.protocol.toUpperCase()}`);
159
-
160
- for (const member of this.members) {
161
- const memberService = member.expression(
162
- `services[types[${endpoint.type}]][0]`
163
- );
164
-
165
- console.log(
166
- member.fullName,
167
- endpoint.type,
168
- memberService?.fullName
169
- );
170
- cfg.push(` real_server ${member.address} ${memberService.port} {`);
171
- cfg.push(` weight ${memberService.weight}`);
172
-
173
- switch (endpoint.type) {
174
- case "dns":
175
- cfg.push(` DNS_CHECK {`);
176
- cfg.push(" type A");
177
- cfg.push(" name google.com");
178
- cfg.push(" }");
179
- break;
180
- case "smtp":
181
- cfg.push(` SMTP_CHECK {`);
182
- cfg.push(" }");
183
- break;
184
-
185
- default:
186
- switch (endpoint.protocol) {
187
- case PROTOCOL_TCP:
188
- cfg.push(` TCP_CHECK {`);
189
- cfg.push(" connect_timeout 10");
190
- cfg.push(" }");
191
- break;
192
- }
193
- }
194
-
195
- cfg.push(" }");
196
- }
197
-
198
- cfg.push("}", "");
199
- break; // only one for now
200
- }
201
- await writeLines(
202
- join(packageStagingDir, "/usr/lib/systemd/system"),
203
- `${name}-master.target`,
204
- [
205
- "[Unit]",
206
- `Description=master state of cluster ${name}`,
207
- "PartOf=keepalived.service",
208
- `Conflicts=${name}-backup.target ${name}-fault.target`
209
- ]
210
- );
211
-
212
- await writeLines(
213
- join(packageStagingDir, "/usr/lib/systemd/system"),
214
- `${name}-backup.target`,
215
- [
216
- "[Unit]",
217
- `Description=backup state of cluster ${name}`,
218
- "PartOf=keepalived.service",
219
- `Conflicts=${name}-master.target ${name}-fault.target`
220
- ]
221
- );
222
-
223
- await writeLines(
224
- join(packageStagingDir, "/usr/lib/systemd/system"),
225
- `${name}-fault.target`,
226
- [
227
- "[Unit]",
228
- `Description=fault state of cluster ${name}`,
229
- `Conflicts=${name}-master.target ${name}-backup.target`
230
- ]
231
- );
232
-
233
- await writeLines(
234
- join(packageStagingDir, "/usr/lib/systemd/system/keepalived.d"),
235
- "credentials.conf",
236
- [
237
- "[Service]",
238
- ...credentials
239
- .entries()
240
- .map(
241
- ([credName, instance]) =>
242
- `LoadCredentialEncrypted=${credName}:/etc/credstore.encrypted/keepalived.${instance}.password`
243
- )
244
- ]
245
- );
246
- }
247
-
248
- await writeLines(
249
- join(packageStagingDir, "etc/keepalived"),
250
- "keepalived.conf",
251
- cfg
252
- );
253
-
254
- yield packageData;
255
- }
256
- }
257
53
  }
@@ -1,6 +1,11 @@
1
+ import { join } from "node:path";
1
2
  import { duration_attribute_writable } from "pacc";
2
3
  import { addType } from "./type.mjs";
3
4
  import { cluster } from "./cluster.mjs";
5
+ import { FAMILY_IPV4 } from "ip-utilties";
6
+ import { serviceEndpoints } from "./core-service.mjs";
7
+ import { PROTOCOL_TCP } from "./constants.mjs";
8
+ import { writeLines } from "./utils.mjs";
4
9
 
5
10
  export class keepalived extends cluster {
6
11
  static priority = 1.5;
@@ -15,4 +20,199 @@ export class keepalived extends cluster {
15
20
  static {
16
21
  addType(this);
17
22
  }
23
+
24
+ checkInterval = 60;
25
+
26
+ async *preparePackages(stagingDir) {
27
+ for (const ni of [...this.owner.clusters.values()].reduce(
28
+ (all, cluster) => all.union(cluster.members),
29
+ new Set()
30
+ )) {
31
+ const host = ni.host;
32
+
33
+ const packageStagingDir = join(stagingDir, host.name);
34
+ const packageData = await host.preparePackage({ dir: packageStagingDir });
35
+
36
+ const extra = [];
37
+
38
+ const smtp = this.smtp;
39
+
40
+ if (smtp) {
41
+ extra.push(` smtp_server ${smtp.address()}`);
42
+ }
43
+
44
+ const cfg = [
45
+ "global_defs {",
46
+ " notification_email {",
47
+ " " + this.administratorEmail,
48
+ " }",
49
+ ...extra,
50
+ ` notification_email_from keepalived@${host.domainName}`,
51
+ " enable_script_security",
52
+ " script_user root",
53
+ " max_auto_priority 20",
54
+ "}",
55
+ ""
56
+ ];
57
+
58
+ const credentials = new Map();
59
+ for (const cluster of [...this.owner.clusters.values()].sort((a, b) =>
60
+ a.name.localeCompare(b.name)
61
+ )) {
62
+ const name = cluster.name;
63
+ cfg.push(`vrrp_instance ${name} {`);
64
+ cfg.push(
65
+ ` state ${cluster.masters.indexOf(ni) === 0 ? "MASTER" : "BACKUP"}`
66
+ );
67
+ cfg.push(` interface ${ni.name}`);
68
+
69
+ for (const na of cluster.networkAddresses(
70
+ na => na.networkInterface.kind !== "loopback"
71
+ )) {
72
+ cfg.push(
73
+ ` ${
74
+ na.family === FAMILY_IPV4
75
+ ? "virtual_ipaddress"
76
+ : "virtual_ipaddress_excluded"
77
+ } {`
78
+ );
79
+ cfg.push(` ${na.cidrAddress} dev ${ni.name} label ${name}`);
80
+ cfg.push(" }");
81
+ }
82
+
83
+ cfg.push(` virtual_router_id ${cluster.id}`);
84
+
85
+ let reducedPrio = cluster.masters.indexOf(ni);
86
+ if (reducedPrio < 0) {
87
+ reducedPrio = cluster.backups.indexOf(ni) + 5;
88
+ }
89
+
90
+ const credential = name.toUpperCase() + "_PASSWORD";
91
+ credentials.set(credential, name);
92
+ cfg.push(` priority ${host.priority - reducedPrio}`);
93
+ cfg.push(" smtp_alert");
94
+ cfg.push(" advert_int 5");
95
+ cfg.push(" authentication {");
96
+ cfg.push(" auth_type PASS");
97
+ cfg.push(" auth_pass pass1234");
98
+ cfg.push(" # auth_pass ${_ENV " + credential + "}");
99
+ cfg.push(" # auth_pass ${" + credential + "}");
100
+ cfg.push(" }");
101
+
102
+ cfg.push(
103
+ ` notify_master "/usr/bin/systemctl start ${name}-master.target"`,
104
+ ` notify_backup "/usr/bin/systemctl start ${name}-backup.target"`,
105
+ ` notify_fault "/usr/bin/systemctl start ${name}-fault.target"`
106
+ );
107
+
108
+ cfg.push("}", "");
109
+
110
+ for (const endpoint of serviceEndpoints(cluster, {
111
+ services: "services[types[http]]",
112
+ endpoints: e =>
113
+ e.networkInterface && e.networkInterface.kind !== "loopback"
114
+ })) {
115
+ cfg.push(`virtual_server ${cluster.address} ${endpoint.port} {`);
116
+ cfg.push(` delay_loop ${cluster.checkInterval}`);
117
+ cfg.push(" lb_algo wlc");
118
+ cfg.push(" persistence_timeout 600");
119
+ cfg.push(` protocol ${endpoint.protocol.toUpperCase()}`);
120
+
121
+ for (const member of this.members) {
122
+ const memberService = member.expression(
123
+ `services[types[${endpoint.type}]][0]`
124
+ );
125
+
126
+ console.log(
127
+ member.fullName,
128
+ endpoint.type,
129
+ memberService?.fullName
130
+ );
131
+ cfg.push(` real_server ${member.address} ${memberService.port} {`);
132
+ cfg.push(` weight ${memberService.weight}`);
133
+
134
+ switch (endpoint.type) {
135
+ case "dns":
136
+ cfg.push(` DNS_CHECK {`);
137
+ cfg.push(" type A");
138
+ cfg.push(" name google.com");
139
+ cfg.push(" }");
140
+ break;
141
+ case "smtp":
142
+ cfg.push(` SMTP_CHECK {`);
143
+ cfg.push(" }");
144
+ break;
145
+
146
+ default:
147
+ switch (endpoint.protocol) {
148
+ case PROTOCOL_TCP:
149
+ cfg.push(` TCP_CHECK {`);
150
+ cfg.push(" connect_timeout 10");
151
+ cfg.push(" }");
152
+ break;
153
+ }
154
+ }
155
+
156
+ cfg.push(" }");
157
+ }
158
+
159
+ cfg.push("}", "");
160
+ break; // only one for now
161
+ }
162
+ await writeLines(
163
+ join(packageStagingDir, "/usr/lib/systemd/system"),
164
+ `${name}-master.target`,
165
+ [
166
+ "[Unit]",
167
+ `Description=master state of cluster ${name}`,
168
+ "PartOf=keepalived.service",
169
+ `Conflicts=${name}-backup.target ${name}-fault.target`
170
+ ]
171
+ );
172
+
173
+ await writeLines(
174
+ join(packageStagingDir, "/usr/lib/systemd/system"),
175
+ `${name}-backup.target`,
176
+ [
177
+ "[Unit]",
178
+ `Description=backup state of cluster ${name}`,
179
+ "PartOf=keepalived.service",
180
+ `Conflicts=${name}-master.target ${name}-fault.target`
181
+ ]
182
+ );
183
+
184
+ await writeLines(
185
+ join(packageStagingDir, "/usr/lib/systemd/system"),
186
+ `${name}-fault.target`,
187
+ [
188
+ "[Unit]",
189
+ `Description=fault state of cluster ${name}`,
190
+ `Conflicts=${name}-master.target ${name}-backup.target`
191
+ ]
192
+ );
193
+
194
+ await writeLines(
195
+ join(packageStagingDir, "/usr/lib/systemd/system/keepalived.d"),
196
+ "credentials.conf",
197
+ [
198
+ "[Service]",
199
+ ...credentials
200
+ .entries()
201
+ .map(
202
+ ([credName, instance]) =>
203
+ `LoadCredentialEncrypted=${credName}:/etc/credstore.encrypted/keepalived.${instance}.password`
204
+ )
205
+ ]
206
+ );
207
+ }
208
+
209
+ await writeLines(
210
+ join(packageStagingDir, "etc/keepalived"),
211
+ "keepalived.conf",
212
+ cfg
213
+ );
214
+
215
+ yield packageData;
216
+ }
217
+ }
18
218
  }