Initial commit: IT Nexus Web-App
This commit is contained in:
195
nexus-scanner/internal/config/config.go
Normal file
195
nexus-scanner/internal/config/config.go
Normal file
@@ -0,0 +1,195 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Config holds the full agent configuration loaded from config.yaml.
|
||||
type Config struct {
|
||||
Site string `yaml:"site"` // LUD or BAR
|
||||
LogLevel string `yaml:"log_level"` // debug | info | warn | error
|
||||
SetupComplete bool `yaml:"setup_complete"` // false → show setup wizard on first run
|
||||
|
||||
DB struct {
|
||||
Path string `yaml:"path"`
|
||||
} `yaml:"db"`
|
||||
|
||||
Web struct {
|
||||
Addr string `yaml:"addr"`
|
||||
Token string `yaml:"token"`
|
||||
} `yaml:"web"`
|
||||
|
||||
Nexus struct {
|
||||
URL string `yaml:"url"`
|
||||
APIKey string `yaml:"api_key"`
|
||||
} `yaml:"nexus"`
|
||||
|
||||
OfflineAfter time.Duration `yaml:"offline_after"` // mark hosts offline after this duration
|
||||
|
||||
Alert AlertConfig `yaml:"alert"`
|
||||
|
||||
Modules struct {
|
||||
ARPDiscovery ARPConfig `yaml:"arp_discovery"`
|
||||
ADSync ADConfig `yaml:"ad_sync"`
|
||||
SiteMonitoring SiteMonConfig `yaml:"site_monitoring"`
|
||||
PortScan PortScanConfig `yaml:"port_scan"`
|
||||
SNMP SNMPConfig `yaml:"snmp"`
|
||||
NexusReporter ReporterConfig `yaml:"nexus_reporter"`
|
||||
} `yaml:"modules"`
|
||||
}
|
||||
|
||||
// ADConfig holds settings for the ad_sync module.
|
||||
type ADConfig struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Interval time.Duration `yaml:"interval"`
|
||||
Server string `yaml:"server"` // DC hostname or IP
|
||||
Port int `yaml:"port"` // default 389
|
||||
BindDN string `yaml:"bind_dn"` // svc-scanner@winkel.local
|
||||
BindPassword string `yaml:"bind_password"`
|
||||
SearchBase string `yaml:"search_base"` // DC=winkel,DC=local
|
||||
TLS bool `yaml:"tls"` // use LDAPS
|
||||
}
|
||||
|
||||
// SiteMonConfig holds settings for the site_monitoring module.
|
||||
type SiteMonConfig struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Interval time.Duration `yaml:"interval"`
|
||||
}
|
||||
|
||||
// PortScanConfig holds settings for the port_scan module.
|
||||
type PortScanConfig struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Interval time.Duration `yaml:"interval"`
|
||||
Ports []int `yaml:"ports"` // empty = use defaults
|
||||
Timeout time.Duration `yaml:"timeout"` // per-port connect timeout
|
||||
}
|
||||
|
||||
// SNMPConfig holds settings for the snmp module.
|
||||
type SNMPConfig struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Interval time.Duration `yaml:"interval"`
|
||||
Community string `yaml:"community"` // default community string
|
||||
}
|
||||
|
||||
// ReporterConfig holds settings for the nexus_reporter module.
|
||||
type ReporterConfig struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Interval time.Duration `yaml:"interval"`
|
||||
}
|
||||
|
||||
// AlertConfig holds notification settings.
|
||||
type AlertConfig struct {
|
||||
SMTP struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Host string `yaml:"host"`
|
||||
Port int `yaml:"port"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
From string `yaml:"from"`
|
||||
To string `yaml:"to"`
|
||||
} `yaml:"smtp"`
|
||||
NexusEnabled bool `yaml:"nexus_enabled"`
|
||||
}
|
||||
|
||||
// ARPConfig holds settings for the arp_discovery module.
|
||||
type ARPConfig struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Interval time.Duration `yaml:"interval"`
|
||||
Subnets []string `yaml:"subnets"`
|
||||
Interface string `yaml:"interface"`
|
||||
}
|
||||
|
||||
// Load reads and validates the YAML config at path.
|
||||
func Load(path string) (*Config, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open config %q: %w", path, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var cfg Config
|
||||
if err := yaml.NewDecoder(f).Decode(&cfg); err != nil {
|
||||
return nil, fmt.Errorf("decode config: %w", err)
|
||||
}
|
||||
|
||||
if err := cfg.applyDefaults(); err != nil {
|
||||
return nil, fmt.Errorf("config validation: %w", err)
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
// Save writes the config back to path in YAML format.
|
||||
func Save(path string, cfg *Config) error {
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create config %q: %w", path, err)
|
||||
}
|
||||
defer f.Close()
|
||||
if err := yaml.NewEncoder(f).Encode(cfg); err != nil {
|
||||
return fmt.Errorf("encode config: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) applyDefaults() error {
|
||||
if c.Site == "" {
|
||||
return fmt.Errorf("site is required (LUD or BAR)")
|
||||
}
|
||||
if c.Site != "LUD" && c.Site != "BAR" {
|
||||
return fmt.Errorf("site must be LUD or BAR, got %q", c.Site)
|
||||
}
|
||||
if c.LogLevel == "" {
|
||||
c.LogLevel = "info"
|
||||
}
|
||||
if c.DB.Path == "" {
|
||||
c.DB.Path = "/var/lib/nexus-scanner/scanner.db"
|
||||
}
|
||||
if c.Web.Addr == "" {
|
||||
c.Web.Addr = ":8080"
|
||||
}
|
||||
if c.Modules.ARPDiscovery.Interval == 0 {
|
||||
c.Modules.ARPDiscovery.Interval = 5 * time.Minute
|
||||
}
|
||||
if c.Modules.ARPDiscovery.Interface == "" {
|
||||
c.Modules.ARPDiscovery.Interface = "eth0"
|
||||
}
|
||||
if c.Modules.ADSync.Port == 0 {
|
||||
c.Modules.ADSync.Port = 389
|
||||
}
|
||||
if c.Modules.ADSync.Interval == 0 {
|
||||
c.Modules.ADSync.Interval = 30 * time.Minute
|
||||
}
|
||||
if c.Modules.ADSync.SearchBase == "" && c.Modules.ADSync.Server != "" {
|
||||
c.Modules.ADSync.SearchBase = "DC=winkel,DC=local"
|
||||
}
|
||||
if c.Modules.SiteMonitoring.Interval == 0 {
|
||||
c.Modules.SiteMonitoring.Interval = time.Minute
|
||||
}
|
||||
if c.Modules.PortScan.Interval == 0 {
|
||||
c.Modules.PortScan.Interval = 15 * time.Minute
|
||||
}
|
||||
if c.Modules.PortScan.Timeout == 0 {
|
||||
c.Modules.PortScan.Timeout = 500 * time.Millisecond
|
||||
}
|
||||
if c.Modules.SNMP.Interval == 0 {
|
||||
c.Modules.SNMP.Interval = 5 * time.Minute
|
||||
}
|
||||
if c.Modules.SNMP.Community == "" {
|
||||
c.Modules.SNMP.Community = "public"
|
||||
}
|
||||
if c.Modules.NexusReporter.Interval == 0 {
|
||||
c.Modules.NexusReporter.Interval = 10 * time.Minute
|
||||
}
|
||||
if c.OfflineAfter == 0 {
|
||||
c.OfflineAfter = 15 * time.Minute
|
||||
}
|
||||
if c.Alert.SMTP.Port == 0 {
|
||||
c.Alert.SMTP.Port = 587
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user