feat(mcp): подготовить сервер и доступ к приёмке
This commit is contained in:
commit
bf3d50e1ff
3835 files changed
+537122
No files matched your search
@@ -0,0 +1,141 @@
|
||||
import { parseConfigRevisions } from "@/lib/config-revisions"
|
||||
import { wgListResponseSchema, wgIfaceDtoSchema, wgImportResponseSchema, wgExportResponseSchema } from "@mmapp/contracts/wireguard"
|
||||
import type {
|
||||
WgCreateInterface,
|
||||
WgCreatePeerRequest,
|
||||
WgExportRequest,
|
||||
WgExportResponse,
|
||||
WgImportRequest,
|
||||
WgImportResponse,
|
||||
WgListResponse,
|
||||
WgPatchInterface,
|
||||
WgPatchPeer,
|
||||
} from "@mmapp/contracts/wireguard"
|
||||
import { requestJson } from "@/shared/api/http-client"
|
||||
|
||||
export async function listWireGuard(
|
||||
baseUrl: string,
|
||||
opts?: { serverId?: string; includePrivateKey?: boolean },
|
||||
): Promise<WgListResponse> {
|
||||
const q = new URLSearchParams()
|
||||
if (opts?.serverId) q.set("serverId", opts.serverId)
|
||||
if (opts?.includePrivateKey) q.set("includePrivateKey", "1")
|
||||
const qs = q.toString()
|
||||
const parsed = wgListResponseSchema.safeParse(await requestJson<unknown>(baseUrl, `/api/wireguard${qs ? `?${qs}` : ""}`))
|
||||
if (!parsed.success) throw new Error("Ответ сервера содержит некорректный каталог WireGuard")
|
||||
const catalog = parsed.data, failures = catalog.failures ?? []
|
||||
const uniqueInterfaces = new Set(catalog.interfaces.map(row => JSON.stringify([row.serverId, row.id]))).size === catalog.interfaces.length
|
||||
const uniquePeers = catalog.interfaces.every(row => new Set(row.peers.map(peer => peer.id)).size === row.peers.length)
|
||||
const consistentFailures = failures.every(f => f.serverId.trim().length > 0) && new Set(failures.map(f => f.serverId)).size === failures.length && !catalog.interfaces.some(row => failures.some(f => f.serverId === row.serverId))
|
||||
if (!uniqueInterfaces || !uniquePeers || !consistentFailures) throw new Error("Ответ сервера содержит некорректный каталог WireGuard")
|
||||
return catalog
|
||||
}
|
||||
|
||||
export async function createWireGuardInterface(
|
||||
baseUrl: string,
|
||||
payload: WgCreateInterface,
|
||||
): Promise<unknown> {
|
||||
const result = await requestJson<unknown>(baseUrl, "/api/wireguard/interfaces", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
const iface = wgIfaceDtoSchema.safeParse(result)
|
||||
const confirmed = iface.success
|
||||
? iface.data.name === payload.name && String(iface.data.serverId) === String(payload.serverId)
|
||||
: typeof result === "object" && result !== null && "ok" in result && result.ok === true && "name" in result && result.name === payload.name
|
||||
if (!confirmed) throw new Error("Сервер не подтвердил создание интерфейса")
|
||||
return result
|
||||
}
|
||||
|
||||
export async function patchWireGuardInterface(
|
||||
baseUrl: string,
|
||||
serverId: string,
|
||||
rosId: string,
|
||||
payload: WgPatchInterface,
|
||||
): Promise<{ ok: boolean }> {
|
||||
return requestJson(baseUrl, `/api/wireguard/interfaces/${encodeURIComponent(serverId)}/${encodeURIComponent(rosId)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
}
|
||||
|
||||
export async function deleteWireGuardInterface(
|
||||
baseUrl: string,
|
||||
serverId: string,
|
||||
rosId: string,
|
||||
): Promise<{ ok: boolean }> {
|
||||
return requestJson(baseUrl, `/api/wireguard/interfaces/${encodeURIComponent(serverId)}/${encodeURIComponent(rosId)}`, {
|
||||
method: "DELETE",
|
||||
})
|
||||
}
|
||||
|
||||
export async function createWireGuardPeer(
|
||||
baseUrl: string,
|
||||
payload: WgCreatePeerRequest,
|
||||
): Promise<{ ok: boolean }> {
|
||||
const result = await requestJson<{ ok: boolean }>(baseUrl, "/api/wireguard/peers", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
if (result?.ok !== true) throw new Error("Сервер не подтвердил создание пира")
|
||||
return result
|
||||
}
|
||||
|
||||
export async function patchWireGuardPeer(
|
||||
baseUrl: string,
|
||||
serverId: string,
|
||||
rosId: string,
|
||||
payload: WgPatchPeer,
|
||||
): Promise<{ ok: boolean }> {
|
||||
return requestJson(baseUrl, `/api/wireguard/peers/${encodeURIComponent(serverId)}/${encodeURIComponent(rosId)}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
}
|
||||
|
||||
export async function deleteWireGuardPeer(
|
||||
baseUrl: string,
|
||||
serverId: string,
|
||||
rosId: string,
|
||||
): Promise<{ ok: boolean }> {
|
||||
return requestJson(baseUrl, `/api/wireguard/peers/${encodeURIComponent(serverId)}/${encodeURIComponent(rosId)}`, {
|
||||
method: "DELETE",
|
||||
})
|
||||
}
|
||||
|
||||
export async function importWireGuard(
|
||||
baseUrl: string,
|
||||
payload: WgImportRequest,
|
||||
): Promise<WgImportResponse> {
|
||||
const response = await requestJson<unknown>(baseUrl, "/api/wireguard/import", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
const parsed = wgImportResponseSchema.safeParse(response)
|
||||
if (!parsed.success) throw new Error("Некорректный ответ импорта WireGuard")
|
||||
const result = parsed.data
|
||||
if (result.dryRun !== (payload.dryRun ?? false) || (!result.dryRun && !result.applied)) {
|
||||
throw new Error("Сервер не подтвердил применение конфигурации")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export async function exportWireGuard(
|
||||
baseUrl: string,
|
||||
payload: WgExportRequest,
|
||||
): Promise<WgExportResponse> {
|
||||
const response = await requestJson<unknown>(baseUrl, "/api/wireguard/export", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
const parsed = wgExportResponseSchema.safeParse(response)
|
||||
if (!parsed.success || parsed.data.format !== payload.format) {
|
||||
throw new Error("Некорректный ответ экспорта WireGuard")
|
||||
}
|
||||
return parsed.data
|
||||
}
|
||||
|
||||
export async function listWireGuardRevisions(baseUrl: string, serverId: string) {
|
||||
const result = await requestJson<unknown>(baseUrl, "/api/wireguard/revisions?serverId=" + encodeURIComponent(serverId))
|
||||
return parseConfigRevisions(result, serverId, "wireguard")
|
||||
}
|
||||
Reference in new issue
Block a user