feat: add github-backed decision storage
This commit is contained in:
@@ -182,7 +182,59 @@ function readDecisionCenterDatabase(decision) {
|
||||
};
|
||||
}
|
||||
|
||||
function readFileSource(sourceRef, path) {
|
||||
const sourcePath = resolve(required(sourceRef.path, `${path}.path`));
|
||||
const value = readFileSync(sourcePath, "utf8");
|
||||
if (value.length === 0) throw new Error(`missing file content in ${sourcePath}`);
|
||||
return {
|
||||
sourcePath,
|
||||
sourceRefPath: required(sourceRef.path, `${path}.path`),
|
||||
value,
|
||||
fingerprint: sha(value),
|
||||
};
|
||||
}
|
||||
|
||||
function readDecisionCenterStorage(decision) {
|
||||
if (decision === null) return null;
|
||||
const storage = optionalRecord(decision.storage, "services.decisionCenter.storage");
|
||||
if (storage === null) return null;
|
||||
const primary = required(storage.primary, "services.decisionCenter.storage.primary");
|
||||
if (primary !== "postgres" && primary !== "github-repo") throw new Error("services.decisionCenter.storage.primary must be postgres or github-repo");
|
||||
const github = primary === "github-repo" ? record(storage.github, "services.decisionCenter.storage.github") : null;
|
||||
if (github === null) return { primary };
|
||||
const ssh = record(github.ssh, "services.decisionCenter.storage.github.ssh");
|
||||
const privateKey = record(ssh.privateKey, "services.decisionCenter.storage.github.ssh.privateKey");
|
||||
const knownHosts = record(ssh.knownHosts, "services.decisionCenter.storage.github.ssh.knownHosts");
|
||||
const privateKeySource = readFileSource(record(privateKey.sourceRef, "services.decisionCenter.storage.github.ssh.privateKey.sourceRef"), "services.decisionCenter.storage.github.ssh.privateKey.sourceRef");
|
||||
const knownHostsSource = readFileSource(record(knownHosts.sourceRef, "services.decisionCenter.storage.github.ssh.knownHosts.sourceRef"), "services.decisionCenter.storage.github.ssh.knownHosts.sourceRef");
|
||||
return {
|
||||
primary,
|
||||
github: {
|
||||
repo: required(github.repo, "services.decisionCenter.storage.github.repo"),
|
||||
sshUrl: required(github.sshUrl, "services.decisionCenter.storage.github.sshUrl"),
|
||||
branch: required(github.branch, "services.decisionCenter.storage.github.branch"),
|
||||
basePath: required(github.basePath, "services.decisionCenter.storage.github.basePath"),
|
||||
worktreePath: required(github.worktreePath, "services.decisionCenter.storage.github.worktreePath"),
|
||||
commitMessagePrefix: required(github.commitMessagePrefix, "services.decisionCenter.storage.github.commitMessagePrefix"),
|
||||
author: {
|
||||
name: required(record(github.author, "services.decisionCenter.storage.github.author").name, "services.decisionCenter.storage.github.author.name"),
|
||||
email: required(record(github.author, "services.decisionCenter.storage.github.author").email, "services.decisionCenter.storage.github.author.email"),
|
||||
},
|
||||
ssh: {
|
||||
secretName: required(ssh.secretName, "services.decisionCenter.storage.github.ssh.secretName"),
|
||||
mountPath: required(ssh.mountPath, "services.decisionCenter.storage.github.ssh.mountPath"),
|
||||
privateKeyKey: required(privateKey.secretKey, "services.decisionCenter.storage.github.ssh.privateKey.secretKey"),
|
||||
knownHostsKey: required(knownHosts.secretKey, "services.decisionCenter.storage.github.ssh.knownHosts.secretKey"),
|
||||
privateKeySource,
|
||||
knownHostsSource,
|
||||
fingerprint: sha(`${privateKeySource.fingerprint}\n${knownHostsSource.fingerprint}`),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const decisionCenterDatabase = readDecisionCenterDatabase(decisionCenter);
|
||||
const decisionCenterStorage = readDecisionCenterStorage(decisionCenter);
|
||||
const effectiveMicroservicesJson = decisionCenter === null
|
||||
? required(runtimeConfig.microservicesJson, "runtimeConfig.microservicesJson")
|
||||
: JSON.stringify([
|
||||
@@ -295,6 +347,24 @@ type: Opaque
|
||||
stringData:
|
||||
${decisionCenterDatabase.secretKey}: ${yamlScalar(decisionCenterDatabase.value)}`);
|
||||
}
|
||||
if (decisionCenterStorage?.github !== undefined) {
|
||||
docs.push(`apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: ${decisionCenterStorage.github.ssh.secretName}
|
||||
namespace: ${namespace}
|
||||
labels:
|
||||
${indent(labels(config), 4)}
|
||||
app.kubernetes.io/name: decision-center
|
||||
annotations:
|
||||
unidesk.ai/private-key-source-ref: ${yamlScalar(decisionCenterStorage.github.ssh.privateKeySource.sourceRefPath)}
|
||||
unidesk.ai/known-hosts-source-ref: ${yamlScalar(decisionCenterStorage.github.ssh.knownHostsSource.sourceRefPath)}
|
||||
unidesk.ai/fingerprint: ${yamlScalar(decisionCenterStorage.github.ssh.fingerprint)}
|
||||
type: Opaque
|
||||
stringData:
|
||||
${decisionCenterStorage.github.ssh.privateKeyKey}: ${yamlScalar(decisionCenterStorage.github.ssh.privateKeySource.value)}
|
||||
${decisionCenterStorage.github.ssh.knownHostsKey}: ${yamlScalar(decisionCenterStorage.github.ssh.knownHostsSource.value)}`);
|
||||
}
|
||||
if (databaseMode === "k8s-postgres") {
|
||||
docs.push(`apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
@@ -552,6 +622,7 @@ spec:
|
||||
app.kubernetes.io/part-of: unidesk
|
||||
annotations:
|
||||
unidesk.ai/secret-fingerprint: ${yamlScalar(decisionCenterDatabase?.fingerprint ?? "")}
|
||||
unidesk.ai/storage-secret-fingerprint: ${yamlScalar(decisionCenterStorage?.github?.ssh.fingerprint ?? "")}
|
||||
unidesk.ai/runtime-config-fingerprint: ${yamlScalar(runtimeConfigFingerprint)}
|
||||
spec:
|
||||
initContainers:
|
||||
@@ -594,9 +665,30 @@ spec:
|
||||
value: ${yamlScalar(required(runtime.commit, "runtime.commit"))}
|
||||
- name: LOG_FILE
|
||||
value: ${yamlScalar(required(decisionCenter.logFile, "services.decisionCenter.logFile"))}
|
||||
- name: DECISION_CENTER_STORAGE_PRIMARY
|
||||
value: ${yamlScalar(decisionCenterStorage?.primary ?? "postgres")}
|
||||
${decisionCenterStorage?.github !== undefined ? indent(`- name: DECISION_CENTER_GIT_REPO_SSH_URL
|
||||
value: ${yamlScalar(decisionCenterStorage.github.sshUrl)}
|
||||
- name: DECISION_CENTER_GIT_BRANCH
|
||||
value: ${yamlScalar(decisionCenterStorage.github.branch)}
|
||||
- name: DECISION_CENTER_GIT_BASE_PATH
|
||||
value: ${yamlScalar(decisionCenterStorage.github.basePath)}
|
||||
- name: DECISION_CENTER_GIT_WORKTREE
|
||||
value: ${yamlScalar(decisionCenterStorage.github.worktreePath)}
|
||||
- name: DECISION_CENTER_GIT_AUTHOR_NAME
|
||||
value: ${yamlScalar(decisionCenterStorage.github.author.name)}
|
||||
- name: DECISION_CENTER_GIT_AUTHOR_EMAIL
|
||||
value: ${yamlScalar(decisionCenterStorage.github.author.email)}
|
||||
- name: DECISION_CENTER_GIT_COMMIT_PREFIX
|
||||
value: ${yamlScalar(decisionCenterStorage.github.commitMessagePrefix)}
|
||||
- name: GIT_SSH_COMMAND
|
||||
value: ${yamlScalar(`ssh -i ${decisionCenterStorage.github.ssh.mountPath}/${decisionCenterStorage.github.ssh.privateKeyKey} -o UserKnownHostsFile=${decisionCenterStorage.github.ssh.mountPath}/${decisionCenterStorage.github.ssh.knownHostsKey} -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes`)}`, 12) : ""}
|
||||
volumeMounts:
|
||||
- name: logs
|
||||
mountPath: /var/log/unidesk
|
||||
${decisionCenterStorage?.github !== undefined ? indent(`- name: github-ssh
|
||||
mountPath: ${yamlScalar(decisionCenterStorage.github.ssh.mountPath)}
|
||||
readOnly: true`, 12) : ""}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: ${required(decisionCenter.healthPath, "services.decisionCenter.healthPath")}
|
||||
@@ -622,6 +714,13 @@ ${indent(resourceBlock(decisionCenter.resources), 10)}
|
||||
volumes:
|
||||
- name: logs
|
||||
emptyDir: {}`);
|
||||
if (decisionCenterStorage?.github !== undefined) {
|
||||
docs[docs.length - 1] += `
|
||||
- name: github-ssh
|
||||
secret:
|
||||
secretName: ${decisionCenterStorage.github.ssh.secretName}
|
||||
defaultMode: 0400`;
|
||||
}
|
||||
}
|
||||
docs.push(`apiVersion: v1
|
||||
kind: Service
|
||||
|
||||
Reference in New Issue
Block a user