Skip to content

Commit afff62a

Browse files
authored
feat: add get conflicted config var keys API (#2262)
1 parent ccc6150 commit afff62a

21 files changed

Lines changed: 718 additions & 239 deletions

File tree

apiserver/paasng/paasng/accessories/servicehub/manager.py

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
# We undertake not to change the open source license (MIT license) applicable
1616
# to the current version of the project delivered to anyone in the future.
1717

18+
import datetime
1819
import logging
1920
import operator
2021
import uuid
2122
from typing import Callable, Dict, Generator, Iterable, Iterator, List, NamedTuple, Optional, TypeVar, cast
2223

24+
from attrs import define
2325
from django.http import Http404
2426

2527
from paasng.accessories.servicehub.constants import ServiceBindingType, ServiceType
@@ -237,37 +239,36 @@ def get_env_vars(
237239
:param filter_enabled: Whether to filter enabled service instances
238240
:returns: Dict of env variables.
239241
"""
240-
rels = list(self.list_provisioned_rels(engine_app, service=service))
241-
if filter_enabled:
242-
instances = [rel.get_instance() for rel in rels if rel.db_obj.credentials_enabled]
243-
else:
244-
instances = [rel.get_instance() for rel in rels]
245-
# 新的覆盖旧的
246-
instances.sort(key=operator.attrgetter("create_time"))
242+
groups = self.get_env_var_groups(engine_app, service=service, filter_enabled=filter_enabled)
243+
# 如果存在同名环境变量,以较新的为准
244+
groups.sort(key=operator.attrgetter("created_at"))
247245

248246
result = {}
249-
for i in instances:
250-
result.update(i.credentials)
247+
for g in groups:
248+
result.update(g.data)
251249
return result
252250

253-
def get_enabled_env_keys(self, engine_app: EngineApp) -> Dict[str, List[str]]:
254-
"""
255-
Get all provisioned services environment keys
251+
def get_env_var_groups(
252+
self, engine_app: EngineApp, service: Optional[ServiceObj] = None, filter_enabled: bool = False
253+
) -> "List[EnvVariableGroup]":
254+
"""Get all provisioned services env variable groups. A group is a collection of environment variables
255+
that belong to a specific service instance.
256256
257257
:param engine_app: EngineApp object
258-
:return: Dictionary of service display names to list of their environment keys
258+
:param service: Optional service object. if given, will only return credentials of the specified service,
259+
otherwise return the credentials of all services.
260+
:param filter_enabled: Whether to filter enabled service instances
261+
:returns: List of env variable groups.
259262
"""
260-
provisioned_rels = self.list_provisioned_rels(engine_app)
261-
# 凭证的信息写入环境变量的增强服务才展示
262-
enabled_rels = [rel for rel in provisioned_rels if rel.db_obj.credentials_enabled]
263-
264-
results = {}
265-
for rel in enabled_rels:
266-
# display_name 会被国际化处理为殊字符串类型(__proxy__类型),必须首先将它们转化为标准的字符串
267-
service_name = str(rel.get_service().display_name)
268-
instance_credentials_keys = list(rel.get_instance().credentials.keys())
269-
results[service_name] = instance_credentials_keys
263+
results = []
264+
for rel in self.list_provisioned_rels(engine_app, service=service):
265+
if filter_enabled and not rel.db_obj.credentials_enabled:
266+
continue
270267

268+
inst = rel.get_instance()
269+
results.append(
270+
EnvVariableGroup(service=rel.get_service(), data=inst.credentials, created_at=inst.create_time)
271+
)
271272
return results
272273

273274
def get_attachment_by_engine_app(self, service: ServiceObj, engine_app: EngineApp):
@@ -340,3 +341,17 @@ def _check_duplicated_sharing(self, service: ServiceObj):
340341
raise DuplicatedServiceBoundError(
341342
f"Module: {self.module.name} already shared an attachment in service: {service.name}"
342343
)
344+
345+
346+
@define
347+
class EnvVariableGroup:
348+
"""An env variable group.
349+
350+
:param service: The owner service object.
351+
:param data: The environment variables.
352+
:param created_at: The time when the var group was created.
353+
"""
354+
355+
service: ServiceObj
356+
data: Dict[str, str]
357+
created_at: datetime.datetime | None

apiserver/paasng/paasng/accessories/servicehub/sharing.py

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
from paasng.accessories.servicehub.manager import (
2626
DuplicatedBindingValidator,
27+
EnvVariableGroup,
2728
SharedServiceInfo,
2829
get_db_properties,
2930
get_db_properties_by_service_type,
@@ -130,37 +131,29 @@ def get_env_variables(self, env: ModuleEnvironment, filter_enabled: bool = False
130131
131132
:param env: ModuleEnvironment object, must belongs to self.module
132133
:param filter_enabled: Whether to filter enabled service instances
134+
:return: A dict of environment variables.
133135
"""
134-
if env.module != self.module:
135-
raise RuntimeError("Invalid env object, must belongs to self.module")
136-
137136
ret = {}
138-
for referenced_info in self.list_all_shared_info():
139-
ref_env = referenced_info.ref_module.get_envs(env.environment)
140-
env_variables = mixed_service_mgr.get_env_vars(ref_env.engine_app, referenced_info.service, filter_enabled)
141-
ret.update(env_variables)
137+
for g in self.get_env_variable_groups(env, filter_enabled):
138+
ret.update(g.data)
142139
return ret
143140

144-
def get_enabled_env_keys(self, env: ModuleEnvironment) -> Dict[str, List[str]]:
145-
"""
146-
Retrieve all environment variable keys shared from other modules.
141+
def get_env_variable_groups(self, env: ModuleEnvironment, filter_enabled: bool = False) -> List[EnvVariableGroup]:
142+
"""Get all env variable groups shared from other modules.
147143
148-
:param env: ModuleEnvironment object that must belong to self.module
149-
:return: Dictionary of service display names to their respective env keys list.
144+
:param env: ModuleEnvironment object, must belongs to self.module
145+
:param filter_enabled: Whether to filter enabled service instances
146+
:return: A list of EnvVariableGroup objects.
150147
"""
151148
if env.module != self.module:
152-
raise RuntimeError("Invalid env object, must belong to self.module")
149+
raise RuntimeError("Invalid env object, must belongs to self.module")
153150

154-
result = {}
151+
results = []
155152
for referenced_info in self.list_all_shared_info():
156153
ref_env = referenced_info.ref_module.get_envs(env.environment)
157-
ref_service = referenced_info.service
158-
env_keys = mixed_service_mgr.get_env_vars(ref_env.engine_app, ref_service, True)
159-
# display_name 会被国际化处理为殊字符串类型(__proxy__类型),必须首先将它们转化为标准的字符串
160-
service_name = str(ref_service.display_name)
161-
result[service_name] = list(env_keys.keys())
162-
163-
return result
154+
groups = mixed_service_mgr.get_env_var_groups(ref_env.engine_app, referenced_info.service, filter_enabled)
155+
results.extend(groups)
156+
return results
164157

165158

166159
def extract_shared_info(attachment: SharedServiceAttachment) -> Optional[SharedServiceInfo]:

apiserver/paasng/paasng/accessories/servicehub/urls.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,6 @@
7474
views.ModuleServiceAttachmentsViewSet.as_view({"get": "retrieve_info"}),
7575
name="api.modules.services.info",
7676
),
77-
re_path(
78-
make_app_pattern("/services/config_var_keys/$", include_envs=False),
79-
views.ModuleServicesViewSet.as_view({"get": "list_provisioned_env_keys"}),
80-
name="api.services.list_provisioned_env_keys",
81-
),
8277
re_path(
8378
make_app_pattern(f"/services/{SERVICE_UUID}/possible_plans$", include_envs=False),
8479
views.ModuleServicesViewSet.as_view({"get": "list_possible_plans"}),

apiserver/paasng/paasng/accessories/servicehub/views.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -292,20 +292,6 @@ def unbind(self, request, code, module_name, service_id):
292292
)
293293
return Response(status=status.HTTP_200_OK)
294294

295-
def list_provisioned_env_keys(self, request, code, module_name):
296-
"""获取已经生效的增强服务环境变量 KEY"""
297-
module = self.get_module_via_path()
298-
299-
# env_key_dict 内容示例: {"svc_name": ["key1", "key2"]}
300-
env_key_dict: Dict[str, List[str]] = {}
301-
for env in module.get_envs():
302-
env_key_dict = {
303-
**env_key_dict,
304-
**ServiceSharingManager(env.module).get_enabled_env_keys(env),
305-
**mixed_service_mgr.get_enabled_env_keys(env.engine_app),
306-
}
307-
return Response(data=env_key_dict)
308-
309295

310296
class ServiceViewSet(viewsets.ViewSet, ApplicationCodeInPathMixin):
311297
"""增强服务相关视图(与应用无关的)"""

apiserver/paasng/paasng/platform/bkapp_model/manifest.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
merge_env_vars_overlay,
7575
override_env_vars_overlay,
7676
)
77-
from paasng.platform.engine.configurations.config_var import get_env_variables
77+
from paasng.platform.engine.configurations.config_var import EnvVarSource, UnifiedEnvVarsReader
7878
from paasng.platform.engine.constants import AppEnvName, ConfigVarEnvName, RuntimeType
7979
from paasng.platform.engine.models import Deployment
8080
from paasng.platform.engine.models.config_var import ENVIRONMENT_ID_FOR_GLOBAL, ConfigVar
@@ -592,9 +592,18 @@ def apply_builtin_env_vars(model_res: crd.BkAppResource, env: ModuleEnvironment)
592592

593593
# 此处,云原生应用忽略这些类型的环境变量:用户手动定义、描述文件定义、服务发现,
594594
# 忽略用户手动定义(include_config_vars)是因为 EnvVarsManifestConstructor 已处理过。
595-
for name, value in get_env_variables(
596-
env, include_config_vars=False, include_preset_env_vars=False, include_svc_disc=False
597-
).items():
595+
system_vars = UnifiedEnvVarsReader(env).get_kv_map(
596+
exclude_sources=[
597+
# 用户在产品或描述文件手动定义,已经由 EnvVarsManifestConstructor 处理
598+
EnvVarSource.USER_CONFIGURED,
599+
EnvVarSource.USER_PRESET,
600+
# 服务发现环境变量,已经由 SvcDiscoveryManifestConstructor 处理,无需在模型主动添加环境变量
601+
EnvVarSource.BUILTIN_SVC_DISC,
602+
# 云原生应用不需要在构建镜像中推送制品到 blobstore,因此忽略
603+
EnvVarSource.BUILTIN_BLOBSTORE,
604+
]
605+
)
606+
for name, value in system_vars.items():
598607
env_vars.append(crd.EnvVar(name=name, value=value))
599608
builtin_env_vars_overlay.append(crd.EnvVarOverlay(envName=environment, name=name, value=value))
600609

0 commit comments

Comments
 (0)