Skip to content

Commit

Permalink
feat: 提供 Agent 包管理后台基础接口 (closed #1683)
Browse files Browse the repository at this point in the history
  • Loading branch information
ping15 committed Oct 28, 2024
1 parent a00f70c commit bc827dd
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 27 deletions.
27 changes: 17 additions & 10 deletions apps/backend/agent/artifact_builder/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,18 +431,23 @@ def _get_version(self, extract_dir: str) -> str:
raise exceptions.NotSemanticVersionError({"version": version_match})

@cache.class_member_cache()
def _get_description(self, extract_dir: str) -> str:
def _get_description(self, extract_dir: str) -> typing.Tuple[str, str]:
"""
获取版本日志
:param extract_dir: 解压目录
:return:
"""
description_file_path: str = os.path.join(extract_dir, "DESCRIPTION")
if not os.path.exists(description_file_path):
return ""
with open(description_file_path, "r", encoding="utf-8") as description_fs:
description: str = description_fs.read()
return description
description_en_file_path: str = os.path.join(extract_dir, "DESCRIPTION_EN")
description, description_en = "", ""
if os.path.exists(description_file_path):
with open(description_file_path, "r", encoding="utf-8") as description_fs:
description: str = description_fs.read()

if os.path.exists(description_en_file_path):
with open(description_en_file_path, "r", encoding="utf-8") as description_en_fs:
description_en: str = description_en_fs.read()
return description, description_en

def generate_location_path(self, upload_path: str, pkg_name: str) -> str:
if settings.STORAGE_TYPE == core_files_constants.StorageType.BLUEKING_ARTIFACTORY.value:
Expand All @@ -468,7 +473,8 @@ def update_or_create_package_records(self, package_infos: typing.List[typing.Dic
package_info["package_upload_info"]["pkg_path"],
package_info["package_upload_info"]["pkg_name"],
),
"version_log": package_info["artifact_meta_info"]["changelog"],
"version_log": package_info["artifact_meta_info"]["description"],
"version_log_en": package_info["artifact_meta_info"]["description_en"],
},
pkg_name=package_info["package_upload_info"]["pkg_name"],
version=package_info["artifact_meta_info"]["version"],
Expand All @@ -484,7 +490,7 @@ def update_or_create_package_records(self, package_infos: typing.List[typing.Dic
if package_infos:
models.GsePackageDesc.objects.update_or_create(
defaults={
"description": package_infos[0]["artifact_meta_info"]["changelog"],
"description": package_infos[0]["artifact_meta_info"]["description"],
},
project=package_infos[0]["artifact_meta_info"]["name"],
category=constants.CategoryType.official,
Expand Down Expand Up @@ -576,12 +582,13 @@ def get_artifact_meta_info(self, extract_dir: str) -> typing.Dict[str, typing.An
# 配置文件
support_files_info = self._get_support_files_info(extract_dir)
# description
description: str = self._get_description(extract_dir)
description, description_en = self._get_description(extract_dir)

return {
"name": self.NAME,
"version": version_str,
"changelog": description,
"description": description,
"description_en": description_en,
"support_files_info": support_files_info,
}

Expand Down
9 changes: 8 additions & 1 deletion apps/backend/agent/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"""
import typing

from django.utils.translation import get_language
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.status import HTTP_200_OK
Expand Down Expand Up @@ -72,7 +73,13 @@ def parse(self, request):
extract_dir, package_dir_infos = builder.list_package_dir_infos()
artifact_meta_info: typing.Dict[str, typing.Any] = builder.get_artifact_meta_info(extract_dir)

res = {"description": artifact_meta_info.get("changelog"), "packages": package_dir_infos}
language = get_language()
res = {
"description": artifact_meta_info["description"]
if language == "zh-hans"
else artifact_meta_info["description_en"],
"packages": package_dir_infos,
}

context = {
"project": project,
Expand Down
1 change: 1 addition & 0 deletions apps/backend/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class InstNodeType(object):
"INSTALL_AGENT",
"REINSTALL_AGENT",
"UPGRADE_AGENT",
"DOWNGRADE_AGENT",
"RESTART_AGENT",
"UNINSTALL_AGENT",
"RELOAD_AGENT",
Expand Down
29 changes: 29 additions & 0 deletions apps/backend/subscription/steps/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from apps.node_man import constants, models
from apps.node_man.constants import DEFAULT_CLOUD
from apps.node_man.models import GsePluginDesc, SubscriptionStep
from apps.node_man.tools.gse_package import GsePackageTools
from env.constants import GseVersion
from pipeline import builder
from pipeline.builder import Var
Expand Down Expand Up @@ -49,6 +50,7 @@ def get_supported_actions(self):
ReinstallAgent,
UninstallAgent,
UpgradeAgent,
DowngradeAgent,
RestartAgent,
InstallProxy,
ReinstallProxy,
Expand Down Expand Up @@ -109,11 +111,31 @@ def make_instances_migrate_actions(self, instances, auto_trigger=False, preview_
# Agent2 走自更新,仍需调整
backend_const.ActionNameType.UPGRADE_PROXY: backend_const.ActionNameType.UPGRADE_PROXY,
}
version_map: Dict[int, str] = {
version_map["bk_host_id"]: version_map["version"]
for version_map in self.subscription_step.config.get("version_map_list", [])
}
for instance_id, instance in instances.items():
if instance["meta"]["GSE_VERSION"] == GseVersion.V1.value:
instance_actions[instance_id] = self.subscription_step.config["job_type"]
continue
instance_actions[instance_id] = job_type_map[self.subscription_step.config["job_type"]]
models.ProcessStatus.objects.filter(
bk_host_id=instance["host"]["bk_host_id"], name=models.ProcessStatus.GSE_AGENT_PROCESS_NAME
)

if instance_actions[instance_id] == backend_const.ActionNameType.UPGRADE_AGENT:
bk_host_id: int = instance["host"]["bk_host_id"]
agent_version: str = models.ProcessStatus.objects.get(
bk_host_id=bk_host_id, name=models.ProcessStatus.GSE_AGENT_PROCESS_NAME
).version
if all(
[
version_map.get(bk_host_id),
not GsePackageTools.compare_version(version_map[bk_host_id], agent_version),
]
):
instance_actions[instance_id] = backend_const.ActionNameType.DOWNGRADE_AGENT

return {"instance_actions": instance_actions, "migrate_reasons": migrate_reasons}

Expand Down Expand Up @@ -325,6 +347,13 @@ def _generate_activities(self, agent_manager: AgentManager):
return activities, None


class DowngradeAgent(UpgradeAgent):
"""回退Agent"""

ACTION_NAME = backend_const.ActionNameType.DOWNGRADE_AGENT
ACTION_DESCRIPTION = _("回退")


class RestartAgent(AgentAction):
"""
重启Agent
Expand Down
5 changes: 4 additions & 1 deletion apps/node_man/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ def get_optional_items(cls) -> List[str]:
"UNINSTALL_AGENT",
"REMOVE_AGENT",
"UPGRADE_AGENT",
"DOWNGRADE_AGENT",
"IMPORT_AGENT",
"RESTART_AGENT",
"RELOAD_AGENT",
Expand Down Expand Up @@ -234,7 +235,7 @@ def get_optional_items(cls) -> List[str]:
JobType.REINSTALL_PROXY: _("重装 Proxy"),
JobType.REINSTALL_AGENT: _("重装 Agent"),
JobType.UPGRADE_PROXY: _("升级 Proxy"),
JobType.UPGRADE_AGENT: _("升级 Agent"),
JobType.UPGRADE_AGENT: _("升级/回退 Agent"),
JobType.REMOVE_AGENT: _("移除 Agent"),
JobType.UNINSTALL_AGENT: _("卸载 Agent"),
JobType.UNINSTALL_PROXY: _("卸载 Proxy"),
Expand Down Expand Up @@ -266,6 +267,7 @@ def get_optional_items(cls) -> List[str]:
"REMOVE",
"REPLACE",
"UPGRADE",
"DOWNGRADE",
"UPDATE",
"IMPORT",
"UPDATE",
Expand Down Expand Up @@ -294,6 +296,7 @@ def get_optional_items(cls) -> List[str]:
OpType.RESTART: _("重启"),
OpType.REPLACE: _("替换"),
OpType.UPGRADE: _("升级"),
OpType.DOWNGRADE: _("回退"),
OpType.REINSTALL: _("重装"),
OpType.UPDATE: _("更新"),
OpType.REMOVE: _("移除"),
Expand Down
4 changes: 4 additions & 0 deletions apps/node_man/tools/gse_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ def extract_numbers(s):
numbers = re.findall(r"\d+", s)
return [int(num) for num in numbers]

@staticmethod
def compare_version(a, b):
return GsePackageTools.extract_numbers(a) > GsePackageTools.extract_numbers(b)

@classmethod
def match_criteria(cls, pkg_version_info, validated_data, filter_keys):
for key in filter_keys:
Expand Down
29 changes: 16 additions & 13 deletions apps/node_man/views/package_manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from django.db import transaction
from django.db.models import Min, Q, QuerySet
from django.http import JsonResponse
from django.utils.translation import get_language
from django.utils.translation import ugettext_lazy as _
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
from drf_yasg import openapi
Expand Down Expand Up @@ -80,13 +81,13 @@ class PackageManageFilterClass(FilterSet):
# version = django_filters.BaseInFilter(field_name="version", lookup_expr="in")
# created_time = django_filters.DateTimeFromToRangeFilter()
# condition = django_filters.CharFilter(method="filter_condition")
os = django_filters.Filter(field_name="os", lookup_expr="in")
cpu_arch = django_filters.Filter(field_name="cpu_arch", lookup_expr="in")
os_cpu_arch = django_filters.Filter(field_name="os_cpu_arch", method="filter_os_cpu_arch")
tag_names = django_filters.Filter(lookup_expr="in", method="filter_tag_names")
created_by = django_filters.Filter(field_name="created_by", lookup_expr="in")
is_ready = django_filters.Filter(field_name="is_ready")
version = django_filters.Filter(field_name="version", lookup_expr="in")
os = django_filters.BaseInFilter(field_name="os", lookup_expr="in")
cpu_arch = django_filters.BaseInFilter(field_name="cpu_arch", lookup_expr="in")
os_cpu_arch = django_filters.BaseInFilter(field_name="os_cpu_arch", method="filter_os_cpu_arch")
tag_names = django_filters.BaseInFilter(lookup_expr="in", method="filter_tag_names")
created_by = django_filters.BaseInFilter(field_name="created_by", lookup_expr="in")
is_ready = django_filters.BooleanFilter(field_name="is_ready")
version = django_filters.BaseInFilter(field_name="version", lookup_expr="in")
created_time = django_filters.DateTimeFromToRangeFilter()
condition = django_filters.Filter(method="filter_condition")

Expand Down Expand Up @@ -116,15 +117,15 @@ def filter_condition(self, queryset, name, query_list):
model_field_query, tag_query = Q(), Q()
tag_names: List[str] = []
for query_info in query_list:
if not isinstance(query_info, dict) or "value" not in query_info:
if not isinstance(query_info, dict) or query_info.get("key") != "query" or "value" not in query_info:
continue

tag_names.append(query_info["value"])

for field in fields_to_search:
model_field_query |= Q(**{f"{field}__icontains": query_info["value"]})

if "project" in self.request.data:
if "project" in self.request.data and tag_names:
tag_query = Q(
id__in=gse_package_handler.filter_tags(
queryset, self.request.data["project"], tag_names=tag_names
Expand All @@ -141,7 +142,7 @@ class Meta:
class PackageManageFilterBackend(DjangoFilterBackend):
def get_filterset_kwargs(self, request, queryset, view):
return {
"data": request.data,
"data": {**request.data, **dict(request.query_params.items())},
"queryset": queryset,
"request": request,
}
Expand All @@ -155,7 +156,7 @@ class PackageManageViewSet(ValidationMixin, ModelViewSet):
ordering_fields = ["version", "created_time"]

def get_queryset(self):
if not self.action == "search": # noqa
if self.action not in ["search", "quick_search_condition"]: # noqa
self.filter_class = None
return models.GsePackages.objects.all().order_by("-is_ready")

Expand Down Expand Up @@ -598,9 +599,11 @@ def version(self, request):
gse_packages: QuerySet = (
self.get_queryset()
.filter(project=validated_data["project"], is_ready=True)
.values("version", "project", "pkg_name", "os", "cpu_arch", "version_log")
.values("version", "project", "pkg_name", "os", "cpu_arch", "version_log", "version_log_en")
)

language = get_language()

version__pkg_info_map: Dict[str, Dict[str, Any]] = {}
max_version_count: int = 0
default_version: str = ""
Expand All @@ -623,7 +626,7 @@ def version(self, request):
"project": project,
"packages": [],
"tags": tags,
"description": package["version_log"],
"description": package["version_log"] if language == "zh-hans" else package["version_log_en"],
"count": 0,
"os_choices": set(),
"cpu_arch_choices": set(),
Expand Down
Binary file modified locale/en/LC_MESSAGES/django.mo
Binary file not shown.
7 changes: 5 additions & 2 deletions locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -1765,6 +1765,9 @@ msgstr ""
msgid "升级"
msgstr "Upgrade"

msgid "回退"
msgstr "Downgrade"

#: apps/backend/subscription/steps/agent.py:351
#: apps/backend/subscription/steps/agent.py:384
#: apps/backend/subscription/steps/agent.py:426
Expand Down Expand Up @@ -2818,8 +2821,8 @@ msgid "升级 Proxy"
msgstr "Upgrade Proxy"

#: apps/node_man/constants.py:233
msgid "升级 Agent"
msgstr "Upgrade Agent"
msgid "升级/回退 Agent"
msgstr "Upgrade/Downgrade Agent"

#: apps/node_man/constants.py:234
msgid "移除 Agent"
Expand Down

0 comments on commit bc827dd

Please sign in to comment.