From 54dba98af221497ac391caa90c8feec2cbd39193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauri=20V=C3=B5sandi?= Date: Sat, 13 Aug 2022 13:48:01 +0300 Subject: [PATCH] Add MySQL operator support --- Dockerfile | 2 +- backup.py | 46 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0257543..e99316e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM harbor.k-space.ee/k-space/microservice-base -RUN apk add mongodb-tools +RUN apk add mongodb-tools mariadb-client mariadb-connector-c gzip ADD backup.py /backup.py ENTRYPOINT /backup.py EXPOSE 3001 diff --git a/backup.py b/backup.py index 801cbce..7b83aa9 100755 --- a/backup.py +++ b/backup.py @@ -6,6 +6,11 @@ from kubernetes.client.api_client import ApiClient from subprocess import Popen, PIPE from flask import Flask, request, send_file from urllib.parse import urlparse +import logging +import useful.logs + +useful.logs.setup(json_fields={"msg": "message", "level": "levelname"}) +logger = logging.getLogger() TOKEN = os.environ["TOKEN"] app = Flask(__name__) @@ -21,6 +26,15 @@ def generate_targets(): v1 = client.CoreV1Api(api) api_instance = client.CustomObjectsApi(api) for i in v1.list_namespace().items: + # Handle MySQL operator + targets = api_instance.list_namespaced_custom_object( + "mysql.oracle.com", + "v2", + i.metadata.name, + "innodbclusters") + for target in targets["items"]: + yield i.metadata.name, "innodbclusters", "-", target["metadata"]["name"] + # Handle MongoDB community operator targets = api_instance.list_namespaced_custom_object( "mongodbcommunity.mongodb.com", @@ -47,8 +61,30 @@ def generate_script(): return app.response_class(generate(), mimetype="text/plain") +@app.route("/stream//innodbclusters//") +def innodbclusters_stream(namespace, user, database): + if request.headers.get("Authorization") != TOKEN: + raise + with ApiClient() as api: + v1 = client.CoreV1Api(api) + secret_name = "%s-backup" % (database) + secret = v1.read_namespaced_secret(secret_name, namespace) + backup_username = base64.b64decode(secret.data["backupUsername"]).decode("ascii") + backup_password = base64.b64decode(secret.data["backupPassword"]).decode("ascii") + cmd = "/usr/bin/mysqldump", "--all-databases", "-u", backup_username, \ + "--password=%s" % backup_password, \ + "-h", "%s.%s.svc.cluster.local" % (database, namespace) + logger.info("Executing: %s", " ".join(cmd)) + process = Popen(cmd, stdout=PIPE, stdin=PIPE, close_fds=True, bufsize=4096 * 1024) + gzip = Popen(["/usr/bin/gzip", "-9"], stdout=PIPE, stdin=process.stdout, close_fds=True, bufsize=4096 * 1024) + return send_file(gzip.stdout, + mimetype="application/gzip", + as_attachment=True, + download_name="%s_%s.sql.gz" % (namespace, database)) + + @app.route("/stream//mongodbcommunity//") -def stream(namespace, user, database): +def mongodbcommunity_stream(namespace, user, database): if request.headers.get("Authorization") != TOKEN: raise with ApiClient() as api: @@ -57,12 +93,12 @@ def stream(namespace, user, database): secret = v1.read_namespaced_secret(secret_name, namespace) uri = base64.b64decode(secret.data["connectionString.standard"]).decode("ascii") cmd = "/usr/bin/mongodump", "--uri", uri, "--gzip", "--archive", "--quiet" - print("Executing:", cmd) + logger.info("Executing: %s", " ".join(cmd)) process = Popen(cmd, stdout=PIPE, stdin=PIPE, close_fds=True, bufsize=4096 * 1024) return send_file(process.stdout, - mimetype="application/tar+gzip", - as_attachment=True, - download_name="%s.tar.gz" % secret_name) + mimetype="application/tar+gzip", + as_attachment=True, + download_name="%s_%s.tar.gz" % (namespace, database)) app.run(host="0.0.0.0", debug=False, threaded=True)