From 1bb5e7b6d6cacc6e99d2a2e5ff679f360fbd1689 Mon Sep 17 00:00:00 2001 From: Hattori Keigo Date: Tue, 7 Aug 2018 17:55:34 +0900 Subject: [PATCH 1/3] Dump running Drucker service configurations for backup --- app/apis/api_kubernetes.py | 94 +++++++++++++++++++++++++++++++++++++- app/settings.yml | 5 ++ app/utils/env_loader.py | 2 +- 3 files changed, 99 insertions(+), 2 deletions(-) diff --git a/app/apis/api_kubernetes.py b/app/apis/api_kubernetes.py index 0d1df6b..d9e209d 100644 --- a/app/apis/api_kubernetes.py +++ b/app/apis/api_kubernetes.py @@ -1,4 +1,4 @@ -import os, uuid, shutil +import os, uuid, shutil, json, pathlib from datetime import datetime, timedelta from flask_restplus import Namespace, fields, Resource, reqparse @@ -338,6 +338,7 @@ def update_dbs_kubernetes(kubernetes_id:int, applist:set=None, description:str=N else: sobj.confirm_date = datetime.utcnow() db.session.flush() + dump_drucker_on_kubernetes(kobj.kubernetes_id, aobj.application_id, sobj.service_id) for application_name in applist: aobj = db.session.query(Application).filter( Application.application_name == application_name, @@ -748,6 +749,97 @@ def create_or_update_drucker_on_kubernetes( ) """ +def dump_drucker_on_kubernetes( + kubernetes_id:int, application_id:int, service_id:int): + kobj = Kubernetes.query.filter_by( + kubernetes_id=kubernetes_id).one_or_none() + if kobj is None: + raise Exception("No such kubernetes_id.") + aobj = Application.query.filter_by( + application_id=application_id).one_or_none() + if aobj is None: + raise Exception("No such application_id.") + sobj = Service.query.filter_by( + service_id=service_id).one_or_none() + if sobj is None: + raise Exception("No such service_id.") + + config_path = kobj.config_path + from kubernetes import client, config + config.load_kube_config(config_path) + save_dir = pathlib.Path(DIR_KUBE_CONFIG, aobj.application_name) + if not os.path.isdir(save_dir): + os.mkdir(save_dir) + api_client = client.ApiClient() + + apps_v1 = client.AppsV1Api() + v1_deployment = apps_v1.read_namespaced_deployment( + name="{0}-deployment".format(sobj.service_name), + namespace=sobj.service_level, + exact=True, + export=True + ) + json.dump(api_client.sanitize_for_serialization(v1_deployment), + pathlib.Path( + DIR_KUBE_CONFIG, + aobj.application_name, + "{0}-deployment.json".format(sobj.service_name)).open("w"), + ensure_ascii = False, indent = 2) + core_vi = client.CoreV1Api() + v1_service = core_vi.read_namespaced_service( + name="{0}-service".format(sobj.service_name), + namespace=sobj.service_level, + exact=True, + export=True + ) + json.dump(api_client.sanitize_for_serialization(v1_service), + pathlib.Path( + DIR_KUBE_CONFIG, + aobj.application_name, + "{0}-service.json".format(sobj.service_name)).open("w"), + ensure_ascii = False, indent = 2) + extensions_v1_beta = client.ExtensionsV1beta1Api() + v1_beta1_ingress = extensions_v1_beta.read_namespaced_ingress( + name="{0}-ingress".format(sobj.service_name), + namespace=sobj.service_level, + exact=True, + export=True + ) + json.dump(api_client.sanitize_for_serialization(v1_beta1_ingress), + pathlib.Path( + DIR_KUBE_CONFIG, + aobj.application_name, + "{0}-ingress.json".format(sobj.service_name)).open("w"), + ensure_ascii = False, indent = 2) + autoscaling_v1 = client.AutoscalingV1Api() + v1_horizontal_pod_autoscaler = autoscaling_v1.read_namespaced_horizontal_pod_autoscaler( + name="{0}-autoscaling".format(sobj.service_name), + namespace=sobj.service_level, + exact=True, + export=True + ) + json.dump(api_client.sanitize_for_serialization(v1_horizontal_pod_autoscaler), + pathlib.Path( + DIR_KUBE_CONFIG, + aobj.application_name, + "{0}-autoscaling.json".format(sobj.service_name)).open("w"), + ensure_ascii = False, indent = 2) + """ + autoscaling_v2_beta1 = client.AutoscalingV2beta1Api() + v2_beta1_horizontal_pod_autoscaler = autoscaling_v2_beta1.read_namespaced_horizontal_pod_autoscaler( + name="{0}-autoscaling".format(sobj.service_name), + namespace=sobj.service_level, + exact=True, + export=True + ) + json.dump(api_client.sanitize_for_serialization(v2_beta1_horizontal_pod_autoscaler), + pathlib.Path( + DIR_KUBE_CONFIG, + aobj.application_name, + "{0}-autoscaling.json".format(sobj.service_name)).open("w"), + ensure_ascii = False, indent = 2) + """ + @kube_info_namespace.route('/') class ApiKubernetes(Resource): diff --git a/app/settings.yml b/app/settings.yml index f1c7e16..ca55f7b 100644 --- a/app/settings.yml +++ b/app/settings.yml @@ -13,6 +13,11 @@ db.mysql.port: 3306 db.mysql.dbname: management db.mysql.user: user db.mysql.password: pass + +# Kubernetes +kube.datadir: kube-config + +# LDAP # auth: # secret: 'super-secret' # ldap: diff --git a/app/utils/env_loader.py b/app/utils/env_loader.py index 9cdd999..225e016 100644 --- a/app/utils/env_loader.py +++ b/app/utils/env_loader.py @@ -10,7 +10,7 @@ DRUCKER_GRPC_VERSION = drucker_pb2.DESCRIPTOR.GetOptions().Extensions[drucker_pb2.drucker_grpc_proto_version] -DIR_KUBE_CONFIG = "kube-config" +DIR_KUBE_CONFIG = os.getenv('DRUCKER_KUBE_DATADIR', config.get('kube.datadir', 'kube-config')) DB_MODE = os.getenv('DRUCKER_DB_MODE', config.get('use.db',"sqlite")) DB_MYSQL_HOST = os.getenv('DRUCKER_DB_MYSQL_HOST', config.get('db.mysql.host',"")) From 0acfe391069847540ce821f6cf16e935d396e42c Mon Sep 17 00:00:00 2001 From: Hattori Keigo Date: Tue, 7 Aug 2018 17:55:34 +0900 Subject: [PATCH 2/3] Dump running Drucker service configurations for backup --- app/apis/api_kubernetes.py | 94 +++++++++++++++++++++++++++++++++++++- app/settings.yml | 5 ++ app/utils/env_loader.py | 2 +- 3 files changed, 99 insertions(+), 2 deletions(-) diff --git a/app/apis/api_kubernetes.py b/app/apis/api_kubernetes.py index b90cd68..b8d82b7 100644 --- a/app/apis/api_kubernetes.py +++ b/app/apis/api_kubernetes.py @@ -1,4 +1,4 @@ -import os, uuid, shutil +import os, uuid, shutil, json, pathlib from datetime import datetime, timedelta from flask_restplus import Namespace, fields, Resource, reqparse @@ -340,6 +340,7 @@ def update_dbs_kubernetes(kubernetes_id:int, applist:set=None, description:str=N else: sobj.confirm_date = datetime.utcnow() db.session.flush() + dump_drucker_on_kubernetes(kobj.kubernetes_id, aobj.application_id, sobj.service_id) for application_name in applist: aobj = db.session.query(Application).filter( Application.application_name == application_name, @@ -811,6 +812,97 @@ def switch_drucker_service_model_assignment( ) return response_body +def dump_drucker_on_kubernetes( + kubernetes_id:int, application_id:int, service_id:int): + kobj = Kubernetes.query.filter_by( + kubernetes_id=kubernetes_id).one_or_none() + if kobj is None: + raise Exception("No such kubernetes_id.") + aobj = Application.query.filter_by( + application_id=application_id).one_or_none() + if aobj is None: + raise Exception("No such application_id.") + sobj = Service.query.filter_by( + service_id=service_id).one_or_none() + if sobj is None: + raise Exception("No such service_id.") + + config_path = kobj.config_path + from kubernetes import client, config + config.load_kube_config(config_path) + save_dir = pathlib.Path(DIR_KUBE_CONFIG, aobj.application_name) + if not os.path.isdir(save_dir): + os.mkdir(save_dir) + api_client = client.ApiClient() + + apps_v1 = client.AppsV1Api() + v1_deployment = apps_v1.read_namespaced_deployment( + name="{0}-deployment".format(sobj.service_name), + namespace=sobj.service_level, + exact=True, + export=True + ) + json.dump(api_client.sanitize_for_serialization(v1_deployment), + pathlib.Path( + DIR_KUBE_CONFIG, + aobj.application_name, + "{0}-deployment.json".format(sobj.service_name)).open("w"), + ensure_ascii = False, indent = 2) + core_vi = client.CoreV1Api() + v1_service = core_vi.read_namespaced_service( + name="{0}-service".format(sobj.service_name), + namespace=sobj.service_level, + exact=True, + export=True + ) + json.dump(api_client.sanitize_for_serialization(v1_service), + pathlib.Path( + DIR_KUBE_CONFIG, + aobj.application_name, + "{0}-service.json".format(sobj.service_name)).open("w"), + ensure_ascii = False, indent = 2) + extensions_v1_beta = client.ExtensionsV1beta1Api() + v1_beta1_ingress = extensions_v1_beta.read_namespaced_ingress( + name="{0}-ingress".format(sobj.service_name), + namespace=sobj.service_level, + exact=True, + export=True + ) + json.dump(api_client.sanitize_for_serialization(v1_beta1_ingress), + pathlib.Path( + DIR_KUBE_CONFIG, + aobj.application_name, + "{0}-ingress.json".format(sobj.service_name)).open("w"), + ensure_ascii = False, indent = 2) + autoscaling_v1 = client.AutoscalingV1Api() + v1_horizontal_pod_autoscaler = autoscaling_v1.read_namespaced_horizontal_pod_autoscaler( + name="{0}-autoscaling".format(sobj.service_name), + namespace=sobj.service_level, + exact=True, + export=True + ) + json.dump(api_client.sanitize_for_serialization(v1_horizontal_pod_autoscaler), + pathlib.Path( + DIR_KUBE_CONFIG, + aobj.application_name, + "{0}-autoscaling.json".format(sobj.service_name)).open("w"), + ensure_ascii = False, indent = 2) + """ + autoscaling_v2_beta1 = client.AutoscalingV2beta1Api() + v2_beta1_horizontal_pod_autoscaler = autoscaling_v2_beta1.read_namespaced_horizontal_pod_autoscaler( + name="{0}-autoscaling".format(sobj.service_name), + namespace=sobj.service_level, + exact=True, + export=True + ) + json.dump(api_client.sanitize_for_serialization(v2_beta1_horizontal_pod_autoscaler), + pathlib.Path( + DIR_KUBE_CONFIG, + aobj.application_name, + "{0}-autoscaling.json".format(sobj.service_name)).open("w"), + ensure_ascii = False, indent = 2) + """ + @kube_info_namespace.route('/') class ApiKubernetes(Resource): diff --git a/app/settings.yml b/app/settings.yml index f1c7e16..ca55f7b 100644 --- a/app/settings.yml +++ b/app/settings.yml @@ -13,6 +13,11 @@ db.mysql.port: 3306 db.mysql.dbname: management db.mysql.user: user db.mysql.password: pass + +# Kubernetes +kube.datadir: kube-config + +# LDAP # auth: # secret: 'super-secret' # ldap: diff --git a/app/utils/env_loader.py b/app/utils/env_loader.py index 13f1f2c..e146b3c 100644 --- a/app/utils/env_loader.py +++ b/app/utils/env_loader.py @@ -14,7 +14,7 @@ DRUCKER_GRPC_VERSION = drucker_pb2.DESCRIPTOR.GetOptions().Extensions[drucker_pb2.drucker_grpc_proto_version] -DIR_KUBE_CONFIG = "kube-config" +DIR_KUBE_CONFIG = os.getenv('DRUCKER_KUBE_DATADIR', config.get('kube.datadir', 'kube-config')) DB_MODE = os.getenv('DRUCKER_DB_MODE', config.get('use.db',"sqlite")) DB_MYSQL_HOST = os.getenv('DRUCKER_DB_MYSQL_HOST', config.get('db.mysql.host',"")) From 8ce4d5158563e926ec2de70f65efba9abf6f4964 Mon Sep 17 00:00:00 2001 From: Hattori Keigo Date: Mon, 27 Aug 2018 12:27:42 +0900 Subject: [PATCH 3/3] Revert "Merge branch 'feature/dump-kubernetes-yaml' of https://github.com/drucker/drucker-dashboard into feature/dump-kubernetes-yaml" This reverts commit 0e60cac24011c31d0d4d7c3a94071882daa13145, reversing changes made to 0acfe391069847540ce821f6cf16e935d396e42c. --- app/apis/api_kubernetes.py | 91 -------------------------------------- 1 file changed, 91 deletions(-) diff --git a/app/apis/api_kubernetes.py b/app/apis/api_kubernetes.py index 496a73a..b8d82b7 100644 --- a/app/apis/api_kubernetes.py +++ b/app/apis/api_kubernetes.py @@ -903,97 +903,6 @@ def dump_drucker_on_kubernetes( ensure_ascii = False, indent = 2) """ -def dump_drucker_on_kubernetes( - kubernetes_id:int, application_id:int, service_id:int): - kobj = Kubernetes.query.filter_by( - kubernetes_id=kubernetes_id).one_or_none() - if kobj is None: - raise Exception("No such kubernetes_id.") - aobj = Application.query.filter_by( - application_id=application_id).one_or_none() - if aobj is None: - raise Exception("No such application_id.") - sobj = Service.query.filter_by( - service_id=service_id).one_or_none() - if sobj is None: - raise Exception("No such service_id.") - - config_path = kobj.config_path - from kubernetes import client, config - config.load_kube_config(config_path) - save_dir = pathlib.Path(DIR_KUBE_CONFIG, aobj.application_name) - if not os.path.isdir(save_dir): - os.mkdir(save_dir) - api_client = client.ApiClient() - - apps_v1 = client.AppsV1Api() - v1_deployment = apps_v1.read_namespaced_deployment( - name="{0}-deployment".format(sobj.service_name), - namespace=sobj.service_level, - exact=True, - export=True - ) - json.dump(api_client.sanitize_for_serialization(v1_deployment), - pathlib.Path( - DIR_KUBE_CONFIG, - aobj.application_name, - "{0}-deployment.json".format(sobj.service_name)).open("w"), - ensure_ascii = False, indent = 2) - core_vi = client.CoreV1Api() - v1_service = core_vi.read_namespaced_service( - name="{0}-service".format(sobj.service_name), - namespace=sobj.service_level, - exact=True, - export=True - ) - json.dump(api_client.sanitize_for_serialization(v1_service), - pathlib.Path( - DIR_KUBE_CONFIG, - aobj.application_name, - "{0}-service.json".format(sobj.service_name)).open("w"), - ensure_ascii = False, indent = 2) - extensions_v1_beta = client.ExtensionsV1beta1Api() - v1_beta1_ingress = extensions_v1_beta.read_namespaced_ingress( - name="{0}-ingress".format(sobj.service_name), - namespace=sobj.service_level, - exact=True, - export=True - ) - json.dump(api_client.sanitize_for_serialization(v1_beta1_ingress), - pathlib.Path( - DIR_KUBE_CONFIG, - aobj.application_name, - "{0}-ingress.json".format(sobj.service_name)).open("w"), - ensure_ascii = False, indent = 2) - autoscaling_v1 = client.AutoscalingV1Api() - v1_horizontal_pod_autoscaler = autoscaling_v1.read_namespaced_horizontal_pod_autoscaler( - name="{0}-autoscaling".format(sobj.service_name), - namespace=sobj.service_level, - exact=True, - export=True - ) - json.dump(api_client.sanitize_for_serialization(v1_horizontal_pod_autoscaler), - pathlib.Path( - DIR_KUBE_CONFIG, - aobj.application_name, - "{0}-autoscaling.json".format(sobj.service_name)).open("w"), - ensure_ascii = False, indent = 2) - """ - autoscaling_v2_beta1 = client.AutoscalingV2beta1Api() - v2_beta1_horizontal_pod_autoscaler = autoscaling_v2_beta1.read_namespaced_horizontal_pod_autoscaler( - name="{0}-autoscaling".format(sobj.service_name), - namespace=sobj.service_level, - exact=True, - export=True - ) - json.dump(api_client.sanitize_for_serialization(v2_beta1_horizontal_pod_autoscaler), - pathlib.Path( - DIR_KUBE_CONFIG, - aobj.application_name, - "{0}-autoscaling.json".format(sobj.service_name)).open("w"), - ensure_ascii = False, indent = 2) - """ - @kube_info_namespace.route('/') class ApiKubernetes(Resource):