diff --git a/api/collections/nodeman.py b/api/collections/nodeman.py
index b97ecb678c..01fd0eec1c 100644
--- a/api/collections/nodeman.py
+++ b/api/collections/nodeman.py
@@ -126,5 +126,9 @@ def get_rsa_public_key(self, executor):
def install_channel(self):
return self._request(method="get", url=_get_nodeman_api_v2("install_channel"), data={})
- def get_ipchooser_host_details(self, params: dict):
- return self._request(method="post", url=_get_nodeman_api("core/api/ipchooser_host/details"), data=params)
+ def get_ipchooser_host_details(self, all_scope: bool, host_list: list):
+ return self._request(
+ method="post",
+ url=_get_nodeman_api("core/api/ipchooser_host/details"),
+ data={"all_scope": all_scope, "host_list": host_list},
+ )
diff --git a/frontend/desktop/src/pages/task/TaskExecute/ExecuteInfo.vue b/frontend/desktop/src/pages/task/TaskExecute/ExecuteInfo.vue
index 51914a8a77..c22f17c8eb 100644
--- a/frontend/desktop/src/pages/task/TaskExecute/ExecuteInfo.vue
+++ b/frontend/desktop/src/pages/task/TaskExecute/ExecuteInfo.vue
@@ -874,11 +874,11 @@
}
this.pluginOutputs = outputs
this.outputRenderConfig = [...storeOutputs, ...outputs]
+ // 设置host
+ const { origin } = window.location
+ const hostUrl = `${origin + window.SITE_URL}plugin_service/data_api/${this.thirdPartyNodeCode}/`
+ $.context.bk_plugin_api_host[this.thirdPartyNodeCode] = hostUrl
if (forms.renderform) {
- // 设置host
- const { origin } = window.location
- const hostUrl = `${origin + window.SITE_URL}plugin_service/data_api/${this.thirdPartyNodeCode}/`
- $.context.bk_plugin_api_host[this.thirdPartyNodeCode] = hostUrl
// 输入参数
const renderFrom = forms.renderform
/* eslint-disable-next-line */
@@ -982,11 +982,11 @@
if (!resp.result) return
// 获取参数
const { forms, inputs } = resp.data
+ // 获取host
+ const { origin } = window.location
+ const hostUrl = `${origin + window.SITE_URL}plugin_service/data_api/${plugin}/`
+ $.context.bk_plugin_api_host[plugin] = hostUrl
if (forms.renderform) {
- // 获取host
- const { origin } = window.location
- const hostUrl = `${origin + window.SITE_URL}plugin_service/data_api/${plugin}/`
- $.context.bk_plugin_api_host[plugin] = hostUrl
// 输入参数
$.atoms[plugin] = {}
const renderFrom = forms.renderform
@@ -1169,7 +1169,7 @@
jsFlowInstance && jsFlowInstance.setCanvasPosition(offsetX, offsetY, true)
}
},
-
+
toggleNodeActive (id, isActive) {
const node = document.getElementById(id)
if (!id || !node) return
diff --git a/frontend/desktop/src/pages/task/TaskExecute/ExecuteInfo/ExecuteInfoForm.vue b/frontend/desktop/src/pages/task/TaskExecute/ExecuteInfo/ExecuteInfoForm.vue
index 8fef9f58b5..38574a2651 100644
--- a/frontend/desktop/src/pages/task/TaskExecute/ExecuteInfo/ExecuteInfoForm.vue
+++ b/frontend/desktop/src/pages/task/TaskExecute/ExecuteInfo/ExecuteInfoForm.vue
@@ -314,7 +314,7 @@
getFormsHookState () {
const hooked = {}
const keys = Object.keys(this.constants)
- this.inputs.forEach(form => {
+ Array.isArray(this.inputs) && this.inputs.forEach(form => {
// 已勾选到全局变量中, 判断勾选的输入参数生成的变量及自定义全局变量source_info是否包含该节点对应表单tag_code
// 可能存在表单勾选时已存在相同key的变量,选择复用自定义变量
const isHooked = keys.some(item => {
@@ -437,46 +437,7 @@
}
// 第三方插件
if (isThird) {
- const resp = await this.loadPluginServiceDetail({
- plugin_code: plugin,
- plugin_version: version,
- with_app_detail: true
- })
- if (!resp.result) return
- // 获取参数
- const { outputs: respsOutputs, forms, inputs } = resp.data
- if (forms.renderform) {
- if (!this.isLegacySubProcess) {
- // 获取第三方插件公共输出参数
- if (!this.pluginOutput['remote_plugin']) {
- await this.loadAtomConfig({ atom: 'remote_plugin', version: '1.0.0' })
- }
- // 输出参数
- const storeOutputs = this.pluginOutput['remote_plugin']['1.0.0']
- const outputs = []
- for (const [key, val] of Object.entries(respsOutputs.properties)) {
- outputs.push({
- name: val.title,
- key,
- type: val.type,
- schema: { description: val.description || '--' }
- })
- }
- this.outputs = [...storeOutputs, ...outputs]
- }
- // 获取host
- const { origin } = window.location
- const hostUrl = `${origin + window.SITE_URL}plugin_service/data_api/${plugin}/`
- $.context.bk_plugin_api_host[plugin] = hostUrl
- // 输入参数
- $.atoms[plugin] = {}
- const renderFrom = forms.renderform
- /* eslint-disable-next-line */
- eval(renderFrom)
- } else {
- $.atoms[plugin] = inputs
- this.outputs = [] // jsonschema form输出参数
- }
+ await this.getThirdConfig(plugin, version)
} else {
await this.loadAtomConfig({ atom: plugin, version, classify, name, project_id, scope: 'task' })
this.outputs = this.pluginOutput[plugin][version]
@@ -487,6 +448,51 @@
console.log(e)
}
},
+ // 第三方插件输入输出配置
+ async getThirdConfig (plugin, version) {
+ try {
+ const resp = await this.loadPluginServiceDetail({
+ plugin_code: plugin,
+ plugin_version: version,
+ with_app_detail: true
+ })
+ if (!resp.result) return
+ // 获取参数
+ const { outputs: respOutputs, forms, inputs } = resp.data
+ // 获取host
+ const { origin } = window.location
+ const hostUrl = `${origin + window.SITE_URL}plugin_service/data_api/${plugin}/`
+ $.context.bk_plugin_api_host[plugin] = hostUrl
+ if (forms.renderform) {
+ // 输入参数
+ $.atoms[plugin] = {}
+ const renderFrom = forms.renderform
+ /* eslint-disable-next-line */
+ eval(renderFrom)
+ } else {
+ $.atoms[plugin] = inputs
+ }
+
+ // 输出参数
+ const outputs = []
+ // 获取第三方插件公共输出参数
+ if (!this.pluginOutput['remote_plugin']) {
+ await this.loadAtomConfig({ atom: 'remote_plugin', version: '1.0.0' })
+ }
+ const storeOutputs = this.pluginOutput['remote_plugin']['1.0.0']
+ for (const [key, val] of Object.entries(respOutputs.properties)) {
+ outputs.push({
+ name: val.title || key,
+ key,
+ type: val.type,
+ schema: { description: val.description }
+ })
+ }
+ this.outputs = [...storeOutputs, ...outputs]
+ } catch (error) {
+ console.warn(error)
+ }
+ },
/**
* 获取子流程任务节点输入参数值
*/
diff --git a/frontend/desktop/src/pages/task/TaskExecute/ExecuteInfo/JsonschemaForm.vue b/frontend/desktop/src/pages/task/TaskExecute/ExecuteInfo/JsonschemaForm.vue
index c4a028d2e5..615549c1d8 100644
--- a/frontend/desktop/src/pages/task/TaskExecute/ExecuteInfo/JsonschemaForm.vue
+++ b/frontend/desktop/src/pages/task/TaskExecute/ExecuteInfo/JsonschemaForm.vue
@@ -35,10 +35,7 @@
data () {
return {
formData: tools.deepClone(this.value),
- context: {
- site_url: $.context.site_url,
- project_id: $.context.project?.id
- }
+ context: { ...$.context }
}
},
watch: {
diff --git a/frontend/desktop/src/pages/template/TemplateEdit/NodeConfig/JsonschemaInputParams.vue b/frontend/desktop/src/pages/template/TemplateEdit/NodeConfig/JsonschemaInputParams.vue
index af6b41329c..ca13736680 100644
--- a/frontend/desktop/src/pages/template/TemplateEdit/NodeConfig/JsonschemaInputParams.vue
+++ b/frontend/desktop/src/pages/template/TemplateEdit/NodeConfig/JsonschemaInputParams.vue
@@ -38,10 +38,7 @@
data () {
return {
inputFormData: tools.deepClone(this.value),
- context: {
- site_url: $.context.site_url,
- project_id: $.context.project?.id
- }
+ context: { ...$.context }
}
},
watch: {
diff --git a/frontend/desktop/src/pages/template/TemplateEdit/NodeConfig/NodeConfig.vue b/frontend/desktop/src/pages/template/TemplateEdit/NodeConfig/NodeConfig.vue
index cc5304f1d5..d5c2c70665 100644
--- a/frontend/desktop/src/pages/template/TemplateEdit/NodeConfig/NodeConfig.vue
+++ b/frontend/desktop/src/pages/template/TemplateEdit/NodeConfig/NodeConfig.vue
@@ -625,53 +625,7 @@
}
// 第三方插件
if (isThird) {
- const resp = await this.loadPluginServiceDetail({
- plugin_code: plugin,
- plugin_version: version,
- with_app_detail: true
- })
- if (!resp.result) return
- // 获取参数
- const { outputs: respsOutputs, forms, inputs } = resp.data
- // 获取不同版本的描述
- let desc = resp.data.desc || ''
- if (desc && desc.includes('\n')) {
- const descList = desc.split('\n')
- desc = descList.join('
')
- }
- this.updateBasicInfo({ desc })
- if (forms.renderform) {
- if (!this.isSubflow) {
- // 获取第三方插件公共输出参数
- if (!this.pluginOutput['remote_plugin']) {
- await this.loadAtomConfig({ atom: 'remote_plugin', version: '1.0.0' })
- }
- // 输出参数
- const storeOutputs = this.pluginOutput['remote_plugin']['1.0.0']
- const outputs = []
- for (const [key, val] of Object.entries(respsOutputs.properties)) {
- outputs.push({
- name: val.title,
- key,
- type: val.type,
- schema: { description: val.description || '--' }
- })
- }
- this.outputs = [...storeOutputs, ...outputs]
- }
- // 获取host
- const { origin } = window.location
- const hostUrl = `${origin + window.SITE_URL}plugin_service/data_api/${plugin}/`
- $.context.bk_plugin_api_host[plugin] = hostUrl
- // 输入参数
- $.atoms[plugin] = {}
- const renderFrom = forms.renderform
- /* eslint-disable-next-line */
- eval(renderFrom)
- } else {
- $.atoms[plugin] = inputs
- this.outputs = [] // jsonschema form输出参数
- }
+ await this.getThirdConfig(plugin, version)
} else {
await this.loadAtomConfig({ atom: plugin, version, classify, name, project_id })
}
@@ -681,6 +635,58 @@
console.log(e)
}
},
+ // 第三方插件输入输出配置
+ async getThirdConfig (plugin, version) {
+ try {
+ const resp = await this.loadPluginServiceDetail({
+ plugin_code: plugin,
+ plugin_version: version,
+ with_app_detail: true
+ })
+ if (!resp.result) return
+ // 获取参数
+ const { outputs: respOutputs, forms, inputs } = resp.data
+ // 获取不同版本的描述
+ let desc = resp.data.desc || ''
+ if (desc && desc.includes('\n')) {
+ const descList = desc.split('\n')
+ desc = descList.join('
')
+ }
+ this.updateBasicInfo({ desc })
+ // 获取host
+ const { origin } = window.location
+ const hostUrl = `${origin + window.SITE_URL}plugin_service/data_api/${plugin}/`
+ $.context.bk_plugin_api_host[plugin] = hostUrl
+ if (forms.renderform) {
+ // 输入参数
+ $.atoms[plugin] = {}
+ const renderFrom = forms.renderform
+ /* eslint-disable-next-line */
+ eval(renderFrom)
+ } else {
+ $.atoms[plugin] = inputs
+ }
+
+ // 输出参数
+ const outputs = []
+ // 获取第三方插件公共输出参数
+ if (!this.pluginOutput['remote_plugin']) {
+ await this.loadAtomConfig({ atom: 'remote_plugin', version: '1.0.0' })
+ }
+ const storeOutputs = this.pluginOutput['remote_plugin']['1.0.0']
+ for (const [key, val] of Object.entries(respOutputs.properties)) {
+ outputs.push({
+ name: val.title || key,
+ key,
+ type: val.type,
+ schema: { description: val.description }
+ })
+ }
+ this.outputs = [...storeOutputs, ...outputs]
+ } catch (error) {
+ console.warn(error)
+ }
+ },
/**
* 加载子流程任务节点输入、输出、版本配置项
*/
diff --git a/frontend/desktop/src/pages/template/TemplateEdit/TemplateSetting/TabGlobalVariables/VariableEdit.vue b/frontend/desktop/src/pages/template/TemplateEdit/TemplateSetting/TabGlobalVariables/VariableEdit.vue
index e93c8370b3..65cdf9e1d4 100644
--- a/frontend/desktop/src/pages/template/TemplateEdit/TemplateSetting/TabGlobalVariables/VariableEdit.vue
+++ b/frontend/desktop/src/pages/template/TemplateEdit/TemplateSetting/TabGlobalVariables/VariableEdit.vue
@@ -1045,7 +1045,7 @@
margin-right: 10px;
padding: 0 25px;
}
-
+
}
.textarea-wrap {
height: 88px;
diff --git a/gcloud/utils/data_handler.py b/gcloud/utils/data_handler.py
new file mode 100644
index 0000000000..d24133eae1
--- /dev/null
+++ b/gcloud/utils/data_handler.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+"""
+Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
+Edition) 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.
+"""
+
+
+def _default_func(data, *args, **kwargs):
+ return data
+
+
+def chunk_data(data, chunk_size, func=None, *args, **kwargs):
+ return [(func or _default_func)(data[i : i + chunk_size], *args, **kwargs) for i in range(0, len(data), chunk_size)]
diff --git a/pipeline_plugins/cmdb_ip_picker/query.py b/pipeline_plugins/cmdb_ip_picker/query.py
index 666d776a2d..a09275b650 100644
--- a/pipeline_plugins/cmdb_ip_picker/query.py
+++ b/pipeline_plugins/cmdb_ip_picker/query.py
@@ -23,8 +23,10 @@
from api.utils.request import batch_request
from gcloud.conf import settings
from gcloud.utils import cmdb
+from gcloud.utils.data_handler import chunk_data
from gcloud.utils.handlers import handle_api_error
from gcloud.utils.ip import format_sundry_ip
+from pipeline_plugins.components.utils.common import batch_execute_func
from .constants import ERROR_CODES, NO_ERROR
from .utils import (
@@ -40,6 +42,17 @@
get_client_by_user = settings.ESB_GET_CLIENT_BY_USER
+def format_agent_ip(data, *args, **kwargs):
+ bk_biz_id = kwargs["bk_biz_id"]
+ return [
+ {
+ "host_id": host["bk_host_id"],
+ "meta": {"bk_biz_id": bk_biz_id, "scope_type": "biz", "scope_id": bk_biz_id},
+ }
+ for host in data
+ ]
+
+
def cmdb_search_topo_tree(request, bk_biz_id, bk_supplier_account=""):
"""
@summary: 获取 CMDB 上业务的拓扑树,包含空闲机和故障机模块,根节点是业务
@@ -162,27 +175,21 @@ def cmdb_search_host(request, bk_biz_id, bk_supplier_account="", bk_supplier_id=
host["agent"] = agent_id_status_map.get(bk_agent_id, -1)
else:
client = BKNodeManClient(username=request.user.username)
- agent_kwargs = {
- "all_scope": True,
- "host_list": [
- {
- "cloud_id": host["bk_cloud_id"],
- "ip": host["bk_host_innerip"],
- "meta": {"bk_biz_id": bk_biz_id, "scope_type": "biz", "scope_id": bk_biz_id},
- }
- for host in data
- if host["bk_host_innerip"] != ""
- ],
- }
- agent_result = client.get_ipchooser_host_details(agent_kwargs)
- if not agent_result["result"]:
- message = handle_api_error(
- _("节点管理(nodeman)"), "nodeman.get_ipchooser_host_details", agent_kwargs, agent_result
- )
- result = {"result": False, "code": ERROR_CODES.API_GSE_ERROR, "message": message}
- return JsonResponse(result)
+ host_list = chunk_data(data, 1000, format_agent_ip, bk_biz_id=bk_biz_id)
+ agent_kwargs = [{"all_scope": True, "host_list": host} for host in host_list]
+ results = batch_execute_func(client.get_ipchooser_host_details, agent_kwargs, interval_enabled=True)
- agent_data = format_agent_data(agent_result["data"])
+ agent_data = []
+ for result in results:
+ agent_result = result["result"]
+ if not agent_result["result"]:
+ message = handle_api_error(
+ _("节点管理(nodeman)"), "nodeman.get_ipchooser_host_details", agent_kwargs, agent_result
+ )
+ result = {"result": False, "code": ERROR_CODES.API_GSE_ERROR, "message": message}
+ return JsonResponse(result)
+ agent_data.extend(agent_result["data"])
+ agent_data = format_agent_data(agent_data)
for host in data:
# agent在线状态,0为不在线,1为在线,-1为未知
agent_info = agent_data.get(
diff --git a/pipeline_plugins/variables/collections/sites/open/ip_filter_base.py b/pipeline_plugins/variables/collections/sites/open/ip_filter_base.py
index 83cbd96e39..d1d954b3fd 100644
--- a/pipeline_plugins/variables/collections/sites/open/ip_filter_base.py
+++ b/pipeline_plugins/variables/collections/sites/open/ip_filter_base.py
@@ -22,11 +22,13 @@
from gcloud.core.models import Project
from gcloud.exceptions import ApiRequestError
from gcloud.utils import cmdb
+from gcloud.utils.data_handler import chunk_data
from gcloud.utils.handlers import handle_api_error
from gcloud.utils.ip import IpRegexType, extract_ip_from_ip_str, get_ip_by_regex_type
from pipeline_plugins.base.utils.inject import supplier_account_for_business, supplier_id_for_project
from pipeline_plugins.cmdb_ip_picker.utils import format_agent_data, get_gse_agent_status_ipv6
from pipeline_plugins.components.collections.sites.open.cc.base import cc_get_host_by_innerip_with_ipv6
+from pipeline_plugins.components.utils.common import batch_execute_func
logger = logging.getLogger("root")
get_client_by_user = gcloud_settings.ESB_GET_CLIENT_BY_USER
@@ -94,30 +96,36 @@ def match_ges_v2(self, gse_agent_status, username, bk_biz_id, bk_supplier_id, or
return match_ip
+ @staticmethod
+ def format_origin_ip(data, *args, **kwargs):
+ bk_biz_id = kwargs["bk_biz_id"]
+ return [
+ {
+ "cloud_id": host["bk_cloud_id"],
+ "ip": host["ip"],
+ "meta": {"bk_biz_id": bk_biz_id, "scope_type": "biz", "scope_id": bk_biz_id},
+ }
+ for host in data
+ ]
+
def match_gse_v1(self, gse_agent_status, username, bk_biz_id, bk_supplier_id, origin_ip_list):
match_ip = origin_ip_list
if gse_agent_status in [GseAgentStatus.ONlINE.value, GseAgentStatus.OFFLINE.value]:
+
client = get_nodeman_client_by_user(username=username)
- agent_kwargs = {
- "all_scope": True,
- "host_list": [
- {
- "cloud_id": host["bk_cloud_id"],
- "ip": host["ip"],
- "meta": {"bk_biz_id": bk_biz_id, "scope_type": "biz", "scope_id": bk_biz_id},
- }
- for host in origin_ip_list
- if host["ip"] != ""
- ],
- }
- agent_result = client.get_ipchooser_host_details(agent_kwargs)
-
- if not agent_result["result"]:
- message = handle_api_error(
- _("节点管理(nodeman)"), "nodeman.get_ipchooser_host_details", agent_kwargs, agent_result
- )
- raise ApiRequestError(f"ERROR:{message}")
- agent_data = format_agent_data(agent_result["data"])
+ host_list = chunk_data(origin_ip_list, 1000, self.format_origin_ip, bk_biz_id=bk_biz_id)
+ agent_kwargs = [{"all_scope": True, "host_list": host} for host in host_list]
+ results = batch_execute_func(client.get_ipchooser_host_details, agent_kwargs, interval_enabled=True)
+ agent_data = []
+ for result in results:
+ agent_result = result["result"]
+ if not agent_result["result"]:
+ message = handle_api_error(
+ _("节点管理(nodeman)"), "nodeman.get_ipchooser_host_details", agent_kwargs, agent_result
+ )
+ raise ApiRequestError(f"ERROR:{message}")
+ agent_data.extend(agent_result["data"])
+ agent_data = format_agent_data(agent_data)
agent_online_ip_list = []
agent_offline_ip_list = []
for plat_ip, info in agent_data.items():