Files
Sebastian Unterschütz 8ae28b3474 feat: persist token_version in config, auto-detect on load
- NetBoxConfig.TokenVersion saved to netssh.yaml by the wizard
- config.Load() auto-detects the version from the token prefix if the
  field is missing (backwards-compatible with existing configs)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 13:12:35 +02:00

96 lines
2.2 KiB
Go

package config
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/spf13/viper"
)
type Config struct {
NetBox NetBoxConfig `mapstructure:"netbox"`
Resolver ResolverConfig `mapstructure:"resolver"`
Cache CacheConfig `mapstructure:"cache"`
SSH SSHConfig `mapstructure:"ssh"`
}
type NetBoxConfig struct {
URL string `mapstructure:"url"`
Token string `mapstructure:"token"`
TokenVersion int `mapstructure:"token_version"`
}
type ResolverConfig struct {
Strategies []string `mapstructure:"strategies"`
ManagementSubnets []string `mapstructure:"management_subnets"`
InterfaceName string `mapstructure:"interface_name"`
}
type CacheConfig struct {
TTL int `mapstructure:"ttl"`
Path string `mapstructure:"path"`
}
type SSHConfig struct {
DefaultUser string `mapstructure:"default_user"`
}
// Path returns the canonical config file path.
func Path() string {
configDir, err := os.UserConfigDir()
if err != nil {
configDir = filepath.Join(os.Getenv("HOME"), ".config")
}
return filepath.Join(configDir, "netssh.yaml")
}
func Load() (*Config, error) {
v := viper.New()
v.SetDefault("resolver.strategies", []string{"management_subnet", "primary_ip"})
v.SetDefault("resolver.management_subnets", []string{})
v.SetDefault("cache.ttl", 3600)
configDir, err := os.UserConfigDir()
if err == nil {
v.SetConfigName("netssh")
v.SetConfigType("yaml")
v.AddConfigPath(filepath.Join(configDir))
v.AddConfigPath(".")
}
v.SetEnvPrefix("NETSSH")
v.AutomaticEnv()
if err := v.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
return nil, fmt.Errorf("reading config: %w", err)
}
}
var cfg Config
if err := v.Unmarshal(&cfg); err != nil {
return nil, fmt.Errorf("parsing config: %w", err)
}
if cfg.NetBox.TokenVersion == 0 && cfg.NetBox.Token != "" {
if strings.HasPrefix(cfg.NetBox.Token, "nbt_") {
cfg.NetBox.TokenVersion = 2
} else {
cfg.NetBox.TokenVersion = 1
}
}
if cfg.Cache.Path == "" {
cacheDir, err := os.UserCacheDir()
if err != nil {
cacheDir = filepath.Join(os.Getenv("HOME"), ".cache")
}
cfg.Cache.Path = filepath.Join(cacheDir, "netssh", "hosts.json")
}
return &cfg, nil
}