refactor: update AS entry handling in API and database to support ASN-only entries. Remove prefix field from AS entry structure and adjust related functions and tests. Enhance OpenAPI specifications and documentation to reflect changes in AS entry representation.
This commit is contained in:
@@ -36,13 +36,15 @@ export type ModulePatch = Partial<Omit<ModuleCreate, 'type'>>;
|
||||
// ---- AS Entries ----
|
||||
export type AsEntry = {
|
||||
id: string;
|
||||
asn: number | null;
|
||||
prefix: string | null;
|
||||
asn: number;
|
||||
community_id: string | null;
|
||||
};
|
||||
export type AsEntryCreate = {
|
||||
asn: number;
|
||||
community_id?: string | null;
|
||||
};
|
||||
export type AsEntryPatch = {
|
||||
asn?: number;
|
||||
prefix?: string;
|
||||
community_id?: string | null;
|
||||
};
|
||||
export type AsEntriesResponse = Page<AsEntry>;
|
||||
@@ -158,6 +160,7 @@ export type RevisionRow = {
|
||||
export type RevisionsResponse = Page<RevisionRow>;
|
||||
|
||||
export type RevisionPrefix = {
|
||||
/** Обычно CIDR; для AS-модуля в снимке ревизии — строка вида `as:<номер_asn>`. */
|
||||
prefix: string;
|
||||
community_id?: string | null;
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
});
|
||||
|
||||
const moduleTypes = [
|
||||
{ value: 'AS_PREFIXES', label: 'AS Prefixes' },
|
||||
{ value: 'AS_PREFIXES', label: 'AS (номера)' },
|
||||
{ value: 'CDN_CIDRS', label: 'CDN CIDRs' },
|
||||
{ value: 'DOMAINS', label: 'Домены' },
|
||||
{ value: 'IP_RANGES', label: 'IP Ranges' }
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
ModulePatch,
|
||||
AsEntry,
|
||||
AsEntryCreate,
|
||||
AsEntryPatch,
|
||||
AsEntriesResponse,
|
||||
CdnSource,
|
||||
CdnSourceCreate,
|
||||
@@ -82,7 +83,7 @@
|
||||
let asEntries = $state<AsEntry[]>([]);
|
||||
let asDialog = $state(false);
|
||||
let asEdit = $state<AsEntry | null>(null);
|
||||
let asForm = $state<AsEntryCreate>({ asn: undefined, prefix: undefined, community_id: null });
|
||||
let asForm = $state<AsEntryCreate>({ asn: 0, community_id: null });
|
||||
let asSaving = $state(false);
|
||||
let asDeleteTarget = $state<AsEntry | null>(null);
|
||||
|
||||
@@ -223,22 +224,28 @@
|
||||
// --- AS Entries ---
|
||||
function openAsCreate() {
|
||||
asEdit = null;
|
||||
asForm = { asn: undefined, prefix: undefined, community_id: null };
|
||||
asForm = { asn: 0, community_id: null };
|
||||
asDialog = true;
|
||||
}
|
||||
function openAsEdit(entry: AsEntry) {
|
||||
asEdit = entry;
|
||||
asForm = { asn: entry.asn ?? undefined, prefix: entry.prefix ?? undefined, community_id: entry.community_id };
|
||||
asForm = { asn: entry.asn, community_id: entry.community_id };
|
||||
asDialog = true;
|
||||
}
|
||||
async function saveAs() {
|
||||
const asn = Number(asForm.asn);
|
||||
if (!Number.isFinite(asn) || asn < 1 || asn > 4294967295) {
|
||||
toast.error('Укажите корректный ASN (1–4294967295)');
|
||||
return;
|
||||
}
|
||||
asSaving = true;
|
||||
try {
|
||||
const body: AsEntryCreate | AsEntryPatch = { asn, community_id: asForm.community_id };
|
||||
if (asEdit) {
|
||||
await apiMutate(`/v1/modules/${moduleId}/as-entries/${asEdit.id}`, 'PATCH', asForm);
|
||||
await apiMutate(`/v1/modules/${moduleId}/as-entries/${asEdit.id}`, 'PATCH', body);
|
||||
toast.success('Запись обновлена');
|
||||
} else {
|
||||
await apiMutate(`/v1/modules/${moduleId}/as-entries`, 'POST', asForm);
|
||||
await apiMutate(`/v1/modules/${moduleId}/as-entries`, 'POST', body as AsEntryCreate);
|
||||
toast.success('Запись добавлена');
|
||||
}
|
||||
asDialog = false;
|
||||
@@ -468,7 +475,7 @@
|
||||
<CardHeader class="flex flex-row items-center justify-between pb-2">
|
||||
<div>
|
||||
<CardTitle class="text-base">AS-записи</CardTitle>
|
||||
<CardDescription>ASN и/или префиксы для анонса</CardDescription>
|
||||
<CardDescription>Номер AS и привязка к BGP community</CardDescription>
|
||||
</div>
|
||||
<Button size="sm" onclick={openAsCreate}><Plus />Добавить</Button>
|
||||
</CardHeader>
|
||||
@@ -477,7 +484,6 @@
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>ASN</TableHead>
|
||||
<TableHead>Префикс</TableHead>
|
||||
<TableHead>Community</TableHead>
|
||||
<TableHead class="w-20"></TableHead>
|
||||
</TableRow>
|
||||
@@ -485,8 +491,7 @@
|
||||
<TableBody>
|
||||
{#each asEntries as entry (entry.id)}
|
||||
<TableRow>
|
||||
<TableCell class="font-mono">{entry.asn ?? '—'}</TableCell>
|
||||
<TableCell class="font-mono">{entry.prefix ?? '—'}</TableCell>
|
||||
<TableCell class="font-mono">{entry.asn}</TableCell>
|
||||
<TableCell class="text-muted-foreground text-sm">{communityName(entry.community_id)}</TableCell>
|
||||
<TableCell>
|
||||
<div class="flex gap-1">
|
||||
@@ -497,7 +502,7 @@
|
||||
</TableRow>
|
||||
{:else}
|
||||
<TableRow>
|
||||
<TableCell colspan={4} class="text-muted-foreground text-center py-6">Нет записей</TableCell>
|
||||
<TableCell colspan={3} class="text-muted-foreground text-center py-6">Нет записей</TableCell>
|
||||
</TableRow>
|
||||
{/each}
|
||||
</TableBody>
|
||||
@@ -717,16 +722,12 @@
|
||||
<DialogContent class="sm:max-w-sm">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{asEdit ? 'Редактировать запись' : 'Новая AS-запись'}</DialogTitle>
|
||||
<DialogDescription>ASN и/или префикс для анонса через BGP.</DialogDescription>
|
||||
<DialogDescription>Номер автономной системы и community для политики анонса.</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div class="space-y-4 py-2">
|
||||
<div class="space-y-1.5">
|
||||
<Label for="as-asn">ASN</Label>
|
||||
<Input id="as-asn" type="number" placeholder="12345" bind:value={asForm.asn} />
|
||||
</div>
|
||||
<div class="space-y-1.5">
|
||||
<Label for="as-prefix">Префикс</Label>
|
||||
<Input id="as-prefix" placeholder="203.0.113.0/24" bind:value={asForm.prefix} />
|
||||
<Input id="as-asn" type="number" placeholder="12345" bind:value={asForm.asn} min={1} max={4294967295} />
|
||||
</div>
|
||||
<div class="space-y-1.5">
|
||||
<Label for="as-comm">Community</Label>
|
||||
@@ -754,7 +755,7 @@
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Удалить запись?</AlertDialogTitle>
|
||||
<AlertDialogDescription>ASN: {asDeleteTarget?.asn ?? '—'}, Префикс: {asDeleteTarget?.prefix ?? '—'}</AlertDialogDescription>
|
||||
<AlertDialogDescription>ASN: {asDeleteTarget?.asn ?? '—'}</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel onclick={() => (asDeleteTarget = null)}>Отмена</AlertDialogCancel>
|
||||
|
||||
Reference in New Issue
Block a user