mirror of
https://github.com/khuedoan/homelab.git
synced 2024-12-22 15:24:31 +07:00
186 lines
5.5 KiB
Python
Executable File
186 lines
5.5 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
import argparse
|
|
from kubernetes import client, config
|
|
from kubernetes.client.rest import ApiException
|
|
|
|
config.load_kube_config()
|
|
|
|
arg_parser = argparse.ArgumentParser()
|
|
arg_parser.add_argument("--namespace", required=True)
|
|
arg_parser.add_argument("--pvc", required=True)
|
|
arg_parser.add_argument("--action", required=True)
|
|
args = arg_parser.parse_args()
|
|
|
|
namespace = args.namespace
|
|
pvc = args.pvc
|
|
secret = f"{pvc}-backup-repository"
|
|
|
|
|
|
def apply_custom_resource(api, group, version, plural, name, namespace, body):
|
|
try:
|
|
# Check if the resource exists
|
|
api.get_namespaced_custom_object(
|
|
group=group,
|
|
version=version,
|
|
namespace=namespace,
|
|
plural=plural,
|
|
name=name,
|
|
)
|
|
|
|
print(f"Patching {body['kind']} {name}")
|
|
api.patch_namespaced_custom_object(
|
|
group=group,
|
|
version=version,
|
|
namespace=namespace,
|
|
plural=plural,
|
|
name=name,
|
|
body=body,
|
|
)
|
|
except ApiException as e:
|
|
if e.status == 404:
|
|
print(f"Creating {body['kind']} {name}")
|
|
api.create_namespaced_custom_object(
|
|
group=group,
|
|
version=version,
|
|
namespace=namespace,
|
|
plural=plural,
|
|
body=body,
|
|
)
|
|
else:
|
|
raise e
|
|
|
|
|
|
apply_custom_resource(
|
|
api=client.CustomObjectsApi(),
|
|
group="external-secrets.io",
|
|
version="v1beta1",
|
|
plural="externalsecrets",
|
|
name=secret,
|
|
namespace=namespace,
|
|
body={
|
|
"apiVersion": "external-secrets.io/v1beta1",
|
|
"kind": "ExternalSecret",
|
|
"metadata": {
|
|
"name": secret,
|
|
"namespace": namespace,
|
|
"annotations": {
|
|
"app.kubernetes.io/managed-by": "scripts/backup",
|
|
},
|
|
},
|
|
"spec": {
|
|
"secretStoreRef": {
|
|
"kind": "ClusterSecretStore",
|
|
"name": "global-secrets",
|
|
},
|
|
"data": [
|
|
{
|
|
"remoteRef": {
|
|
"key": "external",
|
|
"property": "restic-s3-bucket",
|
|
},
|
|
"secretKey": "restic_s3_bucket",
|
|
},
|
|
{
|
|
"remoteRef": {
|
|
"key": "external",
|
|
"property": "restic-s3-access-key",
|
|
},
|
|
"secretKey": "restic_s3_access_key",
|
|
},
|
|
{
|
|
"remoteRef": {
|
|
"key": "external",
|
|
"property": "restic-s3-secret-key",
|
|
},
|
|
"secretKey": "restic_s3_secret_key",
|
|
},
|
|
{
|
|
"remoteRef": {
|
|
"key": "external",
|
|
"property": "restic-password",
|
|
},
|
|
"secretKey": "restic_password",
|
|
},
|
|
],
|
|
"target": {
|
|
"template": {
|
|
"data": {
|
|
"RESTIC_REPOSITORY": f"s3:{{{{ .restic_s3_bucket }}}}/{namespace}/{pvc}",
|
|
"RESTIC_PASSWORD": "{{ .restic_password }}",
|
|
"AWS_ACCESS_KEY_ID": "{{ .restic_s3_access_key }}",
|
|
"AWS_SECRET_ACCESS_KEY": "{{ .restic_s3_secret_key }}",
|
|
}
|
|
}
|
|
},
|
|
},
|
|
},
|
|
)
|
|
|
|
if args.action == "setup":
|
|
apply_custom_resource(
|
|
api=client.CustomObjectsApi(),
|
|
group="volsync.backube",
|
|
version="v1alpha1",
|
|
plural="replicationsources",
|
|
name=pvc,
|
|
namespace=namespace,
|
|
body={
|
|
"apiVersion": "volsync.backube/v1alpha1",
|
|
"kind": "ReplicationSource",
|
|
"metadata": {
|
|
"name": pvc,
|
|
"namespace": namespace,
|
|
"annotations": {
|
|
"app.kubernetes.io/managed-by": "scripts/backup",
|
|
},
|
|
},
|
|
"spec": {
|
|
"sourcePVC": pvc,
|
|
"trigger": {"schedule": "*/30 * * * *"},
|
|
"restic": {
|
|
"pruneIntervalDays": 14,
|
|
"repository": secret,
|
|
"retain": {
|
|
"hourly": 6,
|
|
"daily": 5,
|
|
"weekly": 4,
|
|
"monthly": 2,
|
|
"yearly": 1,
|
|
},
|
|
"copyMethod": "Snapshot",
|
|
},
|
|
},
|
|
},
|
|
)
|
|
elif args.action == "restore":
|
|
apply_custom_resource(
|
|
api=client.CustomObjectsApi(),
|
|
group="volsync.backube",
|
|
version="v1alpha1",
|
|
plural="replicationdestinations",
|
|
name=pvc,
|
|
namespace=namespace,
|
|
body={
|
|
"apiVersion": "volsync.backube/v1alpha1",
|
|
"kind": "ReplicationDestination",
|
|
"metadata": {
|
|
"name": pvc,
|
|
"namespace": namespace,
|
|
"annotations": {
|
|
"app.kubernetes.io/managed-by": "scripts/backup",
|
|
},
|
|
},
|
|
"spec": {
|
|
"trigger": {"manual": "restore-once"},
|
|
"restic": {
|
|
"repository": secret,
|
|
"destinationPVC": pvc,
|
|
"copyMethod": "Direct",
|
|
},
|
|
},
|
|
},
|
|
)
|
|
else:
|
|
raise ValueError(f"Invalid action: {args.action}")
|