diff --git a/pipeline_plugins/components/collections/sites/open/nodeman/base.py b/pipeline_plugins/components/collections/sites/open/nodeman/base.py index 7f69d0d995..93e7133144 100644 --- a/pipeline_plugins/components/collections/sites/open/nodeman/base.py +++ b/pipeline_plugins/components/collections/sites/open/nodeman/base.py @@ -13,7 +13,7 @@ import ujson as json from django.utils.translation import ugettext_lazy as _ from pipeline.core.flow.activity import Service, StaticIntervalGenerator -from pipeline.core.flow.io import IntItemSchema, StringItemSchema +from pipeline.core.flow.io import ArrayItemSchema, IntItemSchema, ObjectItemSchema, StringItemSchema from api.collections.nodeman import BKNodeManClient from gcloud.conf import settings @@ -140,11 +140,11 @@ def get_ip_list(self, ip_str): def get_host_id_list(self, ip_str, executor, bk_cloud_id, bk_biz_id): # 如果开启了ipv6的逻辑,则执行 if settings.ENABLE_IPV6: - ipv6_list, ipv4_list, _, _ = extract_ip_from_ip_str(ip_str) + ipv6_list, ipv4_list, *_ = extract_ip_from_ip_str(ip_str) ip_list = ipv4_list + ipv6_list bk_host_id_dict_ipv6 = get_host_id_by_inner_ipv6(executor, self.logger, bk_cloud_id, bk_biz_id, ip_list) - - return list(bk_host_id_dict_ipv6.values()) + bk_host_id_dict = get_host_id_by_inner_ip(executor, self.logger, bk_cloud_id, bk_biz_id, ip_list) + return list(set(bk_host_id_dict_ipv6.values()) | set(bk_host_id_dict.values())) ip_list = get_ip_by_regex(ip_str) bk_host_id_dict = get_host_id_by_inner_ip(executor, self.logger, bk_cloud_id, bk_biz_id, ip_list) @@ -282,3 +282,66 @@ def schedule(self, data, parent_data, callback_data=None): data.set_outputs("ex_data", error_log) self.finish_schedule() return False + + +class NodeManNewBaseService(NodeManBaseService): + def inputs_format(self): + return [ + self.InputItem( + name=_("业务 ID"), + key="bk_biz_id", + type="int", + schema=IntItemSchema(description=_("当前操作所属的 CMDB 业务 ID")), + ), + self.InputItem( + name=_("节点类型"), + key="nodeman_node_type", + type="string", + schema=StringItemSchema(description=_("AGENT(表示直连区域安装 Agent)、 PROXY(表示安装 Proxy)")), + ), + self.InputItem( + name=_("操作详情"), + key="nodeman_op_info", + type="object", + schema=ObjectItemSchema( + description=_("操作内容信息"), + property_schemas={ + "nodeman_ap_id": StringItemSchema(description=_("接入点 ID")), + "nodeman_op_type": StringItemSchema( + description=_( + "任务操作类型,可以是 INSTALL(安装)、 REINSTALL(重装)、" " UNINSTALL (卸载)、 REMOVE (移除)或 UPGRADE (升级)" + ) + ), + "nodeman_hosts": ArrayItemSchema( + description=_("需要被操作的主机信息(安装与重装时需要)"), + item_schema=ObjectItemSchema( + description=_("主机相关信息"), + property_schemas={ + "nodeman_bk_cloud_id": StringItemSchema(description=_("管控区域ID")), + "nodeman_ap_id": StringItemSchema(description=_("接入点")), + "inner_ip": StringItemSchema(description=_("内网 IP")), + "login_ip": StringItemSchema(description=_("主机登录 IP,可以为空,适配复杂网络时填写")), + "data_ip": StringItemSchema(description=_("主机数据 IP,可以为空,适配复杂网络时填写")), + "outer_ip": StringItemSchema(description=_("外网 IP, 可以为空")), + "os_type": StringItemSchema(description=_("操作系统类型,可以是 LINUX, WINDOWS, 或 AIX")), + "port": StringItemSchema(description=_("端口号")), + "account": StringItemSchema(description=_("登录帐号")), + "auth_type": StringItemSchema(description=_("认证方式,可以是 PASSWORD 或 KEY")), + "auth_key": StringItemSchema(description=_("认证密钥,根据认证方式,是登录密码或者登陆密钥")), + }, + ), + ), + "nodeman_other_hosts": ArrayItemSchema( + description=_("需要被操作的主机信息(升级,卸载,移除时需要)"), + item_schema=ObjectItemSchema( + description=_("主机相关信息"), + property_schemas={ + "nodeman_bk_cloud_id": StringItemSchema(description=_("管控区域ID")), + "nodeman_ip_str": StringItemSchema(description=_("IP")), + }, + ), + ), + }, + ), + ), + ] diff --git a/pipeline_plugins/components/collections/sites/open/nodeman/create_task/v3_0.py b/pipeline_plugins/components/collections/sites/open/nodeman/create_task/v3_0.py index 610864ac50..c3c0cb514a 100644 --- a/pipeline_plugins/components/collections/sites/open/nodeman/create_task/v3_0.py +++ b/pipeline_plugins/components/collections/sites/open/nodeman/create_task/v3_0.py @@ -14,13 +14,12 @@ from django.utils.translation import ugettext_lazy as _ from pipeline.component_framework.component import Component -from pipeline.core.flow.io import ArrayItemSchema, IntItemSchema, ObjectItemSchema, StringItemSchema from api.collections.nodeman import BKNodeManClient from gcloud.conf import settings from gcloud.utils.crypto import decrypt_auth_key, encrypt_auth_key from pipeline_plugins.components.collections.sites.open.nodeman.base import ( - NodeManBaseService, + NodeManNewBaseService, get_host_id_by_inner_ip, get_host_id_by_inner_ipv6, get_nodeman_rsa_public_key, @@ -45,7 +44,7 @@ HOST_EXTRA_PARAMS_IPV6 = ["inner_ipv6", "outer_ipv6"] -class NodemanCreateTaskService(NodeManBaseService): +class NodemanCreateTaskService(NodeManNewBaseService): def execute(self, data, parent_data): executor = parent_data.inputs.executor client = BKNodeManClient(username=executor) @@ -53,15 +52,6 @@ def execute(self, data, parent_data): node_type = data.inputs.nodeman_node_type - nodeman_ticket = data.get_one_of_inputs("nodeman_ticket", {}) - nodeman_tjj_ticket = nodeman_ticket.get("nodeman_tjj_ticket", "") - if nodeman_tjj_ticket: - try: - nodeman_tjj_ticket = decrypt_auth_key(nodeman_tjj_ticket, settings.RSA_PRIV_KEY) - except Exception: - # password is not encrypted - pass - nodeman_op_info = data.inputs.nodeman_op_info op_type = nodeman_op_info.get("nodeman_op_type", "") nodeman_hosts = nodeman_op_info.get("nodeman_hosts", []) @@ -190,8 +180,6 @@ def execute(self, data, parent_data): kwargs = {"job_type": job_name, "hosts": all_hosts, "action": "job_install"} - if nodeman_tjj_ticket: - kwargs.update({"tcoa_ticket": nodeman_tjj_ticket}) else: data.set_outputs("ex_data", _("无效的操作请求:{}".format(job_name))) return False @@ -201,64 +189,6 @@ def execute(self, data, parent_data): return self.get_job_result(result, data, action, kwargs) - def inputs_format(self): - return [ - self.InputItem( - name=_("业务 ID"), key="bk_biz_id", type="int", schema=IntItemSchema(description=_("当前操作所属的 CMDB 业务 ID")), - ), - self.InputItem( - name=_("节点类型"), - key="nodeman_node_type", - type="string", - schema=StringItemSchema(description=_("AGENT(表示直连区域安装 Agent)、 PROXY(表示安装 Proxy)")), - ), - self.InputItem( - name=_("操作详情"), - key="nodeman_op_info", - type="object", - schema=ObjectItemSchema( - description=_("操作内容信息"), - property_schemas={ - "nodeman_ap_id": StringItemSchema(description=_("接入点 ID")), - "nodeman_op_type": StringItemSchema( - description=_( - "任务操作类型,可以是 INSTALL(安装)、 REINSTALL(重装)、" " UNINSTALL (卸载)、 REMOVE (移除)或 UPGRADE (升级)" - ) - ), - "nodeman_hosts": ArrayItemSchema( - description=_("需要被操作的主机信息(安装与重装时需要)"), - item_schema=ObjectItemSchema( - description=_("主机相关信息"), - property_schemas={ - "nodeman_bk_cloud_id": StringItemSchema(description=_("管控区域ID")), - "nodeman_ap_id": StringItemSchema(description=_("接入点")), - "inner_ip": StringItemSchema(description=_("内网 IP")), - "login_ip": StringItemSchema(description=_("主机登录 IP,可以为空,适配复杂网络时填写")), - "data_ip": StringItemSchema(description=_("主机数据 IP,可以为空,适配复杂网络时填写")), - "outer_ip": StringItemSchema(description=_("外网 IP, 可以为空")), - "os_type": StringItemSchema(description=_("操作系统类型,可以是 LINUX, WINDOWS, 或 AIX")), - "port": StringItemSchema(description=_("端口号")), - "account": StringItemSchema(description=_("登录帐号")), - "auth_type": StringItemSchema(description=_("认证方式,可以是 PASSWORD 或 KEY")), - "auth_key": StringItemSchema(description=_("认证密钥,根据认证方式,是登录密码或者登陆密钥")), - }, - ), - ), - "nodeman_other_hosts": ArrayItemSchema( - description=_("需要被操作的主机信息(升级,卸载,移除时需要)"), - item_schema=ObjectItemSchema( - description=_("主机相关信息"), - property_schemas={ - "nodeman_bk_cloud_id": StringItemSchema(description=_("管控区域ID")), - "nodeman_ip_str": StringItemSchema(description=_("IP")), - }, - ), - ), - }, - ), - ), - ] - class NodemanCreateTaskComponent(Component): name = _("新建任务") diff --git a/pipeline_plugins/components/collections/sites/open/nodeman/create_task/v4_0.py b/pipeline_plugins/components/collections/sites/open/nodeman/create_task/v4_0.py index 43eeb95e4c..bf68a50efd 100644 --- a/pipeline_plugins/components/collections/sites/open/nodeman/create_task/v4_0.py +++ b/pipeline_plugins/components/collections/sites/open/nodeman/create_task/v4_0.py @@ -10,9 +10,10 @@ 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. """ +from copy import deepcopy + from django.utils.translation import ugettext_lazy as _ from pipeline.component_framework.component import Component -from pipeline.core.flow.io import ArrayItemSchema, IntItemSchema, ObjectItemSchema, StringItemSchema from api.collections.nodeman import BKNodeManClient from gcloud.conf import settings @@ -20,18 +21,34 @@ from gcloud.utils.crypto import decrypt_auth_key, encrypt_auth_key from pipeline_plugins.base.utils.inject import supplier_account_for_business from pipeline_plugins.components.collections.sites.open.nodeman.base import ( - NodeManBaseService, + NodeManNewBaseService, get_nodeman_rsa_public_key, ) __group_name__ = _("节点管理(Nodeman)") VERSION = "v4.0" -# 安装类任务(job_install) -INSTALL_JOB = ["INSTALL_PROXY", "INSTALL_AGENT", "REINSTALL_PROXY", "REINSTALL_AGENT", "UNINSTALL_AGENT"] +# 无需认证信息的操作 +NOT_NEED_AUTH_JOB = ["RELOAD_AGENT", "RELOAD_PROXY"] + + +# 无需额外配置信息的操作 +NOT_NEED_EXTRA_CONFIG_JOB = ["UNINSTALL_AGENT"] -# 操作类任务(job_operate) -OPERATE_JOB = ["UPGRADE_AGENT", "UNINSTALL_PROXY"] +# 依赖节点管理 job/install 接口的操作 +INSTALL_JOB = ( + [ + "INSTALL_PROXY", + "INSTALL_AGENT", + "REINSTALL_PROXY", + "REINSTALL_AGENT", + ] + + NOT_NEED_EXTRA_CONFIG_JOB + + NOT_NEED_AUTH_JOB +) + +# 依赖节点管理 job/details 接口的操作 +OPERATE_JOB = ["UPGRADE_AGENT", "UPGRADE_PROXY", "UNINSTALL_PROXY", "RESTART_AGENT", "RESTART_PROXY"] # 主机其它参数 HOST_EXTRA_PARAMS = ["outer_ip", "login_ip", "data_ip", "inner_ipv6", "outer_ipv6"] @@ -40,21 +57,12 @@ HOST_EXTRA_PARAMS_IPV6 = ["inner_ipv6", "outer_ipv6"] -class NodemanCreateTaskService(NodeManBaseService): +class NodemanCreateTaskService(NodeManNewBaseService): def execute(self, data, parent_data): executor = parent_data.inputs.executor client = BKNodeManClient(username=executor) bk_biz_id = data.inputs.bk_biz_id - nodeman_ticket = data.get_one_of_inputs("nodeman_ticket", {}) - nodeman_tjj_ticket = nodeman_ticket.get("nodeman_tjj_ticket", "") - if nodeman_tjj_ticket: - try: - nodeman_tjj_ticket = decrypt_auth_key(nodeman_tjj_ticket, settings.RSA_PRIV_KEY) - except Exception: - # password is not encrypted - pass - nodeman_op_info = data.inputs.nodeman_op_info node_type = nodeman_op_info.get("nodeman_node_type") op_type = nodeman_op_info.get("nodeman_op_type", "") @@ -85,10 +93,6 @@ def execute(self, data, parent_data): all_hosts, row_host_params_list = [], [] for host in nodeman_hosts: bk_cloud_id = host["nodeman_bk_cloud_id"] - ap_id = host["nodeman_ap_id"] - auth_type = host["auth_type"] - auth_key = host["auth_key"] - use_inner_ip = True if host.get("inner_ip") else False # use_inner_ip 判定用户输入的的是ipv4还是ipv6 inner_ip_list = self.get_ip_list( @@ -101,46 +105,71 @@ def execute(self, data, parent_data): data.set_outputs("ex_data", _("请确认内网Ip是否合法host_info:{host}".format(host=host["inner_ip"]))) return False - # 处理表格中每行的key/psw - try: - auth_key = decrypt_auth_key(auth_key, settings.RSA_PRIV_KEY) - except Exception: - # password is not encrypted - pass - # auth_key加密 - success, ras_public_key = get_nodeman_rsa_public_key(executor, self.logger) - if not success: - data.set_outputs("ex_data", _("获取节点管理公钥失败,请查看节点日志获取错误详情.")) - return False - auth_key = encrypt_auth_key(auth_key, ras_public_key["name"], ras_public_key["content"]) + auth_params = {} + if job_name not in NOT_NEED_AUTH_JOB: + + # 认证信息 + auth_params.update( + { + "port": host["port"], + "auth_type": host["auth_type"], + "account": host["account"], + } + ) + + auth_key = host["auth_key"] + + # 处理表格中每行的key/psw + try: + auth_key = decrypt_auth_key(auth_key, settings.RSA_PRIV_KEY) + except Exception: + # password is not encrypted + pass + + # auth_key加密 + success, ras_public_key = get_nodeman_rsa_public_key(executor, self.logger) + if not success: + data.set_outputs("ex_data", _("获取节点管理公钥失败,请查看节点日志获取错误详情.")) + return False + auth_key = encrypt_auth_key(auth_key, ras_public_key["name"], ras_public_key["content"]) + + if auth_params["auth_type"] == "PASSWORD": + auth_params["password"] = auth_key + else: + auth_params["key"] = auth_key + + # 额外配置参数 + extra_config_params = {"peer_exchange_switch_for_agent": host.get("peer_exchange_switch_for_agent", 0)} + speed_limit = host.get("speed_limit") + if speed_limit: + extra_config_params.update({"bt_speed_limit": int(speed_limit)}) + # 表格每行基础参数 base_params = { + **auth_params, "bk_biz_id": bk_biz_id, "bk_cloud_id": bk_cloud_id, + "ap_id": host["nodeman_ap_id"], "os_type": host["os_type"], - "port": host["port"], - "account": host["account"], - "auth_type": auth_type, - "ap_id": ap_id, "is_manual": False, - "peer_exchange_switch_for_agent": host.get("peer_exchange_switch_for_agent", 1), } - speed_limit = host.get("speed_limit") - if speed_limit: - base_params.update({"bt_speed_limit": int(speed_limit)}) # 支持表格中一行多ip操作, 拼装表格内的inner_ip参数 for index, inner_ip in enumerate(inner_ip_list): - one = {} + + row_host_info = deepcopy(base_params) if use_inner_ip: - one = {"inner_ip": inner_ip} - if auth_type == "PASSWORD": - one["password"] = auth_key - else: - one["key"] = auth_key + row_host_info.update({"inner_ip": inner_ip}) + + # 注入额外 Agent 配置信息 + if job_name not in NOT_NEED_EXTRA_CONFIG_JOB: + row_host_info.update(extra_config_params) - # 重装必须要bk_host_id - if job_name in ["REINSTALL_PROXY", "REINSTALL_AGENT", "UNINSTALL_AGENT"]: + # 除了安装,其他操作需要 bk_host_id + if ( + job_name + in ["REINSTALL_PROXY", "REINSTALL_AGENT"] + NOT_NEED_AUTH_JOB + NOT_NEED_EXTRA_CONFIG_JOB + ): supplier_account = supplier_account_for_business(bk_biz_id) host_fields = ["bk_host_id", "bk_host_innerip"] # 如果开启了ipv6,并且用户输入的是ipv6的地址 @@ -156,7 +185,7 @@ def execute(self, data, parent_data): ) bk_host_id_dict = {host["bk_host_innerip"]: host["bk_host_id"] for host in host_list} try: - one["bk_host_id"] = bk_host_id_dict[inner_ip] + row_host_info["bk_host_id"] = bk_host_id_dict[inner_ip] except KeyError: data.set_outputs("ex_data", _("获取bk_host_id失败:{},请确认管控区域是否正确".format(inner_ip))) return False @@ -169,14 +198,12 @@ def execute(self, data, parent_data): if host.get(ip_type, False): others_ip_list = self.get_ip_list(host[ip_type]) if len(others_ip_list) == len(inner_ip_list): - one[ip_type] = others_ip_list[index] + row_host_info[ip_type] = others_ip_list[index] else: data.set_outputs("ex_data", _("获取{}的{}失败,请确认是否与inner_ip一一对应".format(inner_ip, ip_type))) return False - one.update(base_params) - - row_host_params_list.append(one) + row_host_params_list.append(row_host_info) all_hosts.extend(row_host_params_list) @@ -185,8 +212,6 @@ def execute(self, data, parent_data): if job_name in ["INSTALL_PROXY", "INSTALL_AGENT", "REINSTALL_PROXY", "REINSTALL_AGENT"]: kwargs.update({"is_install_latest_plugins": nodeman_install_latest_plugins}) - if nodeman_tjj_ticket: - kwargs.update({"tcoa_ticket": nodeman_tjj_ticket}) else: data.set_outputs("ex_data", _("无效的操作请求:{}".format(job_name))) return False @@ -196,64 +221,6 @@ def execute(self, data, parent_data): return self.get_job_result(result, data, action, kwargs) - def inputs_format(self): - return [ - self.InputItem( - name=_("业务 ID"), key="bk_biz_id", type="int", schema=IntItemSchema(description=_("当前操作所属的 CMDB 业务 ID")), - ), - self.InputItem( - name=_("节点类型"), - key="nodeman_node_type", - type="string", - schema=StringItemSchema(description=_("AGENT(表示直连区域安装 Agent)、 PROXY(表示安装 Proxy)")), - ), - self.InputItem( - name=_("操作详情"), - key="nodeman_op_info", - type="object", - schema=ObjectItemSchema( - description=_("操作内容信息"), - property_schemas={ - "nodeman_ap_id": StringItemSchema(description=_("接入点 ID")), - "nodeman_op_type": StringItemSchema( - description=_( - "任务操作类型,可以是 INSTALL(安装)、 REINSTALL(重装)、" " UNINSTALL (卸载)、 REMOVE (移除)或 UPGRADE (升级)" - ) - ), - "nodeman_hosts": ArrayItemSchema( - description=_("需要被操作的主机信息(安装与重装时需要)"), - item_schema=ObjectItemSchema( - description=_("主机相关信息"), - property_schemas={ - "nodeman_bk_cloud_id": StringItemSchema(description=_("管控区域ID")), - "nodeman_ap_id": StringItemSchema(description=_("接入点")), - "inner_ip": StringItemSchema(description=_("内网 IP")), - "login_ip": StringItemSchema(description=_("主机登录 IP,可以为空,适配复杂网络时填写")), - "data_ip": StringItemSchema(description=_("主机数据 IP,可以为空,适配复杂网络时填写")), - "outer_ip": StringItemSchema(description=_("外网 IP, 可以为空")), - "os_type": StringItemSchema(description=_("操作系统类型,可以是 LINUX, WINDOWS, 或 AIX")), - "port": StringItemSchema(description=_("端口号")), - "account": StringItemSchema(description=_("登录帐号")), - "auth_type": StringItemSchema(description=_("认证方式,可以是 PASSWORD 或 KEY")), - "auth_key": StringItemSchema(description=_("认证密钥,根据认证方式,是登录密码或者登陆密钥")), - }, - ), - ), - "nodeman_other_hosts": ArrayItemSchema( - description=_("需要被操作的主机信息(升级,卸载,移除时需要)"), - item_schema=ObjectItemSchema( - description=_("主机相关信息"), - property_schemas={ - "nodeman_bk_cloud_id": StringItemSchema(description=_("管控区域ID")), - "nodeman_ip_str": StringItemSchema(description=_("IP")), - }, - ), - ), - }, - ), - ), - ] - class NodemanCreateTaskComponent(Component): name = _("新建任务") diff --git a/pipeline_plugins/components/static/components/atoms/nodeman/create_task/v4_0.js b/pipeline_plugins/components/static/components/atoms/nodeman/create_task/v4_0.js index d0457cf9bf..86dd4b1df5 100644 --- a/pipeline_plugins/components/static/components/atoms/nodeman/create_task/v4_0.js +++ b/pipeline_plugins/components/static/components/atoms/nodeman/create_task/v4_0.js @@ -13,14 +13,289 @@ (function () { function is_display_tag(self, op_type, value) { if (op_type.indexOf(value) !== -1) { - self.show() + self.show(); } else { - self.hide() + self.hide(); } } - let node_type = "AGENT" - let NODEMAN_TJJ_IS_HIDDEN = true + function is_install_op(self, value) { + is_display_tag(self, ["INSTALL", "REINSTALL"], value); + } + + + function init_columns(self, node_type, op_type) { + let common_columns = [ + { + tag_code: "nodeman_bk_cloud_id", + type: "select", + attrs: { + name: gettext("管控区域ID"), + width: "180px", + remote: true, + items: [], + remote_url: $.context.get("site_url") + "pipeline/nodeman_get_cloud_area/", + remote_data_init: function (resp) { + if (resp.result === false) { + show_msg(resp.message, "error"); + } + resp.data.unshift({"text": gettext("直连区域"), "value": 0}); + return resp.data; + }, + validation: [ + { + type: "required", + } + ] + } + }, + { + tag_code: "nodeman_ap_id", + type: "select", + attrs: { + name: gettext("接入点"), + width: "180px", + remote: true, + items: [], + remote_url: $.context.get("site_url") + "pipeline/nodeman_get_ap_list/", + remote_data_init: function (resp) { + if (resp.result === false) { + show_msg(resp.message, "error"); + } + return resp.data; + }, + validation: [] + } + }, + { + tag_code: "inner_ip", + type: "textarea", + attrs: { + name: gettext("内网IP"), + placeholder: gettext("多个用英文逗号 `,` 或换行分隔"), + width: "180px", + editable: true + } + }, + { + tag_code: "inner_ipv6", + type: "textarea", + attrs: { + name: gettext("内网IP(IPV6)"), + placeholder: gettext("可为空,如纯ipv6主机,内网ipv和外网IP(IPV6)两个必须填一个"), + width: "180px", + editable: true, + } + }, + { + tag_code: "os_type", + type: "select", + attrs: { + name: gettext("操作系统类型"), + width: "180px", + items: [ + {value: "LINUX", text: gettext("LINUX")}, + {value: "WINDOWS", text: gettext("WINDOWS")}, + {value: "AIX", text: gettext("AIX")} + ], + default: "LINUX", + validation: [ + { + type: "required" + } + ], + } + }, + ]; + + let proxy_columns = [ + { + tag_code: "outer_ip", + type: "textarea", + attrs: { + name: gettext("外网IP"), + placeholder: gettext("可选,如填写需与内网ip一一对应,多个用英文逗号 `,` 或换行分隔"), + width: "180px", + editable: true, + validation: [] + }, + }, + { + tag_code: "data_ip", + type: "textarea", + attrs: { + name: gettext("数据IP"), + placeholder: gettext("可为空,如填写需与内网ip一一对应,适配复杂网络时填写,多个用英文逗号 `,` 或换行分隔"), + width: "180px", + editable: true, + } + }, + { + tag_code: "outer_ipv6", + type: "textarea", + attrs: { + name: gettext("外网IP(IPV6)"), + placeholder: gettext("可为空,如纯ipv6主机,外网ipv和外网IP(IPV6)两个必须填一个"), + width: "180px", + editable: true, + }, + }, + ]; + + let auth_columns = [ + { + tag_code: "login_ip", + type: "textarea", + attrs: { + name: gettext("登录IP"), + placeholder: gettext("可为空,如填写需与内网ip一一对应,适配复杂网络时填写,多个用英文逗号 `,` 或换行分隔"), + width: "180px", + editable: true + } + }, + { + tag_code: "account", + type: "input", + attrs: { + name: gettext("登录账号"), + width: "180px", + editable: true, + validation: [ + { + type: "required" + } + ], + } + }, + { + tag_code: "port", + type: "input", + attrs: { + name: gettext("端口号"), + width: "100px", + editable: true, + validation: [ + { + type: "required" + } + ], + } + }, + { + tag_code: "auth_type", + type: "select", + attrs: { + name: gettext("认证方式"), + width: "180px", + items: [ + {value: "PASSWORD", text: gettext("PASSWORD")}, + {value: "KEY", text: gettext("KEY")}, + {value: "TJJ_PASSWORD", text: gettext("TJJ")} + + ], + default: "PASSWORD", + validation: [ + { + type: "required" + } + ], + } + }, + { + tag_code: "auth_key", + type: "textarea", + // TODO 能不能加一个动态选项?如果具有加密前缀,默认展示 * 脱敏 + // TODO 如果重新输入保存,可以拉公钥去做加密 + attrs: { + name: gettext("认证密钥"), + width: "400px", + editable: true, + validation: [ + { + type: "custom", + args: function (value, parent_value) { + let auth_type = parent_value.auth_type; + let result = { + result: true, + error_message: "" + }; + if (auth_type !== "TJJ_PASSWORD" && !value.length) { + result.result = false; + result.error_message = gettext("请输入认证密钥"); + } + return result; + } + } + ], + showPassword: true + }, + }, + ]; + + let config_columns = [ + { + tag_code: "peer_exchange_switch_for_agent", + type: "radio", + attrs: { + name: gettext("BT节点探测"), + items: [ + {value: 1, name: gettext("是")}, + {value: 0, name: gettext("否")} + ], + default: 0, + validation: [ + { + type: "required" + }, + ] + }, + }, + { + tag_code: "speed_limit", + type: "input", + attrs: { + name: gettext("传输限速 M/s"), + width: "100px", + placeholder: gettext("请输入"), + validation: [ + { + type: "custom", + args: function (value) { + var result = { + result: true, + error_message: "" + }; + if (value && !Number(value)) { + result.result = false; + result.error_message = gettext("请输入数字"); + } + return result; + } + } + ] + }, + }, + ]; + + self.columns = common_columns; + + // 如果是 Proxy,补充 Proxy 信息 + if (node_type === "PROXY") { + self.columns.push(...proxy_columns); + } + // 安装 / 卸载需要认证信息 + if (op_type === "INSTALL" || op_type === "UNINSTALL") { + self.columns.push(...auth_columns); + } + // 非卸载场景需要配置信息 + if (op_type !== "UNINSTALL") { + self.columns.push(...config_columns); + } + console.log(node_type, op_type); + }; + + let NODEMAN_TJJ_IS_HIDDEN = true; + $.ajax({ url: $.context.get('site_url') + 'pipeline/nodeman_is_support_tjj/', type: 'GET', @@ -28,13 +303,13 @@ async: false, success: function (resp) { if (resp.data) { - NODEMAN_TJJ_IS_HIDDEN = false + NODEMAN_TJJ_IS_HIDDEN = false; } }, error: function () { show_msg('request nodeman is support tjj error', 'error'); } - }) + }); $.atoms.nodeman_create_task = [ { tag_code: "bk_biz_id", @@ -63,116 +338,10 @@ if (this.value) { return } - this._set_value($.context.getBkBizId()) + this._set_value($.context.getBkBizId()); } } }, - { - tag_code: "nodeman_ticket", - type: "combine", - attrs: { - name: gettext("ticket信息"), - hookable: true, - hidden: NODEMAN_TJJ_IS_HIDDEN, - children: [{ - tag_code: "nodeman_ticket_save", - type: "radio", - attrs: { - name: gettext("ticket获取方式"), - hookable: true, - hidden: false, - value: 2, - disabled: false, - default: 2, - items: [ - { - name: gettext("获取ticket"), - value: 0 - }, - { - name: gettext("实时获取ticket"), - value: 1 - }, - { - name: gettext("不使用ticket"), - value: 2 - } - ], - }, - }, - { - type: "text", - tag_code: "nodeman_tjj_tip", - attrs: { - name: gettext("说明"), - hookable: true, - hidden: false, - raw: false, - value: gettext("TJJ认证需要获取用户的ticket,请选择ticket获取方式") - }, - events: [ - { - source: "nodeman_ticket_save", - type: "change", - action: function (value) { - if (value === 0) { - this._set_value(gettext("此选项将保存ticket到模板,插件长时间未执行可能发生ticket过期失效导致认证失败")) - } - if (value === 1) { - this._set_value(gettext("此选项将在任务执行前获取ticket,选择此选项需要(ticket使用方式)勾选为全局变量")) - } - if (value === 2) { - this._set_value(gettext("TJJ认证需要获取用户的ticket,请选择ticket获取方式")) - } - } - },] - }, - { - tag_code: "nodeman_tjj_ticket", - type: "password", - attrs: { - name: "TJJ认证ticket", - hookable: true, - hidden: true, - placeholder: "用户ticket", - disabled: true, - validation: [] - }, - events: [ - { - source: "nodeman_ticket_save", - type: "change", - action: function (value) { - if (value === 2) { - this._set_value("") - return - } - let a = /TCOA_TICKET=\S+/ - let cookieStr = document.cookie - let ticket = cookieStr.match(a)[0].split(";")[0].split("=")[1] - this._set_value(ticket) - } - }, - { - source: "nodeman_ticket_save", - type: "init", - action: function (value) { - if (value === 1) { - let a = /TCOA_TICKET=\S+/ - let cookieStr = document.cookie - let ticket = cookieStr.match(a)[0].split(";")[0].split("=")[1] - this._set_value(ticket) - } - if (value === 2) { - this._set_value("") - } - } - } - - ], - }] - }, - }, { tag_code: "nodeman_op_info", type: "combine", @@ -195,6 +364,16 @@ { type: "required" } + ], + events: [ + { + source: "nodeman_node_type", + type: "init", + action: function (value) { + // 统一以 change 事件抛出 + this.emit_event(this.tagCode, "change", this.value); + } + }, ] } }, @@ -208,6 +387,8 @@ {value: "REINSTALL", text: gettext("重新安装")}, {value: "UNINSTALL", text: gettext("卸载")}, {value: "UPGRADE", text: gettext("升级")}, + {value: "RESTART", text: gettext("重启")}, + {value: "RELOAD", text: gettext("配置重载")}, ], default: "INSTALL", validation: [ @@ -218,51 +399,10 @@ }, events: [ { - source: "nodeman_node_type", + source: "nodeman_op_type", type: "init", action: function (value) { - node_type = value - if (value == "AGENT") { - this.items = [ - {value: "INSTALL", text: gettext("安裝")}, - {value: "REINSTALL", text: gettext("重新安装")}, - {value: "UNINSTALL", text: gettext("卸载")}, - {value: "UPGRADE", text: gettext("升级")}, - ] - } else { - if (this.value == "UPGRADE") { - this._set_value("INSTALL") - } - this.items = [ - {value: "INSTALL", text: gettext("安裝")}, - {value: "REINSTALL", text: gettext("重新安装")}, - {value: "UNINSTALL", text: gettext("卸载")}, - ] - } - } - }, - { - source: "nodeman_node_type", - type: "change", - action: function (value) { - node_type = value - if (value == "AGENT") { - this.items = [ - {value: "INSTALL", text: gettext("安裝")}, - {value: "REINSTALL", text: gettext("重新安装")}, - {value: "UNINSTALL", text: gettext("卸载")}, - {value: "UPGRADE", text: gettext("升级")}, - ] - } else { - if (this.value == "UPGRADE") { - this._set_value("INSTALL") - } - this.items = [ - {value: "INSTALL", text: gettext("安裝")}, - {value: "REINSTALL", text: gettext("重新安装")}, - {value: "UNINSTALL", text: gettext("卸载")}, - ] - } + this.emit_event(this.tagCode, "change", this.value); } }, ] @@ -284,20 +424,11 @@ ] }, events: [ - { - source: "nodeman_op_type", - type: "init", - action: function (value) { - let op_type = ["INSTALL", "REINSTALL"] - is_display_tag(this, op_type, value) - } - }, { source: "nodeman_op_type", type: "change", action: function (value) { - let op_type = ["INSTALL", "REINSTALL"] - is_display_tag(this, op_type, value) + is_install_op(this, value); } }, ] @@ -313,7 +444,7 @@ type: "add_row", text: gettext("添加"), callback: function () { - this.add_row() + this.add_row(); } }, { @@ -324,305 +455,29 @@ type: "export", text: gettext("导出"), callback: function () { - this.export2Excel() + this.export2Excel(); } }, ], - columns: [ - { - tag_code: "nodeman_bk_cloud_id", - type: "select", - attrs: { - name: gettext("管控区域ID"), - width: "180px", - remote: true, - items: [], - remote_url: $.context.get("site_url") + "pipeline/nodeman_get_cloud_area/", - remote_data_init: function (resp) { - if (resp.result === false) { - show_msg(resp.message, "error"); - } - resp.data.unshift({"text": gettext("直连区域"), "value": 0}) - return resp.data; - }, - validation: [ - { - type: "required", - } - ] - } - }, - { - tag_code: "nodeman_ap_id", - type: "select", - attrs: { - name: gettext("接入点"), - width: "180px", - remote: true, - items: [], - remote_url: $.context.get("site_url") + "pipeline/nodeman_get_ap_list/", - remote_data_init: function (resp) { - if (resp.result === false) { - show_msg(resp.message, "error"); - } - return resp.data; - }, - validation: [] - } - }, - { - tag_code: "inner_ip", - type: "textarea", - attrs: { - name: gettext("内网IP"), - placeholder: gettext("多个用英文逗号 `,` 或换行分隔"), - width: "180px", - editable: true - } - }, - { - tag_code: "outer_ip", - type: "textarea", - attrs: { - name: gettext("外网IP"), - placeholder: gettext("可选,如填写需与内网ip一一对应,多个用英文逗号 `,` 或换行分隔"), - width: "180px", - editable: true, - validation: [] - } - }, - { - tag_code: "login_ip", - type: "textarea", - attrs: { - name: gettext("登录IP"), - placeholder: gettext("可为空,如填写需与内网ip一一对应,适配复杂网络时填写,多个用英文逗号 `,` 或换行分隔"), - width: "180px", - editable: true - } - }, - { - tag_code: "data_ip", - type: "textarea", - attrs: { - name: gettext("数据IP"), - placeholder: gettext("可为空,如填写需与内网ip一一对应,适配复杂网络时填写,多个用英文逗号 `,` 或换行分隔"), - width: "180px", - editable: true, - } - }, - { - tag_code: "inner_ipv6", - type: "textarea", - attrs: { - name: gettext("内网IP(IPV6)"), - placeholder: gettext("可为空,如纯ipv6主机,内网ipv和外网IP(IPV6)两个必须填一个"), - width: "180px", - editable: true, - } - }, - { - tag_code: "outer_ipv6", - type: "textarea", - attrs: { - name: gettext("外网IP(IPV6)"), - placeholder: gettext("可为空,如纯ipv6主机,外网ipv和外网IP(IPV6)两个必须填一个"), - width: "180px", - editable: true, - } - }, - { - tag_code: "os_type", - type: "select", - attrs: { - name: gettext("操作系统类型"), - width: "180px", - items: [ - {value: "LINUX", text: gettext("LINUX")}, - {value: "WINDOWS", text: gettext("WINDOWS")}, - {value: "AIX", text: gettext("AIX")} - ], - default: "LINUX", - validation: [ - { - type: "required" - } - ] - } - }, - { - tag_code: "account", - type: "input", - attrs: { - name: gettext("登录账号"), - width: "180px", - editable: true, - validation: [ - { - type: "required" - } - ] - } - }, - { - tag_code: "port", - type: "input", - attrs: { - name: gettext("端口号"), - width: "100px", - editable: true, - validation: [ - { - type: "required" - } - ] - } - }, - { - tag_code: "auth_type", - type: "select", - attrs: { - name: gettext("认证方式"), - width: "180px", - items: [ - {value: "PASSWORD", text: gettext("PASSWORD")}, - {value: "KEY", text: gettext("KEY")}, - {value: "TJJ_PASSWORD", text: gettext("TJJ")} - - ], - default: "PASSWORD", - validation: [ - { - type: "required" - } - ] - } - }, - { - tag_code: "auth_key", - type: "textarea", - attrs: { - name: gettext("认证密钥"), - width: "400px", - editable: true, - validation: [ - { - type: "custom", - args: function (value, parent_value) { - let auth_type = parent_value.auth_type - let result = { - result: true, - error_message: "" - } - if (auth_type !== "TJJ_PASSWORD" && !value.length) { - result.result = false; - result.error_message = gettext("请输入认证密钥"); - } - return result - } - } - ], - showPassword: true - }, - events: [] - }, - { - tag_code: "peer_exchange_switch_for_agent", - type: "radio", - attrs: { - name: gettext("BT节点探测"), - items: [ - {value: 1, name: gettext("是")}, - {value: 0, name: gettext("否")} - ], - default: 1, - validation: [ - { - type: "required" - }, - ] - }, - events: [ - { - source: "nodeman_op_type", - type: "init", - action: function (value) { - let op_type = ["INSTALL", "REINSTALL"] - is_display_tag(this, op_type, value) - } - }, - { - source: "nodeman_op_type", - type: "change", - action: function (value) { - let op_type = ["INSTALL", "REINSTALL"] - is_display_tag(this, op_type, value) - } - }, - ] - }, - { - tag_code: "speed_limit", - type: "input", - attrs: { - name: gettext("传输限速 M/s"), - width: "100px", - placeholder: gettext("请输入"), - validation: [ - { - type: "custom", - args: function (value) { - var result = { - result: true, - error_message: "" - } - if (value && !Number(value)) { - result.result = false; - result.error_message = gettext("请输入数字"); - } - return result; - } - } - ] - }, - events: [ - { - source: "nodeman_op_type", - type: "init", - action: function (value) { - let op_type = ["INSTALL", "REINSTALL"] - is_display_tag(this, op_type, value) - } - }, - { - source: "nodeman_op_type", - type: "change", - action: function (value) { - let op_type = ["INSTALL", "REINSTALL"] - is_display_tag(this, op_type, value) - } - }, - ] - }, - ], + columns: [], hookable: true, validation: [ { type: "custom", args: function (value) { - let self = this + let self = this; let result = { result: true, error_message: "" - } + }; let op_type = self.get_parent && self.get_parent().get_child("nodeman_op_type").value; - let install_type = ["INSTALL", "REINSTALL"] + let install_type = ["INSTALL", "REINSTALL"]; if (install_type.indexOf(op_type) !== -1 && value === "") { result.result = false; result.error_message = gettext("请完善主机信息"); } - return result + return result; } } @@ -631,24 +486,27 @@ events: [ { source: "nodeman_op_type", - type: "init", + type: "change", action: function (value) { - let op_type = ["INSTALL", "REINSTALL"] - if (node_type == "AGENT") { - op_type = ["INSTALL", "REINSTALL", "UNINSTALL"] + let node_type = this.get_parent().get_child("nodeman_node_type").value; + init_columns(this, node_type, value); + let op_type = ["INSTALL", "REINSTALL", "RELOAD"]; + if (node_type === "AGENT") { + op_type = ["INSTALL", "REINSTALL", "UNINSTALL", "RELOAD"]; } - is_display_tag(this, op_type, value) + is_display_tag(this, op_type, value); } }, { - source: "nodeman_op_type", + source: "nodeman_node_type", type: "change", action: function (value) { - let op_type = ["INSTALL", "REINSTALL"] - if (node_type == "AGENT") { - op_type = ["INSTALL", "REINSTALL", "UNINSTALL"] + init_columns(this, value, this.get_parent().get_child("nodeman_op_type").value); + let op_type = ["INSTALL", "REINSTALL", "RELOAD"]; + if (value === "AGENT") { + op_type = ["INSTALL", "REINSTALL", "UNINSTALL", "RELOAD"]; } - is_display_tag(this, op_type, value) + is_display_tag(this, op_type, this.get_parent().get_child("nodeman_op_type").value); } }, ] @@ -664,7 +522,7 @@ type: "add_row", text: gettext("添加"), callback: function () { - this.add_row() + this.add_row(); } }, { @@ -675,7 +533,7 @@ type: "export", text: gettext("导出"), callback: function () { - this.export2Excel() + this.export2Excel(); } }, @@ -715,18 +573,18 @@ { type: "custom", args: function (value) { - let self = this + let self = this; let result = { result: true, error_message: "" - } + }; let op_type = self.get_parent && self.get_parent().get_child("nodeman_op_type").value; - let install_type = ["UNINSTALL", "UPGRADE"] + let install_type = ["UNINSTALL", "UPGRADE"]; if (install_type.indexOf(op_type) !== -1 && value === "") { result.result = false; result.error_message = gettext("请完善主机信息"); } - return result + return result; } } @@ -735,24 +593,24 @@ events: [ { source: "nodeman_op_type", - type: "init", + type: "change", action: function (value) { - let op_type = ["UPGRADE"] - if (node_type == "PROXY") { - op_type = ["UPGRADE", "UNINSTALL"] + let op_type = ["UPGRADE", "RESTART"]; + if (this.get_parent().get_child("nodeman_node_type").value === "PROXY") { + op_type = ["UPGRADE", "RESTART", "UNINSTALL"]; } - is_display_tag(this, op_type, value) + is_display_tag(this, op_type, value); } }, { - source: "nodeman_op_type", + source: "nodeman_node_type", type: "change", action: function (value) { - let op_type = ["UPGRADE"] - if (node_type == "PROXY") { - op_type = ["UPGRADE", "UNINSTALL"] + let op_type = ["UPGRADE", "RESTART"]; + if (value === "PROXY") { + op_type = ["UPGRADE", "RESTART", "UNINSTALL"]; } - is_display_tag(this, op_type, value) + is_display_tag(this, op_type, this.get_parent().get_child("nodeman_op_type").value); } }, ] @@ -760,5 +618,5 @@ ], }, }, - ] + ]; })(); diff --git a/pipeline_plugins/tests/components/collections/sites/open/nodeman_test/create_task_test/test_nodeman_v3_create_task.py b/pipeline_plugins/tests/components/collections/sites/open/nodeman_test/create_task_test/test_nodeman_v3_create_task.py index 04e0eee81b..5836b6ad1f 100644 --- a/pipeline_plugins/tests/components/collections/sites/open/nodeman_test/create_task_test/test_nodeman_v3_create_task.py +++ b/pipeline_plugins/tests/components/collections/sites/open/nodeman_test/create_task_test/test_nodeman_v3_create_task.py @@ -13,16 +13,16 @@ from django.test import TestCase from mock import MagicMock - from pipeline.component_framework.test import ( Call, CallAssertion, ComponentTestCase, ComponentTestMixin, ExecuteAssertion, - ScheduleAssertion, Patcher, + ScheduleAssertion, ) + from pipeline_plugins.components.collections.sites.open.nodeman.create_task.v3_0 import NodemanCreateTaskComponent @@ -743,7 +743,6 @@ def __init__( inputs={ "bk_biz_id": "1", "nodeman_node_type": "AGENT", - "nodeman_ticket": {"nodeman_tjj_ticket": "xxxxx"}, "nodeman_op_info": { "nodeman_op_type": "INSTALL", "nodeman_ip_str": "", @@ -798,7 +797,6 @@ def __init__( "data_ip": "1.1.1.1", } ], - "tcoa_ticket": "xxxxx", } ) ], diff --git a/pipeline_plugins/tests/components/collections/sites/open/nodeman_test/create_task_test/test_nodeman_v4_create_task.py b/pipeline_plugins/tests/components/collections/sites/open/nodeman_test/create_task_test/test_nodeman_v4_create_task.py index e5dca2876d..8ff67501a0 100644 --- a/pipeline_plugins/tests/components/collections/sites/open/nodeman_test/create_task_test/test_nodeman_v4_create_task.py +++ b/pipeline_plugins/tests/components/collections/sites/open/nodeman_test/create_task_test/test_nodeman_v4_create_task.py @@ -13,16 +13,16 @@ from django.test import TestCase from mock import MagicMock - from pipeline.component_framework.test import ( Call, CallAssertion, ComponentTestCase, ComponentTestMixin, ExecuteAssertion, - ScheduleAssertion, Patcher, + ScheduleAssertion, ) + from pipeline_plugins.components.collections.sites.open.nodeman.create_task.v4_0 import NodemanCreateTaskComponent @@ -31,6 +31,7 @@ def cases(self): return [ INSTALL_SUCCESS_CASE, REINSTALL_SUCCESS_CASE, + RELOAD_SUCCESS_CASE, INSTALL_FAIL_CASE, OPERATE_SUCCESS_CASE, OPERATE_FAIL_CASE, @@ -241,7 +242,7 @@ def __init__( "auth_type": "PASSWORD", "ap_id": "1", "is_manual": False, # 不手动操作 - "peer_exchange_switch_for_agent": 1, # 不加速 + "peer_exchange_switch_for_agent": 0, # 不加速 "password": "encrypt_auth_key", "outer_ip": "1.1.1.1", "login_ip": "1.1.1.1", @@ -332,7 +333,7 @@ def __init__( "auth_type": "PASSWORD", "ap_id": "1", "is_manual": False, # 不手动操作 - "peer_exchange_switch_for_agent": 1, # 不加速 + "peer_exchange_switch_for_agent": 0, # 不加速 "password": "encrypt_auth_key", "outer_ip": "1.1.1.1", "login_ip": "1.1.1.1", @@ -349,7 +350,7 @@ def __init__( "auth_type": "PASSWORD", "ap_id": "1", "is_manual": False, # 不手动操作 - "peer_exchange_switch_for_agent": 1, # 不加速 + "peer_exchange_switch_for_agent": 0, # 不加速 "password": "encrypt_auth_key", "outer_ip": "4.4.4.4", "login_ip": "6.6.6.6", @@ -366,7 +367,7 @@ def __init__( "auth_type": "PASSWORD", "ap_id": "1", "is_manual": False, # 不手动操作 - "peer_exchange_switch_for_agent": 1, # 不加速 + "peer_exchange_switch_for_agent": 0, # 不加速 "password": "encrypt_auth_key", "outer_ip": "5.5.5.5", "login_ip": "7.7.7.7", @@ -400,6 +401,111 @@ def __init__( ], ) +RELOAD_SUCCESS_CASE = ComponentTestCase( + name="nodeman v4.0 reinstall task success case", + inputs={ + "bk_biz_id": "1", + "nodeman_op_info": { + "nodeman_op_type": "RELOAD", + "nodeman_node_type": "AGENT", + "nodeman_hosts": [ + { + "bk_biz_id": "1", + "nodeman_bk_cloud_id": "1", + "nodeman_ap_id": "1", + "inner_ip": "1.1.1.1", + "os_type": "LINUX", + "peer_exchange_switch_for_agent": 0, + "speed_limit": "100", + }, + { + "bk_biz_id": "1", + "nodeman_bk_cloud_id": "1", + "nodeman_ap_id": "1", + "os_type": "LINUX", + "inner_ip": "2.2.2.2,3.3.3.3", + "peer_exchange_switch_for_agent": 0, + "speed_limit": "100", + }, + ], + }, + }, + parent_data={"executor": "tester"}, + execute_assertion=ExecuteAssertion(success=True, outputs={"job_id": "1"}), + schedule_assertion=ScheduleAssertion( + success=True, + callback_data=None, + schedule_finished=True, + outputs={"fail_num": 0, "job_id": "1", "success_num": 1}, + ), + execute_call_assertion=[ + CallAssertion( + func=INSTALL_OR_OPERATE_SUCCESS_CLIENT.job_install, + calls=[ + Call( + **{ + "job_type": "RELOAD_AGENT", + "hosts": [ + { + "bk_biz_id": "1", + "bk_cloud_id": "1", + "os_type": "LINUX", + "inner_ip": "1.1.1.1", + "ap_id": "1", + "is_manual": False, # 不手动操作 + "bt_speed_limit": 100, + "peer_exchange_switch_for_agent": 0, # 不加速 + "bk_host_id": 1, + }, + { + "bk_biz_id": "1", + "bk_cloud_id": "1", + "os_type": "LINUX", + "inner_ip": "2.2.2.2", + "ap_id": "1", + "is_manual": False, # 不手动操作 + "bt_speed_limit": 100, + "peer_exchange_switch_for_agent": 0, # 不加速 + "bk_host_id": 2, + }, + { + "bk_biz_id": "1", + "bk_cloud_id": "1", + "os_type": "LINUX", + "inner_ip": "3.3.3.3", + "ap_id": "1", + "is_manual": False, # 不手动操作 + "bt_speed_limit": 100, + "peer_exchange_switch_for_agent": 0, # 不加速 + "bk_host_id": 3, + }, + ], + } + ) + ], + ), + ], + schedule_call_assertion=[ + CallAssertion( + func=INSTALL_OR_OPERATE_SUCCESS_CLIENT.job_details, + calls=[Call(**{"job_id": "1"})], + ), + ], + patchers=[ + Patcher(target=GET_CLIENT_BY_USER, return_value=INSTALL_OR_OPERATE_SUCCESS_CLIENT), + Patcher(target=BASE_GET_CLIENT_BY_USER, return_value=INSTALL_OR_OPERATE_SUCCESS_CLIENT), + Patcher( + target=GET_BUSINESS_HOST, + return_value=[ + {"bk_host_innerip": "1.1.1.1", "bk_host_id": 1}, + {"bk_host_innerip": "2.2.2.2", "bk_host_id": 2}, + {"bk_host_innerip": "3.3.3.3", "bk_host_id": 3}, + ], + ), + Patcher(target=ENCRYPT_AUTH_KEY, return_value="encrypt_auth_key"), + ], +) + INSTALL_FAIL_CASE = ComponentTestCase( name="nodeman v4.0 install task failed case", inputs={ @@ -447,7 +553,7 @@ def __init__( "auth_type": "PASSWORD", "ap_id": "1", "is_manual": False, # 不手动操作 - "peer_exchange_switch_for_agent": 1, # 不加速 + "peer_exchange_switch_for_agent": 0, # 不加速 "password": "encrypt_auth_key", "outer_ip": "1.1.1.1", "login_ip": "1.1.1.1", @@ -635,7 +741,7 @@ def __init__( "auth_type": "PASSWORD", "ap_id": "1", "is_manual": False, # 不手动操作 - "peer_exchange_switch_for_agent": 1, # 不加速 + "peer_exchange_switch_for_agent": 0, # 不加速 "password": "encrypt_auth_key", "outer_ip": "3.3.3.3", "login_ip": "5.5.5.5", @@ -652,7 +758,7 @@ def __init__( "auth_type": "PASSWORD", "ap_id": "1", "is_manual": False, # 不手动操作 - "peer_exchange_switch_for_agent": 1, # 不加速 + "peer_exchange_switch_for_agent": 0, # 不加速 "password": "encrypt_auth_key", "outer_ip": "4.4.4.4", "login_ip": "6.6.6.6", @@ -669,7 +775,7 @@ def __init__( "auth_type": "PASSWORD", "ap_id": "1", "is_manual": False, # 不手动操作 - "peer_exchange_switch_for_agent": 1, # 不加速 + "peer_exchange_switch_for_agent": 0, # 不加速 "password": "encrypt_auth_key", "outer_ip": "3.3.3.3", "login_ip": "5.5.5.5", @@ -686,7 +792,7 @@ def __init__( "auth_type": "PASSWORD", "ap_id": "1", "is_manual": False, # 不手动操作 - "peer_exchange_switch_for_agent": 1, # 不加速 + "peer_exchange_switch_for_agent": 0, # 不加速 "password": "encrypt_auth_key", "data_ip": "7.7.7.7", "bk_host_id": 1, @@ -720,7 +826,6 @@ def __init__( inputs={ "bk_biz_id": "1", "nodeman_node_type": "AGENT", - "nodeman_ticket": {"nodeman_tjj_ticket": "xxxxx"}, "nodeman_op_info": { "nodeman_op_type": "INSTALL", "nodeman_node_type": "AGENT", @@ -734,7 +839,7 @@ def __init__( "os_type": "LINUX", "port": "22", "account": "test", - "auth_type": "PASSWORD", + "auth_type": "TJJ_PASSWORD", "auth_key": "123", "outer_ip": "1.1.1.1", "login_ip": "1.1.1.1", @@ -767,17 +872,16 @@ def __init__( "os_type": "LINUX", "port": "22", "account": "test", - "auth_type": "PASSWORD", + "auth_type": "TJJ_PASSWORD", "ap_id": "1", "is_manual": False, # 不手动操作 - "peer_exchange_switch_for_agent": 1, # 不加速 - "password": "encrypt_auth_key", + "peer_exchange_switch_for_agent": 0, # 不加速 + "key": "encrypt_auth_key", "outer_ip": "1.1.1.1", "login_ip": "1.1.1.1", "data_ip": "1.1.1.1", } ], - "tcoa_ticket": "xxxxx", } ) ], @@ -910,7 +1014,7 @@ def __init__( "auth_type": "PASSWORD", "ap_id": "1", "is_manual": False, # 不手动操作 - "peer_exchange_switch_for_agent": 1, # 不加速 + "peer_exchange_switch_for_agent": 0, # 不加速 "password": "encrypt_auth_key", "outer_ip": "1.1.1.1", "login_ip": "1.1.1.1", @@ -926,7 +1030,7 @@ def __init__( "auth_type": "PASSWORD", "ap_id": "2", "is_manual": False, # 不手动操作 - "peer_exchange_switch_for_agent": 1, # 不加速 + "peer_exchange_switch_for_agent": 0, # 不加速 "password": "encrypt_auth_key", "outer_ip": "2.2.2.2", "login_ip": "2.2.2.2",