Files
Denozordec 146afc1369
quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 5s
quality / changes (push) Successful in 5s
quality / docker-check (push) Skipped
quality / web (push) Successful in 56s
quality / api (push) Successful in 43s
CD / quality (push) Successful in 1m46s
CD / publish (push) Successful in 1m40s
feat(dns): Implement DNS preview records generation and enhance hostname preview functionality
- Added `buildDnsPreviewRecords` function to generate DNS records based on hostname, TTL, and provided IPv4/IPv6 addresses.
- Updated `fleetRoutes` to utilize the new DNS records generation for hostname previews.
- Enhanced frontend API calls to support IPv4, IPv6, and node ID parameters for more comprehensive hostname previews.
- Updated UI components to display DNS preview information, including A, AAAA, and CNAME records.
2026-09-04 15:09:30 +07:00

156 lines
4.2 KiB
TypeScript

import { describe, it, expect, beforeAll, afterAll } from "vitest";
import { buildApp } from "../src/app.js";
import { loadConfig } from "../src/config.js";
import type { FastifyInstance } from "fastify";
describe("fleet api", () => {
let app: FastifyInstance;
let authHeader: { authorization: string };
beforeAll(async () => {
app = await buildApp({
config: { ...loadConfig(), staticDir: null, authRequired: false },
memory: true,
});
const login = await app.inject({
method: "POST",
url: "/api/v1/auth/login",
payload: { username: "admin", password: "admin" },
});
expect(login.statusCode).toBe(200);
const token = login.json().token as string;
authHeader = { authorization: `Bearer ${token}` };
});
afterAll(async () => {
await app.close();
});
it("lists seeded locations", async () => {
const res = await app.inject({
method: "GET",
url: "/api/v1/locations",
headers: authHeader,
});
expect(res.statusCode).toBe(200);
const body = res.json();
expect(body.length).toBeGreaterThanOrEqual(5);
expect(body.some((l: { code: string }) => l.code === "msk")).toBe(true);
});
it("creates zone, node, alias and exports bind", async () => {
const zoneRes = await app.inject({
method: "POST",
url: "/api/v1/zones",
headers: authHeader,
payload: { name: "rtnt.top" },
});
expect(zoneRes.statusCode).toBe(200);
const zone = zoneRes.json();
const locs = (
await app.inject({
method: "GET",
url: "/api/v1/locations",
headers: authHeader,
})
).json();
const msk = locs.find((l: { code: string }) => l.code === "msk");
const nodeRes = await app.inject({
method: "POST",
url: "/api/v1/nodes",
headers: authHeader,
payload: {
zoneId: zone.id,
locationId: msk.id,
role: "hub",
indexNum: 1,
ipv4: "94.142.140.141",
},
});
expect(nodeRes.statusCode).toBe(200);
const node = nodeRes.json();
expect(node.hostname).toBe("msk-hub01.rtnt.top");
const aliasRes = await app.inject({
method: "POST",
url: "/api/v1/aliases",
headers: authHeader,
payload: {
zoneId: zone.id,
name: "msk.rtnt.top",
purpose: "geo",
mode: "primary",
targetNodeId: node.id,
},
});
expect(aliasRes.statusCode).toBe(200);
const bind = await app.inject({
method: "GET",
url: `/api/v1/zones/${zone.id}/export/bind`,
headers: authHeader,
});
expect(bind.statusCode).toBe(200);
expect(bind.json().content).toContain("msk-hub01.rtnt.top");
expect(bind.json().content).toContain("msk.rtnt.top");
const stats = await app.inject({
method: "GET",
url: "/api/v1/dashboard/stats",
headers: authHeader,
});
expect(stats.statusCode).toBe(200);
expect(stats.json().nodes).toBe(1);
expect(stats.json().aliases).toBe(1);
const topo = await app.inject({
method: "GET",
url: "/api/v1/topology",
headers: authHeader,
});
expect(topo.statusCode).toBe(200);
expect(topo.json().nodes).toHaveLength(1);
const preview = await app.inject({
method: "GET",
url: `/api/v1/naming/preview?${new URLSearchParams({
zoneId: zone.id,
locationId: msk.id,
role: "gw",
indexNum: "2",
ipv4: "198.51.100.10",
ipv6: "2001:db8::10",
nodeId: node.id,
})}`,
headers: authHeader,
});
expect(preview.statusCode).toBe(200);
const body = preview.json() as {
hostname: string;
records: Array<{ type: string; name: string; content: string }>;
};
expect(body.hostname).toBe("msk-gw02.rtnt.top");
expect(body.records).toEqual(
expect.arrayContaining([
expect.objectContaining({
type: "A",
name: "msk-gw02.rtnt.top",
content: "198.51.100.10",
}),
expect.objectContaining({
type: "AAAA",
name: "msk-gw02.rtnt.top",
content: "2001:db8::10",
}),
expect.objectContaining({
type: "CNAME",
name: "msk.rtnt.top",
content: "msk-gw02.rtnt.top",
}),
]),
);
});
});