fix(ci): resolve all lint and test failures

- Go: nil-safe profile cache in SNMPCollector, updated test assertion
- ESLint: fix conditional useQuery hook in SNMPMetricsSection
- ESLint: remove unused CREDENTIAL_TYPE_LABELS, ChevronDown/Right,
  EmptyState import, advancedOpen state
- TypeScript: replace empty interface with type alias

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jason Staack
2026-03-22 17:45:06 -05:00
parent 023e45c908
commit 0c1ffe0e39
6 changed files with 9 additions and 16 deletions

View File

@@ -15,14 +15,14 @@ interface SNMPMetricsSectionProps {
* and are shown by InterfaceGauges. Custom OID charting is Phase 20 (PROF-03). * and are shown by InterfaceGauges. Custom OID charting is Phase 20 (PROF-03).
*/ */
export function SNMPMetricsSection({ tenantId, snmpProfileId }: SNMPMetricsSectionProps) { export function SNMPMetricsSection({ tenantId, snmpProfileId }: SNMPMetricsSectionProps) {
if (!snmpProfileId) return null
const { data: profile } = useQuery({ const { data: profile } = useQuery({
queryKey: ['snmp-profile', tenantId, snmpProfileId], queryKey: ['snmp-profile', tenantId, snmpProfileId],
queryFn: () => snmpProfilesApi.get(tenantId, snmpProfileId!), queryFn: () => snmpProfilesApi.get(tenantId, snmpProfileId!),
enabled: !!snmpProfileId, enabled: !!snmpProfileId && !!tenantId,
}) })
if (!snmpProfileId) return null
return ( return (
<div className="rounded-sm border border-border-default bg-panel px-3 py-2"> <div className="rounded-sm border border-border-default bg-panel px-3 py-2">
<div className="flex items-center gap-2 mb-1"> <div className="flex items-center gap-2 mb-1">

View File

@@ -35,11 +35,6 @@ interface CredentialProfilesPageProps {
type CredentialType = 'routeros' | 'snmp_v2c' | 'snmp_v3' type CredentialType = 'routeros' | 'snmp_v2c' | 'snmp_v3'
type SecurityLevel = 'no_auth_no_priv' | 'auth_no_priv' | 'auth_priv' type SecurityLevel = 'no_auth_no_priv' | 'auth_no_priv' | 'auth_priv'
const CREDENTIAL_TYPE_LABELS: Record<CredentialType, string> = {
routeros: 'RouterOS',
snmp_v2c: 'SNMP v2c',
snmp_v3: 'SNMP v3',
}
const SECURITY_LEVELS: { value: SecurityLevel; label: string }[] = [ const SECURITY_LEVELS: { value: SecurityLevel; label: string }[] = [
{ value: 'no_auth_no_priv', label: 'No Auth, No Privacy' }, { value: 'no_auth_no_priv', label: 'No Auth, No Privacy' },

View File

@@ -10,8 +10,6 @@ import {
X, X,
Network, Network,
Copy, Copy,
ChevronDown,
ChevronRight,
} from 'lucide-react' } from 'lucide-react'
import { import {
snmpProfilesApi, snmpProfilesApi,
@@ -33,7 +31,6 @@ import {
SelectValue, SelectValue,
} from '@/components/ui/select' } from '@/components/ui/select'
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs' import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'
import { EmptyState } from '@/components/ui/empty-state'
import { OIDTreeBrowser } from '@/components/settings/OIDTreeBrowser' import { OIDTreeBrowser } from '@/components/settings/OIDTreeBrowser'
import { ProfileTestPanel } from '@/components/settings/ProfileTestPanel' import { ProfileTestPanel } from '@/components/settings/ProfileTestPanel'
@@ -208,7 +205,6 @@ export function SNMPProfileEditorPage({ tenantId }: SNMPProfileEditorPageProps)
const [pollGroups, setPollGroups] = useState<Record<PollGroupKey, PollGroup>>(buildEmptyPollGroups) const [pollGroups, setPollGroups] = useState<Record<PollGroupKey, PollGroup>>(buildEmptyPollGroups)
const [activePollGroup, setActivePollGroup] = useState<PollGroupKey>('standard') const [activePollGroup, setActivePollGroup] = useState<PollGroupKey>('standard')
const [selectedOids, setSelectedOids] = useState<Set<string>>(new Set()) const [selectedOids, setSelectedOids] = useState<Set<string>>(new Set())
const [advancedOpen, setAdvancedOpen] = useState(false)
// ─── MIB state ───────────────────────────────────────────────────────── // ─── MIB state ─────────────────────────────────────────────────────────

View File

@@ -495,7 +495,7 @@ export interface CredentialProfileCreate {
priv_passphrase?: string priv_passphrase?: string
} }
export interface CredentialProfileUpdate extends Partial<CredentialProfileCreate> {} export type CredentialProfileUpdate = Partial<CredentialProfileCreate>
export const credentialProfilesApi = { export const credentialProfilesApi = {
list: (tenantId: string, credentialType?: string) => list: (tenantId: string, credentialType?: string) =>

View File

@@ -68,12 +68,14 @@ func (c *SNMPCollector) Collect(ctx context.Context, dev store.Device, pub *bus.
profileID := "" profileID := ""
if dev.SNMPProfileID != nil { if dev.SNMPProfileID != nil {
profileID = *dev.SNMPProfileID profileID = *dev.SNMPProfileID
} else { } else if c.profiles != nil {
profileID = c.profiles.GetGenericID() profileID = c.profiles.GetGenericID()
if profileID == "" { if profileID == "" {
return fmt.Errorf("device %s: no SNMP profile assigned and no generic-snmp fallback found", dev.ID) return fmt.Errorf("device %s: no SNMP profile assigned and no generic-snmp fallback found", dev.ID)
} }
slog.Debug("using generic-snmp fallback profile", "device_id", dev.ID) slog.Debug("using generic-snmp fallback profile", "device_id", dev.ID)
} else {
return fmt.Errorf("device %s: no SNMP profile assigned and profile cache not available", dev.ID)
} }
profile := c.profiles.Get(profileID) profile := c.profiles.Get(profileID)
if profile == nil { if profile == nil {

View File

@@ -20,7 +20,7 @@ func TestSNMPCollectorImplementsCollector(t *testing.T) {
} }
// TestSNMPCollectorCollect_NilProfileID verifies that Collect returns an error // TestSNMPCollectorCollect_NilProfileID verifies that Collect returns an error
// when the device has no SNMPProfileID set. // when the device has no SNMPProfileID and the profile cache is nil.
func TestSNMPCollectorCollect_NilProfileID(t *testing.T) { func TestSNMPCollectorCollect_NilProfileID(t *testing.T) {
collector := NewSNMPCollector(nil, nil, nil, DefaultSNMPConfig()) collector := NewSNMPCollector(nil, nil, nil, DefaultSNMPConfig())
dev := store.Device{ dev := store.Device{
@@ -32,7 +32,7 @@ func TestSNMPCollectorCollect_NilProfileID(t *testing.T) {
err := collector.Collect(context.Background(), dev, &bus.Publisher{}) err := collector.Collect(context.Background(), dev, &bus.Publisher{})
require.Error(t, err) require.Error(t, err)
assert.Contains(t, err.Error(), "no SNMP profile") assert.Contains(t, err.Error(), "no SNMP profile assigned")
} }
// TestSNMPCollectorCollect_UnknownProfileID verifies that Collect returns an error // TestSNMPCollectorCollect_UnknownProfileID verifies that Collect returns an error