@superyachttimes/cli 1.2.0 → 1.4.0
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/dist/aws/route53.d.ts +10 -0
- package/dist/aws/route53.d.ts.map +1 -0
- package/dist/aws/route53.js +78 -0
- package/dist/aws/route53.js.map +1 -0
- package/dist/commands/nodejs-api-env.d.ts +2 -0
- package/dist/commands/nodejs-api-env.d.ts.map +1 -0
- package/dist/commands/nodejs-api-env.js +152 -0
- package/dist/commands/nodejs-api-env.js.map +1 -0
- package/dist/commands/recreate-nodejs-api.d.ts +5 -0
- package/dist/commands/recreate-nodejs-api.d.ts.map +1 -1
- package/dist/commands/recreate-nodejs-api.js +16 -103
- package/dist/commands/recreate-nodejs-api.js.map +1 -1
- package/dist/commands/sync-ec2-route53.d.ts +2 -0
- package/dist/commands/sync-ec2-route53.d.ts.map +1 -0
- package/dist/commands/sync-ec2-route53.js +96 -0
- package/dist/commands/sync-ec2-route53.js.map +1 -0
- package/dist/config.d.ts +12 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -0
- package/dist/config.js.map +1 -1
- package/dist/index.js +22 -2
- package/dist/index.js.map +1 -1
- package/dist/portainer/api.d.ts +7 -0
- package/dist/portainer/api.d.ts.map +1 -1
- package/dist/portainer/api.js +34 -0
- package/dist/portainer/api.js.map +1 -1
- package/dist/portainer/env.d.ts +30 -0
- package/dist/portainer/env.d.ts.map +1 -0
- package/dist/portainer/env.js +88 -0
- package/dist/portainer/env.js.map +1 -0
- package/dist/portainer/recreate.d.ts +16 -0
- package/dist/portainer/recreate.d.ts.map +1 -0
- package/dist/portainer/recreate.js +138 -0
- package/dist/portainer/recreate.js.map +1 -0
- package/dist/portainer/urls.d.ts +2 -0
- package/dist/portainer/urls.d.ts.map +1 -1
- package/dist/portainer/urls.js +2 -0
- package/dist/portainer/urls.js.map +1 -1
- package/package.json +6 -3
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AwsOptions } from "./ec2.js";
|
|
2
|
+
export interface DesiredRecord {
|
|
3
|
+
name: string;
|
|
4
|
+
ip: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function slugify(name: string): string;
|
|
7
|
+
export declare function resolveHostedZoneId(opts: AwsOptions, zoneName: string): Promise<string>;
|
|
8
|
+
export declare function listARecords(opts: AwsOptions, zoneId: string): Promise<Map<string, string>>;
|
|
9
|
+
export declare function upsertARecords(opts: AwsOptions, zoneId: string, records: DesiredRecord[], ttl: number): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=route53.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route53.d.ts","sourceRoot":"","sources":["../../src/aws/route53.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAWD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM5C;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAYjB;AAGD,wBAAsB,YAAY,CAChC,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA4B9B;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,aAAa,EAAE,EACxB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC,CAmBf"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Route53Client, ListHostedZonesByNameCommand, ListResourceRecordSetsCommand, ChangeResourceRecordSetsCommand, } from "@aws-sdk/client-route-53";
|
|
2
|
+
import { fromIni } from "@aws-sdk/credential-providers";
|
|
3
|
+
function createClient(opts) {
|
|
4
|
+
return new Route53Client({
|
|
5
|
+
region: opts.region,
|
|
6
|
+
credentials: fromIni({ profile: opts.profile }),
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
// Lowercase; keep [a-z0-9_-]; replace any other run with "-";
|
|
10
|
+
// collapse repeated hyphens; trim leading/trailing hyphens.
|
|
11
|
+
export function slugify(name) {
|
|
12
|
+
return name
|
|
13
|
+
.toLowerCase()
|
|
14
|
+
.replace(/[^a-z0-9_-]+/g, "-")
|
|
15
|
+
.replace(/-+/g, "-")
|
|
16
|
+
.replace(/^-+|-+$/g, "");
|
|
17
|
+
}
|
|
18
|
+
export async function resolveHostedZoneId(opts, zoneName) {
|
|
19
|
+
const client = createClient(opts);
|
|
20
|
+
const target = zoneName.endsWith(".") ? zoneName : `${zoneName}.`;
|
|
21
|
+
const res = await client.send(new ListHostedZonesByNameCommand({ DNSName: target }));
|
|
22
|
+
const zone = (res.HostedZones ?? []).find((z) => z.Name === target);
|
|
23
|
+
if (!zone?.Id) {
|
|
24
|
+
throw new Error(`Route53 hosted zone "${zoneName}" not found.`);
|
|
25
|
+
}
|
|
26
|
+
// Id looks like "/hostedzone/Z123..."; strip the prefix.
|
|
27
|
+
return zone.Id.replace(/^\/hostedzone\//, "");
|
|
28
|
+
}
|
|
29
|
+
// Returns a map of fully-qualified A-record name (no trailing dot) -> IP value.
|
|
30
|
+
export async function listARecords(opts, zoneId) {
|
|
31
|
+
const client = createClient(opts);
|
|
32
|
+
const records = new Map();
|
|
33
|
+
let startName;
|
|
34
|
+
let startType;
|
|
35
|
+
let startIdentifier;
|
|
36
|
+
let truncated = true;
|
|
37
|
+
while (truncated) {
|
|
38
|
+
const res = await client.send(new ListResourceRecordSetsCommand({
|
|
39
|
+
HostedZoneId: zoneId,
|
|
40
|
+
StartRecordName: startName,
|
|
41
|
+
StartRecordType: startType,
|
|
42
|
+
StartRecordIdentifier: startIdentifier,
|
|
43
|
+
}));
|
|
44
|
+
for (const rr of res.ResourceRecordSets ?? []) {
|
|
45
|
+
if (rr.Type !== "A" || !rr.Name)
|
|
46
|
+
continue;
|
|
47
|
+
const ip = rr.ResourceRecords?.[0]?.Value;
|
|
48
|
+
if (!ip)
|
|
49
|
+
continue;
|
|
50
|
+
records.set(rr.Name.replace(/\.$/, ""), ip);
|
|
51
|
+
}
|
|
52
|
+
truncated = Boolean(res.IsTruncated);
|
|
53
|
+
startName = res.NextRecordName;
|
|
54
|
+
startType = res.NextRecordType;
|
|
55
|
+
startIdentifier = res.NextRecordIdentifier;
|
|
56
|
+
}
|
|
57
|
+
return records;
|
|
58
|
+
}
|
|
59
|
+
export async function upsertARecords(opts, zoneId, records, ttl) {
|
|
60
|
+
if (records.length === 0)
|
|
61
|
+
return;
|
|
62
|
+
const client = createClient(opts);
|
|
63
|
+
await client.send(new ChangeResourceRecordSetsCommand({
|
|
64
|
+
HostedZoneId: zoneId,
|
|
65
|
+
ChangeBatch: {
|
|
66
|
+
Changes: records.map((r) => ({
|
|
67
|
+
Action: "UPSERT",
|
|
68
|
+
ResourceRecordSet: {
|
|
69
|
+
Name: r.name,
|
|
70
|
+
Type: "A",
|
|
71
|
+
TTL: ttl,
|
|
72
|
+
ResourceRecords: [{ Value: r.ip }],
|
|
73
|
+
},
|
|
74
|
+
})),
|
|
75
|
+
},
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=route53.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route53.js","sourceRoot":"","sources":["../../src/aws/route53.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodejs-api-env.d.ts","sourceRoot":"","sources":["../../src/commands/nodejs-api-env.ts"],"names":[],"mappings":"AAsJA,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBhE"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { confirm, input, select } from "@inquirer/prompts";
|
|
2
|
+
import { loadConfig } from "../config.js";
|
|
3
|
+
import * as portainer from "../portainer/api.js";
|
|
4
|
+
import { applyEnvChanges, assertValidKey, envValue, hasChanges, parseAssignments, summariseEnv, } from "../portainer/env.js";
|
|
5
|
+
import { recreateContainer } from "../portainer/recreate.js";
|
|
6
|
+
const USAGE = `Usage:
|
|
7
|
+
syt-cli nodejs-api-env list [--show KEY]
|
|
8
|
+
syt-cli nodejs-api-env set KEY=VALUE [KEY=VALUE...] [--dry-run] [--yes]
|
|
9
|
+
syt-cli nodejs-api-env unset KEY [KEY...] [--dry-run] [--yes]
|
|
10
|
+
|
|
11
|
+
Changes recreate each api-nodejs container one host at a time, with the same
|
|
12
|
+
image (no pull). Existing values are never printed except with list --show.`;
|
|
13
|
+
const hostLabel = (instance) => new URL(instance.portainerUrl).hostname.split(".")[0];
|
|
14
|
+
async function readEnv(instance) {
|
|
15
|
+
const container = await portainer.getContainer({
|
|
16
|
+
portainerUrl: instance.portainerUrl,
|
|
17
|
+
portainerEndpointId: instance.portainerEndpointId,
|
|
18
|
+
portainerApiKey: instance.portainerApiKey,
|
|
19
|
+
portainerContainerName: instance.portainerContainerName,
|
|
20
|
+
});
|
|
21
|
+
return container.Config.Env ?? [];
|
|
22
|
+
}
|
|
23
|
+
async function list(instances, show) {
|
|
24
|
+
const hosts = await Promise.all(instances.map(async (i) => ({ host: hostLabel(i), env: await readEnv(i) })));
|
|
25
|
+
if (show) {
|
|
26
|
+
for (const h of hosts) {
|
|
27
|
+
const value = envValue(h.env, show);
|
|
28
|
+
console.log(`${h.host} ${show}=${value === undefined ? "(not set)" : value}`);
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
for (const row of summariseEnv(hosts)) {
|
|
33
|
+
const note = row.status === "missing"
|
|
34
|
+
? ` missing on ${row.missingOn.join(", ")}`
|
|
35
|
+
: row.status === "differs"
|
|
36
|
+
? " differs between hosts"
|
|
37
|
+
: "";
|
|
38
|
+
console.log(`${row.name}${note}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function change(instances, changes, opts) {
|
|
42
|
+
const plan = await Promise.all(instances.map(async (instance) => {
|
|
43
|
+
const { outcomes } = applyEnvChanges(await readEnv(instance), changes);
|
|
44
|
+
return { instance, outcomes };
|
|
45
|
+
}));
|
|
46
|
+
for (const { instance, outcomes } of plan) {
|
|
47
|
+
const parts = Object.entries(outcomes).map(([k, o]) => `${k} ${o}`);
|
|
48
|
+
console.log(`${hostLabel(instance)}: ${parts.join(", ")}`);
|
|
49
|
+
}
|
|
50
|
+
const todo = plan.filter((p) => hasChanges(p.outcomes));
|
|
51
|
+
if (todo.length === 0) {
|
|
52
|
+
console.log("\nNothing to change.");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (opts.dryRun) {
|
|
56
|
+
console.log(`\nDry run: ${todo.length} host(s) would be recreated.`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (!opts.yes) {
|
|
60
|
+
const ok = await confirm({
|
|
61
|
+
message: `Recreate ${todo.length} host(s) one at a time (same image, no pull)?`,
|
|
62
|
+
default: false,
|
|
63
|
+
});
|
|
64
|
+
if (!ok) {
|
|
65
|
+
console.log("Aborted.");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (const [i, { instance }] of todo.entries()) {
|
|
70
|
+
const prefix = `[${hostLabel(instance)}]`;
|
|
71
|
+
const log = (msg) => console.log(`${prefix} ${msg}`);
|
|
72
|
+
try {
|
|
73
|
+
await recreateContainer(instance, {
|
|
74
|
+
pull: false,
|
|
75
|
+
transformEnv: (env) => applyEnvChanges(env, changes).env,
|
|
76
|
+
log,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
throw new Error(`${prefix} failed: ${err.message}. ${i}/${todo.length} host(s) were changed; the rest were not touched.`);
|
|
81
|
+
}
|
|
82
|
+
const after = applyEnvChanges(await readEnv(instance), changes).outcomes;
|
|
83
|
+
if (hasChanges(after)) {
|
|
84
|
+
throw new Error(`${prefix} recreated, but the env does not match the requested change`);
|
|
85
|
+
}
|
|
86
|
+
log("Done.");
|
|
87
|
+
}
|
|
88
|
+
console.log(`\n${todo.length} host(s) updated.`);
|
|
89
|
+
}
|
|
90
|
+
function parseFlags(args) {
|
|
91
|
+
const rest = [];
|
|
92
|
+
let dryRun = false;
|
|
93
|
+
let yes = false;
|
|
94
|
+
let show;
|
|
95
|
+
for (let i = 0; i < args.length; i++) {
|
|
96
|
+
const a = args[i];
|
|
97
|
+
if (a === "--dry-run")
|
|
98
|
+
dryRun = true;
|
|
99
|
+
else if (a === "--yes" || a === "-y")
|
|
100
|
+
yes = true;
|
|
101
|
+
else if (a === "--show")
|
|
102
|
+
show = args[++i];
|
|
103
|
+
else
|
|
104
|
+
rest.push(a);
|
|
105
|
+
}
|
|
106
|
+
return { rest, dryRun, yes, show };
|
|
107
|
+
}
|
|
108
|
+
async function promptForArgs() {
|
|
109
|
+
const action = await select({
|
|
110
|
+
message: "What do you want to do?",
|
|
111
|
+
choices: [
|
|
112
|
+
{ name: "List variable names", value: "list" },
|
|
113
|
+
{ name: "Show one variable's value", value: "show" },
|
|
114
|
+
{ name: "Set a variable", value: "set" },
|
|
115
|
+
{ name: "Unset a variable", value: "unset" },
|
|
116
|
+
],
|
|
117
|
+
});
|
|
118
|
+
if (action === "list")
|
|
119
|
+
return ["list"];
|
|
120
|
+
if (action === "show")
|
|
121
|
+
return ["list", "--show", await input({ message: "Variable name" })];
|
|
122
|
+
if (action === "set")
|
|
123
|
+
return ["set", await input({ message: "KEY=VALUE" })];
|
|
124
|
+
return ["unset", await input({ message: "Variable name" })];
|
|
125
|
+
}
|
|
126
|
+
export async function nodejsApiEnv(argv) {
|
|
127
|
+
const args = argv.length > 0 ? argv : await promptForArgs();
|
|
128
|
+
const [sub, ...restArgs] = args;
|
|
129
|
+
const { rest, dryRun, yes, show } = parseFlags(restArgs);
|
|
130
|
+
const instances = loadConfig().nodejsApi;
|
|
131
|
+
switch (sub) {
|
|
132
|
+
case "list":
|
|
133
|
+
if (show !== undefined)
|
|
134
|
+
assertValidKey(show);
|
|
135
|
+
await list(instances, show);
|
|
136
|
+
return;
|
|
137
|
+
case "set":
|
|
138
|
+
if (rest.length === 0)
|
|
139
|
+
throw new Error(`Nothing to set.\n\n${USAGE}`);
|
|
140
|
+
await change(instances, { set: parseAssignments(rest), unset: [] }, { dryRun, yes });
|
|
141
|
+
return;
|
|
142
|
+
case "unset":
|
|
143
|
+
if (rest.length === 0)
|
|
144
|
+
throw new Error(`Nothing to unset.\n\n${USAGE}`);
|
|
145
|
+
rest.forEach(assertValidKey);
|
|
146
|
+
await change(instances, { set: {}, unset: rest }, { dryRun, yes });
|
|
147
|
+
return;
|
|
148
|
+
default:
|
|
149
|
+
throw new Error(USAGE);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=nodejs-api-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodejs-api-env.js","sourceRoot":"","sources":["../../src/commands/nodejs-api-env.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pull the latest image and recreate every api-nodejs container, one host at
|
|
3
|
+
* a time so the API never loses more than one of its hosts. Stops at the
|
|
4
|
+
* first host that fails (its old container is restored).
|
|
5
|
+
*/
|
|
1
6
|
export declare function recreateNodejsApi(): Promise<void>;
|
|
2
7
|
//# sourceMappingURL=recreate-nodejs-api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recreate-nodejs-api.d.ts","sourceRoot":"","sources":["../../src/commands/recreate-nodejs-api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"recreate-nodejs-api.d.ts","sourceRoot":"","sources":["../../src/commands/recreate-nodejs-api.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAoBvD"}
|
|
@@ -1,113 +1,26 @@
|
|
|
1
1
|
import { loadConfig } from "../config.js";
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return {
|
|
9
|
-
...config,
|
|
10
|
-
HostConfig: hostConfig,
|
|
11
|
-
name,
|
|
12
|
-
NetworkingConfig: {
|
|
13
|
-
EndpointsConfig: networks,
|
|
14
|
-
},
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
async function recreateInstance(instance, log) {
|
|
18
|
-
const { portainerUrl, portainerEndpointId, portainerApiKey, portainerRegistryAuth, portainerContainerName, } = instance;
|
|
19
|
-
const common = { portainerUrl, portainerEndpointId, portainerApiKey };
|
|
20
|
-
// [Step 1] Get the container information
|
|
21
|
-
log("[Step 1] Get the container information");
|
|
22
|
-
const container = await portainer.getContainer({
|
|
23
|
-
...common,
|
|
24
|
-
portainerContainerName,
|
|
25
|
-
});
|
|
26
|
-
const oldContainerId = container.Id;
|
|
27
|
-
// [Step 2] Pull the latest image
|
|
28
|
-
log("[Step 2] Pull the latest image");
|
|
29
|
-
await portainer.pullImage({
|
|
30
|
-
...common,
|
|
31
|
-
portainerRegistryAuth,
|
|
32
|
-
image: container.Config.Image,
|
|
33
|
-
});
|
|
34
|
-
// [Step 3] Stop the current container
|
|
35
|
-
log("[Step 3] Stop the current container");
|
|
36
|
-
await portainer.stopContainer({
|
|
37
|
-
...common,
|
|
38
|
-
portainerContainerId: oldContainerId,
|
|
39
|
-
});
|
|
40
|
-
// [Step 4] Rename the current container
|
|
41
|
-
log("[Step 4] Rename the current container");
|
|
42
|
-
await portainer.renameContainer({
|
|
43
|
-
...common,
|
|
44
|
-
portainerContainerId: oldContainerId,
|
|
45
|
-
name: `${portainerContainerName}-old`,
|
|
46
|
-
});
|
|
47
|
-
// [Step 5] Create a new container
|
|
48
|
-
log("[Step 5] Create a new container");
|
|
49
|
-
const newContainerConfig = buildNewContainerConfig(container, portainerContainerName);
|
|
50
|
-
const newContainer = await portainer.createContainer({
|
|
51
|
-
...common,
|
|
52
|
-
name: portainerContainerName,
|
|
53
|
-
config: newContainerConfig,
|
|
54
|
-
});
|
|
55
|
-
const newContainerId = newContainer.Id;
|
|
56
|
-
// [Step 6] Connect to networks
|
|
57
|
-
log("[Step 6] Connect to networks");
|
|
58
|
-
const networks = (container.NetworkSettings?.Networks ?? {});
|
|
59
|
-
await Promise.all(Object.keys(networks).map((networkName) => portainer.connectContainerToNetwork({
|
|
60
|
-
...common,
|
|
61
|
-
portainerContainerId: newContainerId,
|
|
62
|
-
networkName,
|
|
63
|
-
})));
|
|
64
|
-
// [Step 7] Start the new container
|
|
65
|
-
log("[Step 7] Start the new container");
|
|
66
|
-
await portainer.startContainer({
|
|
67
|
-
...common,
|
|
68
|
-
portainerContainerId: newContainerId,
|
|
69
|
-
});
|
|
70
|
-
// [Step 8] Update the resource controller
|
|
71
|
-
log("[Step 8] Update the resource controller");
|
|
72
|
-
const resourceControl = container.Portainer?.ResourceControl;
|
|
73
|
-
if (resourceControl) {
|
|
74
|
-
await portainer.updateResourceControl({
|
|
75
|
-
portainerUrl,
|
|
76
|
-
portainerApiKey,
|
|
77
|
-
resourceControlId: resourceControl.Id,
|
|
78
|
-
data: {
|
|
79
|
-
AdministratorsOnly: resourceControl.AdministratorsOnly,
|
|
80
|
-
Public: resourceControl.Public,
|
|
81
|
-
Users: resourceControl.UserAccesses.map((a) => a.UserId),
|
|
82
|
-
Teams: resourceControl.TeamAccesses,
|
|
83
|
-
},
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
// [Step 9] Delete the old container
|
|
87
|
-
log("[Step 9] Delete the old container");
|
|
88
|
-
await portainer.deleteContainer({
|
|
89
|
-
...common,
|
|
90
|
-
portainerContainerId: oldContainerId,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
2
|
+
import { recreateContainer } from "../portainer/recreate.js";
|
|
3
|
+
/**
|
|
4
|
+
* Pull the latest image and recreate every api-nodejs container, one host at
|
|
5
|
+
* a time so the API never loses more than one of its hosts. Stops at the
|
|
6
|
+
* first host that fails (its old container is restored).
|
|
7
|
+
*/
|
|
93
8
|
export async function recreateNodejsApi() {
|
|
94
9
|
const config = loadConfig();
|
|
95
|
-
const
|
|
10
|
+
const total = config.nodejsApi.length;
|
|
11
|
+
for (const [i, instance] of config.nodejsApi.entries()) {
|
|
96
12
|
const prefix = `[${instance.portainerUrl} (${instance.portainerContainerName})]`;
|
|
97
13
|
const log = (msg) => console.log(`${prefix} ${msg}`);
|
|
98
14
|
log("Starting...");
|
|
99
|
-
|
|
100
|
-
log
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const failed = results.filter((r) => r.status === "rejected");
|
|
105
|
-
if (failed.length > 0) {
|
|
106
|
-
for (const r of failed) {
|
|
107
|
-
console.error(`Failed: ${r.reason}`);
|
|
15
|
+
try {
|
|
16
|
+
await recreateContainer(instance, { pull: true, log });
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
throw new Error(`${prefix} failed: ${err.message}. ${i}/${total} instance(s) were recreated; the rest were not touched.`);
|
|
108
20
|
}
|
|
109
|
-
|
|
21
|
+
log("Done.");
|
|
110
22
|
}
|
|
111
|
-
console.log(
|
|
23
|
+
console.log();
|
|
24
|
+
console.log(`All ${total} instance(s) completed successfully.`);
|
|
112
25
|
}
|
|
113
26
|
//# sourceMappingURL=recreate-nodejs-api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recreate-nodejs-api.js","sourceRoot":"","sources":["../../src/commands/recreate-nodejs-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"recreate-nodejs-api.js","sourceRoot":"","sources":["../../src/commands/recreate-nodejs-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;IAEtC,KAAK,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,YAAY,KAAK,QAAQ,CAAC,sBAAsB,IAAI,CAAC;QACjF,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC;QAC7D,GAAG,CAAC,aAAa,CAAC,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,iBAAiB,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,YAAa,GAAa,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,yDAAyD,CACpH,CAAC;QACJ,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,CAAC;IACf,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,sCAAsC,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-ec2-route53.d.ts","sourceRoot":"","sources":["../../src/commands/sync-ec2-route53.ts"],"names":[],"mappings":"AAKA,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAuGtD"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { checkbox } from "@inquirer/prompts";
|
|
2
|
+
import { loadConfig, getAwsConfig, getRoute53Config } from "../config.js";
|
|
3
|
+
import * as ec2 from "../aws/ec2.js";
|
|
4
|
+
import * as route53 from "../aws/route53.js";
|
|
5
|
+
export async function syncEc2ToRoute53() {
|
|
6
|
+
const config = loadConfig();
|
|
7
|
+
const aws = getAwsConfig(config);
|
|
8
|
+
const r53 = getRoute53Config(config);
|
|
9
|
+
console.log(`Listing running EC2 instances in ${aws.region}...`);
|
|
10
|
+
const instances = await ec2.listInstances(aws);
|
|
11
|
+
const running = instances.filter((i) => i.state === "running" && i.publicIp);
|
|
12
|
+
if (running.length === 0) {
|
|
13
|
+
console.log("No running instances with a public IP found. Nothing to do.");
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
// Group by slug so we can detect collisions; skip unnamed instances.
|
|
17
|
+
const suffix = `${r53.subdomain}.${r53.zoneName}`;
|
|
18
|
+
const bySlug = new Map();
|
|
19
|
+
for (const inst of running) {
|
|
20
|
+
if (inst.name === "(no name)") {
|
|
21
|
+
console.log(`Skipping ${inst.instanceId}: no Name tag.`);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const slug = route53.slugify(inst.name);
|
|
25
|
+
if (!slug) {
|
|
26
|
+
console.log(`Skipping ${inst.instanceId}: name "${inst.name}" slugified to empty.`);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const list = bySlug.get(slug) ?? [];
|
|
30
|
+
list.push(inst);
|
|
31
|
+
bySlug.set(slug, list);
|
|
32
|
+
}
|
|
33
|
+
const desired = [];
|
|
34
|
+
for (const [slug, insts] of bySlug) {
|
|
35
|
+
if (insts.length > 1) {
|
|
36
|
+
console.log(`Skipping slug "${slug}": ${insts.length} instances share it (${insts
|
|
37
|
+
.map((i) => i.instanceId)
|
|
38
|
+
.join(", ")}).`);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
desired.push({
|
|
42
|
+
name: `${slug}.${suffix}`,
|
|
43
|
+
ip: insts[0].publicIp,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
if (desired.length === 0) {
|
|
47
|
+
console.log("No records to sync after filtering. Nothing to do.");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
console.log(`Resolving hosted zone "${r53.zoneName}"...`);
|
|
51
|
+
const zoneId = await route53.resolveHostedZoneId(aws, r53.zoneName);
|
|
52
|
+
const existing = await route53.listARecords(aws, zoneId);
|
|
53
|
+
const toCreate = [];
|
|
54
|
+
const toUpdate = [];
|
|
55
|
+
let unchanged = 0;
|
|
56
|
+
for (const rec of desired) {
|
|
57
|
+
const current = existing.get(rec.name);
|
|
58
|
+
if (current === undefined)
|
|
59
|
+
toCreate.push(rec);
|
|
60
|
+
else if (current !== rec.ip)
|
|
61
|
+
toUpdate.push(rec);
|
|
62
|
+
else
|
|
63
|
+
unchanged++;
|
|
64
|
+
}
|
|
65
|
+
if (toCreate.length === 0 && toUpdate.length === 0) {
|
|
66
|
+
console.log(`All ${unchanged} record(s) already up to date — no changes.`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (unchanged > 0)
|
|
70
|
+
console.log(`${unchanged} record(s) already up to date.`);
|
|
71
|
+
const choices = [
|
|
72
|
+
...toCreate.map((r) => ({
|
|
73
|
+
name: `+ ${r.name} -> ${r.ip}`,
|
|
74
|
+
value: r,
|
|
75
|
+
checked: true,
|
|
76
|
+
})),
|
|
77
|
+
...toUpdate.map((r) => ({
|
|
78
|
+
name: `~ ${r.name} -> ${r.ip} (was ${existing.get(r.name)})`,
|
|
79
|
+
value: r,
|
|
80
|
+
checked: true,
|
|
81
|
+
})),
|
|
82
|
+
].sort((a, b) => a.value.name.localeCompare(b.value.name));
|
|
83
|
+
const selected = await checkbox({
|
|
84
|
+
message: `Select records to apply to ${r53.zoneName} (space toggles, enter confirms):`,
|
|
85
|
+
choices,
|
|
86
|
+
});
|
|
87
|
+
if (selected.length === 0) {
|
|
88
|
+
console.log("Nothing selected. Aborted.");
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
await route53.upsertARecords(aws, zoneId, selected, r53.ttl);
|
|
92
|
+
const createdCount = selected.filter((r) => toCreate.includes(r)).length;
|
|
93
|
+
const updatedCount = selected.length - createdCount;
|
|
94
|
+
console.log(`Done. ${createdCount} created, ${updatedCount} updated.`);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=sync-ec2-route53.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-ec2-route53.js","sourceRoot":"","sources":["../../src/commands/sync-ec2-route53.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -14,12 +14,18 @@ export interface CloudflareConfig {
|
|
|
14
14
|
zoneName?: string;
|
|
15
15
|
ruleDescription?: string;
|
|
16
16
|
}
|
|
17
|
+
export interface Route53Config {
|
|
18
|
+
zoneName?: string;
|
|
19
|
+
subdomain?: string;
|
|
20
|
+
ttl?: number;
|
|
21
|
+
}
|
|
17
22
|
export interface Config {
|
|
18
23
|
sytApiUrl: string;
|
|
19
24
|
sytApiKey: string;
|
|
20
25
|
nodejsApi: PortainerInstance[];
|
|
21
26
|
aws?: AwsConfig;
|
|
22
27
|
cloudflare?: CloudflareConfig;
|
|
28
|
+
route53?: Route53Config;
|
|
23
29
|
}
|
|
24
30
|
export declare function loadConfig(): Config;
|
|
25
31
|
export interface ResolvedAwsConfig {
|
|
@@ -33,4 +39,10 @@ export interface ResolvedCloudflareConfig {
|
|
|
33
39
|
}
|
|
34
40
|
export declare function getAwsConfig(config: Config): ResolvedAwsConfig;
|
|
35
41
|
export declare function getCloudflareConfig(config: Config): ResolvedCloudflareConfig;
|
|
42
|
+
export interface ResolvedRoute53Config {
|
|
43
|
+
zoneName: string;
|
|
44
|
+
subdomain: string;
|
|
45
|
+
ttl: number;
|
|
46
|
+
}
|
|
47
|
+
export declare function getRoute53Config(config: Config): ResolvedRoute53Config;
|
|
36
48
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,UAAU,CAAC,EAAE,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAID,wBAAgB,UAAU,IAAI,MAAM,CAmDnC;AAOD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAK9D;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,wBAAwB,CAa5E;AAMD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,qBAAqB,CAOtE"}
|
package/dist/config.js
CHANGED
|
@@ -60,4 +60,15 @@ export function getCloudflareConfig(config) {
|
|
|
60
60
|
ruleDescription: config.cloudflare?.ruleDescription?.trim() || DEFAULT_CLOUDFLARE_RULE,
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
+
const DEFAULT_ROUTE53_ZONE = "superyachtapi.com";
|
|
64
|
+
const DEFAULT_ROUTE53_SUBDOMAIN = "infra";
|
|
65
|
+
const DEFAULT_ROUTE53_TTL = 300;
|
|
66
|
+
export function getRoute53Config(config) {
|
|
67
|
+
const ttl = config.route53?.ttl;
|
|
68
|
+
return {
|
|
69
|
+
zoneName: config.route53?.zoneName?.trim() || DEFAULT_ROUTE53_ZONE,
|
|
70
|
+
subdomain: config.route53?.subdomain?.trim() || DEFAULT_ROUTE53_SUBDOMAIN,
|
|
71
|
+
ttl: typeof ttl === "number" && ttl > 0 ? ttl : DEFAULT_ROUTE53_TTL,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
63
74
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -5,9 +5,11 @@ import { fileURLToPath } from "node:url";
|
|
|
5
5
|
import { select } from "@inquirer/prompts";
|
|
6
6
|
import { collapseLastModified } from "./commands/collapse-last-modified.js";
|
|
7
7
|
import { createApiKey } from "./commands/create-api-key.js";
|
|
8
|
+
import { nodejsApiEnv } from "./commands/nodejs-api-env.js";
|
|
8
9
|
import { recreateNodejsApi } from "./commands/recreate-nodejs-api.js";
|
|
9
10
|
import { restartEc2 } from "./commands/restart-ec2.js";
|
|
10
11
|
import { syncEc2IpsToCloudflare } from "./commands/sync-ec2-ips-cloudflare.js";
|
|
12
|
+
import { syncEc2ToRoute53 } from "./commands/sync-ec2-route53.js";
|
|
11
13
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
14
|
const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
|
|
13
15
|
function printHelp() {
|
|
@@ -18,9 +20,11 @@ function printHelp() {
|
|
|
18
20
|
console.log("Commands:");
|
|
19
21
|
console.log(" collapse-last-modified Collapse last-modified yacht likes");
|
|
20
22
|
console.log(" create-api-key Create a new API key");
|
|
23
|
+
console.log(" nodejs-api-env List, set or unset env vars on the Node.js API containers");
|
|
21
24
|
console.log(" recreate-nodejs-api Recreate Node.js API containers via Portainer");
|
|
22
25
|
console.log(" restart-ec2 Restart (reboot) one or more EC2 servers");
|
|
23
26
|
console.log(" sync-ec2-ips-cloudflare Sync EC2 egress IPs to a Cloudflare WAF rule");
|
|
27
|
+
console.log(" sync-ec2-route53 Sync running EC2 public IPs to Route53 infra records");
|
|
24
28
|
console.log();
|
|
25
29
|
console.log("Options:");
|
|
26
30
|
console.log(" -v, --version Show version");
|
|
@@ -36,7 +40,7 @@ if (args.includes("--help") || args.includes("-h")) {
|
|
|
36
40
|
printHelp();
|
|
37
41
|
process.exit(0);
|
|
38
42
|
}
|
|
39
|
-
async function runCommand(cmd) {
|
|
43
|
+
async function runCommand(cmd, cmdArgs = []) {
|
|
40
44
|
switch (cmd) {
|
|
41
45
|
case "collapse-last-modified":
|
|
42
46
|
await collapseLastModified();
|
|
@@ -44,6 +48,9 @@ async function runCommand(cmd) {
|
|
|
44
48
|
case "create-api-key":
|
|
45
49
|
await createApiKey();
|
|
46
50
|
break;
|
|
51
|
+
case "nodejs-api-env":
|
|
52
|
+
await nodejsApiEnv(cmdArgs);
|
|
53
|
+
break;
|
|
47
54
|
case "recreate-nodejs-api":
|
|
48
55
|
await recreateNodejsApi();
|
|
49
56
|
break;
|
|
@@ -53,6 +60,9 @@ async function runCommand(cmd) {
|
|
|
53
60
|
case "sync-ec2-ips-cloudflare":
|
|
54
61
|
await syncEc2IpsToCloudflare();
|
|
55
62
|
break;
|
|
63
|
+
case "sync-ec2-route53":
|
|
64
|
+
await syncEc2ToRoute53();
|
|
65
|
+
break;
|
|
56
66
|
default:
|
|
57
67
|
console.error(`Unknown command: ${cmd}`);
|
|
58
68
|
printHelp();
|
|
@@ -73,6 +83,11 @@ async function showMenu() {
|
|
|
73
83
|
value: "create-api-key",
|
|
74
84
|
description: "Create a new API key",
|
|
75
85
|
},
|
|
86
|
+
{
|
|
87
|
+
name: "nodejs-api-env",
|
|
88
|
+
value: "nodejs-api-env",
|
|
89
|
+
description: "List, set or unset env vars on the Node.js API containers",
|
|
90
|
+
},
|
|
76
91
|
{
|
|
77
92
|
name: "recreate-nodejs-api",
|
|
78
93
|
value: "recreate-nodejs-api",
|
|
@@ -88,12 +103,17 @@ async function showMenu() {
|
|
|
88
103
|
value: "sync-ec2-ips-cloudflare",
|
|
89
104
|
description: "Sync EC2 egress IPs to a Cloudflare WAF rule",
|
|
90
105
|
},
|
|
106
|
+
{
|
|
107
|
+
name: "Sync EC2 IPs to Route53",
|
|
108
|
+
value: "sync-ec2-route53",
|
|
109
|
+
description: "Sync running EC2 public IPs to Route53 infra records",
|
|
110
|
+
},
|
|
91
111
|
],
|
|
92
112
|
});
|
|
93
113
|
await runCommand(chosen);
|
|
94
114
|
}
|
|
95
115
|
if (command) {
|
|
96
|
-
runCommand(command).catch((err) => {
|
|
116
|
+
runCommand(command, args.slice(1)).catch((err) => {
|
|
97
117
|
console.error(`Error: ${err.message}`);
|
|
98
118
|
process.exit(1);
|
|
99
119
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/portainer/api.d.ts
CHANGED
|
@@ -61,4 +61,11 @@ export declare function deleteContainer(opts: {
|
|
|
61
61
|
portainerApiKey: string;
|
|
62
62
|
portainerContainerId: string;
|
|
63
63
|
}): Promise<void>;
|
|
64
|
+
export declare function execInContainer(opts: {
|
|
65
|
+
portainerUrl: string;
|
|
66
|
+
portainerEndpointId: string;
|
|
67
|
+
portainerApiKey: string;
|
|
68
|
+
portainerContainerId: string;
|
|
69
|
+
cmd: string[];
|
|
70
|
+
}): Promise<string>;
|
|
64
71
|
//# sourceMappingURL=api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/portainer/api.ts"],"names":[],"mappings":"AA0CA,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;CAEhC,GAAG,OAAO,CAAC,GAAG,CAAC,CASf;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBhB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,GAAG,OAAO,CAAC,IAAI,CAAC,CAShB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhB;AAGD,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;CAEjB,GAAG,OAAO,CAAC,GAAG,CAAC,CASf;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAahB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,GAAG,OAAO,CAAC,IAAI,CAAC,CAShB;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE;QACJ,kBAAkB,EAAE,OAAO,CAAC;QAC5B,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,KAAK,EAAE,OAAO,EAAE,CAAC;KAClB,CAAC;CACH,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,GAAG,OAAO,CAAC,IAAI,CAAC,CAShB"}
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/portainer/api.ts"],"names":[],"mappings":"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"}
|
package/dist/portainer/api.js
CHANGED
|
@@ -71,4 +71,38 @@ export async function updateResourceControl(opts) {
|
|
|
71
71
|
export async function deleteContainer(opts) {
|
|
72
72
|
await request(urls.containerDeleteUrl(opts.portainerUrl, opts.portainerEndpointId, opts.portainerContainerId), { method: "DELETE", apiKey: opts.portainerApiKey });
|
|
73
73
|
}
|
|
74
|
+
// Docker multiplexes stdout/stderr when the exec has no TTY: each frame is an
|
|
75
|
+
// 8-byte header (stream type, 3 zero bytes, uint32 BE length) followed by the
|
|
76
|
+
// payload. Concatenate the payloads.
|
|
77
|
+
function demultiplex(buf) {
|
|
78
|
+
const parts = [];
|
|
79
|
+
let offset = 0;
|
|
80
|
+
while (offset + 8 <= buf.length) {
|
|
81
|
+
const size = buf.readUInt32BE(offset + 4);
|
|
82
|
+
parts.push(buf.subarray(offset + 8, offset + 8 + size));
|
|
83
|
+
offset += 8 + size;
|
|
84
|
+
}
|
|
85
|
+
return offset === 0 ? buf.toString("utf-8") : Buffer.concat(parts).toString("utf-8");
|
|
86
|
+
}
|
|
87
|
+
export async function execInContainer(opts) {
|
|
88
|
+
const exec = (await request(urls.containerExecUrl(opts.portainerUrl, opts.portainerEndpointId, opts.portainerContainerId), {
|
|
89
|
+
method: "POST",
|
|
90
|
+
apiKey: opts.portainerApiKey,
|
|
91
|
+
body: { AttachStdout: true, AttachStderr: true, Cmd: opts.cmd },
|
|
92
|
+
}));
|
|
93
|
+
const url = urls.execStartUrl(opts.portainerUrl, opts.portainerEndpointId, exec.Id);
|
|
94
|
+
const res = await fetch(url, {
|
|
95
|
+
method: "POST",
|
|
96
|
+
headers: {
|
|
97
|
+
"X-API-Key": opts.portainerApiKey,
|
|
98
|
+
"Content-Type": "application/json",
|
|
99
|
+
},
|
|
100
|
+
body: JSON.stringify({ Detach: false, Tty: false }),
|
|
101
|
+
});
|
|
102
|
+
if (!res.ok) {
|
|
103
|
+
const text = await res.text().catch(() => "");
|
|
104
|
+
throw new Error(`Portainer API error: POST ${url} → ${res.status} ${res.statusText}${text ? `\n${text}` : ""}`);
|
|
105
|
+
}
|
|
106
|
+
return demultiplex(Buffer.from(await res.arrayBuffer()));
|
|
107
|
+
}
|
|
74
108
|
//# sourceMappingURL=api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/portainer/api.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/portainer/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type EnvOutcome = "added" | "changed" | "unchanged" | "removed" | "absent";
|
|
2
|
+
export interface EnvChanges {
|
|
3
|
+
set: Record<string, string>;
|
|
4
|
+
unset: string[];
|
|
5
|
+
}
|
|
6
|
+
export declare function assertValidKey(key: string): void;
|
|
7
|
+
export declare function parseAssignments(args: string[]): Record<string, string>;
|
|
8
|
+
export declare function applyEnvChanges(env: string[], changes: EnvChanges): {
|
|
9
|
+
env: string[];
|
|
10
|
+
outcomes: Record<string, EnvOutcome>;
|
|
11
|
+
};
|
|
12
|
+
export declare function hasChanges(outcomes: Record<string, EnvOutcome>): boolean;
|
|
13
|
+
export type EnvSummaryRow = {
|
|
14
|
+
name: string;
|
|
15
|
+
status: "same" | "differs";
|
|
16
|
+
} | {
|
|
17
|
+
name: string;
|
|
18
|
+
status: "missing";
|
|
19
|
+
missingOn: string[];
|
|
20
|
+
};
|
|
21
|
+
export declare function summariseEnv(hosts: {
|
|
22
|
+
host: string;
|
|
23
|
+
env: string[];
|
|
24
|
+
}[]): EnvSummaryRow[];
|
|
25
|
+
export declare function envValue(env: string[], key: string): string | undefined;
|
|
26
|
+
export declare function probePort(config: {
|
|
27
|
+
Env?: string[];
|
|
28
|
+
ExposedPorts?: Record<string, unknown>;
|
|
29
|
+
}): number | null;
|
|
30
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/portainer/env.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAElF,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAOD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAIhD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWvE;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EAAE,EACb,OAAO,EAAE,UAAU,GAClB;IAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CAAE,CA2BzD;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,OAAO,CAIxE;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE7D,wBAAgB,YAAY,CAC1B,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,GACvC,aAAa,EAAE,CAajB;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMvE;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE;IAChC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC,GAAG,MAAM,GAAG,IAAI,CAMhB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Pure helpers for editing a Docker container's Env array (["KEY=VALUE", ...]).
|
|
2
|
+
// Nothing here prints or returns an existing value: most of these are secrets.
|
|
3
|
+
const KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
4
|
+
function splitEntry(entry) {
|
|
5
|
+
const i = entry.indexOf("=");
|
|
6
|
+
return i === -1 ? [entry, ""] : [entry.slice(0, i), entry.slice(i + 1)];
|
|
7
|
+
}
|
|
8
|
+
export function assertValidKey(key) {
|
|
9
|
+
if (!KEY_PATTERN.test(key)) {
|
|
10
|
+
throw new Error(`Invalid environment variable name: "${key}"`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function parseAssignments(args) {
|
|
14
|
+
const result = {};
|
|
15
|
+
for (const arg of args) {
|
|
16
|
+
if (!arg.includes("=")) {
|
|
17
|
+
throw new Error(`Expected KEY=VALUE, got "${arg}"`);
|
|
18
|
+
}
|
|
19
|
+
const [key, value] = splitEntry(arg);
|
|
20
|
+
assertValidKey(key);
|
|
21
|
+
result[key] = value;
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
export function applyEnvChanges(env, changes) {
|
|
26
|
+
const outcomes = {};
|
|
27
|
+
const pending = new Map(Object.entries(changes.set));
|
|
28
|
+
const unset = new Set(changes.unset);
|
|
29
|
+
const result = [];
|
|
30
|
+
for (const entry of env) {
|
|
31
|
+
const [key, value] = splitEntry(entry);
|
|
32
|
+
if (pending.has(key)) {
|
|
33
|
+
const next = pending.get(key);
|
|
34
|
+
outcomes[key] = next === value ? "unchanged" : "changed";
|
|
35
|
+
result.push(`${key}=${next}`);
|
|
36
|
+
pending.delete(key);
|
|
37
|
+
}
|
|
38
|
+
else if (unset.has(key)) {
|
|
39
|
+
outcomes[key] = "removed";
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
result.push(entry);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
for (const [key, value] of pending) {
|
|
46
|
+
outcomes[key] = "added";
|
|
47
|
+
result.push(`${key}=${value}`);
|
|
48
|
+
}
|
|
49
|
+
for (const key of unset) {
|
|
50
|
+
if (!(key in outcomes))
|
|
51
|
+
outcomes[key] = "absent";
|
|
52
|
+
}
|
|
53
|
+
return { env: result, outcomes };
|
|
54
|
+
}
|
|
55
|
+
export function hasChanges(outcomes) {
|
|
56
|
+
return Object.values(outcomes).some((o) => o === "added" || o === "changed" || o === "removed");
|
|
57
|
+
}
|
|
58
|
+
export function summariseEnv(hosts) {
|
|
59
|
+
const maps = hosts.map((h) => ({
|
|
60
|
+
host: h.host,
|
|
61
|
+
values: new Map(h.env.map(splitEntry)),
|
|
62
|
+
}));
|
|
63
|
+
const names = [...new Set(maps.flatMap((m) => [...m.values.keys()]))].sort();
|
|
64
|
+
return names.map((name) => {
|
|
65
|
+
const missingOn = maps.filter((m) => !m.values.has(name)).map((m) => m.host);
|
|
66
|
+
if (missingOn.length > 0)
|
|
67
|
+
return { name, status: "missing", missingOn };
|
|
68
|
+
const distinct = new Set(maps.map((m) => m.values.get(name)));
|
|
69
|
+
return { name, status: distinct.size === 1 ? "same" : "differs" };
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
export function envValue(env, key) {
|
|
73
|
+
for (const entry of env) {
|
|
74
|
+
const [k, v] = splitEntry(entry);
|
|
75
|
+
if (k === key)
|
|
76
|
+
return v;
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
export function probePort(config) {
|
|
81
|
+
const fromEnv = Number(envValue(config.Env ?? [], "PORT"));
|
|
82
|
+
if (Number.isInteger(fromEnv) && fromEnv > 0)
|
|
83
|
+
return fromEnv;
|
|
84
|
+
const first = Object.keys(config.ExposedPorts ?? {})[0];
|
|
85
|
+
const port = first ? Number(first.split("/")[0]) : NaN;
|
|
86
|
+
return Number.isInteger(port) && port > 0 ? port : null;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/portainer/env.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PortainerInstance } from "../config.js";
|
|
2
|
+
export interface RecreateOptions {
|
|
3
|
+
/** Pull the container's image tag before recreating (deploys new code). */
|
|
4
|
+
pull: boolean;
|
|
5
|
+
/** Rewrite the Env array; omit to keep it as is. */
|
|
6
|
+
transformEnv?: (env: string[]) => string[];
|
|
7
|
+
log: (msg: string) => void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Recreate one container from its own config. Steps: inspect → (pull) → stop
|
|
11
|
+
* → rename to <name>-old → create → start → probe → copy resource control →
|
|
12
|
+
* delete old. Any failure after the stop restores the old container and
|
|
13
|
+
* throws, so the host is never left without a running container.
|
|
14
|
+
*/
|
|
15
|
+
export declare function recreateContainer(instance: PortainerInstance, options: RecreateOptions): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=recreate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recreate.d.ts","sourceRoot":"","sources":["../../src/portainer/recreate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAOtD,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,IAAI,EAAE,OAAO,CAAC;IACd,oDAAoD;IACpD,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IAC3C,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5B;AA2BD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC,CAuHf"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import * as portainer from "./api.js";
|
|
2
|
+
import { probePort } from "./env.js";
|
|
3
|
+
const PROBE_INTERVAL_MS = 5_000;
|
|
4
|
+
const PROBE_ATTEMPTS = 18; // 90 s
|
|
5
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
6
|
+
/**
|
|
7
|
+
* Ask the container itself whether it answers HTTP on its port. Any status
|
|
8
|
+
* counts as ready — the point is that the process is up and listening.
|
|
9
|
+
*/
|
|
10
|
+
async function probe(common, containerId, port) {
|
|
11
|
+
const script = `fetch("http://localhost:${port}/").then(r=>console.log("STATUS",r.status)).catch(e=>console.log("ERR",e.message))`;
|
|
12
|
+
try {
|
|
13
|
+
const out = await portainer.execInContainer({
|
|
14
|
+
...common,
|
|
15
|
+
portainerContainerId: containerId,
|
|
16
|
+
cmd: ["node", "-e", script],
|
|
17
|
+
});
|
|
18
|
+
const match = out.match(/STATUS (\d+)/);
|
|
19
|
+
return match ? match[1] : null;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Recreate one container from its own config. Steps: inspect → (pull) → stop
|
|
27
|
+
* → rename to <name>-old → create → start → probe → copy resource control →
|
|
28
|
+
* delete old. Any failure after the stop restores the old container and
|
|
29
|
+
* throws, so the host is never left without a running container.
|
|
30
|
+
*/
|
|
31
|
+
export async function recreateContainer(instance, options) {
|
|
32
|
+
const { portainerUrl, portainerEndpointId, portainerApiKey, portainerRegistryAuth, portainerContainerName: name, } = instance;
|
|
33
|
+
const common = { portainerUrl, portainerEndpointId, portainerApiKey };
|
|
34
|
+
const { log } = options;
|
|
35
|
+
log("Inspect the container");
|
|
36
|
+
const container = await portainer.getContainer({
|
|
37
|
+
...common,
|
|
38
|
+
portainerContainerName: name,
|
|
39
|
+
});
|
|
40
|
+
const oldId = container.Id;
|
|
41
|
+
if (options.pull) {
|
|
42
|
+
log("Pull the latest image");
|
|
43
|
+
await portainer.pullImage({
|
|
44
|
+
...common,
|
|
45
|
+
portainerRegistryAuth,
|
|
46
|
+
image: container.Config.Image,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
const env = container.Config.Env ?? [];
|
|
50
|
+
const config = {
|
|
51
|
+
...container.Config,
|
|
52
|
+
Env: options.transformEnv ? options.transformEnv(env) : env,
|
|
53
|
+
HostConfig: container.HostConfig,
|
|
54
|
+
NetworkingConfig: {
|
|
55
|
+
EndpointsConfig: container.NetworkSettings?.Networks ?? {},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
const port = probePort(config);
|
|
59
|
+
log("Stop and rename the current container");
|
|
60
|
+
await portainer.stopContainer({ ...common, portainerContainerId: oldId });
|
|
61
|
+
await portainer.renameContainer({
|
|
62
|
+
...common,
|
|
63
|
+
portainerContainerId: oldId,
|
|
64
|
+
name: `${name}-old`,
|
|
65
|
+
});
|
|
66
|
+
let newId;
|
|
67
|
+
try {
|
|
68
|
+
log("Create and start the new container");
|
|
69
|
+
const created = await portainer.createContainer({ ...common, name, config });
|
|
70
|
+
newId = created.Id;
|
|
71
|
+
const fresh = await portainer.getContainer({
|
|
72
|
+
...common,
|
|
73
|
+
portainerContainerName: newId,
|
|
74
|
+
});
|
|
75
|
+
const attached = new Set(Object.keys(fresh.NetworkSettings?.Networks ?? {}));
|
|
76
|
+
for (const networkName of Object.keys(container.NetworkSettings?.Networks ?? {})) {
|
|
77
|
+
if (attached.has(networkName))
|
|
78
|
+
continue;
|
|
79
|
+
await portainer.connectContainerToNetwork({
|
|
80
|
+
...common,
|
|
81
|
+
portainerContainerId: newId,
|
|
82
|
+
networkName,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
await portainer.startContainer({ ...common, portainerContainerId: newId });
|
|
86
|
+
if (port === null) {
|
|
87
|
+
log("No port to probe (no PORT env, no exposed port); waiting 15 s for it to stay up");
|
|
88
|
+
await sleep(15_000);
|
|
89
|
+
const state = await portainer.getContainer({ ...common, portainerContainerName: newId });
|
|
90
|
+
if (state.State?.Status !== "running") {
|
|
91
|
+
throw new Error(`new container is ${state.State?.Status}, not running`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
log(`Wait for the new container to answer on :${port}`);
|
|
96
|
+
let status = null;
|
|
97
|
+
for (let i = 0; i < PROBE_ATTEMPTS && status === null; i++) {
|
|
98
|
+
await sleep(PROBE_INTERVAL_MS);
|
|
99
|
+
status = await probe(common, newId, port);
|
|
100
|
+
}
|
|
101
|
+
if (status === null) {
|
|
102
|
+
throw new Error(`new container did not answer on :${port} within 90 s`);
|
|
103
|
+
}
|
|
104
|
+
log(`New container answers (HTTP ${status})`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
log(`FAILED: ${err.message} — restoring the old container`);
|
|
109
|
+
if (newId) {
|
|
110
|
+
await portainer.stopContainer({ ...common, portainerContainerId: newId }).catch(() => { });
|
|
111
|
+
await portainer
|
|
112
|
+
.renameContainer({ ...common, portainerContainerId: newId, name: `${name}-failed` })
|
|
113
|
+
.catch(() => { });
|
|
114
|
+
}
|
|
115
|
+
await portainer.renameContainer({ ...common, portainerContainerId: oldId, name });
|
|
116
|
+
await portainer.startContainer({ ...common, portainerContainerId: oldId });
|
|
117
|
+
log(`Old container restored${newId ? `; the failed one is kept as ${name}-failed` : ""}`);
|
|
118
|
+
throw err;
|
|
119
|
+
}
|
|
120
|
+
const resourceControl = container.Portainer?.ResourceControl;
|
|
121
|
+
if (resourceControl) {
|
|
122
|
+
log("Copy the Portainer resource control");
|
|
123
|
+
await portainer.updateResourceControl({
|
|
124
|
+
portainerUrl,
|
|
125
|
+
portainerApiKey,
|
|
126
|
+
resourceControlId: resourceControl.Id,
|
|
127
|
+
data: {
|
|
128
|
+
AdministratorsOnly: resourceControl.AdministratorsOnly,
|
|
129
|
+
Public: resourceControl.Public,
|
|
130
|
+
Users: resourceControl.UserAccesses.map((a) => a.UserId),
|
|
131
|
+
Teams: resourceControl.TeamAccesses,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
log("Delete the old container");
|
|
136
|
+
await portainer.deleteContainer({ ...common, portainerContainerId: oldId });
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=recreate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recreate.js","sourceRoot":"","sources":["../../src/portainer/recreate.ts"],"names":[],"mappings":"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"}
|
package/dist/portainer/urls.d.ts
CHANGED
|
@@ -7,4 +7,6 @@ export declare const networkConnectUrl: (baseUrl: string, endpointId: string, ne
|
|
|
7
7
|
export declare const imagePullUrl: (baseUrl: string, endpointId: string, image: string) => string;
|
|
8
8
|
export declare const containerDeleteUrl: (baseUrl: string, endpointId: string, containerId: string) => string;
|
|
9
9
|
export declare const resourceControlsUrl: (baseUrl: string, resourceControlId: number) => string;
|
|
10
|
+
export declare const containerExecUrl: (baseUrl: string, endpointId: string, containerId: string) => string;
|
|
11
|
+
export declare const execStartUrl: (baseUrl: string, endpointId: string, execId: string) => string;
|
|
10
12
|
//# sourceMappingURL=urls.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urls.d.ts","sourceRoot":"","sources":["../../src/portainer/urls.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,GACvB,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,eAAe,MAAM,WAC+C,CAAC;AAEvE,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,aAAa,MAAM,WAC+C,CAAC;AAErE,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,aAAa,MAAM,WACgD,CAAC;AAEtE,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,aAAa,MAAM,EACnB,MAAM,MAAM,WAEkE,CAAC;AAEjF,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,MAAM,MAAM,WACsD,CAAC;AAErE,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,aAAa,MAAM,WACgD,CAAC;AAEtE,eAAO,MAAM,YAAY,GACvB,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,OAAO,MAAM,WACuD,CAAC;AAEvE,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,aAAa,MAAM,WACyD,CAAC;AAE/E,eAAO,MAAM,mBAAmB,GAC9B,SAAS,MAAM,EACf,mBAAmB,MAAM,WACiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"urls.d.ts","sourceRoot":"","sources":["../../src/portainer/urls.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,GACvB,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,eAAe,MAAM,WAC+C,CAAC;AAEvE,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,aAAa,MAAM,WAC+C,CAAC;AAErE,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,aAAa,MAAM,WACgD,CAAC;AAEtE,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,aAAa,MAAM,EACnB,MAAM,MAAM,WAEkE,CAAC;AAEjF,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,MAAM,MAAM,WACsD,CAAC;AAErE,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,aAAa,MAAM,WACgD,CAAC;AAEtE,eAAO,MAAM,YAAY,GACvB,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,OAAO,MAAM,WACuD,CAAC;AAEvE,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,aAAa,MAAM,WACyD,CAAC;AAE/E,eAAO,MAAM,mBAAmB,GAC9B,SAAS,MAAM,EACf,mBAAmB,MAAM,WACiC,CAAC;AAE7D,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,aAAa,MAAM,WAC+C,CAAC;AAErE,eAAO,MAAM,YAAY,GACvB,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,QAAQ,MAAM,WAC0C,CAAC"}
|
package/dist/portainer/urls.js
CHANGED
|
@@ -8,4 +8,6 @@ export const networkConnectUrl = (baseUrl, endpointId, networkName) => `${docker
|
|
|
8
8
|
export const imagePullUrl = (baseUrl, endpointId, image) => `${docker(baseUrl, endpointId)}/images/create?fromImage=${image}`;
|
|
9
9
|
export const containerDeleteUrl = (baseUrl, endpointId, containerId) => `${docker(baseUrl, endpointId)}/containers/${containerId}?v=1&force=true`;
|
|
10
10
|
export const resourceControlsUrl = (baseUrl, resourceControlId) => `${baseUrl}/api/resource_controls/${resourceControlId}`;
|
|
11
|
+
export const containerExecUrl = (baseUrl, endpointId, containerId) => `${docker(baseUrl, endpointId)}/containers/${containerId}/exec`;
|
|
12
|
+
export const execStartUrl = (baseUrl, endpointId, execId) => `${docker(baseUrl, endpointId)}/exec/${execId}/start`;
|
|
11
13
|
//# sourceMappingURL=urls.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urls.js","sourceRoot":"","sources":["../../src/portainer/urls.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,GAAG,CAAC,OAAe,EAAE,UAAkB,EAAE,EAAE,CACrD,GAAG,OAAO,kBAAkB,UAAU,SAAS,CAAC;AAElD,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAe,EACf,UAAkB,EAClB,aAAqB,EACrB,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,eAAe,aAAa,OAAO,CAAC;AAEvE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,eAAe,WAAW,OAAO,CAAC;AAErE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,eAAe,WAAW,QAAQ,CAAC;AAEtE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,IAAY,EACZ,EAAE,CACF,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,eAAe,WAAW,gBAAgB,IAAI,EAAE,CAAC;AAEjF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,OAAe,EACf,UAAkB,EAClB,IAAY,EACZ,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,2BAA2B,IAAI,EAAE,CAAC;AAErE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,WAAW,UAAU,CAAC;AAEtE,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAe,EACf,UAAkB,EAClB,KAAa,EACb,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,4BAA4B,KAAK,EAAE,CAAC;AAEvE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,eAAe,WAAW,iBAAiB,CAAC;AAE/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,OAAe,EACf,iBAAyB,EACzB,EAAE,CAAC,GAAG,OAAO,0BAA0B,iBAAiB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"urls.js","sourceRoot":"","sources":["../../src/portainer/urls.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,GAAG,CAAC,OAAe,EAAE,UAAkB,EAAE,EAAE,CACrD,GAAG,OAAO,kBAAkB,UAAU,SAAS,CAAC;AAElD,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAe,EACf,UAAkB,EAClB,aAAqB,EACrB,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,eAAe,aAAa,OAAO,CAAC;AAEvE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,eAAe,WAAW,OAAO,CAAC;AAErE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,eAAe,WAAW,QAAQ,CAAC;AAEtE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,IAAY,EACZ,EAAE,CACF,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,eAAe,WAAW,gBAAgB,IAAI,EAAE,CAAC;AAEjF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,OAAe,EACf,UAAkB,EAClB,IAAY,EACZ,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,2BAA2B,IAAI,EAAE,CAAC;AAErE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,WAAW,UAAU,CAAC;AAEtE,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAe,EACf,UAAkB,EAClB,KAAa,EACb,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,4BAA4B,KAAK,EAAE,CAAC;AAEvE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,eAAe,WAAW,iBAAiB,CAAC;AAE/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,OAAe,EACf,iBAAyB,EACzB,EAAE,CAAC,GAAG,OAAO,0BAA0B,iBAAiB,EAAE,CAAC;AAE7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,OAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,eAAe,WAAW,OAAO,CAAC;AAErE,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAe,EACf,UAAkB,EAClB,MAAc,EACd,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,SAAS,MAAM,QAAQ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superyachttimes/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "SuperYachtTimes CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"syt-cli": "./dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"dist"
|
|
10
|
+
"dist",
|
|
11
|
+
"!dist/**/*.test.*"
|
|
11
12
|
],
|
|
12
13
|
"scripts": {
|
|
13
14
|
"build": "tsc",
|
|
@@ -15,7 +16,8 @@
|
|
|
15
16
|
"clean": "rm -rf dist",
|
|
16
17
|
"prepublishOnly": "npm run clean && npm run build",
|
|
17
18
|
"push": "npm login && npm publish --scope @superyachttimes --access public",
|
|
18
|
-
"ship": "bash scripts/ship.sh"
|
|
19
|
+
"ship": "bash scripts/ship.sh",
|
|
20
|
+
"test": "tsc && node --test \"dist/**/*.test.js\""
|
|
19
21
|
},
|
|
20
22
|
"engines": {
|
|
21
23
|
"node": ">=20"
|
|
@@ -26,6 +28,7 @@
|
|
|
26
28
|
},
|
|
27
29
|
"dependencies": {
|
|
28
30
|
"@aws-sdk/client-ec2": "^3.1053.0",
|
|
31
|
+
"@aws-sdk/client-route-53": "^3.1061.0",
|
|
29
32
|
"@aws-sdk/credential-providers": "^3.1053.0",
|
|
30
33
|
"@inquirer/prompts": "^8.2.0"
|
|
31
34
|
}
|