diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml new file mode 100644 index 0000000..5956f3a --- /dev/null +++ b/.github/workflows/release-artifacts.yml @@ -0,0 +1,150 @@ +name: Release Artifacts +run-name: 'Release run by ${{ github.actor }}' + +on: + # Release unstable from HEAD on every merge + push: + branches: + - main + + # Run manually to release unstable from HEAD + workflow_dispatch: + + # Official stable versioned release + release: + types: + - published + +permissions: + contents: read + +jobs: + build-push-image: + name: 'Build and publish protect-${{ matrix.component }} images' + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + component: + - webhook + permissions: + contents: read + packages: write + steps: + - name: 'Harden runner' + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 + with: + egress-policy: audit + + - name: 'Checkout repository' + uses: actions/checkout@6b42224f41ee5dfe5395e27c8b2746f1f9955030 # v4.2.0 + with: + submodules: recursive + persist-credentials: false + + - name: 'Setup docker buildx' + uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1 + + - name: 'Login to ghcr' + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + with: + registry: ghcr.io + username: '${{ github.actor }}' + password: '${{ github.token }}' + + - name: Docker meta + uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 + id: meta + with: + images: | + ghcr.io/edera-dev/protect-${{ matrix.component }} + tags: | + # Tag with branch on push + type=ref,event=branch + + # Tag with short sha on all events + type=sha,prefix= + + # Tag version and stable on tag push + type=semver,pattern={{raw}} + type=semver,pattern={{version}} + type=semver,pattern={{major}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern=stable + + # Tag nightly on schedule event + type=schedule,pattern=nightly + + - name: 'Docker build and push protect-${{ inputs.component }}' + uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0 + id: push + with: + file: Dockerfile + platforms: linux/amd64 + tags: '${{ steps.meta.outputs.tags }}' + push: true + + - name: 'Install cosign' + uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3.6.0 + + - name: 'Cosign sign all images' + shell: bash + run: | + for tag in $(echo '${{ steps.meta.outputs.tags }}'); do + pullstring="${tag}@${DIGEST}" + echo "Signing ${pullstring}" + cosign sign --yes "${pullstring}" + done + env: + DIGEST: '${{ steps.push.outputs.digest }}' + COSIGN_EXPERIMENTAL: 'true' + + publish-helm-chart: + needs: build-push-image + name: Publish Helm chart for protect-webhook + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: 'Harden runner' + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 + with: + egress-policy: audit + + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + persist-credentials: false + + - name: Resolve parameters + id: resolve_parameters + run: | + resolved_ref="${{ github.ref }}" + echo "INFO: Resolving short SHA for $resolved_ref" + echo "short_sha=$(git rev-parse --short $resolved_ref)" >> $GITHUB_OUTPUT + echo "INFO: Normalizing repository name (lowercase)" + echo "repository_owner=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT + + - name: Set up Helm + uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2 + with: + version: ${{ env.HELM_VERSION }} + + - name: Publish new helm chart for protect-webhook + run: | + echo ${{ secrets.GITHUB_TOKEN }} | helm registry login ghcr.io --username ${{ github.actor }} --password-stdin + PROTECT_WEBHOOK_CHART_VERSION_TAG=$(cat charts/protect-webhook/Chart.yaml | grep version: | cut -d " " -f 2) + echo "PROTECT_WEBHOOK_CHART_VERSION_TAG=${PROTECT_WEBHOOK_CHART_VERSION_TAG}" >> $GITHUB_ENV + helm package charts/protect-webhook/ --version="${PROTECT_WEBHOOK_CHART_VERSION_TAG}" + helm push protect-webhook-"${PROTECT_WEBHOOK_CHART_VERSION_TAG}".tgz oci://ghcr.io/${{ steps.resolve_parameters.outputs.repository_owner }}/charts + + - name: Job summary + run: | + echo "New helm chart for protect-webhook published successfully!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Parameters:**" >> $GITHUB_STEP_SUMMARY + echo "- Ref: ${{ steps.resolve_parameters.outputs.resolved_ref }}" >> $GITHUB_STEP_SUMMARY + echo "- Short SHA: ${{ steps.resolve_parameters.outputs.short_sha }}" >> $GITHUB_STEP_SUMMARY + echo "- protect-webhook Chart version: ${{ env.PROTECT_WEBHOOK_CHART_VERSION_TAG }}" >> $GITHUB_STEP_SUMMARY diff --git a/.gitignore b/.gitignore index a37adc8..ed029b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target/ certs/ +local/ diff --git a/NOTES.txt b/NOTES.txt deleted file mode 100644 index 59262f6..0000000 --- a/NOTES.txt +++ /dev/null @@ -1,22 +0,0 @@ -1. Get the application URL by running these commands: -{{- if .Values.ingress.enabled }} -{{- range $host := .Values.ingress.hosts }} - {{- range .paths }} - http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} - {{- end }} -{{- end }} -{{- else if contains "NodePort" .Values.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "mutatingwebhook.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.service.type }} - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "mutatingwebhook.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "mutatingwebhook.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - echo http://$SERVICE_IP:{{ .Values.service.port }} -{{- else if contains "ClusterIP" .Values.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "mutatingwebhook.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT -{{- end }} diff --git a/chart/.helmignore b/chart/.helmignore deleted file mode 100644 index 0e8a0eb..0000000 --- a/chart/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/chart/Chart.yaml b/charts/protect-webhook/Chart.yaml similarity index 100% rename from chart/Chart.yaml rename to charts/protect-webhook/Chart.yaml diff --git a/chart/templates/_helpers.tpl b/charts/protect-webhook/templates/_helpers.tpl similarity index 100% rename from chart/templates/_helpers.tpl rename to charts/protect-webhook/templates/_helpers.tpl diff --git a/chart/templates/deployment.yaml b/charts/protect-webhook/templates/deployment.yaml similarity index 100% rename from chart/templates/deployment.yaml rename to charts/protect-webhook/templates/deployment.yaml diff --git a/chart/templates/service.yaml b/charts/protect-webhook/templates/service.yaml similarity index 100% rename from chart/templates/service.yaml rename to charts/protect-webhook/templates/service.yaml diff --git a/chart/templates/tests/test-connection.yaml b/charts/protect-webhook/templates/tests/test-connection.yaml similarity index 100% rename from chart/templates/tests/test-connection.yaml rename to charts/protect-webhook/templates/tests/test-connection.yaml diff --git a/chart/templates/webhook.yaml b/charts/protect-webhook/templates/webhook.yaml similarity index 100% rename from chart/templates/webhook.yaml rename to charts/protect-webhook/templates/webhook.yaml diff --git a/chart/values.yaml b/charts/protect-webhook/values.yaml similarity index 100% rename from chart/values.yaml rename to charts/protect-webhook/values.yaml diff --git a/manifest.yaml b/manifest.yaml deleted file mode 100644 index b391c80..0000000 --- a/manifest.yaml +++ /dev/null @@ -1,120 +0,0 @@ ---- -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: self-signed -spec: - selfSigned: {} - ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: webhook-ca -spec: - isCA: true - duration: 8760h # 1 year - secretName: webhook-ca-secret - commonName: webhook-ca - issuerRef: - name: self-signed - kind: Issuer - ---- -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: webhook-ca-issuer -spec: - ca: - secretName: webhook-ca-secret - ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: webhook-server-cert -spec: - duration: 8760h # 1 year - secretName: webhook-server-tls - commonName: webhook-service.default.svc - dnsNames: - - mutate-protect-webhook.edera-system.svc - - mutate-protect-webhook.edera-system.svc.cluster.local - issuerRef: - name: webhook-ca-issuer - kind: Issuer -# -# --- -# apiVersion: apps/v1 -# kind: Deployment -# metadata: -# name: webhook-server -# namespace: default -# labels: -# app: webhook-server -# spec: -# replicas: 1 -# selector: -# matchLabels: -# app: webhook-server -# template: -# metadata: -# labels: -# app: webhook-server -# spec: -# containers: -# - name: webhook-server -# image: ttl.sh/beet/protect-webhook:latest@sha256:b69b6ae2acbdc1915592138127f0d9698626f81b52774f760ef25126fbeb96fe -# imagePullPolicy: Always -# ports: -# - containerPort: 8443 -# name: https -# volumeMounts: -# - name: webhook-tls -# mountPath: /certs -# readOnly: true -# volumes: -# - name: webhook-tls -# secret: -# secretName: webhook-server-tls -# terminationGracePeriodSeconds: 30 -# -# --- -# apiVersion: v1 -# kind: Service -# metadata: -# name: webhook-service -# namespace: default -# labels: -# app: webhook-server -# spec: -# ports: -# - port: 443 -# targetPort: 8443 -# protocol: TCP -# selector: -# app: webhook-server -# type: ClusterIP -# -# --- -# apiVersion: admissionregistration.k8s.io/v1 -# kind: MutatingWebhookConfiguration -# metadata: -# name: runtime-class-injector -# annotations: -# cert-manager.io/inject-ca-from: default/webhook-ca -# webhooks: -# - name: runtime-class-injector.edera.dev -# clientConfig: -# service: -# name: webhook-service -# namespace: default -# path: /mutate -# rules: -# - operations: ["CREATE"] -# apiGroups: [""] -# apiVersions: ["v1"] -# resources: ["pods"] -# admissionReviewVersions: ["v1"] -# sideEffects: None diff --git a/test.yaml b/test.yaml deleted file mode 100644 index 1d918e7..0000000 --- a/test.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: test-pod - labels: - actions-ephemeral-runner: "true" - annotations: - dev.edera/kernel_verbose: "true" -spec: - containers: - - name: test-container - image: nginx