mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/khuedoan/homelab.git
synced 2026-09-20 08:03:58 +08:00
feat: backup and restore script
This commit is contained in:
185
scripts/backup
Executable file
185
scripts/backup
Executable file
@@ -0,0 +1,185 @@
|
||||
#!/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}")
|
||||
Reference in New Issue
Block a user