Skip to content

Commit

Permalink
feat: 添加查询已生效的增强服务环境变量 KEY API (#1374)
Browse files Browse the repository at this point in the history
  • Loading branch information
jiayuan929 authored Jun 11, 2024
1 parent e4ecdeb commit 4d0650b
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 1 deletion.
19 changes: 19 additions & 0 deletions apiserver/paasng/paasng/accessories/servicehub/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,25 @@ def get_env_vars(
result.update(i.credentials)
return result

def get_enabled_env_keys(self, engine_app: EngineApp) -> Dict[str, List[str]]:
"""
Get all provisioned services environment keys
:param engine_app: EngineApp object
:return: Dictionary of service display names to list of their environment keys
"""
provisioned_rels = self.list_provisioned_rels(engine_app)
# 凭证的信息写入环境变量的增强服务才展示
enabled_rels = [rel for rel in provisioned_rels if rel.db_obj.credentials_enabled]

results = {}
for rel in enabled_rels:
service_name = rel.get_service().display_name
instance_credentials_keys = list(rel.get_instance().credentials.keys())
results[service_name] = instance_credentials_keys

return results

def get_attachment_by_engine_app(self, service: ServiceObj, engine_app: EngineApp):
for mgr in self.mgr_instances:
try:
Expand Down
22 changes: 21 additions & 1 deletion apiserver/paasng/paasng/accessories/servicehub/sharing.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"""
"""Shared service across modules"""
import logging
from typing import Dict, Iterable, Optional, Sequence
from typing import Dict, Iterable, List, Optional, Sequence

from django.core.exceptions import ObjectDoesNotExist

Expand Down Expand Up @@ -138,6 +138,26 @@ def get_env_variables(self, env: ModuleEnvironment, filter_enabled: bool = False
ret.update(env_variables)
return ret

def get_enabled_env_keys(self, env: ModuleEnvironment) -> Dict[str, List[str]]:
"""
Retrieve all environment variable keys shared from other modules.
:param env: ModuleEnvironment object that must belong to self.module
:return: Dictionary of service display names to their respective env keys list.
"""
if env.module != self.module:
raise RuntimeError("Invalid env object, must belong to self.module")

result = {}
for referenced_info in self.list_all_shared_info():
ref_env = referenced_info.ref_module.get_envs(env.environment)
ref_service = referenced_info.service
env_keys = mixed_service_mgr.get_env_vars(ref_env.engine_app, ref_service, True)

result[ref_service.display_name] = list(env_keys.keys())

return result


def extract_shared_info(attachment: SharedServiceAttachment) -> Optional[SharedServiceInfo]:
"""Extract shared service infomation by attachment object
Expand Down
5 changes: 5 additions & 0 deletions apiserver/paasng/paasng/accessories/servicehub/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@
views.ModuleServiceAttachmentsViewSet.as_view({"get": "retrieve_info"}),
name="api.modules.services.info",
),
re_path(
make_app_pattern("/services/config_var_keys/$", include_envs=False),
views.ModuleServiceAttachmentsViewSet.as_view({"get": "list_provisioned_env_keys"}),
name="api.services.list_provisioned_env_keys",
),
re_path(
make_app_pattern(f"/services/{SERVICE_UUID}/specs$", include_envs=False),
views.ModuleServicesViewSet.as_view({"get": "retrieve_specs"}),
Expand Down
14 changes: 14 additions & 0 deletions apiserver/paasng/paasng/accessories/servicehub/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,20 @@ def retrieve_info(self, request, code, module_name):
services_info[env.environment] = ServicesInfo.get_detail(env.engine_app)["services_info"]
return Response(data=slzs.ModuleServiceInfoSLZ(services_info).data)

def list_provisioned_env_keys(self, request, code, module_name):
"""获取已经生效的增强服务环境变量 KEY"""
module = self.get_module_via_path()

# env_key_dict 内容示例: {"svc_name": ["key1", "key2"]}
env_key_dict: Dict[str, List[str]] = {}
for env in module.get_envs():
env_key_dict = {
**env_key_dict,
**ServiceSharingManager(env.module).get_enabled_env_keys(env),
**mixed_service_mgr.get_enabled_env_keys(env.engine_app),
}
return Response(data=env_key_dict)


class ModuleServicesViewSet(viewsets.ViewSet, ApplicationCodeInPathMixin):
"""与蓝鲸应用模块相关的增强服务接口"""
Expand Down
32 changes: 32 additions & 0 deletions apiserver/paasng/tests/api/test_servicehub.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
We undertake not to change the open source license (MIT license) applicable
to the current version of the project delivered to anyone in the future.
"""
import datetime
from unittest import mock

import pytest
from django_dynamic_fixture import G

from paasng.accessories.servicehub.models import RemoteServiceEngineAppAttachment
from paasng.accessories.servicehub.services import ServiceInstanceObj
from paasng.accessories.services.models import Service

pytestmark = pytest.mark.django_db
Expand All @@ -38,6 +40,15 @@ def side_effect(*args, **kwargs):

return side_effect

def create_mock_rel(self, service, credentials_enabled, create_time: "datetime.datetime", **credentials):
rel = mock.MagicMock()
rel.get_instance.return_value = ServiceInstanceObj(
uuid=service.uuid, credentials=credentials, config={}, create_time=create_time
)
rel.get_service.return_value = service
rel.db_obj.credentials_enabled = credentials_enabled
return rel

@mock.patch("paasng.accessories.servicehub.views.mixed_service_mgr.get_or_404")
@mock.patch("paasng.accessories.servicehub.views.mixed_service_mgr.get_attachment_by_engine_app")
def test_list(self, get_attachment_by_engine_app, get_or_404, api_client, bk_app, bk_module):
Expand All @@ -63,3 +74,24 @@ def test_update(self, get_attachment_by_engine_app, get_or_404, api_client, bk_a
assert response.status_code == 200
assert response.data[0]["credentials_enabled"] is False
assert response.data[1]["credentials_enabled"] is False

@mock.patch("paasng.accessories.servicehub.manager.MixedServiceMgr.list_provisioned_rels")
def test_config_vars(self, list_provisioned_rels, api_client, bk_app, bk_module):
service = G(Service)
credentials_disabled_service = G(Service)
list_provisioned_rels.return_value = [
self.create_mock_rel(service, True, datetime.datetime(2020, 1, 1), a=1, b=1),
# 增强服务环境变量不写入
self.create_mock_rel(credentials_disabled_service, False, datetime.datetime(2020, 1, 1), c=1),
]

response = api_client.get(
f"/api/bkapps/applications/{bk_app.code}/modules/{bk_module.name}/services/config_var_keys/",
)
assert response.status_code == 200
# 返回的增强服务名称列表
return_svc_names = list(response.data.keys())
assert service.display_name in return_svc_names
assert set(response.data[service.display_name]) == {"a", "b"}
# 增强服务环境变量设置为不写入则不返回
assert credentials_disabled_service.display_name not in return_svc_names

0 comments on commit 4d0650b

Please sign in to comment.