gitops-ai 1.2.1 → 1.2.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 +4 -4
- package/dist/commands/bootstrap.js +33 -16
- package/dist/commands/bootstrap.js.map +1 -1
- package/dist/commands/sops.js +5 -9
- package/dist/commands/sops.js.map +1 -1
- package/dist/core/bootstrap-runner.js +35 -6
- package/dist/core/bootstrap-runner.js.map +1 -1
- package/dist/core/dependencies.js +0 -28
- package/dist/core/dependencies.js.map +1 -1
- package/dist/core/flux.d.ts +5 -2
- package/dist/core/flux.js +38 -46
- package/dist/core/flux.js.map +1 -1
- package/dist/core/k8s-api.d.ts +33 -0
- package/dist/core/k8s-api.js +255 -0
- package/dist/core/k8s-api.js.map +1 -0
- package/dist/core/kubernetes.d.ts +2 -2
- package/dist/core/kubernetes.js +29 -48
- package/dist/core/kubernetes.js.map +1 -1
- package/dist/core/template-sync.js +1 -1
- package/dist/core/template-sync.js.map +1 -1
- package/dist/utils/log.js +35 -4
- package/dist/utils/log.js.map +1 -1
- package/package.json +3 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../src/core/dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AASnD,KAAK,UAAU,UAAU,CAAC,GAAW;IACnC,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,QAAQ,GAAiB;IAC7B;QACE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../src/core/dependencies.ts"],"names":[],"mappings":"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"}
|
package/dist/core/flux.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { type BootstrapConfig } from "../schemas.js";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Installs the Flux Operator and a FluxInstance in one step using the official CLI.
|
|
4
|
+
* Requires `flux-system` namespace and the `flux-system` git credentials secret to exist first.
|
|
5
|
+
*/
|
|
6
|
+
export declare function installFluxOperatorAndInstance(config: BootstrapConfig, repoRoot: string): Promise<void>;
|
|
4
7
|
export declare function waitForInstance(): Promise<void>;
|
|
5
8
|
export declare function reconcile(): Promise<void>;
|
|
6
9
|
export declare function getStatus(): string;
|
package/dist/core/flux.js
CHANGED
|
@@ -1,23 +1,16 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync, unlinkSync } from "node:fs";
|
|
2
|
-
import { exec, execAsync
|
|
2
|
+
import { exec, execAsync } from "../utils/shell.js";
|
|
3
3
|
import { log, withSpinner, p, pc } from "../utils/log.js";
|
|
4
4
|
import { getProvider } from "./git-provider.js";
|
|
5
5
|
import { shouldUseSshDeployKey } from "../schemas.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
].join(" ");
|
|
15
|
-
log.detail(cmd);
|
|
16
|
-
await withSpinner("Installing Flux Operator via Helm", () => execAsync(cmd));
|
|
17
|
-
}
|
|
18
|
-
export async function installInstance(config, repoRoot) {
|
|
19
|
-
const templatePath = `${repoRoot}/flux-instance-values.yaml`;
|
|
20
|
-
const tmpPath = "/tmp/flux-instance-values.yaml";
|
|
6
|
+
import * as k8sApi from "./k8s-api.js";
|
|
7
|
+
/**
|
|
8
|
+
* Installs the Flux Operator and a FluxInstance in one step using the official CLI.
|
|
9
|
+
* Requires `flux-system` namespace and the `flux-system` git credentials secret to exist first.
|
|
10
|
+
*/
|
|
11
|
+
export async function installFluxOperatorAndInstance(config, repoRoot) {
|
|
12
|
+
const templatePath = `${repoRoot}/flux-instance.yaml`;
|
|
13
|
+
const tmpPath = "/tmp/flux-instance.yaml";
|
|
21
14
|
const provider = await getProvider(config.gitProvider ?? "gitlab");
|
|
22
15
|
const gitHost = config.gitHost ?? provider.defaultHost;
|
|
23
16
|
let content = readFileSync(templatePath, "utf-8");
|
|
@@ -29,11 +22,9 @@ export async function installInstance(config, repoRoot) {
|
|
|
29
22
|
CLUSTER_NAME: config.clusterName,
|
|
30
23
|
};
|
|
31
24
|
content = envsubst(content, vars);
|
|
32
|
-
// Replace hardcoded gitlab.com URLs in the template with the actual host
|
|
33
25
|
if (gitHost !== "gitlab.com") {
|
|
34
26
|
content = content.replaceAll("https://gitlab.com/", `https://${gitHost}/`);
|
|
35
27
|
}
|
|
36
|
-
// SSH deploy key: rewrite HTTPS URL → SSH URL for Flux source-controller
|
|
37
28
|
if (shouldUseSshDeployKey(config)) {
|
|
38
29
|
const httpsUrl = `https://${gitHost}/${config.repoOwner}/${config.repoName}.git`;
|
|
39
30
|
const sshUrl = `ssh://git@${gitHost}/${config.repoOwner}/${config.repoName}.git`;
|
|
@@ -41,25 +32,41 @@ export async function installInstance(config, repoRoot) {
|
|
|
41
32
|
}
|
|
42
33
|
writeFileSync(tmpPath, content);
|
|
43
34
|
const cmd = [
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"--wait",
|
|
35
|
+
"flux-operator install",
|
|
36
|
+
"-n flux-system",
|
|
37
|
+
`-f ${tmpPath}`,
|
|
38
|
+
"--timeout 30m",
|
|
49
39
|
].join(" ");
|
|
50
40
|
log.detail(cmd);
|
|
51
|
-
await withSpinner("Installing Flux
|
|
41
|
+
await withSpinner("Installing Flux Operator and Flux instance (flux-operator install)", () => execAsync(cmd));
|
|
52
42
|
unlinkSync(tmpPath);
|
|
53
43
|
}
|
|
44
|
+
async function getPodStatusLine() {
|
|
45
|
+
const kc = k8sApi.kubeConfigFromDefault();
|
|
46
|
+
const raw = await k8sApi.listPodsStatusLines(kc, k8sApi.FLUX_SYSTEM_NS);
|
|
47
|
+
if (!raw)
|
|
48
|
+
return "";
|
|
49
|
+
const pods = raw.split("\n").filter(Boolean).map((line) => {
|
|
50
|
+
const parts = line.trim().split(/\t/);
|
|
51
|
+
const name = (parts[0] ?? "").replace(/^(.*?)-[a-f0-9]+-[a-z0-9]+$/, "$1");
|
|
52
|
+
const phase = parts[1] ?? "?";
|
|
53
|
+
const ready = parts[2] === "True";
|
|
54
|
+
const icon = ready ? pc.green("✓") : phase === "Running" ? pc.yellow("●") : pc.dim("○");
|
|
55
|
+
return ` ${icon} ${pc.dim(name)} ${pc.dim(phase)}`;
|
|
56
|
+
});
|
|
57
|
+
return pods.join("\n");
|
|
58
|
+
}
|
|
54
59
|
export async function waitForInstance() {
|
|
55
60
|
const s = p.spinner();
|
|
56
61
|
s.start("Waiting for FluxInstance to be ready");
|
|
57
|
-
const
|
|
62
|
+
const kc = k8sApi.kubeConfigFromDefault();
|
|
63
|
+
const waitPromise = k8sApi.waitForFluxInstanceReady(kc, 300_000);
|
|
58
64
|
const poll = setInterval(() => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
void getPodStatusLine().then((status) => {
|
|
66
|
+
if (status) {
|
|
67
|
+
s.message(`Waiting for FluxInstance to be ready\n${pc.dim(status)}`);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
63
70
|
}, 3000);
|
|
64
71
|
try {
|
|
65
72
|
await waitPromise;
|
|
@@ -73,26 +80,11 @@ export async function waitForInstance() {
|
|
|
73
80
|
clearInterval(poll);
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
|
-
function getPodStatusLine() {
|
|
77
|
-
const { stdout, exitCode } = execSafe(`kubectl get pods -n flux-system --no-headers -o custom-columns="NAME:.metadata.name,STATUS:.status.phase,READY:.status.conditions[?(@.type=='Ready')].status" 2>/dev/null`);
|
|
78
|
-
if (exitCode !== 0 || !stdout)
|
|
79
|
-
return "";
|
|
80
|
-
const pods = stdout.split("\n").filter(Boolean).map((line) => {
|
|
81
|
-
const parts = line.trim().split(/\s+/);
|
|
82
|
-
const name = (parts[0] ?? "").replace(/^(.*?)-[a-f0-9]+-[a-z0-9]+$/, "$1");
|
|
83
|
-
const phase = parts[1] ?? "?";
|
|
84
|
-
const ready = parts[2] === "True";
|
|
85
|
-
const icon = ready ? pc.green("✓") : phase === "Running" ? pc.yellow("●") : pc.dim("○");
|
|
86
|
-
return ` ${icon} ${pc.dim(name)} ${pc.dim(phase)}`;
|
|
87
|
-
});
|
|
88
|
-
return pods.join("\n");
|
|
89
|
-
}
|
|
90
83
|
export async function reconcile() {
|
|
91
84
|
await withSpinner("Reconciling Flux", async () => {
|
|
92
|
-
const
|
|
93
|
-
await execAsync(`kubectl -n flux-system annotate --overwrite fluxinstance/flux reconcile.fluxcd.io/requestedAt="${ts}"`);
|
|
85
|
+
const kc = k8sApi.kubeConfigFromDefault();
|
|
94
86
|
log.detail("Waiting for FluxInstance condition=Ready...");
|
|
95
|
-
await
|
|
87
|
+
await k8sApi.reconcileFluxInstance(kc, 300_000);
|
|
96
88
|
});
|
|
97
89
|
}
|
|
98
90
|
export function getStatus() {
|
package/dist/core/flux.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flux.js","sourceRoot":"","sources":["../../src/core/flux.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"flux.js","sourceRoot":"","sources":["../../src/core/flux.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as k8s from "@kubernetes/client-node";
|
|
2
|
+
export declare const FLUX_SYSTEM_NS = "flux-system";
|
|
3
|
+
export declare const FLUX_INSTANCE_GROUP = "fluxcd.controlplane.io";
|
|
4
|
+
export declare const FLUX_INSTANCE_VERSION = "v1";
|
|
5
|
+
export declare const FLUX_INSTANCE_PLURAL = "fluxinstances";
|
|
6
|
+
export declare function kubeConfigFromDefault(): k8s.KubeConfig;
|
|
7
|
+
export declare function makeClients(kc: k8s.KubeConfig): {
|
|
8
|
+
core: k8s.CoreV1Api;
|
|
9
|
+
apps: k8s.AppsV1Api;
|
|
10
|
+
custom: k8s.CustomObjectsApi;
|
|
11
|
+
};
|
|
12
|
+
export declare function isClusterReachableApi(kc: k8s.KubeConfig): Promise<boolean>;
|
|
13
|
+
export declare function waitForAllNodesReady(kc: k8s.KubeConfig, timeoutMs: number): Promise<void>;
|
|
14
|
+
export declare function createNamespaceApi(kc: k8s.KubeConfig, name: string): Promise<void>;
|
|
15
|
+
export declare function createSecretLiteralsApi(kc: k8s.KubeConfig, name: string, namespace: string, data: Record<string, string>): Promise<void>;
|
|
16
|
+
export declare function secretExistsApi(kc: k8s.KubeConfig, name: string, namespace: string): Promise<boolean>;
|
|
17
|
+
export declare function deleteSecretApi(kc: k8s.KubeConfig, name: string, namespace: string): Promise<void>;
|
|
18
|
+
export declare function createSecretFromFilesApi(kc: k8s.KubeConfig, name: string, namespace: string, files: Record<string, string>): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Run a command in a pod (by deployment name). Returns captured stdout/stderr.
|
|
21
|
+
*/
|
|
22
|
+
export declare function execInDeploymentContainer(kc: k8s.KubeConfig, namespace: string, deploymentName: string, containerName: string, command: string[]): Promise<{
|
|
23
|
+
stdout: string;
|
|
24
|
+
stderr: string;
|
|
25
|
+
exitCode: number;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Stream exec to process stdout/stderr (for interactive listing).
|
|
29
|
+
*/
|
|
30
|
+
export declare function execInDeploymentContainerTty(kc: k8s.KubeConfig, namespace: string, deploymentName: string, containerName: string, command: string[]): Promise<number>;
|
|
31
|
+
export declare function listPodsStatusLines(kc: k8s.KubeConfig, namespace: string): Promise<string>;
|
|
32
|
+
export declare function waitForFluxInstanceReady(kc: k8s.KubeConfig, timeoutMs: number): Promise<void>;
|
|
33
|
+
export declare function reconcileFluxInstance(kc: k8s.KubeConfig, timeoutMs: number): Promise<void>;
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kubernetes API access via @kubernetes/client-node
|
|
3
|
+
*/
|
|
4
|
+
import { Buffer } from "node:buffer";
|
|
5
|
+
import { Writable } from "node:stream";
|
|
6
|
+
import * as k8s from "@kubernetes/client-node";
|
|
7
|
+
export const FLUX_SYSTEM_NS = "flux-system";
|
|
8
|
+
export const FLUX_INSTANCE_GROUP = "fluxcd.controlplane.io";
|
|
9
|
+
export const FLUX_INSTANCE_VERSION = "v1";
|
|
10
|
+
export const FLUX_INSTANCE_PLURAL = "fluxinstances";
|
|
11
|
+
function sleep(ms) {
|
|
12
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
13
|
+
}
|
|
14
|
+
export function kubeConfigFromDefault() {
|
|
15
|
+
const kc = new k8s.KubeConfig();
|
|
16
|
+
kc.loadFromDefault();
|
|
17
|
+
return kc;
|
|
18
|
+
}
|
|
19
|
+
export function makeClients(kc) {
|
|
20
|
+
return {
|
|
21
|
+
core: kc.makeApiClient(k8s.CoreV1Api),
|
|
22
|
+
apps: kc.makeApiClient(k8s.AppsV1Api),
|
|
23
|
+
custom: kc.makeApiClient(k8s.CustomObjectsApi),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export async function isClusterReachableApi(kc) {
|
|
27
|
+
try {
|
|
28
|
+
const { core } = makeClients(kc);
|
|
29
|
+
await core.listNamespace({ limit: 1 });
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export async function waitForAllNodesReady(kc, timeoutMs) {
|
|
37
|
+
const { core } = makeClients(kc);
|
|
38
|
+
const deadline = Date.now() + timeoutMs;
|
|
39
|
+
while (Date.now() < deadline) {
|
|
40
|
+
const list = await core.listNode();
|
|
41
|
+
const items = list.items ?? [];
|
|
42
|
+
if (items.length > 0) {
|
|
43
|
+
const allReady = items.every((n) => n.status?.conditions?.some((c) => c.type === "Ready" && c.status === "True"));
|
|
44
|
+
if (allReady)
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
await sleep(2000);
|
|
48
|
+
}
|
|
49
|
+
throw new Error(`Timed out after ${timeoutMs}ms waiting for all nodes to be Ready`);
|
|
50
|
+
}
|
|
51
|
+
export async function createNamespaceApi(kc, name) {
|
|
52
|
+
const { core } = makeClients(kc);
|
|
53
|
+
try {
|
|
54
|
+
await core.createNamespace({
|
|
55
|
+
body: { metadata: { name } },
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
const code = e?.code
|
|
60
|
+
?? e?.body?.code;
|
|
61
|
+
if (code === 409)
|
|
62
|
+
return;
|
|
63
|
+
throw e;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export async function createSecretLiteralsApi(kc, name, namespace, data) {
|
|
67
|
+
const { core } = makeClients(kc);
|
|
68
|
+
const body = {
|
|
69
|
+
metadata: { name, namespace },
|
|
70
|
+
stringData: data,
|
|
71
|
+
};
|
|
72
|
+
try {
|
|
73
|
+
await core.createNamespacedSecret({ namespace, body });
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
const code = e?.code;
|
|
77
|
+
if (code === 409) {
|
|
78
|
+
await core.deleteNamespacedSecret({ name, namespace });
|
|
79
|
+
await core.createNamespacedSecret({ namespace, body });
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
throw e;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export async function secretExistsApi(kc, name, namespace) {
|
|
86
|
+
const { core } = makeClients(kc);
|
|
87
|
+
try {
|
|
88
|
+
await core.readNamespacedSecret({ name, namespace });
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export async function deleteSecretApi(kc, name, namespace) {
|
|
96
|
+
const { core } = makeClients(kc);
|
|
97
|
+
try {
|
|
98
|
+
await core.deleteNamespacedSecret({ name, namespace });
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
const code = e?.code;
|
|
102
|
+
if (code === 404)
|
|
103
|
+
return;
|
|
104
|
+
throw e;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export async function createSecretFromFilesApi(kc, name, namespace, files) {
|
|
108
|
+
const fs = await import("node:fs");
|
|
109
|
+
const stringData = {};
|
|
110
|
+
for (const [key, path] of Object.entries(files)) {
|
|
111
|
+
stringData[key] = fs.readFileSync(path, "utf-8");
|
|
112
|
+
}
|
|
113
|
+
await createSecretLiteralsApi(kc, name, namespace, stringData);
|
|
114
|
+
}
|
|
115
|
+
async function podNameForDeployment(kc, namespace, deploymentName) {
|
|
116
|
+
const { apps, core } = makeClients(kc);
|
|
117
|
+
const dep = await apps.readNamespacedDeployment({
|
|
118
|
+
name: deploymentName,
|
|
119
|
+
namespace,
|
|
120
|
+
});
|
|
121
|
+
const match = dep.spec?.selector?.matchLabels;
|
|
122
|
+
if (!match || Object.keys(match).length === 0)
|
|
123
|
+
return null;
|
|
124
|
+
const labelSelector = Object.entries(match)
|
|
125
|
+
.map(([k, v]) => `${k}=${String(v)}`)
|
|
126
|
+
.join(",");
|
|
127
|
+
const pods = await core.listNamespacedPod({ namespace, labelSelector });
|
|
128
|
+
const pick = pods.items?.find((p) => p.status?.phase === "Running") ?? pods.items?.[0];
|
|
129
|
+
return pick?.metadata?.name ?? null;
|
|
130
|
+
}
|
|
131
|
+
function statusExitCode(status) {
|
|
132
|
+
if (status.status === "Success")
|
|
133
|
+
return 0;
|
|
134
|
+
const c = status.code;
|
|
135
|
+
return typeof c === "number" ? c : 1;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Run a command in a pod (by deployment name). Returns captured stdout/stderr.
|
|
139
|
+
*/
|
|
140
|
+
export async function execInDeploymentContainer(kc, namespace, deploymentName, containerName, command) {
|
|
141
|
+
const podName = await podNameForDeployment(kc, namespace, deploymentName);
|
|
142
|
+
if (!podName) {
|
|
143
|
+
throw new Error(`No pod found for Deployment ${namespace}/${deploymentName}`);
|
|
144
|
+
}
|
|
145
|
+
const execApi = new k8s.Exec(kc);
|
|
146
|
+
const stdoutChunks = [];
|
|
147
|
+
const stderrChunks = [];
|
|
148
|
+
const stdout = new Writable({
|
|
149
|
+
write(chunk, _enc, cb) {
|
|
150
|
+
stdoutChunks.push(Buffer.from(chunk));
|
|
151
|
+
cb();
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
const stderr = new Writable({
|
|
155
|
+
write(chunk, _enc, cb) {
|
|
156
|
+
stderrChunks.push(Buffer.from(chunk));
|
|
157
|
+
cb();
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
let exitCode = 0;
|
|
161
|
+
await new Promise((resolve, reject) => {
|
|
162
|
+
execApi
|
|
163
|
+
.exec(namespace, podName, containerName, command, stdout, stderr, null, false, (status) => {
|
|
164
|
+
exitCode = statusExitCode(status);
|
|
165
|
+
resolve();
|
|
166
|
+
})
|
|
167
|
+
.catch(reject);
|
|
168
|
+
});
|
|
169
|
+
return {
|
|
170
|
+
stdout: Buffer.concat(stdoutChunks).toString("utf8"),
|
|
171
|
+
stderr: Buffer.concat(stderrChunks).toString("utf8"),
|
|
172
|
+
exitCode,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Stream exec to process stdout/stderr (for interactive listing).
|
|
177
|
+
*/
|
|
178
|
+
export async function execInDeploymentContainerTty(kc, namespace, deploymentName, containerName, command) {
|
|
179
|
+
const podName = await podNameForDeployment(kc, namespace, deploymentName);
|
|
180
|
+
if (!podName) {
|
|
181
|
+
throw new Error(`No pod found for Deployment ${namespace}/${deploymentName}`);
|
|
182
|
+
}
|
|
183
|
+
const execApi = new k8s.Exec(kc);
|
|
184
|
+
let exitCode = 0;
|
|
185
|
+
await new Promise((resolve, reject) => {
|
|
186
|
+
execApi
|
|
187
|
+
.exec(namespace, podName, containerName, command, process.stdout, process.stderr, null, false, (status) => {
|
|
188
|
+
exitCode = statusExitCode(status);
|
|
189
|
+
resolve();
|
|
190
|
+
})
|
|
191
|
+
.catch(reject);
|
|
192
|
+
});
|
|
193
|
+
return exitCode;
|
|
194
|
+
}
|
|
195
|
+
export async function listPodsStatusLines(kc, namespace) {
|
|
196
|
+
const { core } = makeClients(kc);
|
|
197
|
+
const list = await core.listNamespacedPod({ namespace });
|
|
198
|
+
const lines = [];
|
|
199
|
+
for (const pod of list.items ?? []) {
|
|
200
|
+
const name = pod.metadata?.name ?? "?";
|
|
201
|
+
const phase = pod.status?.phase ?? "?";
|
|
202
|
+
const ready = pod.status?.conditions?.find((c) => c.type === "Ready")?.status ===
|
|
203
|
+
"True";
|
|
204
|
+
lines.push(`${name}\t${phase}\t${ready ? "True" : "False"}`);
|
|
205
|
+
}
|
|
206
|
+
return lines.join("\n");
|
|
207
|
+
}
|
|
208
|
+
function fluxInstanceReady(obj) {
|
|
209
|
+
const o = obj;
|
|
210
|
+
return (o.status?.conditions?.some((c) => c.type === "Ready" && c.status === "True") ?? false);
|
|
211
|
+
}
|
|
212
|
+
export async function waitForFluxInstanceReady(kc, timeoutMs) {
|
|
213
|
+
const { custom } = makeClients(kc);
|
|
214
|
+
const deadline = Date.now() + timeoutMs;
|
|
215
|
+
while (Date.now() < deadline) {
|
|
216
|
+
const obj = await custom.getNamespacedCustomObject({
|
|
217
|
+
group: FLUX_INSTANCE_GROUP,
|
|
218
|
+
version: FLUX_INSTANCE_VERSION,
|
|
219
|
+
namespace: FLUX_SYSTEM_NS,
|
|
220
|
+
plural: FLUX_INSTANCE_PLURAL,
|
|
221
|
+
name: "flux",
|
|
222
|
+
});
|
|
223
|
+
if (fluxInstanceReady(obj))
|
|
224
|
+
return;
|
|
225
|
+
await sleep(2000);
|
|
226
|
+
}
|
|
227
|
+
throw new Error(`Timed out after ${timeoutMs}ms waiting for FluxInstance flux to be Ready`);
|
|
228
|
+
}
|
|
229
|
+
export async function reconcileFluxInstance(kc, timeoutMs) {
|
|
230
|
+
const { custom } = makeClients(kc);
|
|
231
|
+
const ts = Math.floor(Date.now() / 1000);
|
|
232
|
+
const existing = await custom.getNamespacedCustomObject({
|
|
233
|
+
group: FLUX_INSTANCE_GROUP,
|
|
234
|
+
version: FLUX_INSTANCE_VERSION,
|
|
235
|
+
namespace: FLUX_SYSTEM_NS,
|
|
236
|
+
plural: FLUX_INSTANCE_PLURAL,
|
|
237
|
+
name: "flux",
|
|
238
|
+
});
|
|
239
|
+
const merged = existing;
|
|
240
|
+
const meta = (merged.metadata ?? {});
|
|
241
|
+
const ann = (meta.annotations ?? {});
|
|
242
|
+
ann["reconcile.fluxcd.io/requestedAt"] = String(ts);
|
|
243
|
+
meta.annotations = ann;
|
|
244
|
+
merged.metadata = meta;
|
|
245
|
+
await custom.replaceNamespacedCustomObject({
|
|
246
|
+
group: FLUX_INSTANCE_GROUP,
|
|
247
|
+
version: FLUX_INSTANCE_VERSION,
|
|
248
|
+
namespace: FLUX_SYSTEM_NS,
|
|
249
|
+
plural: FLUX_INSTANCE_PLURAL,
|
|
250
|
+
name: "flux",
|
|
251
|
+
body: merged,
|
|
252
|
+
});
|
|
253
|
+
await waitForFluxInstanceReady(kc, timeoutMs);
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=k8s-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"k8s-api.js","sourceRoot":"","sources":["../../src/core/k8s-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare function isClusterReachable(): boolean
|
|
1
|
+
export declare function isClusterReachable(): Promise<boolean>;
|
|
2
2
|
export interface ExistingCluster {
|
|
3
3
|
type: "k3d" | "k3s";
|
|
4
4
|
names: string[];
|
|
@@ -13,7 +13,7 @@ export declare function setupKubeconfig(clusterName: string): string;
|
|
|
13
13
|
export declare function waitForCluster(): Promise<void>;
|
|
14
14
|
export declare function createNamespace(name: string): Promise<void>;
|
|
15
15
|
export declare function createSecret(name: string, namespace: string, data: Record<string, string>): Promise<void>;
|
|
16
|
-
export declare function secretExists(name: string, namespace: string): boolean
|
|
16
|
+
export declare function secretExists(name: string, namespace: string): Promise<boolean>;
|
|
17
17
|
export declare function deleteSecret(name: string, namespace: string): Promise<void>;
|
|
18
18
|
export declare function createSecretFromFile(name: string, namespace: string, key: string, filePath: string): Promise<void>;
|
|
19
19
|
export declare function createSshSecret(name: string, namespace: string, privateKey: string, publicKey: string, knownHosts: string): Promise<void>;
|
package/dist/core/kubernetes.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { mkdirSync, writeFileSync, rmSync, mkdtempSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
3
4
|
import { exec, execAsync, execSafe } from "../utils/shell.js";
|
|
4
5
|
import { isMacOS, isCI } from "../utils/platform.js";
|
|
5
6
|
import { log, withSpinner } from "../utils/log.js";
|
|
6
7
|
import { KUBERNETES_VERSION } from "../schemas.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return
|
|
8
|
+
import * as k8sApi from "./k8s-api.js";
|
|
9
|
+
export async function isClusterReachable() {
|
|
10
|
+
return k8sApi.isClusterReachableApi(k8sApi.kubeConfigFromDefault());
|
|
10
11
|
}
|
|
11
12
|
export function detectExistingClusters() {
|
|
12
13
|
if (isMacOS() || isCI()) {
|
|
@@ -82,62 +83,42 @@ export function setupKubeconfig(clusterName) {
|
|
|
82
83
|
export async function waitForCluster() {
|
|
83
84
|
await withSpinner("Waiting for cluster to be ready", async () => {
|
|
84
85
|
await new Promise((r) => setTimeout(r, 5000));
|
|
85
|
-
|
|
86
|
+
const kc = k8sApi.kubeConfigFromDefault();
|
|
87
|
+
await k8sApi.waitForAllNodesReady(kc, 120_000);
|
|
86
88
|
});
|
|
87
89
|
}
|
|
88
90
|
export async function createNamespace(name) {
|
|
89
|
-
await
|
|
91
|
+
await k8sApi.createNamespaceApi(k8sApi.kubeConfigFromDefault(), name);
|
|
90
92
|
}
|
|
91
93
|
export async function createSecret(name, namespace, data) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
"create",
|
|
95
|
-
"secret",
|
|
96
|
-
"generic",
|
|
97
|
-
name,
|
|
98
|
-
`--namespace=${namespace}`,
|
|
99
|
-
...Object.entries(data).flatMap(([k, v]) => ["--from-literal", `${k}=${v}`]),
|
|
100
|
-
];
|
|
101
|
-
log.detail(`kubectl create secret generic ${name} --namespace=${namespace}`);
|
|
102
|
-
const r = spawnSync("kubectl", args, {
|
|
103
|
-
encoding: "utf-8",
|
|
104
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
105
|
-
});
|
|
106
|
-
if (r.error)
|
|
107
|
-
throw r.error;
|
|
108
|
-
if (r.status !== 0) {
|
|
109
|
-
throw new Error(r.stderr?.trim() ||
|
|
110
|
-
`kubectl create secret failed (exit ${r.status ?? 1})`);
|
|
111
|
-
}
|
|
94
|
+
log.detail(`create secret ${name} --namespace=${namespace}`);
|
|
95
|
+
await k8sApi.createSecretLiteralsApi(k8sApi.kubeConfigFromDefault(), name, namespace, data);
|
|
112
96
|
}
|
|
113
|
-
export function secretExists(name, namespace) {
|
|
114
|
-
|
|
115
|
-
return exitCode === 0;
|
|
97
|
+
export async function secretExists(name, namespace) {
|
|
98
|
+
return k8sApi.secretExistsApi(k8sApi.kubeConfigFromDefault(), name, namespace);
|
|
116
99
|
}
|
|
117
100
|
export async function deleteSecret(name, namespace) {
|
|
118
|
-
await
|
|
101
|
+
await k8sApi.deleteSecretApi(k8sApi.kubeConfigFromDefault(), name, namespace);
|
|
119
102
|
}
|
|
120
103
|
export async function createSecretFromFile(name, namespace, key, filePath) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
await execAsync(cmd);
|
|
104
|
+
log.detail(`create secret generic ${name} --namespace=${namespace} --from-file=${key}`);
|
|
105
|
+
await k8sApi.createSecretFromFilesApi(k8sApi.kubeConfigFromDefault(), name, namespace, { [key]: filePath });
|
|
124
106
|
}
|
|
125
107
|
export async function createSshSecret(name, namespace, privateKey, publicKey, knownHosts) {
|
|
126
|
-
const tmpDir = "
|
|
127
|
-
mkdirSync(tmpDir, { recursive: true });
|
|
108
|
+
const tmpDir = mkdtempSync(join(tmpdir(), "flux-ssh-"));
|
|
128
109
|
try {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
110
|
+
const identity = join(tmpDir, "identity");
|
|
111
|
+
const identityPub = join(tmpDir, "identity.pub");
|
|
112
|
+
const knownHostsPath = join(tmpDir, "known_hosts");
|
|
113
|
+
writeFileSync(identity, privateKey, { mode: 0o600 });
|
|
114
|
+
writeFileSync(identityPub, publicKey);
|
|
115
|
+
writeFileSync(knownHostsPath, knownHosts);
|
|
116
|
+
log.detail(`create secret generic ${name} --namespace=${namespace} (SSH)`);
|
|
117
|
+
await k8sApi.createSecretFromFilesApi(k8sApi.kubeConfigFromDefault(), name, namespace, {
|
|
118
|
+
identity,
|
|
119
|
+
"identity.pub": identityPub,
|
|
120
|
+
known_hosts: knownHostsPath,
|
|
121
|
+
});
|
|
141
122
|
}
|
|
142
123
|
finally {
|
|
143
124
|
rmSync(tmpDir, { recursive: true, force: true });
|