diff --git a/spug_api/apps/apis/config.py b/spug_api/apps/apis/config.py index 77ede68..1c13bf4 100644 --- a/spug_api/apps/apis/config.py +++ b/spug_api/apps/apis/config.py @@ -3,49 +3,26 @@ # Released under the AGPL-3.0 License. from django.http.response import HttpResponse from django_redis import get_redis_connection -from apps.config.models import Config, Service, Environment -from apps.setting.utils import AppSetting +from apps.config.models import Environment from apps.app.models import App +from apps.setting.utils import AppSetting +from apps.config.utils import compose_configs import json def get_configs(request): - data = {} app, env_id, no_prefix = _parse_params(request) if not app or not env_id: return HttpResponse('Invalid params', status=400) - # app own configs - for item in Config.objects.filter(type='app', o_id=app.id, env_id=env_id).only('key', 'value'): - key = item.key if no_prefix else f'{app.key}_{item.key}' - data[key] = item.value - # relation app public configs - if app.rel_apps: - app_ids = json.loads(app.rel_apps) - if app_ids: - id_key_map = {x.id: x.key for x in App.objects.filter(id__in=app_ids)} - for item in Config.objects.filter(type='app', o_id__in=app_ids, env_id=env_id, is_public=True) \ - .only('key', 'value'): - key = item.key if no_prefix else f'{id_key_map[item.o_id]}_{item.key}' - data[key] = item.value - - # relation service configs - if app.rel_services: - src_ids = json.loads(app.rel_services) - if src_ids: - id_key_map = {x.id: x.key for x in Service.objects.filter(id__in=src_ids)} - for item in Config.objects.filter(type='src', o_id__in=src_ids, env_id=env_id).only('key', 'value'): - key = item.key if no_prefix else f'{id_key_map[item.o_id]}_{item.key}' - data[key] = item.value - - # format + configs = compose_configs(app, env_id, no_prefix) fmt = request.GET.get('format', 'kv') if fmt == 'kv': - return _kv_response(data) + return _kv_response(configs) elif fmt == 'env': - return _env_response(data) + return _env_response(configs) elif fmt == 'json': - return _json_response(data) + return _json_response(configs) else: return HttpResponse('Unsupported output format', status=400) diff --git a/spug_api/apps/config/utils.py b/spug_api/apps/config/utils.py new file mode 100644 index 0000000..3a21951 --- /dev/null +++ b/spug_api/apps/config/utils.py @@ -0,0 +1,34 @@ +# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug +# Copyright: (c) +# Released under the AGPL-3.0 License. +from apps.config.models import Config, Service +from apps.app.models import App +import json + + +def compose_configs(app, env_id, no_prefix=False): + configs = dict() + # app own configs + for item in Config.objects.filter(type='app', o_id=app.id, env_id=env_id).only('key', 'value'): + key = item.key if no_prefix else f'{app.key}_{item.key}' + configs[key] = item.value + + # relation app public configs + if app.rel_apps: + app_ids = json.loads(app.rel_apps) + if app_ids: + id_key_map = {x.id: x.key for x in App.objects.filter(id__in=app_ids)} + for item in Config.objects.filter(type='app', o_id__in=app_ids, env_id=env_id, is_public=True) \ + .only('key', 'value'): + key = item.key if no_prefix else f'{id_key_map[item.o_id]}_{item.key}' + configs[key] = item.value + + # relation service configs + if app.rel_services: + src_ids = json.loads(app.rel_services) + if src_ids: + id_key_map = {x.id: x.key for x in Service.objects.filter(id__in=src_ids)} + for item in Config.objects.filter(type='src', o_id__in=src_ids, env_id=env_id).only('key', 'value'): + key = item.key if no_prefix else f'{id_key_map[item.o_id]}_{item.key}' + configs[key] = item.value + return configs diff --git a/spug_api/apps/deploy/utils.py b/spug_api/apps/deploy/utils.py index c62fa0e..9b602e5 100644 --- a/spug_api/apps/deploy/utils.py +++ b/spug_api/apps/deploy/utils.py @@ -6,6 +6,7 @@ from django.conf import settings from libs.utils import AttrDict, human_time, human_datetime from apps.host.models import Host from apps.notify.models import Notify +from apps.config.utils import compose_configs from concurrent import futures import requests import subprocess @@ -40,6 +41,11 @@ def dispatch(req): SPUG_API_TOKEN=api_token, SPUG_REPOS_DIR=REPOS_DIR, ) + # append configs + configs = compose_configs(req.deploy.app, req.deploy.env_id) + configs_env = {f'_SPUG_{k.upper()}': v for k, v in configs.items()} + env.update(configs_env) + if req.deploy.extend == '1': _ext1_deploy(req, helper, env) else: diff --git a/spug_api/libs/ssh.py b/spug_api/libs/ssh.py index 63ff94a..56f721f 100644 --- a/spug_api/libs/ssh.py +++ b/spug_api/libs/ssh.py @@ -62,7 +62,7 @@ class SSH: chan.settimeout(timeout) chan.set_combine_stderr(True) if environment: - str_env = ' '.join(f"{k}='{v}'" for k, v in environment.items()) + str_env = ' '.join(f"{k}='{self._handle_env(v)}'" for k, v in environment.items()) command = f'export {str_env} && {command}' chan.exec_command(command) stdout = chan.makefile("rb", -1) @@ -75,7 +75,7 @@ class SSH: chan.settimeout(timeout) chan.set_combine_stderr(True) if environment: - str_env = ' '.join(f"{k}='{v}'" for k, v in environment.items()) + str_env = ' '.join(f"{k}='{self._handle_env(v)}'" for k, v in environment.items()) command = f'export {str_env} && {command}' chan.exec_command(command) stdout = chan.makefile("rb", -1) @@ -106,6 +106,11 @@ class SSH: except UnicodeDecodeError: return out.decode('GBK') + def _handle_env(self, value): + if isinstance(value, str): + value = value.replace("'", "'\"'\"'") + return value + def __enter__(self): if self.client is not None: raise RuntimeError('Already connected')