Compare commits
4 Commits
3790f30e29
...
b42bd46efe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b42bd46efe | ||
|
|
2ac8bc2c71 | ||
|
|
46247d17ae | ||
|
|
da8b224cf0 |
@ -57,6 +57,8 @@ type TargetContainer struct {
|
|||||||
Steps []Step `json:"steps,omitempty"`
|
Steps []Step `json:"steps,omitempty"`
|
||||||
// +kubebuilder:default:=/formol-shared
|
// +kubebuilder:default:=/formol-shared
|
||||||
SharePath string `json:"sharePath"`
|
SharePath string `json:"sharePath"`
|
||||||
|
// +optional
|
||||||
|
Job []Step `json:"job,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Target struct {
|
type Target struct {
|
||||||
|
|||||||
@ -614,6 +614,13 @@ func (in *TargetContainer) DeepCopyInto(out *TargetContainer) {
|
|||||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if in.Job != nil {
|
||||||
|
in, out := &in.Job, &out.Job
|
||||||
|
*out = make([]Step, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetContainer.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetContainer.
|
||||||
|
|||||||
@ -130,6 +130,36 @@ func (r *BackupConfigurationReconciler) AddCronJob(backupConf formolv1alpha1.Bac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *BackupConfigurationReconciler) getTargetObjects(kind formolv1alpha1.TargetKind, namespace string, name string) (targetObject client.Object, targetPodSpec *corev1.PodSpec, err error) {
|
||||||
|
switch kind {
|
||||||
|
case formolv1alpha1.Deployment:
|
||||||
|
deployment := appsv1.Deployment{}
|
||||||
|
if err = r.Get(r.Context, client.ObjectKey{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
}, &deployment); err != nil {
|
||||||
|
r.Log.Error(err, "cannot get deployment", "Deployment", name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
targetObject = &deployment
|
||||||
|
targetPodSpec = &deployment.Spec.Template.Spec
|
||||||
|
|
||||||
|
case formolv1alpha1.StatefulSet:
|
||||||
|
statefulSet := appsv1.StatefulSet{}
|
||||||
|
if err = r.Get(r.Context, client.ObjectKey{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
}, &statefulSet); err != nil {
|
||||||
|
r.Log.Error(err, "cannot get StatefulSet", "StatefulSet", name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
targetObject = &statefulSet
|
||||||
|
targetPodSpec = &statefulSet.Spec.Template.Spec
|
||||||
|
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1.BackupConfiguration) error {
|
func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1.BackupConfiguration) error {
|
||||||
removeTags := func(podSpec *corev1.PodSpec, target formolv1alpha1.Target) {
|
removeTags := func(podSpec *corev1.PodSpec, target formolv1alpha1.Target) {
|
||||||
for i, container := range podSpec.Containers {
|
for i, container := range podSpec.Containers {
|
||||||
@ -160,34 +190,11 @@ func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1.
|
|||||||
}
|
}
|
||||||
r.Log.V(1).Info("Got Repository", "repo", repo)
|
r.Log.V(1).Info("Got Repository", "repo", repo)
|
||||||
for _, target := range backupConf.Spec.Targets {
|
for _, target := range backupConf.Spec.Targets {
|
||||||
var targetObject client.Object
|
targetObject, targetPodSpec, err := r.getTargetObjects(target.TargetKind, backupConf.Namespace, target.TargetName)
|
||||||
var targetPodSpec *corev1.PodSpec
|
if err != nil {
|
||||||
switch target.TargetKind {
|
r.Log.Error(err, "unable to get target objects")
|
||||||
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
|
return err
|
||||||
}
|
}
|
||||||
targetObject = &deployment
|
|
||||||
targetPodSpec = &deployment.Spec.Template.Spec
|
|
||||||
|
|
||||||
case formolv1alpha1.StatefulSet:
|
|
||||||
statefulSet := appsv1.StatefulSet{}
|
|
||||||
if err := r.Get(r.Context, client.ObjectKey{
|
|
||||||
Namespace: backupConf.Namespace,
|
|
||||||
Name: target.TargetName,
|
|
||||||
}, &statefulSet); err != nil {
|
|
||||||
r.Log.Error(err, "cannot get deployment", "Deployment", target.TargetName)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
targetObject = &statefulSet
|
|
||||||
targetPodSpec = &statefulSet.Spec.Template.Spec
|
|
||||||
|
|
||||||
}
|
|
||||||
restoreContainers := []corev1.Container{}
|
restoreContainers := []corev1.Container{}
|
||||||
for _, container := range targetPodSpec.Containers {
|
for _, container := range targetPodSpec.Containers {
|
||||||
if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME {
|
if container.Name == formolv1alpha1.SIDECARCONTAINER_NAME {
|
||||||
@ -218,7 +225,7 @@ func (r *BackupConfigurationReconciler) DeleteSidecar(backupConf formolv1alpha1.
|
|||||||
}
|
}
|
||||||
targetPodSpec.Volumes = restoreVolumes
|
targetPodSpec.Volumes = restoreVolumes
|
||||||
removeTags(targetPodSpec, target)
|
removeTags(targetPodSpec, target)
|
||||||
if err := r.Update(r.Context, targetObject); err != nil {
|
if err = r.Update(r.Context, targetObject); err != nil {
|
||||||
r.Log.Error(err, "unable to remove sidecar", "targetObject", targetObject)
|
r.Log.Error(err, "unable to remove sidecar", "targetObject", targetObject)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -265,32 +272,14 @@ func (r *BackupConfigurationReconciler) addSidecar(backupConf formolv1alpha1.Bac
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
VolumeMounts: []corev1.VolumeMount{},
|
VolumeMounts: []corev1.VolumeMount{},
|
||||||
|
SecurityContext: &corev1.SecurityContext{
|
||||||
|
Privileged: func() *bool { b := true; return &b }(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
var targetObject client.Object
|
targetObject, targetPodSpec, err := r.getTargetObjects(target.TargetKind, backupConf.Namespace, target.TargetName)
|
||||||
var targetPodSpec *corev1.PodSpec
|
if err != nil {
|
||||||
switch target.TargetKind {
|
r.Log.Error(err, "unable to get target objects")
|
||||||
case formolv1alpha1.Deployment:
|
return err
|
||||||
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
|
|
||||||
}
|
|
||||||
targetObject = &deployment
|
|
||||||
targetPodSpec = &deployment.Spec.Template.Spec
|
|
||||||
case formolv1alpha1.StatefulSet:
|
|
||||||
statefulSet := appsv1.StatefulSet{}
|
|
||||||
if err = r.Get(r.Context, client.ObjectKey{
|
|
||||||
Namespace: backupConf.Namespace,
|
|
||||||
Name: target.TargetName,
|
|
||||||
}, &statefulSet); err != nil {
|
|
||||||
r.Log.Error(err, "cannot get deployment", "Deployment", target.TargetName)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
targetObject = &statefulSet
|
|
||||||
targetPodSpec = &statefulSet.Spec.Template.Spec
|
|
||||||
}
|
}
|
||||||
if !hasSidecar(targetPodSpec) {
|
if !hasSidecar(targetPodSpec) {
|
||||||
if err = r.createRBACSidecar(corev1.ServiceAccount{
|
if err = r.createRBACSidecar(corev1.ServiceAccount{
|
||||||
|
|||||||
@ -70,106 +70,3 @@ data:
|
|||||||
RESTIC_PASSWORD: bHIyOXhtOTU=
|
RESTIC_PASSWORD: bHIyOXhtOTU=
|
||||||
AWS_ACCESS_KEY_ID: OWFTSXZBSEVzWlNVMmkyTU9zVGxWSk1lL1NjPQ==
|
AWS_ACCESS_KEY_ID: OWFTSXZBSEVzWlNVMmkyTU9zVGxWSk1lL1NjPQ==
|
||||||
AWS_SECRET_ACCESS_KEY: WVN5ck9ncVllcjBWNFNLdlVOcmx2OGhjTllhZGZuN2xaNjBIaXRlL3djWT0=
|
AWS_SECRET_ACCESS_KEY: WVN5ck9ncVllcjBWNFNLdlVOcmx2OGhjTllhZGZuN2xaNjBIaXRlL3djWT0=
|
||||||
---
|
|
||||||
apiVersion: formol.desmojim.fr/v1alpha1
|
|
||||||
kind: Repo
|
|
||||||
metadata:
|
|
||||||
name: repo-local
|
|
||||||
namespace: demo
|
|
||||||
spec:
|
|
||||||
backend:
|
|
||||||
local:
|
|
||||||
emptyDir:
|
|
||||||
repositorySecrets: secret-minio
|
|
||||||
---
|
|
||||||
apiVersion: formol.desmojim.fr/v1alpha1
|
|
||||||
kind: Repo
|
|
||||||
metadata:
|
|
||||||
name: repo-minio
|
|
||||||
namespace: demo
|
|
||||||
spec:
|
|
||||||
backend:
|
|
||||||
s3:
|
|
||||||
server: raid5.desmojim.fr:9000
|
|
||||||
bucket: testbucket2
|
|
||||||
repositorySecrets: secret-minio
|
|
||||||
---
|
|
||||||
apiVersion: formol.desmojim.fr/v1alpha1
|
|
||||||
kind: Function
|
|
||||||
metadata:
|
|
||||||
name: restore-pg
|
|
||||||
namespace: demo
|
|
||||||
spec:
|
|
||||||
name: restore-pg
|
|
||||||
image: desmo999r/formolcli:latest
|
|
||||||
args: ["postgres", "restore", "--hostname", $(PGHOST), "--database", $(PGDATABASE), "--username", $(PGUSER), "--password", $(PGPASSWD), "--file", "/output/backup-pg.sql"]
|
|
||||||
env:
|
|
||||||
- name: PGHOST
|
|
||||||
value: postgres
|
|
||||||
- name: PGDATABASE
|
|
||||||
value: demopostgres
|
|
||||||
- name: PGUSER
|
|
||||||
value: demopostgres
|
|
||||||
- name: PGPASSWD
|
|
||||||
value: password123!
|
|
||||||
---
|
|
||||||
apiVersion: formol.desmojim.fr/v1alpha1
|
|
||||||
kind: Function
|
|
||||||
metadata:
|
|
||||||
name: with-envfrom
|
|
||||||
namespace: demo
|
|
||||||
spec:
|
|
||||||
name: with-envfrom
|
|
||||||
command: ["touch", $(title)]
|
|
||||||
envFrom:
|
|
||||||
- secretRef:
|
|
||||||
name: with-envfrom-secret
|
|
||||||
---
|
|
||||||
apiVersion: formol.desmojim.fr/v1alpha1
|
|
||||||
kind: Function
|
|
||||||
metadata:
|
|
||||||
name: with-env
|
|
||||||
namespace: demo
|
|
||||||
spec:
|
|
||||||
name: with-env
|
|
||||||
command: ["touch", $(TESTFILE)]
|
|
||||||
env:
|
|
||||||
- name: TESTFILE
|
|
||||||
value: /data/testfile
|
|
||||||
---
|
|
||||||
apiVersion: formol.desmojim.fr/v1alpha1
|
|
||||||
kind: Function
|
|
||||||
metadata:
|
|
||||||
name: backup-pg
|
|
||||||
namespace: demo
|
|
||||||
spec:
|
|
||||||
name: backup-pg
|
|
||||||
image: desmo999r/formolcli:latest
|
|
||||||
args: ["postgres", "backup", "--hostname", $(PGHOST), "--database", $(PGDATABASE), "--username", $(PGUSER), "--password", $(PGPASSWD), "--file", "/output/backup-pg.sql"]
|
|
||||||
env:
|
|
||||||
- name: PGHOST
|
|
||||||
value: postgres
|
|
||||||
- name: PGDATABASE
|
|
||||||
value: demopostgres
|
|
||||||
- name: PGUSER
|
|
||||||
value: demopostgres
|
|
||||||
- name: PGPASSWD
|
|
||||||
value: password123!
|
|
||||||
---
|
|
||||||
apiVersion: formol.desmojim.fr/v1alpha1
|
|
||||||
kind: Function
|
|
||||||
metadata:
|
|
||||||
name: maintenance-off
|
|
||||||
namespace: demo
|
|
||||||
spec:
|
|
||||||
name: maintenance-off
|
|
||||||
command: ["/bin/sh", "-c", "echo $(date +%Y/%m/%d-%H:%M:%S) maintenance-off >> /data/logs.txt"]
|
|
||||||
---
|
|
||||||
apiVersion: formol.desmojim.fr/v1alpha1
|
|
||||||
kind: Function
|
|
||||||
metadata:
|
|
||||||
name: maintenance-on
|
|
||||||
namespace: demo
|
|
||||||
spec:
|
|
||||||
name: maintenance-on
|
|
||||||
command: ["/bin/sh", "-c", "echo $(date +%Y/%m/%d-%H:%M:%S) maintenance-on >> /data/logs.txt"]
|
|
||||||
|
|||||||
@ -84,9 +84,11 @@ spec:
|
|||||||
name: postgres-config-demo
|
name: postgres-config-demo
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 5432
|
- containerPort: 5432
|
||||||
name: postgredb
|
name: postgresdb
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: postgredb
|
- name: postgres-volume
|
||||||
mountPath: /var/lib/postgresql/data
|
mountPath: /var/lib/postgresql/data
|
||||||
volumes:
|
volumes:
|
||||||
- name: postgredb
|
- name: postgres-volume
|
||||||
|
hostPath:
|
||||||
|
path: /data/postgresdb
|
||||||
|
|||||||
@ -1,5 +1,104 @@
|
|||||||
---
|
---
|
||||||
apiVersion: formol.desmojim.fr/v1alpha1
|
apiVersion: formol.desmojim.fr/v1alpha1
|
||||||
|
kind: Repo
|
||||||
|
metadata:
|
||||||
|
name: repo-local
|
||||||
|
namespace: demo
|
||||||
|
spec:
|
||||||
|
backend:
|
||||||
|
local:
|
||||||
|
emptyDir:
|
||||||
|
repositorySecrets: secret-minio
|
||||||
|
---
|
||||||
|
apiVersion: formol.desmojim.fr/v1alpha1
|
||||||
|
kind: Repo
|
||||||
|
metadata:
|
||||||
|
name: repo-minio
|
||||||
|
namespace: demo
|
||||||
|
spec:
|
||||||
|
backend:
|
||||||
|
s3:
|
||||||
|
server: raid5.desmojim.fr:9000
|
||||||
|
bucket: testbucket2
|
||||||
|
repositorySecrets: secret-minio
|
||||||
|
---
|
||||||
|
apiVersion: formol.desmojim.fr/v1alpha1
|
||||||
|
kind: Function
|
||||||
|
metadata:
|
||||||
|
name: restore-pg
|
||||||
|
namespace: demo
|
||||||
|
spec:
|
||||||
|
name: restore-pg
|
||||||
|
image: desmo999r/formolcli:latest
|
||||||
|
args: ["postgres", "restore", "--hostname", $(PGHOST), "--database", $(PGDATABASE), "--username", $(PGUSER), "--password", $(PGPASSWD), "--file", "/output/backup-pg.sql"]
|
||||||
|
env:
|
||||||
|
- name: PGHOST
|
||||||
|
value: postgres
|
||||||
|
- name: PGDATABASE
|
||||||
|
value: demopostgres
|
||||||
|
- name: PGUSER
|
||||||
|
value: demopostgres
|
||||||
|
- name: PGPASSWD
|
||||||
|
value: password123!
|
||||||
|
---
|
||||||
|
apiVersion: formol.desmojim.fr/v1alpha1
|
||||||
|
kind: Function
|
||||||
|
metadata:
|
||||||
|
name: with-envfrom
|
||||||
|
namespace: demo
|
||||||
|
spec:
|
||||||
|
name: with-envfrom
|
||||||
|
command: ["touch", $(title)]
|
||||||
|
envFrom:
|
||||||
|
- secretRef:
|
||||||
|
name: with-envfrom-secret
|
||||||
|
---
|
||||||
|
apiVersion: formol.desmojim.fr/v1alpha1
|
||||||
|
kind: Function
|
||||||
|
metadata:
|
||||||
|
name: with-env
|
||||||
|
namespace: demo
|
||||||
|
spec:
|
||||||
|
name: with-env
|
||||||
|
command: ["touch", $(TESTFILE)]
|
||||||
|
env:
|
||||||
|
- name: TESTFILE
|
||||||
|
value: /data/testfile
|
||||||
|
---
|
||||||
|
apiVersion: formol.desmojim.fr/v1alpha1
|
||||||
|
kind: Function
|
||||||
|
metadata:
|
||||||
|
name: backup-pg
|
||||||
|
namespace: demo
|
||||||
|
spec:
|
||||||
|
name: backup-pg
|
||||||
|
command: ["pg_dump"]
|
||||||
|
args: ["--username", $(PGUSER), "--clean", "--if-exists", "--inserts", "--file", "/formol-shared/backup-pg.sql"]
|
||||||
|
env:
|
||||||
|
- name: PGUSER
|
||||||
|
value: demopostgres
|
||||||
|
---
|
||||||
|
apiVersion: formol.desmojim.fr/v1alpha1
|
||||||
|
kind: Function
|
||||||
|
metadata:
|
||||||
|
name: maintenance-off
|
||||||
|
namespace: demo
|
||||||
|
spec:
|
||||||
|
name: maintenance-off
|
||||||
|
command: ["/bin/sh"]
|
||||||
|
args: ["-c", "echo $(date +%Y/%m/%d-%H:%M:%S) maintenance-off >> /data/logs.txt"]
|
||||||
|
---
|
||||||
|
apiVersion: formol.desmojim.fr/v1alpha1
|
||||||
|
kind: Function
|
||||||
|
metadata:
|
||||||
|
name: maintenance-on
|
||||||
|
namespace: demo
|
||||||
|
spec:
|
||||||
|
name: maintenance-on
|
||||||
|
command: ["/bin/sh"]
|
||||||
|
args: ["-c", "echo $(date +%Y/%m/%d-%H:%M:%S) maintenance-on >> /data/logs.txt"]
|
||||||
|
---
|
||||||
|
apiVersion: formol.desmojim.fr/v1alpha1
|
||||||
kind: BackupConfiguration
|
kind: BackupConfiguration
|
||||||
metadata:
|
metadata:
|
||||||
name: backup-demo
|
name: backup-demo
|
||||||
@ -32,6 +131,8 @@ spec:
|
|||||||
targetName: postgres-demo
|
targetName: postgres-demo
|
||||||
containers:
|
containers:
|
||||||
- name: postgres
|
- name: postgres
|
||||||
|
job:
|
||||||
|
- name: backup-pg
|
||||||
# - kind: Job
|
# - kind: Job
|
||||||
# name: backup-pg
|
# name: backup-pg
|
||||||
# steps:
|
# steps:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user