Skip to content

Commit 31ac5c3

Browse files
authored
Role fixes (#11)
- Put permissions in same order in both roles - Add back support for specifying namespace for the platform-role, as it is either configurable fully or none at all - add apiGroups: [""] resources: ["namespaces"] verbs: ["update", "patch"] to operator role - add apiGroups: [""] resources: ["pods/status"] verbs: ["get"] permission to platform role - add apiGroups: ["apps"] resources: ["statefulsets/scale"] verbs: ["get", "patch", "update"] permission to platform role - Add hack/generate-sa-token.sh to easily generate credentials for the service account
1 parent b4b2166 commit 31ac5c3

File tree

10 files changed

+144
-18
lines changed

10 files changed

+144
-18
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Packaged as a Helm chart for customer-managed Kubernetes clusters. Operates with
2525

2626
Install a specific version
2727
```
28-
operator_version=0.1.2
28+
operator_version=0.1.3
2929
operator_env_regex=""
3030
helm repo add quix-environment-operator https://quixio.github.io/quix-environment-operator/ && helm repo update
3131
helm pull quix-environment-operator/quix-environment-operator --version $operator_version

deploy/quix-environment-operator/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apiVersion: v2
22
name: quix-environment-operator
33
description: A Kubernetes operator for provisioning isolated application environments
44
type: application
5-
version: 0.1.2
5+
version: 0.1.3
66
appVersion: "0.1.0"
77
icon: https://quixstorageaccount.blob.core.windows.net/portal/img/quix_favicon.png
88
keywords:

deploy/quix-environment-operator/templates/deployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ spec:
4040
- name: SERVICE_ACCOUNT_NAME
4141
value: {{ .Values.env.serviceAccountName | quote }}
4242
- name: SERVICE_ACCOUNT_NAMESPACE
43-
value: {{ .Release.Namespace | quote }}
43+
value: {{ .Values.env.serviceAccountNameSpace | default .Release.Namespace | quote }}
4444
- name: CLUSTER_ROLE_NAME
4545
value: {{ .Values.env.clusterRoleName | quote }}
4646
- name: CACHE_SYNC_PERIOD

deploy/quix-environment-operator/templates/operator-cluster-role.yaml

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ rules:
2020
# Allows the controller to create and manage namespaces for environments
2121
- apiGroups: [""]
2222
resources: ["namespaces"]
23-
verbs: ["get", "create", "delete", "watch"]
23+
verbs: ["get", "create", "delete", "watch", "update", "patch"]
2424
# Enables the controller to manage role bindings for environment access control
2525
- apiGroups: ["rbac.authorization.k8s.io"]
2626
resources: ["rolebindings"]
@@ -37,23 +37,29 @@ rules:
3737

3838
# The following rules are required for the operator only to be able to grant them to the service account at namespace level
3939
# see /deploy/quix-environment-operator/templates/platform-cluster-role.yaml
40-
# Allow management of core resources
40+
# Allow users to access standard Kubernetes resources within their namespace
4141
- apiGroups: [""]
42-
resources: ["configmaps", "persistentvolumeclaims", "pods", "secrets", "serviceaccounts", "services"]
42+
resources: ["pods", "services", "configmaps", "secrets", "serviceaccounts", "persistentvolumeclaims"]
4343
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
44-
# Special pod-related permissions
45-
- apiGroups: [""]
46-
resources: ["pods/exec", "pods/log"]
47-
verbs: ["get", "list", "create"]
48-
# App deployment resources
44+
# Allow users to access deployment-related resources
4945
- apiGroups: ["apps"]
50-
resources: ["daemonsets", "deployments", "replicasets", "statefulsets"]
46+
resources: ["deployments", "replicasets", "statefulsets", "daemonsets"]
5147
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
52-
# Batch job resources
48+
- apiGroups: ["apps"]
49+
resources: ["statefulsets/scale"]
50+
verbs: ["get", "patch", "update"]
51+
# Allow users to access batch resources
5352
- apiGroups: ["batch"]
54-
resources: ["cronjobs", "jobs"]
53+
resources: ["jobs", "cronjobs"]
5554
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
56-
# Networking resources
55+
# Allow users to access networking resources
5756
- apiGroups: ["networking.k8s.io"]
5857
resources: ["ingresses", "networkpolicies"]
59-
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
58+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
59+
# Allow users to execute pods for debugging
60+
- apiGroups: [""]
61+
resources: ["pods/exec", "pods/log"]
62+
verbs: ["get", "list", "create"]
63+
- apiGroups: [""]
64+
resources: ["pods/status"]
65+
verbs: ["get"]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
apiVersion: rbac.authorization.k8s.io/v1
2+
kind: ClusterRoleBinding
3+
metadata:
4+
name: {{ .Values.env.clusterRoleName }}-env
5+
labels:
6+
{{- include "quix-environment-operator.labels" . | nindent 4 }}
7+
subjects:
8+
- kind: ServiceAccount
9+
name: {{ .Values.env.serviceAccountName }}
10+
namespace: {{ .Values.env.serviceAccountNamespace | default .Release.Namespace }}
11+
roleRef:
12+
apiGroup: rbac.authorization.k8s.io
13+
kind: ClusterRole
14+
name: {{ .Values.env.clusterRoleName }}-env
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: rbac.authorization.k8s.io/v1
2+
kind: ClusterRole
3+
metadata:
4+
name: {{ .Values.env.clusterRoleName }}-env
5+
labels:
6+
{{- include "quix-environment-operator.labels" . | nindent 4 }}
7+
rules:
8+
# Allows the controller to manage the custom environment resources
9+
- apiGroups: ["quix.io"]
10+
resources: ["environments"]
11+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

deploy/quix-environment-operator/templates/platform-cluster-role.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ rules:
1313
- apiGroups: ["apps"]
1414
resources: ["deployments", "replicasets", "statefulsets", "daemonsets"]
1515
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
16+
- apiGroups: ["apps"]
17+
resources: ["statefulsets/scale"]
18+
verbs: ["get", "patch", "update"]
1619
# Allow users to access batch resources
1720
- apiGroups: ["batch"]
1821
resources: ["jobs", "cronjobs"]
@@ -24,4 +27,7 @@ rules:
2427
# Allow users to execute pods for debugging
2528
- apiGroups: [""]
2629
resources: ["pods/exec", "pods/log"]
27-
verbs: ["get", "list", "create"]
30+
verbs: ["get", "list", "create"]
31+
- apiGroups: [""]
32+
resources: ["pods/status"]
33+
verbs: ["get"]

deploy/quix-environment-operator/templates/platform-service-account.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ apiVersion: v1
22
kind: ServiceAccount
33
metadata:
44
name: {{ .Values.env.serviceAccountName }}
5-
namespace: {{ .Values.env.serviceAccountNamespace }}
5+
namespace: {{ .Values.env.serviceAccountNamespace | default .Release.Namespace }}
66
labels:
77
{{- include "quix-environment-operator.labels" . | nindent 4 }}

deploy/quix-environment-operator/values.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ env:
4848

4949
# ServiceAccount for RoleBindings
5050
serviceAccountName: "quix-platform-account"
51+
52+
# Service account namespace, which defaults to release namespace
53+
serviceAccountNameSpace:
5154

5255
# ClusterRole for RoleBindings
5356
clusterRoleName: "quix-platform-account-role"

hack/generate-sa-token.sh

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
SA_NAME="${1:-quix-platform-account}"
6+
NAMESPACE="${2:-quix-operator}"
7+
8+
if [[ -z "$SA_NAME" ]]; then
9+
echo "Usage: $0 [service-account-name] [namespace]" >&2
10+
exit 1
11+
fi
12+
13+
# Only run context validation if terminal is interactive
14+
if [[ -t 1 ]]; then
15+
echo "🔍 Validating current Kubernetes context..."
16+
if ! kubectl cluster-info > /dev/null 2>&1; then
17+
echo "❌ Error: Unable to connect to current Kubernetes context." >&2
18+
kubectl config current-context || true
19+
exit 1
20+
fi
21+
22+
CONTEXT=$(kubectl config current-context)
23+
echo "✅ Connected to context: $CONTEXT"
24+
read -rp "❓ Proceed with this context? [y/N]: " CONFIRM
25+
case "$CONFIRM" in
26+
[yY][eE][sS]|[yY]) ;;
27+
*) echo "❌ Aborted by user."; exit 1 ;;
28+
esac
29+
fi
30+
31+
# Check if ServiceAccount exists
32+
if ! kubectl get sa "$SA_NAME" -n "$NAMESPACE" >/dev/null 2>&1; then
33+
echo "❌ Error: ServiceAccount '$SA_NAME' not found in namespace '$NAMESPACE'" >&2
34+
exit 1
35+
fi
36+
37+
# Generate unique secret name
38+
BASE_SECRET_NAME="${SA_NAME}-token"
39+
SECRET_NAME="$BASE_SECRET_NAME"
40+
i=2
41+
while kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" >/dev/null 2>&1; do
42+
SECRET_NAME="${BASE_SECRET_NAME}-$i"
43+
((i++))
44+
done
45+
46+
echo "🔐 Creating Secret '$SECRET_NAME' bound to ServiceAccount '$SA_NAME'..."
47+
cat <<EOF | kubectl apply -f -
48+
apiVersion: v1
49+
kind: Secret
50+
metadata:
51+
name: ${SECRET_NAME}
52+
namespace: ${NAMESPACE}
53+
annotations:
54+
kubernetes.io/service-account.name: ${SA_NAME}
55+
type: kubernetes.io/service-account-token
56+
EOF
57+
58+
echo "⏳ Waiting for token to be populated..."
59+
for i in {1..10}; do
60+
TOKEN=$(kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" -o jsonpath='{.data.token}' 2>/dev/null || true)
61+
if [[ -n "$TOKEN" ]]; then
62+
break
63+
fi
64+
sleep 1
65+
done
66+
67+
if [[ -z "$TOKEN" ]]; then
68+
echo "❌ Error: Token not populated in Secret '$SECRET_NAME'" >&2
69+
exit 1
70+
fi
71+
72+
echo
73+
echo "✅ Secret Name: $SECRET_NAME"
74+
echo "✅ Bearer Token:"
75+
echo "$TOKEN" | base64 -d
76+
echo
77+
78+
echo "✅ Kubernetes API Server:"
79+
kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}'
80+
echo
81+
82+
echo "✅ CA Certificate (base64):"
83+
kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" -o jsonpath='{.data.ca\.crt}'
84+
echo
85+
86+
echo "🎉 Token Secret generated successfully."

0 commit comments

Comments
 (0)