Compare commits
2 Commits
6c2fa76111
...
cfea083594
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfea083594 | ||
|
|
9f91876dd2 |
@ -30,8 +30,6 @@ const (
|
||||
AWS_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
type S3 struct {
|
||||
Server string `json:"server"`
|
||||
Bucket string `json:"bucket"`
|
||||
@ -39,11 +37,15 @@ type S3 struct {
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
}
|
||||
|
||||
type Local struct {
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type Backend struct {
|
||||
// +optional
|
||||
S3 *S3 `json:"s3,omitempty"`
|
||||
// +optional
|
||||
Nfs *string `json:"nfs,omitempty"`
|
||||
Local *Local `json:"local,omitempty"`
|
||||
}
|
||||
|
||||
// RepoSpec defines the desired state of Repo
|
||||
@ -96,7 +98,6 @@ func (repo *Repo) GetResticEnv(backupConf BackupConfiguration) []corev1.EnvVar {
|
||||
for _, key := range []string{
|
||||
AWS_ACCESS_KEY_ID,
|
||||
AWS_SECRET_ACCESS_KEY,
|
||||
RESTIC_PASSWORD,
|
||||
} {
|
||||
env = append(env, corev1.EnvVar{
|
||||
Name: key,
|
||||
@ -111,6 +112,23 @@ func (repo *Repo) GetResticEnv(backupConf BackupConfiguration) []corev1.EnvVar {
|
||||
})
|
||||
}
|
||||
}
|
||||
if repo.Spec.Backend.Local != nil {
|
||||
env = append(env, corev1.EnvVar{
|
||||
Name: RESTIC_REPOSITORY,
|
||||
Value: repo.Spec.Backend.Local.Path,
|
||||
})
|
||||
}
|
||||
env = append(env, corev1.EnvVar{
|
||||
Name: RESTIC_PASSWORD,
|
||||
ValueFrom: &corev1.EnvVarSource{
|
||||
SecretKeyRef: &corev1.SecretKeySelector{
|
||||
LocalObjectReference: corev1.LocalObjectReference{
|
||||
Name: repo.Spec.RepositorySecrets,
|
||||
},
|
||||
Key: RESTIC_PASSWORD,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return env
|
||||
}
|
||||
|
||||
@ -34,9 +34,9 @@ func (in *Backend) DeepCopyInto(out *Backend) {
|
||||
*out = new(S3)
|
||||
**out = **in
|
||||
}
|
||||
if in.Nfs != nil {
|
||||
in, out := &in.Nfs, &out.Nfs
|
||||
*out = new(string)
|
||||
if in.Local != nil {
|
||||
in, out := &in.Local, &out.Local
|
||||
*out = new(Local)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
@ -347,6 +347,21 @@ func (in *Keep) DeepCopy() *Keep {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Local) DeepCopyInto(out *Local) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Local.
|
||||
func (in *Local) DeepCopy() *Local {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Local)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Repo) DeepCopyInto(out *Repo) {
|
||||
*out = *in
|
||||
|
||||
@ -150,30 +150,54 @@ func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1.
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
for _, target := range backupConf.Spec.Targets {
|
||||
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 err
|
||||
}
|
||||
restoreContainers := []corev1.Container{}
|
||||
for _, container := range deployment.Spec.Template.Spec.Containers {
|
||||
if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME {
|
||||
targetObject = &deployment
|
||||
targetPodSpec = &deployment.Spec.Template.Spec
|
||||
|
||||
}
|
||||
restoreContainers := []corev1.Container{}
|
||||
for _, container := range targetPodSpec.Containers {
|
||||
if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME {
|
||||
continue
|
||||
}
|
||||
restoreContainers = append(restoreContainers, container)
|
||||
}
|
||||
targetPodSpec.Containers = restoreContainers
|
||||
if repo.Spec.Backend.Local != nil {
|
||||
restoreVolumes := []corev1.Volume{}
|
||||
for _, volume := range targetPodSpec.Volumes {
|
||||
if volume.Name == "restic-local-repo" {
|
||||
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
|
||||
restoreVolumes = append(restoreVolumes, volume)
|
||||
}
|
||||
targetPodSpec.Volumes = restoreVolumes
|
||||
}
|
||||
removeTags(targetPodSpec, target)
|
||||
if err := r.Update(r.Context, targetObject); err != nil {
|
||||
r.Log.Error(err, "unable to remove sidecar", "targetObject", targetObject)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,14 +304,28 @@ func (r *BackupConfigurationReconciler) addOnlineSidecar(backupConf formolv1alph
|
||||
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)),
|
||||
})
|
||||
if repo.Spec.Backend.Local != nil {
|
||||
sidecar.VolumeMounts = append(vms, corev1.VolumeMount{
|
||||
Name: "restic-local-repo",
|
||||
MountPath: "/repo",
|
||||
})
|
||||
targetPodSpec.Volumes = append(targetPodSpec.Volumes, corev1.Volume{
|
||||
Name: "restic-local-repo",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
||||
},
|
||||
})
|
||||
} else {
|
||||
sidecar.VolumeMounts = vms
|
||||
}
|
||||
|
||||
// The sidecar definition is complete. Add it to the targetObject
|
||||
targetPodSpec.Containers = append(targetPodSpec.Containers, sidecar)
|
||||
targetPodSpec.ShareProcessNamespace = func() *bool { b := true; return &b }()
|
||||
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)
|
||||
@ -333,7 +371,7 @@ func (r *BackupConfigurationReconciler) createRBACSidecar(sa corev1.ServiceAccou
|
||||
rbacv1.PolicyRule{
|
||||
Verbs: []string{"get", "list", "watch"},
|
||||
APIGroups: []string{"formol.desmojim.fr"},
|
||||
Resources: []string{"backupsessions", "backupconfigurations"},
|
||||
Resources: []string{"backupsessions", "backupconfigurations", "functions", "repos"},
|
||||
},
|
||||
rbacv1.PolicyRule{
|
||||
Verbs: []string{"get", "list", "watch", "create", "update", "patch", "delete"},
|
||||
|
||||
@ -74,11 +74,12 @@ data:
|
||||
apiVersion: formol.desmojim.fr/v1alpha1
|
||||
kind: Repo
|
||||
metadata:
|
||||
name: repo-empty
|
||||
name: repo-local
|
||||
namespace: demo
|
||||
spec:
|
||||
backend:
|
||||
nfs: "toto"
|
||||
local:
|
||||
path: /repo
|
||||
repositorySecrets: secret-minio
|
||||
---
|
||||
apiVersion: formol.desmojim.fr/v1alpha1
|
||||
@ -162,7 +163,7 @@ metadata:
|
||||
namespace: demo
|
||||
spec:
|
||||
name: maintenance-off
|
||||
command: ["/bin/bash", "-c", "echo $(date +%Y/%m/%d-%H:%M:%S) maintenance-off >> /data/logs.txt"]
|
||||
command: ["/bin/sh", "-c", "echo $(date +%Y/%m/%d-%H:%M:%S) maintenance-off >> /data/logs.txt"]
|
||||
---
|
||||
apiVersion: formol.desmojim.fr/v1alpha1
|
||||
kind: Function
|
||||
@ -171,4 +172,4 @@ metadata:
|
||||
namespace: demo
|
||||
spec:
|
||||
name: maintenance-on
|
||||
command: ["/bin/bash", "-c", "echo $(date +%Y/%m/%d-%H:%M:%S) maintenance-on >> /data/logs.txt"]
|
||||
command: ["/bin/sh", "-c", "echo $(date +%Y/%m/%d-%H:%M:%S) maintenance-on >> /data/logs.txt"]
|
||||
|
||||
@ -2,27 +2,27 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
name: apache-deployment
|
||||
namespace: demo
|
||||
labels:
|
||||
app: nginx
|
||||
app: apache
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
app: apache
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
app: apache
|
||||
spec:
|
||||
imagePullSecrets:
|
||||
- name: regcred
|
||||
containers:
|
||||
- name: nginx
|
||||
image: docker.io/nginx:1.23.3
|
||||
- name: apache
|
||||
image: docker.io/httpd:alpine3.17
|
||||
ports:
|
||||
- containerPort: 80
|
||||
volumeMounts:
|
||||
|
||||
@ -7,7 +7,7 @@ metadata:
|
||||
spec:
|
||||
suspend: true
|
||||
image: desmo999r/formolcli:latest
|
||||
repository: repo-minio
|
||||
repository: repo-local
|
||||
schedule: "15 * * * *"
|
||||
keep:
|
||||
last: 5
|
||||
@ -18,13 +18,11 @@ spec:
|
||||
targets:
|
||||
- backupType: Online
|
||||
targetKind: Deployment
|
||||
targetName: nginx-deployment
|
||||
targetName: apache-deployment
|
||||
containers:
|
||||
- name: nginx
|
||||
- name: apache
|
||||
steps:
|
||||
- name: maintenance-on
|
||||
- name: with-env
|
||||
- name: with-envfrom
|
||||
- name: maintenance-off
|
||||
finalize: true
|
||||
paths:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user