From 620c910b282b11bf4c515bfb966cee938dff1240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20B=C3=A4hler?= Date: Wed, 5 Feb 2025 12:05:59 +0100 Subject: [PATCH 1/7] feat(helm): change cert-gen job image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oliver Bähler --- .github/workflows/helm-test.yml | 24 +- Makefile | 18 +- charts/capsule-proxy/.helmignore | 1 + charts/capsule-proxy/.schema.yaml | 6 + charts/capsule-proxy/Chart.yaml | 8 +- charts/capsule-proxy/README.md | 14 +- charts/capsule-proxy/README.md.gotmpl | 4 +- ...ompatbility.yaml => backwards-values.yaml} | 0 charts/capsule-proxy/values.schema.json | 638 ++++++++++++++++++ charts/capsule-proxy/values.yaml | 10 +- 10 files changed, 701 insertions(+), 22 deletions(-) create mode 100644 charts/capsule-proxy/.schema.yaml rename charts/capsule-proxy/ci/{compatbility.yaml => backwards-values.yaml} (100%) create mode 100644 charts/capsule-proxy/values.schema.json diff --git a/.github/workflows/helm-test.yml b/.github/workflows/helm-test.yml index 9654059c..5682f6f9 100644 --- a/.github/workflows/helm-test.yml +++ b/.github/workflows/helm-test.yml @@ -10,6 +10,17 @@ concurrency: cancel-in-progress: true jobs: + linter-artifacthub: + runs-on: ubuntu-latest + container: + image: artifacthub/ah + options: --user root + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Run ah lint + working-directory: ./charts/ + run: ah lint lint: runs-on: ubuntu-20.04 steps: @@ -40,6 +51,17 @@ jobs: else echo -e '\033[0;32mDocumentation up to date\033[0m ✔' fi + - name: Run schema-testing (helm-schema) + id: helm-schema + run: | + make helm-schema + if [[ $(git diff --stat) != '' ]]; then + echo -e '\033[0;31mSchema outdated! (Run make helm-schema locally and commit)\033[0m ❌' + git diff --color + exit 1 + else + echo -e '\033[0;32mSchema up to date\033[0m ✔' + fi - name: Run chart-testing (install) run: make helm-test - if: steps.list-changed.outputs.changed == 'true' \ No newline at end of file + if: steps.list-changed.outputs.changed == 'true' diff --git a/Makefile b/Makefile index 814f4e54..cda74870 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,9 @@ IMG_BASE ?= $(REPOSITORY) IMG ?= $(IMG_BASE):$(VERSION) CAPSULE_PROXY_IMG ?= $(REGISTRY)/$(IMG_BASE) +## Tool Binaries +KUBECTL ?= kubectl +HELM ?= helm OS := $(shell uname) SRC_ROOT = $(shell git rev-parse --show-toplevel) @@ -106,6 +109,9 @@ helm-docs: docker helm-lint: docker @docker run -v "$(SRC_ROOT):/workdir" --entrypoint /bin/sh quay.io/helmpack/chart-testing:v3.3.1 -c "cd /workdir; ct lint --config .github/configs/ct.yaml --lint-conf .github/configs/lintconf.yaml --all --debug" +helm-schema: helm-plugin-schema + cd charts/capsule-proxy && $(HELM) schema + helm-test: helm-controller-version ct helm-create helm-install helm-destroy helm-test-ct: helm-load-image @@ -233,8 +239,8 @@ install-dependencies: install-capsule @kubectl apply --server-side=true -f https://github.com/prometheus-operator/prometheus-operator/releases/download/v0.58.0/bundle.yaml @helm repo add cert-manager https://charts.jetstack.io @helm repo add bitnami https://charts.bitnami.com/bitnami - @helm repo update - @helm upgrade --install cert-manager cert-manager/cert-manager --namespace cert-manager --create-namespace --version 1.16.2 --set crds.enabled=true + @helm repo update + @helm upgrade --install cert-manager cert-manager/cert-manager --namespace cert-manager --create-namespace --version 1.16.2 --set crds.enabled=true @helm upgrade --install --namespace metrics-system --create-namespace metrics-server bitnami/metrics-server \ --set apiService.create=true --set "extraArgs[0]=--kubelet-insecure-tls=true" --version 6.2.9 @kubectl --namespace metrics-system wait --for=condition=ready --timeout=320s pod -l app.kubernetes.io/instance=metrics-server @@ -267,6 +273,14 @@ install: manifests ## Install CRDs into the K8s cluster specified in ~/.kube/con uninstall: manifests ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. kubectl delete -f charts/capsule-proxy/crds +#################### +# -- Helm Plugins +#################### + +HELM_SCHEMA_VERSION := "" +helm-plugin-schema: + $(HELM) plugin install https://github.com/losisin/helm-values-schema-json.git --version $(HELM_SCHEMA_VERSION) || true + #################### # -- Tools #################### diff --git a/charts/capsule-proxy/.helmignore b/charts/capsule-proxy/.helmignore index 7e478cd6..34fc69cc 100644 --- a/charts/capsule-proxy/.helmignore +++ b/charts/capsule-proxy/.helmignore @@ -25,3 +25,4 @@ /*.tgz ci/ *.gotmpl +.schema.yaml diff --git a/charts/capsule-proxy/.schema.yaml b/charts/capsule-proxy/.schema.yaml new file mode 100644 index 00000000..4b4010a4 --- /dev/null +++ b/charts/capsule-proxy/.schema.yaml @@ -0,0 +1,6 @@ +input: + - ci/cert-manager-values.yaml + - ci/backwards-values.yaml + - ci/deploy-values.yaml + - ci/ds-values.yaml + - ci/webhook-values.yaml diff --git a/charts/capsule-proxy/Chart.yaml b/charts/capsule-proxy/Chart.yaml index 0e655b9a..df728e57 100644 --- a/charts/capsule-proxy/Chart.yaml +++ b/charts/capsule-proxy/Chart.yaml @@ -33,9 +33,7 @@ annotations: - name: Documentation url: https://projectcapsule.dev/ artifacthub.io/changes: | + - kind: changed + description: cert-job image from docker.io/jettech/kube-webhook-certgen to registry.k8s.io/ingress-nginx/kube-webhook-certgen (.Values.global.jobs.certs.image) - kind: added - description: Upgrading k8s.io packages to v1.31.2 - - kind: added - description: Support for bearer tokens in WebSocket protocols - - kind: fix - description: Support ServiceAccount bound token expiration + description: Webhook values diff --git a/charts/capsule-proxy/README.md b/charts/capsule-proxy/README.md index 93487f02..8c1fbda9 100644 --- a/charts/capsule-proxy/README.md +++ b/charts/capsule-proxy/README.md @@ -37,7 +37,7 @@ The Capsule-proxy Chart can be used to instantly deploy the Capsule-proxy on you $ helm upgrade capsule-proxy projectcapsule/capsule-proxy -n capsule-system 5. Uninstall the Chart - + $ helm uninstall capsule-proxy -n capsule-system ## Upgrading the Chart @@ -67,7 +67,7 @@ The `--values` option is the preferred method because it allows you to keep your Specify your overrides file when you install the chart: - $ helm install capsule-proxy projectcapsule/capsule-proxy --values myvalues.yaml -n capsule-system + $ helm install capsule-proxy projectcapsule/capsule-proxy --values myvalues.yaml -n capsule-system The values in your overrides file `myvalues.yaml` will override their counterparts in the chart’s values.yaml file. Any values in `values.yaml` that weren’t overridden will keep their defaults. @@ -91,9 +91,9 @@ If you only need to make minor customizations, you can specify them on the comma | global.jobs.certs.affinity | object | `{}` | Set affinity rules | | global.jobs.certs.annotations | object | `{}` | Annotations to add to the certgen job. | | global.jobs.certs.image.pullPolicy | string | `"IfNotPresent"` | Set the image pull policy of the post install certgen job | -| global.jobs.certs.image.registry | string | `"docker.io"` | Set the image repository of the post install certgen job | -| global.jobs.certs.image.repository | string | `"jettech/kube-webhook-certgen"` | Set the image repository of the post install certgen job | -| global.jobs.certs.image.tag | string | `"v1.3.0"` | Set the image tag of the post install certgen job | +| global.jobs.certs.image.registry | string | `"registry.k8s.io"` | Set the image repository of the post install certgen job | +| global.jobs.certs.image.repository | string | `"ingress-nginx/kube-webhook-certgen"` | Set the image repository of the post install certgen job | +| global.jobs.certs.image.tag | string | `"v1.4.3"` | Set the image tag of the post install certgen job | | global.jobs.certs.nodeSelector | object | `{}` | Set the node selector | | global.jobs.certs.podSecurityContext | object | `{"seccompProfile":{"type":"RuntimeDefault"}}` | Security context for the job pods. | | global.jobs.certs.priorityClassName | string | `""` | Set a pod priorityClassName | @@ -259,8 +259,8 @@ You can manage the certificate with the help of [cert-manager](https://cert-mana | autoscaling.maxReplicas | int | `3` | Set the maxReplicas for capsule-proxy hpa. | | autoscaling.metrics | list | `[]` | Custom [metrics-objects](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics) for capsule-proxy hpa | | autoscaling.minReplicas | int | `1` | Set the minReplicas for capsule-proxy hpa. | -| autoscaling.targetCPUUtilizationPercentage | string | `nil` | Set the targetCPUUtilizationPercentage for capsule-proxy hpa. | -| autoscaling.targetMemoryUtilizationPercentage | string | `nil` | Set the targetMemoryUtilizationPercentage for capsule-proxy hpa. | +| autoscaling.targetCPUUtilizationPercentage | int | `0` | Set the targetCPUUtilizationPercentage for capsule-proxy hpa. | +| autoscaling.targetMemoryUtilizationPercentage | int | `0` | Set the targetMemoryUtilizationPercentage for capsule-proxy hpa. | ### ServiceMonitor Parameters diff --git a/charts/capsule-proxy/README.md.gotmpl b/charts/capsule-proxy/README.md.gotmpl index b26b95f5..f2cbaace 100644 --- a/charts/capsule-proxy/README.md.gotmpl +++ b/charts/capsule-proxy/README.md.gotmpl @@ -37,7 +37,7 @@ The Capsule-proxy Chart can be used to instantly deploy the Capsule-proxy on you $ helm upgrade capsule-proxy projectcapsule/capsule-proxy -n capsule-system 5. Uninstall the Chart - + $ helm uninstall capsule-proxy -n capsule-system ## Upgrading the Chart @@ -67,7 +67,7 @@ The `--values` option is the preferred method because it allows you to keep your Specify your overrides file when you install the chart: - $ helm install capsule-proxy projectcapsule/capsule-proxy --values myvalues.yaml -n capsule-system + $ helm install capsule-proxy projectcapsule/capsule-proxy --values myvalues.yaml -n capsule-system The values in your overrides file `myvalues.yaml` will override their counterparts in the chart’s values.yaml file. Any values in `values.yaml` that weren’t overridden will keep their defaults. diff --git a/charts/capsule-proxy/ci/compatbility.yaml b/charts/capsule-proxy/ci/backwards-values.yaml similarity index 100% rename from charts/capsule-proxy/ci/compatbility.yaml rename to charts/capsule-proxy/ci/backwards-values.yaml diff --git a/charts/capsule-proxy/values.schema.json b/charts/capsule-proxy/values.schema.json new file mode 100644 index 00000000..6b9ab826 --- /dev/null +++ b/charts/capsule-proxy/values.schema.json @@ -0,0 +1,638 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "properties": { + "affinity": { + "properties": { + "nodeAffinity": { + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "preference": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "weight": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "autoscaling": { + "properties": { + "annotations": { + "properties": { + "example": { + "type": "string" + } + }, + "type": "object" + }, + "behavior": { + "properties": { + "scaleDown": { + "properties": { + "policies": { + "items": { + "properties": { + "periodSeconds": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "value": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "labels": { + "properties": { + "example": { + "type": "string" + } + }, + "type": "object" + }, + "maxReplicas": { + "type": "integer" + }, + "metrics": { + "items": { + "properties": { + "pods": { + "properties": { + "metric": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "target": { + "properties": { + "averageValue": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "minReplicas": { + "type": "integer" + }, + "targetCPUUtilizationPercentage": { + "type": "integer" + } + }, + "type": "object" + }, + "certManager": { + "properties": { + "certificate": { + "properties": { + "dnsNames": { + "items": { + "type": "string" + }, + "type": "array" + }, + "fields": { + "properties": { + "privateKey": { + "properties": { + "rotationPolicy": { + "type": "string" + } + }, + "type": "object" + }, + "renewBefore": { + "type": "string" + } + }, + "type": "object" + }, + "ipAddresses": { + "items": { + "type": "string" + }, + "type": "array" + }, + "uris": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "externalCA": { + "properties": { + "enabled": { + "type": "boolean" + }, + "secretName": { + "type": "string" + } + }, + "type": "object" + }, + "generateCertificates": { + "type": "boolean" + }, + "issuer": { + "properties": { + "kind": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "crds": { + "properties": { + "install": { + "type": "boolean" + }, + "keep": { + "type": "boolean" + } + }, + "type": "object" + }, + "daemonset": { + "properties": { + "hostNetwork": { + "type": "boolean" + }, + "hostPort": { + "type": "boolean" + } + }, + "type": "object" + }, + "global": { + "properties": { + "jobs": { + "properties": { + "certs": { + "properties": { + "nodeSelector": { + "properties": { + "global-field": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "kubectl": { + "properties": { + "ttlSecondsAfterFinished": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "imagePullSecrets": { + "type": "array" + }, + "ingress": { + "properties": { + "annotations": { + "properties": { + "example": { + "type": "string" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "hosts": { + "items": { + "properties": { + "host": { + "type": "string" + }, + "paths": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "ingressClassName": { + "type": "string" + }, + "labels": { + "properties": { + "example": { + "type": "string" + } + }, + "type": "object" + }, + "tls": { + "items": { + "properties": { + "hosts": { + "items": { + "type": "string" + }, + "type": "array" + }, + "secretName": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "jobs": { + "properties": { + "affinity": { + "properties": { + "nodeAffinity": { + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "preference": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "weight": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "certs": { + "properties": { + "pullPolicy": { + "type": "string" + }, + "registry": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "nodeSelector": { + "properties": { + "node-role.kubernetes.io/master": { + "type": "string" + } + }, + "type": "object" + }, + "priorityClassName": { + "type": "string" + }, + "tolerations": { + "items": { + "properties": { + "effect": { + "type": "string" + }, + "key": { + "type": "string" + }, + "operator": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "topologySpreadConstraints": { + "items": { + "properties": { + "labelSelector": { + "properties": { + "matchLabels": { + "properties": { + "app.kubernetes.io/name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "maxSkew": { + "type": "integer" + }, + "topologyKey": { + "type": "string" + }, + "whenUnsatisfiable": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "kind": { + "type": "string" + }, + "nodeSelector": { + "properties": { + "node-role.kubernetes.io/master": { + "type": "string" + } + }, + "type": "object" + }, + "options": { + "properties": { + "enableSSL": { + "type": "boolean" + }, + "generateCertificates": { + "type": "boolean" + } + }, + "type": "object" + }, + "podAnnotations": { + "properties": { + "extra": { + "type": "string" + }, + "scheduler.alpha.kubernetes.io/critical-pod": { + "type": "string" + } + }, + "type": "object" + }, + "podLabels": { + "properties": { + "extra": { + "type": "string" + } + }, + "type": "object" + }, + "priorityClassName": { + "type": "string" + }, + "rbac": { + "properties": { + "annotations": { + "properties": { + "extra": { + "type": "string" + } + }, + "type": "object" + }, + "labels": { + "properties": { + "extra": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "properties": { + "limits": { + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + }, + "type": "object" + }, + "requests": { + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "service": { + "properties": { + "annotations": { + "properties": { + "example": { + "type": "string" + } + }, + "type": "object" + }, + "labels": { + "properties": { + "example": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "serviceMonitor": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "tolerations": { + "items": { + "properties": { + "effect": { + "type": "string" + }, + "key": { + "type": "string" + }, + "operator": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "topologySpreadConstraints": { + "items": { + "properties": { + "labelSelector": { + "properties": { + "matchLabels": { + "properties": { + "app.kubernetes.io/name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "maxSkew": { + "type": "integer" + }, + "topologyKey": { + "type": "string" + }, + "whenUnsatisfiable": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "webhooks": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" +} diff --git a/charts/capsule-proxy/values.yaml b/charts/capsule-proxy/values.yaml index 916a94ef..40f2f336 100644 --- a/charts/capsule-proxy/values.yaml +++ b/charts/capsule-proxy/values.yaml @@ -54,13 +54,13 @@ global: certs: image: # -- Set the image repository of the post install certgen job - registry: docker.io + registry: registry.k8s.io # -- Set the image repository of the post install certgen job - repository: jettech/kube-webhook-certgen + repository: ingress-nginx/kube-webhook-certgen # -- Set the image pull policy of the post install certgen job pullPolicy: IfNotPresent # -- Set the image tag of the post install certgen job - tag: "v1.3.0" + tag: "v1.4.3" # -- Annotations to add to the certgen job. annotations: {} # -- Set the restartPolicy @@ -390,9 +390,9 @@ autoscaling: # -- Set the maxReplicas for capsule-proxy hpa. maxReplicas: 3 # -- Set the targetCPUUtilizationPercentage for capsule-proxy hpa. - targetCPUUtilizationPercentage: + targetCPUUtilizationPercentage: 0 # -- Set the targetMemoryUtilizationPercentage for capsule-proxy hpa. - targetMemoryUtilizationPercentage: + targetMemoryUtilizationPercentage: 0 # -- Custom [metrics-objects](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics) for capsule-proxy hpa metrics: [] # - type: Pods From 7fe6749ca1e4e0d5143610bce3c613100759a4f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20B=C3=A4hler?= Date: Wed, 5 Feb 2025 12:06:31 +0100 Subject: [PATCH 2/7] sec(release): release sboms and signatures in same repository as artefact MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oliver Bähler --- .github/workflows/docker-publish.yml | 8 ++++---- .github/workflows/helm-publish.yml | 4 ++-- SECURITY.md | 19 +++++++------------ 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index b8c60e74..de9d48b7 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest permissions: packages: write - id-token: write + id-token: write outputs: capsule-digest: ${{ steps.publish-capsule.outputs.digest }} steps: @@ -49,8 +49,8 @@ jobs: version: ${{ github.ref_name }} sign-image: true sbom-name: capsule-proxy - sbom-repository: ghcr.io/${{ github.repository_owner }}/sbom - signature-repository: ghcr.io/${{ github.repository_owner }}/signatures + sbom-repository: ghcr.io/${{ github.repository_owner }}/capsule-proxy + signature-repository: ghcr.io/${{ github.repository_owner }}/capsule-proxy main-path: ./ env: REPOSITORY: ${{ github.repository }} @@ -66,4 +66,4 @@ jobs: digest: "${{ needs.publish-images.outputs.capsule-digest }}" registry-username: ${{ github.actor }} secrets: - registry-password: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + registry-password: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/helm-publish.yml b/.github/workflows/helm-publish.yml index f93b615a..a4a331dc 100644 --- a/.github/workflows/helm-publish.yml +++ b/.github/workflows/helm-publish.yml @@ -54,7 +54,7 @@ jobs: echo "version=$(echo $VERSION)" >> $GITHUB_OUTPUT - name: Helm | Publish id: helm_publish - uses: peak-scale/github-actions/helm-oci-chart@38322faabccd75abfa581c435e367d446b6d2c3b + uses: peak-scale/github-actions/helm-oci-chart@38322faabccd75abfa581c435e367d446b6d2c3b with: registry: ghcr.io repository: ${{ github.repository_owner }}/charts @@ -65,7 +65,7 @@ jobs: registry-password: ${{ secrets.GITHUB_TOKEN }} update-dependencies: 'true' # Defaults to false sign-image: 'true' - signature-repository: ghcr.io/${{ github.repository_owner }}/signatures + signature-repository: ghcr.io/${{ github.repository_owner }}/charts/capsule-proxy helm-provenance: needs: publish-helm-oci permissions: diff --git a/SECURITY.md b/SECURITY.md index 3724f9ab..f867a407 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -35,7 +35,7 @@ To report a security issue or vulnerability, [submit a private vulnerability rep Describe the issue in English, ideally with some example configuration or code which allows the issue to be reproduced. Explain why you believe this to be a security issue in capsule-proxy, if that's not obvious. should contain the following: * description of the problem - * precise and detailed steps (include screenshots) + * precise and detailed steps (include screenshots) * the affected version(s). This may also include environment relevant versions. * any possible mitigations @@ -55,19 +55,17 @@ Response times could be affected by weekends, holidays, breaks or time zone diff ## Verifing -To verify artifacts you need to have [cosign installed](https://github.com/sigstore/cosign#installation). This guide assumes you are using v2.x of cosign. All of the signatures are created using [keyless signing](https://docs.sigstore.dev/verifying/verify/#keyless-verification-using-openid-connect). We have a seperate repository for all the signatures for all the artifacts released under the projectcapsule - `ghcr.io/projectcapsule/signatures`. You can set the environment variable `COSIGN_REPOSITORY` to point to this repository. For example: - - export COSIGN_REPOSITORY=ghcr.io/projectcapsule/signatures +To verify artifacts you need to have [cosign installed](https://github.com/sigstore/cosign#installation). This guide assumes you are using v2.x of cosign. All of the signatures are created using [keyless signing](https://docs.sigstore.dev/verifying/verify/#keyless-verification-using-openid-connect). To verify the signature of the docker image, run the following command. Replace `` with an [available release tag](https://github.com/projectcapsule/capsule-proxy/pkgs/container/capsule-proxy): - COSIGN_REPOSITORY=ghcr.io/projectcapsule/signatures cosign verify ghcr.io/projectcapsule/capsule-proxy: \ + cosign verify ghcr.io/projectcapsule/capsule-proxy: \ --certificate-identity-regexp="https://github.com/projectcapsule/capsule-proxy/.github/workflows/docker-publish.yml@refs/tags/*" \ --certificate-oidc-issuer="https://token.actions.githubusercontent.com" | jq To verify the signature of the helm image, run the following command. Replace `` with an [available release tag](https://github.com/projectcapsule/capsule/pkgs/container/charts%2Fcapsule): - COSIGN_REPOSITORY=ghcr.io/projectcapsule/signatures cosign verify ghcr.io/projectcapsule/charts/capsule-proxy: \ + cosign verify ghcr.io/projectcapsule/charts/capsule-proxy: \ --certificate-identity-regexp="https://github.com/projectcapsule/capsule-proxy/.github/workflows/helm-publish.yml@refs/tags/*" \ --certificate-oidc-issuer="https://token.actions.githubusercontent.com" | jq @@ -96,18 +94,15 @@ cosign verify-attestation --type slsaprovenance \ ## Software Bill of Materials (SBOM) -An SBOM (Software Bill of Materials) in CycloneDX JSON format is published for each Kyverno release, including pre-releases. Like signatures, SBOMs are stored in a separate repository at `ghcr.io/projectcapsule/sbom`. You can set the environment variable `COSIGN_REPOSITORY` to point to this repository. For example: - - export COSIGN_REPOSITORY=ghcr.io/projectcapsule/sbom +An SBOM (Software Bill of Materials) in CycloneDX JSON format is published for each release, including pre-releases. To inspect the SBOM of the docker image, run the following command. Replace `` with an [available release tag](https://github.com/projectcapsule/capsule-proxy/pkgs/container/capsule-proxy): + COSIGN_REPOSITORY=ghcr.io/projectcapsule/capsule-proxy cosign download sbom ghcr.io/projectcapsule/capsule-proxy: - COSIGN_REPOSITORY=ghcr.io/projectcapsule/sbom cosign download sbom ghcr.io/projectcapsule/capsule-proxy: - To inspect the SBOM of the helm image, run the following command. Replace `` with an [available release tag](https://github.com/projectcapsule/capsule-proxy/pkgs/container/charts%2Fcapsule-proxy): - COSIGN_REPOSITORY=ghcr.io/projectcapsule/sbom cosign download sbom ghcr.io/projectcapsule/charts/capsule-proxy: + COSIGN_REPOSITORY=ghcr.io/projectcapsule/charts/capsule-proxy cosign download sbom ghcr.io/projectcapsule/charts/capsule-proxy: # Credits From f0130816d5a7df2a1b5bc2edc47e1bf91162d45a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20B=C3=A4hler?= Date: Fri, 7 Feb 2025 08:26:37 +0100 Subject: [PATCH 3/7] ci(helm): update workflows and correct testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oliver Bähler --- .github/configs/lintconf.yaml | 9 +- .github/workflows/check-actions.yml | 7 +- .github/workflows/check-commit.yml | 7 +- .github/workflows/codecov.yml | 38 ----- .github/workflows/coverage.yml | 84 ++++++++++ .github/workflows/docker-build.yml | 45 ++++++ .github/workflows/e2e-legacy.yaml | 58 ------- .github/workflows/e2e.yml | 24 +-- .github/workflows/fossa.yml | 35 ----- .github/workflows/helm-test.yml | 25 ++- .github/workflows/lint.yaml | 53 +++++-- .goreleaser.yml | 15 +- .pre-commit-config.yaml | 64 +++----- Makefile | 143 ++++++++++-------- charts/capsule-proxy/.helmignore | 1 + charts/capsule-proxy/README.md | 2 + charts/capsule-proxy/README.md.gotmpl | 2 + charts/capsule-proxy/artifacthub-repo.yml | 4 + charts/capsule-proxy/ci/backwards-values.yaml | 15 +- .../capsule-proxy/templates/certgen-job.yaml | 8 +- .../templates/crd-lifecycle/_helpers.tpl | 3 +- .../templates/crd-lifecycle/job.yaml | 7 +- charts/capsule-proxy/values.schema.json | 47 +++--- e2e/distro/flux/kustomization.yaml | 33 ++++ e2e/distro/objects/capsule.flux.yaml | 44 ++++++ e2e/distro/objects/cert-manager.flux.yaml | 38 +++++ e2e/distro/objects/kustomization.yaml | 8 + e2e/distro/objects/metrics.flux.yaml | 38 +++++ renovate.json | 24 +++ 29 files changed, 549 insertions(+), 332 deletions(-) delete mode 100644 .github/workflows/codecov.yml create mode 100644 .github/workflows/coverage.yml create mode 100644 .github/workflows/docker-build.yml delete mode 100644 .github/workflows/e2e-legacy.yaml delete mode 100644 .github/workflows/fossa.yml create mode 100644 charts/capsule-proxy/artifacthub-repo.yml create mode 100644 e2e/distro/flux/kustomization.yaml create mode 100644 e2e/distro/objects/capsule.flux.yaml create mode 100644 e2e/distro/objects/cert-manager.flux.yaml create mode 100644 e2e/distro/objects/kustomization.yaml create mode 100644 e2e/distro/objects/metrics.flux.yaml diff --git a/.github/configs/lintconf.yaml b/.github/configs/lintconf.yaml index f52bab7e..577d81e6 100644 --- a/.github/configs/lintconf.yaml +++ b/.github/configs/lintconf.yaml @@ -1,5 +1,12 @@ --- +ignore: + - config/ + - charts/*/templates/ + - charts/**/templates/ rules: + truthy: + level: warning + check-keys: false braces: min-spaces-inside: 0 max-spaces-inside: 0 @@ -38,5 +45,3 @@ rules: new-lines: type: unix trailing-spaces: enable - truthy: - level: warning \ No newline at end of file diff --git a/.github/workflows/check-actions.yml b/.github/workflows/check-actions.yml index 375c6b7a..5bf17d4a 100644 --- a/.github/workflows/check-actions.yml +++ b/.github/workflows/check-actions.yml @@ -3,7 +3,8 @@ permissions: {} on: pull_request: - branches: [ "*" ] + branches: + - "*" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -18,7 +19,7 @@ jobs: - name: Ensure SHA pinned actions uses: zgosalvez/github-actions-ensure-sha-pinned-actions@6ae615f6475d2ede5ad88bea6baa7a1d5e93ffaa # v3.0.19 with: - # slsa-github-generator requires using a semver tag for reusable workflows. + # slsa-github-generator requires using a semver tag for reusable workflows. # See: https://github.com/slsa-framework/slsa-github-generator#referencing-slsa-builders-and-generators allowlist: | - slsa-framework/slsa-github-generator \ No newline at end of file + slsa-framework/slsa-github-generator diff --git a/.github/workflows/check-commit.yml b/.github/workflows/check-commit.yml index 3d2be3a1..b33adaef 100644 --- a/.github/workflows/check-commit.yml +++ b/.github/workflows/check-commit.yml @@ -3,7 +3,8 @@ permissions: {} on: pull_request: - branches: [ "*" ] + branches: + - "*" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -16,6 +17,4 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 - - uses: wagoid/commitlint-github-action@3d28780bbf0365e29b144e272b2121204d5be5f3 #v6.1.2 - with: - firstParent: true + - uses: wagoid/commitlint-github-action@3d28780bbf0365e29b144e272b2121204d5be5f3 # v6.1.2 diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml deleted file mode 100644 index 88972d4c..00000000 --- a/.github/workflows/codecov.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Codecov -permissions: {} - -on: - pull_request: - branches: [ "main" ] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - codecov: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Setup caches - uses: ./.github/actions/setup-caches - timeout-minutes: 5 - continue-on-error: true - with: - build-cache-key: codecov - - name: Check secret - id: checksecret - uses: ./.github/actions/exists - with: - value: ${{ secrets.CODECOV_TOKEN }} - - name: Generate Code Coverage Report - if: steps.checksecret.outputs.result == 'true' - run: make test - - name: Upload Report to Codecov - if: steps.checksecret.outputs.result == 'true' - uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2 - with: - file: ./coverage.out - fail_ci_if_error: true - verbose: true diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 00000000..59ed58b1 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,84 @@ +name: Coverage + +on: + push: + branches: + - "main" + pull_request: + types: [opened, reopened, synchronize] + branches: + - "main" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + compliance: + name: "License Compliance" + runs-on: ubuntu-24.04 + steps: + - name: "Checkout Code" + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Check secret + id: checksecret + uses: ./.github/actions/exists + with: + value: ${{ secrets.FOSSA_API_KEY }} + - name: "Run FOSSA Scan" + if: steps.checksecret.outputs.result == 'true' + uses: fossas/fossa-action@93a52ecf7c3ac7eb40f5de77fd69b1a19524de94 # v1.5.0 + with: + api-key: ${{ secrets.FOSSA_API_KEY }} + - name: "Run FOSSA Test" + if: steps.checksecret.outputs.result == 'true' + uses: fossas/fossa-action@93a52ecf7c3ac7eb40f5de77fd69b1a19524de94 # v1.5.0 + with: + api-key: ${{ secrets.FOSSA_API_KEY }} + run-tests: true + sast: + name: "SAST" + runs-on: ubuntu-24.04 + env: + GO111MODULE: on + permissions: + security-events: write + actions: read + contents: read + steps: + - name: Checkout Source + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 + with: + go-version-file: 'go.mod' + - name: Run Gosec Security Scanner + uses: securego/gosec@e0cca6fe95306b7e7790d6f1bf6a7bec6d622459 # v2.22.0 + with: + args: '-no-fail -fmt sarif -out gosec.sarif ./...' + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@24e1c2d337459cce262cbca8d69998e56cd5eb8e + with: + sarif_file: gosec.sarif + unit_tests: + name: "Unit tests" + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 + with: + go-version-file: 'go.mod' + - name: Unit Test + run: make test + - name: Check secret + id: checksecret + uses: ./.github/actions/exists + with: + value: ${{ secrets.CODECOV_TOKEN }} + - name: Upload Report to Codecov + if: ${{ steps.checksecret.outputs.result == 'true' }} + uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1 + with: + files: ./coverage.out + fail_ci_if_error: true + verbose: true diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 00000000..8afbb4bd --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,45 @@ +name: Build images +permissions: {} +on: + pull_request: + branches: + - "main" + paths: + - '.github/workflows/docker-*.yml' + - 'api/**' + - 'controllers/**' + - 'pkg/**' + - 'e2e/*' + - '.ko.yaml' + - 'go.*' + - 'main.go' + - 'Makefile' + +jobs: + build-images: + runs-on: ubuntu-latest + permissions: + security-events: write + actions: read + contents: read + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: ko build + run: VERSION=${{ github.sha }} make ko-build-all + - name: Trivy Scan Image + uses: aquasecurity/trivy-action@18f2510ee396bbf400402947b394f2dd8c87dbb0 # v0.29.0 + with: + scan-type: 'fs' + ignore-unfixed: true + format: 'sarif' + output: 'trivy-results.sarif' + severity: 'CRITICAL,HIGH' + env: + # Trivy is returning TOOMANYREQUESTS + # See: https://github.com/aquasecurity/trivy-action/issues/389#issuecomment-2385416577 + TRIVY_DB_REPOSITORY: 'public.ecr.aws/aquasecurity/trivy-db:2' + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@24e1c2d337459cce262cbca8d69998e56cd5eb8e + with: + sarif_file: 'trivy-results.sarif' diff --git a/.github/workflows/e2e-legacy.yaml b/.github/workflows/e2e-legacy.yaml deleted file mode 100644 index c266723c..00000000 --- a/.github/workflows/e2e-legacy.yaml +++ /dev/null @@ -1,58 +0,0 @@ -name: e2e - -on: - push: - branches: [ "issues/257" ] - paths: - - '.github/workflows/e2e.yaml' - - 'e2e/**' - - 'internal/**' - - 'Dockerfile' - - 'go.*' - - 'main.go' - - 'Makefile' - pull_request: - branches: [ "issues/257" ] - paths: - - '.github/workflows/e2e.yaml' - - 'e2e/**' - - 'internal/**' - - 'Dockerfile' - - 'go.*' - - 'main.go' - - 'Makefile' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - kind: - name: Kubernetes - strategy: - fail-fast: false - matrix: - k8s-version: [ 'v1.16.15', 'v1.17.11', 'v1.18.8', 'v1.19.4', 'v1.20.7', 'v1.21.2', 'v1.22.0' ] - capsule-proxy-mode: [ 'https', 'http' ] - test-clients: [ 'kubectl', 'curl' ] - runs-on: ubuntu-18.04 - timeout-minutes: 20 - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - with: - fetch-depth: 0 - - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 - with: - version: 3.3.4 - - name: Installing BATS - run: sudo apt-get install -y bats - - name: Installing jq - run: sudo apt-get install -y jq - - name: e2e testing - run: CLIENT_TEST=${{ matrix.test-clients }} CAPSULE_PROXY_MODE=${{ matrix.capsule-proxy-mode }} KIND_K8S_VERSION=${{ matrix.k8s-version }} make e2e - - name: Dumping Capsule logs - if: failure() - run: kubectl -n capsule-system logs -l app.kubernetes.io/instance=capsule - - name: Dumping Capsule Proxy logs - if: failure() - run: kubectl -n capsule-system logs -l app.kubernetes.io/instance=capsule-proxy diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 1e9bc91f..0a1dc42d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -2,20 +2,9 @@ name: e2e permissions: {} on: - push: - branches: [ "*" ] - paths: - - '.github/workflows/e2e.yml' - - 'api/**' - - 'controllers/**' - - 'internal/**' - - 'e2e/*' - - 'Dockerfile' - - 'go.*' - - 'main.go' - - 'Makefile' pull_request: - branches: [ "*" ] + branches: + - "*" paths: - '.github/workflows/e2e.yml' - 'api/**' @@ -34,10 +23,6 @@ concurrency: jobs: kind: name: Kubernetes - strategy: - fail-fast: false - matrix: - k8s-version: [ 'v1.24.7', 'v1.25.3', 'v1.26.3', 'v1.27.2', 'v1.28.0', 'v1.29.0', 'v1.30.0', 'v1.31.0' ] runs-on: ubuntu-20.04 steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 @@ -49,8 +34,5 @@ jobs: - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v3 with: version: v3.14.2 - - uses: engineerd/setup-kind@aa272fe2a7309878ffc2a81c56cfe3ef108ae7d0 # v0.5.0 - with: - skipClusterCreation: true - name: e2e testing - run: KIND_K8S_VERSION=${{ matrix.k8s-version }} make e2e + run: make e2e diff --git a/.github/workflows/fossa.yml b/.github/workflows/fossa.yml deleted file mode 100644 index df12a6e2..00000000 --- a/.github/workflows/fossa.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: FOSSA -permissions: {} - -on: - push: - branches: [ "*" ] - pull_request: - branches: [ "*" ] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - fossa-scan: - runs-on: ubuntu-20.04 - steps: - - name: "Checkout Code" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Check secret - id: checksecret - uses: ./.github/actions/exists - with: - value: ${{ secrets.FOSSA_API_KEY }} - - name: "Run FOSSA Scan" - if: steps.checksecret.outputs.result == 'true' - uses: fossas/fossa-action@09bcf127dc0ccb4b5a023f6f906728878e8610ba # v1.4.0 - with: - api-key: ${{ secrets.FOSSA_API_KEY }} - - name: "Run FOSSA Test" - if: steps.checksecret.outputs.result == 'true' - uses: fossas/fossa-action@09bcf127dc0ccb4b5a023f6f906728878e8610ba # v1.4.0 - with: - api-key: ${{ secrets.FOSSA_API_KEY }} - run-tests: true diff --git a/.github/workflows/helm-test.yml b/.github/workflows/helm-test.yml index 5682f6f9..189fb408 100644 --- a/.github/workflows/helm-test.yml +++ b/.github/workflows/helm-test.yml @@ -3,7 +3,13 @@ permissions: {} on: pull_request: - branches: [ "main" ] + branches: + - "main" + paths: + - '.github/configs/**' + - '.github/workflows/helm-*.yml' + - 'charts/**' + - 'Makefile' concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -22,24 +28,14 @@ jobs: working-directory: ./charts/ run: ah lint lint: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 - - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v3 - - name: Setup Chart Linting - id: lint - uses: helm/chart-testing-action@e6669bcd63d7cb57cb4380c33043eebe5d111992 - - name: Run chart-testing (list-changed) - id: list-changed - run: | - changed=$(ct list-changed --config ./.github/configs/ct.yaml) - if [[ -n "$changed" ]]; then - echo "::set-output name=changed::true" - fi + - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4 - name: Run chart-testing (lint) - run: ct lint --debug --config ./.github/configs/ct.yaml --lint-conf ./.github/configs/lintconf.yaml + run: make helm-lint - name: Run docs-testing (helm-docs) id: helm-docs run: | @@ -64,4 +60,3 @@ jobs: fi - name: Run chart-testing (install) run: make helm-test - if: steps.list-changed.outputs.changed == 'true' diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 492c4638..23f6fe99 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -1,29 +1,56 @@ -name: Go Lint - +name: Linting +permissions: {} on: push: - branches: [ "*" ] + branches: + - "*" pull_request: - branches: [ "*" ] - + branches: + - "*" concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - jobs: + manifests: + name: diff + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 + with: + go-version-file: 'go.mod' + - name: Generate manifests + run: | + make manifests + if [[ $(git diff --stat) != '' ]]; then + echo -e '\033[0;31mManifests outdated! (Run make manifests locally and commit)\033[0m ❌' + git diff --color + exit 1 + else + echo -e '\033[0;32mDocumentation up to date\033[0m ✔' + fi + yamllint: + name: yamllint + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Install yamllint + run: pip install yamllint + - name: Lint YAML files + run: yamllint -c=.github/configs/lintconf.yaml . golangci: name: lint - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Install Go - uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 + - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 with: - go-version-file: go.mod - cache: false + go-version-file: 'go.mod' - name: Run golangci-lint - uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 + uses: golangci/golangci-lint-action@e60da84bfae8c7920a47be973d75e15710aa8bd7 # v6.3.0 with: - version: v1.61.0 + version: v1.56.2 only-new-issues: false args: --timeout 5m --config .golangci.yml diff --git a/.goreleaser.yml b/.goreleaser.yml index f7cfa2a0..577d4c00 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -34,7 +34,7 @@ release: Thanks to all the contributors! **Full Changelog**: https://github.com/projectcapsule/{{ .ProjectName }}/compare/{{ .PreviousTag }}...{{ .Tag }} - + **Docker Images** - `ghcr.io/projectcapsule/{{ .ProjectName }}:{{ .Version }}` - `ghcr.io/projectcapsule/{{ .ProjectName }}:latest` @@ -44,6 +44,17 @@ release: - `ghcr.io/projectcapsule/charts/{{ .ProjectName }}:{{ .Version }}` + **Kubernetes compatibility** + + [!IMPORTANT] + Note that the Capsule project offers support only for the latest minor version of Kubernetes. + Backwards compatibility with older versions of Kubernetes and OpenShift is [offered by supporters](https://projectcapsule.dev/support/). + + | Kubernetes version | Minimum required | + |--------------------|------------------| + | `v1.31` | `>= 1.31.0` | + + Thanks to all the contributors! 🚀 🦄 checksum: name_template: 'checksums.txt' changelog: @@ -89,4 +100,4 @@ signs: - "--output-signature=${signature}" - "${artifact}" - "--yes" - artifacts: all \ No newline at end of file + artifacts: all diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3f347e5b..d4867510 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,51 +2,35 @@ repos: - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook rev: v9.20.0 hooks: - - id: commitlint - stages: [commit-msg] - additional_dependencies: ['@commitlint/config-conventional', 'commitlint-plugin-function-rules'] + - id: commitlint + stages: [commit-msg] + additional_dependencies: ['@commitlint/config-conventional', 'commitlint-plugin-function-rules'] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.2.0 + rev: v5.0.0 hooks: - id: check-executables-have-shebangs - - id: check-yaml - id: double-quote-string-fixer - id: end-of-file-fixer - id: trailing-whitespace -- repo: local +- repo: https://github.com/adrienverge/yamllint + rev: v1.35.1 hooks: - - id: run-helm-docs - name: Execute helm-docs - entry: make helm-docs - language: system - files: ^charts/ - - id: run-helm-schema - name: Execute helm-schema - entry: make helm-schema - language: system - files: ^charts/ - - id: run-helm-lint - name: Execute helm-lint - entry: make helm-lint - language: system - files: ^charts/ - - id: golangci-lint - name: Execute golangci-lint - entry: make golint - language: system - files: \.go$ -- repo: https://github.com/tekwizely/pre-commit-golang - rev: v1.0.0-rc.1 + - id: yamllint + args: [-c=.github/configs/lintconf.yaml] +- repo: local hooks: - - id: go-vet - - id: go-vet-mod - - id: go-vet-pkg - - id: go-vet-repo-mod - - id: go-vet-repo-pkg - - id: go-revive - - id: go-revive-mod - - id: go-revive-repo-mod - - id: go-sec-mod - - id: go-sec-pkg - - id: go-sec-repo-mod - - id: go-sec-repo-pkg + - id: run-helm-docs + name: Execute helm-docs + entry: make helm-docs + language: system + files: ^charts/ + - id: run-helm-schema + name: Execute helm-schema + entry: make helm-schema + language: system + files: ^charts/ + - id: run-helm-lint + name: Execute helm-lint + entry: make helm-lint + language: system + files: ^charts/ diff --git a/Makefile b/Makefile index cda74870..b03a16e1 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,9 @@ IMG_BASE ?= $(REPOSITORY) IMG ?= $(IMG_BASE):$(VERSION) CAPSULE_PROXY_IMG ?= $(REGISTRY)/$(IMG_BASE) +## Kubernetes Version Support +KUBERNETES_SUPPORTED_VERSION ?= "v1.31.0" + ## Tool Binaries KUBECTL ?= kubectl HELM ?= helm @@ -91,7 +94,6 @@ ko-publish-capsule-proxy: ko-login .PHONY: ko-publish-all ko-publish-all: ko-publish-capsule-proxy - #################### # -- Helm #################### @@ -101,27 +103,26 @@ helm-controller-version: $(eval KO_TAGS := $(shell grep 'appVersion:' charts/capsule-proxy/Chart.yaml | awk '{print "v"$$2}')) .PHONY: helm-docs -helm-docs: HELMDOCS_VERSION := v1.11.0 -helm-docs: docker - @docker run -v "$(SRC_ROOT):/helm-docs" jnorwood/helm-docs:$(HELMDOCS_VERSION) --chart-search-root /helm-docs +helm-docs: helm-doc + $(HELM_DOCS) --chart-search-root ./charts .PHONY: helm-lint -helm-lint: docker - @docker run -v "$(SRC_ROOT):/workdir" --entrypoint /bin/sh quay.io/helmpack/chart-testing:v3.3.1 -c "cd /workdir; ct lint --config .github/configs/ct.yaml --lint-conf .github/configs/lintconf.yaml --all --debug" +helm-lint: ct + @$(CT) lint --config .github/configs/ct.yaml --validate-yaml=false --all --debug helm-schema: helm-plugin-schema cd charts/capsule-proxy && $(HELM) schema -helm-test: helm-controller-version ct helm-create helm-install helm-destroy +helm-test: helm-create helm-install helm-destroy -helm-test-ct: helm-load-image +helm-test-ct: ct helm-load-image @$(CT) install --config $(SRC_ROOT)/.github/configs/ct.yaml --namespace=capsule-system --all --debug helm-install: install-dependencies helm-test-ct helm-create: kind - @$(KIND) create cluster --wait=60s --name capsule-charts - @kubectl create ns capsule-system + @$(KIND) create cluster --wait=60s --name capsule-charts --image kindest/node:$(KUBERNETES_SUPPORTED_VERSION) + @$(KUBECTL) create ns capsule-system helm-load-image: kind helm-controller-version ko-build-all @$(KIND) load docker-image --name capsule-charts $(CAPSULE_PROXY_IMG):$(VERSION) @@ -146,13 +147,13 @@ e2e-exec: ginkgo .PHONY: e2e-build e2e-build: kind - @echo "Building kubernetes env using Kind $${KIND_K8S_VERSION:-v1.27.0}..." - @$(KIND) create cluster --name capsule --image kindest/node:$${KIND_K8S_VERSION:-v1.27.0} --config ./e2e/kind.yaml --wait=120s \ + @echo "Building kubernetes env using Kind $(KUBERNETES_SUPPORTED_VERSION)..." + @$(KIND) create cluster --name capsule --image kindest/node:$(KUBERNETES_SUPPORTED_VERSION) --config ./e2e/kind.yaml --wait=120s \ && kubectl taint nodes capsule-worker2 key1=value1:NoSchedule @echo "Waiting for metrics-server pod to be ready for listing metrics" .PHONY: e2e-install -e2e-install: install-capsule install-dependencies install-capsule-proxy rbac-fix +e2e-install: install-dependencies install-capsule-proxy rbac-fix .PHONY: e2e-load-image e2e-load-image: kind ko-build-all @@ -163,14 +164,6 @@ e2e-load-image: kind ko-build-all e2e-destroy: kind $(KIND) delete cluster --name capsule -install-capsule: - @echo "Installing capsule..." - @helm repo add projectcapsule https://projectcapsule.github.io/charts - @helm upgrade --install --create-namespace --namespace capsule-system capsule projectcapsule/capsule \ - --set "manager.resources=null" \ - --set "manager.options.forceTenantPrefix=true" \ - --set "options.logLevel=8" - install-capsule-proxy: mkcert e2e-load-image @echo "Installing Capsule-Proxy..." ifeq ($(CAPSULE_PROXY_MODE),http) @@ -235,16 +228,16 @@ else endif @kubectl rollout restart ds capsule-proxy -n capsule-system || true -install-dependencies: install-capsule - @kubectl apply --server-side=true -f https://github.com/prometheus-operator/prometheus-operator/releases/download/v0.58.0/bundle.yaml - @helm repo add cert-manager https://charts.jetstack.io - @helm repo add bitnami https://charts.bitnami.com/bitnami - @helm repo update - @helm upgrade --install cert-manager cert-manager/cert-manager --namespace cert-manager --create-namespace --version 1.16.2 --set crds.enabled=true - @helm upgrade --install --namespace metrics-system --create-namespace metrics-server bitnami/metrics-server \ - --set apiService.create=true --set "extraArgs[0]=--kubelet-insecure-tls=true" --version 6.2.9 - @kubectl --namespace metrics-system wait --for=condition=ready --timeout=320s pod -l app.kubernetes.io/instance=metrics-server +install-dependencies: + @$(KUBECTL) kustomize e2e/distro/flux/ | kubectl apply --force-conflicts --server-side=true -f - + @$(KUBECTL) kustomize e2e/distro/objects/ | kubectl apply --force-conflicts --server-side=true -f - + @$(MAKE) wait-for-helmreleases +wait-for-helmreleases: + @ echo "Waiting for all HelmReleases to have observedGeneration >= 0..." + @while [ "$$($(KUBECTL) get helmrelease -A -o jsonpath='{range .items[?(@.status.observedGeneration<0)]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{end}' | wc -l)" -ne 0 ]; do \ + sleep 5; \ + done rbac-fix: @echo "RBAC customization..." @@ -273,64 +266,84 @@ install: manifests ## Install CRDs into the K8s cluster specified in ~/.kube/con uninstall: manifests ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. kubectl delete -f charts/capsule-proxy/crds +#################### +# -- Helpers +#################### +## Location to install dependencies to +LOCALBIN ?= $(shell pwd)/bin +$(LOCALBIN): + mkdir -p $(LOCALBIN) + #################### # -- Helm Plugins #################### HELM_SCHEMA_VERSION := "" helm-plugin-schema: - $(HELM) plugin install https://github.com/losisin/helm-values-schema-json.git --version $(HELM_SCHEMA_VERSION) || true + @$(HELM) plugin install https://github.com/losisin/helm-values-schema-json.git --version $(HELM_SCHEMA_VERSION) || true + +HELM_DOCS := $(LOCALBIN)/helm-docs +HELM_DOCS_VERSION := v1.14.1 +HELM_DOCS_LOOKUP := norwoodj/helm-docs +helm-doc: + @test -s $(HELM_DOCS) || \ + $(call go-install-tool,$(HELM_DOCS),github.com/$(HELM_DOCS_LOOKUP)/cmd/helm-docs@$(HELM_DOCS_VERSION)) #################### # -- Tools #################### - -CONTROLLER_GEN = $(shell pwd)/bin/controller-gen -CONTROLLER_GEN_VERSION = v0.8.0 -controller-gen: ## Download controller-gen locally if necessary. +CONTROLLER_GEN := $(LOCALBIN)/controller-gen +CONTROLLER_GEN_VERSION ?= v0.16.3 +CONTROLLER_GEN_LOOKUP := kubernetes-sigs/controller-tools +controller-gen: + @test -s $(CONTROLLER_GEN) && $(CONTROLLER_GEN) --version | grep -q $(CONTROLLER_GEN_VERSION) || \ $(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION)) -GINKGO := $(shell pwd)/bin/ginkgo -GINKGO_VERSION = v2.19.0 +GINKGO := $(LOCALBIN)/ginkgo +GINKGO_VERSION := v2.19.0 +GINKGO_LOOKUP := onsi/ginkgo ginkgo: ## Download ginkgo locally if necessary. - $(call go-install-tool,$(GINKGO),github.com/onsi/ginkgo/v2/ginkgo@$(GINKGO_VERSION)) + $(call go-install-tool,$(GINKGO),github.com/$(GINKGO_LOOKUP)/v2/ginkgo@$(GINKGO_VERSION)) -MKCERT = $(shell pwd)/bin/mkcert -MKCERT_VERSION = v1.4.4 +MKCERT := $(LOCALBIN)/mkcert +MKCERT_VERSION := v1.4.4 +MKCERT_LOOKUP := FiloSottile/mkcert mkcert: ## Download mkcert locally if necessary. $(call go-install-tool,$(MKCERT),filippo.io/mkcert@$(MKCERT_VERSION)) -GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint -GOLANGCI_LINT_VERSION = v1.61.0 -golangci-lint: ## Download golangci-lint locally if necessary. - $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)) - -CT := $(shell pwd)/bin/ct -CT_VERSION := v3.7.1 -ct: ## Download ct locally if necessary. - $(call go-install-tool,$(CT),github.com/helm/chart-testing/v3/ct@$(CT_VERSION)) - -KIND := $(shell pwd)/bin/kind -KIND_VERSION := v0.17.0 -kind: ## Download kind locally if necessary. +CT := $(LOCALBIN)/ct +CT_VERSION := v3.12.0 +CT_LOOKUP := helm/chart-testing +ct: + @test -s $(CT) && $(CT) version | grep -q $(CT_VERSION) || \ + $(call go-install-tool,$(CT),github.com/$(CT_LOOKUP)/v3/ct@$(CT_VERSION)) + +KIND := $(LOCALBIN)/kind +KIND_VERSION := v0.26.0 +KIND_LOOKUP := kubernetes-sigs/kind +kind: + @test -s $(KIND) && $(KIND) --version | grep -q $(KIND_VERSION) || \ $(call go-install-tool,$(KIND),sigs.k8s.io/kind/cmd/kind@$(KIND_VERSION)) -KO = $(shell pwd)/bin/ko -KO_VERSION = v0.14.1 +KO := $(LOCALBIN)/ko +KO_VERSION := v0.17.1 +KO_LOOKUP := google/ko ko: - $(call go-install-tool,$(KO),github.com/google/ko@$(KO_VERSION)) + @test -s $(KO) && $(KO) -h | grep -q $(KO_VERSION) || \ + $(call go-install-tool,$(KO),github.com/$(KO_LOOKUP)@$(KO_VERSION)) + +GOLANGCI_LINT := $(LOCALBIN)/golangci-lint +GOLANGCI_LINT_VERSION := v1.63.4 +GOLANGCI_LINT_LOOKUP := golangci/golangci-lint +golangci-lint: ## Download golangci-lint locally if necessary. + @test -s $(GOLANGCI_LINT) && $(GOLANGCI_LINT) -h | grep -q $(GOLANGCI_LINT_VERSION) || \ + $(call go-install-tool,$(GOLANGCI_LINT),github.com/$(GOLANGCI_LINT_LOOKUP)/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)) # go-install-tool will 'go install' any package $2 and install it to $1. PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) define go-install-tool -@[ -f $(1) ] || { \ -set -e ;\ -GOBIN=$(PROJECT_DIR)/bin go install $(2) ;\ +[ -f $(1) ] || { \ + set -e ;\ + GOBIN=$(LOCALBIN) go install $(2) ;\ } endef - -docker: - @hash docker 2>/dev/null || {\ - echo "You need docker" &&\ - exit 1;\ - } diff --git a/charts/capsule-proxy/.helmignore b/charts/capsule-proxy/.helmignore index 34fc69cc..1c974858 100644 --- a/charts/capsule-proxy/.helmignore +++ b/charts/capsule-proxy/.helmignore @@ -26,3 +26,4 @@ ci/ *.gotmpl .schema.yaml +artifacthub-repo.yml diff --git a/charts/capsule-proxy/README.md b/charts/capsule-proxy/README.md index 8c1fbda9..5f7351de 100644 --- a/charts/capsule-proxy/README.md +++ b/charts/capsule-proxy/README.md @@ -61,6 +61,8 @@ With the new CRD management we can release update CRDs bundled with the chart. T ## Customize the installation +> When using **OCI** we recommend our dedicated [OCI Repository]() for this chart + There are two methods for specifying overrides of values during chart installation: `--values` and `--set`. The `--values` option is the preferred method because it allows you to keep your overrides in a YAML file, rather than specifying them all on the command line. Create a copy of the YAML file `values.yaml` and add your overrides to it. diff --git a/charts/capsule-proxy/README.md.gotmpl b/charts/capsule-proxy/README.md.gotmpl index f2cbaace..e64d2265 100644 --- a/charts/capsule-proxy/README.md.gotmpl +++ b/charts/capsule-proxy/README.md.gotmpl @@ -61,6 +61,8 @@ With the new CRD management we can release update CRDs bundled with the chart. T ## Customize the installation +> When using **OCI** we recommend our dedicated [OCI Repository]() for this chart + There are two methods for specifying overrides of values during chart installation: `--values` and `--set`. The `--values` option is the preferred method because it allows you to keep your overrides in a YAML file, rather than specifying them all on the command line. Create a copy of the YAML file `values.yaml` and add your overrides to it. diff --git a/charts/capsule-proxy/artifacthub-repo.yml b/charts/capsule-proxy/artifacthub-repo.yml new file mode 100644 index 00000000..0df4d9c3 --- /dev/null +++ b/charts/capsule-proxy/artifacthub-repo.yml @@ -0,0 +1,4 @@ +repositoryID: 6f8cec74-cd77-4792-a0e7-675147fe20c3 +owners: + - name: capsule-maintainers + email: cncf-capsule-maintainers@lists.cncf.io diff --git a/charts/capsule-proxy/ci/backwards-values.yaml b/charts/capsule-proxy/ci/backwards-values.yaml index 32f562da..6b6f9e93 100644 --- a/charts/capsule-proxy/ci/backwards-values.yaml +++ b/charts/capsule-proxy/ci/backwards-values.yaml @@ -4,11 +4,12 @@ crds: global: jobs: certs: - nodeSelector: - global-field: "global-value" + resources: + limits: + memory: 128Mi + cpu: 0.125 jobs: - certs: - registry: custom-registry - repository: jettech/kube-webhook-certgen - pullPolicy: IfNotPresent - tag: "v1.5.2" + resources: + requests: + memory: 128Mi + cpu: 0.125 diff --git a/charts/capsule-proxy/templates/certgen-job.yaml b/charts/capsule-proxy/templates/certgen-job.yaml index d7239479..7343dbb8 100644 --- a/charts/capsule-proxy/templates/certgen-job.yaml +++ b/charts/capsule-proxy/templates/certgen-job.yaml @@ -1,14 +1,14 @@ {{/* Backwards compatibility */}} {{- $Values := mergeOverwrite $.Values.global.jobs.certs $.Values.jobs -}} -{{- if and .Values.options.enableSSL .Values.options.generateCertificates (not .Values.certManager.generateCertificates) -}} +{{- if and .Values.options.enableSSL .Values.options.generateCertificates -}} apiVersion: batch/v1 kind: Job metadata: name: {{ include "capsule-proxy.fullname" . }}-certgen labels: {{- include "capsule-proxy.labels" . | nindent 4 }} - {{- with .Values.global.jobs.annotations }} + {{- with $Values.annotations }} annotations: {{- toYaml . | nindent 4 }} {{- end }} @@ -40,7 +40,7 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} {{- with $Values.topologySpreadConstraints }} - topologySpreadConstraints: + topologySpreadConstraints: {{- toYaml . | nindent 8 }} {{- end }} {{- with $Values.priorityClassName }} @@ -73,6 +73,6 @@ spec: {{- with $.Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} - {{- end }} + {{- end }} serviceAccountName: {{ include "capsule-proxy.serviceAccountName" . }} {{- end }} diff --git a/charts/capsule-proxy/templates/crd-lifecycle/_helpers.tpl b/charts/capsule-proxy/templates/crd-lifecycle/_helpers.tpl index fb23aaf5..fece8c6e 100644 --- a/charts/capsule-proxy/templates/crd-lifecycle/_helpers.tpl +++ b/charts/capsule-proxy/templates/crd-lifecycle/_helpers.tpl @@ -4,6 +4,7 @@ {{- define "capsule-proxy.crds.annotations" -}} "helm.sh/hook": "pre-install,pre-upgrade" +"helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" {{- with $.Values.global.jobs.annotations }} {{- . | toYaml | nindent 0 }} {{- end }} @@ -15,4 +16,4 @@ crd-install-hook {{- define "capsule-proxy.crds.regexReplace" -}} {{- printf "%s" ($ | base | trimSuffix ".yaml" | regexReplaceAll "[_.]" "-") -}} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/charts/capsule-proxy/templates/crd-lifecycle/job.yaml b/charts/capsule-proxy/templates/crd-lifecycle/job.yaml index 66d7f489..c4549ac8 100644 --- a/charts/capsule-proxy/templates/crd-lifecycle/job.yaml +++ b/charts/capsule-proxy/templates/crd-lifecycle/job.yaml @@ -5,7 +5,6 @@ metadata: name: {{ include "capsule-proxy.crds.name" . }} namespace: {{ .Release.Namespace | quote }} annotations: - # create hook dependencies in the right order "helm.sh/hook-weight": "-1" {{- include "capsule-proxy.crds.annotations" . | nindent 4 }} labels: @@ -40,7 +39,7 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.global.jobs.kubectl.topologySpreadConstraints }} - topologySpreadConstraints: + topologySpreadConstraints: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.global.jobs.kubectl.priorityClassName }} @@ -49,7 +48,7 @@ spec: {{- with .Values.global.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} - {{- end }} + {{- end }} serviceAccountName: {{ include "capsule-proxy.crds.name" . }} containers: - name: crds-hook @@ -92,4 +91,4 @@ spec: {{- end }} {{- end }} backoffLimit: 4 -{{- end }} \ No newline at end of file +{{- end }} diff --git a/charts/capsule-proxy/values.schema.json b/charts/capsule-proxy/values.schema.json index 6b9ab826..b423f54e 100644 --- a/charts/capsule-proxy/values.schema.json +++ b/charts/capsule-proxy/values.schema.json @@ -239,10 +239,18 @@ "properties": { "certs": { "properties": { - "nodeSelector": { + "resources": { "properties": { - "global-field": { - "type": "string" + "limits": { + "properties": { + "cpu": { + "type": "number" + }, + "memory": { + "type": "string" + } + }, + "type": "object" } }, "type": "object" @@ -376,23 +384,6 @@ }, "type": "object" }, - "certs": { - "properties": { - "pullPolicy": { - "type": "string" - }, - "registry": { - "type": "string" - }, - "repository": { - "type": "string" - }, - "tag": { - "type": "string" - } - }, - "type": "object" - }, "nodeSelector": { "properties": { "node-role.kubernetes.io/master": { @@ -404,6 +395,22 @@ "priorityClassName": { "type": "string" }, + "resources": { + "properties": { + "requests": { + "properties": { + "cpu": { + "type": "number" + }, + "memory": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, "tolerations": { "items": { "properties": { diff --git a/e2e/distro/flux/kustomization.yaml b/e2e/distro/flux/kustomization.yaml new file mode 100644 index 00000000..8a8c2444 --- /dev/null +++ b/e2e/distro/flux/kustomization.yaml @@ -0,0 +1,33 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - https://github.com/fluxcd/flux2/releases/download/v2.4.0/install.yaml +patches: + - patch: | + - op: add + path: /spec/template/spec/containers/0/args/- + value: --no-cross-namespace-refs=true + target: + kind: Deployment + name: "(kustomize-controller|helm-controller|notification-controller|image-reflector-controller|image-automation-controller)" + - patch: | + - op: add + path: /spec/template/spec/containers/0/args/- + value: --no-remote-bases=true + target: + kind: Deployment + name: "kustomize-controller" + - patch: | + - op: add + path: /spec/template/spec/containers/0/args/- + value: --default-service-account=default + target: + kind: Deployment + name: "(kustomize-controller|helm-controller)" + - patch: | + - op: replace + path: /spec/replicas + value: 0 + target: + kind: Deployment + name: "(notification-controller|image-reflector-controller|image-automation-controller)" diff --git a/e2e/distro/objects/capsule.flux.yaml b/e2e/distro/objects/capsule.flux.yaml new file mode 100644 index 00000000..15380233 --- /dev/null +++ b/e2e/distro/objects/capsule.flux.yaml @@ -0,0 +1,44 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: projectcapsule +spec: + interval: 30s + url: https://projectcapsule.github.io/charts +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: capsule +spec: + serviceAccountName: kustomize-controller + interval: 30s + targetNamespace: capsule-system + releaseName: "capsule" + chart: + spec: + chart: capsule + version: "0.7.2" + sourceRef: + kind: HelmRepository + name: projectcapsule + interval: 24h + install: + createNamespace: true + remediation: + retries: -1 + upgrade: + remediation: + remediateLastFailure: true + driftDetection: + mode: enabled + values: + crds: + install: true + manager: + resources: null + options: + forceTenantPrefix: false + options: + logLevel: 8 diff --git a/e2e/distro/objects/cert-manager.flux.yaml b/e2e/distro/objects/cert-manager.flux.yaml new file mode 100644 index 00000000..8899d7b0 --- /dev/null +++ b/e2e/distro/objects/cert-manager.flux.yaml @@ -0,0 +1,38 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: cert-manager + namespace: flux-system +spec: + interval: 30s + url: https://charts.jetstack.io +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: cert-manager +spec: + serviceAccountName: kustomize-controller + interval: 30s + releaseName: "cert-manager" + targetNamespace: "cert-manager" + chart: + spec: + chart: cert-manager + version: "1.15.3" + sourceRef: + kind: HelmRepository + name: cert-manager + interval: 24h + install: + createNamespace: true + upgrade: + remediation: + remediateLastFailure: true + retries: -1 + driftDetection: + mode: enabled + values: + crds: + enabled: true diff --git a/e2e/distro/objects/kustomization.yaml b/e2e/distro/objects/kustomization.yaml new file mode 100644 index 00000000..139b1926 --- /dev/null +++ b/e2e/distro/objects/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: flux-system +resources: + - https://github.com/prometheus-operator/prometheus-operator/releases/download/v0.58.0/bundle.yaml + - cert-manager.flux.yaml + - capsule.flux.yaml + - metrics.flux.yaml diff --git a/e2e/distro/objects/metrics.flux.yaml b/e2e/distro/objects/metrics.flux.yaml new file mode 100644 index 00000000..50409c83 --- /dev/null +++ b/e2e/distro/objects/metrics.flux.yaml @@ -0,0 +1,38 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: metrics-server +spec: + interval: 30s + url: https://kubernetes-sigs.github.io/metrics-server/ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: metrics-server +spec: + serviceAccountName: kustomize-controller + interval: 1m + releaseName: "metrics-server" + targetNamespace: "kube-system" + chart: + spec: + chart: metrics-server + version: "3.12.2" + sourceRef: + kind: HelmRepository + name: metrics-server + interval: 24h + install: + createNamespace: false + remediation: + retries: -1 + upgrade: + remediation: + remediateLastFailure: true + driftDetection: + mode: enabled + values: + args: + - --kubelet-insecure-tls diff --git a/renovate.json b/renovate.json index 9b0244eb..61b1fd1c 100644 --- a/renovate.json +++ b/renovate.json @@ -21,5 +21,29 @@ "groupName": "all-ci-updates", "updateTypes": ["major", "minor", "patch"] } + ], + "customManagers": [ + { + "customType": "regex", + "fileMatch": ["^Makefile$"], + "matchStrings": [ + "(?[A-Z0-9_]+)_VERSION\\s*[:=?]+\\s*\"?(?[^\"\\r\\n]+)\"?[\\s\\S]*?(?[A-Z0-9_]+)_LOOKUP\\s*[:=?]+\\s*\"?(?[^\"\\r\\n]+)\"?(?:[\\s\\S]*?(?[A-Z0-9_]+)_SOURCE\\s*[:=?]+\\s*\"?(?[^\"\\r\\n]+)\"?)?" + ], + "depNameTemplate": "{{lookupValue}}", + "datasourceTemplate": "{{#sourceValue}}{{sourceValue}}{{/sourceValue}}{{^sourceValue}}github-tags{{/sourceValue}}", + "lookupNameTemplate": "{{lookupValue}}", + "versioningTemplate": "semver" + }, + { + "customType": "regex", + "fileMatch": [".*\\.pre-commit-config\\.ya?ml$"], + "matchStrings": [ + "repo:\\s*https://github\\.com/(?[^/]+/[^\\s]+)[\\s\\S]*?rev:\\s*(?v?\\d+\\.\\d+\\.\\d+)" + ], + "depNameTemplate": "{{lookupValue}}", + "datasourceTemplate": "github-tags", + "lookupNameTemplate": "{{lookupValue}}", + "versioningTemplate": "semver" + } ] } From 50b0ff44a48dcc7bdde19e1c849ab84c0eb73bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20B=C3=A4hler?= Date: Fri, 7 Feb 2025 08:36:40 +0100 Subject: [PATCH 4/7] ci(helm): update workflows and correct testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oliver Bähler --- .github/ISSUE_TEMPLATE/config.yaml | 2 +- .github/actions/exists/action.yaml | 2 +- .github/actions/setup-caches/action.yaml | 2 +- .github/configs/ct.yaml | 4 +- .github/workflows/helm-publish.yml | 2 +- .github/workflows/scorecard.yml | 2 +- .golangci.yml | 2 - .ko.yaml | 2 +- api/v1beta1/zz_generated.deepcopy.go | 1 - ...apsule.clastix.io_globalproxysettings.yaml | 80 +++++++++---------- .../capsule.clastix.io_proxysettings.yaml | 70 ++++++++-------- e2e/kind.yaml | 6 +- 12 files changed, 82 insertions(+), 93 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yaml b/.github/ISSUE_TEMPLATE/config.yaml index b96db624..55ab0366 100644 --- a/.github/ISSUE_TEMPLATE/config.yaml +++ b/.github/ISSUE_TEMPLATE/config.yaml @@ -2,4 +2,4 @@ blank_issues_enabled: false contact_links: - name: Chat on Slack url: https://kubernetes.slack.com/archives/C03GETTJQRL - about: Maybe chatting with the community can help \ No newline at end of file + about: Maybe chatting with the community can help diff --git a/.github/actions/exists/action.yaml b/.github/actions/exists/action.yaml index 7f9c6ddc..4f11f556 100644 --- a/.github/actions/exists/action.yaml +++ b/.github/actions/exists/action.yaml @@ -18,4 +18,4 @@ runs: - shell: bash id: check run: | - echo "result=${{ inputs.value != '' }}" >> $GITHUB_OUTPUT \ No newline at end of file + echo "result=${{ inputs.value != '' }}" >> $GITHUB_OUTPUT diff --git a/.github/actions/setup-caches/action.yaml b/.github/actions/setup-caches/action.yaml index c1237b98..8138123a 100644 --- a/.github/actions/setup-caches/action.yaml +++ b/.github/actions/setup-caches/action.yaml @@ -17,4 +17,4 @@ runs: if: ${{ inputs.build-cache-key }} with: path: ~/.cache/go-build - key: ${{ runner.os }}-build-cache-${{ inputs.build-cache-key }}-${{ hashFiles('**/go.sum') }}-${{ hashFiles('Makefile') }} \ No newline at end of file + key: ${{ runner.os }}-build-cache-${{ inputs.build-cache-key }}-${{ hashFiles('**/go.sum') }}-${{ hashFiles('Makefile') }} diff --git a/.github/configs/ct.yaml b/.github/configs/ct.yaml index a7987184..7ea51e8e 100644 --- a/.github/configs/ct.yaml +++ b/.github/configs/ct.yaml @@ -2,9 +2,9 @@ remote: origin target-branch: main chart-dirs: - charts -helm-extra-args: "--timeout 600s" +helm-extra-args: "--timeout 600s" validate-chart-schema: false validate-maintainers: false validate-yaml: true exclude-deprecated: true -check-version-increment: false \ No newline at end of file +check-version-increment: false diff --git a/.github/workflows/helm-publish.yml b/.github/workflows/helm-publish.yml index c9f5796a..2c318340 100644 --- a/.github/workflows/helm-publish.yml +++ b/.github/workflows/helm-publish.yml @@ -54,7 +54,7 @@ jobs: echo "version=$(echo $VERSION)" >> $GITHUB_OUTPUT - name: Helm | Publish id: helm_publish - uses: peak-scale/github-actions/helm-oci-chart@a441cca016861c546ab7e065277e40ce41a3eb84 + uses: peak-scale/github-actions/helm-oci-chart@a441cca016861c546ab7e065277e40ce41a3eb84 with: registry: ghcr.io repository: ${{ github.repository_owner }}/charts diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 954f2e27..de6a8470 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -39,4 +39,4 @@ jobs: - name: Upload to code-scanning uses: github/codeql-action/upload-sarif@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 with: - sarif_file: results.sarif \ No newline at end of file + sarif_file: results.sarif diff --git a/.golangci.yml b/.golangci.yml index bcbab8f0..c58dda9c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -20,8 +20,6 @@ issues: linters: enable-all: true disable: - - err113 - - mnd - errchkjson - errname - forcetypeassert diff --git a/.ko.yaml b/.ko.yaml index 2b17d863..5252c42d 100644 --- a/.ko.yaml +++ b/.ko.yaml @@ -6,4 +6,4 @@ builds: - id: capsule-proxy main: ./ ldflags: - - '{{ if index .Env "LD_FLAGS" }}{{ .Env.LD_FLAGS }}{{ end }}' \ No newline at end of file + - '{{ if index .Env "LD_FLAGS" }}{{ .Env.LD_FLAGS }}{{ end }}' diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index c209456b..a4ff3773 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated // Copyright 2020-2023 Project Capsule Authors. // SPDX-License-Identifier: Apache-2.0 diff --git a/charts/capsule-proxy/crds/capsule.clastix.io_globalproxysettings.yaml b/charts/capsule-proxy/crds/capsule.clastix.io_globalproxysettings.yaml index f21c92fb..8c0f7898 100644 --- a/charts/capsule-proxy/crds/capsule.clastix.io_globalproxysettings.yaml +++ b/charts/capsule-proxy/crds/capsule.clastix.io_globalproxysettings.yaml @@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.16.3 name: globalproxysettings.capsule.clastix.io spec: group: capsule.clastix.io @@ -22,14 +21,19 @@ spec: API. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -37,10 +41,10 @@ spec: description: GlobalProxySettingsSpec defines the desired state of GlobalProxySettings. properties: rules: - description: Subjects that should receive additional permissions. - The subjects are selected based on the oncoming requests. They don't - have to relate to an existing tenant. However they must be part - of the capsule-user groups. + description: |- + Subjects that should receive additional permissions. + The subjects are selected based on the oncoming requests. They don't have to relate to an existing tenant. + However they must be part of the capsule-user groups. items: properties: clusterResources: @@ -75,17 +79,16 @@ spec: type: string type: array selector: - description: Select all cluster scoped resources with - the given label selector. Defining a selector which - does not match any resources is considered not selectable - (eg. using operation NotExists). + description: |- + Select all cluster scoped resources with the given label selector. + Defining a selector which does not match any resources is considered not selectable (eg. using operation NotExists). properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -93,17 +96,16 @@ spec: applies to. type: string operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -117,13 +119,13 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + x-kubernetes-map-type: atomic required: - apiGroups - operations @@ -132,10 +134,10 @@ spec: type: object type: array subjects: - description: Subjects that should receive additional permissions. - The subjects are selected based on the oncoming requests. - They don't have to relate to an existing tenant. However they - must be part of the capsule-user groups. + description: |- + Subjects that should receive additional permissions. + The subjects are selected based on the oncoming requests. They don't have to relate to an existing tenant. + However they must be part of the capsule-user groups. items: properties: kind: @@ -167,9 +169,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/charts/capsule-proxy/crds/capsule.clastix.io_proxysettings.yaml b/charts/capsule-proxy/crds/capsule.clastix.io_proxysettings.yaml index 37ef8895..bed0c7e5 100644 --- a/charts/capsule-proxy/crds/capsule.clastix.io_proxysettings.yaml +++ b/charts/capsule-proxy/crds/capsule.clastix.io_proxysettings.yaml @@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.16.3 name: proxysettings.capsule.clastix.io spec: group: capsule.clastix.io @@ -21,21 +20,26 @@ spec: description: ProxySetting is the Schema for the proxysettings API. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object spec: - description: ProxySettingSpec defines the additional Capsule Proxy settings - for additional users of the Tenant. Resource is Namespace-scoped and - applies the settings to the belonged Tenant. + description: |- + ProxySettingSpec defines the additional Capsule Proxy settings for additional users of the Tenant. + Resource is Namespace-scoped and applies the settings to the belonged Tenant. properties: subjects: description: Subjects that should receive additional permissions. @@ -73,17 +77,16 @@ spec: type: string type: array selector: - description: Select all cluster scoped resources with - the given label selector. Defining a selector which - does not match any resources is considered not selectable - (eg. using operation NotExists). + description: |- + Select all cluster scoped resources with the given label selector. + Defining a selector which does not match any resources is considered not selectable (eg. using operation NotExists). properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. properties: key: @@ -91,17 +94,16 @@ spec: applies to. type: string operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. type: string values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. items: type: string type: array @@ -115,13 +117,13 @@ spec: matchLabels: additionalProperties: type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. type: object type: object + x-kubernetes-map-type: atomic required: - apiGroups - operations @@ -178,9 +180,3 @@ spec: type: object served: true storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/e2e/kind.yaml b/e2e/kind.yaml index 075bea13..68456f3b 100644 --- a/e2e/kind.yaml +++ b/e2e/kind.yaml @@ -1,8 +1,8 @@ apiVersion: kind.x-k8s.io/v1alpha4 kind: Cluster -#networking: -# apiServerAddress: "127.0.0.1" -# apiServerPort: 6443 +# networking: +# apiServerAddress: "127.0.0.1" +# apiServerPort: 6443 nodes: - role: control-plane - role: worker From cf01b6c5440d085f7526326759264807c8feb50c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20B=C3=A4hler?= Date: Fri, 7 Feb 2025 08:47:59 +0100 Subject: [PATCH 5/7] ci(helm): update workflows and correct testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oliver Bähler --- .github/workflows/lint.yaml | 6 +----- Makefile | 8 ++++++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 23f6fe99..954569f7 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -49,8 +49,4 @@ jobs: with: go-version-file: 'go.mod' - name: Run golangci-lint - uses: golangci/golangci-lint-action@e60da84bfae8c7920a47be973d75e15710aa8bd7 # v6.3.0 - with: - version: v1.56.2 - only-new-issues: false - args: --timeout 5m --config .golangci.yml + run: make golint diff --git a/Makefile b/Makefile index b03a16e1..93da4792 100644 --- a/Makefile +++ b/Makefile @@ -246,6 +246,14 @@ rbac-fix: @kubectl create clusterrolebinding capsule:selfsubjectaccessreviews --clusterrole=capsule-selfsubjectaccessreviews --group=capsule.clastix.io @kubectl create clusterrolebinding capsule:apis --clusterrole=capsule-apis --group=capsule.clastix.io +# Run tests +.PHONY: test +test: test-clean generate manifests test-clean + @GO111MODULE=on go test -v ./... -coverprofile coverage.out + +.PHONY: test-clean +test-clean: ## Clean tests cache + @go clean -testcache .PHONY: manifests manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. From 853af993a65a458f36566941d2ddb8fa7e79553d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20B=C3=A4hler?= Date: Fri, 7 Feb 2025 10:44:15 +0100 Subject: [PATCH 6/7] ci(test): fix helm testing and golint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oliver Bähler --- .golangci.yml | 70 +++++++++++-------- Makefile | 2 +- internal/controllers/role_bindings.go | 17 +++-- internal/controllers/watchdog/crds_watcher.go | 1 + .../watchdog/namespaced_watcher.go | 4 +- internal/indexer/global_proxy_setting.go | 1 + internal/indexer/proxy_setting.go | 1 + internal/modules/errors/bad_request.go | 1 + internal/modules/ingressclass/utils.go | 2 +- internal/modules/lease/get.go | 1 + internal/modules/pod/get.go | 1 + internal/modules/priorityclass/utils.go | 2 +- internal/modules/storageclass/utils.go | 2 +- internal/request/error.go | 1 + internal/webserver/errors/panic.go | 2 + internal/webserver/middleware/jwt.go | 1 + .../webserver/middleware/user_in_group.go | 1 + internal/webserver/webserver.go | 8 ++- main.go | 2 +- 19 files changed, 80 insertions(+), 40 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index c58dda9c..cce4ac23 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,42 +1,56 @@ linters-settings: - gci: - sections: - - standard - - default - - prefix(github.com/projectcapsule/capsule-proxy) dupl: threshold: 100 goconst: min-len: 2 min-occurrences: 2 cyclop: - max-complexity: 17 -issues: - exclude-rules: - - path: (.+)_test.go - linters: - - revive - text: "^(dot-imports)" + max-complexity: 27 + gocognit: + min-complexity: 50 + gci: + sections: + - standard + - default + - prefix(github.com/projectcapsule/capsule-proxy) + gofumpt: + module-path: github.com/projectcapsule/capsule-proxy + extra-rules: false + inamedparam: + # Skips check for interface methods with only a single parameter. + # Default: false + skip-single-param: true + nakedret: + # Make an issue if func has more lines of code than this setting, and it has naked returns. + max-func-lines: 50 linters: enable-all: true disable: - - errchkjson - - errname - - forcetypeassert + - err113 + - depguard + - perfsprint + - funlen + - gochecknoinits + - lll + - gochecknoglobals + - mnd + - nilnil + - recvcheck + - unparam + - paralleltest - ireturn + - testpackage - varnamelen - wrapcheck - - gomnd - - lll - - nonamedreturns - - tparallel - - nilerr - exhaustruct - - depguard - - revive - - nilnil - - wsl - - perfsprint - - exportloopref - - execinquery - - forcetypeassert + - nonamedreturns +issues: + exclude-files: + - "zz_.*\\.go$" + - ".+\\.generated.go" + - ".+_test.go" + - ".+_test_.+.go" +run: + timeout: 3m + allow-parallel-runners: true + tests: false diff --git a/Makefile b/Makefile index 93da4792..c1d05aad 100644 --- a/Makefile +++ b/Makefile @@ -249,7 +249,7 @@ rbac-fix: # Run tests .PHONY: test test: test-clean generate manifests test-clean - @GO111MODULE=on go test -v ./... -coverprofile coverage.out + @GO111MODULE=on go test -v $(go list ./... | grep -v /e2e/) -coverprofile coverage.out .PHONY: test-clean test-clean: ## Clean tests cache diff --git a/internal/controllers/role_bindings.go b/internal/controllers/role_bindings.go index 5c012833..65f7818d 100644 --- a/internal/controllers/role_bindings.go +++ b/internal/controllers/role_bindings.go @@ -75,8 +75,12 @@ func (r *RoleBindingReflector) GetUserNamespacesFromRequest(req request.Request) } for _, rb := range userRoleBindings { - rb := rb.(*rbacv1.RoleBinding) - namespaces.Insert(rb.GetNamespace()) + rbt, ok := rb.(*rbacv1.RoleBinding) + if !ok { + return nil, fmt.Errorf("expected *rbacv1.RoleBinding but got %T", rb) + } + + namespaces.Insert(rbt.GetNamespace()) } for _, group := range groups { @@ -86,8 +90,12 @@ func (r *RoleBindingReflector) GetUserNamespacesFromRequest(req request.Request) } for _, rb := range groupRoleBindings { - rb := rb.(*rbacv1.RoleBinding) - namespaces.Insert(rb.GetNamespace()) + rbt, ok := rb.(*rbacv1.RoleBinding) + if !ok { + return nil, fmt.Errorf("expected *rbacv1.RoleBinding but got %T", rb) + } + + namespaces.Insert(rbt.GetNamespace()) } } @@ -101,6 +109,7 @@ func (r *RoleBindingReflector) Start(ctx context.Context) error { } func OwnerRoleBindingsIndexFunc(obj interface{}) (result []string, err error) { + //nolint:forcetypeassert rb := obj.(*rbacv1.RoleBinding) for _, subject := range rb.Subjects { diff --git a/internal/controllers/watchdog/crds_watcher.go b/internal/controllers/watchdog/crds_watcher.go index 2aecde5a..301d3794 100644 --- a/internal/controllers/watchdog/crds_watcher.go +++ b/internal/controllers/watchdog/crds_watcher.go @@ -163,6 +163,7 @@ func (c *CRDWatcher) SetupWithManager(ctx context.Context, mgr manager.Manager) return ctrl.NewControllerManagedBy(mgr). WatchesRawSource(source.Channel(c.requeue, &handler.EnqueueRequestForObject{})). For(&apiextensionsv1.CustomResourceDefinition{}, builder.WithPredicates(predicate.NewPredicateFuncs(func(object client.Object) bool { + //nolint:forcetypeassert crd := object.(*apiextensionsv1.CustomResourceDefinition) return crd.Spec.Scope == apiextensionsv1.NamespaceScoped diff --git a/internal/controllers/watchdog/namespaced_watcher.go b/internal/controllers/watchdog/namespaced_watcher.go index 4c5f2099..c2c6ce05 100644 --- a/internal/controllers/watchdog/namespaced_watcher.go +++ b/internal/controllers/watchdog/namespaced_watcher.go @@ -117,11 +117,11 @@ func (c *NamespacedWatcher) SetupWithManager(mgr manager.Manager, gvk metav1.Gro return false }, - DeleteFunc: func(e event.DeleteEvent) bool { + DeleteFunc: func(_ event.DeleteEvent) bool { // Ignore delete events return false }, - GenericFunc: func(e event.GenericEvent) bool { + GenericFunc: func(_ event.GenericEvent) bool { // Ignore generic events return false }, diff --git a/internal/indexer/global_proxy_setting.go b/internal/indexer/global_proxy_setting.go index 41c8d30d..88daa16e 100644 --- a/internal/indexer/global_proxy_setting.go +++ b/internal/indexer/global_proxy_setting.go @@ -29,6 +29,7 @@ func (p GlobalProxySetting) Field() string { func (p GlobalProxySetting) Func() client.IndexerFunc { return func(object client.Object) (owners []string) { + //nolint:forcetypeassert proxySetting := object.(*v1beta1.GlobalProxySettings) for _, owner := range proxySetting.Spec.Rules { diff --git a/internal/indexer/proxy_setting.go b/internal/indexer/proxy_setting.go index 93c85fbe..324435d2 100644 --- a/internal/indexer/proxy_setting.go +++ b/internal/indexer/proxy_setting.go @@ -29,6 +29,7 @@ func (p ProxySetting) Field() string { func (p ProxySetting) Func() client.IndexerFunc { return func(object client.Object) (owners []string) { + //nolint:forcetypeassert proxySetting := object.(*v1beta1.ProxySetting) for _, owner := range proxySetting.Spec.Subjects { diff --git a/internal/modules/errors/bad_request.go b/internal/modules/errors/bad_request.go index 916e4d3c..cfc97143 100644 --- a/internal/modules/errors/bad_request.go +++ b/internal/modules/errors/bad_request.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) +//nolint:errname type badRequest struct { message string details *metav1.StatusDetails diff --git a/internal/modules/ingressclass/utils.go b/internal/modules/ingressclass/utils.go index 7a51d121..90d44afb 100644 --- a/internal/modules/ingressclass/utils.go +++ b/internal/modules/ingressclass/utils.go @@ -62,7 +62,7 @@ func getIngressClasses(request *http.Request, proxyTenants []*tenant.ProxyTenant requirements = append(requirements, reqs...) } - sort.SliceStable(exact, func(i, j int) bool { + sort.SliceStable(exact, func(i, _ int) bool { return exact[i] < exact[0] }) diff --git a/internal/modules/lease/get.go b/internal/modules/lease/get.go index bad0684e..ae225f3f 100644 --- a/internal/modules/lease/get.go +++ b/internal/modules/lease/get.go @@ -67,6 +67,7 @@ func (g get) Handle(proxyTenants []*tenant.ProxyTenant, proxyRequest request.Req name := mux.Vars(httpRequest)["name"] node := &corev1.Node{} + //nolint:nilerr if err = g.client.Get(httpRequest.Context(), types.NamespacedName{Name: name}, node); err != nil { // offload failure to Kubernetes API due to missing RBAC return nil, nil diff --git a/internal/modules/pod/get.go b/internal/modules/pod/get.go index 2ffba10c..a2541dcf 100644 --- a/internal/modules/pod/get.go +++ b/internal/modules/pod/get.go @@ -67,6 +67,7 @@ func (g get) Handle(proxyTenants []*tenant.ProxyTenant, proxyRequest request.Req var fieldSelector labels.Selector + //nolint:nilerr if fieldSelector, err = labels.Parse(rawFieldSelector[0]); err != nil { // not valid labels, offloading Kubernetes to deal with the failure return nil, nil diff --git a/internal/modules/priorityclass/utils.go b/internal/modules/priorityclass/utils.go index 0763b7cf..b5faa62d 100644 --- a/internal/modules/priorityclass/utils.go +++ b/internal/modules/priorityclass/utils.go @@ -59,7 +59,7 @@ func getPriorityClass(req *http.Request, proxyTenants []*tenant.ProxyTenant) (al requirements = append(requirements, reqs...) } - sort.SliceStable(exact, func(i, j int) bool { + sort.SliceStable(exact, func(i, _ int) bool { return exact[i] < exact[0] }) diff --git a/internal/modules/storageclass/utils.go b/internal/modules/storageclass/utils.go index ba3b0bf9..09102abf 100644 --- a/internal/modules/storageclass/utils.go +++ b/internal/modules/storageclass/utils.go @@ -59,7 +59,7 @@ func getStorageClasses(req *http.Request, proxyTenants []*tenant.ProxyTenant) (a requirements = append(requirements, reqs...) } - sort.SliceStable(exact, func(i, j int) bool { + sort.SliceStable(exact, func(i, _ int) bool { return exact[i] < exact[0] }) diff --git a/internal/request/error.go b/internal/request/error.go index b8d2610d..d783e6db 100644 --- a/internal/request/error.go +++ b/internal/request/error.go @@ -3,6 +3,7 @@ package request +//nolint:errname type ErrUnauthorized struct { message string } diff --git a/internal/webserver/errors/panic.go b/internal/webserver/errors/panic.go index 5abacc4d..0b53a445 100644 --- a/internal/webserver/errors/panic.go +++ b/internal/webserver/errors/panic.go @@ -26,6 +26,7 @@ func HandleUnauthorized(w http.ResponseWriter, err error, message string) { w.Header().Set("content-type", "application/json") + //nolint:errchkjson b, _ := json.Marshal(status) _, _ = w.Write(b) @@ -45,6 +46,7 @@ func HandleError(w http.ResponseWriter, err error, message string) { w.Header().Set("content-type", "application/json") + //nolint:errchkjson b, _ := json.Marshal(status) _, _ = w.Write(b) diff --git a/internal/webserver/middleware/jwt.go b/internal/webserver/middleware/jwt.go index 9f4f32fe..ce8b9fcd 100644 --- a/internal/webserver/middleware/jwt.go +++ b/internal/webserver/middleware/jwt.go @@ -40,6 +40,7 @@ func CheckJWTMiddleware(client client.Writer) mux.MiddlewareFunc { if err = client.Create(request.Context(), &tr); err != nil { errors.HandleError(writer, err, "cannot create TokenReview") } + if statusErr := tr.Status.Error; len(statusErr) > 0 { invalidatedToken.Insert(token) diff --git a/internal/webserver/middleware/user_in_group.go b/internal/webserver/middleware/user_in_group.go index 5d9d6c30..e4c3adee 100644 --- a/internal/webserver/middleware/user_in_group.go +++ b/internal/webserver/middleware/user_in_group.go @@ -47,6 +47,7 @@ func CheckUserInCapsuleGroupMiddleware(client client.Writer, log logr.Logger, cl if err != nil { log.Error(err, "Cannot retrieve username and group from request") } + log.V(10).Info("request groups", "groups", groups) for _, group := range groups { diff --git a/internal/webserver/webserver.go b/internal/webserver/webserver.go index e4d20a75..b6b3351d 100644 --- a/internal/webserver/webserver.go +++ b/internal/webserver/webserver.go @@ -300,10 +300,12 @@ func (n *kubeFilter) registerModules(ctx context.Context, root *mux.Router) { ) sr.HandleFunc("", func(writer http.ResponseWriter, request *http.Request) { proxyRequest := req.NewHTTP(request, n.authTypes, n.usernameClaimField, n.writer, n.ignoredImpersonationGroups, n.impersonationGroupsRegexp, n.skipImpersonationReview) + username, groups, err := proxyRequest.GetUserAndGroups() if err != nil { server.HandleError(writer, err, "cannot retrieve user and group from the request") } + proxyTenants, err := n.getTenantsForOwner(ctx, username, groups) if err != nil { server.HandleError(writer, err, "cannot list Tenant resources") @@ -311,15 +313,19 @@ func (n *kubeFilter) registerModules(ctx context.Context, root *mux.Router) { var selector labels.Selector selector, err = mod.Handle(proxyTenants, proxyRequest) + switch { case err != nil: var t moderrors.Error if errors.As(err, &t) { writer.Header().Set("Content-Type", "application/json") + b, _ := json.Marshal(t.Status()) _, _ = writer.Write(b) + panic(err.Error()) } + server.HandleError(writer, err, err.Error()) case selector == nil: // if there's no selector, let it pass to the @@ -336,7 +342,7 @@ func (n *kubeFilter) Start(ctx context.Context) error { r := mux.NewRouter() r.Use(handlers.RecoveryHandler()) - r.Path("/_healthz").Subrouter().HandleFunc("", func(writer http.ResponseWriter, request *http.Request) { + r.Path("/_healthz").Subrouter().HandleFunc("", func(writer http.ResponseWriter, _ *http.Request) { writer.WriteHeader(http.StatusOK) _, _ = writer.Write([]byte("ok")) }) diff --git a/main.go b/main.go index 6831e9f6..76046fe2 100644 --- a/main.go +++ b/main.go @@ -46,7 +46,7 @@ const ( WebhookLabler ) -//nolint:funlen,gocyclo,cyclop,maintidx,gocognit +//nolint:funlen,gocyclo,cyclop,maintidx func main() { scheme := runtime.NewScheme() log := ctrl.Log.WithName("main") From 3825a8ce75466be9046b1f142b99fe3ef2bf79dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20B=C3=A4hler?= Date: Fri, 7 Feb 2025 13:41:30 +0100 Subject: [PATCH 7/7] ci(test): fix helm testing and golint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oliver Bähler --- .github/workflows/coverage.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 59ed58b1..30ce024b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -79,6 +79,8 @@ jobs: if: ${{ steps.checksecret.outputs.result == 'true' }} uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1 with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: projectcapsule/capsule-proxy files: ./coverage.out fail_ci_if_error: true verbose: true