first version
This commit is contained in:
125
config/config.go
Normal file
125
config/config.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
)
|
||||
|
||||
type (
|
||||
Configuration struct {
|
||||
GlobalContainerConfiguration ContainerConfiguration `json:"containers"`
|
||||
DaemonConfiguration DaemonConfiguration `json:"daemon"`
|
||||
IgnoreRunningUnspecifiedContainers bool `json:"ignore_running_unspecified_containers"`
|
||||
StrictValidation bool `json:"strict_validation"`
|
||||
}
|
||||
|
||||
DaemonConfiguration struct {
|
||||
PullInterval uint `json:"pull_interval"`
|
||||
}
|
||||
|
||||
ContainerConfiguration struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Schedule string `json:"schedule"`
|
||||
}
|
||||
)
|
||||
|
||||
func Load(configPath string) (Configuration, error) {
|
||||
file, err := os.OpenFile(configPath, os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
slog.Warn("no configuration found, loading the default one", "thread", "main", "path", configPath)
|
||||
return Default(), nil
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var c map[string]any
|
||||
d := json.NewDecoder(file)
|
||||
if err := d.Decode(&c); err != nil {
|
||||
return Configuration{}, fmt.Errorf("unable to parse the configuration file: %s", err)
|
||||
}
|
||||
|
||||
return parseConfiguration(c)
|
||||
}
|
||||
|
||||
func Default() Configuration {
|
||||
return Configuration{
|
||||
GlobalContainerConfiguration: ContainerConfiguration{
|
||||
Enabled: false,
|
||||
Schedule: "* * * * *",
|
||||
},
|
||||
DaemonConfiguration: DaemonConfiguration{
|
||||
PullInterval: 2,
|
||||
},
|
||||
IgnoreRunningUnspecifiedContainers: true,
|
||||
StrictValidation: false,
|
||||
}
|
||||
}
|
||||
|
||||
func parseConfiguration(currentConfig map[string]any) (Configuration, error) {
|
||||
c := Default()
|
||||
|
||||
if defaultContainerConfiguration, ok := currentConfig["containers"]; ok {
|
||||
if defaultContainerData, ok := defaultContainerConfiguration.(map[string]any); ok {
|
||||
if schedule, ok := defaultContainerData["schedule"]; ok {
|
||||
if data, ok := schedule.(string); ok {
|
||||
c.GlobalContainerConfiguration.Schedule = data
|
||||
} else {
|
||||
return Configuration{}, fmt.Errorf("configuration parsing: invalid containers.schedule value, expected a string")
|
||||
}
|
||||
}
|
||||
if enabled, ok := defaultContainerData["enabled"]; ok {
|
||||
if data, ok := enabled.(bool); ok {
|
||||
c.GlobalContainerConfiguration.Enabled = data
|
||||
} else {
|
||||
return Configuration{}, fmt.Errorf("configuration parsing: invalid containers.enabled value, expected a bool")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Configuration{}, fmt.Errorf("configuration parsing: invalid containers section, expected an object")
|
||||
}
|
||||
}
|
||||
|
||||
if daemonConfiguration, ok := currentConfig["daemon"]; ok {
|
||||
if daemonData, ok := daemonConfiguration.(map[string]any); ok {
|
||||
if pullInterval, ok := daemonData["pull_interval"]; ok {
|
||||
if data, ok := pullInterval.(uint); ok {
|
||||
c.DaemonConfiguration.PullInterval = data
|
||||
}
|
||||
} else {
|
||||
return Configuration{}, fmt.Errorf("configuration parsing: invalid daemon.pull_interval value, expected an unsigned integer")
|
||||
}
|
||||
} else {
|
||||
return Configuration{}, fmt.Errorf("configuration parsing: invalid daemon section, expected an object")
|
||||
}
|
||||
}
|
||||
|
||||
if ignoreRunningUnspecifiedContainers, ok := currentConfig["ignore_running_unspecified_containers"]; ok {
|
||||
if data, ok := ignoreRunningUnspecifiedContainers.(bool); ok {
|
||||
c.IgnoreRunningUnspecifiedContainers = data
|
||||
} else {
|
||||
return Configuration{}, fmt.Errorf("configuration parsing: invalid ignore_running_unspecified_containers value, expected a bool")
|
||||
}
|
||||
}
|
||||
|
||||
if strictValidation, ok := currentConfig["strict_validation"]; ok {
|
||||
if data, ok := strictValidation.(bool); ok {
|
||||
c.StrictValidation = data
|
||||
} else {
|
||||
return Configuration{}, fmt.Errorf("configuration parsing: invalid strict_validation value, expected a bool")
|
||||
}
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c Configuration) Validate() error {
|
||||
_, err := cron.ParseStandard(c.GlobalContainerConfiguration.Schedule)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to validate: invalid schedule: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user