135 lines
4.3 KiB
Go
135 lines
4.3 KiB
Go
package settings
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"log/slog"
|
|
"os"
|
|
"path/filepath"
|
|
"vctp/internal/utils"
|
|
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
type Settings struct {
|
|
SettingsPath string
|
|
Logger *slog.Logger
|
|
Values *SettingsYML
|
|
}
|
|
|
|
// SettingsYML struct holds various runtime data that is too cumbersome to specify via command line, eg replacement properties
|
|
type SettingsYML struct {
|
|
Settings struct {
|
|
LogLevel string `yaml:"log_level"`
|
|
LogOutput string `yaml:"log_output"`
|
|
DatabaseDriver string `yaml:"database_driver"`
|
|
DatabaseURL string `yaml:"database_url"`
|
|
BindIP string `yaml:"bind_ip"`
|
|
BindPort int `yaml:"bind_port"`
|
|
BindDisableTLS bool `yaml:"bind_disable_tls"`
|
|
TLSCertFilename string `yaml:"tls_cert_filename"`
|
|
TLSKeyFilename string `yaml:"tls_key_filename"`
|
|
VcenterUsername string `yaml:"vcenter_username"`
|
|
VcenterPassword string `yaml:"vcenter_password"`
|
|
VcenterInsecure bool `yaml:"vcenter_insecure"`
|
|
VcenterEventPollingSeconds int `yaml:"vcenter_event_polling_seconds"`
|
|
VcenterInventoryPollingSeconds int `yaml:"vcenter_inventory_polling_seconds"`
|
|
VcenterInventorySnapshotSeconds int `yaml:"vcenter_inventory_snapshot_seconds"`
|
|
VcenterInventoryAggregateSeconds int `yaml:"vcenter_inventory_aggregate_seconds"`
|
|
HourlySnapshotConcurrency int `yaml:"hourly_snapshot_concurrency"`
|
|
HourlySnapshotMaxAgeDays int `yaml:"hourly_snapshot_max_age_days"`
|
|
DailySnapshotMaxAgeMonths int `yaml:"daily_snapshot_max_age_months"`
|
|
SnapshotCleanupCron string `yaml:"snapshot_cleanup_cron"`
|
|
TenantsToFilter []string `yaml:"tenants_to_filter"`
|
|
NodeChargeClusters []string `yaml:"node_charge_clusters"`
|
|
SrmActiveActiveVms []string `yaml:"srm_activeactive_vms"`
|
|
VcenterAddresses []string `yaml:"vcenter_addresses"`
|
|
} `yaml:"settings"`
|
|
}
|
|
|
|
func New(logger *slog.Logger, settingsPath string) *Settings {
|
|
return &Settings{
|
|
SettingsPath: utils.GetFilePath(settingsPath),
|
|
Logger: logger,
|
|
}
|
|
}
|
|
|
|
func (s *Settings) ReadYMLSettings() error {
|
|
// Create config structure
|
|
var settings SettingsYML
|
|
|
|
// Check for empty filename
|
|
if len(s.SettingsPath) == 0 {
|
|
return errors.New("settings file path not specified")
|
|
}
|
|
|
|
//path := utils.GetFilePath(settingsPath)
|
|
|
|
// Open config file
|
|
file, err := os.Open(s.SettingsPath)
|
|
if err != nil {
|
|
return fmt.Errorf("unable to open settings file : '%s'", err)
|
|
}
|
|
s.Logger.Debug("Opened settings yaml file", "file_path", s.SettingsPath)
|
|
defer file.Close()
|
|
|
|
// Init new YAML decode
|
|
d := yaml.NewDecoder(file)
|
|
|
|
// Start YAML decoding from file
|
|
if err := d.Decode(&settings); err != nil {
|
|
return fmt.Errorf("unable to decode settings file : '%s'", err)
|
|
}
|
|
|
|
s.Logger.Debug("Updating settings", "settings", settings)
|
|
s.Values = &settings
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *Settings) WriteYMLSettings() error {
|
|
if s.Values == nil {
|
|
return errors.New("settings are not loaded")
|
|
}
|
|
if len(s.SettingsPath) == 0 {
|
|
return errors.New("settings file path not specified")
|
|
}
|
|
|
|
data, err := yaml.Marshal(s.Values)
|
|
if err != nil {
|
|
return fmt.Errorf("unable to encode settings file: %w", err)
|
|
}
|
|
|
|
mode := os.FileMode(0o644)
|
|
if info, err := os.Stat(s.SettingsPath); err == nil {
|
|
mode = info.Mode().Perm()
|
|
}
|
|
|
|
dir := filepath.Dir(s.SettingsPath)
|
|
tmp, err := os.CreateTemp(dir, "vctp-settings-*.yml")
|
|
if err != nil {
|
|
return fmt.Errorf("unable to create temp settings file: %w", err)
|
|
}
|
|
tmpName := tmp.Name()
|
|
defer func() {
|
|
_ = os.Remove(tmpName)
|
|
}()
|
|
|
|
if _, err := tmp.Write(data); err != nil {
|
|
_ = tmp.Close()
|
|
return fmt.Errorf("unable to write temp settings file: %w", err)
|
|
}
|
|
if err := tmp.Chmod(mode); err != nil {
|
|
_ = tmp.Close()
|
|
return fmt.Errorf("unable to set temp settings permissions: %w", err)
|
|
}
|
|
if err := tmp.Close(); err != nil {
|
|
return fmt.Errorf("unable to close temp settings file: %w", err)
|
|
}
|
|
if err := os.Rename(tmpName, s.SettingsPath); err != nil {
|
|
return fmt.Errorf("unable to replace settings file: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|