fix(netbird-rotation): use python:alpine — apk install fails under non-root PSA #307
@@ -69,9 +69,11 @@ spec:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: rotate
|
||||
# Class-B jobs need an HTTP client + JSON. alpine + runtime apk add
|
||||
# (same runtime-install approach as seed/influxdb/ha-token-job.yaml).
|
||||
image: alpine:3.21
|
||||
# Class-B jobs need an HTTP client + JSON. python:alpine provides both
|
||||
# via stdlib (urllib/json) with NO runtime package install, so it runs
|
||||
# cleanly under the non-root securityContext (apk/apt need root and fail
|
||||
# here — the openbao ns enforces restricted PSA).
|
||||
image: python:3.13-alpine
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
@@ -84,32 +86,34 @@ spec:
|
||||
# FILL IN: comma-separated NetBird group IDs for the new key.
|
||||
- name: NB_AUTO_GROUPS
|
||||
value: "REPLACE_WITH_GROUP_IDS"
|
||||
command: ["/bin/sh", "-ec"]
|
||||
command: ["python3", "-c"]
|
||||
args:
|
||||
- |
|
||||
apk add --no-cache curl jq ca-certificates >/dev/null
|
||||
JWT="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
|
||||
# 1. OpenBao login (k8s auth) → client token
|
||||
T=$(curl -sf --request POST "$BAO_ADDR/v1/auth/kubernetes/login" \
|
||||
-d "{\"role\":\"rotator-netbird\",\"jwt\":\"$JWT\"}" | jq -r .auth.client_token)
|
||||
[ -n "$T" ] && [ "$T" != null ] || { echo "openbao login failed"; exit 1; }
|
||||
import json, os, urllib.request as u
|
||||
bao = os.environ["BAO_ADDR"]; mgmt = os.environ["NB_MANAGEMENT_URL"]
|
||||
groups = [g for g in os.environ["NB_AUTO_GROUPS"].split(",") if g]
|
||||
jwt = open("/var/run/secrets/kubernetes.io/serviceaccount/token").read()
|
||||
def call(method, url, headers=None, body=None, ct="application/json"):
|
||||
data = json.dumps(body).encode() if body is not None else None
|
||||
req = u.Request(url, data=data, method=method, headers=headers or {})
|
||||
if data is not None:
|
||||
req.add_header("Content-Type", ct)
|
||||
with u.urlopen(req, timeout=30) as r:
|
||||
return json.loads(r.read() or b"{}")
|
||||
# 1. OpenBao login (k8s auth)
|
||||
tok = call("POST", bao + "/v1/auth/kubernetes/login",
|
||||
body={"role": "rotator-netbird", "jwt": jwt})["auth"]["client_token"]
|
||||
# 2. read the bootstrap NetBird PAT
|
||||
PAT=$(curl -sf -H "X-Vault-Token: $T" \
|
||||
"$BAO_ADDR/v1/homelab/data/infrastructure/secret-rotators-bootstrap/netbird" \
|
||||
| jq -r .data.data.pat)
|
||||
[ -n "$PAT" ] && [ "$PAT" != null ] || { echo "no bootstrap PAT"; exit 1; }
|
||||
pat = call("GET", bao + "/v1/homelab/data/infrastructure/secret-rotators-bootstrap/netbird",
|
||||
{"X-Vault-Token": tok})["data"]["data"]["pat"]
|
||||
# 3. mint a new reusable setup key via the NetBird mgmt API
|
||||
GROUPS=$(echo "$NB_AUTO_GROUPS" | jq -R 'split(",")')
|
||||
NEW=$(curl -sf -H "Authorization: Token $PAT" -H "Content-Type: application/json" \
|
||||
-X POST "$NB_MANAGEMENT_URL/api/setup-keys" \
|
||||
-d "{\"name\":\"ingress-rotated\",\"type\":\"reusable\",\"expires_in\":31536000,\"usage_limit\":0,\"auto_groups\":$GROUPS}" \
|
||||
| jq -r .key)
|
||||
[ -n "$NEW" ] && [ "$NEW" != null ] || { echo "setup-key creation failed"; exit 1; }
|
||||
key = call("POST", mgmt + "/api/setup-keys", {"Authorization": "Token " + pat},
|
||||
{"name": "ingress-rotated", "type": "reusable", "expires_in": 31536000,
|
||||
"usage_limit": 0, "auto_groups": groups})["key"]
|
||||
# 4. patch the new key into OpenBao (KV v2 merge-patch)
|
||||
curl -sf -H "X-Vault-Token: $T" -H "Content-Type: application/merge-patch+json" \
|
||||
-X PATCH "$BAO_ADDR/v1/homelab/data/infrastructure/netbird-ingress" \
|
||||
-d "{\"data\":{\"setup-key\":\"$NEW\"}}" >/dev/null
|
||||
echo "rotated setup-key at homelab/infrastructure/netbird-ingress (value not logged)"
|
||||
call("PATCH", bao + "/v1/homelab/data/infrastructure/netbird-ingress",
|
||||
{"X-Vault-Token": tok}, {"data": {"setup-key": key}}, "application/merge-patch+json")
|
||||
print("rotated setup-key at homelab/infrastructure/netbird-ingress (value not logged)")
|
||||
resources:
|
||||
requests:
|
||||
cpu: 25m
|
||||
|
||||
Reference in New Issue
Block a user