feat: add Cloudflare DNS provisioning and health checks
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:
54
src/services/cloudflare.ts
Normal file
54
src/services/cloudflare.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { config } from "../lib/config";
|
||||
|
||||
const CF_API = "https://api.cloudflare.com/client/v4";
|
||||
|
||||
async function cfFetch(path: string, options: RequestInit = {}) {
|
||||
const res = await fetch(`${CF_API}${path}`, {
|
||||
...options,
|
||||
headers: {
|
||||
"Authorization": `Bearer ${config.cfApiToken}`,
|
||||
"Content-Type": "application/json",
|
||||
...options.headers,
|
||||
},
|
||||
});
|
||||
const data = await res.json() as { success: boolean; result: any; errors: any[] };
|
||||
if (!data.success) throw new Error(`Cloudflare API error: ${JSON.stringify(data.errors)}`);
|
||||
return data.result;
|
||||
}
|
||||
|
||||
export async function createCustomerDnsRecord(slug: string): Promise<void> {
|
||||
await cfFetch(`/zones/${config.cfZoneId}/dns_records`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
type: "A",
|
||||
name: `${slug}.lunarfront.tech`,
|
||||
content: config.ingressIp,
|
||||
ttl: 1, // auto TTL
|
||||
proxied: true,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
export async function deleteCustomerDnsRecord(slug: string): Promise<void> {
|
||||
const records = await cfFetch(`/zones/${config.cfZoneId}/dns_records?name=${slug}.lunarfront.tech&type=A`);
|
||||
for (const record of records) {
|
||||
await cfFetch(`/zones/${config.cfZoneId}/dns_records/${record.id}`, { method: "DELETE" });
|
||||
}
|
||||
}
|
||||
|
||||
export async function getCustomerDnsRecord(slug: string): Promise<{ exists: boolean; proxied: boolean; ip: string | null }> {
|
||||
const records = await cfFetch(`/zones/${config.cfZoneId}/dns_records?name=${slug}.lunarfront.tech&type=A`);
|
||||
if (!records.length) return { exists: false, proxied: false, ip: null };
|
||||
return { exists: true, proxied: records[0].proxied, ip: records[0].content };
|
||||
}
|
||||
|
||||
export async function checkCustomerHealth(slug: string): Promise<{ reachable: boolean; status: number | null }> {
|
||||
try {
|
||||
const res = await fetch(`https://${slug}.lunarfront.tech/health`, {
|
||||
signal: AbortSignal.timeout(5000),
|
||||
});
|
||||
return { reachable: res.ok, status: res.status };
|
||||
} catch {
|
||||
return { reachable: false, status: null };
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ spec:
|
||||
helm:
|
||||
parameters:
|
||||
- name: ingress.host
|
||||
value: ${slug}.lunarfront.app
|
||||
value: ${slug}.lunarfront.tech
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: customer-${slug}
|
||||
|
||||
Reference in New Issue
Block a user