Skip to content

Commit a532a90

Browse files
authored
Merge pull request #7542 from TencentBlueKing/master
master_2_hb_20240823
2 parents a13521c + fe453eb commit a532a90

File tree

13 files changed

+280
-48
lines changed

13 files changed

+280
-48
lines changed

frontend/desktop/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"license": "ISC",
1212
"dependencies": {
1313
"@blueking/bkcharts": "^2.0.11-alpha.5",
14-
"@blueking/bkui-form": "0.0.42-beta.5",
14+
"@blueking/bkui-form": "0.0.42-beta.11",
1515
"@blueking/crypto-js-sdk": "0.0.5",
1616
"@blueking/login-modal": "^1.0.1",
1717
"@blueking/notice-component-vue2": "^2.0.1",

frontend/desktop/src/config/i18n/cn.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1436,7 +1436,7 @@ const cn = {
14361436
'留在此页': '留在此页',
14371437
'直接离开': '直接离开',
14381438
'流程名': '流程名',
1439-
'ID/流程名称/标签/更新人/创建人/子流程更新': 'ID/流程名称/标签/更新人/创建人/子流程更新',
1439+
'ID/流程名称/标签/更新人/创建人/子流程更新/执行代理人': 'ID/流程名称/标签/更新人/创建人/子流程更新/执行代理人',
14401440
'ID/流程名/创建人/更新人': 'ID/流程名/创建人/更新人',
14411441
'任务名': '任务名',
14421442
'task_任务名': '任务名',

frontend/desktop/src/config/i18n/en.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1473,7 +1473,7 @@ const en = {
14731473
'留在此页': 'Stay on this page',
14741474
'直接离开': 'Just leave',
14751475
'流程名': 'Flow Name',
1476-
'ID/流程名称/标签/更新人/创建人/子流程更新': 'ID/Flow Name/Tags/Modified By/Created By/Subflow Changed',
1476+
'ID/流程名称/标签/更新人/创建人/子流程更新/执行代理人': 'ID/Flow Name/Tags/Modified By/Created By/Subflow Changed/Representative',
14771477
'ID/流程名/创建人/更新人': 'ID/Flow Name/Created By/Modified By',
14781478
'任务名': 'Task Name',
14791479
'task_任务名': 'Name',

frontend/desktop/src/pages/template/TemplateList/projectTplList.vue

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
<search-select
7070
ref="searchSelect"
7171
id="templateList"
72-
:placeholder="$t('ID/流程名称/标签/更新人/创建人/子流程更新')"
72+
:placeholder="$t('ID/流程名称/标签/更新人/创建人/子流程更新/执行代理人')"
7373
v-model="searchSelectValue"
7474
:search-list="searchList"
7575
@change="handleSearchValueChange">
@@ -456,6 +456,10 @@
456456
{
457457
id: 'editor',
458458
name: i18n.t('更新人')
459+
},
460+
{
461+
id: 'executor_proxy',
462+
name: i18n.t('执行代理人')
459463
}
460464
]
461465
@@ -499,6 +503,11 @@
499503
label: i18n.t('分类'),
500504
min_width: 180
501505
},
506+
{
507+
id: 'executor_proxy',
508+
label: i18n.t('执行代理人'),
509+
width: 120
510+
},
502511
{
503512
id: 'creator_name',
504513
label: i18n.t('创建人'),
@@ -538,7 +547,8 @@
538547
editor = '',
539548
flowName = '',
540549
label_ids = '',
541-
template_id = ''
550+
template_id = '',
551+
executor_proxy = ''
542552
} = this.$route.query
543553
const searchList = [
544554
...SEARCH_LIST,
@@ -625,7 +635,8 @@
625635
edit_time: edit_time ? edit_time.split(',') : ['', ''],
626636
label_ids: label_ids ? label_ids.split(',') : [],
627637
flowName,
628-
template_id
638+
template_id,
639+
executor_proxy
629640
},
630641
isInit: true, // 避免default-sort在初始化时去触发table的sort-change事件
631642
totalPage: 1,
@@ -821,7 +832,7 @@
821832
}
822833
},
823834
getQueryData () {
824-
const { subprocessUpdateVal, creator, create_time, edit_time, flowName, label_ids, template_id, editor } = this.requestData
835+
const { subprocessUpdateVal, creator, create_time, edit_time, flowName, label_ids, template_id, editor, executor_proxy } = this.requestData
825836
826837
/**
827838
* 无子流程 has_subprocess=false
@@ -843,7 +854,8 @@
843854
project__id: this.project_id,
844855
new: true,
845856
id__in: tplIds,
846-
pipeline_template__editor: editor || undefined
857+
pipeline_template__editor: editor || undefined,
858+
executor_proxy
847859
}
848860
const keys = ['edit_time', '-edit_time', 'create_time', '-create_time']
849861
if (keys.includes(this.ordering)) {
@@ -1480,7 +1492,7 @@
14801492
},
14811493
updateUrl () {
14821494
const { current, limit } = this.pagination
1483-
const { category, create_time, edit_time, subprocessUpdateVal, creator, label_ids, flowName, template_id, editor } = this.requestData
1495+
const { category, create_time, edit_time, subprocessUpdateVal, creator, label_ids, flowName, template_id, editor, executor_proxy } = this.requestData
14841496
const filterObj = {
14851497
limit,
14861498
category,
@@ -1492,7 +1504,8 @@
14921504
label_ids: label_ids && label_ids.length ? label_ids.join(',') : '',
14931505
flowName: flowName,
14941506
template_id,
1495-
editor
1507+
editor,
1508+
executor_proxy
14961509
}
14971510
const query = {}
14981511
Object.keys(filterObj).forEach(key => {

gcloud/apigw/views/create_and_start_task.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
specific language governing permissions and limitations under the License.
1212
"""
1313

14+
import re
15+
1416
import jsonschema
1517
import ujson as json
1618
from apigw_manager.apigw.decorators import apigw_require
@@ -20,30 +22,22 @@
2022

2123
import env
2224
from gcloud import err_code
23-
from gcloud.apigw.decorators import (
24-
mark_request_whether_is_trust,
25-
project_inject,
26-
return_json_response,
27-
)
25+
from gcloud.apigw.decorators import mark_request_whether_is_trust, project_inject, return_json_response
2826
from gcloud.apigw.schemas import APIGW_CREATE_AND_START_TASK_PARAMS
2927
from gcloud.apigw.validators import CreateTaskValidator
3028
from gcloud.apigw.views.utils import logger
3129
from gcloud.common_template.models import CommonTemplate
3230
from gcloud.conf import settings
3331
from gcloud.constants import BUSINESS, COMMON, TaskCreateMethod
34-
from gcloud.contrib.operate_record.constants import (
35-
OperateSource,
36-
OperateType,
37-
RecordType,
38-
)
32+
from gcloud.contrib.operate_record.constants import OperateSource, OperateType, RecordType
3933
from gcloud.contrib.operate_record.decorators import record_operation
4034
from gcloud.core.models import EngineConfig
4135
from gcloud.iam_auth.intercept import iam_intercept
4236
from gcloud.iam_auth.view_interceptors.apigw import CreateTaskInterceptor
4337
from gcloud.taskflow3.celery.tasks import prepare_and_start_task
4438
from gcloud.taskflow3.domains.auto_retry import AutoRetryNodeStrategyCreator
4539
from gcloud.taskflow3.domains.queues import PrepareAndStartTaskQueueResolver
46-
from gcloud.taskflow3.models import TaskFlowInstance
40+
from gcloud.taskflow3.models import TaskCallBackRecord, TaskFlowInstance
4741
from gcloud.tasktmpl3.models import TaskTemplate
4842
from gcloud.utils.decorators import request_validate
4943
from gcloud.utils.throttle import check_task_operation_throttle
@@ -77,6 +71,15 @@ def create_and_start_task(request, template_id, project_id):
7771
)
7872
)
7973

74+
callback_url = params.pop("callback_url", None)
75+
CALLBACK_URL_PATTERN = r"^https?://\w.+$"
76+
if callback_url and not (isinstance(callback_url, str) and re.match(CALLBACK_URL_PATTERN, callback_url)):
77+
return {
78+
"result": False,
79+
"code": err_code.REQUEST_PARAM_INVALID.code,
80+
"message": f"callback_url format error, must match {CALLBACK_URL_PATTERN}",
81+
}
82+
8083
# 根据template_id获取template
8184
if template_source == BUSINESS:
8285
try:
@@ -152,6 +155,11 @@ def create_and_start_task(request, template_id, project_id):
152155
)
153156
except Exception as e:
154157
return {"result": False, "message": str(e), "code": err_code.UNKNOWN_ERROR.code}
158+
159+
# create callback url record
160+
if callback_url:
161+
TaskCallBackRecord.objects.create(task_id=task.id, url=callback_url)
162+
155163
# 开始执行task
156164
queue, routing_key = PrepareAndStartTaskQueueResolver(
157165
settings.API_TASK_QUEUE_NAME_V2

gcloud/core/apis/drf/viewsets/task_template.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class Meta:
100100
"pipeline_template__edit_time": ["gte", "lte"],
101101
"pipeline_template__create_time": ["gte", "lte"],
102102
"project__id": ["exact"],
103+
"executor_proxy": ["exact"],
103104
}
104105
property_fields = [("subprocess_has_update", BooleanPropertyFilter, ["exact"])]
105106

gcloud/utils/cmdb.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def get_business_host(username, bk_biz_id, supplier_account, host_fields, ip_lis
123123
kwargs = {"bk_biz_id": bk_biz_id, "bk_supplier_account": supplier_account, "fields": list(host_fields or [])}
124124

125125
# 带管控区域的主机数据查询
126-
if ip_list and bk_cloud_id:
126+
if ip_list and bk_cloud_id is not None:
127127
kwargs["host_property_filter"] = {
128128
"condition": "AND",
129129
"rules": [

pipeline_plugins/components/collections/sites/open/cc/base.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,76 @@ def cc_get_host_id_by_innerip(executor, bk_biz_id, ip_list, supplier_account):
138138
return {"result": True, "data": [str(host["bk_host_id"]) for host in host_list]}
139139

140140

141+
def cc_get_host_id_by_innerip_and_cloudid(executor, bk_biz_id, ip_str, supplier_account):
142+
"""根据主机内网 IP 获取主机 ID
143+
144+
:param executor: API 请求用户身份
145+
:type executor: string
146+
:param bk_biz_id: 业务 CC ID
147+
:type bk_biz_id: int
148+
:param ip_list: 主机内网 IP 或 cloudID:IP 列表
149+
:type ip_str: string
150+
:param supplier_account: 开发商账号
151+
:type supplier_account: int
152+
:return: 主机 id 列表
153+
:rtype: list
154+
["1", "2", "3", ...]
155+
"""
156+
ipv4_list_with_cloud_id, ip_str_without_ipv4_with_cloud_id = get_ip_by_regex_type(
157+
IpRegexType.IPV4_WITH_CLOUD_ID.value, ip_str
158+
)
159+
ipv4_list, _ = get_ip_by_regex_type(IpRegexType.IPV4.value, ip_str_without_ipv4_with_cloud_id)
160+
ip_dict = {None: ipv4_list} if ipv4_list else {}
161+
[ip_dict.setdefault(int(ipv4.split(":")[0]), []).append(ipv4.split(":")[1]) for ipv4 in ipv4_list_with_cloud_id]
162+
# TODO 待优化
163+
hosts = []
164+
for cloud_id, ipv4s in ip_dict.items():
165+
if cloud_id is None:
166+
host_fields = ["bk_host_id", "bk_host_innerip"]
167+
else:
168+
host_fields = ["bk_host_id", "bk_host_innerip", "bk_cloud_id"]
169+
host_list = cmdb.get_business_host(
170+
executor,
171+
bk_biz_id,
172+
supplier_account,
173+
host_fields,
174+
ipv4s,
175+
cloud_id,
176+
)
177+
178+
if not host_list:
179+
message = f"IP {ipv4s} 在本业务下不存在: 请检查配置, 修复后重新执行 | cc_get_host_id_by_innerip_and_cloudid"
180+
logger.error(message)
181+
return {"result": False, "message": message}
182+
183+
if len(host_list) > len(ipv4s):
184+
# find repeat innerip host
185+
host_counter = Counter([host["bk_host_innerip"] for host in host_list])
186+
mutiple_hosts = [innerip for innerip, count in host_counter.items() if count > 1]
187+
message = f"IP [{', '.join(mutiple_hosts)}] 在本业务下重复: 请检查配置, 修复后重新执行 | cc_get_host_id_by_innerip_and_cloudid"
188+
logger.error(message)
189+
return {
190+
"result": False,
191+
"message": message,
192+
}
193+
194+
if len(host_list) < len(ipv4s):
195+
return_innerip_set = set()
196+
for host in host_list:
197+
if host.get("bk_cloud_id") is not None:
198+
return_innerip_set.add(f"{host['bk_cloud_id']}:{host['bk_host_innerip']}")
199+
else:
200+
return_innerip_set.add(host["bk_host_innerip"])
201+
absent_innerip = set(ipv4s).difference(return_innerip_set)
202+
message = (
203+
f"IP [{', '.join(absent_innerip)}] 在本业务下不存在: 请检查配置, 修复后重新执行 | cc_get_host_id_by_innerip_and_cloudid"
204+
)
205+
logger.error(message)
206+
return {"result": False, "message": message}
207+
hosts.extend(host_list)
208+
return {"result": True, "data": list({str(host["bk_host_id"]) for host in hosts})}
209+
210+
141211
def cc_get_host_by_innerip_with_ipv6(
142212
executor, bk_biz_id, ip_str, supplier_account, is_biz_set=False, host_id_detail=False
143213
):
@@ -519,6 +589,23 @@ def get_host_topo(self, executor, biz_cc_id, supplier_account, host_attrs, ip_st
519589
executor, biz_cc_id, supplier_account, host_attrs, ip_list=None, property_filters=property_filters
520590
)
521591

592+
def get_host_list_with_cloud_id(self, executor, biz_cc_id, ip_str, supplier_account):
593+
"""
594+
获取host_list
595+
@param executor: executor 执行人
596+
@param biz_cc_id: biz_cc_id 业务id
597+
@param ip_str: ip_str ip字符串
598+
@param supplier_account: supplier_account
599+
@return:
600+
"""
601+
# 如果开启IPV6
602+
if settings.ENABLE_IPV6:
603+
host_result = cc_get_host_by_innerip_with_ipv6(executor, biz_cc_id, ip_str, supplier_account)
604+
if not host_result["result"]:
605+
return host_result
606+
return {"result": True, "data": [str(host["bk_host_id"]) for host in host_result["data"]]}
607+
return cc_get_host_id_by_innerip_and_cloudid(executor, biz_cc_id, ip_str, supplier_account)
608+
522609

523610
class BaseTransferHostToModuleService(Service, CCPluginIPMixin, metaclass=ABCMeta):
524611
def inputs_format(self):

pipeline_plugins/components/collections/sites/open/cc/batch_update_host/v1_0.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
from pipeline_plugins.base.utils.inject import supplier_account_for_business
2525
from pipeline_plugins.components.collections.sites.open.cc.base import CCPluginIPMixin, cc_format_prop_data
2626
from pipeline_plugins.components.utils import chunk_table_data, convert_num_to_str
27-
from pipeline_plugins.components.utils.sites.open.utils import plat_ip_reg
2827

2928
logger = logging.getLogger("celery")
3029
get_client_by_user = settings.ESB_GET_CLIENT_BY_USER
@@ -122,12 +121,8 @@ def execute(self, data, parent_data):
122121
host_property_copy = deepcopy(host_property_custom)
123122
update_host_message = []
124123
for host_property_dir in host_property_copy:
125-
inner_host_ip = host_property_dir["bk_host_innerip"]
126-
# 兼容填写管控区域ID:IP的情况, 只获取对应IP, 判断ipv4
127-
if plat_ip_reg.match(inner_host_ip) and ":" in inner_host_ip:
128-
inner_host_ip = inner_host_ip.split(":")[1]
129-
130-
host_result = self.get_host_list(executor, biz_cc_id, inner_host_ip, supplier_account)
124+
ip_str = host_property_dir["bk_host_innerip"]
125+
host_result = self.get_host_list_with_cloud_id(executor, biz_cc_id, ip_str, supplier_account)
131126
if not host_result["result"]:
132127
data.outputs.ex_data = host_result.get("message")
133128
return False

pipeline_plugins/components/collections/sites/open/cc/update_host/legacy.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,14 @@
1616

1717
from django.utils import translation
1818
from django.utils.translation import ugettext_lazy as _
19-
19+
from pipeline.component_framework.component import Component
2020
from pipeline.core.flow.activity import Service
2121
from pipeline.core.flow.io import StringItemSchema
22-
from pipeline.component_framework.component import Component
23-
24-
from pipeline_plugins.base.utils.inject import supplier_account_for_business
25-
from pipeline_plugins.components.collections.sites.open.cc.base import (
26-
cc_format_prop_data,
27-
CCPluginIPMixin,
28-
)
2922

3023
from gcloud.conf import settings
3124
from gcloud.utils.handlers import handle_api_error
25+
from pipeline_plugins.base.utils.inject import supplier_account_for_business
26+
from pipeline_plugins.components.collections.sites.open.cc.base import CCPluginIPMixin, cc_format_prop_data
3227

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

8176
# 查询主机id
82-
ip_list = data.get_one_of_inputs("cc_host_ip")
83-
host_result = self.get_host_list(executor, biz_cc_id, ip_list, supplier_account)
77+
ip_str = data.get_one_of_inputs("cc_host_ip")
78+
host_result = self.get_host_list_with_cloud_id(executor, biz_cc_id, ip_str, supplier_account)
8479
if not host_result["result"]:
8580
data.set_outputs("ex_data", host_result["message"])
8681
return False

0 commit comments

Comments
 (0)