diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..83c26dc33 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +deploy +.gitignore +Dockerfile +LICENSE +Tiltfile diff --git a/main.go b/main.go index 05f086ab8..aaf0bcb91 100644 --- a/main.go +++ b/main.go @@ -16,9 +16,9 @@ package main import ( "flag" - "github.com/reactiveops/fairwinds/pkg/validator" "os" + "github.com/reactiveops/fairwinds/pkg/validator" admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" corev1 "k8s.io/api/core/v1" apitypes "k8s.io/apimachinery/pkg/types" diff --git a/pkg/validator/container.go b/pkg/validator/container.go new file mode 100644 index 000000000..537dbbdc9 --- /dev/null +++ b/pkg/validator/container.go @@ -0,0 +1,50 @@ +// Copyright 2018 ReactiveOps +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package validator + +import ( + "strings" + + corev1 "k8s.io/api/core/v1" +) + +type containerResults struct { + Name string + Reason string +} + +func validateContainer(container corev1.Container) containerResults { + var sb strings.Builder + c := containerResults{ + Name: container.Name, + } + + log.Info("validateing Container:", "container resources", container.Resources) + if container.Resources.Requests.Cpu().IsZero() { + sb.WriteString("- CPU requests are not set.\n") + } + if container.Resources.Requests.Memory().IsZero() { + sb.WriteString("- Memory requests are not set.\n") + } + if container.Resources.Limits.Cpu().IsZero() { + sb.WriteString("- CPU limits are not set.\n") + } + if container.Resources.Limits.Memory().IsZero() { + sb.WriteString("- Memory limits are not set.\n") + } + c.Reason = sb.String() + + return c +} diff --git a/pkg/validator/pod.go b/pkg/validator/pod.go index 65a200b61..0569f3a42 100644 --- a/pkg/validator/pod.go +++ b/pkg/validator/pod.go @@ -16,7 +16,9 @@ package validator import ( "context" + "fmt" "net/http" + "strings" corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -46,46 +48,31 @@ func (v *PodValidator) Handle(ctx context.Context, req types.Request) types.Resp return admission.ErrorResponse(http.StatusBadRequest, err) } - allowed, reason, err := v.validatePods(ctx, pod) - if err != nil { - return admission.ErrorResponse(http.StatusInternalServerError, err) - } + allowed, reason := validatePods(ctx, pod) + return admission.ValidationResponse(allowed, reason) } -func (v *PodValidator) validatePods(ctx context.Context, pod *corev1.Pod) (bool, string, error) { +func validatePods(ctx context.Context, pod *corev1.Pod) (bool, string) { + var sb strings.Builder + allowed := true for _, container := range pod.Spec.InitContainers { - if container.Resources.Requests.Cpu().IsZero() { - return false, "CPU resource request not Set", nil - } - if container.Resources.Requests.Memory().IsZero() { - return false, "Memory resource request not Set", nil - } - if container.Resources.Limits.Cpu().IsZero() { - return false, "CPU resource limit not Set", nil - } - if container.Resources.Limits.Memory().IsZero() { - return false, "Memory resource limit not Set", nil + c := validateContainer(container) + if c.Reason != "" { + sb.WriteString(fmt.Sprintf("\nContainer Name: %s\n%s", c.Name, c.Reason)) + allowed = false } } for _, container := range pod.Spec.Containers { - log.Info("validating container", "container", container.Resources, "memoryLimit", container.Resources.Limits.Memory().Value(), "isZero", container.Resources.Limits.Memory().IsZero()) - if container.Resources.Requests.Cpu().IsZero() { - return false, "CPU resource request not Set", nil - } - if container.Resources.Requests.Memory().IsZero() { - return false, "Memory resource request not Set", nil - } - if container.Resources.Limits.Cpu().IsZero() { - return false, "CPU resource limit not Set", nil - } - if container.Resources.Limits.Memory().IsZero() { - return false, "Memory resource limit not Set", nil + c := validateContainer(container) + if c.Reason != "" { + sb.WriteString(fmt.Sprintf("\nName: %s\n%s", c.Name, c.Reason)) + allowed = false } } - return true, "", nil + return allowed, sb.String() } // PodValidator implements inject.Client.