mirror of
https://github.com/stakater/Reloader.git
synced 2026-08-20 04:26:28 +00:00
161 lines
3.8 KiB
Go
161 lines
3.8 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"k8s.io/apimachinery/pkg/labels"
|
|
|
|
"github.com/stakater/Reloader/internal/pkg/workload"
|
|
)
|
|
|
|
// ValidationError represents a configuration validation error.
|
|
type ValidationError struct {
|
|
Field string
|
|
Message string
|
|
}
|
|
|
|
func (e ValidationError) Error() string {
|
|
return fmt.Sprintf("config.%s: %s", e.Field, e.Message)
|
|
}
|
|
|
|
// ValidationErrors is a collection of validation errors.
|
|
type ValidationErrors []ValidationError
|
|
|
|
func (e ValidationErrors) Error() string {
|
|
if len(e) == 0 {
|
|
return ""
|
|
}
|
|
if len(e) == 1 {
|
|
return e[0].Error()
|
|
}
|
|
var b strings.Builder
|
|
b.WriteString("multiple configuration errors:\n")
|
|
for _, err := range e {
|
|
b.WriteString(" - ")
|
|
b.WriteString(err.Error())
|
|
b.WriteString("\n")
|
|
}
|
|
return b.String()
|
|
}
|
|
|
|
// Validate checks the configuration for errors and normalizes values.
|
|
func (c *Config) Validate() error {
|
|
var errs ValidationErrors
|
|
|
|
switch c.ReloadStrategy {
|
|
case ReloadStrategyEnvVars, ReloadStrategyAnnotations:
|
|
// valid
|
|
case "":
|
|
c.ReloadStrategy = ReloadStrategyEnvVars
|
|
default:
|
|
errs = append(
|
|
errs, ValidationError{
|
|
Field: "ReloadStrategy",
|
|
Message: fmt.Sprintf("invalid value %q, must be %q or %q", c.ReloadStrategy, ReloadStrategyEnvVars, ReloadStrategyAnnotations),
|
|
},
|
|
)
|
|
}
|
|
|
|
switch c.ArgoRolloutStrategy {
|
|
case ArgoRolloutStrategyRestart, ArgoRolloutStrategyRollout:
|
|
// valid
|
|
case "":
|
|
c.ArgoRolloutStrategy = ArgoRolloutStrategyRollout
|
|
default:
|
|
errs = append(
|
|
errs, ValidationError{
|
|
Field: "ArgoRolloutStrategy",
|
|
Message: fmt.Sprintf(
|
|
"invalid value %q, must be %q or %q", c.ArgoRolloutStrategy, ArgoRolloutStrategyRestart, ArgoRolloutStrategyRollout,
|
|
),
|
|
},
|
|
)
|
|
}
|
|
|
|
switch strings.ToLower(c.LogLevel) {
|
|
case "trace", "debug", "info", "warn", "warning", "error", "fatal", "panic", "":
|
|
// valid
|
|
default:
|
|
errs = append(
|
|
errs, ValidationError{
|
|
Field: "LogLevel",
|
|
Message: fmt.Sprintf("invalid log level %q", c.LogLevel),
|
|
},
|
|
)
|
|
}
|
|
|
|
switch strings.ToLower(c.LogFormat) {
|
|
case "json", "":
|
|
// valid
|
|
default:
|
|
errs = append(
|
|
errs, ValidationError{
|
|
Field: "LogFormat",
|
|
Message: fmt.Sprintf("invalid log format %q, must be \"json\" or empty", c.LogFormat),
|
|
},
|
|
)
|
|
}
|
|
|
|
c.IgnoredResources = normalizeToLower(c.IgnoredResources)
|
|
|
|
// Normalize ignored workloads to canonical Kind values (e.g., "cronjobs" -> "CronJob")
|
|
c.IgnoredWorkloads = normalizeToLower(c.IgnoredWorkloads)
|
|
normalizedWorkloads := make([]string, 0, len(c.IgnoredWorkloads))
|
|
for _, w := range c.IgnoredWorkloads {
|
|
kind, err := workload.KindFromString(w)
|
|
if err != nil {
|
|
errs = append(
|
|
errs, ValidationError{
|
|
Field: "IgnoredWorkloads",
|
|
Message: fmt.Sprintf("unknown workload type %q", w),
|
|
},
|
|
)
|
|
} else {
|
|
normalizedWorkloads = append(normalizedWorkloads, string(kind))
|
|
}
|
|
}
|
|
c.IgnoredWorkloads = normalizedWorkloads
|
|
|
|
if len(errs) > 0 {
|
|
return errs
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// normalizeToLower converts all strings in the slice to lowercase and removes empty strings.
|
|
func normalizeToLower(items []string) []string {
|
|
if len(items) == 0 {
|
|
return items
|
|
}
|
|
result := make([]string, 0, len(items))
|
|
for _, item := range items {
|
|
item = strings.TrimSpace(strings.ToLower(item))
|
|
if item != "" {
|
|
result = append(result, item)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// ParseSelectors parses a slice of selector strings into label selectors.
|
|
func ParseSelectors(selectorStrings []string) ([]labels.Selector, error) {
|
|
if len(selectorStrings) == 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
selectors := make([]labels.Selector, 0, len(selectorStrings))
|
|
for _, s := range selectorStrings {
|
|
s = strings.TrimSpace(s)
|
|
if s == "" {
|
|
continue
|
|
}
|
|
selector, err := labels.Parse(s)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid selector %q: %w", s, err)
|
|
}
|
|
selectors = append(selectors, selector)
|
|
}
|
|
return selectors, nil
|
|
}
|