@forgezero/agent 0.1.122 → 0.1.123

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.
@@ -917,7 +917,7 @@ async function postSignedNode(options, path, body) {
917
917
  }
918
918
 
919
919
  // src/version.ts
920
- var VERSION3 = "0.1.122";
920
+ var VERSION3 = "0.1.123";
921
921
 
922
922
  // src/agent-heartbeat.ts
923
923
  function readAgentHostMetrics() {
package/dist/bootstrap.js CHANGED
@@ -1460,7 +1460,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
1460
1460
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
1461
1461
 
1462
1462
  // src/version.ts
1463
- var VERSION = "0.1.122";
1463
+ var VERSION = "0.1.123";
1464
1464
 
1465
1465
  // src/software.ts
1466
1466
  var PINNED_BUN_VERSION = "1.3.14";
@@ -6,7 +6,9 @@ export declare const COMMUNITY_CREDENTIAL_PARENT = "/etc/forgezero-rehearsal";
6
6
  export declare const COMMUNITY_CREDENTIAL_ROOT = "/etc/forgezero-rehearsal/creds";
7
7
  export declare const COMMUNITY_REHEARSAL_STARTER_PORT = 18528;
8
8
  export declare const COMMUNITY_REHEARSAL_COORDINATOR_PORT = 18529;
9
+ export declare const COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE = "18528:18539";
9
10
  export declare const COMMUNITY_REHEARSAL_API_PORT = 18787;
11
+ export declare const COMMUNITY_REHEARSAL_FIREWALL_COMMENT = "fz-community-rehearsal";
10
12
  export interface CommunityRehearsalNode {
11
13
  name: string;
12
14
  address: string;
@@ -44,6 +46,8 @@ export type CommunityRehearsalHostRequest = {
44
46
  export type CommunityHostOperation = {
45
47
  kind: 'remove-tree';
46
48
  path: typeof COMMUNITY_DATABASE_ROOT | typeof COMMUNITY_REHEARSAL_ROOT | typeof COMMUNITY_CREDENTIAL_PARENT;
49
+ } | {
50
+ kind: 'clear-firewall';
47
51
  } | {
48
52
  kind: 'write';
49
53
  path: string;
@@ -70,5 +74,6 @@ export declare function planCommunityRehearsalPrepare(request: Extract<Community
70
74
  }>): CommunityHostOperation[];
71
75
  /** Remove only the dedicated rehearsal units, credentials, release and data. */
72
76
  export declare function planCommunityRehearsalCleanup(): CommunityHostOperation[];
77
+ export declare function communityRehearsalFirewallRuleNumbers(status: string): number[];
73
78
  /** Execute only the dedicated four-node rehearsal operation selected by a typed request. */
74
79
  export declare function runCommunityRehearsalHost(request: CommunityRehearsalHostRequest): Promise<Record<string, unknown>>;
@@ -574,7 +574,9 @@ var COMMUNITY_CREDENTIAL_PARENT = "/etc/forgezero-rehearsal";
574
574
  var COMMUNITY_CREDENTIAL_ROOT = "/etc/forgezero-rehearsal/creds";
575
575
  var COMMUNITY_REHEARSAL_STARTER_PORT = 18528;
576
576
  var COMMUNITY_REHEARSAL_COORDINATOR_PORT = 18529;
577
+ var COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE = "18528:18539";
577
578
  var COMMUNITY_REHEARSAL_API_PORT = 18787;
579
+ var COMMUNITY_REHEARSAL_FIREWALL_COMMENT = "fz-community-rehearsal";
578
580
  var RELEASE = /^[a-f0-9]{64}$/;
579
581
  var SAFE_NAME = /^[a-z][a-z0-9-]{0,62}$/;
580
582
  async function ensureCommunityRehearsalArango(execute = executeSoftwareOperation) {
@@ -737,6 +739,24 @@ function planCommunityRehearsalPrepare(request) {
737
739
  { kind: "exec", argv: ["/usr/sbin/arangod", "--version"] },
738
740
  { kind: "exec", argv: ["/usr/bin/systemctl", "stop", "forgezero-community-api.service"], accepted: [0, 5] },
739
741
  { kind: "exec", argv: ["/usr/bin/systemctl", "stop", "forgezero-rehearsal-db.service"], accepted: [0, 5] },
742
+ { kind: "clear-firewall" },
743
+ ...topology.map(({ address }) => ({
744
+ kind: "exec",
745
+ argv: [
746
+ "/usr/sbin/ufw",
747
+ "allow",
748
+ "from",
749
+ address,
750
+ "to",
751
+ "any",
752
+ "port",
753
+ COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE,
754
+ "proto",
755
+ "tcp",
756
+ "comment",
757
+ COMMUNITY_REHEARSAL_FIREWALL_COMMENT
758
+ ]
759
+ })),
740
760
  { kind: "remove-tree", path: COMMUNITY_DATABASE_ROOT },
741
761
  { kind: "exec", argv: ["/usr/bin/install", "-d", "-m", "0700", "-o", "root", "-g", "root", COMMUNITY_CREDENTIAL_ROOT] },
742
762
  { kind: "exec", argv: ["/usr/bin/install", "-d", "-m", "0700", "-o", "arangodb", "-g", "arangodb", COMMUNITY_DATABASE_ROOT] },
@@ -765,6 +785,7 @@ function planCommunityRehearsalCleanup() {
765
785
  { kind: "remove-tree", path: COMMUNITY_DATABASE_ROOT },
766
786
  { kind: "remove-tree", path: COMMUNITY_REHEARSAL_ROOT },
767
787
  { kind: "remove-tree", path: COMMUNITY_CREDENTIAL_PARENT },
788
+ { kind: "clear-firewall" },
768
789
  { kind: "exec", argv: ["/usr/bin/systemctl", "daemon-reload"] },
769
790
  { kind: "exec", argv: ["/usr/bin/systemctl", "reset-failed", "forgezero-community-api.service", "forgezero-rehearsal-db.service"], accepted: [0, 1, 5] }
770
791
  ];
@@ -784,6 +805,8 @@ async function applyOperations(operations) {
784
805
  for (const operation of operations) {
785
806
  if (operation.kind === "remove-tree")
786
807
  rmSync2(operation.path, { recursive: true, force: true });
808
+ else if (operation.kind === "clear-firewall")
809
+ await clearCommunityRehearsalFirewall();
787
810
  else if (operation.kind === "write") {
788
811
  mkdirSync2(dirname2(operation.path), { recursive: true });
789
812
  writeFileSync2(operation.path, operation.content, { mode: operation.mode });
@@ -806,6 +829,25 @@ async function applyOperations(operations) {
806
829
  }
807
830
  }
808
831
  }
832
+ function communityRehearsalFirewallRuleNumbers(status) {
833
+ return status.split(/\r?\n/).flatMap((line) => {
834
+ if (!line.includes(`# ${COMMUNITY_REHEARSAL_FIREWALL_COMMENT}`))
835
+ return [];
836
+ const match = line.match(/^\[\s*(\d+)\]/);
837
+ return match ? [Number(match[1])] : [];
838
+ }).filter((number) => Number.isSafeInteger(number) && number > 0).sort((left, right) => right - left);
839
+ }
840
+ async function clearCommunityRehearsalFirewall() {
841
+ const status = await exec(["/usr/sbin/ufw", "status", "numbered"]);
842
+ if (status.exitCode !== 0)
843
+ throw new Error(`unable to inspect rehearsal firewall rules: ${status.output.trim()}`);
844
+ for (const number of communityRehearsalFirewallRuleNumbers(status.output)) {
845
+ const removed = await exec(["/usr/sbin/ufw", "--force", "delete", String(number)]);
846
+ if (removed.exitCode !== 0) {
847
+ throw new Error(`unable to remove rehearsal firewall rule ${number}: ${removed.output.trim()}`);
848
+ }
849
+ }
850
+ }
809
851
  var responseFor = async (request) => {
810
852
  const base = `http://127.0.0.1:${COMMUNITY_REHEARSAL_API_PORT}`;
811
853
  if (request.operation === "health")
@@ -892,9 +934,12 @@ export {
892
934
  planCommunityRehearsalCleanup,
893
935
  parseCommunityRehearsalHostRequest,
894
936
  ensureCommunityRehearsalArango,
937
+ communityRehearsalFirewallRuleNumbers,
895
938
  COMMUNITY_REHEARSAL_VERSION,
896
939
  COMMUNITY_REHEARSAL_STARTER_PORT,
897
940
  COMMUNITY_REHEARSAL_ROOT,
941
+ COMMUNITY_REHEARSAL_FIREWALL_COMMENT,
942
+ COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE,
898
943
  COMMUNITY_REHEARSAL_COORDINATOR_PORT,
899
944
  COMMUNITY_REHEARSAL_API_PORT,
900
945
  COMMUNITY_DATABASE_ROOT,
package/dist/fz-agent.js CHANGED
@@ -9640,7 +9640,7 @@ async function writeAndCloseProcessInput(input, value) {
9640
9640
  }
9641
9641
 
9642
9642
  // src/version.ts
9643
- var VERSION2 = "0.1.122";
9643
+ var VERSION2 = "0.1.123";
9644
9644
 
9645
9645
  // src/ssh-bootstrap.ts
9646
9646
  class SshBootstrapError extends Error {
@@ -17122,7 +17122,9 @@ var COMMUNITY_CREDENTIAL_PARENT = "/etc/forgezero-rehearsal";
17122
17122
  var COMMUNITY_CREDENTIAL_ROOT = "/etc/forgezero-rehearsal/creds";
17123
17123
  var COMMUNITY_REHEARSAL_STARTER_PORT = 18528;
17124
17124
  var COMMUNITY_REHEARSAL_COORDINATOR_PORT = 18529;
17125
+ var COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE = "18528:18539";
17125
17126
  var COMMUNITY_REHEARSAL_API_PORT = 18787;
17127
+ var COMMUNITY_REHEARSAL_FIREWALL_COMMENT = "fz-community-rehearsal";
17126
17128
  var RELEASE = /^[a-f0-9]{64}$/;
17127
17129
  var SAFE_NAME2 = /^[a-z][a-z0-9-]{0,62}$/;
17128
17130
  async function ensureCommunityRehearsalArango(execute3 = executeSoftwareOperation) {
@@ -17285,6 +17287,24 @@ function planCommunityRehearsalPrepare(request) {
17285
17287
  { kind: "exec", argv: ["/usr/sbin/arangod", "--version"] },
17286
17288
  { kind: "exec", argv: ["/usr/bin/systemctl", "stop", "forgezero-community-api.service"], accepted: [0, 5] },
17287
17289
  { kind: "exec", argv: ["/usr/bin/systemctl", "stop", "forgezero-rehearsal-db.service"], accepted: [0, 5] },
17290
+ { kind: "clear-firewall" },
17291
+ ...topology.map(({ address }) => ({
17292
+ kind: "exec",
17293
+ argv: [
17294
+ "/usr/sbin/ufw",
17295
+ "allow",
17296
+ "from",
17297
+ address,
17298
+ "to",
17299
+ "any",
17300
+ "port",
17301
+ COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE,
17302
+ "proto",
17303
+ "tcp",
17304
+ "comment",
17305
+ COMMUNITY_REHEARSAL_FIREWALL_COMMENT
17306
+ ]
17307
+ })),
17288
17308
  { kind: "remove-tree", path: COMMUNITY_DATABASE_ROOT },
17289
17309
  { kind: "exec", argv: ["/usr/bin/install", "-d", "-m", "0700", "-o", "root", "-g", "root", COMMUNITY_CREDENTIAL_ROOT] },
17290
17310
  { kind: "exec", argv: ["/usr/bin/install", "-d", "-m", "0700", "-o", "arangodb", "-g", "arangodb", COMMUNITY_DATABASE_ROOT] },
@@ -17313,6 +17333,7 @@ function planCommunityRehearsalCleanup() {
17313
17333
  { kind: "remove-tree", path: COMMUNITY_DATABASE_ROOT },
17314
17334
  { kind: "remove-tree", path: COMMUNITY_REHEARSAL_ROOT },
17315
17335
  { kind: "remove-tree", path: COMMUNITY_CREDENTIAL_PARENT },
17336
+ { kind: "clear-firewall" },
17316
17337
  { kind: "exec", argv: ["/usr/bin/systemctl", "daemon-reload"] },
17317
17338
  { kind: "exec", argv: ["/usr/bin/systemctl", "reset-failed", "forgezero-community-api.service", "forgezero-rehearsal-db.service"], accepted: [0, 1, 5] }
17318
17339
  ];
@@ -17332,6 +17353,8 @@ async function applyOperations(operations) {
17332
17353
  for (const operation of operations) {
17333
17354
  if (operation.kind === "remove-tree")
17334
17355
  rmSync13(operation.path, { recursive: true, force: true });
17356
+ else if (operation.kind === "clear-firewall")
17357
+ await clearCommunityRehearsalFirewall();
17335
17358
  else if (operation.kind === "write") {
17336
17359
  mkdirSync17(dirname15(operation.path), { recursive: true });
17337
17360
  writeFileSync17(operation.path, operation.content, { mode: operation.mode });
@@ -17354,6 +17377,25 @@ async function applyOperations(operations) {
17354
17377
  }
17355
17378
  }
17356
17379
  }
17380
+ function communityRehearsalFirewallRuleNumbers(status) {
17381
+ return status.split(/\r?\n/).flatMap((line) => {
17382
+ if (!line.includes(`# ${COMMUNITY_REHEARSAL_FIREWALL_COMMENT}`))
17383
+ return [];
17384
+ const match = line.match(/^\[\s*(\d+)\]/);
17385
+ return match ? [Number(match[1])] : [];
17386
+ }).filter((number2) => Number.isSafeInteger(number2) && number2 > 0).sort((left, right) => right - left);
17387
+ }
17388
+ async function clearCommunityRehearsalFirewall() {
17389
+ const status = await exec(["/usr/sbin/ufw", "status", "numbered"]);
17390
+ if (status.exitCode !== 0)
17391
+ throw new Error(`unable to inspect rehearsal firewall rules: ${status.output.trim()}`);
17392
+ for (const number2 of communityRehearsalFirewallRuleNumbers(status.output)) {
17393
+ const removed = await exec(["/usr/sbin/ufw", "--force", "delete", String(number2)]);
17394
+ if (removed.exitCode !== 0) {
17395
+ throw new Error(`unable to remove rehearsal firewall rule ${number2}: ${removed.output.trim()}`);
17396
+ }
17397
+ }
17398
+ }
17357
17399
  var responseFor = async (request) => {
17358
17400
  const base = `http://127.0.0.1:${COMMUNITY_REHEARSAL_API_PORT}`;
17359
17401
  if (request.operation === "health")
package/dist/fz.js CHANGED
@@ -4844,7 +4844,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
4844
4844
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
4845
4845
 
4846
4846
  // src/version.ts
4847
- var VERSION2 = "0.1.122";
4847
+ var VERSION2 = "0.1.123";
4848
4848
 
4849
4849
  // src/software.ts
4850
4850
  var PINNED_BUN_VERSION = "1.3.14";
@@ -366,7 +366,7 @@ function systemdAgentEgressDirectives(loopbackTcpPorts = []) {
366
366
  }
367
367
 
368
368
  // src/version.ts
369
- var VERSION = "0.1.122";
369
+ var VERSION = "0.1.123";
370
370
 
371
371
  // src/otel-collector.ts
372
372
  var FORGEZERO_OTEL_COLLECTOR_UNIT = "forgezero-otel-collector.service";
@@ -1460,7 +1460,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
1460
1460
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
1461
1461
 
1462
1462
  // src/version.ts
1463
- var VERSION = "0.1.122";
1463
+ var VERSION = "0.1.123";
1464
1464
 
1465
1465
  // src/software.ts
1466
1466
  var PINNED_BUN_VERSION = "1.3.14";
@@ -3020,7 +3020,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
3020
3020
  }
3021
3021
 
3022
3022
  // src/version.ts
3023
- var VERSION3 = "0.1.122";
3023
+ var VERSION3 = "0.1.123";
3024
3024
 
3025
3025
  // src/egress-policy.ts
3026
3026
  import { realpathSync as realpathSync3 } from "node:fs";
package/dist/provision.js CHANGED
@@ -3020,7 +3020,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
3020
3020
  }
3021
3021
 
3022
3022
  // src/version.ts
3023
- var VERSION3 = "0.1.122";
3023
+ var VERSION3 = "0.1.123";
3024
3024
 
3025
3025
  // src/egress-policy.ts
3026
3026
  import { realpathSync as realpathSync3 } from "node:fs";
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** One package version shared by both public binaries. Pinned to package.json by tests. */
2
- export declare const VERSION = "0.1.122";
2
+ export declare const VERSION = "0.1.123";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgezero/agent",
3
- "version": "0.1.122",
3
+ "version": "0.1.123",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "check": "tsc --noEmit",