diff --git a/spug_api/apps/apis/__init__.py b/spug_api/apps/apis/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/spug_api/apps/apis/config.py b/spug_api/apps/apis/config.py new file mode 100644 index 0000000..3513e3a --- /dev/null +++ b/spug_api/apps/apis/config.py @@ -0,0 +1,76 @@ +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.app.models import App +import json + + +def get_configs(request): + data = {} + app, env_id = _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).only('key', 'value'): + data[f'{app.key}_{item.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, is_public=True).only('key', 'value'): + key = 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).only('key', 'value'): + key = f'{id_key_map[item.o_id]}_{item.key}' + data[key] = item.value + + # format + fmt = request.GET.get('format', 'kv') + if fmt == 'kv': + return _kv_response(data) + elif fmt == 'json': + return _json_response(data) + else: + return HttpResponse('Unsupported output format', status=400) + + +def _kv_response(data): + output = '' + for k, v in data.items(): + output += f'{k} = {v}\r\n' + return HttpResponse(output, content_type='text/plain; charset=utf-8') + + +def _json_response(data): + return HttpResponse(json.dumps(data), content_type='application/json') + + +def _parse_params(request): + app, env_id = None, None + api_token = request.GET.get('apiToken') + if api_token: + rds = get_redis_connection() + content = rds.get(api_token) + if content: + app_id, env_id = content.split(',') + app = App.objects.filter(pk=app_id).first() + else: + api_key = AppSetting.get_default('api_key') + if api_key and request.GET.get('apiKey') == api_key: + app_key = request.GET.get('app') + env_key = request.GET.get('env') + if app_key and env_key: + app = App.objects.filter(key=app_key).first() + env = Environment.objects.filter(key=env_key).first() + if env: + env_id = env.id + return app, env_id diff --git a/spug_api/apps/apis/urls.py b/spug_api/apps/apis/urls.py new file mode 100644 index 0000000..5cbac86 --- /dev/null +++ b/spug_api/apps/apis/urls.py @@ -0,0 +1,7 @@ +from django.urls import path + +from apps.apis import config + +urlpatterns = [ + path('config/', config.get_configs), +] diff --git a/spug_api/apps/setting/utils.py b/spug_api/apps/setting/utils.py index 081874d..d7c2c7c 100644 --- a/spug_api/apps/setting/utils.py +++ b/spug_api/apps/setting/utils.py @@ -3,7 +3,7 @@ from apps.setting.models import Setting class AppSetting: - keys = ('public_key', 'private_key', 'mail_service') + keys = ('public_key', 'private_key', 'mail_service', 'api_key') @classmethod @lru_cache(maxsize=64) @@ -13,6 +13,13 @@ class AppSetting: raise KeyError(f'no such key for {key!r}') return info.value + @classmethod + def get_default(cls, key, default=None): + info = Setting.objects.filter(key=key).first() + if not info: + return default + return info.value + @classmethod def set(cls, key, value, desc=None): if key in cls.keys: diff --git a/spug_api/spug/settings.py b/spug_api/spug/settings.py index f760903..2720777 100644 --- a/spug_api/spug/settings.py +++ b/spug_api/spug/settings.py @@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/2.2/ref/settings/ """ import os +import re # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -111,6 +112,7 @@ USE_TZ = True AUTHENTICATION_EXCLUDES = ( '/account/login/', + re.compile('/apis/.*'), ) # override default config diff --git a/spug_api/spug/urls.py b/spug_api/spug/urls.py index 527a787..24d3792 100644 --- a/spug_api/spug/urls.py +++ b/spug_api/spug/urls.py @@ -26,4 +26,5 @@ urlpatterns = [ path('config/', include('apps.config.urls')), path('app/', include('apps.app.urls')), path('deploy/', include('apps.deploy.urls')), + path('apis/', include('apps.apis.urls')), ]