diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0f04682 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file +# Ignore build and test binaries. +bin/ +testbin/ diff --git a/Dockerfile b/Dockerfile index 3b8b5b7..a905fe8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,11 +17,9 @@ RUN apk update && \ # Build Go binary RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-w -s" -o kyverno-notation-aws . -FROM scratch +FROM gcr.io/distroless/static:nonroot WORKDIR / -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ - # Notation home ENV PLUGINS_DIR=/plugins diff --git a/configs/install.yaml b/configs/install.yaml index 7857008..6e8144c 100644 --- a/configs/install.yaml +++ b/configs/install.yaml @@ -193,7 +193,7 @@ spec: securityContext: runAsNonRoot: true containers: - - image: ghcr.io/nirmata/kyverno-notation-aws:v1-rc2 + - image: ghcr.io/vishal-chdhry/kyverno-notation-aws:kn-rc4 imagePullPolicy: Always name: kyverno-notation-aws # args: @@ -234,30 +234,6 @@ spec: mountPath: /notation - name: certs mountPath: /certs - - image: ghcr.io/nirmata/kube-notation:v1-alpha1 - imagePullPolicy: Always - name: kube-notation - env: - - name: NOTATION_DIR - value: /notation - securityContext: - runAsUser: 2000 - runAsGroup: 3000 - allowPrivilegeEscalation: false - seccompProfile: - type: RuntimeDefault - capabilities: - drop: - - ALL - resources: - limits: - memory: 512Mi - requests: - memory: 32Mi - cpu: 100m - volumeMounts: - - name: notation - mountPath: /notation volumes: - name: notation emptyDir: {} diff --git a/configs/newdeploy.yaml b/configs/newdeploy.yaml new file mode 100644 index 0000000..87856a9 --- /dev/null +++ b/configs/newdeploy.yaml @@ -0,0 +1,77 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: kyverno-notation-aws + name: kyverno-notation-aws + namespace: kyverno-notation-aws +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: kyverno-notation-aws + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + app: kyverno-notation-aws + spec: + securityContext: + runAsNonRoot: true + containers: + - image: ghcr.io/vishal-chdhry/kyverno-notation-aws:kn-rc4 + imagePullPolicy: Always + name: kyverno-notation-aws + # args: + # - --debug + # USE IF IRSA IS NOT CONFIGURED + # - --imagePullSecrets=regcred + resources: + limits: + memory: 512Mi + requests: + memory: 32Mi + cpu: 100m + securityContext: + runAsUser: 2000 + runAsGroup: 3000 + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + env: + - name: NOTATION_DIR + value: /notation + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # USE IF IRSA IS NOT CONFIGURED + # - name: AWS_ACCESS_KEY_ID + # value: ${AWS_ACCESS_KEY_ID} + # - name: AWS_SECRET_ACCESS_KEY + # value: ${AWS_SECRET_ACCESS_KEY} + - name: AWS_REGION + value: us-west-2 + volumeMounts: + - name: notation + mountPath: /notation + - name: certs + mountPath: /certs + volumes: + - name: notation + emptyDir: {} + - name: certs + secret: + defaultMode: 420 + secretName: kyverno-notation-aws-tls + serviceAccountName: kyverno-notation-aws \ No newline at end of file diff --git a/configs/olddeploy.yaml b/configs/olddeploy.yaml new file mode 100644 index 0000000..c30126e --- /dev/null +++ b/configs/olddeploy.yaml @@ -0,0 +1,100 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: kyverno-notation-aws + name: kyverno-notation-aws + namespace: kyverno-notation-aws +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: kyverno-notation-aws + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + app: kyverno-notation-aws + spec: + securityContext: + runAsNonRoot: true + containers: + - image: ghcr.io/vishal-chdhry/kyverno-notation-aws:v1-rc3 + imagePullPolicy: Always + name: kyverno-notation-aws + # args: + # - --debug + # USE IF IRSA IS NOT CONFIGURED + # - --imagePullSecrets=regcred + resources: + limits: + memory: 512Mi + requests: + memory: 32Mi + cpu: 100m + securityContext: + runAsUser: 2000 + runAsGroup: 3000 + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + env: + - name: NOTATION_DIR + value: /notation + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # USE IF IRSA IS NOT CONFIGURED + # - name: AWS_ACCESS_KEY_ID + # value: ${AWS_ACCESS_KEY_ID} + # - name: AWS_SECRET_ACCESS_KEY + # value: ${AWS_SECRET_ACCESS_KEY} + - name: AWS_REGION + value: us-west-2 + volumeMounts: + - name: notation + mountPath: /notation + - name: certs + mountPath: /certs + - image: ghcr.io/nirmata/kube-notation:v1-alpha1 + imagePullPolicy: Always + name: kube-notation + env: + - name: NOTATION_DIR + value: /notation + securityContext: + runAsUser: 2000 + runAsGroup: 3000 + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + resources: + limits: + memory: 512Mi + requests: + memory: 32Mi + cpu: 100m + volumeMounts: + - name: notation + mountPath: /notation + volumes: + - name: notation + emptyDir: {} + - name: certs + secret: + defaultMode: 420 + secretName: kyverno-notation-aws-tls + serviceAccountName: kyverno-notation-aws \ No newline at end of file diff --git a/go.mod b/go.mod index 645af3c..b64280e 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,15 @@ go 1.19 require ( github.com/aws/aws-sdk-go-v2/config v1.18.21 github.com/aws/aws-sdk-go-v2/service/ecr v1.18.7 + github.com/go-logr/zapr v1.2.4 github.com/google/go-containerregistry v0.14.0 - github.com/nirmata/kyverno-notation-verifier v0.3.3 + github.com/nirmata/kyverno-notation-verifier v0.4.4 github.com/notaryproject/notation-core-go v1.0.0-rc.4 github.com/pkg/errors v0.9.1 go.uber.org/zap v1.24.0 gotest.tools v2.2.0+incompatible oras.land/oras-go/v2 v2.2.0 + sigs.k8s.io/controller-runtime v0.15.0-alpha.1 ) require ( @@ -47,7 +49,6 @@ require ( github.com/go-errors/errors v1.4.2 // indirect github.com/go-ldap/ldap/v3 v3.4.4 // indirect github.com/go-logr/logr v1.2.4 // indirect - github.com/go-logr/zapr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect @@ -119,7 +120,6 @@ require ( k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c // indirect k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect - sigs.k8s.io/controller-runtime v0.15.0-alpha.1 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.13.2 // indirect sigs.k8s.io/kustomize/kyaml v0.14.1 // indirect diff --git a/go.sum b/go.sum index db0db10..3ab42de 100644 --- a/go.sum +++ b/go.sum @@ -97,6 +97,7 @@ github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxI github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-ldap/ldap/v3 v3.4.4 h1:qPjipEpt+qDa6SI/h1fzuGWoRUY+qqQ9sOZq67/PYUs= github.com/go-ldap/ldap/v3 v3.4.4/go.mod h1:fe1MsuN5eJJ1FeLT/LEBVdWfNWKh459R7aXgXtJC+aI= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -175,8 +176,10 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -206,12 +209,11 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/nirmata/kyverno-notation-verifier v0.3.1 h1:iiR8raD5wgVO+B2VZfiJ+YrzsMg4kZgpMhd/1kMaDh4= -github.com/nirmata/kyverno-notation-verifier v0.3.1/go.mod h1:NuW0wH4IKDVgjaZ+cn/EIPy6TjmdPlG7tzKY1+pQBvY= -github.com/nirmata/kyverno-notation-verifier v0.3.2 h1:Cl8P50Ygqm5kO3dmthDmRmaeaqwsNPseafTrqB9KcWk= -github.com/nirmata/kyverno-notation-verifier v0.3.2/go.mod h1:NuW0wH4IKDVgjaZ+cn/EIPy6TjmdPlG7tzKY1+pQBvY= -github.com/nirmata/kyverno-notation-verifier v0.3.3 h1:hMKaKEOrC/yMd5j/0TBstFGD1Y+picEeF6wQGncRCr0= -github.com/nirmata/kyverno-notation-verifier v0.3.3/go.mod h1:NuW0wH4IKDVgjaZ+cn/EIPy6TjmdPlG7tzKY1+pQBvY= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nirmata/kyverno-notation-verifier v0.4.2 h1:JlzQy+mhzpk8F6vqBXCJpZKrG3HmhusQTehjj9nLyu0= +github.com/nirmata/kyverno-notation-verifier v0.4.2/go.mod h1:mZXcz1doavjZbr25M/RZ4quugSeOSNfqmYsGTdXY/hQ= +github.com/nirmata/kyverno-notation-verifier v0.4.4 h1:ecTxIDtj9JufdTgzL/S3MNe7mASrrhNSaMe95CI+a7c= +github.com/nirmata/kyverno-notation-verifier v0.4.4/go.mod h1:mZXcz1doavjZbr25M/RZ4quugSeOSNfqmYsGTdXY/hQ= github.com/notaryproject/notation-core-go v1.0.0-rc.4 h1:gzo4JzKRMLGoOeOhPXxoudjL79Mi9X6flS8qJbRtZ+k= github.com/notaryproject/notation-core-go v1.0.0-rc.4/go.mod h1:PEHrnhW0mEIVpyYdXqAJoJAaUgfz757tqxB3LG4qcag= github.com/notaryproject/notation-go v1.0.0-rc.6 h1:Wu9PiCzf2v75iBsKanJTgd91jgvpTzMX5kvnKjximi4= diff --git a/main.go b/main.go index 0dbf68d..961dc04 100644 --- a/main.go +++ b/main.go @@ -6,11 +6,14 @@ import ( "net/http" "os" + "github.com/go-logr/zapr" + "github.com/nirmata/kyverno-notation-verifier/kubenotation" knvSetup "github.com/nirmata/kyverno-notation-verifier/setup" knvVerifier "github.com/nirmata/kyverno-notation-verifier/verifier" _ "github.com/notaryproject/notation-core-go/signature/cose" _ "github.com/notaryproject/notation-core-go/signature/jws" "go.uber.org/zap" + ctrl "sigs.k8s.io/controller-runtime" ) func main() { @@ -35,6 +38,17 @@ func main() { var flagMaxSignatureAtempts int flag.IntVar(&flagMaxSignatureAtempts, "maxSignatureAttempts", 30, "Maximum number of signature envelopes that will be processed for verification") + var metricsAddr string + flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") + + var probeAddr string + flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") + + var enableLeaderElection bool + flag.BoolVar(&enableLeaderElection, "leader-elect", false, + "Enable leader election for controller manager. "+ + "Enabling this will ensure there is only one active controller manager.") + flag.Parse() logger, err := zap.NewDevelopment() if err != nil { @@ -42,6 +56,22 @@ func main() { } slog := logger.Sugar().WithOptions(zap.AddStacktrace(zap.DPanicLevel)) + + crdSetup, err := kubenotation.Setup(zapr.NewLogger(logger), metricsAddr, probeAddr, enableLeaderElection) + if err != nil { + log.Fatalf("failed to initialize crds: %v", err) + } + + crdManager := *crdSetup.CRDManager + crdChangeChan := *crdSetup.CRDChangeInformer + + slog.Info("Starting CRD Manager") + errsMgr := make(chan error, 1) + go func() { + errsMgr <- crdManager.Start(ctrl.SetupSignalHandler()) + }() + slog.Info("CRD Manager Started") + if !flagLocal { knvSetup.SetupLocal(slog) } @@ -68,14 +98,30 @@ func main() { }() } - slog.Info("Listening...") - select { - case err := <-errsHTTP: - slog.Infof("HTTP server error: %v", err) - case err := <-errsTLS: - slog.Infof("TLS server error: %v", err) + slog.Info("Listening for requests...") + for { + select { + case crdChanged := <-crdChangeChan: + slog.Infof("CRD Changed, updating notation verifier %v", crdChanged) + err := verifier.UpdateNotationVerfier() + if err != nil { + slog.Infof("failed to update verifier, reverting update err: %v", err) + } + slog.Infof("Notation verifier updated %v", crdChanged) + case err := <-errsHTTP: + slog.Infof("HTTP server error: %v", err) + verifier.Stop() + os.Exit(-1) + + case err := <-errsTLS: + slog.Infof("TLS server error: %v", err) + verifier.Stop() + os.Exit(-1) + + case err := <-errsMgr: + slog.Infof("problem running manager: %v", err) + verifier.Stop() + os.Exit(-1) + } } - - verifier.Stop() - os.Exit(-1) }