From bbf2f4f6e76b4615ec623135ce760ebafafbb55f Mon Sep 17 00:00:00 2001 From: jessicagreben Date: Tue, 18 Dec 2018 12:16:47 -0800 Subject: [PATCH] use config in ctr validation --- deploy/all.yaml | 15 ++++---------- deploy/pod.yaml | 8 ++++++++ main.go | 9 ++++---- pkg/config/config.go | 16 +++++++++------ pkg/validator/container.go | 42 +++++++++++++++++++++++++++----------- 5 files changed, 56 insertions(+), 34 deletions(-) create mode 100644 deploy/pod.yaml diff --git a/deploy/all.yaml b/deploy/all.yaml index d93a722c..406fb796 100644 --- a/deploy/all.yaml +++ b/deploy/all.yaml @@ -5,20 +5,13 @@ metadata: name: fairwinds-config data: config.yml: | - Requests: + resources: cpu: min: 100m - max: 2000m + max: 500m memory: - min: 100M - max: 2000M - Limits: - cpu: - min: 100m - max: 2000m - memory: - min: 100M - max: 2000M + min: 100M + max: 200M --- apiVersion: v1 kind: Namespace diff --git a/deploy/pod.yaml b/deploy/pod.yaml new file mode 100644 index 00000000..a78dd294 --- /dev/null +++ b/deploy/pod.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-2 +spec: + containers: + - name: nginx + image: nginx:latest diff --git a/main.go b/main.go index 40791f3d..5262a605 100644 --- a/main.go +++ b/main.go @@ -50,17 +50,16 @@ func main() { // Parse config. viper.SetConfigName("config") viper.AddConfigPath(".") - var conf conf.Configuration if err := viper.ReadInConfig(); err != nil { entryLog.Error(err, "config err") } - if err := viper.Unmarshal(&conf); err != nil { + var c conf.Configuration + if err := viper.Unmarshal(&c); err != nil { entryLog.Error(err, "unmarshal config err") } - entryLog.Info(fmt.Sprintf("conf requests: %s", conf.Requests)) - entryLog.Info(fmt.Sprintf("conf limits: %s", conf.Limits)) + entryLog.Info(fmt.Sprintf("conf: %#v", c)) // Setup a Manager entryLog.Info("setting up manager") @@ -76,7 +75,7 @@ func main() { Operations(admissionregistrationv1beta1.Create, admissionregistrationv1beta1.Update). WithManager(mgr). ForType(&corev1.Pod{}). - Handlers(&validator.PodValidator{}). + Handlers(&validator.PodValidator{Config: c}). Build() if err != nil { entryLog.Error(err, "unable to setup validating webhook") diff --git a/pkg/config/config.go b/pkg/config/config.go index c8b0e004..6ee052f6 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,12 +1,16 @@ package config -// example) min: 100m -type minmax map[string]string +import ( + corev1 "k8s.io/api/core/v1" +) -// example) cpu.min: 100m -type resources map[string]minmax +type resourceQuanityRange struct { + Min string + Max string +} + +type ResourceListRange map[corev1.ResourceName]resourceQuanityRange type Configuration struct { - Requests resources - Limits resources + Resources ResourceListRange } diff --git a/pkg/validator/container.go b/pkg/validator/container.go index 0ff6fec5..91da5d35 100644 --- a/pkg/validator/container.go +++ b/pkg/validator/container.go @@ -15,9 +15,12 @@ package validator import ( + "fmt" "strings" + conf "github.com/reactiveops/fairwinds/pkg/config" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" ) type containerResults struct { @@ -25,25 +28,38 @@ type containerResults struct { Reason string } -func validateContainer(container corev1.Container) containerResults { +func validateContainer(conf conf.Configuration, container corev1.Container) containerResults { var sb strings.Builder results := containerResults{ Name: container.Name, } - resources(container, sb) - probes(container, sb) - tag(container, sb) + sb.WriteString(resources(conf.Resources, container)) + sb.WriteString(probes(container)) + sb.WriteString(tag(container)) results.Reason = sb.String() return results } -func resources(c corev1.Container, sb strings.Builder) string { - log.Info("validating Container:", "container resources", c.Resources) - if c.Resources.Requests.Cpu().IsZero() { - sb.WriteString("- CPU requests are not set.\n") +func resources(conf conf.ResourceListRange, c corev1.Container) string { + var sb strings.Builder + confCPUmin, err := resource.ParseQuantity(conf["cpu"].Min) + if err != nil { + log.Error(err, "cpu min parse quan") } + // CPUmax, err := resource.ParseQuantity(conf["cpu"].Max) + // if err != nil { + // log.Error(err, "cpu max parse quan") + // } + + ctrRequests := c.Resources.Requests.Cpu().MilliValue() + configMin := confCPUmin.MilliValue() + if ctrRequests < configMin { + s := fmt.Sprintf("- CPU requests are too low. Expected greater than: %d, Actual: %d.\n", configMin, ctrRequests) + sb.WriteString(s) + } + if c.Resources.Requests.Memory().IsZero() { sb.WriteString("- Memory requests are not set.\n") } @@ -53,11 +69,11 @@ func resources(c corev1.Container, sb strings.Builder) string { if c.Resources.Limits.Memory().IsZero() { sb.WriteString("- Memory limits are not set.\n") } - return sb.String() } -func probes(c corev1.Container, sb strings.Builder) string { +func probes(c corev1.Container) string { + var sb strings.Builder if c.ReadinessProbe == nil { sb.WriteString("- Readiness Probe is not set.\n") } @@ -68,7 +84,8 @@ func probes(c corev1.Container, sb strings.Builder) string { return sb.String() } -func tag(c corev1.Container, sb strings.Builder) string { +func tag(c corev1.Container) string { + var sb strings.Builder img := strings.Split(c.Image, ":") if len(img) == 1 || img[1] == "latest" { sb.WriteString("- Image tag is latest.\n") @@ -77,7 +94,8 @@ func tag(c corev1.Container, sb strings.Builder) string { return sb.String() } -func hostPort(c corev1.Container, sb strings.Builder) string { +func hostPort(c corev1.Container) string { + var sb strings.Builder for _, port := range c.Ports { if port.HostPort != 0 { sb.WriteString("- Host Port set.\n")