formol/controllers/backupconfiguration_controller_sidecar.go

138 lines
4.5 KiB
Go

package controllers
import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
formolv1alpha1 "github.com/desmo999r/formol/api/v1alpha1"
)
func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1.BackupConfiguration) error {
removeTags := func(podSpec *corev1.PodSpec, target formolv1alpha1.Target) {
for i, container := range podSpec.Containers {
for _, targetContainer := range target.Containers {
if targetContainer.Name == container.Name {
if container.Env[len(container.Env)-1].Name == formolv1alpha1.TARGETCONTAINER_TAG {
podSpec.Containers[i].Env = container.Env[:len(container.Env)-1]
} else {
for j, e := range container.Env {
if e.Name == formolv1alpha1.TARGETCONTAINER_TAG {
container.Env[j] = container.Env[len(container.Env)-1]
podSpec.Containers[i].Env = container.Env[:len(container.Env)-1]
break
}
}
}
}
}
}
}
for _, target := range backupConf.Spec.Targets {
switch target.TargetKind {
case formolv1alpha1.Deployment:
deployment := &appsv1.Deployment{}
if err := r.Get(r.Context, client.ObjectKey{
Namespace: backupConf.Namespace,
Name: target.TargetName,
}, deployment); err != nil {
r.Log.Error(err, "cannot get deployment", "Deployment", target.TargetName)
return err
}
restoreContainers := []corev1.Container{}
for _, container := range deployment.Spec.Template.Spec.Containers {
if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME {
continue
}
restoreContainers = append(restoreContainers, container)
}
deployment.Spec.Template.Spec.Containers = restoreContainers
removeTags(&deployment.Spec.Template.Spec, target)
if err := r.Update(r.Context, deployment); err != nil {
r.Log.Error(err, "unable to update deployment", "deployment", deployment)
return err
}
}
}
return nil
}
func (r *BackupConfigurationReconciler) AddSidecar(backupConf formolv1alpha1.BackupConfiguration) error {
// Go through all the 'targets'
// the backupType: Online needs a sidecar container for every single listed 'container'
// if the backupType is something else than Online, the 'container' will still need a sidecar
// if it has 'steps'
addTags := func(podSpec *corev1.PodSpec, target formolv1alpha1.Target) bool {
for i, container := range podSpec.Containers {
if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME {
return false
}
for _, targetContainer := range target.Containers {
if targetContainer.Name == container.Name {
podSpec.Containers[i].Env = append(container.Env, corev1.EnvVar{
Name: formolv1alpha1.TARGETCONTAINER_TAG,
Value: container.Name,
})
}
}
}
return true
}
for _, target := range backupConf.Spec.Targets {
addSidecar := false
for _, targetContainer := range target.Containers {
if len(targetContainer.Steps) > 0 {
addSidecar = true
}
}
if target.BackupType == formolv1alpha1.OnlineKind {
addSidecar = true
}
if addSidecar {
repo := formolv1alpha1.Repo{}
if err := r.Get(r.Context, client.ObjectKey{
Namespace: backupConf.Namespace,
Name: backupConf.Spec.Repository,
}, &repo); err != nil {
r.Log.Error(err, "unable to get Repo")
return err
}
r.Log.V(1).Info("Got Repository", "repo", repo)
env := repo.GetResticEnv(backupConf)
sideCar := corev1.Container{
Name: formolv1alpha1.SIDECARCONTAINER_NAME,
Image: backupConf.Spec.Image,
Args: []string{"backupsession", "server"},
Env: append(env, corev1.EnvVar{
Name: formolv1alpha1.TARGET_NAME,
Value: target.TargetName,
}),
VolumeMounts: []corev1.VolumeMount{},
}
switch target.TargetKind {
case formolv1alpha1.Deployment:
deployment := &appsv1.Deployment{}
if err := r.Get(r.Context, client.ObjectKey{
Namespace: backupConf.Namespace,
Name: target.TargetName,
}, deployment); err != nil {
r.Log.Error(err, "cannot get deployment", "Deployment", target.TargetName)
return err
}
if addTags(&deployment.Spec.Template.Spec, target) {
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 err
}
}
}
}
}
return nil
}