feat(network): implement peer discovery features and UI integration
CI / changes (push) Successful in 6s
CI / commitlint (push) Skipped
CI / openapi (push) Successful in 28s
CI / web (push) Successful in 52s
CI / go (push) Successful in 2m22s
CI / bird2 (push) Successful in 15s
CI / release (push) Successful in 4m36s
CI / changes (push) Successful in 6s
CI / commitlint (push) Skipped
CI / openapi (push) Successful in 28s
CI / web (push) Successful in 52s
CI / go (push) Successful in 2m22s
CI / bird2 (push) Successful in 15s
CI / release (push) Successful in 4m36s
Added functionality for peer discovery, including new API endpoints for listing, approving, and rejecting discovered peers. Updated the network queries and settings to support peer discovery configurations. Enhanced the UI to display discovered peers and integrated related settings in the tenant settings component. Updated OpenAPI documentation to reflect the new endpoints and parameters. This improves the network management capabilities by allowing dynamic peer discovery and management.
This commit is contained in:
@@ -8,6 +8,9 @@ import type {
|
||||
BgpSpeakerCreate,
|
||||
BgpSpeakerPatch,
|
||||
BirdStatus,
|
||||
PeerDiscoveryApprove,
|
||||
PeerDiscoveriesResponse,
|
||||
PeerDiscoveryRow,
|
||||
PeerRow,
|
||||
PeersResponse,
|
||||
SpeakerRow,
|
||||
@@ -19,6 +22,7 @@ export const NETWORK_AUTO_REFRESH_MS = 30_000
|
||||
export const networkKeys = {
|
||||
all: ['network'] as const,
|
||||
peers: () => [...networkKeys.all, 'peers'] as const,
|
||||
discovered: () => [...networkKeys.all, 'discovered'] as const,
|
||||
speakers: () => [...networkKeys.all, 'speakers'] as const,
|
||||
bird: () => [...networkKeys.all, 'bird'] as const,
|
||||
}
|
||||
@@ -31,6 +35,14 @@ export function networkPeersQueryOptions() {
|
||||
})
|
||||
}
|
||||
|
||||
export function networkDiscoveredPeersQueryOptions() {
|
||||
return queryOptions<PeerDiscoveriesResponse>({
|
||||
queryKey: networkKeys.discovered(),
|
||||
queryFn: () => apiJSON<PeerDiscoveriesResponse>('/v1/peers/discovered?status=pending'),
|
||||
staleTime: 10_000,
|
||||
})
|
||||
}
|
||||
|
||||
export function networkSpeakersQueryOptions() {
|
||||
return queryOptions<SpeakersResponse>({
|
||||
queryKey: networkKeys.speakers(),
|
||||
@@ -91,6 +103,39 @@ export function useDeletePeerMutation() {
|
||||
})
|
||||
}
|
||||
|
||||
export function useApproveDiscoveredPeerMutation() {
|
||||
const qc = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: ({ id, body }: { id: string; body?: PeerDiscoveryApprove }) =>
|
||||
apiMutate<{ peer: PeerRow; discovery: PeerDiscoveryRow }>(
|
||||
`/v1/peers/discovered/${id}/approve`,
|
||||
'POST',
|
||||
body ?? {},
|
||||
{ idempotent: false },
|
||||
),
|
||||
onSuccess: () => {
|
||||
toast.success('Пир одобрен')
|
||||
invalidateNetwork(qc)
|
||||
},
|
||||
onError: (e) => toast.error(e instanceof Error ? e.message : 'Не удалось одобрить пира'),
|
||||
})
|
||||
}
|
||||
|
||||
export function useRejectDiscoveredPeerMutation() {
|
||||
const qc = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (id: string) =>
|
||||
apiMutate<PeerDiscoveryRow>(`/v1/peers/discovered/${id}/reject`, 'POST', {}, {
|
||||
idempotent: false,
|
||||
}),
|
||||
onSuccess: () => {
|
||||
toast.success('Пир отклонён')
|
||||
invalidateNetwork(qc)
|
||||
},
|
||||
onError: (e) => toast.error(e instanceof Error ? e.message : 'Не удалось отклонить пира'),
|
||||
})
|
||||
}
|
||||
|
||||
export function useCreateSpeakerMutation() {
|
||||
const qc = useQueryClient()
|
||||
return useMutation({
|
||||
|
||||
@@ -10,6 +10,10 @@ export const BIRD_SETTING_KEYS = [
|
||||
'bird_local_asn',
|
||||
'bird_bgp_source_ipv4',
|
||||
'bird_bgp_source_ipv6',
|
||||
'peer_discovery_enabled',
|
||||
'peer_discovery_ranges_v4',
|
||||
'peer_discovery_ranges_v6',
|
||||
'peer_discovery_require_external',
|
||||
] as const
|
||||
|
||||
export const REVISION_SETTING_KEYS = ['revision_retention_minutes'] as const
|
||||
@@ -38,7 +42,11 @@ export const NUMERIC_SETTING_KEYS = new Set<KnownSettingKey>([
|
||||
'runtime_logs_max_file_mb',
|
||||
])
|
||||
|
||||
export const BOOLEAN_SETTING_KEYS = new Set<KnownSettingKey>(['runtime_logs_auto_enabled'])
|
||||
export const BOOLEAN_SETTING_KEYS = new Set<KnownSettingKey>([
|
||||
'runtime_logs_auto_enabled',
|
||||
'peer_discovery_enabled',
|
||||
'peer_discovery_require_external',
|
||||
])
|
||||
|
||||
export const settingsKeys = {
|
||||
all: ['settings'] as const,
|
||||
@@ -53,6 +61,11 @@ export function settingsQueryOptions() {
|
||||
}
|
||||
|
||||
export function parseKnownValue(key: KnownSettingKey, value: unknown): string {
|
||||
if (BOOLEAN_SETTING_KEYS.has(key)) {
|
||||
if (value === true || value === 1 || value === 'true' || value === '1') return 'true'
|
||||
if (value === false || value === 0 || value === 'false' || value === '0') return 'false'
|
||||
return ''
|
||||
}
|
||||
if (NUMERIC_SETTING_KEYS.has(key)) {
|
||||
if (typeof value === 'number' && Number.isFinite(value)) return String(value)
|
||||
if (typeof value === 'string') return value
|
||||
|
||||
Reference in New Issue
Block a user