Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lx9FNLG2CqeBbVGGd9bFsP
52 lines
1.4 KiB
Go
52 lines
1.4 KiB
Go
package importcsv
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/v10networks/nmon/internal/store"
|
|
)
|
|
|
|
// inventory is the lookup state the validators need, loaded once per Build.
|
|
type inventory struct {
|
|
bySlug map[string]store.Device
|
|
byName map[string]store.Device
|
|
creds map[string]int64 // lower-case credential name to id
|
|
}
|
|
|
|
func loadInventory(ctx context.Context, st store.Store) (*inventory, error) {
|
|
inv := &inventory{bySlug: map[string]store.Device{}, byName: map[string]store.Device{}, creds: map[string]int64{}}
|
|
for off := int64(0); ; off += store.MaxLimit {
|
|
devs, total, err := st.ListDevices(ctx, store.DeviceFilter{IncludeRetired: true}, store.Page{Offset: off, Limit: store.MaxLimit})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("list devices: %w", err)
|
|
}
|
|
for _, d := range devs {
|
|
inv.bySlug[strings.ToLower(d.Slug)] = d
|
|
inv.byName[strings.ToLower(d.Name)] = d
|
|
}
|
|
if off+store.MaxLimit >= total {
|
|
break
|
|
}
|
|
}
|
|
cs, err := st.ListCredentials(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("list credentials: %w", err)
|
|
}
|
|
for _, c := range cs {
|
|
inv.creds[strings.ToLower(c.Name)] = c.ID
|
|
}
|
|
return inv, nil
|
|
}
|
|
|
|
// lookup finds an existing device by slug, then by name.
|
|
func (inv *inventory) lookup(key string) (store.Device, bool) {
|
|
k := strings.ToLower(key)
|
|
if d, ok := inv.bySlug[k]; ok {
|
|
return d, true
|
|
}
|
|
d, ok := inv.byName[k]
|
|
return d, ok
|
|
}
|