From 64b42bb818f56ef7462bd837a415340f033886d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Vav=C5=99=C3=ADk?= Date: Mon, 28 Jun 2021 17:40:08 +0200 Subject: [PATCH] Simplified everything. 42 --- README.md | 2 +- build/Dockerfile.cert-generator | 1 + .../scripts/create-signed-cert.sh | 2 +- .../secret-duplicator/templates/_helpers.tpl | 2 +- .../certificate-gen/job-certificate-gen.yaml | 1 + .../templates/deployment.yaml | 4 +- .../templates/mutatingwebhook.yaml | 7 +- charts/secret-duplicator/templates/rbac.yaml | 1 - cmd/webhook.go | 120 +++--------------- 9 files changed, 30 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index 42333d3..9ca87f8 100644 --- a/README.md +++ b/README.md @@ -57,4 +57,4 @@ Of note is also a fact that the chart runs a lookup to the connected cluster to The `get` command should display _some_ non-empty result. ## Releasing locally -To authenticate to the docker registry to push the images manually, you will need your own Github Personal Access Token. For more information follow this guide https://docs.github.com/en/packages/guides/migrating-to-github-container-registry-for-docker-images#authenticating-with-the-container-registry \ No newline at end of file +To authenticate to the docker registry to push the images manually, you will need your own Github Personal Access Token. For more information follow this guide https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-to-the-container-registry \ No newline at end of file diff --git a/build/Dockerfile.cert-generator b/build/Dockerfile.cert-generator index 93cbb7c..b791920 100644 --- a/build/Dockerfile.cert-generator +++ b/build/Dockerfile.cert-generator @@ -1,6 +1,7 @@ FROM alpine:3.13.4 RUN apk add bash curl openssl \ + && apk add --update coreutils jq \ && curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" \ && chmod 755 ./kubectl \ && mv ./kubectl /usr/bin/kubectl diff --git a/charts/secret-duplicator/scripts/create-signed-cert.sh b/charts/secret-duplicator/scripts/create-signed-cert.sh index 2e461d7..3abc26c 100644 --- a/charts/secret-duplicator/scripts/create-signed-cert.sh +++ b/charts/secret-duplicator/scripts/create-signed-cert.sh @@ -46,7 +46,7 @@ while [[ $# -gt 0 ]]; do shift done -[ -z "${service}" ] && service=ips-injector-svc +[ -z "${service}" ] && service=secret-duplicator-svc [ -z "${secret}" ] && secret=descret-duplicator-webhook-certs [ -z "${namespace}" ] && namespace=secret-duplicator diff --git a/charts/secret-duplicator/templates/_helpers.tpl b/charts/secret-duplicator/templates/_helpers.tpl index 41d43f1..3f92564 100644 --- a/charts/secret-duplicator/templates/_helpers.tpl +++ b/charts/secret-duplicator/templates/_helpers.tpl @@ -7,7 +7,7 @@ Expand the name of the chart. {{- end }} {{- define "secret-duplicator.serviceName" -}} -ips-injector-svc +secret-duplicator-svc {{- end }} {{- define "secret-duplicator.certificateSecretName" -}} diff --git a/charts/secret-duplicator/templates/certificate-gen/job-certificate-gen.yaml b/charts/secret-duplicator/templates/certificate-gen/job-certificate-gen.yaml index 624422c..faefadd 100644 --- a/charts/secret-duplicator/templates/certificate-gen/job-certificate-gen.yaml +++ b/charts/secret-duplicator/templates/certificate-gen/job-certificate-gen.yaml @@ -13,6 +13,7 @@ spec: containers: - name: pre-install-job image: "{{ .Values.certificateGeneratorImage.registry }}/{{ .Values.certificateGeneratorImage.repository }}:{{ .Values.certificateGeneratorImage.tag | default .Chart.AppVersion }}" + imagePullPolicy: Always command: ["/entrypoint/entrypoint.sh"] args: - --service diff --git a/charts/secret-duplicator/templates/deployment.yaml b/charts/secret-duplicator/templates/deployment.yaml index 5f35758..1ff44d3 100644 --- a/charts/secret-duplicator/templates/deployment.yaml +++ b/charts/secret-duplicator/templates/deployment.yaml @@ -13,14 +13,14 @@ spec: app: secret-duplicator template: metadata: - labels: + labels: {{- include "secret-duplicator.labels" . | nindent 8 }} app: secret-duplicator spec: serviceAccountName: secret-duplicator containers: - name: secret-duplicator image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: IfNotPresent + imagePullPolicy: Always args: - -alsologtostderr - -v=4 diff --git a/charts/secret-duplicator/templates/mutatingwebhook.yaml b/charts/secret-duplicator/templates/mutatingwebhook.yaml index 327854e..761c80d 100644 --- a/charts/secret-duplicator/templates/mutatingwebhook.yaml +++ b/charts/secret-duplicator/templates/mutatingwebhook.yaml @@ -15,11 +15,14 @@ webhooks: path: "/mutate" caBundle: {{ include "secret-duplicator.lookupCaBundle" . }} rules: - - operations: ["CREATE", "UPDATE"] + - operations: ["CREATE"] apiGroups: [""] apiVersions: ["v1"] - resources: ["serviceaccounts"] + resources: ["namespaces"] admissionReviewVersions: ["v1", "v1beta1"] + namespaceSelector: + matchLabels: + gardener.cloud/role: shoot sideEffects: None # The default "Fail" option prevents Gardener cluster to be hibernated failurePolicy: Ignore diff --git a/charts/secret-duplicator/templates/rbac.yaml b/charts/secret-duplicator/templates/rbac.yaml index c7f3b18..72eb77c 100644 --- a/charts/secret-duplicator/templates/rbac.yaml +++ b/charts/secret-duplicator/templates/rbac.yaml @@ -18,7 +18,6 @@ rules: - "" resources: - secrets - - serviceaccounts verbs: - list - patch diff --git a/cmd/webhook.go b/cmd/webhook.go index 5bb173d..14c5031 100644 --- a/cmd/webhook.go +++ b/cmd/webhook.go @@ -7,6 +7,7 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "net/http" "strings" + "time" "github.com/golang/glog" "k8s.io/api/admission/v1beta1" @@ -47,10 +48,6 @@ var ( metav1.NamespaceSystem, metav1.NamespacePublic, } - - defaultServiceAccounts = []string{ - "default", - } ) // NewWebhookServer constructor for WebhookServer @@ -86,12 +83,6 @@ func DefaultParametersObject() WhSvrParameters { } } -type patchOperation struct { - Op string `json:"op"` - Path string `json:"path"` - Value interface{} `json:"value,omitempty"` -} - func init() { _ = corev1.AddToScheme(runtimeScheme) _ = admissionregistrationv1beta1.AddToScheme(runtimeScheme) @@ -100,66 +91,25 @@ func init() { _ = v1.AddToScheme(runtimeScheme) } -func addImagePullSecret(target, added []corev1.LocalObjectReference, basePath string) (patch []patchOperation) { - first := len(target) == 0 - var value interface{} - for _, add := range added { - value = add - path := basePath - if first { - first = false - value = []corev1.LocalObjectReference{add} - } else { - path = path + "/-" - } - patch = append(patch, patchOperation{ - Op: "add", - Path: path, - Value: value, - }) - } - return patch -} +// createSecret makes sure the target secret exists and contains annotations +func (whsvr *WebhookServer) createSecret(targetNamespace string) { + glog.Infof("Will wait 10sec before create secrets") + time.Sleep(time.Second * 10) + glog.Infof("Will create secrets now") -// ensureSecrets looks up the target secret and makes sure the target secret exists and contains annotations -func (whsvr *WebhookServer) ensureSecrets(ar *v1beta1.AdmissionReview) error { - glog.Infof("Ensuring existing secrets") - targetNamespace := ar.Request.Namespace - - glog.Infof("Looking for the existing target secret") - secret, err := whsvr.client.CoreV1().Secrets(targetNamespace).Get(whsvr.config.targetSecretName, metav1.GetOptions{}) - if err != nil && !errors.IsNotFound(err) { - glog.Errorf("Could not fetch secret %s in namespace %s: %v", whsvr.config.targetSecretName, targetNamespace, err) - return err - } - - if err != nil && errors.IsNotFound(err) { - glog.Infof("Target secret not found, creating a new one") - if _, createErr := whsvr.client.CoreV1().Secrets(targetNamespace).Create(&corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: whsvr.config.targetSecretName, - Namespace: targetNamespace, - }, - Data: nil, - Type: corev1.SecretTypeOpaque, - }); createErr != nil { - glog.Errorf("Could not create secret %s in namespace %s: %v", whsvr.config.targetSecretName, targetNamespace, err) - return err - } - glog.Infof("Target secret created successfully") - return nil - } - - glog.Infof("Target secret found, updating") annotationData := strings.Split(whsvr.config.targetSecretAnnotation, "=") - secret.Annotations[annotationData[0]] = annotationData[1] - if _, err := whsvr.client.CoreV1().Secrets(targetNamespace).Update(secret); err != nil { - glog.Errorf("Could not update secret %s in namespace %s: %v", whsvr.config.targetSecretName, targetNamespace, err) - return err + if _, createErr := whsvr.client.CoreV1().Secrets(targetNamespace).Create(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: whsvr.config.targetSecretName, + Namespace: targetNamespace, + Annotations: map[string]string{annotationData[0]: annotationData[1]}, + }, + Data: nil, + Type: corev1.SecretTypeOpaque, + }); createErr != nil { + glog.Errorf("Could not create secret %s in namespace %s: %v", whsvr.config.targetSecretName, targetNamespace, createErr) } - glog.Infof("Target secret updated successfully") - - return nil + glog.Infof("Target secret created successfully") } // shouldMutate goes through all filters and determines whether the incoming NS matches them @@ -196,42 +146,8 @@ func (whsvr *WebhookServer) mutateNamespace(ar *v1beta1.AdmissionReview) *v1beta Allowed: true, } } - secretList, err := whsvr.client.CoreV1().Secrets(ns.Name).List(metav1.ListOptions{ - Watch: false, - }) - if err != nil { - glog.Errorf("Could not get secret from namespace: %v", err) - return &v1beta1.AdmissionResponse{ - Result: &metav1.Status{ - Message: err.Error(), - }, - } - } - // Check whether we already have configured secret with annotation present - if secretList != nil { - for _, item := range secretList.Items { - if item.Name == whsvr.config.targetSecretName { - annotationToCheck := strings.Split(whsvr.config.targetSecretAnnotation, "=") - if val, ok := item.Annotations[annotationToCheck[0]]; ok { - glog.Infof("Namespace is already in the correct state and contains secret %s with value %s=%s, skipping", whsvr.config.targetSecretName, annotationToCheck, val) - return &v1beta1.AdmissionResponse{ - Allowed: true, - } - } - } - } - } - - if err := whsvr.ensureSecrets(ar); err != nil { - glog.Errorf("Could not ensure existence of the secret") - glog.Errorf("Failing the mutation process") - return &v1beta1.AdmissionResponse{ - Result: &metav1.Status{ - Message: err.Error(), - }, - } - } + go whsvr.createSecret(ar.Request.Name) return &v1beta1.AdmissionResponse{ Allowed: true,