Track tcp/udp dports via deny_port_hits, expose aggregate and per-IP ports in UI; install-link re-run refreshes nft rules. Co-authored-by: Cursor <cursoragent@cursor.com>
214 lines
5.4 KiB
TypeScript
214 lines
5.4 KiB
TypeScript
import { queryOptions } from '@tanstack/react-query'
|
|
import { apiFetch } from '@/lib/api'
|
|
import type {
|
|
Agent,
|
|
DashboardStats,
|
|
IpList,
|
|
PolicyRule,
|
|
PolicySet,
|
|
} from '@evofw/shared'
|
|
|
|
export const dashboardQueryOptions = () =>
|
|
queryOptions({
|
|
queryKey: ['dashboard'],
|
|
queryFn: () => apiFetch<DashboardStats>('/api/v1/dashboard'),
|
|
})
|
|
|
|
export const agentsQueryOptions = () =>
|
|
queryOptions({
|
|
queryKey: ['agents'],
|
|
queryFn: () => apiFetch<{ items: Agent[] }>('/api/v1/agents'),
|
|
})
|
|
|
|
export const agentQueryOptions = (id: string) =>
|
|
queryOptions({
|
|
queryKey: ['agents', id],
|
|
queryFn: () => apiFetch<Agent>(`/api/v1/agents/${id}`),
|
|
})
|
|
|
|
export const listsQueryOptions = () =>
|
|
queryOptions({
|
|
queryKey: ['lists'],
|
|
queryFn: () => apiFetch<{ items: IpList[] }>('/api/v1/lists'),
|
|
})
|
|
|
|
export const listQueryOptions = (id: string) =>
|
|
queryOptions({
|
|
queryKey: ['lists', id],
|
|
queryFn: () =>
|
|
apiFetch<{
|
|
id: string
|
|
name: string
|
|
type: IpList['type']
|
|
config_json: string
|
|
content_hash?: string | null
|
|
refreshed_at?: string | null
|
|
last_error?: string | null
|
|
entries: string[]
|
|
items: {
|
|
kind: 'ip' | 'cidr' | 'hostname' | 'list'
|
|
value: string
|
|
list_name?: string | null
|
|
resolved_count: number
|
|
resolved_cidrs: string[]
|
|
}[]
|
|
entry_count: number
|
|
created_at: string
|
|
updated_at: string
|
|
}>(`/api/v1/lists/${id}`),
|
|
})
|
|
|
|
export const policySetsQueryOptions = () =>
|
|
queryOptions({
|
|
queryKey: ['policy-sets'],
|
|
queryFn: () => apiFetch<{ items: PolicySet[] }>('/api/v1/policy-sets'),
|
|
})
|
|
|
|
export const policySetQueryOptions = (id: string) =>
|
|
queryOptions({
|
|
queryKey: ['policy-sets', id],
|
|
queryFn: () =>
|
|
apiFetch<PolicySet & { agent_ids: string[] }>(
|
|
`/api/v1/policy-sets/${id}`,
|
|
),
|
|
})
|
|
|
|
export const policySetRulesQueryOptions = (setId: string) =>
|
|
queryOptions({
|
|
queryKey: ['policy-sets', setId, 'rules'],
|
|
queryFn: () =>
|
|
apiFetch<{ items: PolicyRule[] }>(
|
|
`/api/v1/policy-sets/${setId}/rules`,
|
|
),
|
|
})
|
|
|
|
export const agentPolicySetsQueryOptions = (agentId: string) =>
|
|
queryOptions({
|
|
queryKey: ['agents', agentId, 'policy-sets'],
|
|
queryFn: () =>
|
|
apiFetch<{
|
|
items: {
|
|
set_id: string
|
|
sort: number
|
|
name: string
|
|
description?: string | null
|
|
enabled: boolean
|
|
}[]
|
|
}>(`/api/v1/agents/${agentId}/policy-sets`),
|
|
})
|
|
|
|
export const agentPreviewQueryOptions = (agentId: string) =>
|
|
queryOptions({
|
|
queryKey: ['agents', agentId, 'preview'],
|
|
queryFn: () =>
|
|
apiFetch<import('@evofw/shared').AgentPolicyPreview>(
|
|
`/api/v1/agents/${agentId}/preview?limit_cidrs=100`,
|
|
),
|
|
})
|
|
|
|
export const evobgpCommunitiesQueryOptions = () =>
|
|
queryOptions({
|
|
queryKey: ['integrations', 'evobgp', 'communities'],
|
|
queryFn: () =>
|
|
apiFetch<{
|
|
items: import('@evofw/shared').EvobgpCommunity[]
|
|
}>('/api/v1/integrations/evobgp/communities'),
|
|
staleTime: 30_000,
|
|
retry: false,
|
|
})
|
|
|
|
export const agentOverridesQueryOptions = (agentId: string) =>
|
|
queryOptions({
|
|
queryKey: ['agents', agentId, 'overrides'],
|
|
queryFn: () =>
|
|
apiFetch<{
|
|
items: {
|
|
id: string
|
|
agent_id: string
|
|
cidr: string
|
|
action: 'allow' | 'deny'
|
|
comment?: string | null
|
|
created_at: string
|
|
}[]
|
|
}>(`/api/v1/agents/${agentId}/overrides`),
|
|
})
|
|
|
|
export const installContextQueryOptions = () =>
|
|
queryOptions({
|
|
queryKey: ['install-context'],
|
|
queryFn: () =>
|
|
apiFetch<{
|
|
suggested_cp_url: string
|
|
enroll_seed: string
|
|
install_sh_url: string
|
|
mikrotik_url: string
|
|
sync_interval_sec: number
|
|
}>('/api/v1/install-context'),
|
|
})
|
|
|
|
export const settingsQueryOptions = () =>
|
|
queryOptions({
|
|
queryKey: ['settings'],
|
|
queryFn: () => apiFetch<Record<string, string>>('/api/v1/settings'),
|
|
})
|
|
|
|
export const agentStatsQueryOptions = (id: string) =>
|
|
queryOptions({
|
|
queryKey: ['agents', id, 'stats'],
|
|
queryFn: () =>
|
|
apiFetch<{
|
|
items: {
|
|
packets_dropped: number
|
|
packets_accepted: number
|
|
recorded_at: string
|
|
}[]
|
|
}>(`/api/v1/agents/${id}/stats`),
|
|
})
|
|
|
|
export const agentBlockedIpsQueryOptions = (id: string) =>
|
|
queryOptions({
|
|
queryKey: ['agents', id, 'blocked-ips'],
|
|
queryFn: () =>
|
|
apiFetch<{
|
|
items: {
|
|
ip: string
|
|
packets: number
|
|
first_seen_at: string
|
|
last_seen_at: string
|
|
ports?: {
|
|
port: number
|
|
protocol: string
|
|
packets: number
|
|
}[]
|
|
}[]
|
|
}>(`/api/v1/agents/${id}/blocked-ips`),
|
|
})
|
|
|
|
export const agentBlockedPortsQueryOptions = (id: string) =>
|
|
queryOptions({
|
|
queryKey: ['agents', id, 'blocked-ports'],
|
|
queryFn: () =>
|
|
apiFetch<{
|
|
items: {
|
|
port: number
|
|
protocol: string
|
|
packets: number
|
|
last_seen_at: string
|
|
}[]
|
|
}>(`/api/v1/agents/${id}/blocked-ports`),
|
|
})
|
|
|
|
export const recentStatsQueryOptions = () =>
|
|
queryOptions({
|
|
queryKey: ['stats-recent'],
|
|
queryFn: () =>
|
|
apiFetch<{
|
|
items: {
|
|
agent_id: string
|
|
packets_dropped: number
|
|
packets_accepted: number
|
|
recorded_at: string
|
|
}[]
|
|
}>('/api/v1/stats/recent'),
|
|
})
|