Skip to content
This repository was archived by the owner on Jul 14, 2026. It is now read-only.
Open
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
49 changes: 49 additions & 0 deletions charts/simplyblock-operator/templates/roles/manager_role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ kind: ClusterRole
metadata:
name: simplyblock-operator-manager-role
rules:
# events — all controllers post Warning/Normal events against their CRs so
# kubectl describe surfaces reconcile progress and errors.
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
# nodes — StorageNode controller reads node labels and cordon state; patches
# storage.simplyblock.io/* labels to track storage node membership and status.
- apiGroups:
- ""
resources:
Expand All @@ -21,6 +25,12 @@ rules:
- patch
- update
- watch
# persistentvolumeclaims — BackupRestore controller creates a PVC for each
# restored volume (ensurePVC in backuprestore_controller.go).
# persistentvolumes — BackupRestore controller creates a cluster-scoped PV for
# each restored volume (ensurePV in backuprestore_controller.go); PVs are
# cluster-scoped so a ClusterRole is required. BackupPolicy and StorageBackup
# controllers read PVs to reconcile volume state.
- apiGroups:
- ""
resources:
Expand All @@ -31,6 +41,10 @@ rules:
- get
- list
- watch
# pods — NodeDrain controller patches a drain label onto SPDK-proxy pods to
# coordinate safe eviction order; StorageCluster controller deletes the
# storage-node pod to trigger a DaemonSet restart when node recycling is
# needed. list/get/watch are used to observe pod readiness.
- apiGroups:
- ""
resources:
Expand All @@ -42,6 +56,13 @@ rules:
- patch
- update
- watch
# secrets — StorageCluster controller creates/rotates the cluster UUID/secret
# and the CSI credentials secret (simplyblock-csi-secret-v2) in the operator
# namespace; StorageNode controller reads the cluster secret for API auth.
# serviceaccounts — operator creates simplyblock-storage-node-sa for the
# storage-node DaemonSet pod in every StorageNode namespace.
# services — StorageNode controller creates/updates the headless storage-node-api
# and spdk-proxy Services used for per-pod stable DNS addressing.
- apiGroups:
- ""
resources:
Expand All @@ -56,6 +77,9 @@ rules:
- patch
- update
- watch
# daemonsets — StorageNode controller owns the storage-node DaemonSet lifecycle:
# creates it on first StorageNode CR, updates it on image/config changes,
# and deletes it on cleanup.
- apiGroups:
- apps
resources:
Expand All @@ -68,6 +92,9 @@ rules:
- patch
- update
- watch
# certificates — cert-manager TLS certificates for the storage-node-api and
# spdk-proxy Services; created and rotated by the StorageNode controller
# when tls.provider=cert-manager.
- apiGroups:
- cert-manager.io
resources:
Expand All @@ -80,6 +107,9 @@ rules:
- patch
- update
- watch
# endpointslices — StorageNode controller maintains a custom EndpointSlice for
# the headless storage-node-api and spdk-proxy Services so each pod has a
# stable DNS entry (<nodehostname>.<svc>.<ns>.svc.cluster.local).
- apiGroups:
- discovery.k8s.io
resources:
Expand All @@ -92,6 +122,9 @@ rules:
- patch
- update
- watch
# poddisruptionbudgets — NodeDrain controller creates per-node PDBs
# (maxUnavailable=0) to prevent Kubernetes evicting more than one storage-node
# pod at a time during cluster upgrades or node drain operations.
- apiGroups:
- policy
resources:
Expand All @@ -104,6 +137,10 @@ rules:
- patch
- update
- watch
# clusterroles + clusterrolebindings — operator creates simplyblock-storage-node-role
# and its ClusterRoleBinding so the storage-node DaemonSet SA can manage SPDK
# Jobs and Pods on every worker node.
# TODO(INCIDENT-003) restrict with resourceNames once remediation is complete.
- apiGroups:
- rbac.authorization.k8s.io
resources:
Expand All @@ -117,6 +154,8 @@ rules:
- patch
- update
- watch
# storageclasses — operator creates a StorageClass per storage pool so PVCs
# can reference the correct simplyblock.io provisioner and pool parameters.
- apiGroups:
- storage.k8s.io
resources:
Expand All @@ -127,6 +166,10 @@ rules:
- get
- list
- watch
# storage.simplyblock.io CRDs — operator owns the full lifecycle of all
# simplyblock custom resources: StorageCluster, StorageNode, Pool, Task,
# StorageBackup, BackupPolicy, BackupRestore, BackupImport,
# SnapshotReplication, ControlPlane.
- apiGroups:
- storage.simplyblock.io
resources:
Expand All @@ -148,6 +191,9 @@ rules:
- patch
- update
- watch
# finalizers — controllers set finalizers on CRs to ensure cleanup logic runs
# before deletion (e.g. deregistering the storage node from the cluster,
# removing CSI credentials) even if the CR is force-deleted.
- apiGroups:
- storage.simplyblock.io
resources:
Expand All @@ -162,6 +208,9 @@ rules:
- tasks/finalizers
verbs:
- update
# status subresources — controllers write reconcile outcomes (phase, conditions,
# lastOperation, message) back to CR status without triggering a full spec
# re-reconcile.
- apiGroups:
- storage.simplyblock.io
resources:
Expand Down
71 changes: 55 additions & 16 deletions charts/simplyblock-operator/templates/simplyblock-operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,29 @@ kind: ClusterRole
metadata:
name: simplyblock-operator-clusterrole
rules:
# configmaps — controllers read/write configmaps for node configuration state
# in both the operator namespace and the StorageNode namespace (which may differ).
# events — all controllers post Warning/Normal events against their CRs so
# kubectl describe surfaces reconcile progress and errors.
# persistentvolumeclaims — BackupRestore controller creates a PVC for each
# restored volume (ensurePVC in backuprestore_controller.go).
# pods — NodeDrain controller patches drain labels onto SPDK-proxy pods to
# coordinate safe eviction order; StorageCluster controller deletes the
# storage-node pod to trigger a DaemonSet restart during node recycling.
# secrets — StorageCluster controller writes cluster UUID/secret and the CSI
# credentials secret (simplyblock-csi-secret-v2) in the operator namespace;
# StorageNode controller reads the cluster secret for API auth.
# services — StorageNode controller creates/updates the headless storage-node-api
# and spdk-proxy Services used for per-pod stable DNS addressing.
# serviceaccounts — operator creates simplyblock-storage-node-sa for the
# storage-node DaemonSet pod in every StorageNode namespace.
- apiGroups:
- ""
resources:
- configmaps
- events
- persistentvolumeclaims
- pods
- pods/exec
- namespaces
- secrets
- services
- serviceaccounts
Expand All @@ -179,10 +193,23 @@ rules:
- patch
- update
- watch
# namespaces — read-only lookup used by controllers to verify target namespaces
# exist before creating resources in them. Write verbs are not needed; the
# operator works within pre-existing namespaces only.
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
# daemonsets — StorageNode controller owns the storage-node DaemonSet lifecycle:
# creates it on first StorageNode CR, updates it on image/config changes,
# and deletes it on cleanup.
- apiGroups:
- apps
resources:
- deployments
- daemonsets
verbs:
- create
Expand All @@ -192,6 +219,8 @@ rules:
- patch
- update
- watch
# jobs — operator submits and cleans up one-shot init Jobs when a storage node
# first joins the cluster (hugepage setup, NVMe driver binding, etc.).
- apiGroups:
- batch
resources:
Expand All @@ -205,6 +234,8 @@ rules:
- update
- watch
{{- if and .Values.tls.enabled (eq .Values.tls.provider "cert-manager") }}
# certificates — cert-manager TLS certificates for the storage-node-api and
# spdk-proxy Services; created and rotated by the StorageNode controller.
- apiGroups:
- cert-manager.io
resources:
Expand All @@ -218,6 +249,9 @@ rules:
- update
- watch
{{- end }}
# nodes — operator reads node labels and cordon state to schedule DaemonSets
# correctly; patches storage.simplyblock.io/* labels to track storage node
# membership and operational state.
- apiGroups:
- ""
resources:
Expand All @@ -228,6 +262,9 @@ rules:
- watch
- update
- patch
# persistentvolumes — BackupRestore controller creates a cluster-scoped PV for
# each restored volume (ensurePV in backuprestore_controller.go). PVs are
# cluster-scoped so a ClusterRole is required.
- apiGroups:
- ""
resources:
Expand All @@ -239,6 +276,8 @@ rules:
- watch
- update
- patch
# storageclasses — operator creates a StorageClass per storage pool so PVCs
# can reference the correct simplyblock.io provisioner and pool parameters.
- apiGroups:
- storage.k8s.io
resources:
Expand All @@ -249,23 +288,14 @@ rules:
- get
- list
- watch
# clusterroles + clusterrolebindings — operator creates simplyblock-storage-node-role
# and its ClusterRoleBinding so the storage-node DaemonSet SA can manage SPDK
# Jobs and Pods on every worker node.
# TODO(INCIDENT-003) restrict with resourceNames once remediation is complete.
- apiGroups:
- "rbac.authorization.k8s.io"
resources:
- roles
- clusterroles
verbs:
- create
- delete
- get
- list
- watch
- update
- patch
- apiGroups:
- "rbac.authorization.k8s.io"
resources:
- rolebindings
- clusterrolebindings
verbs:
- create
Expand All @@ -275,6 +305,9 @@ rules:
- watch
- update
- patch
# poddisruptionbudgets — NodeDrain controller creates per-node PDBs (maxUnavailable=0)
# to prevent Kubernetes evicting more than one storage-node pod at a time during
# cluster upgrades or node drain operations.
- apiGroups:
- policy
resources:
Expand All @@ -287,6 +320,9 @@ rules:
- patch
- update
- watch
# OpenShift only — operator configures kubelet CPU management and core isolation
# via MachineConfig/KubeletConfig objects; MachineConfigPool is watched to
# track rollout progress after each config change.
- apiGroups:
- machineconfiguration.openshift.io
resources:
Expand All @@ -300,6 +336,9 @@ rules:
- patch
- update
- watch
# endpointslices — StorageNode controller maintains a custom EndpointSlice for
# the headless storage-node-api and spdk-proxy Services so each pod has a
# stable DNS entry (<nodehostname>.<svc>.<ns>.svc.cluster.local.
- apiGroups:
- discovery.k8s.io
resources:
Expand Down
28 changes: 20 additions & 8 deletions charts/simplyblock-operator/templates/storage-node.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,38 @@ apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: simplyblock-storage-node-role
rules:
# pods — spdk_process_start() creates snode-spdk-pod-* and simplyblock-fluentd-*
# via create_namespaced_pod(); spdk_process_kill() removes them via
# delete_namespaced_pod(); _is_pod_up()/_is_pod_present() poll
# list_namespaced_pod() to check SPDK container readiness.
- apiGroups: [""]
resources: ["pods", "namespaces", "pods/exec"]
resources: ["pods"]
verbs: ["list", "get", "create", "delete", "watch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["create", "delete"]
# jobs — spdk_process_start() submits up to three namespaced Jobs sequentially
# (storage_init_job for hugepages + driver binding, ubuntu_kernel_extra for
# Ubuntu kernel modules, and a core-isolation/CPU-topology Job when enabled).
# Each Job is deleted after completion; stale Jobs from prior crashes are purged
# before re-creation. read_namespaced_job() checks for pre-existing Jobs and
# wait_for_job_completion() polls until done.
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["create", "delete", "get", "list", "watch"]
# nodes — spdk_process_start() calls read_node() in a retry loop to detect
# whether the node is cordoned (spec.unschedulable) before starting SPDK.
# update+patch are required to write storage.simplyblock.io/* labels and
# annotations back to the Node so the operator and control plane can observe
# node-level storage state without querying the storage node API directly.
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
verbs: ["get", "list", "update", "patch", "watch"]

{{- if .Values.storagenode.openShiftCluster }}
# OpenShift only — configures kubelet CPU management and core isolation by
# creating/patching MachineConfig and KubeletConfig objects; MachineConfigPool
# is watched to track rollout progress after each config change.
- apiGroups: ["machineconfiguration.openshift.io"]
resources: ["machineconfigs", "machineconfigpools", "kubeletconfigs"]
verbs: ["list", "get", "create", "update", "patch", "watch"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list", "get", "update", "patch", "watch"]
{{- end }}

---
Expand Down
Loading