From 099d0d993bccecad900f341daf3b97e72c8f991a Mon Sep 17 00:00:00 2001 From: Jean-Marc Andre Date: Sun, 31 Jan 2021 12:40:20 +0100 Subject: [PATCH] Needed more RBAC rules for Tasks to be allowed to update BackupSession status --- controllers/backupconfiguration_controller.go | 20 ++- pkg/rbac/backupconfiguration.go | 117 ++++++++++++++++-- 2 files changed, 124 insertions(+), 13 deletions(-) diff --git a/controllers/backupconfiguration_controller.go b/controllers/backupconfiguration_controller.go index c62059d..36a4386 100644 --- a/controllers/backupconfiguration_controller.go +++ b/controllers/backupconfiguration_controller.go @@ -220,6 +220,10 @@ func (r *BackupConfigurationReconciler) addSidecarContainer(backupConf *formolv1 log.Error(err, "unable to create backupsessionlistener RBAC") return nil } + if err := formolrbac.CreateBackupSessionStatusUpdaterRBAC(r.Client, "default", backupConf.Namespace); err != nil { + log.Error(err, "unable to create backupsession-statusupdater RBAC") + return nil + } log.V(0).Info("Adding a sicar container") if err := r.Update(context.Background(), deployment); err != nil { @@ -262,6 +266,10 @@ func (r *BackupConfigurationReconciler) addCronJob(backupConf *formolv1alpha1.Ba log.Error(err, "unable to create backupsession-creator RBAC") return nil } + if err := formolrbac.CreateBackupSessionStatusUpdaterRBAC(r.Client, "default", backupConf.Namespace); err != nil { + log.Error(err, "unable to create backupsession-statusupdater RBAC") + return nil + } cronjob = &kbatch_beta1.CronJob{ ObjectMeta: metav1.ObjectMeta{ @@ -385,14 +393,20 @@ func (r *BackupConfigurationReconciler) deleteExternalResources(backupConf *form if err := formolrbac.DeleteBackupSessionListenerRBAC(r.Client, deployment.Spec.Template.Spec.ServiceAccountName, deployment.Namespace); err != nil { return err } - if err := formolrbac.DeleteBackupSessionCreatorRBAC(r.Client, backupConf.Namespace); err != nil { - return err - } if err := r.deleteSidecarContainer(backupConf, target); err != nil { return err } + case "Task": + } } + // TODO: remove the hardcoded "default" + if err := formolrbac.DeleteBackupSessionStatusUpdaterRBAC(r.Client, "default", backupConf.Namespace); err != nil { + return err + } + if err := formolrbac.DeleteBackupSessionCreatorRBAC(r.Client, backupConf.Namespace); err != nil { + return err + } return nil } diff --git a/pkg/rbac/backupconfiguration.go b/pkg/rbac/backupconfiguration.go index 368d211..d1583e5 100644 --- a/pkg/rbac/backupconfiguration.go +++ b/pkg/rbac/backupconfiguration.go @@ -10,11 +10,13 @@ import ( ) const ( - backupListenerRole = "backup-listener-role" - backupListenerRoleBinding = "backup-listener-rolebinding" - backupSessionCreatorSA = "backupsession-creator" - backupSessionCreatorRole = "backupsession-creator-role" - backupSessionCreatorRoleBinding = "backupsession-creator-rolebinding" + backupListenerRole = "backup-listener-role" + backupListenerRoleBinding = "backup-listener-rolebinding" + backupSessionCreatorSA = "backupsession-creator" + backupSessionCreatorRole = "backupsession-creator-role" + backupSessionCreatorRoleBinding = "backupsession-creator-rolebinding" + backupSessionStatusUpdaterRole = "backupsession-statusupdater-role" + backupSessionStatusUpdaterRoleBinding = "backupsession-statusupdater-rolebinding" ) func DeleteBackupSessionCreatorRBAC(cl client.Client, namespace string) error { @@ -197,11 +199,6 @@ func CreateBackupSessionListenerRBAC(cl client.Client, saName string, namespace APIGroups: []string{"formol.desmojim.fr"}, Resources: []string{"backupsessions"}, }, - rbacv1.PolicyRule{ - Verbs: []string{"get", "list", "watch", "patch", "update"}, - APIGroups: []string{"formol.desmojim.fr"}, - Resources: []string{"backupsessions/status"}, - }, }, } if err := cl.Get(context.Background(), client.ObjectKey{ @@ -239,3 +236,103 @@ func CreateBackupSessionListenerRBAC(cl client.Client, saName string, namespace } return nil } + +func DeleteBackupSessionStatusUpdaterRBAC(cl client.Client, saName string, namespace string) error { + if saName == "" { + saName = "default" + } + sa := &corev1.ServiceAccount{} + if err := cl.Get(context.Background(), client.ObjectKey{ + Namespace: namespace, + Name: saName, + }, sa); err != nil { + return err + } + + role := &rbacv1.Role{} + if err := cl.Get(context.Background(), client.ObjectKey{ + Namespace: namespace, + Name: backupSessionStatusUpdaterRole, + }, role); err == nil { + if err = cl.Delete(context.Background(), role); err != nil { + return err + } + } + + rolebinding := &rbacv1.RoleBinding{} + if err := cl.Get(context.Background(), client.ObjectKey{ + Namespace: namespace, + Name: backupSessionStatusUpdaterRoleBinding, + }, rolebinding); err == nil { + if err = cl.Delete(context.Background(), rolebinding); err != nil { + return err + } + } + + return nil +} + +func CreateBackupSessionStatusUpdaterRBAC(cl client.Client, saName string, namespace string) error { + if saName == "" { + saName = "default" + } + sa := &corev1.ServiceAccount{} + if err := cl.Get(context.Background(), client.ObjectKey{ + Namespace: namespace, + Name: saName, + }, sa); err != nil { + return err + } + role := &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: backupSessionStatusUpdaterRole, + }, + Rules: []rbacv1.PolicyRule{ + rbacv1.PolicyRule{ + Verbs: []string{"get", "list", "watch", "patch", "update"}, + APIGroups: []string{"formol.desmojim.fr"}, + Resources: []string{"backupsessions/status"}, + }, + rbacv1.PolicyRule{ + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{"formol.desmojim.fr"}, + Resources: []string{"backupsessions"}, + }, + }, + } + if err := cl.Get(context.Background(), client.ObjectKey{ + Namespace: namespace, + Name: backupSessionStatusUpdaterRole, + }, role); err != nil && errors.IsNotFound(err) { + if err = cl.Create(context.Background(), role); err != nil { + return err + } + } + rolebinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: backupSessionStatusUpdaterRoleBinding, + }, + Subjects: []rbacv1.Subject{ + rbacv1.Subject{ + Kind: "ServiceAccount", + Name: saName, + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "Role", + Name: backupSessionStatusUpdaterRole, + }, + } + if err := cl.Get(context.Background(), client.ObjectKey{ + Namespace: namespace, + Name: backupSessionStatusUpdaterRoleBinding, + }, rolebinding); err != nil && errors.IsNotFound(err) { + if err = cl.Create(context.Background(), rolebinding); err != nil { + return err + } + } + return nil +}