feat: add individual and bulk chart upgrade, fix health check URL
All checks were successful
Build & Release / build (push) Successful in 12s
All checks were successful
Build & Release / build (push) Successful in 12s
This commit is contained in:
@@ -4,7 +4,7 @@ import crypto from "crypto";
|
||||
import postgres from "postgres";
|
||||
import { createDatabase, createDatabaseUser, deleteDatabase, deleteDatabaseUser } from "../services/do";
|
||||
import { addCustomerToPool, removeCustomerFromPool } from "../services/pgbouncer";
|
||||
import { addCustomerChart, removeCustomerChart } from "../services/git";
|
||||
import { addCustomerChart, removeCustomerChart, upgradeCustomerChart, upgradeAllCustomerCharts, getLatestChartVersion } from "../services/git";
|
||||
import { setupCustomerDatabase, teardownCustomerDatabase } from "../services/db";
|
||||
import { createNamespace, deleteNamespace, createSecret, createDockerRegistrySecret, patchSecret, getSecret, k8sFetch } from "../lib/k8s";
|
||||
import { deleteSpacesObjects, getSpacesUsage } from "../services/spaces";
|
||||
@@ -305,6 +305,27 @@ export async function customerRoutes(app: FastifyInstance) {
|
||||
return reply.code(200).send({ slug, status: "provisioned" });
|
||||
});
|
||||
|
||||
app.post("/customers/:slug/upgrade", async (req, reply) => {
|
||||
const { slug } = req.params as { slug: string };
|
||||
const [customer] = await db`SELECT * FROM customers WHERE slug = ${slug}`;
|
||||
if (!customer) return reply.code(404).send({ message: "Not found" });
|
||||
const version = await getLatestChartVersion();
|
||||
await upgradeCustomerChart(slug, version);
|
||||
await db`UPDATE customers SET updated_at = NOW() WHERE slug = ${slug}`;
|
||||
app.log.info({ slug, version }, "customer chart upgraded");
|
||||
return reply.send({ slug, version });
|
||||
});
|
||||
|
||||
app.post("/customers/upgrade-all", async (req, reply) => {
|
||||
const customers = await db`SELECT slug FROM customers WHERE status = 'provisioned'`;
|
||||
if (!customers.length) return reply.send({ upgraded: [], version: null });
|
||||
const version = await getLatestChartVersion();
|
||||
const slugs = customers.map((c: any) => c.slug);
|
||||
await upgradeAllCustomerCharts(slugs, version);
|
||||
app.log.info({ slugs, version }, "all customers chart upgraded");
|
||||
return reply.send({ upgraded: slugs, version });
|
||||
});
|
||||
|
||||
// Remove only the manager DB record without touching infrastructure
|
||||
app.delete("/customers/:slug/record", async (req, reply) => {
|
||||
const { slug } = req.params as { slug: string };
|
||||
|
||||
@@ -44,7 +44,7 @@ export async function getCustomerDnsRecord(slug: string): Promise<{ exists: bool
|
||||
|
||||
export async function checkCustomerHealth(slug: string): Promise<{ reachable: boolean; status: number | null }> {
|
||||
try {
|
||||
const res = await fetch(`https://${slug}.lunarfront.tech/api/health`, {
|
||||
const res = await fetch(`https://${slug}.lunarfront.tech/v1/health`, {
|
||||
signal: AbortSignal.timeout(5000),
|
||||
});
|
||||
return { reachable: res.ok, status: res.status };
|
||||
|
||||
@@ -4,7 +4,7 @@ import { tmpdir } from "os";
|
||||
import { join } from "path";
|
||||
import { config } from "../lib/config";
|
||||
|
||||
async function getLatestChartVersion(): Promise<string> {
|
||||
export async function getLatestChartVersion(): Promise<string> {
|
||||
const res = await fetch("https://api.digitalocean.com/v2/registry/lunarfront/repositories/lunarfront/tags?page=1&per_page=100", {
|
||||
headers: { Authorization: `Bearer ${config.doToken}` },
|
||||
});
|
||||
@@ -57,6 +57,26 @@ export async function addCustomerChart(slug: string, appVersion: string) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function upgradeCustomerChart(slug: string, version: string) {
|
||||
withRepo((dir, env) => {
|
||||
const manifest = buildArgoCDApp(slug, version);
|
||||
writeFileSync(join(dir, "customers", `${slug}.yaml`), manifest);
|
||||
execSync(`git -C ${dir} add customers/${slug}.yaml`, { env });
|
||||
execSync(`git -C ${dir} commit -m "chore: upgrade customer ${slug} to chart ${version}"`, { env });
|
||||
});
|
||||
}
|
||||
|
||||
export async function upgradeAllCustomerCharts(slugs: string[], version: string) {
|
||||
withRepo((dir, env) => {
|
||||
for (const slug of slugs) {
|
||||
const manifest = buildArgoCDApp(slug, version);
|
||||
writeFileSync(join(dir, "customers", `${slug}.yaml`), manifest);
|
||||
execSync(`git -C ${dir} add customers/${slug}.yaml`, { env });
|
||||
}
|
||||
execSync(`git -C ${dir} commit -m "chore: upgrade all customers to chart ${version}"`, { env });
|
||||
});
|
||||
}
|
||||
|
||||
export function removeCustomerChart(slug: string) {
|
||||
withRepo((dir, env) => {
|
||||
const filePath = join(dir, "customers", `${slug}.yaml`);
|
||||
|
||||
Reference in New Issue
Block a user