From 321c1d1d0d8eca3fa43c089c7dcda3b711e1e547 Mon Sep 17 00:00:00 2001 From: Alan Hughes Date: Fri, 17 Apr 2020 16:44:21 +0100 Subject: [PATCH] Add default labels and ignored namespaces, improved build chain --- .gitignore | 2 +- Dockerfile | 17 +++--- main.go | 15 +++--- pkg/admission/podnodesselector/handler.go | 63 ++++++++++++++++------- ssl.sh | 11 ++-- 5 files changed, 67 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index 93a49f7..5099454 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,5 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out -chart/ssl +helm/ssl admitCtlr diff --git a/Dockerfile b/Dockerfile index a529596..92b27d5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,12 @@ -FROM alpine:3.10 +FROM golang:alpine AS builder +LABEL stage=builder +RUN apk add --no-cache gcc libc-dev git ca-certificates +WORKDIR /workspace +COPY main.go go.sum go.mod ./ +COPY pkg ./pkg/ +RUN CGO_ENABLED=0 GOOS=linux go build -a -o admitCtlr -RUN apk update --no-cache && apk add ca-certificates - -COPY admitCtlr /admitCtlr - -ENTRYPOINT ["/admitCtlr"] +FROM alpine AS final +WORKDIR / +COPY --from=builder /workspace/admitCtlr . +CMD [ "/admitCtlr" ] diff --git a/main.go b/main.go index e3fc7a8..d6ee1aa 100644 --- a/main.go +++ b/main.go @@ -9,20 +9,21 @@ import ( "github.com/liangrog/admission-webhook-server/pkg/utils" ) -// TLS secrets -const ( - tlsDir = `/run/secrets/tls` - tlsCert = `tls.crt` - tlsKey = `tls.key` -) - // Port to listen to const ( ENV_LISTEN_PORT = "LISTEN_PORT" listenPort = ":8443" ) +// TLS secrets +const ( + ENV_TLS_DIR = "TLS_DIR" + tlsCert = `tls.crt` + tlsKey = `tls.key` +) + func main() { + tlsDir := utils.GetEnvVal(ENV_TLS_DIR, "/run/secrets/tls") cert := filepath.Join(tlsDir, tlsCert) key := filepath.Join(tlsDir, tlsKey) diff --git a/pkg/admission/podnodesselector/handler.go b/pkg/admission/podnodesselector/handler.go index 8ed1a6c..ee07af2 100644 --- a/pkg/admission/podnodesselector/handler.go +++ b/pkg/admission/podnodesselector/handler.go @@ -36,6 +36,9 @@ const ( namespaceSeperator = ";" namespaceLabelSeperator = ":" + + ENV_IGNORED_NAMESPACES = "IGNORED_NAMESPACES" + ENV_DEFAULT_LABELS = "DEFAULT_LABELS" ) var ( @@ -83,31 +86,42 @@ func handler(req *v1beta1.AdmissionRequest) ([]admit.PatchOperation, error) { log.Fatal(err) } - if selectors != nil { - if labelSet, ok := selectors[req.Namespace]; ok { - op := "replace" - if pod.Spec.NodeSelector == nil { - op = "add" + if ignoreNamespace(req.Namespace, strings.Split(utils.GetEnvVal(ENV_IGNORED_NAMESPACES, ""), ",")) { + log.Printf("Namespace %s is configured to be ignored, so applying no labels\n", req.Namespace) + } else { + labelSet := labels.Set{} + labelsDefinedForNamespace := false + if labelSet, labelsDefinedForNamespace = selectors[req.Namespace]; labelsDefinedForNamespace { + log.Printf("Applying isolation labels to %s", req.Namespace) + } else { + log.Printf("Applying default labels to %s\n", req.Namespace) + labelSet, err = labels.ConvertSelectorToLabelsMap(utils.GetEnvVal(ENV_DEFAULT_LABELS, "")) + if err != nil { + log.Fatal(err) } + } + op := "replace" + if pod.Spec.NodeSelector == nil { + op = "add" + } - if labels.Conflicts(labelSet, labels.Set(pod.Spec.NodeSelector)) { - return patches, errors.New(fmt.Sprintf("pod node label selector conflicts with its namespace node label selector for pod %s", podName)) - } + if labels.Conflicts(labelSet, labels.Set(pod.Spec.NodeSelector)) { + return patches, errors.New(fmt.Sprintf("pod node label selector conflicts with its namespace node label selector for pod %s", podName)) + } - podNodeSelectorLabels := labels.Merge(labelSet, labels.Set(pod.Spec.NodeSelector)) + podNodeSelectorLabels := labels.Merge(labelSet, labels.Set(pod.Spec.NodeSelector)) - patches = append(patches, admit.PatchOperation{ - Op: op, - Path: "/spec/nodeSelector", - Value: podNodeSelectorLabels, - }) + patches = append(patches, admit.PatchOperation{ + Op: op, + Path: "/spec/nodeSelector", + Value: podNodeSelectorLabels, + }) - log.Printf("%s processed pod %s with selectors: %s", - handlerName, - podName, - fmt.Sprintf("%v", podNodeSelectorLabels), - ) - } + log.Printf("%s processed pod %s with selectors: %s", + handlerName, + podName, + fmt.Sprintf("%v", podNodeSelectorLabels), + ) } return patches, nil @@ -139,3 +153,12 @@ func getConfiguredSelectorMap() (map[string]labels.Set, error) { return selectors, nil } + +func ignoreNamespace(lookup string, ignored []string) bool { + for _, val := range ignored { + if val == lookup { + return true + } + } + return false +} diff --git a/ssl.sh b/ssl.sh index 07f6998..7b2392d 100644 --- a/ssl.sh +++ b/ssl.sh @@ -4,16 +4,13 @@ cn="$1" secret_dir="helm/ssl" expiration="3650" -mkdir -p helm/ssl - -chmod 0700 "$secret_dir" -cd "$secret_dir" - -rm -rf * +mkdir -p ${secret_dir} +chmod 0700 "${secret_dir}" +cd "${secret_dir}" # Generate the CA cert and private key openssl req -nodes -new -x509 -days $expiration -keyout ca.key -out ca.crt -subj "/CN=Admission Controller Webhook Server CA" - +rm server.pem cat ca.key > server.pem cat ca.crt >> server.pem