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
- 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.
156 lines
4.2 KiB
TypeScript
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",
|
|
}),
|
|
]),
|
|
);
|
|
});
|
|
});
|