~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/knotless-runner-k8s

0
0
83 lines · 2.9 KB Raw History
#!/usr/bin/env bash
# Makes a scoped kubeconfig for knotless-run from a tenant admin
# kubeconfig: a ServiceAccount, a namespaced Role for Jobs, pods, exec,
# logs, events and NetworkPolicies, and a 24-hour token.
#
# The token is written only into the output kubeconfig, mode 0600. It is
# not printed. Re-run this before the 24 hours are up.
#
# Environment:
#   ADMIN_KUBECONFIG  tenant admin kubeconfig
#   OUT               scoped kubeconfig to write
#   NAMESPACE         namespace (default knotless-runs)
#   SERVICE_ACCOUNT   service account (default knotless-runner)
set -euo pipefail

ADMIN_KUBECONFIG=${ADMIN_KUBECONFIG:-$HOME/.tmp/knotless-runner-k8s/tenant/knotless-poc.kubeconfig.yaml}
OUT=${OUT:-$HOME/.tmp/knotless-runner-k8s/tenant/knotless-runner.kubeconfig.yaml}
NAMESPACE=${NAMESPACE:-knotless-runs}
SERVICE_ACCOUNT=${SERVICE_ACCOUNT:-knotless-runner}

admin() { kubectl --kubeconfig "$ADMIN_KUBECONFIG" "$@"; }

admin create namespace "$NAMESPACE" --dry-run=client -o yaml | admin apply -f - >/dev/null
admin -n "$NAMESPACE" create serviceaccount "$SERVICE_ACCOUNT" --dry-run=client -o yaml | admin apply -f - >/dev/null

admin apply -f - >/dev/null <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: knotless-runner
  namespace: $NAMESPACE
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log", "pods/exec", "events"]
    verbs: ["get", "list", "watch", "create"]
  - apiGroups: ["batch"]
    resources: ["jobs"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["networkpolicies"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: knotless-runner
  namespace: $NAMESPACE
subjects:
  - kind: ServiceAccount
    name: $SERVICE_ACCOUNT
    namespace: $NAMESPACE
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: knotless-runner
EOF

SERVER=$(admin config view --minify -o jsonpath='{.clusters[0].cluster.server}')
TOKEN=$(admin -n "$NAMESPACE" create token "$SERVICE_ACCOUNT" --duration=24h)

tmp=$(mktemp "$OUT.XXXXXX")
trap 'rm -f "$tmp"' EXIT
chmod 0600 "$tmp"
{
  printf 'apiVersion: v1\nkind: Config\n'
  printf 'clusters:\n- name: tenant\n  cluster:\n    server: "%s"\n' "$SERVER"
  printf 'contexts:\n- name: %s\n  context:\n    cluster: tenant\n    user: %s\n    namespace: %s\n' "$NAMESPACE" "$SERVICE_ACCOUNT" "$NAMESPACE"
  printf 'current-context: %s\n' "$NAMESPACE"
  printf 'users:\n- name: %s\n  user:\n    token: "%s"\n' "$SERVICE_ACCOUNT" "$TOKEN"
} > "$tmp"
mv "$tmp" "$OUT"
chmod 0600 "$OUT"
trap - EXIT

if [ "$(kubectl --kubeconfig "$OUT" auth can-i create jobs -n "$NAMESPACE")" != yes ]; then
  echo "scoped-kubeconfig: the token cannot create Jobs" >&2
  exit 1
fi
if [ "$(kubectl --kubeconfig "$OUT" auth can-i get nodes)" != no ]; then
  echo "scoped-kubeconfig: the token is not scoped: it can read nodes" >&2
  exit 1
fi
printf '%s\n' "$OUT"