feat(19-01): extend API client with SNMP types and methods

- Add device_type, snmp_port, snmp_version, snmp_profile_id, credential_profile_id, board_name to DeviceResponse
- Add device_type filter to DeviceListParams
- Add CredentialProfileResponse, CredentialProfileCreate, CredentialProfileUpdate types
- Add credentialProfilesApi with list/get/create/update/delete/devices methods
- Add SNMPProfileResponse type and snmpProfilesApi with list/get methods
- Add BulkAddWithProfile request/result types and devicesApi.bulkAddWithProfile method
- Add SNMPMetricPoint type and metricsApi.snmp method

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jason Staack
2026-03-21 19:57:02 -05:00
parent cec645a109
commit 6b87b88ce4

View File

@@ -304,6 +304,12 @@ export interface DeviceResponse {
longitude: number | null longitude: number | null
status: string status: string
tls_mode: string tls_mode: string
device_type: string // "routeros" | "snmp"
snmp_port: number | null
snmp_version: string | null
snmp_profile_id: string | null
credential_profile_id: string | null
board_name: string | null
tags: DeviceTagRef[] tags: DeviceTagRef[]
groups: DeviceGroupRef[] groups: DeviceGroupRef[]
site_id: string | null site_id: string | null
@@ -323,10 +329,15 @@ export interface DeviceListResponse {
export interface DeviceCreate { export interface DeviceCreate {
hostname: string hostname: string
ip_address: string ip_address: string
device_type?: 'routeros' | 'snmp'
api_port?: number api_port?: number
api_ssl_port?: number api_ssl_port?: number
username: string username?: string
password: string password?: string
credential_profile_id?: string
snmp_version?: 'v2c' | 'v3'
snmp_port?: number
snmp_profile_id?: string
} }
export interface DeviceUpdate { export interface DeviceUpdate {
@@ -348,6 +359,7 @@ export interface DeviceListParams {
sort_dir?: 'asc' | 'desc' sort_dir?: 'asc' | 'desc'
search?: string search?: string
status?: string status?: string
device_type?: string // "routeros" | "snmp"
model?: string model?: string
tag?: string tag?: string
site_id?: string site_id?: string
@@ -388,6 +400,11 @@ export const devicesApi = {
.post<BulkAddResult>(`/api/tenants/${tenantId}/devices/bulk-add`, data) .post<BulkAddResult>(`/api/tenants/${tenantId}/devices/bulk-add`, data)
.then((r) => r.data), .then((r) => r.data),
bulkAddWithProfile: (tenantId: string, data: BulkAddWithProfileRequest) =>
api
.post<BulkAddWithProfileResult>(`/api/tenants/${tenantId}/devices/bulk`, data)
.then((r) => r.data),
addToGroup: (tenantId: string, deviceId: string, groupId: string) => addToGroup: (tenantId: string, deviceId: string, groupId: string) =>
api api
.post(`/api/tenants/${tenantId}/devices/${deviceId}/groups/${groupId}`) .post(`/api/tenants/${tenantId}/devices/${deviceId}/groups/${groupId}`)
@@ -445,6 +462,152 @@ export interface BulkAddResult {
failed: Array<{ ip_address: string; error: string }> failed: Array<{ ip_address: string; error: string }>
} }
// ─── Credential Profiles ─────────────────────────────────────────────────────
export interface CredentialProfileResponse {
id: string
name: string
description: string | null
credential_type: string // "routeros" | "snmp_v2c" | "snmp_v3"
device_count: number
created_at: string
updated_at: string
}
export interface CredentialProfileListResponse {
profiles: CredentialProfileResponse[]
}
export interface CredentialProfileCreate {
name: string
description?: string
credential_type: string
// RouterOS
username?: string
password?: string
// SNMP v1/v2c
community?: string
// SNMP v3
security_level?: string
auth_protocol?: string
auth_passphrase?: string
privacy_protocol?: string
privacy_passphrase?: string
security_name?: string
}
export interface CredentialProfileUpdate extends Partial<CredentialProfileCreate> {}
export const credentialProfilesApi = {
list: (tenantId: string, credentialType?: string) =>
api
.get<CredentialProfileListResponse>(
`/api/tenants/${tenantId}/credential-profiles`,
{ params: credentialType ? { credential_type: credentialType } : undefined },
)
.then((r) => r.data),
get: (tenantId: string, profileId: string) =>
api
.get<CredentialProfileResponse>(
`/api/tenants/${tenantId}/credential-profiles/${profileId}`,
)
.then((r) => r.data),
create: (tenantId: string, data: CredentialProfileCreate) =>
api
.post<CredentialProfileResponse>(
`/api/tenants/${tenantId}/credential-profiles`,
data,
)
.then((r) => r.data),
update: (tenantId: string, profileId: string, data: CredentialProfileUpdate) =>
api
.put<CredentialProfileResponse>(
`/api/tenants/${tenantId}/credential-profiles/${profileId}`,
data,
)
.then((r) => r.data),
delete: (tenantId: string, profileId: string) =>
api
.delete(`/api/tenants/${tenantId}/credential-profiles/${profileId}`)
.then((r) => r.data),
devices: (tenantId: string, profileId: string) =>
api
.get<DeviceResponse[]>(
`/api/tenants/${tenantId}/credential-profiles/${profileId}/devices`,
)
.then((r) => r.data),
}
// ─── SNMP Profiles ───────────────────────────────────────────────────────────
export interface SNMPProfileResponse {
id: string
name: string
description: string | null
is_system: boolean
profile_data: Record<string, unknown> | null
device_count: number
created_at: string
updated_at: string
}
export const snmpProfilesApi = {
list: (tenantId: string) =>
api
.get<SNMPProfileResponse[]>(`/api/tenants/${tenantId}/snmp-profiles`)
.then((r) => r.data),
get: (tenantId: string, profileId: string) =>
api
.get<SNMPProfileResponse>(
`/api/tenants/${tenantId}/snmp-profiles/${profileId}`,
)
.then((r) => r.data),
}
// ─── Bulk Add (credential profile) ──────────────────────────────────────────
export interface BulkAddWithProfileDevice {
ip_address: string
hostname?: string
}
export interface BulkAddWithProfileDefaults {
api_port?: number
api_ssl_port?: number
tls_mode?: string
snmp_port?: number
snmp_version?: string
snmp_profile_id?: string
}
export interface BulkAddWithProfileRequest {
credential_profile_id: string
device_type: 'routeros' | 'snmp'
defaults?: BulkAddWithProfileDefaults
devices: BulkAddWithProfileDevice[]
}
export interface BulkAddWithProfileDeviceResult {
ip_address: string
hostname: string | null
success: boolean
device_id: string | null
error: string | null
}
export interface BulkAddWithProfileResult {
total: number
succeeded: number
failed: number
results: BulkAddWithProfileDeviceResult[]
}
// ─── Device Groups ──────────────────────────────────────────────────────────── // ─── Device Groups ────────────────────────────────────────────────────────────
export interface DeviceGroupResponse { export interface DeviceGroupResponse {
@@ -948,6 +1111,16 @@ export async function getAccessToken(): Promise<string> {
return response.access_token return response.access_token
} }
export interface SNMPMetricPoint {
bucket: string
metric_name: string
metric_group: string
oid: string
avg_value: number | null
max_value: number | null
min_value: number | null
}
export const metricsApi = { export const metricsApi = {
health: (tenantId: string, deviceId: string, start: string, end: string) => health: (tenantId: string, deviceId: string, start: string, end: string) =>
api api
@@ -1014,6 +1187,14 @@ export const metricsApi = {
`/api/tenants/${tenantId}/devices/${deviceId}/metrics/sparkline`, `/api/tenants/${tenantId}/devices/${deviceId}/metrics/sparkline`,
) )
.then((r) => r.data), .then((r) => r.data),
snmp: (tenantId: string, deviceId: string, metricName: string, start: string, end: string) =>
api
.get<SNMPMetricPoint[]>(
`/api/tenants/${tenantId}/devices/${deviceId}/metrics/snmp`,
{ params: { metric_name: metricName, start, end } },
)
.then((r) => r.data),
} }
// ─── Maintenance Windows ──────────────────────────────────────────────────── // ─── Maintenance Windows ────────────────────────────────────────────────────