ff9c61c087
Release / release (push) Successful in 1m36s
- Auto-detects missing config (netbox.url empty) and launches wizard - `netssh configure` re-runs the wizard anytime to change settings - 3-page huh form: NetBox connection, SSH defaults, resolver & cache - Saves to ~/.config/netssh.yaml (permissions 0600) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"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"`
|
|
}
|
|
|
|
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.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
|
|
}
|