Create/Delete RBAC. Restore deployment to original state when BackupConfiguration is deleted
This commit is contained in:
parent
43fb07ddea
commit
cfbfd38ae4
@ -48,8 +48,6 @@ type BackupConfigurationSpec struct {
|
|||||||
// +optional
|
// +optional
|
||||||
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
|
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
|
||||||
Paths []string `json:"paths"`
|
Paths []string `json:"paths"`
|
||||||
// +optional
|
|
||||||
Suspend *bool `json:"suspend,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BackupConfigurationStatus defines the observed state of BackupConfiguration
|
// BackupConfigurationStatus defines the observed state of BackupConfiguration
|
||||||
@ -62,10 +60,9 @@ type BackupConfigurationStatus struct {
|
|||||||
ActiveSidecar bool `json:"activeSidecar"`
|
ActiveSidecar bool `json:"activeSidecar"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BackupConfiguration is the Schema for the backupconfigurations API
|
||||||
// +kubebuilder:object:root=true
|
// +kubebuilder:object:root=true
|
||||||
// +kubebuilder:subresource:status
|
// +kubebuilder:subresource:status
|
||||||
|
|
||||||
// BackupConfiguration is the Schema for the backupconfigurations API
|
|
||||||
type BackupConfiguration struct {
|
type BackupConfiguration struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|||||||
@ -118,11 +118,6 @@ func (in *BackupConfigurationSpec) DeepCopyInto(out *BackupConfigurationSpec) {
|
|||||||
*out = make([]string, len(*in))
|
*out = make([]string, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
if in.Suspend != nil {
|
|
||||||
in, out := &in.Suspend, &out.Suspend
|
|
||||||
*out = new(bool)
|
|
||||||
**out = **in
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupConfigurationSpec.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupConfigurationSpec.
|
||||||
|
|||||||
@ -19,17 +19,20 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
formolrbac "github.com/desmo999r/formol/pkg/rbac"
|
||||||
|
formolutils "github.com/desmo999r/formol/pkg/utils"
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
batchv1 "k8s.io/api/batch/v1"
|
batchv1 "k8s.io/api/batch/v1"
|
||||||
kbatch_beta1 "k8s.io/api/batch/v1beta1"
|
kbatch_beta1 "k8s.io/api/batch/v1beta1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
// rbacv1 "k8s.io/api/rbac/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||||
|
|
||||||
formolv1alpha1 "github.com/desmo999r/formol/api/v1alpha1"
|
formolv1alpha1 "github.com/desmo999r/formol/api/v1alpha1"
|
||||||
)
|
)
|
||||||
@ -41,6 +44,16 @@ type BackupConfigurationReconciler struct {
|
|||||||
Scheme *runtime.Scheme
|
Scheme *runtime.Scheme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *BackupConfigurationReconciler) getDeployment(namespace string, name string) (*appsv1.Deployment, error) {
|
||||||
|
|
||||||
|
deployment := &appsv1.Deployment{}
|
||||||
|
err := r.Get(context.Background(), client.ObjectKey{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
}, deployment)
|
||||||
|
return deployment, err
|
||||||
|
}
|
||||||
|
|
||||||
// +kubebuilder:rbac:groups=formol.desmojim.fr,resources=backupconfigurations,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=formol.desmojim.fr,resources=backupconfigurations,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=formol.desmojim.fr,resources=backupconfigurations/status,verbs=get;update;patch
|
// +kubebuilder:rbac:groups=formol.desmojim.fr,resources=backupconfigurations/status,verbs=get;update;patch
|
||||||
// +kubebuilder:rbac:groups=formol.desmojim.fr,resources=repoes,verbs=get;list;watch
|
// +kubebuilder:rbac:groups=formol.desmojim.fr,resources=repoes,verbs=get;list;watch
|
||||||
@ -49,23 +62,65 @@ type BackupConfigurationReconciler struct {
|
|||||||
// +kubebuilder:rbac:groups=batch,resources=cronjobs,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=batch,resources=cronjobs,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=batch,resources=cronjobs/status,verbs=get
|
// +kubebuilder:rbac:groups=batch,resources=cronjobs/status,verbs=get
|
||||||
|
|
||||||
func (r *BackupConfigurationReconciler) addSidecarContainer(backupConf *formolv1alpha1.BackupConfiguration) error {
|
func (r *BackupConfigurationReconciler) deleteSidecarContainer(backupConf *formolv1alpha1.BackupConfiguration) error {
|
||||||
log := r.Log.WithValues("backupconf", backupConf.Name)
|
deployment, err := r.getDeployment(backupConf.Namespace, backupConf.Spec.Target.Name)
|
||||||
getDeployment := func() (*appsv1.Deployment, error) {
|
if err != nil {
|
||||||
deployment := &appsv1.Deployment{}
|
return err
|
||||||
err := r.Get(context.Background(), client.ObjectKey{
|
}
|
||||||
Namespace: backupConf.Namespace,
|
restorecontainers := []corev1.Container{}
|
||||||
Name: backupConf.Spec.Target.Name,
|
for _, container := range deployment.Spec.Template.Spec.Containers {
|
||||||
}, deployment)
|
if container.Name == "backup" {
|
||||||
return deployment, err
|
continue
|
||||||
|
}
|
||||||
|
restorecontainers = append(restorecontainers, container)
|
||||||
|
}
|
||||||
|
deployment.Spec.Template.Spec.Containers = restorecontainers
|
||||||
|
if err := r.Update(context.Background(), deployment); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
selector, err := metav1.LabelSelectorAsMap(deployment.Spec.Selector)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
pods := &corev1.PodList{}
|
||||||
|
err = r.List(context.Background(), pods, client.MatchingLabels(selector))
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
replicasToDelete := []appsv1.ReplicaSet{}
|
||||||
|
for _, pod := range pods.Items {
|
||||||
|
for _, podRef := range pod.OwnerReferences {
|
||||||
|
rs := &appsv1.ReplicaSet{}
|
||||||
|
if err := r.Get(context.Background(), client.ObjectKey{
|
||||||
|
Name: podRef.Name,
|
||||||
|
Namespace: pod.Namespace,
|
||||||
|
}, rs); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, rsRef := range rs.OwnerReferences {
|
||||||
|
if rsRef.Kind == deployment.Kind && rsRef.Name == deployment.Name {
|
||||||
|
replicasToDelete = append(replicasToDelete, *rs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deployment, err := getDeployment()
|
for _, replica := range replicasToDelete {
|
||||||
|
if err := r.Delete(context.TODO(), &replica); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *BackupConfigurationReconciler) addSidecarContainer(backupConf *formolv1alpha1.BackupConfiguration) error {
|
||||||
|
log := r.Log.WithValues("backupconf", backupConf.Name)
|
||||||
|
deployment, err := r.getDeployment(backupConf.Namespace, backupConf.Spec.Target.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err, "unable to get Deployment")
|
log.Error(err, "unable to get Deployment")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.WithValues("Deployment", backupConf.Spec.Target.Name)
|
log.V(1).Info("got deployment", "Deployment", deployment)
|
||||||
for _, container := range deployment.Spec.Template.Spec.Containers {
|
for _, container := range deployment.Spec.Template.Spec.Containers {
|
||||||
if container.Name == "backup" {
|
if container.Name == "backup" {
|
||||||
log.V(0).Info("There is already a backup sidecar container. Skipping", "container", container)
|
log.V(0).Info("There is already a backup sidecar container. Skipping", "container", container)
|
||||||
@ -155,7 +210,7 @@ func (r *BackupConfigurationReconciler) addSidecarContainer(backupConf *formolv1
|
|||||||
log.Error(err, "unable to get deployment pods")
|
log.Error(err, "unable to get deployment pods")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
podsToDelete := []appsv1.ReplicaSet{}
|
replicasToDelete := []appsv1.ReplicaSet{}
|
||||||
log.V(1).Info("got that list of pods", "pods", len(pods.Items))
|
log.V(1).Info("got that list of pods", "pods", len(pods.Items))
|
||||||
for _, pod := range pods.Items {
|
for _, pod := range pods.Items {
|
||||||
log.V(1).Info("checking pod", "pod", pod)
|
log.V(1).Info("checking pod", "pod", pod)
|
||||||
@ -172,78 +227,35 @@ func (r *BackupConfigurationReconciler) addSidecarContainer(backupConf *formolv1
|
|||||||
for _, rsRef := range rs.OwnerReferences {
|
for _, rsRef := range rs.OwnerReferences {
|
||||||
if rsRef.Kind == deployment.Kind && rsRef.Name == deployment.Name {
|
if rsRef.Kind == deployment.Kind && rsRef.Name == deployment.Name {
|
||||||
log.V(0).Info("Adding pod to the list of pods to be restarted", "pod", pod.Name)
|
log.V(0).Info("Adding pod to the list of pods to be restarted", "pod", pod.Name)
|
||||||
podsToDelete = append(podsToDelete, *rs)
|
replicasToDelete = append(replicasToDelete, *rs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
deployment.Spec.Template.Spec.Containers = append(deployment.Spec.Template.Spec.Containers, sidecar)
|
deployment.Spec.Template.Spec.Containers = append(deployment.Spec.Template.Spec.Containers, sidecar)
|
||||||
|
|
||||||
|
if err := formolrbac.CreateBackupSessionListenerRBAC(r.Client, deployment.Spec.Template.Spec.ServiceAccountName, deployment.Namespace); err != nil {
|
||||||
|
log.Error(err, "unable to create backupsessionlistener RBAC")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
log.V(0).Info("Adding a sicar container")
|
log.V(0).Info("Adding a sicar container")
|
||||||
if err := r.Update(context.Background(), deployment); err != nil {
|
if err := r.Update(context.Background(), deployment); err != nil {
|
||||||
log.Error(err, "unable to update the Deployment")
|
log.Error(err, "unable to update the Deployment")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, pod := range podsToDelete {
|
for _, replica := range replicasToDelete {
|
||||||
if err := r.Delete(context.TODO(), &pod); err != nil {
|
if err := r.Delete(context.TODO(), &replica); err != nil {
|
||||||
log.Error(err, "unable to delete pod", "pod", pod.Name)
|
log.Error(err, "unable to delete replica", "replica", replica.Name)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
deployment, err = getDeployment()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err, "unable to get Deployment")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *BackupConfigurationReconciler) addCronJob(backupConf *formolv1alpha1.BackupConfiguration) error {
|
func (r *BackupConfigurationReconciler) addCronJob(backupConf *formolv1alpha1.BackupConfiguration) error {
|
||||||
log := r.Log.WithName("addCronJob")
|
log := r.Log.WithName("addCronJob")
|
||||||
|
|
||||||
// serviceaccount := &corev1.ServiceAccount{
|
|
||||||
// ObjectMeta: metav1.ObjectMeta{
|
|
||||||
// Namespace: backupConf.Namespace,
|
|
||||||
// Name: "backupsession-creator",
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// if err := r.Get(context.Background(), client.ObjectKey{
|
|
||||||
// Namespace: backupConf.Namespace,
|
|
||||||
// Name: "backupsession-creator",
|
|
||||||
// }, serviceaccount); err != nil && errors.IsNotFound(err) {
|
|
||||||
// log.V(0).Info("creating service account", "service account", serviceaccount)
|
|
||||||
// if err = r.Create(context.Background(), serviceaccount); err != nil {
|
|
||||||
// log.Error(err, "unable to create serviceaccount", "serviceaccount", serviceaccount)
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// rolebinding := &rbacv1.RoleBinding{
|
|
||||||
// ObjectMeta: metav1.ObjectMeta{
|
|
||||||
// Namespace: backupConf.Namespace,
|
|
||||||
// Name: "backupsession-creator-rolebinding",
|
|
||||||
// },
|
|
||||||
// Subjects: []rbacv1.Subject{
|
|
||||||
// rbacv1.Subject{
|
|
||||||
// Kind: "ServiceAccount",
|
|
||||||
// Name: "backupsession-creator",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// RoleRef: rbacv1.RoleRef{
|
|
||||||
// APIGroup: "rbac.authorization.k8s.io",
|
|
||||||
// Kind: "ClusterRole",
|
|
||||||
// Name: "backupsession-creator",
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// if err := r.Get(context.Background(), client.ObjectKey{
|
|
||||||
// Namespace: backupConf.Namespace,
|
|
||||||
// Name: "backupsession-creator-rolebinding",
|
|
||||||
// }, rolebinding); err != nil && errors.IsNotFound(err) {
|
|
||||||
// log.V(0).Info("creating role binding for service account", "rolebinding", rolebinding, "service account", serviceaccount)
|
|
||||||
// if err = r.Create(context.Background(), rolebinding); err != nil {
|
|
||||||
// log.Error(err, "unable to create rolebinding", "rolebinding", rolebinding)
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
cronjob := &kbatch_beta1.CronJob{}
|
cronjob := &kbatch_beta1.CronJob{}
|
||||||
if err := r.Get(context.Background(), client.ObjectKey{
|
if err := r.Get(context.Background(), client.ObjectKey{
|
||||||
Namespace: backupConf.Namespace,
|
Namespace: backupConf.Namespace,
|
||||||
@ -256,6 +268,11 @@ func (r *BackupConfigurationReconciler) addCronJob(backupConf *formolv1alpha1.Ba
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := formolrbac.CreateBackupSessionCreatorRBAC(r.Client, backupConf.Namespace); err != nil {
|
||||||
|
log.Error(err, "unable to create backupsession-creator RBAC")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
cronjob = &kbatch_beta1.CronJob{
|
cronjob = &kbatch_beta1.CronJob{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "backup-" + backupConf.Name,
|
Name: "backup-" + backupConf.Name,
|
||||||
@ -310,10 +327,35 @@ func (r *BackupConfigurationReconciler) Reconcile(req ctrl.Request) (ctrl.Result
|
|||||||
// your logic here
|
// your logic here
|
||||||
backupConf := &formolv1alpha1.BackupConfiguration{}
|
backupConf := &formolv1alpha1.BackupConfiguration{}
|
||||||
if err := r.Get(ctx, req.NamespacedName, backupConf); err != nil {
|
if err := r.Get(ctx, req.NamespacedName, backupConf); err != nil {
|
||||||
log.Error(err, "unable to fetch BackupConfiguration")
|
|
||||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finalizerName := "finalizer.backupconfiguration.formol.desmojim.fr"
|
||||||
|
|
||||||
|
if backupConf.ObjectMeta.DeletionTimestamp.IsZero() {
|
||||||
|
if !formolutils.ContainsString(backupConf.ObjectMeta.Finalizers, finalizerName) {
|
||||||
|
backupConf.ObjectMeta.Finalizers = append(backupConf.ObjectMeta.Finalizers, finalizerName)
|
||||||
|
if err := r.Update(context.Background(), backupConf); err != nil {
|
||||||
|
log.Error(err, "unable to append finalizer")
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.V(0).Info("backupconf being deleted", "backupconf", backupConf.Name)
|
||||||
|
if formolutils.ContainsString(backupConf.ObjectMeta.Finalizers, finalizerName) {
|
||||||
|
if err := r.deleteExternelResources(backupConf); err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
backupConf.ObjectMeta.Finalizers = formolutils.RemoveString(backupConf.ObjectMeta.Finalizers, finalizerName)
|
||||||
|
if err := r.Update(context.Background(), backupConf); err != nil {
|
||||||
|
log.Error(err, "unable to remove finalizer")
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
// We have been deleted. Return here
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
if err := r.addCronJob(backupConf); err != nil {
|
if err := r.addCronJob(backupConf); err != nil {
|
||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
@ -330,12 +372,7 @@ func (r *BackupConfigurationReconciler) Reconcile(req ctrl.Request) (ctrl.Result
|
|||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if backupConf.Spec.Suspend != nil && *backupConf.Spec.Suspend == true {
|
backupConf.Status.Suspended = false
|
||||||
log.V(0).Info("We are suspended return and wait for the next event")
|
|
||||||
// TODO Suspend the CronJob
|
|
||||||
return ctrl.Result{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
log.V(1).Info("updating backupconf")
|
log.V(1).Info("updating backupconf")
|
||||||
if err := r.Status().Update(ctx, backupConf); err != nil {
|
if err := r.Status().Update(ctx, backupConf); err != nil {
|
||||||
log.Error(err, "unable to update backupconf", "backupconf", backupConf)
|
log.Error(err, "unable to update backupconf", "backupconf", backupConf)
|
||||||
@ -345,9 +382,28 @@ func (r *BackupConfigurationReconciler) Reconcile(req ctrl.Request) (ctrl.Result
|
|||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *BackupConfigurationReconciler) deleteExternelResources(backupConf *formolv1alpha1.BackupConfiguration) error {
|
||||||
|
deployment, err := r.getDeployment(backupConf.Namespace, backupConf.Spec.Target.Name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
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); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *BackupConfigurationReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
func (r *BackupConfigurationReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||||
return ctrl.NewControllerManagedBy(mgr).
|
return ctrl.NewControllerManagedBy(mgr).
|
||||||
For(&formolv1alpha1.BackupConfiguration{}).
|
For(&formolv1alpha1.BackupConfiguration{}).
|
||||||
Owns(&kbatch_beta1.CronJob{}).
|
WithOptions(controller.Options{MaxConcurrentReconciles: 3}).
|
||||||
|
WithEventFilter(predicate.GenerationChangedPredicate{}).
|
||||||
|
// Owns(&kbatch_beta1.CronJob{}).
|
||||||
Complete(r)
|
Complete(r)
|
||||||
}
|
}
|
||||||
|
|||||||
14
go.mod
14
go.mod
@ -4,10 +4,12 @@ go 1.13
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-logr/logr v0.1.0
|
github.com/go-logr/logr v0.1.0
|
||||||
github.com/onsi/ginkgo v1.11.0
|
github.com/onsi/ginkgo v1.12.1
|
||||||
github.com/onsi/gomega v1.8.1
|
github.com/onsi/gomega v1.10.1
|
||||||
k8s.io/api v0.17.2
|
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e // indirect
|
||||||
k8s.io/apimachinery v0.17.2
|
k8s.io/api v0.18.6
|
||||||
k8s.io/client-go v0.17.2
|
k8s.io/apimachinery v0.18.6
|
||||||
sigs.k8s.io/controller-runtime v0.5.0
|
k8s.io/client-go v0.18.6
|
||||||
|
sigs.k8s.io/controller-runtime v0.6.4
|
||||||
|
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
16
main.go
16
main.go
@ -74,14 +74,14 @@ func main() {
|
|||||||
setupLog.Error(err, "unable to create controller", "controller", "BackupConfiguration")
|
setupLog.Error(err, "unable to create controller", "controller", "BackupConfiguration")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
if err = (&controllers.BackupSessionReconciler{
|
// if err = (&controllers.BackupSessionReconciler{
|
||||||
Client: mgr.GetClient(),
|
// Client: mgr.GetClient(),
|
||||||
Log: ctrl.Log.WithName("controllers").WithName("BackupSession"),
|
// Log: ctrl.Log.WithName("controllers").WithName("BackupSession"),
|
||||||
Scheme: mgr.GetScheme(),
|
// Scheme: mgr.GetScheme(),
|
||||||
}).SetupWithManager(mgr); err != nil {
|
// }).SetupWithManager(mgr); err != nil {
|
||||||
setupLog.Error(err, "unable to create controller", "controller", "BackupSession")
|
// setupLog.Error(err, "unable to create controller", "controller", "BackupSession")
|
||||||
os.Exit(1)
|
// os.Exit(1)
|
||||||
}
|
// }
|
||||||
if os.Getenv("ENABLE_WEBHOOKS") != "false" {
|
if os.Getenv("ENABLE_WEBHOOKS") != "false" {
|
||||||
if err = (&formolv1alpha1.BackupSession{}).SetupWebhookWithManager(mgr); err != nil {
|
if err = (&formolv1alpha1.BackupSession{}).SetupWebhookWithManager(mgr); err != nil {
|
||||||
setupLog.Error(err, "unable to create webhook", "webhook", "BackupSession")
|
setupLog.Error(err, "unable to create webhook", "webhook", "BackupSession")
|
||||||
|
|||||||
231
pkg/rbac/backupconfiguration.go
Normal file
231
pkg/rbac/backupconfiguration.go
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
package rbac
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
backupListenerRole = "backup-listener-role"
|
||||||
|
backupListenerRoleBinding = "backup-listener-rolebinding"
|
||||||
|
backupSessionCreatorSA = "backupsession-creator"
|
||||||
|
backupSessionCreatorRole = "backupsession-creator-role"
|
||||||
|
backupSessionCreatorRoleBinding = "backupsession-creator-rolebinding"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DeleteBackupSessionCreatorRBAC(cl client.Client, namespace string) error {
|
||||||
|
serviceaccount := &corev1.ServiceAccount{}
|
||||||
|
if err := cl.Get(context.Background(), client.ObjectKey{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: backupSessionCreatorSA,
|
||||||
|
}, serviceaccount); err == nil {
|
||||||
|
if err = cl.Delete(context.Background(), serviceaccount); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
role := &rbacv1.Role{}
|
||||||
|
if err := cl.Get(context.Background(), client.ObjectKey{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: backupSessionCreatorRole,
|
||||||
|
}, 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: backupSessionCreatorRoleBinding,
|
||||||
|
}, rolebinding); err == nil {
|
||||||
|
if err = cl.Delete(context.Background(), rolebinding); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateBackupSessionCreatorRBAC(cl client.Client, namespace string) error {
|
||||||
|
serviceaccount := &corev1.ServiceAccount{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: backupSessionCreatorSA,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := cl.Get(context.Background(), client.ObjectKey{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: backupSessionCreatorSA,
|
||||||
|
}, serviceaccount); err != nil && errors.IsNotFound(err) {
|
||||||
|
if err = cl.Create(context.Background(), serviceaccount); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
role := &rbacv1.Role{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: backupSessionCreatorRole,
|
||||||
|
},
|
||||||
|
Rules: []rbacv1.PolicyRule{
|
||||||
|
rbacv1.PolicyRule{
|
||||||
|
Verbs: []string{"get", "list", "watch", "create", "update", "patch", "delete"},
|
||||||
|
APIGroups: []string{"formol.desmojim.fr"},
|
||||||
|
Resources: []string{"backupsessions"},
|
||||||
|
},
|
||||||
|
rbacv1.PolicyRule{
|
||||||
|
Verbs: []string{"get", "list", "watch"},
|
||||||
|
APIGroups: []string{"formol.desmojim.fr"},
|
||||||
|
Resources: []string{"backupconfigurations"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := cl.Get(context.Background(), client.ObjectKey{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: backupSessionCreatorRole,
|
||||||
|
}, 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: backupSessionCreatorRoleBinding,
|
||||||
|
},
|
||||||
|
Subjects: []rbacv1.Subject{
|
||||||
|
rbacv1.Subject{
|
||||||
|
Kind: "ServiceAccount",
|
||||||
|
Name: backupSessionCreatorSA,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RoleRef: rbacv1.RoleRef{
|
||||||
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
|
Kind: "Role",
|
||||||
|
Name: backupSessionCreatorRole,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := cl.Get(context.Background(), client.ObjectKey{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: backupSessionCreatorRoleBinding,
|
||||||
|
}, rolebinding); err != nil && errors.IsNotFound(err) {
|
||||||
|
if err = cl.Create(context.Background(), rolebinding); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteBackupSessionListenerRBAC(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: backupListenerRole,
|
||||||
|
}, 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: backupListenerRoleBinding,
|
||||||
|
}, rolebinding); err == nil {
|
||||||
|
if err = cl.Delete(context.Background(), rolebinding); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateBackupSessionListenerRBAC(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: backupListenerRole,
|
||||||
|
},
|
||||||
|
Rules: []rbacv1.PolicyRule{
|
||||||
|
rbacv1.PolicyRule{
|
||||||
|
Verbs: []string{"get", "list", "watch"},
|
||||||
|
APIGroups: []string{""},
|
||||||
|
Resources: []string{"pods"},
|
||||||
|
},
|
||||||
|
rbacv1.PolicyRule{
|
||||||
|
Verbs: []string{"get", "list", "watch"},
|
||||||
|
APIGroups: []string{"apps"},
|
||||||
|
Resources: []string{"deployments", "replicasets"},
|
||||||
|
},
|
||||||
|
rbacv1.PolicyRule{
|
||||||
|
Verbs: []string{"get", "list", "watch"},
|
||||||
|
APIGroups: []string{"formol.desmojim.fr"},
|
||||||
|
Resources: []string{"backupsessions", "backupconfigurations"},
|
||||||
|
},
|
||||||
|
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{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: backupListenerRole,
|
||||||
|
}, 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: backupListenerRoleBinding,
|
||||||
|
},
|
||||||
|
Subjects: []rbacv1.Subject{
|
||||||
|
rbacv1.Subject{
|
||||||
|
Kind: "ServiceAccount",
|
||||||
|
Name: saName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RoleRef: rbacv1.RoleRef{
|
||||||
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
|
Kind: "Role",
|
||||||
|
Name: backupListenerRole,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := cl.Get(context.Background(), client.ObjectKey{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: backupListenerRoleBinding,
|
||||||
|
}, rolebinding); err != nil && errors.IsNotFound(err) {
|
||||||
|
if err = cl.Create(context.Background(), rolebinding); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
20
pkg/utils/root.go
Normal file
20
pkg/utils/root.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
func ContainsString(slice []string, s string) bool {
|
||||||
|
for _, item := range slice {
|
||||||
|
if item == s {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveString(slice []string, s string) (result []string) {
|
||||||
|
for _, item := range slice {
|
||||||
|
if item == s {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result = append(result, item)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
@ -52,86 +52,6 @@ spec:
|
|||||||
storage: 50Mi
|
storage: 50Mi
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: backupsession-creator
|
|
||||||
namespace: demo
|
|
||||||
labels:
|
|
||||||
app: backupsession-creator
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: backup-listener
|
|
||||||
labels:
|
|
||||||
app: backup-listener
|
|
||||||
rules:
|
|
||||||
- apiGroups: ["formol.desmojim.fr"]
|
|
||||||
resources: ["backupsessions", "backupconfigurations"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["formol.desmojim.fr"]
|
|
||||||
resources: ["backupsessions/status"]
|
|
||||||
verbs: ["update"]
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
||||||
kind: Role
|
|
||||||
metadata:
|
|
||||||
name: backupsession-creator
|
|
||||||
namespace: demo
|
|
||||||
labels:
|
|
||||||
app: backupsession-creator
|
|
||||||
rules:
|
|
||||||
- apiGroups: ["formol.desmojim.fr"]
|
|
||||||
resources: ["backupsessions"]
|
|
||||||
verbs: ["get", "list", "create", "delete"]
|
|
||||||
- apiGroups: ["formol.desmojim.fr"]
|
|
||||||
resources: ["backupconfigurations"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
||||||
kind: RoleBinding
|
|
||||||
metadata:
|
|
||||||
name: backupsession-creator
|
|
||||||
namespace: demo
|
|
||||||
labels:
|
|
||||||
app: backupsession-creator
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: Role
|
|
||||||
name: backupsession-creator
|
|
||||||
subjects:
|
|
||||||
- name: backupsession-creator
|
|
||||||
kind: ServiceAccount
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
metadata:
|
|
||||||
name: backup-listener
|
|
||||||
labels:
|
|
||||||
app: backup-listener
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: ClusterRole
|
|
||||||
name: backup-listener
|
|
||||||
subjects:
|
|
||||||
- name: default
|
|
||||||
namespace: demo
|
|
||||||
kind: ServiceAccount
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
|
||||||
kind: RoleBinding
|
|
||||||
metadata:
|
|
||||||
name: demo-viewer
|
|
||||||
namespace: demo
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: ClusterRole
|
|
||||||
name: view
|
|
||||||
subjects:
|
|
||||||
- name: default
|
|
||||||
kind: ServiceAccount
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: secret-minio
|
name: secret-minio
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user