@@ -25,6 +25,7 @@ import (
2525
2626 barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
2727 cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
28+ "github.com/cloudnative-pg/cloudnative-pg/pkg/utils"
2829 machineryapi "github.com/cloudnative-pg/machinery/pkg/api"
2930 . "github.com/onsi/ginkgo/v2"
3031 . "github.com/onsi/gomega"
@@ -42,6 +43,15 @@ import (
4243 "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/rbac"
4344)
4445
46+ func expectRequiredLabels (labels map [string ]string , clusterName string ) {
47+ ExpectWithOffset (1 , labels ).To (HaveKeyWithValue (metadata .ClusterLabelName , clusterName ))
48+ ExpectWithOffset (1 , labels ).To (HaveKeyWithValue (utils .KubernetesAppLabelName , utils .AppName ))
49+ ExpectWithOffset (1 , labels ).To (HaveKeyWithValue (utils .KubernetesAppInstanceLabelName , clusterName ))
50+ ExpectWithOffset (1 , labels ).To (HaveKeyWithValue (utils .KubernetesAppManagedByLabelName , "plugin-barman-cloud" ))
51+ ExpectWithOffset (1 , labels ).To (HaveKeyWithValue (utils .KubernetesAppComponentLabelName , utils .DatabaseComponentName ))
52+ ExpectWithOffset (1 , labels ).To (HaveKey (utils .KubernetesAppVersionLabelName ))
53+ }
54+
4555func newScheme () * runtime.Scheme {
4656 s := runtime .NewScheme ()
4757 utilruntime .Must (rbacv1 .AddToScheme (s ))
@@ -124,7 +134,7 @@ var _ = Describe("EnsureRole", func() {
124134 Expect (role .OwnerReferences [0 ].Name ).To (Equal ("test-cluster" ))
125135 Expect (role .OwnerReferences [0 ].Kind ).To (Equal ("Cluster" ))
126136
127- Expect (role .Labels ). To ( HaveKeyWithValue ( metadata . ClusterLabelName , "test-cluster" ) )
137+ expectRequiredLabels (role .Labels , "test-cluster" )
128138 })
129139 })
130140
@@ -210,7 +220,7 @@ var _ = Describe("EnsureRole", func() {
210220 Name : "test-cluster-barman-cloud" ,
211221 Namespace : "default" ,
212222 Labels : map [string ]string {
213- "app.kubernetes.io/managed-by " : "helm " ,
223+ "custom-label " : "custom-value " ,
214224 },
215225 },
216226 }
@@ -227,8 +237,8 @@ var _ = Describe("EnsureRole", func() {
227237 Name : "test-cluster-barman-cloud" ,
228238 }, & role )).To (Succeed ())
229239
230- Expect (role .Labels ).To (HaveKeyWithValue ("app.kubernetes.io/managed-by " , "helm " ))
231- Expect (role .Labels ). To ( HaveKeyWithValue ( metadata . ClusterLabelName , "test-cluster" ) )
240+ Expect (role .Labels ).To (HaveKeyWithValue ("custom-label " , "custom-value " ))
241+ expectRequiredLabels (role .Labels , "test-cluster" )
232242 })
233243 })
234244
@@ -257,12 +267,202 @@ var _ = Describe("EnsureRole", func() {
257267 Name : "test-cluster-barman-cloud" ,
258268 }, & role )).To (Succeed ())
259269
260- Expect (role .Labels ). To ( HaveKeyWithValue ( metadata . ClusterLabelName , "test-cluster" ) )
270+ expectRequiredLabels (role .Labels , "test-cluster" )
261271 Expect (role .Rules ).To (HaveLen (3 ))
262272 })
263273 })
264274})
265275
276+ var _ = Describe ("EnsureRoleBinding" , func () {
277+ var (
278+ ctx context.Context
279+ cluster * cnpgv1.Cluster
280+ fakeClient client.Client
281+ )
282+
283+ BeforeEach (func () {
284+ ctx = context .Background ()
285+ cluster = newCluster ("test-cluster" , "default" )
286+ })
287+
288+ Context ("when the RoleBinding does not exist" , func () {
289+ BeforeEach (func () {
290+ fakeClient = fake .NewClientBuilder ().WithScheme (newScheme ()).Build ()
291+ })
292+
293+ It ("should create the RoleBinding with owner reference, labels, and correct subjects" , func () {
294+ err := rbac .EnsureRoleBinding (ctx , fakeClient , cluster )
295+ Expect (err ).NotTo (HaveOccurred ())
296+
297+ var rb rbacv1.RoleBinding
298+ Expect (fakeClient .Get (ctx , client.ObjectKey {
299+ Namespace : "default" ,
300+ Name : "test-cluster-barman-cloud" ,
301+ }, & rb )).To (Succeed ())
302+
303+ Expect (rb .OwnerReferences ).To (HaveLen (1 ))
304+ Expect (rb .OwnerReferences [0 ].Name ).To (Equal ("test-cluster" ))
305+ Expect (rb .OwnerReferences [0 ].Kind ).To (Equal ("Cluster" ))
306+
307+ expectRequiredLabels (rb .Labels , "test-cluster" )
308+
309+ Expect (rb .Subjects ).To (HaveLen (1 ))
310+ Expect (rb .Subjects [0 ].Name ).To (Equal ("test-cluster" ))
311+ Expect (rb .Subjects [0 ].Kind ).To (Equal ("ServiceAccount" ))
312+
313+ Expect (rb .RoleRef .Kind ).To (Equal ("Role" ))
314+ Expect (rb .RoleRef .Name ).To (Equal ("test-cluster-barman-cloud" ))
315+ })
316+ })
317+
318+ Context ("when the RoleBinding exists with matching state" , func () {
319+ BeforeEach (func () {
320+ fakeClient = fake .NewClientBuilder ().WithScheme (newScheme ()).Build ()
321+ Expect (rbac .EnsureRoleBinding (ctx , fakeClient , cluster )).To (Succeed ())
322+ })
323+
324+ It ("should not patch the RoleBinding" , func () {
325+ var before rbacv1.RoleBinding
326+ Expect (fakeClient .Get (ctx , client.ObjectKey {
327+ Namespace : "default" ,
328+ Name : "test-cluster-barman-cloud" ,
329+ }, & before )).To (Succeed ())
330+
331+ err := rbac .EnsureRoleBinding (ctx , fakeClient , cluster )
332+ Expect (err ).NotTo (HaveOccurred ())
333+
334+ var after rbacv1.RoleBinding
335+ Expect (fakeClient .Get (ctx , client.ObjectKey {
336+ Namespace : "default" ,
337+ Name : "test-cluster-barman-cloud" ,
338+ }, & after )).To (Succeed ())
339+
340+ Expect (after .ResourceVersion ).To (Equal (before .ResourceVersion ))
341+ })
342+ })
343+
344+ Context ("when the RoleBinding exists with different subjects" , func () {
345+ BeforeEach (func () {
346+ fakeClient = fake .NewClientBuilder ().WithScheme (newScheme ()).Build ()
347+ existing := & rbacv1.RoleBinding {
348+ ObjectMeta : metav1.ObjectMeta {
349+ Name : "test-cluster-barman-cloud" ,
350+ Namespace : "default" ,
351+ },
352+ Subjects : []rbacv1.Subject {
353+ {
354+ Kind : "ServiceAccount" ,
355+ Name : "old-sa" ,
356+ APIGroup : "" ,
357+ },
358+ },
359+ RoleRef : rbacv1.RoleRef {
360+ APIGroup : "rbac.authorization.k8s.io" ,
361+ Kind : "Role" ,
362+ Name : "test-cluster-barman-cloud" ,
363+ },
364+ }
365+ Expect (fakeClient .Create (ctx , existing )).To (Succeed ())
366+ })
367+
368+ It ("should patch the subjects to match the desired state" , func () {
369+ err := rbac .EnsureRoleBinding (ctx , fakeClient , cluster )
370+ Expect (err ).NotTo (HaveOccurred ())
371+
372+ var rb rbacv1.RoleBinding
373+ Expect (fakeClient .Get (ctx , client.ObjectKey {
374+ Namespace : "default" ,
375+ Name : "test-cluster-barman-cloud" ,
376+ }, & rb )).To (Succeed ())
377+
378+ Expect (rb .Subjects ).To (HaveLen (1 ))
379+ Expect (rb .Subjects [0 ].Name ).To (Equal ("test-cluster" ))
380+ })
381+ })
382+
383+ Context ("when the RoleBinding has pre-existing unrelated labels" , func () {
384+ BeforeEach (func () {
385+ fakeClient = fake .NewClientBuilder ().WithScheme (newScheme ()).Build ()
386+ existing := & rbacv1.RoleBinding {
387+ ObjectMeta : metav1.ObjectMeta {
388+ Name : "test-cluster-barman-cloud" ,
389+ Namespace : "default" ,
390+ Labels : map [string ]string {
391+ "custom-label" : "custom-value" ,
392+ },
393+ },
394+ Subjects : []rbacv1.Subject {
395+ {
396+ Kind : "ServiceAccount" ,
397+ Name : "test-cluster" ,
398+ Namespace : "default" ,
399+ APIGroup : "" ,
400+ },
401+ },
402+ RoleRef : rbacv1.RoleRef {
403+ APIGroup : "rbac.authorization.k8s.io" ,
404+ Kind : "Role" ,
405+ Name : "test-cluster-barman-cloud" ,
406+ },
407+ }
408+ Expect (fakeClient .Create (ctx , existing )).To (Succeed ())
409+ })
410+
411+ It ("should preserve unrelated labels while adding the required labels" , func () {
412+ err := rbac .EnsureRoleBinding (ctx , fakeClient , cluster )
413+ Expect (err ).NotTo (HaveOccurred ())
414+
415+ var rb rbacv1.RoleBinding
416+ Expect (fakeClient .Get (ctx , client.ObjectKey {
417+ Namespace : "default" ,
418+ Name : "test-cluster-barman-cloud" ,
419+ }, & rb )).To (Succeed ())
420+
421+ Expect (rb .Labels ).To (HaveKeyWithValue ("custom-label" , "custom-value" ))
422+ expectRequiredLabels (rb .Labels , "test-cluster" )
423+ })
424+ })
425+
426+ Context ("when the RoleBinding exists without labels (upgrade scenario)" , func () {
427+ BeforeEach (func () {
428+ fakeClient = fake .NewClientBuilder ().WithScheme (newScheme ()).Build ()
429+ existing := & rbacv1.RoleBinding {
430+ ObjectMeta : metav1.ObjectMeta {
431+ Name : "test-cluster-barman-cloud" ,
432+ Namespace : "default" ,
433+ },
434+ Subjects : []rbacv1.Subject {
435+ {
436+ Kind : "ServiceAccount" ,
437+ Name : "test-cluster" ,
438+ Namespace : "default" ,
439+ APIGroup : "" ,
440+ },
441+ },
442+ RoleRef : rbacv1.RoleRef {
443+ APIGroup : "rbac.authorization.k8s.io" ,
444+ Kind : "Role" ,
445+ Name : "test-cluster-barman-cloud" ,
446+ },
447+ }
448+ Expect (fakeClient .Create (ctx , existing )).To (Succeed ())
449+ })
450+
451+ It ("should add the required labels" , func () {
452+ err := rbac .EnsureRoleBinding (ctx , fakeClient , cluster )
453+ Expect (err ).NotTo (HaveOccurred ())
454+
455+ var rb rbacv1.RoleBinding
456+ Expect (fakeClient .Get (ctx , client.ObjectKey {
457+ Namespace : "default" ,
458+ Name : "test-cluster-barman-cloud" ,
459+ }, & rb )).To (Succeed ())
460+
461+ expectRequiredLabels (rb .Labels , "test-cluster" )
462+ })
463+ })
464+ })
465+
266466var _ = Describe ("EnsureRoleRules" , func () {
267467 var (
268468 ctx context.Context
0 commit comments