This is an automated email from the ASF dual-hosted git repository.

squakez pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git


The following commit(s) were added to refs/heads/main by this push:
     new 2b49410af Fix #6952: Move StorageClass RBAC to a ClusterRole for all 
install modes
2b49410af is described below

commit 2b49410afb5be6a25f0ce38a3c71451747f93cde
Author: SnehaNprog <[email protected]>
AuthorDate: Tue Nov 10 21:17:04 2026 +0530

    Fix #6952: Move StorageClass RBAC to a ClusterRole for all install modes
---
 helm/camel-k/templates/rbacs-common.yaml           | 30 +++++++++++++
 helm/camel-k/templates/rbacs-descoped.yaml         |  7 ---
 helm/camel-k/templates/rbacs-namespaced.yaml       |  7 ---
 .../rbac/descoped/operator-cluster-role.yaml       |  7 ---
 ...> get-storageclasses-cluster-role-binding.yaml} | 30 ++++++-------
 ...n.yaml => get-storageclasses-cluster-role.yaml} | 31 ++++++-------
 pkg/resources/config/rbac/kustomization.yaml       |  2 +
 .../config/rbac/namespaced/operator-role.yaml      |  7 ---
 pkg/resources/resources_test.go                    | 52 ++++++++++++++++++++++
 9 files changed, 111 insertions(+), 62 deletions(-)

diff --git a/helm/camel-k/templates/rbacs-common.yaml 
b/helm/camel-k/templates/rbacs-common.yaml
index 4df1868df..86899d111 100644
--- a/helm/camel-k/templates/rbacs-common.yaml
+++ b/helm/camel-k/templates/rbacs-common.yaml
@@ -185,6 +185,21 @@ rules:
   - get
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  labels:
+    app: camel-k
+  name: {{ include "camel-k.fullname" . }}-operator-storageclasses
+rules:
+- apiGroups:
+  - storage.k8s.io
+  resources:
+  - storageclasses
+  verbs:
+  - get
+  - list
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
 metadata:
   labels:
@@ -255,3 +270,18 @@ subjects:
 - kind: ServiceAccount
   name: {{ include "camel-k.fullname" . }}-operator
   namespace: '{{ .Release.Namespace }}'
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  labels:
+    app: camel-k
+  name: {{ include "camel-k.fullname" . }}-operator-storageclasses
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: {{ include "camel-k.fullname" . }}-operator-storageclasses
+subjects:
+- kind: ServiceAccount
+  name: {{ include "camel-k.fullname" . }}-operator
+  namespace: '{{ .Release.Namespace }}'
diff --git a/helm/camel-k/templates/rbacs-descoped.yaml 
b/helm/camel-k/templates/rbacs-descoped.yaml
index eb11fa0d6..5f315c641 100644
--- a/helm/camel-k/templates/rbacs-descoped.yaml
+++ b/helm/camel-k/templates/rbacs-descoped.yaml
@@ -149,13 +149,6 @@ rules:
   - list
   - patch
   - watch
-- apiGroups:
-  - storage.k8s.io
-  resources:
-  - storageclasses
-  verbs:
-  - get
-  - list
 - apiGroups:
   - ""
   resources:
diff --git a/helm/camel-k/templates/rbacs-namespaced.yaml 
b/helm/camel-k/templates/rbacs-namespaced.yaml
index 5c53106a8..e6d421037 100644
--- a/helm/camel-k/templates/rbacs-namespaced.yaml
+++ b/helm/camel-k/templates/rbacs-namespaced.yaml
@@ -199,13 +199,6 @@ rules:
   - get
   - list
   - watch
-- apiGroups:
-  - storage.k8s.io
-  resources:
-  - storageclasses
-  verbs:
-  - get
-  - list
 - apiGroups:
   - ""
   resources:
diff --git a/pkg/resources/config/rbac/descoped/operator-cluster-role.yaml 
b/pkg/resources/config/rbac/descoped/operator-cluster-role.yaml
index 5e51a35c8..4764e2451 100644
--- a/pkg/resources/config/rbac/descoped/operator-cluster-role.yaml
+++ b/pkg/resources/config/rbac/descoped/operator-cluster-role.yaml
@@ -153,13 +153,6 @@ rules:
   - patch
   - watch
 # Required by mount trait
-- apiGroups:
-  - storage.k8s.io
-  resources:
-  - storageclasses
-  verbs:
-  - get
-  - list
 - apiGroups:
   - ""
   resources:
diff --git a/pkg/resources/config/rbac/kustomization.yaml 
b/pkg/resources/config/rbac/get-storageclasses-cluster-role-binding.yaml
similarity index 67%
copy from pkg/resources/config/rbac/kustomization.yaml
copy to pkg/resources/config/rbac/get-storageclasses-cluster-role-binding.yaml
index 9df92da16..6cd3db353 100644
--- a/pkg/resources/config/rbac/kustomization.yaml
+++ b/pkg/resources/config/rbac/get-storageclasses-cluster-role-binding.yaml
@@ -15,20 +15,16 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
-#
-# rbac resources applicable for all kubernetes platforms
-#
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-
-resources:
-- builder-role.yaml
-- builder-role-openshift.yaml
-- dev-registry-role.yaml
-- kamelets-viewer-role.yaml
-- builder-role-binding.yaml
-- builder-role-binding-openshift.yaml
-- dev-registry-role-binding.yaml
-- kamelets-viewer-role-binding.yaml
-- get-namespaces-cluster-role.yaml
-- get-namespaces-cluster-role-binding.yaml
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: camel-k-operator-storageclasses
+  labels:
+    app: "camel-k"
+subjects:
+- kind: ServiceAccount
+  name: camel-k-operator
+roleRef:
+  kind: ClusterRole
+  name: camel-k-operator-storageclasses
+  apiGroup: rbac.authorization.k8s.io
diff --git a/pkg/resources/config/rbac/kustomization.yaml 
b/pkg/resources/config/rbac/get-storageclasses-cluster-role.yaml
similarity index 67%
copy from pkg/resources/config/rbac/kustomization.yaml
copy to pkg/resources/config/rbac/get-storageclasses-cluster-role.yaml
index 9df92da16..ec219ffa9 100644
--- a/pkg/resources/config/rbac/kustomization.yaml
+++ b/pkg/resources/config/rbac/get-storageclasses-cluster-role.yaml
@@ -15,20 +15,17 @@
 # limitations under the License.
 # ---------------------------------------------------------------------------
 
-#
-# rbac resources applicable for all kubernetes platforms
-#
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-
-resources:
-- builder-role.yaml
-- builder-role-openshift.yaml
-- dev-registry-role.yaml
-- kamelets-viewer-role.yaml
-- builder-role-binding.yaml
-- builder-role-binding-openshift.yaml
-- dev-registry-role-binding.yaml
-- kamelets-viewer-role-binding.yaml
-- get-namespaces-cluster-role.yaml
-- get-namespaces-cluster-role-binding.yaml
+kind: ClusterRole
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: camel-k-operator-storageclasses
+  labels:
+    app: "camel-k"
+rules:
+- apiGroups:
+  - storage.k8s.io
+  resources:
+  - storageclasses
+  verbs:
+  - get
+  - list
diff --git a/pkg/resources/config/rbac/kustomization.yaml 
b/pkg/resources/config/rbac/kustomization.yaml
index 9df92da16..4fbda038e 100644
--- a/pkg/resources/config/rbac/kustomization.yaml
+++ b/pkg/resources/config/rbac/kustomization.yaml
@@ -32,3 +32,5 @@ resources:
 - kamelets-viewer-role-binding.yaml
 - get-namespaces-cluster-role.yaml
 - get-namespaces-cluster-role-binding.yaml
+- get-storageclasses-cluster-role.yaml
+- get-storageclasses-cluster-role-binding.yaml
diff --git a/pkg/resources/config/rbac/namespaced/operator-role.yaml 
b/pkg/resources/config/rbac/namespaced/operator-role.yaml
index c9054a877..276fcac2b 100644
--- a/pkg/resources/config/rbac/namespaced/operator-role.yaml
+++ b/pkg/resources/config/rbac/namespaced/operator-role.yaml
@@ -204,13 +204,6 @@ rules:
   - get
   - list
   - watch
-- apiGroups:
-  - storage.k8s.io
-  resources:
-  - storageclasses
-  verbs:
-  - get
-  - list
 # Service Accounts (dynamic SA creation)
 - apiGroups:
   - ""
diff --git a/pkg/resources/resources_test.go b/pkg/resources/resources_test.go
index 42bb9cd27..8d45de4b9 100644
--- a/pkg/resources/resources_test.go
+++ b/pkg/resources/resources_test.go
@@ -18,10 +18,13 @@ limitations under the License.
 package resources
 
 import (
+       "slices"
        "testing"
 
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/require"
+       rbacv1 "k8s.io/api/rbac/v1"
+       "sigs.k8s.io/yaml"
 )
 
 func NoErrorAndNotEmptyBytes(t *testing.T, path string, callable func(path 
string) ([]byte, error)) {
@@ -128,3 +131,52 @@ func TestCRDResources(t *testing.T) {
        NoErrorAndNotEmptyBytes(t, 
"/config/crd/bases/camel.apache.org_kamelets.yaml", Resource)
        NoErrorAndNotEmptyBytes(t, 
"/config/crd/bases/camel.apache.org_pipes.yaml", Resource)
 }
+
+// StorageClass is a cluster scoped resource: a namespaced Role can never 
grant access to it,
+// so the permission must be granted through a dedicated ClusterRole in every 
installation mode.
+func TestStorageClassesRBACIsClusterScoped(t *testing.T) {
+       hasStorageClasses := func(rules []rbacv1.PolicyRule) bool {
+               for _, rule := range rules {
+                       if slices.Contains(rule.Resources, "storageclasses") {
+                               return true
+                       }
+               }
+
+               return false
+       }
+
+       var role rbacv1.Role
+       data, err := Resource("config/rbac/namespaced/operator-role.yaml")
+       require.NoError(t, err)
+       require.NoError(t, yaml.Unmarshal(data, &role))
+       assert.False(t, hasStorageClasses(role.Rules), "namespaced operator 
Role cannot grant access to cluster scoped storageclasses")
+
+       var descopedRole rbacv1.ClusterRole
+       data, err = Resource("config/rbac/descoped/operator-cluster-role.yaml")
+       require.NoError(t, err)
+       require.NoError(t, yaml.Unmarshal(data, &descopedRole))
+       assert.False(t, hasStorageClasses(descopedRole.Rules), "storageclasses 
must be granted by the common ClusterRole only")
+
+       var clusterRole rbacv1.ClusterRole
+       data, err = Resource("config/rbac/get-storageclasses-cluster-role.yaml")
+       require.NoError(t, err)
+       require.NoError(t, yaml.Unmarshal(data, &clusterRole))
+       require.True(t, hasStorageClasses(clusterRole.Rules))
+       assert.Equal(t, []string{"storage.k8s.io"}, 
clusterRole.Rules[0].APIGroups)
+       assert.ElementsMatch(t, []string{"get", "list"}, 
clusterRole.Rules[0].Verbs)
+
+       var binding rbacv1.ClusterRoleBinding
+       data, err = 
Resource("config/rbac/get-storageclasses-cluster-role-binding.yaml")
+       require.NoError(t, err)
+       require.NoError(t, yaml.Unmarshal(data, &binding))
+       assert.Equal(t, clusterRole.Name, binding.RoleRef.Name)
+       assert.Equal(t, "ClusterRole", binding.RoleRef.Kind)
+       require.Len(t, binding.Subjects, 1)
+       assert.Equal(t, "camel-k-operator", binding.Subjects[0].Name)
+
+       // the common RBAC kustomization must ship them, so they apply to every 
installation mode
+       kustomization, err := ResourceAsString("config/rbac/kustomization.yaml")
+       require.NoError(t, err)
+       assert.Contains(t, kustomization, 
"get-storageclasses-cluster-role.yaml")
+       assert.Contains(t, kustomization, 
"get-storageclasses-cluster-role-binding.yaml")
+}

Reply via email to