fix issue

pull/360/head
vapao 2021-07-26 17:36:52 +08:00
parent c49345be38
commit 6a25d33c2b
4 changed files with 54 additions and 32 deletions

View File

@ -3,49 +3,26 @@
# Released under the AGPL-3.0 License. # Released under the AGPL-3.0 License.
from django.http.response import HttpResponse from django.http.response import HttpResponse
from django_redis import get_redis_connection from django_redis import get_redis_connection
from apps.config.models import Config, Service, Environment from apps.config.models import Environment
from apps.setting.utils import AppSetting
from apps.app.models import App from apps.app.models import App
from apps.setting.utils import AppSetting
from apps.config.utils import compose_configs
import json import json
def get_configs(request): def get_configs(request):
data = {}
app, env_id, no_prefix = _parse_params(request) app, env_id, no_prefix = _parse_params(request)
if not app or not env_id: if not app or not env_id:
return HttpResponse('Invalid params', status=400) 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 configs = compose_configs(app, env_id, no_prefix)
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
fmt = request.GET.get('format', 'kv') fmt = request.GET.get('format', 'kv')
if fmt == 'kv': if fmt == 'kv':
return _kv_response(data) return _kv_response(configs)
elif fmt == 'env': elif fmt == 'env':
return _env_response(data) return _env_response(configs)
elif fmt == 'json': elif fmt == 'json':
return _json_response(data) return _json_response(configs)
else: else:
return HttpResponse('Unsupported output format', status=400) return HttpResponse('Unsupported output format', status=400)

View File

@ -0,0 +1,34 @@
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
# Copyright: (c) <spug.dev@gmail.com>
# 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

View File

@ -6,6 +6,7 @@ from django.conf import settings
from libs.utils import AttrDict, human_time, human_datetime from libs.utils import AttrDict, human_time, human_datetime
from apps.host.models import Host from apps.host.models import Host
from apps.notify.models import Notify from apps.notify.models import Notify
from apps.config.utils import compose_configs
from concurrent import futures from concurrent import futures
import requests import requests
import subprocess import subprocess
@ -40,6 +41,11 @@ def dispatch(req):
SPUG_API_TOKEN=api_token, SPUG_API_TOKEN=api_token,
SPUG_REPOS_DIR=REPOS_DIR, 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': if req.deploy.extend == '1':
_ext1_deploy(req, helper, env) _ext1_deploy(req, helper, env)
else: else:

View File

@ -62,7 +62,7 @@ class SSH:
chan.settimeout(timeout) chan.settimeout(timeout)
chan.set_combine_stderr(True) chan.set_combine_stderr(True)
if environment: 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}' command = f'export {str_env} && {command}'
chan.exec_command(command) chan.exec_command(command)
stdout = chan.makefile("rb", -1) stdout = chan.makefile("rb", -1)
@ -75,7 +75,7 @@ class SSH:
chan.settimeout(timeout) chan.settimeout(timeout)
chan.set_combine_stderr(True) chan.set_combine_stderr(True)
if environment: 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}' command = f'export {str_env} && {command}'
chan.exec_command(command) chan.exec_command(command)
stdout = chan.makefile("rb", -1) stdout = chan.makefile("rb", -1)
@ -106,6 +106,11 @@ class SSH:
except UnicodeDecodeError: except UnicodeDecodeError:
return out.decode('GBK') return out.decode('GBK')
def _handle_env(self, value):
if isinstance(value, str):
value = value.replace("'", "'\"'\"'")
return value
def __enter__(self): def __enter__(self):
if self.client is not None: if self.client is not None:
raise RuntimeError('Already connected') raise RuntimeError('Already connected')