Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/hasadna_mutating_webhook_tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: haadna_mutating_webhook_tests
on:
push:
paths:
- .github/workflows/hasadna_mutating_webhook_tests.yaml
- hasadna-mutating-webhook/**
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: hasadna-mutating-webhook/go.mod
- run: |
wget https://releases.hashicorp.com/terraform/1.12.1/terraform_1.12.1_linux_amd64.zip
unzip terraform_1.12.1_linux_amd64.zip -d /usr/local/bin
rm terraform_1.12.1_linux_amd64.zip /usr/local/bin/LICENSE.txt
chmod +x /usr/local/bin/terraform
- run: |
wget https://releases.hashicorp.com/vault/1.19.4/vault_1.19.4_linux_amd64.zip
unzip vault_1.19.4_linux_amd64.zip -d /usr/local/bin
rm vault_1.19.4_linux_amd64.zip /usr/local/bin/LICENSE.txt
chmod +x /usr/local/bin/vault
- run: |
cd hasadna-mutating-webhook
go fmt
git diff --exit-code
go vet
go test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,4 @@ ENV/
get_helm.sh
.dfs-checkpoints
.rancher.kubeconfig
.AGENTS.sh.completed
12 changes: 12 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# AI Agents Instructions

If file `.AGENTS.sh.completed` exists, it means that environment was already setup for you and all relevant dependencies are installed / downloaded.
If it does not exist, setup the environment by running the script: `./AGENTS.sh`

Activate the virtual environment before running any commands:

```bash
. .venv/bin/activate
```

Check README.md and CONTRIBUTING.md at the project root and under relevant subdirectories for more information.
24 changes: 24 additions & 0 deletions AGENTS.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

# script to setup environment for AI agents

set -euo pipefail

uv sync
uv pip install -r tests/requirements.txt

cd hasadna-mutating-webhook
go mod download -json
cd ..

wget https://releases.hashicorp.com/terraform/1.12.1/terraform_1.12.1_linux_amd64.zip
unzip terraform_1.12.1_linux_amd64.zip -d /usr/local/bin
rm terraform_1.12.1_linux_amd64.zip /usr/local/bin/LICENSE.txt
chmod +x /usr/local/bin/terraform

wget https://releases.hashicorp.com/vault/1.19.4/vault_1.19.4_linux_amd64.zip
unzip vault_1.19.4_linux_amd64.zip -d /usr/local/bin
rm vault_1.19.4_linux_amd64.zip /usr/local/bin/LICENSE.txt
chmod +x /usr/local/bin/vault

touch .AGENTS.sh.completed
1 change: 1 addition & 0 deletions hasadna-mutating-webhook/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/hasadna-mutating-webhook
42 changes: 42 additions & 0 deletions hasadna-mutating-webhook/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Hasadna Mutating Webhook

Kubernetes admission webhook that replaces the `~iac:` and `~vault:`
place-holders used in the Hasadna charts.

It is implemented with controller-runtime (kubebuilder-style layout) and
exposes a single mutating endpoint `/mutate-placeholders`.

Runtime behaviour
* `~iac:<terraform-output-key>~` → value read from Terraform backend as configured in the env vars described below.
* `~vault:<path>:<field>~` → base-64 of the field from Vault KV v2 as configured in the env vars described below.

Configuration via env vars:

* `TF_BACKEND_TYPE` - Terraform backend type, e.g. `local`, `gcs`, `s3` etc..
* `TF_BACKEND_CONFIG__*` - Set values for the backend configuration, for example `TF_BACKEND_CONFIG__bucket=my-bucket`.
* `VAULT_ADDR` - Vault address, e.g. `https://vault.example.com`.
* `VAULT_TOKEN` - Vault token with read access to the secrets.
* `VAULT_ROLE_ID` - Vault AppRole Role ID, used for authentication.
* `VAULT_SECRET_ID` - Vault AppRole Secret ID, used for authentication.

TLS certificates are issued automatically by cert-manager (`Certificate`
CR) and injected into the `MutatingWebhookConfiguration` via the
`cert-manager.io/inject-ca-from` annotation.

Kustomize manifests under `config/` install:

* Namespace, SA and RBAC (read ConfigMap).
* Deployment + Service.
* Certificate and MutatingWebhookConfiguration.

## Local Development

```
cd hasadna-mutating-webhook
go mod tidy
go fmt
go vet ./...
go test ./...
go build
./hasadna-mutating-webhook --help
```
13 changes: 13 additions & 0 deletions hasadna-mutating-webhook/config/certificate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: haadna-mutating-webhook-tls
namespace: hasadna-mutating-webhook
spec:
dnsNames:
- hasadna-mutating-webhook.hasadna-mutating-webhook.svc
- hasadna-mutating-webhook.hasadna-mutating-webhook.svc.cluster.local
secretName: hasadna-mutating-webhook-tls
issuerRef:
name: ca-issuer
kind: ClusterIssuer
50 changes: 50 additions & 0 deletions hasadna-mutating-webhook/config/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: haadna-mutating-webhook
namespace: hasadna-mutating-webhook
spec:
replicas: 2
selector:
matchLabels:
app: haadna-mutating-webhook
template:
metadata:
labels:
app: haadna-mutating-webhook
spec:
serviceAccountName: hasadna-mutating-webhook
containers:
- name: webhook
image: ghcr.io/hasadna/hasadna-mutating-webhook:latest
imagePullPolicy: IfNotPresent
args:
- "--metrics-bind-address=0"
ports:
- name: webhook
containerPort: 9443
protocol: TCP
env:
- name: VAULT_ADDR
valueFrom:
secretKeyRef:
name: argocd-vault-plugin-credentials
key: VAULT_ADDR
- name: VAULT_ROLE_ID
valueFrom:
secretKeyRef:
name: argocd-vault-plugin-credentials
key: AVP_ROLE_ID
- name: VAULT_SECRET_ID
valueFrom:
secretKeyRef:
name: argocd-vault-plugin-credentials
key: AVP_SECRET_ID
volumeMounts:
- name: cert
mountPath: /tmp/k8s-webhook-server/serving-certs
readOnly: true
volumes:
- name: cert
secret:
secretName: hasadna-mutating-webhook-tls
22 changes: 22 additions & 0 deletions hasadna-mutating-webhook/config/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# Namespace
namespace: hasadna-mutating-webhook

resources:
- namespace.yaml
- serviceaccount.yaml
- role.yaml
- rolebinding.yaml
- deployment.yaml
- service.yaml
- certificate.yaml
- mutatingwebhookconfiguration.yaml

generatorOptions:
disableNameSuffixHash: true

images:
- name: ghcr.io/hasadna/hasadna-mutating-webhook
newTag: latest
23 changes: 23 additions & 0 deletions hasadna-mutating-webhook/config/mutatingwebhookconfiguration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: haadna-mutating-webhook
annotations:
cert-manager.io/inject-ca-from: hasadna-mutating-webhook/hasadna-mutating-webhook-tls
webhooks:
- name: placeholders.haadna.org
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
clientConfig:
service:
name: hasadna-mutating-webhook
namespace: hasadna-mutating-webhook
path: /mutate-placeholders
port: 443
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["*/*"]
failurePolicy: Ignore
namespaceSelector: {}
4 changes: 4 additions & 0 deletions hasadna-mutating-webhook/config/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: haadna-mutating-webhook
9 changes: 9 additions & 0 deletions hasadna-mutating-webhook/config/role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: haadna-mutating-webhook
namespace: argocd
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
13 changes: 13 additions & 0 deletions hasadna-mutating-webhook/config/rolebinding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: haadna-mutating-webhook
namespace: argocd
subjects:
- kind: ServiceAccount
name: hasadna-mutating-webhook
namespace: hasadna-mutating-webhook
roleRef:
kind: Role
name: hasadna-mutating-webhook
apiGroup: rbac.authorization.k8s.io
13 changes: 13 additions & 0 deletions hasadna-mutating-webhook/config/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: haadna-mutating-webhook
namespace: hasadna-mutating-webhook
spec:
selector:
app: haadna-mutating-webhook
ports:
- port: 443
targetPort: webhook
protocol: TCP
name: https
5 changes: 5 additions & 0 deletions hasadna-mutating-webhook/config/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: haadna-mutating-webhook
namespace: hasadna-mutating-webhook
90 changes: 90 additions & 0 deletions hasadna-mutating-webhook/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
module github.com/hasadna/hasadna-k8s/hasadna-mutating-webhook

go 1.21

require (
github.com/hashicorp/go-tfe v1.81.0
github.com/hashicorp/vault/api v1.14.0
k8s.io/api v0.28.4
k8s.io/apimachinery v0.28.4
sigs.k8s.io/controller-runtime v0.16.4
)

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v3 v3.0.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-jose/go-jose/v4 v4.0.1 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/zapr v1.2.4 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/go-slug v0.16.4 // indirect
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/jsonapi v1.4.3-0.20250220162346-81a76b606f3e // indirect
github.com/imdario/mergo v0.3.6 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.25.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/oauth2 v0.8.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/term v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/time v0.10.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.28.3 // indirect
k8s.io/client-go v0.28.4 // indirect
k8s.io/component-base v0.28.3 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
Loading