Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add workloads related env vars LOG_NAME_PREFIX/PROCESS_TYPE for cnative apps #1488

Merged
merged 4 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
# to the current version of the project delivered to anyone in the future.

from .app_build import mark_as_latest_artifact
from .app_configvar import AppConfigVarManager
from .app_metadata import WlAppMetadata, get_metadata, update_metadata

__all__ = ["AppConfigVarManager", "WlAppMetadata", "get_metadata", "update_metadata", "mark_as_latest_artifact"]
__all__ = ["WlAppMetadata", "get_metadata", "update_metadata", "mark_as_latest_artifact"]

This file was deleted.

6 changes: 3 additions & 3 deletions apiserver/paasng/paas_wl/bk_app/processes/kres_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from kubernetes.dynamic import ResourceField

from paas_wl.bk_app.applications.constants import WlAppType
from paas_wl.bk_app.applications.managers import AppConfigVarManager
from paas_wl.bk_app.applications.models import Release
from paas_wl.bk_app.processes.entities import Probe, Resources, Runtime, Status
from paas_wl.bk_app.processes.kres_slzs import InstanceDeserializer, ProcessDeserializer, ProcessSerializer
Expand All @@ -31,6 +30,7 @@
from paas_wl.infras.resources.generation.version import AppResVerManager
from paas_wl.infras.resources.kube_res.base import AppEntity, Schedule
from paas_wl.infras.resources.utils.basic import get_full_node_selector, get_full_tolerations
from paas_wl.utils.env_vars import VarsRenderContext, render_vars_dict
from paas_wl.workloads.images.utils import make_image_pull_secret_name


Expand Down Expand Up @@ -116,9 +116,9 @@ def from_release(cls, type_: str, release: "Release", extra_envs: Optional[dict]
build = release.build
config = release.config
procfile = release.get_procfile()
envs = AppConfigVarManager(app=release.app).get_process_envs(type_)
envs.update(release.get_envs())
envs = release.get_envs()
envs.update(extra_envs or {})
envs = render_vars_dict(envs, VarsRenderContext(process_type=type_))

mapper_version = AppResVerManager(release.app).curr_version
process = Process(
Expand Down
48 changes: 48 additions & 0 deletions apiserver/paasng/paas_wl/utils/env_vars.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# TencentBlueKing is pleased to support the open source community by making
# 蓝鲸智云 - PaaS 平台 (BlueKing - PaaS System) available.
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
# Licensed under the MIT License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://opensource.org/licenses/MIT
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific language governing permissions and
# limitations under the License.
#
# 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.
from dataclasses import dataclass
from typing import Dict


@dataclass
class VarsRenderContext:
"""The context for rendering environment variables.

:param process_type: The type of the process, e.g. "web", "worker".
"""

process_type: str


def render_vars_dict(d: Dict[str, str], context: VarsRenderContext) -> Dict[str, str]:
"""Render an environment variable dict, replace all supported variables with
values in the given context.

:param d: The environment variable dict to be rendered.
:param context: The context for rendering.
:return: The rendered environment variable dict. The original dict is not modified.
"""
# Use a whitelist to avoid unexpected variable replacement
_supported_key_suffixes = {"_LOG_NAME_PREFIX", "_PROCESS_TYPE"}
result = d.copy()
for k, v in d.items():
if not any(k.endswith(suffix) for suffix in _supported_key_suffixes):
continue

# TODO: Use regular expression or other methods to replace variables when
# there are more variables to be supported.
result[k] = v.replace("{{bk_var_process_type}}", context.process_type)
return result
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
from kubernetes.dynamic import ResourceField, ResourceInstance
from typing_extensions import Literal

from paas_wl.bk_app.applications.managers import AppConfigVarManager
from paas_wl.bk_app.applications.models import WlApp
from paas_wl.infras.cluster.utils import get_cluster_by_app
from paas_wl.infras.resource_templates.logging import get_app_logging_volume, get_app_logging_volume_mounts
Expand All @@ -41,6 +40,7 @@
)
from paas_wl.infras.resources.kube_res.envs import decode_envs, encode_envs
from paas_wl.infras.resources.utils.basic import get_full_node_selector, get_full_tolerations
from paas_wl.utils.env_vars import VarsRenderContext, render_vars_dict
from paas_wl.utils.kubestatus import (
check_pod_health_status,
get_container_fail_message,
Expand Down Expand Up @@ -226,8 +226,8 @@ class Meta:
@classmethod
def from_db_obj(cls, command: "CommandModel", extra_envs: Optional[Dict] = None) -> "Command":
envs = command.get_envs()
envs.update(AppConfigVarManager(command.app).get_envs())
envs.update(extra_envs or {})
envs = render_vars_dict(envs, context=VarsRenderContext(process_type="sys-cmd"))

return cls(
app=command.app,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# to the current version of the project delivered to anyone in the future.

"""Config variables related functions"""

from typing import TYPE_CHECKING, Dict, Iterator, List

from django.conf import settings
Expand Down Expand Up @@ -78,6 +79,10 @@ def get_env_variables(
# Part: system-wide env vars
result.update(get_builtin_env_variables(engine_app, settings.CONFIGVAR_SYSTEM_PREFIX))

# Port: workloads related env vars
vars_wl = _flatten_envs(generate_wl_builtin_env_vars(settings.CONFIGVAR_SYSTEM_PREFIX, env))
result.update(vars_wl)

# Part: insert blobstore env vars
if env.application.type != ApplicationType.CLOUD_NATIVE:
result.update(generate_blobstore_env_vars(engine_app))
Expand Down Expand Up @@ -331,6 +336,54 @@ def get_builtin_env_variables(engine_app: "EngineApp", config_vars_prefix: str)
}


# '{bk_var_*}' is a special placeholder and will be replaced by the actual value
# when the workloads resources are created.
_bk_var_tmpl_process_type = "{{bk_var_process_type}}"


def generate_wl_builtin_env_vars(config_vars_prefix: str, env=None) -> List[BuiltInEnvVarDetail]:
"""Generate env vars related with workloads.

:param config_vars_prefix: The prefix of the env vars.
:param env: Optional, the env object, if given, will include the env vars related
to the environment, such as subpath, process type, etc.
"""
items = [
BuiltInEnvVarDetail(
key="APP_LOG_PATH",
value=settings.MUL_MODULE_VOLUME_MOUNT_APP_LOGGING_DIR,
description=_("应用日志文件存放路径"),
prefix=config_vars_prefix,
),
BuiltInEnvVarDetail(key="PORT", value=str(settings.CONTAINER_PORT), description=_("目标端口号,值为 5000")),
]
# Extend the env vars related to the env when given
if env:
wl_app = env.wl_app
app = env.module.application
items += [
BuiltInEnvVarDetail(
key="LOG_NAME_PREFIX",
value=f"{app.region}-bkapp-{app.code}-{env.environment}-{_bk_var_tmpl_process_type}",
description=_("日志文件推荐使用的前缀"),
prefix=config_vars_prefix,
),
BuiltInEnvVarDetail(
key="PROCESS_TYPE",
value=_bk_var_tmpl_process_type,
description=_("[不推荐使用] 当前进程类型"),
prefix=config_vars_prefix,
),
BuiltInEnvVarDetail(
key="SUB_PATH",
value=f"/{wl_app.region}-{wl_app.name}/",
description=_("[不推荐使用] 基于规则拼接的应用访问子路径,仅适合向前兼容时使用"),
prefix=config_vars_prefix,
),
]
return items


def get_preset_env_variables(env: ModuleEnvironment) -> Dict[str, str]:
"""Get PresetEnvVariable as env variables dict"""
qs: Iterator[PresetEnvVariable] = PresetEnvVariable.objects.filter(module=env.module)
Expand Down
6 changes: 0 additions & 6 deletions apiserver/paasng/paasng/platform/engine/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,3 @@ class AppRunTimeBuiltinEnv(str, StructuredEnum):
"DEFAULT_PREALLOCATED_URLS",
label=_('应用模块各环境的访问地址,如 {"stag": "http://stag.com", "prod": "http://prod.com"}'),
)


class NoPrefixAppRunTimeBuiltinEnv(str, StructuredEnum):
"""Built-in envs without prefix in the app runtime"""

PORT = EnumField("PORT", label=_("目标端口号,值为 5000"))
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@
from blue_krill.storages.blobstore.base import SignatureType
from django.conf import settings

from paas_wl.bk_app.applications.managers import AppConfigVarManager

# NOTE: Import kube resource related modules from paas_wl
from paas_wl.bk_app.applications.models.build import BuildProcess
from paas_wl.bk_app.deploy.app_res.utils import get_schedule_config
from paas_wl.utils.env_vars import VarsRenderContext, render_vars_dict
from paas_wl.utils.text import b64encode
from paas_wl.workloads.images.kres_entities import ImageCredentials
from paas_wl.workloads.images.utils import make_image_pull_secret_name
Expand Down Expand Up @@ -117,8 +116,6 @@ def generate_builder_env_vars(bp: BuildProcess, metadata: Dict) -> Dict[str, str
PILOT_BUILDER_TIMEOUT=f"{settings.BUILD_PROCESS_TIMEOUT // 60}m",
)

env_vars.update(AppConfigVarManager(app=app).get_envs())

# Inject extra env vars in settings for development purpose
if settings.BUILD_EXTRA_ENV_VARS:
env_vars.update(settings.BUILD_EXTRA_ENV_VARS)
Expand All @@ -128,6 +125,7 @@ def generate_builder_env_vars(bp: BuildProcess, metadata: Dict) -> Dict[str, str

if metadata:
update_env_vars_with_metadata(env_vars, metadata)

return env_vars


Expand All @@ -154,6 +152,7 @@ def update_env_vars_with_metadata(env_vars: Dict, metadata: Dict):
:param metadata: metadata dict
:return:
"""
# All system built-in vars were injected by this step
if "extra_envs" in metadata:
env_vars.update(metadata["extra_envs"])

Expand All @@ -177,6 +176,8 @@ def prepare_slugbuilder_template(
image = builder_image or settings.DEFAULT_SLUGBUILDER_IMAGE
logger.info(f"build wl_app<{app.name}> with slugbuilder<{image}>")

env_vars = render_vars_dict(env_vars, VarsRenderContext(process_type="sys-builder"))

return SlugBuilderTemplate(
name=generate_builder_name(app),
namespace=app.namespace,
Expand Down
11 changes: 8 additions & 3 deletions apiserver/paasng/paasng/platform/engine/views/configvar.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
from paasng.platform.engine.configurations.config_var import (
generate_env_vars_by_region_and_env,
generate_env_vars_for_bk_platform,
generate_wl_builtin_env_vars,
)
from paasng.platform.engine.constants import (
AppInfoBuiltinEnv,
AppRunTimeBuiltinEnv,
ConfigVarEnvName,
NoPrefixAppRunTimeBuiltinEnv,
)
from paasng.platform.engine.models import ConfigVar
from paasng.platform.engine.models.config_var import add_prefix_to_key
Expand Down Expand Up @@ -164,8 +164,13 @@ def get_runtime_envs(self, request, code):
env_dict = self._get_enum_choices_dict(AppRunTimeBuiltinEnv)
envs = add_prefix_to_key(env_dict, settings.CONFIGVAR_SYSTEM_PREFIX)

no_prefix_envs = self._get_enum_choices_dict(NoPrefixAppRunTimeBuiltinEnv)
return Response({**envs, **no_prefix_envs})
wl_vars = generate_wl_builtin_env_vars(settings.CONFIGVAR_SYSTEM_PREFIX)
for env in wl_vars:
# Transform the dict structure to remove the value field in order to
# keep consistent and be compatible with the frontend.
# TODO: Show the value in the future.
envs.update({k: v["description"] for k, v in env.to_dict().items()})
return Response({**envs})


class ConfigVarImportExportViewSet(viewsets.ViewSet, ApplicationCodeInPathMixin):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,12 @@
# to the current version of the project delivered to anyone in the future.

import pytest
from django.conf import settings

from paas_wl.bk_app.applications.managers import AppConfigVarManager, WlAppMetadata
from tests.paas_wl.utils.wl_app import create_wl_app
from paas_wl.bk_app.applications.managers import WlAppMetadata

pytestmark = pytest.mark.django_db(databases=["workloads"])


class TestAppConfigVarManager:
def test_app_configvar_generate(self):
wl_app = create_wl_app(
force_app_info={"name": "bkapp-test_me-stag", "region": settings.DEFAULT_REGION_NAME},
paas_app_code="test_me",
environment="stag",
)

action = AppConfigVarManager(app=wl_app)
result = action.get_envs()
assert result["BKPAAS_SUB_PATH"] == "/default-bkapp-test_me-stag/"

result_with_process = action.get_process_envs(process_type="fake")
assert result_with_process["BKPAAS_LOG_NAME_PREFIX"] == "default-bkapp-test_me-stag-fake"
assert result_with_process["PORT"] == str(settings.CONTAINER_PORT)


class TestWlAppMetadata:
def test_empty_data(self):
obj = WlAppMetadata()
Expand Down
Loading