Skip to content

Commit

Permalink
optimization: CMDB batch_create_proc_template 限制创建数量不大于100 (closed #89)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhuoZhuoCrayon committed Oct 26, 2021
1 parent 761dfa2 commit 5b48ee8
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 44 deletions.
12 changes: 9 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ repos:
entry: python scripts/check_migrate/check_migrate.py
language: system
types: [python]
- id: check-sensitive-info
name: Check Sensitive Info
entry: sh scripts/workflows/pre-commit/check_sensitive_info.sh
language: system
- id: check-commit-message
name: Check commit message
entry: python scripts/workflows/pre-commit/check_commit_message.py
language: system
stages: [commit-msg]
- id: check-sensitive-info
name: Check Sensitive Info
entry: sh scripts/workflows/pre-commit/check_sensitive_info.sh
- id: generate-dev-log
name: Generate dev log
entry: python scripts/workflows/pre-commit/generate_dev_log.py
language: system
always_run: true
stages: [commit-msg]
74 changes: 43 additions & 31 deletions apps/gsekit/migrate/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from apps.gsekit.process.models import Process, ProcessInst
from apps.iam import Permission, ResourceEnum
from apps.utils.batch_request import batch_request, request_multi_thread
from apps.utils import basic

DIRECT_OLD_GSEKIT_ROOT = os.getenv("DIRECT_OLD_GSEKIT_ROOT", "http://apps.****.com/ieod-bkapp-gsekit-prod")

Expand Down Expand Up @@ -115,38 +116,49 @@ def migrate_process(self):
to_be_created_process_templates = module_process_difference["to_be_created_process_templates"]
to_be_modified_process_templates = module_process_difference["to_be_modified_process_templates"]
if to_be_created_process_templates:
batch_create_params = {
"bk_biz_id": self.bk_biz_id,
"service_template_id": int(service_template["ModuleID"]),
"processes": [
{
"spec": {
"auto_start": {"as_default_value": True, "value": True},
"bk_start_check_secs": {
"as_default_value": True,
"value": int(proc["StartCheckBeginTime"]) or 5,
},
"bk_func_name": {"as_default_value": True, "value": proc["ProcName"]},
"bk_process_name": {"as_default_value": True, "value": proc["FuncID"]},
"description": {"as_default_value": True, "value": proc["FuncName"]},
"face_stop_cmd": {"as_default_value": True, "value": proc["KillCmd"]},
"pid_file": {"as_default_value": True, "value": proc["PidFile"]},
"priority": {"as_default_value": True, "value": int(proc["Seq"]) or 1},
"proc_num": {"as_default_value": True, "value": int(proc["ProcNum"]) or 1},
"reload_cmd": {"as_default_value": True, "value": proc["ReloadCmd"]},
"restart_cmd": {"as_default_value": True, "value": proc["ReStartCmd"]},
"start_cmd": {"as_default_value": True, "value": proc["StartCmd"]},
"stop_cmd": {"as_default_value": True, "value": proc["StopCmd"]},
"timeout": {"as_default_value": True, "value": int(proc["OpTimeout"]) or 60},
"user": {"as_default_value": True, "value": proc["User"]},
"work_path": {"as_default_value": True, "value": proc["WorkPath"]},
"bk_start_param_regex": {"as_default_value": True, "value": proc["FuncName"]},
}
to_be_created_processes = [
{
"spec": {
"auto_start": {"as_default_value": True, "value": True},
"bk_start_check_secs": {
"as_default_value": True,
"value": int(proc["StartCheckBeginTime"]) or 5,
},
"bk_func_name": {"as_default_value": True, "value": proc["ProcName"]},
"bk_process_name": {"as_default_value": True, "value": proc["FuncID"]},
"description": {"as_default_value": True, "value": proc["FuncName"]},
"face_stop_cmd": {"as_default_value": True, "value": proc["KillCmd"]},
"pid_file": {"as_default_value": True, "value": proc["PidFile"]},
"priority": {"as_default_value": True, "value": int(proc["Seq"]) or 1},
"proc_num": {"as_default_value": True, "value": int(proc["ProcNum"]) or 1},
"reload_cmd": {"as_default_value": True, "value": proc["ReloadCmd"]},
"restart_cmd": {"as_default_value": True, "value": proc["ReStartCmd"]},
"start_cmd": {"as_default_value": True, "value": proc["StartCmd"]},
"stop_cmd": {"as_default_value": True, "value": proc["StopCmd"]},
"timeout": {"as_default_value": True, "value": int(proc["OpTimeout"]) or 60},
"user": {"as_default_value": True, "value": proc["User"]},
"work_path": {"as_default_value": True, "value": proc["WorkPath"]},
"bk_start_param_regex": {"as_default_value": True, "value": proc["FuncName"]},
}
for proc in to_be_created_process_templates
],
}
batch_create_results = CCApi.batch_create_proc_template(batch_create_params)
}
for proc in to_be_created_process_templates
]

# CMDB限制该接口的processes长度上限为100
to_be_created_processes_slice_list = basic.list_slice(to_be_created_processes, limit=100)
params_list = [
{
"params": {
"bk_biz_id": self.bk_biz_id,
"service_template_id": int(service_template["ModuleID"]),
"processes": to_be_created_processes_slice,
}
}
for to_be_created_processes_slice in to_be_created_processes_slice_list
]
batch_create_results = request_multi_thread(
func=CCApi.batch_create_proc_template, params_list=params_list, get_data=lambda x: x
)
cmdb_process_templates = CMDBHandler(bk_biz_id=self.bk_biz_id).process_template(
process_template_ids=batch_create_results
)
Expand Down
11 changes: 11 additions & 0 deletions apps/utils/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

from django.utils import timezone

from typing import Any, List


def utc_strftime2local_strftime(
utc_strftime: str, fmt: str = "%Y-%m-%d %H:%M:%S.%f", target_fmt: str = "%Y-%m-%d %H:%M:%S"
Expand Down Expand Up @@ -71,3 +73,12 @@ def distinct_dict_list(dict_list: list):
:return: 去重后的字典列表
"""
return [dict(tupl) for tupl in set([tuple(sorted(item.items())) for item in dict_list])]


def list_slice(lst: List[Any], limit: int) -> List[List[Any]]:
begin = 0
slice_list = []
while begin < len(lst):
slice_list.append(lst[begin : begin + limit])
begin += limit
return slice_list
3 changes: 3 additions & 0 deletions dev_log/1.0.6/crayon_202110261726.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
optimization:
- "CMDB batch_create_proc_template 限制创建数量不大于100 (closed #89)"
5 changes: 0 additions & 5 deletions docs/release.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
# Release

## 1.0.5

- bugfix
- 引导页进程管理路由跳转404 (closed #84)
- 操作进程时主机的过滤条件没有生效(fixed #30)

## 1.0.5

Expand Down
4 changes: 0 additions & 4 deletions release/V1.0.5_20211026.md

This file was deleted.

4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,6 @@ gunicorn==19.6.0
gevent==1.2.2
celery==4.4.7
mako==1.1.3
lxml==4.6.3
lxml==4.6.3
ruamel.yaml==0.17.16
packaging==20.9
168 changes: 168 additions & 0 deletions scripts/workflows/pre-commit/generate_dev_log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# -*- coding: utf-8 -*-
"""
TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-节点管理(BlueKing-BK-NODEMAN) available.
Copyright (C) 2017-2021 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 https://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.
"""

import os
import subprocess
import sys
import traceback
from datetime import datetime
from typing import Any, Dict, List

import ruamel.yaml
from packaging import version
from ruamel.yaml.scalarstring import DoubleQuotedScalarString

DEV_LOG_ROOT = "dev_log"
WF_CMD_PATTERN = "(wf -l)"


def parse_commit_message(commit_message: str) -> Dict[str, str]:
"""
解析提交信息
:param commit_message: git提交信息
:return: 写入yaml的结构
"""
commit_type, commit_content = commit_message.split(":", maxsplit=1)
return {"commit_type": commit_type.strip(), "commit_content": commit_content.strip()}


def get_commit_message() -> Dict[str, str]:
print("flag", sys.argv)
if len(sys.argv) <= 1:
raise ValueError("Can't not find commit message path.")
commit_message_file_path = sys.argv[1]
with open(commit_message_file_path, "r", encoding="utf-8") as fs:
commit_message = fs.read()

return {"commit_message": commit_message, "commit_message_file_path": commit_message_file_path}


def get_git_username() -> str:
"""
获取git username
:return: git username
"""
# 优先取本地配置
resource_cmd_list = [["git", "config", "user.name"], ["git", "config", "--global", "user.name"]]

for resource_cmd in resource_cmd_list:
process = subprocess.Popen(resource_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, __ = process.communicate()
out = out.decode(encoding="utf-8")
if out.endswith("\n"):
out = out[:-1]
if out:
return out

raise ValueError("get git username error: confirm your config.")


def check_is_record(dev_log_yaml_paths: List[str], commit_msg_parse_result: Dict[str, str]) -> bool:
"""
检查是否已记录提交日志
:param dev_log_yaml_paths: 需要检查的文件
:param commit_msg_parse_result: 提交信息解析结果
:return: bool 是否已记录
"""
for dev_log_yaml_path in dev_log_yaml_paths:
if not os.path.exists(dev_log_yaml_path):
continue
with open(file=dev_log_yaml_path, mode="r", encoding="utf-8") as fs:
content = fs.read()
if commit_msg_parse_result["commit_content"] in content:
return True
return False


def generate_dev_log(dev_log_root: str, commit_message: str) -> Dict[str, Any]:
"""
根据 git 提交信息生成 dev_log
:param dev_log_root: dev_log 目录
:param commit_message: git 提交信息
:return:
"""
version_list = os.listdir(dev_log_root)
if not version_list:
raise ValueError(f"dev_log_path -> {dev_log_root} version dev log dir not exist.")
rc_version = sorted(version_list, key=lambda v: version.parse(v))[-1]
git_username = get_git_username()
dt_str = datetime.now().strftime("%Y%m%d%H%M")
user_dev_log_yaml_path = os.path.join(dev_log_root, rc_version, f"{git_username}_{dt_str}.yaml")
commit_msg_parse_result = parse_commit_message(commit_message)

check_is_record_yaml_paths = []
for yaml_file_name in os.listdir(os.path.join(dev_log_root, rc_version)):
check_is_record_yaml_paths.append(os.path.join(dev_log_root, rc_version, yaml_file_name))
is_record = check_is_record(
dev_log_yaml_paths=check_is_record_yaml_paths, commit_msg_parse_result=commit_msg_parse_result
)
if is_record:
return {"is_generated": False}

# 不存在时新建 yaml
if not os.path.exists(user_dev_log_yaml_path):
with open(file=user_dev_log_yaml_path, mode="w+"):
pass

else:
with open(file=user_dev_log_yaml_path, mode="a", encoding="utf-8") as fs:
fs.write("\n")

with open(file=user_dev_log_yaml_path, encoding="utf-8") as yaml_fs:
yaml_info = ruamel.yaml.round_trip_load(yaml_fs, preserve_quotes=True)

# 空yaml文件 yaml_info 为 None
yaml_info = yaml_info or {}
commit_type = commit_msg_parse_result["commit_type"]
commit_content = commit_msg_parse_result["commit_content"]

# DoubleQuotedScalarString -> 保存时携带双引号
# 参考:https://stackoverflow.com/questions/39262556/preserve-quotes-and-also-add-data-with-quotes-in-ruamel
yaml_info[commit_type] = yaml_info.get("commit_type", []) + [DoubleQuotedScalarString(commit_content)]

with open(file=user_dev_log_yaml_path, mode="w", encoding="utf-8") as yaml_fs:
ruamel.yaml.round_trip_dump(yaml_info, yaml_fs, explicit_start=True, block_seq_indent=2)

subprocess.call(["git", "add", user_dev_log_yaml_path])

return {"is_generated": True, "user_dev_log_yaml_path": user_dev_log_yaml_path}


def main() -> int:
get_commit_message_result = get_commit_message()
commit_message_untreated = get_commit_message_result["commit_message"]
commit_message_file_path = get_commit_message_result["commit_message_file_path"]
if WF_CMD_PATTERN not in commit_message_untreated:
print("workflow command not found, skip")
return 0

commit_message = commit_message_untreated.replace(WF_CMD_PATTERN, "")
if commit_message.endswith("\n"):
commit_message = commit_message[:-1]

try:
generate_dev_log_result = generate_dev_log(dev_log_root=DEV_LOG_ROOT, commit_message=commit_message)

with open(file=commit_message_file_path, mode="w", encoding="utf-8") as fs:
fs.write(commit_message)

if generate_dev_log_result["is_generated"]:
print(f"generated dev log yaml -> {generate_dev_log_result['user_dev_log_yaml_path']}")
return 1

except Exception as e:
print(f"Failed to generate dev log: {e}, traceback -> {traceback.format_exc()}")
return 1
return 0


if __name__ == "__main__":
exit(main())

0 comments on commit 5b48ee8

Please sign in to comment.