8ae28b3474
- 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>
96 lines
2.2 KiB
Go
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
|
|
}
|