mirror of
https://github.com/yannh/kubeconform.git
synced 2026-02-11 14:09:21 +00:00
126 lines
5.4 KiB
Go
126 lines
5.4 KiB
Go
package config
|
|
|
|
import (
|
|
"bytes"
|
|
"flag"
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
type Config struct {
|
|
Cache string `yaml:"cache" json:"cache"`
|
|
Debug bool `yaml:"debug" json:"debug"`
|
|
ExitOnError bool `yaml:"exitOnError" json:"exitOnError"`
|
|
Files []string `yaml:"files" json:"files"`
|
|
Help bool `yaml:"help" json:"help"`
|
|
IgnoreFilenamePatterns []string `yaml:"ignoreFilenamePatterns" json:"ignoreFilenamePatterns"`
|
|
IgnoreMissingSchemas bool `yaml:"ignoreMissingSchemas" json:"ignoreMissingSchemas"`
|
|
InjectMissingDefaults bool `yaml:"injectMissingDefaults" json:"injectMissingDefaults"` // New field added
|
|
KubernetesVersion k8sVersionValue `yaml:"kubernetesVersion" json:"kubernetesVersion"`
|
|
NumberOfWorkers int `yaml:"numberOfWorkers" json:"numberOfWorkers"`
|
|
OutputFormat string `yaml:"output" json:"output"`
|
|
RejectKinds map[string]struct{} `yaml:"reject" json:"reject"`
|
|
SchemaLocations []string `yaml:"schemaLocations" json:"schemaLocations"`
|
|
SkipKinds map[string]struct{} `yaml:"skip" json:"skip"`
|
|
SkipTLS bool `yaml:"insecureSkipTLSVerify" json:"insecureSkipTLSVerify"`
|
|
Strict bool `yaml:"strict" json:"strict"`
|
|
Summary bool `yaml:"summary" json:"summary"`
|
|
Verbose bool `yaml:"verbose" json:"verbose"`
|
|
Version bool `yaml:"version" json:"version"`
|
|
}
|
|
|
|
type arrayParam []string
|
|
|
|
func (ap *arrayParam) String() string {
|
|
return strings.Join(*ap, " - ")
|
|
}
|
|
|
|
func (ap *arrayParam) Set(value string) error {
|
|
*ap = append(*ap, value)
|
|
return nil
|
|
}
|
|
|
|
type k8sVersionValue string
|
|
|
|
func (kv *k8sVersionValue) String() string {
|
|
return string(*kv)
|
|
}
|
|
|
|
func (kv k8sVersionValue) MarshalText() ([]byte, error) {
|
|
return []byte(kv), nil
|
|
}
|
|
|
|
func (kv *k8sVersionValue) UnmarshalText(v []byte) error {
|
|
if ok, _ := regexp.MatchString(`^(master|\d+\.\d+\.\d+)$`, string(v)); ok != true {
|
|
return fmt.Errorf("%v is not a valid version. Valid values are \"master\" (default) or full version x.y.z (e.g. \"1.27.2\")", string(v))
|
|
}
|
|
*kv = k8sVersionValue(v)
|
|
return nil
|
|
}
|
|
|
|
func splitCSV(csvStr string) map[string]struct{} {
|
|
splitValues := strings.Split(csvStr, ",")
|
|
valuesMap := map[string]struct{}{}
|
|
|
|
for _, kind := range splitValues {
|
|
kind = strings.TrimSpace(kind)
|
|
if len(kind) > 0 {
|
|
valuesMap[kind] = struct{}{}
|
|
}
|
|
}
|
|
|
|
return valuesMap
|
|
}
|
|
|
|
// FromFlags retrieves kubeconform's runtime configuration from the command-line parameters
|
|
func FromFlags(progName string, args []string) (Config, string, error) {
|
|
var schemaLocationsParam, ignoreFilenamePatterns arrayParam
|
|
var skipKindsCSV, rejectKindsCSV string
|
|
flags := flag.NewFlagSet(progName, flag.ContinueOnError)
|
|
var buf bytes.Buffer
|
|
flags.SetOutput(&buf)
|
|
|
|
c := Config{}
|
|
c.Files = []string{}
|
|
|
|
flags.TextVar(&c.KubernetesVersion, "kubernetes-version", k8sVersionValue("master"), "version of Kubernetes to validate against, e.g.: 1.18.0")
|
|
flags.Var(&schemaLocationsParam, "schema-location", "override schemas location search path (can be specified multiple times)")
|
|
flags.StringVar(&skipKindsCSV, "skip", "", "comma-separated list of kinds or GVKs to ignore")
|
|
flags.StringVar(&rejectKindsCSV, "reject", "", "comma-separated list of kinds or GVKs to reject")
|
|
flags.BoolVar(&c.Debug, "debug", false, "print debug information")
|
|
flags.BoolVar(&c.ExitOnError, "exit-on-error", false, "immediately stop execution when the first error is encountered")
|
|
flags.BoolVar(&c.IgnoreMissingSchemas, "ignore-missing-schemas", false, "skip files with missing schemas instead of failing")
|
|
flags.Var(&ignoreFilenamePatterns, "ignore-filename-pattern", "regular expression specifying paths to ignore (can be specified multiple times)")
|
|
flags.BoolVar(&c.Summary, "summary", false, "print a summary at the end (ignored for junit output)")
|
|
flags.IntVar(&c.NumberOfWorkers, "n", 4, "number of goroutines to run concurrently")
|
|
flags.BoolVar(&c.Strict, "strict", false, "disallow additional properties not in schema or duplicated keys")
|
|
flags.StringVar(&c.OutputFormat, "output", "text", "output format - json, junit, pretty, tap, text")
|
|
flags.BoolVar(&c.Verbose, "verbose", false, "print results for all resources (ignored for tap and junit output)")
|
|
flags.BoolVar(&c.SkipTLS, "insecure-skip-tls-verify", false, "disable verification of the server's SSL certificate. This will make your HTTPS connections insecure")
|
|
flags.StringVar(&c.Cache, "cache", "", "cache schemas downloaded via HTTP to this folder")
|
|
flags.BoolVar(&c.Help, "h", false, "show help information")
|
|
flags.BoolVar(&c.Version, "v", false, "show version information")
|
|
|
|
// New flag added for injecting missing defaults
|
|
flags.BoolVar(&c.InjectMissingDefaults, "inject-missing-defaults", false, "Inject missing required fields with defaults from the schema")
|
|
|
|
flags.Usage = func() {
|
|
fmt.Fprintf(&buf, "Usage: %s [OPTION]... [FILE OR FOLDER]...\n", progName)
|
|
flags.PrintDefaults()
|
|
}
|
|
|
|
err := flags.Parse(args)
|
|
|
|
c.SkipKinds = splitCSV(skipKindsCSV)
|
|
c.RejectKinds = splitCSV(rejectKindsCSV)
|
|
c.IgnoreFilenamePatterns = ignoreFilenamePatterns
|
|
c.SchemaLocations = schemaLocationsParam
|
|
c.Files = flags.Args()
|
|
|
|
if c.Help {
|
|
flags.Usage()
|
|
}
|
|
|
|
return c, buf.String(), err
|
|
}
|