diff --git a/api/v1alpha1/backupconfiguration_types.go b/api/v1alpha1/backupconfiguration_types.go index aff1486..582d5bd 100644 --- a/api/v1alpha1/backupconfiguration_types.go +++ b/api/v1alpha1/backupconfiguration_types.go @@ -61,11 +61,6 @@ type Target struct { Retry int `json:"retry"` } -type TargetSidecarPath struct { - TargetName string `json:"targetName"` - SidecarPaths []string `json:"sidecarPaths"` -} - type Keep struct { Last int32 `json:"last"` Daily int32 `json:"daily"` @@ -91,8 +86,6 @@ type BackupConfigurationStatus struct { Suspended bool `json:"suspended"` ActiveCronJob bool `json:"activeCronJob"` ActiveSidecar bool `json:"activeSidecar"` - // +optional - Targets []TargetSidecarPath `json:"targets,omitempty"` } //+kubebuilder:object:root=true diff --git a/api/v1alpha1/common.go b/api/v1alpha1/common.go index 9c21ad6..3491639 100644 --- a/api/v1alpha1/common.go +++ b/api/v1alpha1/common.go @@ -10,4 +10,6 @@ const ( // Used by the backupsession controller POD_NAME string = "POD_NAME" POD_NAMESPACE string = "POD_NAMESPACE" + // Backup Paths list + BACKUP_PATHS = "BACKUP_PATHS" ) diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 1cef863..3cd2fac 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -145,13 +145,6 @@ func (in *BackupConfigurationStatus) DeepCopyInto(out *BackupConfigurationStatus in, out := &in.LastBackupTime, &out.LastBackupTime *out = (*in).DeepCopy() } - if in.Targets != nil { - in, out := &in.Targets, &out.Targets - *out = make([]TargetSidecarPath, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupConfigurationStatus. @@ -617,26 +610,6 @@ func (in *TargetContainer) DeepCopy() *TargetContainer { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TargetSidecarPath) DeepCopyInto(out *TargetSidecarPath) { - *out = *in - if in.SidecarPaths != nil { - in, out := &in.SidecarPaths, &out.SidecarPaths - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetSidecarPath. -func (in *TargetSidecarPath) DeepCopy() *TargetSidecarPath { - if in == nil { - return nil - } - out := new(TargetSidecarPath) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TargetStatus) DeepCopyInto(out *TargetStatus) { *out = *in diff --git a/controllers/backupconfiguration_controller.go b/controllers/backupconfiguration_controller.go index 792d94c..459d05d 100644 --- a/controllers/backupconfiguration_controller.go +++ b/controllers/backupconfiguration_controller.go @@ -97,15 +97,9 @@ func (r *BackupConfigurationReconciler) Reconcile(ctx context.Context, req ctrl. switch target.BackupType { case formolv1alpha1.OnlineKind: // TODO: add a sidecar to the pod with the target.Containers[].Paths mounted - if sidecarPaths, err := r.addOnlineSidecar(backupConf, target); err != nil { + if err := r.addOnlineSidecar(backupConf, target); err != nil { r.Log.Error(err, "unable to add online sidecar") return ctrl.Result{}, err - } else if len(sidecarPaths) > 0 { - backupConf.Status.Targets = append(backupConf.Status.Targets, - formolv1alpha1.TargetSidecarPath{ - TargetName: target.TargetName, - SidecarPaths: sidecarPaths, - }) } backupConf.Status.ActiveSidecar = true case formolv1alpha1.JobKind: diff --git a/controllers/backupconfiguration_controller_helpers.go b/controllers/backupconfiguration_controller_helpers.go index 26c0f9e..7de1a43 100644 --- a/controllers/backupconfiguration_controller_helpers.go +++ b/controllers/backupconfiguration_controller_helpers.go @@ -24,9 +24,11 @@ import ( rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "os" "path/filepath" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "strings" formolv1alpha1 "github.com/desmo999r/formol/api/v1alpha1" ) @@ -178,13 +180,18 @@ func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1. return nil } -func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alpha1.BackupConfiguration, target formolv1alpha1.Target) (sidecarPaths []string, err error) { - addTags := func(sideCar *corev1.Container, podSpec *corev1.PodSpec, target formolv1alpha1.Target) ([]string, bool) { - var sidecarPaths []string +func hasSidecar(podSpec *corev1.PodSpec) bool { + for _, container := range podSpec.Containers { + if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME { + return true + } + } + return false +} + +func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alpha1.BackupConfiguration, target formolv1alpha1.Target) (err error) { + addTags := func(podSpec *corev1.PodSpec, target formolv1alpha1.Target) (sidecarPaths []string, vms []corev1.VolumeMount) { for i, container := range podSpec.Containers { - if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME { - return sidecarPaths, false - } for _, targetContainer := range target.Containers { if targetContainer.Name == container.Name { // Found a target container. Tag it. @@ -209,13 +216,13 @@ func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alph sidecarPath = filepath.Join(vm.MountPath, rel) } } - sideCar.VolumeMounts = append(sideCar.VolumeMounts, vm) + vms = append(vms, vm) sidecarPaths = append(sidecarPaths, sidecarPath) } } } } - return sidecarPaths, true + return } repo := formolv1alpha1.Repo{} @@ -224,11 +231,11 @@ func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alph Name: backupConf.Spec.Repository, }, &repo); err != nil { r.Log.Error(err, "unable to get Repo") - return + return err } r.Log.V(1).Info("Got Repository", "repo", repo) env := repo.GetResticEnv(backupConf) - sideCar := corev1.Container{ + sidecar := corev1.Container{ Name: formolv1alpha1.SIDECARCONTAINER_NAME, Image: backupConf.Spec.Image, Args: []string{"backupsession", "server"}, @@ -247,33 +254,44 @@ func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alph }), VolumeMounts: []corev1.VolumeMount{}, } + var targetObject client.Object + var targetPodSpec *corev1.PodSpec switch target.TargetKind { case formolv1alpha1.Deployment: - deployment := &appsv1.Deployment{} + deployment := appsv1.Deployment{} if err = r.Get(r.Context, client.ObjectKey{ Namespace: backupConf.Namespace, Name: target.TargetName, - }, deployment); err != nil { + }, &deployment); err != nil { r.Log.Error(err, "cannot get deployment", "Deployment", target.TargetName) return } - if paths, add := addTags(&sideCar, &deployment.Spec.Template.Spec, target); add == true { - sidecarPaths = paths - if err = r.createRBACSidecar(corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: deployment.Namespace, - Name: deployment.Spec.Template.Spec.ServiceAccountName, - }, - }); err != nil { - r.Log.Error(err, "unable to create RBAC for the sidecar container") - return - } - deployment.Spec.Template.Spec.Containers = append(deployment.Spec.Template.Spec.Containers, sideCar) - r.Log.V(1).Info("Updating deployment", "deployment", deployment, "containers", deployment.Spec.Template.Spec.Containers) - if err = r.Update(r.Context, deployment); err != nil { - r.Log.Error(err, "cannot update deployment", "Deployment", deployment) - return - } + targetObject = &deployment + targetPodSpec = &deployment.Spec.Template.Spec + } + if !hasSidecar(targetPodSpec) { + if err = r.createRBACSidecar(corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: backupConf.Namespace, + Name: targetPodSpec.ServiceAccountName, + }, + }); err != nil { + r.Log.Error(err, "unable to create RBAC for the sidecar container") + return + } + sidecarPaths, vms := addTags(targetPodSpec, target) + sidecar.VolumeMounts = vms + sidecar.Env = append(sidecar.Env, corev1.EnvVar{ + Name: formolv1alpha1.BACKUP_PATHS, + Value: strings.Join(sidecarPaths, string(os.PathListSeparator)), + }) + + // The sidecar definition is complete. Add it to the targetObject + targetPodSpec.Containers = append(targetPodSpec.Containers, sidecar) + r.Log.V(1).Info("Adding sidecar", "targetObject", targetObject, "sidecar", sidecar) + if err = r.Update(r.Context, targetObject); err != nil { + r.Log.Error(err, "unable to add sidecar", "targetObject", targetObject) + return } }