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

master_2_hb_20240823 #7542

Merged
merged 5 commits into from
Aug 23, 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
2 changes: 1 addition & 1 deletion frontend/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"license": "ISC",
"dependencies": {
"@blueking/bkcharts": "^2.0.11-alpha.5",
"@blueking/bkui-form": "0.0.42-beta.5",
"@blueking/bkui-form": "0.0.42-beta.11",
"@blueking/crypto-js-sdk": "0.0.5",
"@blueking/login-modal": "^1.0.1",
"@blueking/notice-component-vue2": "^2.0.1",
Expand Down
2 changes: 1 addition & 1 deletion frontend/desktop/src/config/i18n/cn.js
Original file line number Diff line number Diff line change
Expand Up @@ -1436,7 +1436,7 @@ const cn = {
'留在此页': '留在此页',
'直接离开': '直接离开',
'流程名': '流程名',
'ID/流程名称/标签/更新人/创建人/子流程更新': 'ID/流程名称/标签/更新人/创建人/子流程更新',
'ID/流程名称/标签/更新人/创建人/子流程更新/执行代理人': 'ID/流程名称/标签/更新人/创建人/子流程更新/执行代理人',
'ID/流程名/创建人/更新人': 'ID/流程名/创建人/更新人',
'任务名': '任务名',
'task_任务名': '任务名',
Expand Down
2 changes: 1 addition & 1 deletion frontend/desktop/src/config/i18n/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -1474,7 +1474,7 @@ const en = {
'留在此页': 'Stay on this page',
'直接离开': 'Just leave',
'流程名': 'Flow Name',
'ID/流程名称/标签/更新人/创建人/子流程更新': 'ID/Flow Name/Tags/Modified By/Created By/Subflow Changed',
'ID/流程名称/标签/更新人/创建人/子流程更新/执行代理人': 'ID/Flow Name/Tags/Modified By/Created By/Subflow Changed/Representative',
'ID/流程名/创建人/更新人': 'ID/Flow Name/Created By/Modified By',
'任务名': 'Task Name',
'task_任务名': 'Name',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
<search-select
ref="searchSelect"
id="templateList"
:placeholder="$t('ID/流程名称/标签/更新人/创建人/子流程更新')"
:placeholder="$t('ID/流程名称/标签/更新人/创建人/子流程更新/执行代理人')"
v-model="searchSelectValue"
:search-list="searchList"
@change="handleSearchValueChange">
Expand Down Expand Up @@ -455,6 +455,10 @@
{
id: 'editor',
name: i18n.t('更新人')
},
{
id: 'executor_proxy',
name: i18n.t('执行代理人')
}
]

Expand Down Expand Up @@ -498,6 +502,11 @@
label: i18n.t('分类'),
min_width: 180
},
{
id: 'executor_proxy',
label: i18n.t('执行代理人'),
width: 120
},
{
id: 'creator_name',
label: i18n.t('创建人'),
Expand Down Expand Up @@ -537,7 +546,8 @@
editor = '',
flowName = '',
label_ids = '',
template_id = ''
template_id = '',
executor_proxy = ''
} = this.$route.query
const searchList = [
...SEARCH_LIST,
Expand Down Expand Up @@ -624,7 +634,8 @@
edit_time: edit_time ? edit_time.split(',') : ['', ''],
label_ids: label_ids ? label_ids.split(',') : [],
flowName,
template_id
template_id,
executor_proxy
},
isInit: true, // 避免default-sort在初始化时去触发table的sort-change事件
totalPage: 1,
Expand Down Expand Up @@ -819,7 +830,7 @@
}
},
getQueryData () {
const { subprocessUpdateVal, creator, create_time, edit_time, flowName, label_ids, template_id, editor } = this.requestData
const { subprocessUpdateVal, creator, create_time, edit_time, flowName, label_ids, template_id, editor, executor_proxy } = this.requestData

/**
* 无子流程 has_subprocess=false
Expand All @@ -841,7 +852,8 @@
project__id: this.project_id,
new: true,
id__in: tplIds,
pipeline_template__editor: editor || undefined
pipeline_template__editor: editor || undefined,
executor_proxy
}
const keys = ['edit_time', '-edit_time', 'create_time', '-create_time']
if (keys.includes(this.ordering)) {
Expand Down Expand Up @@ -1478,7 +1490,7 @@
},
updateUrl () {
const { current, limit } = this.pagination
const { category, create_time, edit_time, subprocessUpdateVal, creator, label_ids, flowName, template_id, editor } = this.requestData
const { category, create_time, edit_time, subprocessUpdateVal, creator, label_ids, flowName, template_id, editor, executor_proxy } = this.requestData
const filterObj = {
limit,
category,
Expand All @@ -1490,7 +1502,8 @@
label_ids: label_ids && label_ids.length ? label_ids.join(',') : '',
flowName: flowName,
template_id,
editor
editor,
executor_proxy
}
const query = {}
Object.keys(filterObj).forEach(key => {
Expand Down
30 changes: 19 additions & 11 deletions gcloud/apigw/views/create_and_start_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
specific language governing permissions and limitations under the License.
"""

import re

import jsonschema
import ujson as json
from apigw_manager.apigw.decorators import apigw_require
Expand All @@ -20,30 +22,22 @@

import env
from gcloud import err_code
from gcloud.apigw.decorators import (
mark_request_whether_is_trust,
project_inject,
return_json_response,
)
from gcloud.apigw.decorators import mark_request_whether_is_trust, project_inject, return_json_response
from gcloud.apigw.schemas import APIGW_CREATE_AND_START_TASK_PARAMS
from gcloud.apigw.validators import CreateTaskValidator
from gcloud.apigw.views.utils import logger
from gcloud.common_template.models import CommonTemplate
from gcloud.conf import settings
from gcloud.constants import BUSINESS, COMMON, TaskCreateMethod
from gcloud.contrib.operate_record.constants import (
OperateSource,
OperateType,
RecordType,
)
from gcloud.contrib.operate_record.constants import OperateSource, OperateType, RecordType
from gcloud.contrib.operate_record.decorators import record_operation
from gcloud.core.models import EngineConfig
from gcloud.iam_auth.intercept import iam_intercept
from gcloud.iam_auth.view_interceptors.apigw import CreateTaskInterceptor
from gcloud.taskflow3.celery.tasks import prepare_and_start_task
from gcloud.taskflow3.domains.auto_retry import AutoRetryNodeStrategyCreator
from gcloud.taskflow3.domains.queues import PrepareAndStartTaskQueueResolver
from gcloud.taskflow3.models import TaskFlowInstance
from gcloud.taskflow3.models import TaskCallBackRecord, TaskFlowInstance
from gcloud.tasktmpl3.models import TaskTemplate
from gcloud.utils.decorators import request_validate
from gcloud.utils.throttle import check_task_operation_throttle
Expand Down Expand Up @@ -77,6 +71,15 @@ def create_and_start_task(request, template_id, project_id):
)
)

callback_url = params.pop("callback_url", None)
CALLBACK_URL_PATTERN = r"^https?://\w.+$"
if callback_url and not (isinstance(callback_url, str) and re.match(CALLBACK_URL_PATTERN, callback_url)):
return {
"result": False,
"code": err_code.REQUEST_PARAM_INVALID.code,
"message": f"callback_url format error, must match {CALLBACK_URL_PATTERN}",
}

# 根据template_id获取template
if template_source == BUSINESS:
try:
Expand Down Expand Up @@ -152,6 +155,11 @@ def create_and_start_task(request, template_id, project_id):
)
except Exception as e:
return {"result": False, "message": str(e), "code": err_code.UNKNOWN_ERROR.code}

# create callback url record
if callback_url:
TaskCallBackRecord.objects.create(task_id=task.id, url=callback_url)

# 开始执行task
queue, routing_key = PrepareAndStartTaskQueueResolver(
settings.API_TASK_QUEUE_NAME_V2
Expand Down
1 change: 1 addition & 0 deletions gcloud/core/apis/drf/viewsets/task_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class Meta:
"pipeline_template__edit_time": ["gte", "lte"],
"pipeline_template__create_time": ["gte", "lte"],
"project__id": ["exact"],
"executor_proxy": ["exact"],
}
property_fields = [("subprocess_has_update", BooleanPropertyFilter, ["exact"])]

Expand Down
2 changes: 1 addition & 1 deletion gcloud/utils/cmdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def get_business_host(username, bk_biz_id, supplier_account, host_fields, ip_lis
kwargs = {"bk_biz_id": bk_biz_id, "bk_supplier_account": supplier_account, "fields": list(host_fields or [])}

# 带管控区域的主机数据查询
if ip_list and bk_cloud_id:
if ip_list and bk_cloud_id is not None:
kwargs["host_property_filter"] = {
"condition": "AND",
"rules": [
Expand Down
87 changes: 87 additions & 0 deletions pipeline_plugins/components/collections/sites/open/cc/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,76 @@ def cc_get_host_id_by_innerip(executor, bk_biz_id, ip_list, supplier_account):
return {"result": True, "data": [str(host["bk_host_id"]) for host in host_list]}


def cc_get_host_id_by_innerip_and_cloudid(executor, bk_biz_id, ip_str, supplier_account):
"""根据主机内网 IP 获取主机 ID

:param executor: API 请求用户身份
:type executor: string
:param bk_biz_id: 业务 CC ID
:type bk_biz_id: int
:param ip_list: 主机内网 IP 或 cloudID:IP 列表
:type ip_str: string
:param supplier_account: 开发商账号
:type supplier_account: int
:return: 主机 id 列表
:rtype: list
["1", "2", "3", ...]
"""
ipv4_list_with_cloud_id, ip_str_without_ipv4_with_cloud_id = get_ip_by_regex_type(
IpRegexType.IPV4_WITH_CLOUD_ID.value, ip_str
)
ipv4_list, _ = get_ip_by_regex_type(IpRegexType.IPV4.value, ip_str_without_ipv4_with_cloud_id)
ip_dict = {None: ipv4_list} if ipv4_list else {}
[ip_dict.setdefault(int(ipv4.split(":")[0]), []).append(ipv4.split(":")[1]) for ipv4 in ipv4_list_with_cloud_id]
# TODO 待优化
hosts = []
for cloud_id, ipv4s in ip_dict.items():
if cloud_id is None:
host_fields = ["bk_host_id", "bk_host_innerip"]
else:
host_fields = ["bk_host_id", "bk_host_innerip", "bk_cloud_id"]
host_list = cmdb.get_business_host(
executor,
bk_biz_id,
supplier_account,
host_fields,
ipv4s,
cloud_id,
)

if not host_list:
message = f"IP {ipv4s} 在本业务下不存在: 请检查配置, 修复后重新执行 | cc_get_host_id_by_innerip_and_cloudid"
logger.error(message)
return {"result": False, "message": message}

if len(host_list) > len(ipv4s):
# find repeat innerip host
host_counter = Counter([host["bk_host_innerip"] for host in host_list])
mutiple_hosts = [innerip for innerip, count in host_counter.items() if count > 1]
message = f"IP [{', '.join(mutiple_hosts)}] 在本业务下重复: 请检查配置, 修复后重新执行 | cc_get_host_id_by_innerip_and_cloudid"
logger.error(message)
return {
"result": False,
"message": message,
}

if len(host_list) < len(ipv4s):
return_innerip_set = set()
for host in host_list:
if host.get("bk_cloud_id") is not None:
return_innerip_set.add(f"{host['bk_cloud_id']}:{host['bk_host_innerip']}")
else:
return_innerip_set.add(host["bk_host_innerip"])
absent_innerip = set(ipv4s).difference(return_innerip_set)
message = (
f"IP [{', '.join(absent_innerip)}] 在本业务下不存在: 请检查配置, 修复后重新执行 | cc_get_host_id_by_innerip_and_cloudid"
)
logger.error(message)
return {"result": False, "message": message}
hosts.extend(host_list)
return {"result": True, "data": list({str(host["bk_host_id"]) for host in hosts})}


def cc_get_host_by_innerip_with_ipv6(
executor, bk_biz_id, ip_str, supplier_account, is_biz_set=False, host_id_detail=False
):
Expand Down Expand Up @@ -519,6 +589,23 @@ def get_host_topo(self, executor, biz_cc_id, supplier_account, host_attrs, ip_st
executor, biz_cc_id, supplier_account, host_attrs, ip_list=None, property_filters=property_filters
)

def get_host_list_with_cloud_id(self, executor, biz_cc_id, ip_str, supplier_account):
"""
获取host_list
@param executor: executor 执行人
@param biz_cc_id: biz_cc_id 业务id
@param ip_str: ip_str ip字符串
@param supplier_account: supplier_account
@return:
"""
# 如果开启IPV6
if settings.ENABLE_IPV6:
host_result = cc_get_host_by_innerip_with_ipv6(executor, biz_cc_id, ip_str, supplier_account)
if not host_result["result"]:
return host_result
return {"result": True, "data": [str(host["bk_host_id"]) for host in host_result["data"]]}
return cc_get_host_id_by_innerip_and_cloudid(executor, biz_cc_id, ip_str, supplier_account)


class BaseTransferHostToModuleService(Service, CCPluginIPMixin, metaclass=ABCMeta):
def inputs_format(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from pipeline_plugins.base.utils.inject import supplier_account_for_business
from pipeline_plugins.components.collections.sites.open.cc.base import CCPluginIPMixin, cc_format_prop_data
from pipeline_plugins.components.utils import chunk_table_data, convert_num_to_str
from pipeline_plugins.components.utils.sites.open.utils import plat_ip_reg

logger = logging.getLogger("celery")
get_client_by_user = settings.ESB_GET_CLIENT_BY_USER
Expand Down Expand Up @@ -122,12 +121,8 @@ def execute(self, data, parent_data):
host_property_copy = deepcopy(host_property_custom)
update_host_message = []
for host_property_dir in host_property_copy:
inner_host_ip = host_property_dir["bk_host_innerip"]
# 兼容填写管控区域ID:IP的情况, 只获取对应IP, 判断ipv4
if plat_ip_reg.match(inner_host_ip) and ":" in inner_host_ip:
inner_host_ip = inner_host_ip.split(":")[1]

host_result = self.get_host_list(executor, biz_cc_id, inner_host_ip, supplier_account)
ip_str = host_property_dir["bk_host_innerip"]
host_result = self.get_host_list_with_cloud_id(executor, biz_cc_id, ip_str, supplier_account)
if not host_result["result"]:
data.outputs.ex_data = host_result.get("message")
return False
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,14 @@

from django.utils import translation
from django.utils.translation import ugettext_lazy as _

from pipeline.component_framework.component import Component
from pipeline.core.flow.activity import Service
from pipeline.core.flow.io import StringItemSchema
from pipeline.component_framework.component import Component

from pipeline_plugins.base.utils.inject import supplier_account_for_business
from pipeline_plugins.components.collections.sites.open.cc.base import (
cc_format_prop_data,
CCPluginIPMixin,
)

from gcloud.conf import settings
from gcloud.utils.handlers import handle_api_error
from pipeline_plugins.base.utils.inject import supplier_account_for_business
from pipeline_plugins.components.collections.sites.open.cc.base import CCPluginIPMixin, cc_format_prop_data

logger = logging.getLogger("celery")
get_client_by_user = settings.ESB_GET_CLIENT_BY_USER
Expand Down Expand Up @@ -79,8 +74,8 @@ def execute(self, data, parent_data):
supplier_account = supplier_account_for_business(biz_cc_id)

# 查询主机id
ip_list = data.get_one_of_inputs("cc_host_ip")
host_result = self.get_host_list(executor, biz_cc_id, ip_list, supplier_account)
ip_str = data.get_one_of_inputs("cc_host_ip")
host_result = self.get_host_list_with_cloud_id(executor, biz_cc_id, ip_str, supplier_account)
if not host_result["result"]:
data.set_outputs("ex_data", host_result["message"])
return False
Expand Down
Loading
Loading