quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 6s
quality / changes (push) Successful in 8s
quality / web (push) Skipped
quality / docker-check (push) Skipped
quality / api (push) Successful in 42s
CD / quality (push) Successful in 54s
CD / publish (push) Successful in 1m36s
Схлопывание дубликатов в группе вызывало ReferenceError при сохранении сервиса. Co-authored-by: Cursor <[email protected]>
131 lines
3.9 KiB
TypeScript
131 lines
3.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { createMemoryDb, repos, runMigrations } from "@cfdm/db";
|
|
import type { CloudflareClient } from "../src/lib/cf-client.js";
|
|
import { updateConfig } from "../src/services/service-config-service.js";
|
|
|
|
function mockCf(): CloudflareClient {
|
|
return {
|
|
listDnsRecords: async () => [],
|
|
createDnsRecord: async () => ({
|
|
id: "cf-new",
|
|
type: "A",
|
|
name: "api.example.com",
|
|
content: "10.0.0.1",
|
|
ttl: 1,
|
|
proxied: false,
|
|
}),
|
|
updateDnsRecord: async () => ({
|
|
id: "cf-upd",
|
|
type: "A",
|
|
name: "api.example.com",
|
|
content: "10.0.0.1",
|
|
ttl: 1,
|
|
proxied: false,
|
|
}),
|
|
deleteDnsRecord: async () => undefined,
|
|
verifyToken: async () => true,
|
|
listZones: async () => [],
|
|
} as unknown as CloudflareClient;
|
|
}
|
|
|
|
function setupDb() {
|
|
const { db, sqlite } = createMemoryDb();
|
|
runMigrations(sqlite);
|
|
return db;
|
|
}
|
|
|
|
describe("service bindings prune", () => {
|
|
it("updateConfig with domains: [] removes all bindings", async () => {
|
|
const db = setupDb();
|
|
const cf = mockCf();
|
|
|
|
const domain = repos.createDomain(db, null, "example.com", "cf-zone-example");
|
|
const service = repos.createService(db, "Web", "web");
|
|
repos.replaceServiceIps(db, service.id, ["10.0.0.1"]);
|
|
const binding = repos.insertBinding(db, domain.id, service.id, "api", null);
|
|
repos.replaceBindingIps(db, binding.id, ["10.0.0.1"]);
|
|
|
|
expect(repos.listBindingsByService(db, service.id)).toHaveLength(1);
|
|
|
|
const view = await updateConfig(db, cf, service.id, {
|
|
ips: ["10.0.0.1"],
|
|
domains: [],
|
|
});
|
|
|
|
expect(repos.listBindingsByService(db, service.id)).toHaveLength(0);
|
|
expect(view.domains).toEqual([]);
|
|
});
|
|
|
|
it("updateConfig keeps multiple FQDN bindings", async () => {
|
|
const db = setupDb();
|
|
const cf = mockCf();
|
|
|
|
repos.createDomain(db, null, "a.example", "cf-zone-a");
|
|
repos.createDomain(db, null, "b.example", "cf-zone-b");
|
|
const service = repos.createService(db, "Edge", "edge");
|
|
repos.replaceServiceIps(db, service.id, ["10.0.0.2"]);
|
|
|
|
const view = await updateConfig(db, cf, service.id, {
|
|
ips: ["10.0.0.2"],
|
|
domains: [
|
|
{ fqdn: "api.a.example", target_ips: ["10.0.0.2"] },
|
|
{ fqdn: "www.b.example", target_ips: ["10.0.0.2"] },
|
|
],
|
|
});
|
|
|
|
expect(view.domains).toHaveLength(2);
|
|
const bindings = repos.listBindingsByService(db, service.id);
|
|
expect(bindings).toHaveLength(2);
|
|
expect(bindings.map((b) => b.hostname).sort()).toEqual(["api", "www"]);
|
|
});
|
|
|
|
it("updateConfig with extra FQDN per IP does not throw when group health-check is on", async () => {
|
|
const db = setupDb();
|
|
const cf = mockCf();
|
|
const health = {
|
|
health_check_enabled: true,
|
|
health_check_type: "tcp" as const,
|
|
health_check_port: 443,
|
|
health_check_providers: ["local", "cloudflare", "globalping"] as const,
|
|
health_check_aggregate: "majority" as const,
|
|
};
|
|
|
|
repos.createDomain(db, null, "example.com", "cf-zone-example");
|
|
const group = repos.createServiceGroup(
|
|
db,
|
|
"VPN",
|
|
"vpn",
|
|
null,
|
|
"vpn.example.com",
|
|
{ ...health },
|
|
);
|
|
const service = repos.createService(db, "GT", "gt");
|
|
repos.setServiceGroup(db, service.id, group.id);
|
|
repos.setServiceEnabled(db, service.id, true);
|
|
|
|
const view = await updateConfig(db, cf, service.id, {
|
|
ips: ["93.115.203.183", "130.49.213.153"],
|
|
domains: [
|
|
{
|
|
fqdn: "gt.example.com",
|
|
target_ips: ["93.115.203.183", "130.49.213.153"],
|
|
...health,
|
|
},
|
|
{
|
|
fqdn: "rutg.example.com",
|
|
target_ips: ["93.115.203.183"],
|
|
...health,
|
|
},
|
|
{
|
|
fqdn: "nsgt.example.com",
|
|
target_ips: ["130.49.213.153"],
|
|
...health,
|
|
},
|
|
],
|
|
});
|
|
|
|
expect(view.domains).toHaveLength(3);
|
|
expect(view.ips.sort()).toEqual(["130.49.213.153", "93.115.203.183"]);
|
|
});
|
|
});
|