def get_value(self): if "executor" not in self.pipeline_data or "biz_cc_id" not in self.pipeline_data: return "ERROR: executor and biz_cc_id of pipeline is needed" operator = self.pipeline_data["executor"] bk_biz_id = int(self.pipeline_data["biz_cc_id"]) supplier_account = supplier_account_for_business(bk_biz_id) client = get_client_by_user(operator) # 自定义项目分组和cc 人员分组 staff_group_id_list = [group_id for group_id in self.value if str(group_id).isdigit()] cc_staff_group = list(set(self.value).difference(set(staff_group_id_list))) # 获取项目的自定义人员分组人员 staff_names_list = StaffGroupSet.objects.filter(id__in=staff_group_id_list, is_deleted=False).values_list( "members", flat=True ) staff_names_str = ",".join(staff_names_list) staff_names_list_clear = list(set(staff_names_str.split(","))) staff_names = ",".join(staff_names_list_clear) # 拼接cc分组人员和自定义分组人员 res = get_notify_receivers(client, bk_biz_id, supplier_account, cc_staff_group, staff_names) if res["result"]: return res["data"] else: logger.error("get cc({}) staff_group failed".format(bk_biz_id)) return staff_names
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs('executor') client = get_client_by_user(executor) if parent_data.get_one_of_inputs('language'): setattr(client, 'language', parent_data.get_one_of_inputs('language')) translation.activate(parent_data.get_one_of_inputs('language')) biz_cc_id = data.get_one_of_inputs('biz_cc_id', parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) cc_set_select = cc_format_tree_mode_id( data.get_one_of_inputs('cc_set_select')) for set_id in cc_set_select: cc_kwargs = { "bk_biz_id": biz_cc_id, "bk_supplier_account": supplier_account, "bk_set_id": set_id, "data": { "bk_service_status": data.get_one_of_inputs('cc_set_status') } } cc_result = client.cc.update_set(cc_kwargs) if not cc_result['result']: message = cc_handle_api_error('cc.update_set', cc_kwargs, cc_result) self.logger.error(message) data.set_outputs('ex_data', message) return False return True
def execute(self, data, parent_data): bk_biz_id = parent_data.get_one_of_inputs("biz_cc_id") executor = parent_data.get_one_of_inputs("executor") client = BKMonitorClient(username=executor) combine = data.get_one_of_inputs("bk_alarm_shield_info") scope_type = combine.get("bk_alarm_shield_scope") scope_value = combine.get(SCOPE[scope_type]) target = data.get_one_of_inputs("bk_alarm_shield_target") begin_time = data.get_one_of_inputs("bk_alarm_shield_begin_time") end_time = data.get_one_of_inputs("bk_alarm_shield_end_time") if parent_data.get_one_of_inputs("language"): setattr(client, "language", parent_data.get_one_of_inputs("language")) translation.activate(parent_data.get_one_of_inputs("language")) supplier_account = supplier_account_for_business(bk_biz_id) request_body = self.get_request_body(bk_biz_id, begin_time, end_time, scope_type, scope_value, executor, supplier_account) if "all" not in target: request_body["dimension_config"].update({"metric_id": target}) result_flag = self.send_request(request_body, data, client) return result_flag
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) if parent_data.get_one_of_inputs("language"): setattr(client, "language", parent_data.get_one_of_inputs("language")) translation.activate(parent_data.get_one_of_inputs("language")) biz_cc_id = data.get_one_of_inputs("biz_cc_id", parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) # 查询主机id ip_list = get_ip_by_regex(data.get_one_of_inputs("cc_host_ip")) # 获取主机id列表 host_result = cc_get_host_id_by_innerip(executor, biz_cc_id, ip_list, supplier_account) if not host_result["result"]: data.set_outputs("ex_data", host_result["message"]) return False cc_is_increment = data.get_one_of_inputs("cc_is_increment") cc_module_select_method = data.get_one_of_inputs("cc_module_select_method") if cc_module_select_method == SelectMethod.TOPO.value: cc_module_select = data.get_one_of_inputs("cc_module_select_topo") or [] filtered_modules = [module for module in cc_module_select if module.startswith("module")] cc_module_select = cc_format_tree_mode_id(filtered_modules) elif cc_module_select_method == SelectMethod.TEXT.value: cc_module_select_text = data.get_one_of_inputs("cc_module_select_text") cc_list_select_node_inst_id_return = cc_list_select_node_inst_id( executor, biz_cc_id, supplier_account, BkObjType.MODULE, cc_module_select_text ) if not cc_list_select_node_inst_id_return["result"]: data.set_outputs("ex_data", cc_list_select_node_inst_id_return["message"]) return False cc_module_select = cc_list_select_node_inst_id_return["data"] else: data.set_outputs("ex_data", _("请选择填参方式")) return False cc_kwargs = { "bk_biz_id": biz_cc_id, "bk_supplier_account": supplier_account, "bk_host_id": [int(host_id) for host_id in host_result["data"]], "bk_module_id": cc_module_select, "is_increment": True if cc_is_increment == "true" else False, } cc_result = client.cc.transfer_host_module(cc_kwargs) if cc_result["result"]: return True else: message = cc_handle_api_error("cc.transfer_host_module", cc_kwargs, cc_result) self.logger.error(message) data.set_outputs("ex_data", message) return False
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) bk_biz_id = parent_data.get_one_of_inputs("bk_biz_id") supplier_account = supplier_account_for_business(bk_biz_id) set_list = data.get_one_of_inputs("set_list") cc_set_select = set_list.split(",") set_select_method = data.get_one_of_inputs("set_select_method") set_status = data.get_one_of_inputs("set_status") set_attr_id = data.get_one_of_inputs("set_attr_id") or "bk_set_name" bk_set_ids = [] if set_select_method in ("name", "custom"): for set_name in cc_set_select: cc_search_set_kwargs = { "bk_biz_id": int(bk_biz_id), "fields": ["bk_set_id", set_attr_id], "condition": { set_attr_id: set_name }, } cc_search_set_result = batch_request(client.cc.search_set, cc_search_set_kwargs) if not cc_search_set_result: self.logger.error( "batch_request client.cc.search_set error") data.set_outputs( "ex_data", "batch_request client.cc.search_set error") return False for bk_set in cc_search_set_result: if bk_set[set_attr_id] == set_name: bk_set_ids.append(bk_set["bk_set_id"]) elif set_select_method == "id": bk_set_ids = cc_set_select for set_id in bk_set_ids: cc_kwargs = { "bk_biz_id": bk_biz_id, "bk_supplier_account": supplier_account, "bk_set_id": set_id, "data": { "bk_service_status": set_status }, } cc_result = client.cc.update_set(cc_kwargs) if not cc_result["result"]: message = cc_handle_api_error("cc.update_set", cc_kwargs, cc_result) self.logger.error(message) data.set_outputs("ex_data", message) return False return True
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs('executor') client = get_client_by_user(executor) if parent_data.get_one_of_inputs('language'): translation.activate(parent_data.get_one_of_inputs('language')) biz_cc_id = data.get_one_of_inputs('biz_cc_id', parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) notify_type = data.get_one_of_inputs('bk_notify_type') receiver_info = data.get_one_of_inputs('bk_receiver_info') # 兼容原有数据格式 if receiver_info: receiver_groups = receiver_info.get('bk_receiver_group') more_receiver = receiver_info.get('bk_more_receiver') # 转换为cc3.0字段 receiver_group = [ CC_V2_ROLE_MAP[group] for group in receiver_groups ] else: receiver_group = data.get_one_of_inputs('bk_receiver_group') more_receiver = data.get_one_of_inputs('bk_more_receiver') title = data.get_one_of_inputs('bk_notify_title') content = data.get_one_of_inputs('bk_notify_content') code = '' message = '' res = get_notify_receivers(client, biz_cc_id, supplier_account, receiver_group, more_receiver) result, msg, receivers = res["result"], res["message"], res["data"] if not result: data.set_outputs('ex_data', msg) return False for t in notify_type: kwargs = self._args_gen[t](self, receivers, title, content) result = getattr(client.cmsi, self._send_func[t])(kwargs) if not result['result']: data.set_outputs('ex_data', result['message']) return False code = result['code'] message = result['message'] data.set_outputs('code', code) data.set_outputs('message', message) return True
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) if parent_data.get_one_of_inputs("language"): setattr(client, "language", parent_data.get_one_of_inputs("language")) translation.activate(parent_data.get_one_of_inputs("language")) biz_cc_id = data.get_one_of_inputs("biz_cc_id", parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) cc_set_select_method = data.get_one_of_inputs("cc_set_select_method") if cc_set_select_method == SelectMethod.TOPO.value: cc_set_select = cc_format_tree_mode_id( data.get_one_of_inputs("cc_set_select_topo")) elif cc_set_select_method == SelectMethod.TEXT.value: cc_set_select_text = data.get_one_of_inputs("cc_set_select_text") cc_list_select_node_inst_id_return = cc_list_select_node_inst_id( executor, biz_cc_id, supplier_account, BkObjType.SET, cc_set_select_text) if not cc_list_select_node_inst_id_return["result"]: data.set_outputs("ex_data", cc_list_select_node_inst_id_return["message"]) return False cc_set_select = cc_list_select_node_inst_id_return["data"] else: data.set_outputs("ex_data", _("请选择填参方式")) return True for set_id in cc_set_select: cc_kwargs = { "bk_biz_id": biz_cc_id, "bk_supplier_account": supplier_account, "bk_set_id": set_id, } cc_result = client.cc.transfer_sethost_to_idle_module(cc_kwargs) if not cc_result["result"]: message = cc_handle_api_error( "cc.transfer_sethost_to_idle_module", cc_kwargs, cc_result) self.logger.error(message) data.set_outputs("ex_data", message) return False return True
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) if parent_data.get_one_of_inputs("language"): translation.activate(parent_data.get_one_of_inputs("language")) biz_cc_id = data.get_one_of_inputs("biz_cc_id", parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) notify_type = data.get_one_of_inputs("bk_notify_type") title = data.get_one_of_inputs("bk_notify_title") content = data.get_one_of_inputs("bk_notify_content") receiver_info = data.get_one_of_inputs("bk_receiver_info") receiver_groups = receiver_info.get("bk_receiver_group") staff_groups = receiver_info.get("bk_staff_group") more_receiver = receiver_info.get("bk_more_receiver") notify = data.get_one_of_inputs("notify") # 转换为cc3.0字段 receiver_group = [CC_V2_ROLE_MAP[group] for group in receiver_groups] result = get_notify_receivers(client, biz_cc_id, supplier_account, receiver_group, more_receiver, self.logger) if not result["result"]: data.set_outputs("ex_data", result["message"]) return False # 获取项目的自定义人员分组人员 staff_names = StaffGroupSet.objects.get_members_with_group_ids( staff_groups) if staff_groups else [] usernames = result["data"].split(",") + staff_names # 当通知接收人包含执行人时,执行人放在列表第一位,且对通知名单进行去重处理 if notify or executor in usernames: usernames.insert(0, executor) unique_usernames = sorted(set(usernames), key=usernames.index) base_kwargs = { "receiver__username": "******".join(unique_usernames).strip(","), "title": title, "content": content, } error_flag = False error = "" for msg_type in notify_type: kwargs = {} kwargs.update(**base_kwargs) kwargs.update({"msg_type": msg_type}) # 保留通知内容中的换行和空格 if msg_type == "mail": kwargs["content"] = "<pre>%s</pre>" % kwargs["content"] result = client.cmsi.send_msg(kwargs) if not result["result"]: message = bk_handle_api_error("cmsi.send_msg", kwargs, result) self.logger.error(message) error_flag = True error += "%s;" % message if error_flag: # 这里不需要返回 html 格式到前端,避免导致异常信息展示格式错乱 data.set_outputs("ex_data", error.replace("<", "|").replace(">", "|")) return False return True
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) biz_cc_id = data.get_one_of_inputs("biz_cc_id", parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) cc_set_select_method = data.get_one_of_inputs("cc_set_select_method") cc_set_update_data_list = data.get_one_of_inputs("cc_set_update_data") cc_set_template_break_line = data.get_one_of_inputs( "cc_set_template_break_line") or "," cc_set_update_data = convert_num_to_str(cc_set_update_data_list) attr_list = [] # 如果用户选择了单行扩展 if cc_set_select_method == "auto": for cc_set_item in cc_set_update_data: chunk_result = chunk_table_data(cc_set_item, cc_set_template_break_line) if not chunk_result["result"]: data.set_outputs("ex_data", chunk_result["message"]) return False attr_list.extend(chunk_result["data"]) else: # 非单行扩展的情况无需处理 attr_list = cc_set_update_data success_update = [] failed_update = [] search_attr_kwargs = { "bk_obj_id": "set", "bk_supplier_account": supplier_account } attr_result = client.cc.search_object_attribute(search_attr_kwargs) if not attr_result["result"]: message = handle_api_error("cc", "cc.search_object_attribute", search_attr_kwargs, attr_result) logger.error(message) data.set_outputs("ex_data", message) return False attr_type_mapping = {} for item in attr_result["data"]: attr_type_transformer = None if item["bk_property_type"] == "bool": attr_type_transformer = bool elif item["bk_property_type"] == "int": attr_type_transformer = int if attr_type_transformer: attr_type_mapping[ item["bk_property_id"]] = attr_type_transformer for update_item in attr_list: # 过滤,去除用户没有填的字段 update_params = { key: value for key, value in update_item.items() if value } # 对字段类型进行转换 transform_success = True for attr, value in update_params.items(): if attr in attr_type_mapping: try: update_params[attr] = attr_type_mapping[attr](value) except Exception as e: transform_success = False message = "item: {}, 转换属性{}为{}类型时出错: {}".format( update_item, attr, attr_type_mapping[attr], e) logger.error(message) failed_update.append(message) break if not transform_success: continue if "bk_set_name" not in update_params: message = "item: {}, 目前Set名称未填写".format(update_item) logger.error(message) failed_update.append(message) continue bk_set_name = update_params["bk_set_name"] if "bk_new_set_name" in update_params: update_params["bk_set_name"] = update_params["bk_new_set_name"] del update_params["bk_new_set_name"] # 检查set name是否存在 if not bk_set_name: message = "set 属性更新失败, set name有空值, item={}".format( update_item) failed_update.append(message) self.logger.info(message) continue # 根据set name查询set id kwargs = { "bk_biz_id": biz_cc_id, "fields": ["bk_set_id", "bk_set_name"], "condition": { "bk_set_name": bk_set_name }, } search_result = client.cc.search_set(kwargs) bk_set_id = 0 for search_set in search_result["data"]["info"]: if search_set["bk_set_name"] == bk_set_name: bk_set_id = search_set["bk_set_id"] break # 更新set属性 kwargs = { "bk_biz_id": biz_cc_id, "bk_set_id": bk_set_id, "data": update_params, } update_result = client.cc.update_set(kwargs) if update_result["result"]: self.logger.info("set 属性更新成功, item={}, data={}".format( update_item, kwargs)) success_update.append(update_item) else: message = "set 属性更新失败, item={}, data={}, message: {}".format( update_item, kwargs, update_result["message"]) self.logger.info(message) failed_update.append(message) data.set_outputs("set_update_success", success_update) data.set_outputs("set_update_failed", failed_update) # 如果没有更新失败的行 if not failed_update: return True data.set_outputs("ex_data", failed_update) return False
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) if parent_data.get_one_of_inputs("language"): setattr(client, "language", parent_data.get_one_of_inputs("language")) translation.activate(parent_data.get_one_of_inputs("language")) biz_cc_id = data.get_one_of_inputs("biz_cc_id", parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) cc_set_parent_select = cc_format_tree_mode_id( data.get_one_of_inputs("cc_set_parent_select")) cc_set_info = deepcopy(data.get_one_of_inputs("cc_set_info")) bk_set_env = cc_format_prop_data( executor, "set", "bk_set_env", parent_data.get_one_of_inputs("language"), supplier_account) if not bk_set_env["result"]: data.set_outputs("ex_data", bk_set_env["message"]) return False bk_service_status = cc_format_prop_data( executor, "set", "bk_service_status", parent_data.get_one_of_inputs("language"), supplier_account) if not bk_service_status["result"]: data.set_outputs("ex_data", bk_service_status["message"]) return False set_list = [] for set_params in cc_set_info: chunk_result = chunk_table_data(set_params) if not chunk_result["result"]: data.set_outputs("ex_data", chunk_result["message"]) return False for property_data in chunk_result["data"]: set_property = {} for key, value in property_data.items(): if value: if key == "bk_set_env": value = bk_set_env["data"].get(value) if not value: data.set_outputs("ex_data", _("环境类型校验失败,请重试并修改为正确的环境类型")) return False elif key == "bk_service_status": value = bk_service_status["data"].get(value) if not value: data.set_outputs("ex_data", _("服务状态校验失败,请重试并修改为正确的服务状态")) return False elif key == "bk_capacity": try: value = int(value) except ValueError: self.logger.error(traceback.format_exc()) data.set_outputs("ex_data", _("集群容量必须为整数")) return False set_property[key] = value set_list.append(set_property) for parent_id in cc_set_parent_select: for set_data in set_list: cc_kwargs = { "bk_biz_id": biz_cc_id, "bk_supplier_account": supplier_account, "data": { "bk_parent_id": parent_id }, } cc_kwargs["data"].update(set_data) cc_result = client.cc.create_set(cc_kwargs) if not cc_result["result"]: message = cc_handle_api_error("cc.create_set", cc_kwargs, cc_result) self.logger.error(message) data.set_outputs("ex_data", message) return False return True
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) biz_cc_id = data.get_one_of_inputs("biz_cc_id", parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) cc_module_select_method = data.get_one_of_inputs( "cc_module_select_method") cc_host_transfer_detail = data.get_one_of_inputs( "cc_host_transfer_detail") cc_transfer_host_template_break_line = data.get_one_of_inputs( "cc_transfer_host_template_break_line") or "," is_append = data.get_one_of_inputs("is_append", default=True) cc_host_transfer_detail = convert_num_to_str(cc_host_transfer_detail) attr_list = [] # 对 单行扩展 填参方式 if cc_module_select_method == "auto": for cc_srv_busi_item in cc_host_transfer_detail: chunk_result = chunk_table_data( cc_srv_busi_item, cc_transfer_host_template_break_line) if not chunk_result["result"]: data.set_outputs("ex_data", chunk_result["message"]) return False attr_list.extend(chunk_result["data"]) else: # 非单行扩展的情况无需处理 attr_list = cc_host_transfer_detail success_update = [] failed_update = [] for attr in attr_list: cc_host_ip_list = [attr["cc_transfer_host_ip"]] cc_module_path = attr["cc_transfer_host_target_module"] # 获取主机id列表 host_result = cc_get_host_id_by_innerip(executor, biz_cc_id, cc_host_ip_list, supplier_account) if not host_result["result"]: message = _("无法获取主机id列表,主机属性={}, message={}".format( attr, host_result["message"])) self.logger.info(message) failed_update.append(message) continue # 获取 bk module id cc_list_select_node_inst_id_return = cc_list_select_node_inst_id( executor, biz_cc_id, supplier_account, BkObjType.MODULE, cc_module_path, parent_data.get_one_of_inputs("bk_biz_name"), ) if not cc_list_select_node_inst_id_return["result"]: message = _("无法获取bk module id," "主机属性={}, message={}".format( attr, cc_list_select_node_inst_id_return["message"])) self.logger.info(message) failed_update.append(message) continue cc_module_select = cc_list_select_node_inst_id_return["data"] cc_kwargs = { "bk_biz_id": biz_cc_id, "bk_supplier_account": supplier_account, "bk_host_id": [int(host_id) for host_id in host_result["data"]], "bk_module_id": [int(module_id) for module_id in cc_module_select], "is_increment": is_append, } update_result = client.cc.transfer_host_module(cc_kwargs) if update_result["result"]: self.logger.info("主机所属业务模块更新成功, data={}".format(cc_kwargs)) success_update.append(attr) else: message = _("主机所属业务模块更新失败," "主机属性={}, kwargs={} message={}".format( attr, cc_kwargs, update_result["message"])) self.logger.info(message) failed_update.append(message) data.set_outputs("transfer_host_module_success", success_update) data.set_outputs("transfer_host_module_failed", failed_update) # 如果没有更新失败的行 if not failed_update: return True data.set_outputs("ex_data", failed_update) return False
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) if parent_data.get_one_of_inputs("language"): setattr(client, "language", parent_data.get_one_of_inputs("language")) translation.activate(parent_data.get_one_of_inputs("language")) biz_cc_id = data.get_one_of_inputs("biz_cc_id", parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) cc_hosts = data.get_one_of_inputs("cc_host_replace_detail") copy_attrs = data.get_one_of_inputs("copy_attributes", True) # 查询主机可编辑属性 search_attr_kwargs = { "bk_obj_id": "host", "bk_supplier_account": supplier_account } search_attr_result = client.cc.search_object_attribute( search_attr_kwargs) if not search_attr_result["result"]: message = cc_handle_api_error("cc.search_object_attribute", search_attr_kwargs, search_attr_result) self.logger.error(message) data.outputs.ex_data = message return False editable_attrs = [] for item in search_attr_result["data"]: if item["editable"]: editable_attrs.append(item["bk_property_id"]) # 拉取所有主机信息 fault_replace_ip_map = {} for item in cc_hosts: fault_replace_ip_map["".join(get_ip_by_regex( item["cc_fault_ip"]))] = "".join( get_ip_by_regex(item["cc_new_ip"])) all_hosts = [] all_hosts.extend(list(fault_replace_ip_map.keys())) all_hosts.extend(list(fault_replace_ip_map.values())) host_attrs = editable_attrs + ["bk_host_innerip"] hosts_topo = cmdb.get_business_host_topo(executor, biz_cc_id, supplier_account, host_attrs, all_hosts) if not hosts_topo: data.outputs.ex_data = "fetch host topo for {} failed".format( all_hosts) return False # 只有复制故障机属性时才用到 batch_update_kwargs = { "bk_obj_id": "host", "bk_supplier_account": supplier_account, "update": [] } host_dict = { host_info["host"]["bk_host_innerip"]: host_info["host"] for host_info in hosts_topo } host_id_to_ip = { host_info["host"]["bk_host_id"]: host_info["host"]["bk_host_innerip"] for host_info in hosts_topo } fault_replace_id_map = {} for fault_ip, new_ip in list(fault_replace_ip_map.items()): fault_host = host_dict.get(fault_ip) new_host = host_dict.get(new_ip) if not fault_host: data.outputs.ex_data = _( "无法查询到 %s 机器信息,请确认该机器是否在当前业务下") % fault_ip return False if not new_host: data.outputs.ex_data = _( "无法查询到 %s 机器信息,请确认该机器是否在当前业务下") % new_ip return False if copy_attrs: update_item = { "properties": {}, "bk_host_id": new_host["bk_host_id"] } for attr in [ attr for attr in editable_attrs if attr in fault_host ]: update_item["properties"][attr] = fault_host[attr] batch_update_kwargs["update"].append(update_item) fault_replace_id_map[ fault_host["bk_host_id"]] = new_host["bk_host_id"] # 更新替换机信息 if copy_attrs: update_result = client.cc.batch_update_host(batch_update_kwargs) if not update_result["result"]: message = cc_handle_api_error("cc.batch_update_host", batch_update_kwargs, update_result) self.logger.error(message) data.outputs.ex_data = message return False # 将主机上交至故障机模块 fault_transfer_kwargs = { "bk_supplier_account": supplier_account, "bk_biz_id": biz_cc_id, "bk_host_id": list(fault_replace_id_map.keys()), } fault_transfer_result = client.cc.transfer_host_to_faultmodule( fault_transfer_kwargs) if not fault_transfer_result["result"]: message = cc_handle_api_error("cc.transfer_host_to_faultmodule", fault_transfer_kwargs, fault_transfer_result) self.logger.error(message) data.set_outputs("ex_data", message) return False # 转移主机模块 transfer_kwargs_list = [] for host_info in hosts_topo: new_host_id = fault_replace_id_map.get( host_info["host"]["bk_host_id"]) if new_host_id: transfer_kwargs_list.append({ "bk_biz_id": biz_cc_id, "bk_supplier_account": supplier_account, "bk_host_id": [new_host_id], "bk_module_id": [ module_info["bk_module_id"] for module_info in host_info["module"] ], "is_increment": True, }) success = [] for kwargs in transfer_kwargs_list: transfer_result = client.cc.transfer_host_module(kwargs) if not transfer_result["result"]: message = cc_handle_api_error("cc.transfer_host_module", kwargs, transfer_result) self.logger.error(message) data.outputs.ex_data = "{msg}\n{success}".format( msg=message, success=_("成功替换的机器: %s") % ",".join(success)) return False success.append(host_id_to_ip[kwargs["bk_host_id"][0]])
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs('executor') client = get_client_by_user(executor) if parent_data.get_one_of_inputs('language'): setattr(client, 'language', parent_data.get_one_of_inputs('language')) translation.activate(parent_data.get_one_of_inputs('language')) biz_cc_id = data.get_one_of_inputs('biz_cc_id', parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) cc_set_parent_select = cc_format_tree_mode_id( data.get_one_of_inputs('cc_set_parent_select')) cc_set_info = data.get_one_of_inputs('cc_set_info') bk_set_env = cc_format_prop_data( executor, 'set', 'bk_set_env', parent_data.get_one_of_inputs('language'), supplier_account) if not bk_set_env['result']: data.set_outputs('ex_data', bk_set_env['message']) return False bk_service_status = cc_format_prop_data( executor, 'set', 'bk_service_status', parent_data.get_one_of_inputs('language'), supplier_account) if not bk_service_status['result']: data.set_outputs('ex_data', bk_service_status['message']) return False set_list = [] for set_params in cc_set_info: set_property = {} for key, value in list(set_params.items()): if value: if key == "bk_set_env": value = bk_set_env['data'].get(value) if not value: data.set_outputs('ex_data', _("环境类型校验失败,请重试并修改为正确的环境类型")) return False elif key == "bk_service_status": value = bk_service_status['data'].get(value) if not value: data.set_outputs('ex_data', _("服务状态校验失败,请重试并修改为正确的服务状态")) return False elif key == "bk_capacity": try: value = int(value) except Exception: self.logger.error(traceback.format_exc()) data.set_outputs('ex_data', _("集群容量必须为整数")) return False set_property[key] = value set_list.append(set_property) for parent_id in cc_set_parent_select: for set_data in set_list: cc_kwargs = { 'bk_biz_id': biz_cc_id, 'bk_supplier_account': supplier_account, 'data': { 'bk_parent_id': parent_id } } cc_kwargs['data'].update(set_data) cc_result = client.cc.create_set(cc_kwargs) if not cc_result['result']: message = cc_handle_api_error('cc.create_set', cc_kwargs, cc_result) self.logger.error(message) data.set_outputs('ex_data', message) return False return True
def execute(self, data, parent_data): biz_cc_id = parent_data.get_one_of_inputs("biz_cc_id") executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) supplier_account = supplier_account_for_business(biz_cc_id) language = parent_data.get_one_of_inputs("language") host_update_method = data.get_one_of_inputs("cc_host_update_method") host_property_custom = data.get_one_of_inputs( "cc_host_property_custom") separator = data.get_one_of_inputs("cc_auto_separator") host_property_custom = convert_num_to_str(host_property_custom) if host_update_method == "auto": host_property_data = [] for column in host_property_custom: column_result = chunk_table_data(column, separator) if not column_result["result"]: message = _("单行扩展失败,请检查输入参数格式是否合法, error={}".format( column_result["message"])) data.outputs.ex_data = message self.logger.error(message) return False host_property_data.extend(column_result["data"]) host_property_custom = host_property_data bk_host_innerip_list = [] for host in host_property_custom: bk_host_innerip_list.append(host["bk_host_innerip"]) ip_str = ",".join(bk_host_innerip_list) ip_list = cc_get_ips_info_by_str(username=executor, biz_cc_id=biz_cc_id, ip_str=ip_str, use_cache=False) if not ip_list["result"] or not ip_list["ip_count"]: data.outputs.ex_data = _("无法从配置平台(CMDB)查询到对应 IP,请确认输入的 IP 是否合法") return False if ip_list["invalid_ip"]: data.outputs.ex_data = _("无法从配置平台(CMDB)查询到对应 IP,请确认输入的 IP 是否合法") data.outputs.invalid_ip = ",".join(ip_list["invalid_ip"]) return False ip_dir = {} for host in ip_list["ip_result"]: ip_dir.update({host["InnerIP"]: host["HostID"]}) # do not operate inputs data directly 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 if ":" in inner_host_ip: inner_host_ip = inner_host_ip.split(":")[1] if inner_host_ip not in ip_dir: message = _("innerip【{}】找不到对应的host_id".format(inner_host_ip)) data.outputs.ex_data = message self.logger.error(message) return False host_id = ip_dir[inner_host_ip] host_update = {"bk_host_id": host_id} host_property_dir.pop("bk_host_innerip") properties = {} for cc_host_property, cc_host_prop_value in host_property_dir.items( ): if cc_host_prop_value: is_legal, ex_data = verify_host_property( executor, supplier_account, language, cc_host_property, cc_host_prop_value) if not is_legal: data.outputs.ex_data = ex_data self.logger.error(ex_data) return False properties[cc_host_property] = cc_host_prop_value host_update["properties"] = properties update_host_message.append(host_update) cc_kwargs = { "bk_supplier_account": supplier_account, "update": update_host_message } cc_result = client.cc.batch_update_host(cc_kwargs) if cc_result["result"]: return True else: message = cc_handle_api_error("cc.batch_update_host", cc_kwargs, cc_result) self.logger.error(message) data.set_outputs("ex_data", message) return False
def cc_get_ips_info_by_str(username, biz_cc_id, ip_str, use_cache=True): """ @summary: 从ip_str中匹配出IP信息 @param username @param biz_cc_id @param ip_str @param use_cache(deprecated) @note: 需要兼容的ip_str格式有 1: IP,纯IP格式 2: 集群名称|模块名称|IP,集群名称|模块名称|IP 这种格式可以唯一定位到一 个IP(如果业务把相同IP放到同一模块,还是有问题) 3: 云区域ID:IP,云区域ID:IP 这种格式可以唯一定位到一个IP,主要是兼容Job组件 传参需要和获取Job作业模板步骤参数 @return: {'result': True or False, 'data': [{'InnerIP': ,'HostID': , 'Source': , 'SetID': , 'SetName': , 'ModuleID': , 'ModuleName': , 'Sets': , 'Module': },{}]} """ ip_input_list = get_ip_by_regex(ip_str) supplier_account = supplier_account_for_business(biz_cc_id) ip_list = cmdb.get_business_host_topo( username=username, bk_biz_id=biz_cc_id, supplier_account=supplier_account, host_fields=["bk_host_innerip", "bk_host_id", "bk_cloud_id"], ip_list=ip_input_list, ) ip_result = [] # 如果是格式2 集群名称|模块名称|IP,暂时不支持这种格式bk_host_innerip有多个值的情况 if set_module_ip_reg.match(ip_str): set_module_ip_list = [] for match in set_module_ip_reg.finditer(ip_str): set_module_ip_list.append(match.group()) for ip_info in ip_list: match = False for parent_set in ip_info["set"]: if match: break for parent_module in ip_info["module"]: if match: break topo_ip = "{set}|{module}|{ip}".format( set=parent_set["bk_set_name"], module=parent_module["bk_module_name"], ip=ip_info["host"].get("bk_host_innerip", ""), ) if topo_ip in set_module_ip_list: match = True ip_result.append({ "InnerIP": ip_info["host"].get("bk_host_innerip", ""), "HostID": ip_info["host"]["bk_host_id"], "Source": ip_info["host"].get("bk_cloud_id", -1), "SetID": parent_set["bk_set_id"], "SetName": parent_set["bk_set_name"], "ModuleID": parent_module["bk_module_id"], "ModuleName": parent_module["bk_module_name"], "Sets": ip_info["set"], "Modules": ip_info["module"], }) # 格式3 云区域ID:IP elif plat_ip_reg.match(ip_str): plat_ip = [] for match in plat_ip_reg.finditer(ip_str): plat_ip.append(match.group()) for ip_info in ip_list: valid_hosts = [ x for x in ip_info["host"].get("bk_host_innerip", "").split(",") if x and f'{ip_info["host"].get("bk_cloud_id", -1)}:{x}' in plat_ip ] if valid_hosts: ip_result.append({ "InnerIP": valid_hosts[0], # 即使多个host命中,也都是同一个主机id,这里以第一个合法host为标识 "HostID": ip_info["host"]["bk_host_id"], "Source": ip_info["host"].get("bk_cloud_id", -1), "Sets": ip_info["set"], "Modules": ip_info["module"], }) # 格式1 纯IP格式 else: ip = [] for match in ip_pattern.finditer(ip_str): ip.append(match.group()) proccessed = set() for ip_info in ip_list: valid_hosts = [ x for x in ip_info["host"].get("bk_host_innerip", "").split(",") if x and x in ip ] if valid_hosts and ip_info["host"]["bk_host_id"] not in proccessed: ip_result.append({ "InnerIP": valid_hosts[0], # 即使多个host命中,也都是同一个主机id,这里以第一个合法host为标识 "HostID": ip_info["host"]["bk_host_id"], "Source": ip_info["host"].get("bk_cloud_id", -1), "Sets": ip_info["set"], "Modules": ip_info["module"], }) proccessed.add(ip_info["host"]["bk_host_id"]) valid_ip = [ip_info["InnerIP"] for ip_info in ip_result] invalid_ip = list(set(ip_input_list) - set(valid_ip)) result = { "result": True, "ip_result": ip_result, "ip_count": len(ip_result), "invalid_ip": invalid_ip, } return result
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) if parent_data.get_one_of_inputs("language"): setattr(client, "language", parent_data.get_one_of_inputs("language")) translation.activate(parent_data.get_one_of_inputs("language")) biz_cc_id = data.get_one_of_inputs("biz_cc_id", parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) cc_select_set_parent_method = data.get_one_of_inputs( "cc_select_set_parent_method") if cc_select_set_parent_method == SelectMethod.TOPO.value: # topo类型直接通过cc_format_tree_mode_id解析父节点bz_inst_id cc_set_parent_select = cc_format_tree_mode_id( data.get_one_of_inputs("cc_set_parent_select_topo")) elif cc_select_set_parent_method == SelectMethod.TEXT.value: cc_set_parent_select_text = data.get_one_of_inputs( "cc_set_parent_select_text") cc_list_select_node_inst_id_return = cc_list_select_node_inst_id( executor, biz_cc_id, supplier_account, BkObjType.LAST_CUSTOM, cc_set_parent_select_text) if not cc_list_select_node_inst_id_return["result"]: data.set_outputs("ex_data", cc_list_select_node_inst_id_return["message"]) return False cc_set_parent_select = cc_list_select_node_inst_id_return["data"] else: data.set_outputs("ex_data", _("请选择填参方式")) return False cc_set_names = data.get_one_of_inputs("cc_set_name") cc_set_template = data.get_one_of_inputs("cc_set_template") result = {"fail": [], "success": []} for parent_id in cc_set_parent_select: cc_kwargs = { "bk_biz_id": biz_cc_id, "bk_supplier_account": supplier_account, "data": { "bk_parent_id": parent_id }, } for cc_set_name in cc_set_names.split(","): try: attr_data_list = data.get_one_of_inputs("cc_set_attr") except Exception: attr_data_list = [] cc_kwargs["data"].update({ "bk_parent_id": parent_id, "bk_set_name": cc_set_name, "set_template_id": cc_set_template }) if attr_data_list: for attr_data in attr_data_list: cc_kwargs["data"].update( {attr_data["attr_id"]: attr_data["attr_value"]}) cc_result = client.cc.create_set(cc_kwargs) if not cc_result["result"]: message = cc_handle_api_error("cc.create_set", cc_kwargs, cc_result) self.logger.error(message) result["fail"].append(message) else: result["success"].append(cc_result["data"]) if result["fail"]: data.set_outputs("ex_data", result["fail"]) return False return True
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) if parent_data.get_one_of_inputs("language"): setattr(client, "language", parent_data.get_one_of_inputs("language")) translation.activate(parent_data.get_one_of_inputs("language")) biz_cc_id = data.get_one_of_inputs("biz_cc_id", parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) cc_set_select_method = data.get_one_of_inputs("cc_set_select_method") if cc_set_select_method == SelectMethod.TOPO.value: cc_set_select = cc_format_tree_mode_id(data.get_one_of_inputs("cc_set_select_topo")) elif cc_set_select_method == SelectMethod.TEXT.value: cc_set_select_text = data.get_one_of_inputs("cc_set_select_text") cc_list_select_node_inst_id_return = cc_list_select_node_inst_id( executor, biz_cc_id, supplier_account, BkObjType.SET, cc_set_select_text ) if not cc_list_select_node_inst_id_return["result"]: data.set_outputs("ex_data", cc_list_select_node_inst_id_return["message"]) return False cc_set_select = cc_list_select_node_inst_id_return["data"] else: data.set_outputs("ex_data", _("请选择填参方式")) return False cc_set_property = data.get_one_of_inputs("cc_set_property") if cc_set_property == "bk_service_status": bk_service_status = cc_format_prop_data( executor, "set", "bk_service_status", parent_data.get_one_of_inputs("language"), supplier_account ) if not bk_service_status["result"]: data.set_outputs("ex_data", bk_service_status["message"]) return False cc_set_prop_value = bk_service_status["data"].get(data.get_one_of_inputs("cc_set_prop_value")) if not cc_set_prop_value: data.set_outputs("ex_data", _("服务状态校验失败,请重试并修改为正确的服务状态")) return False elif cc_set_property == "bk_set_env": bk_set_env = cc_format_prop_data( executor, "set", "bk_set_env", parent_data.get_one_of_inputs("language"), supplier_account ) if not bk_set_env["result"]: data.set_outputs("ex_data", bk_set_env["message"]) return False cc_set_prop_value = bk_set_env["data"].get(data.get_one_of_inputs("cc_set_prop_value")) if not cc_set_prop_value: data.set_outputs("ex_data", _("环境类型校验失败,请重试并修改为正确的环境类型")) return False elif cc_set_property == "bk_capacity": try: cc_set_prop_value = int(data.get_one_of_inputs("cc_set_prop_value")) except Exception: self.logger.error(traceback.format_exc()) data.set_outputs("ex_data", _("集群容量必须为整数")) return False else: cc_set_prop_value = data.get_one_of_inputs("cc_set_prop_value") for set_id in cc_set_select: cc_kwargs = { "bk_biz_id": biz_cc_id, "bk_supplier_account": supplier_account, "bk_set_id": set_id, "data": {cc_set_property: cc_set_prop_value}, } cc_result = client.cc.update_set(cc_kwargs) if not cc_result["result"]: message = cc_handle_api_error("cc.update_set", cc_kwargs, cc_result) self.logger.error(message) data.set_outputs("ex_data", message) return False return True
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) if parent_data.get_one_of_inputs("language"): setattr(client, "language", parent_data.get_one_of_inputs("language")) translation.activate(parent_data.get_one_of_inputs("language")) biz_cc_id = data.get_one_of_inputs("biz_cc_id", parent_data.inputs.biz_cc_id) cc_module_select_method = data.get_one_of_inputs( "cc_module_select_method") supplier_account = supplier_account_for_business(biz_cc_id) kwargs = { "bk_biz_id": biz_cc_id, "bk_supplier_account": supplier_account } tree_data = client.cc.search_biz_inst_topo(kwargs) if not tree_data["result"]: message = cc_handle_api_error("cc.search_biz_inst_topo", kwargs, tree_data) self.logger.error(message) data.set_outputs("ex_data", message) return False if cc_module_select_method == SelectMethod.TOPO.value: module_list = data.get_one_of_inputs("cc_module_select_topo") # 过滤掉set的情况 module_list = list( filter(lambda x: x.startswith("module"), module_list)) cc_module_select = cc_format_tree_mode_id(module_list) elif cc_module_select_method == SelectMethod.TEXT.value: cc_module_select_text = data.get_one_of_inputs( "cc_module_select_text") cc_list_select_node_inst_id_return = cc_list_select_node_inst_id( executor, biz_cc_id, supplier_account, BkObjType.MODULE, cc_module_select_text) if not cc_list_select_node_inst_id_return["result"]: data.set_outputs("ex_data", cc_list_select_node_inst_id_return["message"]) return False cc_module_select = cc_list_select_node_inst_id_return["data"] else: data.set_outputs("ex_data", _("请选择模块填参方式")) return False cc_module_property = data.get_one_of_inputs("cc_module_property") if cc_module_property == "bk_module_type": bk_module_type = cc_format_prop_data( executor, "module", "bk_module_type", parent_data.get_one_of_inputs("language"), supplier_account) if not bk_module_type["result"]: data.set_outputs("ex_data", bk_module_type["message"]) return False cc_module_prop_value = bk_module_type["data"].get( data.get_one_of_inputs("cc_module_prop_value")) if not cc_module_prop_value: data.set_outputs("ex_data", _("模块类型校验失败,请重试并填写正确的模块类型")) return False else: cc_module_prop_value = data.get_one_of_inputs( "cc_module_prop_value") for module_id in cc_module_select: cc_kwargs = { "bk_biz_id": biz_cc_id, "bk_supplier_account": supplier_account, "bk_set_id": get_module_set_id(tree_data["data"], module_id), "bk_module_id": module_id, "data": { cc_module_property: cc_module_prop_value }, } cc_result = client.cc.update_module(cc_kwargs) if not cc_result["result"]: message = cc_handle_api_error("cc.update_module", cc_kwargs, cc_result) self.logger.error(message) data.set_outputs("ex_data", message) return False return True
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs('executor') client = get_client_by_user(executor) if parent_data.get_one_of_inputs('language'): setattr(client, 'language', parent_data.get_one_of_inputs('language')) translation.activate(parent_data.get_one_of_inputs('language')) biz_cc_id = data.get_one_of_inputs('biz_cc_id', parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) cc_set_select = cc_format_tree_mode_id( data.get_one_of_inputs('cc_set_select')) cc_set_property = data.get_one_of_inputs('cc_set_property') if cc_set_property == "bk_service_status": bk_service_status = cc_format_prop_data( executor, 'set', 'bk_service_status', parent_data.get_one_of_inputs('language'), supplier_account) if not bk_service_status['result']: data.set_outputs('ex_data', bk_service_status['message']) return False cc_set_prop_value = bk_service_status['data'].get( data.get_one_of_inputs('cc_set_prop_value')) if not cc_set_prop_value: data.set_outputs('ex_data', _("服务状态校验失败,请重试并修改为正确的服务状态")) return False elif cc_set_property == "bk_set_env": bk_set_env = cc_format_prop_data( executor, 'set', 'bk_set_env', parent_data.get_one_of_inputs('language'), supplier_account) if not bk_set_env['result']: data.set_outputs('ex_data', bk_set_env['message']) return False cc_set_prop_value = bk_set_env['data'].get( data.get_one_of_inputs('cc_set_prop_value')) if not cc_set_prop_value: data.set_outputs('ex_data', _("环境类型校验失败,请重试并修改为正确的环境类型")) return False elif cc_set_property == "bk_capacity": try: cc_set_prop_value = int( data.get_one_of_inputs('cc_set_prop_value')) except Exception: self.logger.error(traceback.format_exc()) data.set_outputs('ex_data', _("集群容量必须为整数")) return False else: cc_set_prop_value = data.get_one_of_inputs('cc_set_prop_value') for set_id in cc_set_select: cc_kwargs = { "bk_biz_id": biz_cc_id, "bk_supplier_account": supplier_account, "bk_set_id": set_id, "data": { cc_set_property: cc_set_prop_value } } cc_result = client.cc.update_set(cc_kwargs) if not cc_result['result']: message = cc_handle_api_error('cc.update_set', cc_kwargs, cc_result) self.logger.error(message) data.set_outputs('ex_data', message) return False return True
def execute(self, data, parent_data): executor = parent_data.get_one_of_inputs("executor") client = get_client_by_user(executor) if parent_data.get_one_of_inputs("language"): setattr(client, "language", parent_data.get_one_of_inputs("language")) translation.activate(parent_data.get_one_of_inputs("language")) biz_cc_id = data.get_one_of_inputs("biz_cc_id", parent_data.inputs.biz_cc_id) supplier_account = supplier_account_for_business(biz_cc_id) cc_set_select_method = data.get_one_of_inputs("cc_set_select_method") cc_create_method = data.get_one_of_inputs("cc_create_method") # 校验创建及填参方式,避免中途校验失败时已进行多余的逻辑判断 if cc_set_select_method not in [SelectMethod.TOPO.value, SelectMethod.TEXT.value]: data.set_outputs("ex_data", _("请选择填参方式")) return False if cc_create_method not in [ModuleCreateMethod.CATEGORY.value, ModuleCreateMethod.TEMPLATE.value]: data.set_outputs("ex_data", _("请选择创建方式")) return False if cc_set_select_method == SelectMethod.TOPO.value: cc_set_select = cc_format_tree_mode_id(data.get_one_of_inputs("cc_set_select_topo")) else: cc_set_select_text = data.get_one_of_inputs("cc_set_select_text") cc_list_select_node_inst_id_return = cc_list_select_node_inst_id( executor, biz_cc_id, supplier_account, BkObjType.SET, cc_set_select_text ) if not cc_list_select_node_inst_id_return["result"]: data.set_outputs("ex_data", cc_list_select_node_inst_id_return["message"]) return False cc_set_select = cc_list_select_node_inst_id_return["data"] # 对象深拷贝保证inputs对象执行前后不变 if cc_create_method == ModuleCreateMethod.TEMPLATE.value: cc_module_infos_untreated = copy.deepcopy(data.get_one_of_inputs("cc_module_infos_template")) else: cc_module_infos_untreated = copy.deepcopy(data.get_one_of_inputs("cc_module_infos_category")) if not cc_module_infos_untreated: data.set_outputs("ex_data", _("模块信息不能为空")) return False cc_module_infos = [] for cc_module_info_untreated in cc_module_infos_untreated: if cc_create_method == ModuleCreateMethod.TEMPLATE.value: service_template_name, service_template_id = cc_get_name_id_from_combine_value( cc_module_info_untreated.pop("cc_service_template") ) if service_template_id is None: data.set_outputs("ex_data", _("请选择正确的服务模板")) return False cc_module_info_untreated["service_template_id"] = service_template_id # 按模板创建时,模块名称与模板名称保持一致 cc_module_info_untreated["bk_module_name"] = service_template_name else: if len(cc_module_info_untreated["cc_service_category"]) != 2: data.set_outputs("ex_data", _("请选择正确的服务类型")) return False service_category_id = cc_module_info_untreated.pop("cc_service_category")[-1] cc_module_info_untreated["service_category_id"] = service_category_id # 过滤空值 cc_module_info = { module_property: module_prop_value for module_property, module_prop_value in cc_module_info_untreated.items() if module_prop_value } if cc_create_method == ModuleCreateMethod.CATEGORY.value and "bk_module_name" not in cc_module_info: data.set_outputs("ex_data", _("模块名称不能为空")) return False # 校验模块类型 if "bk_module_type" in cc_module_info: format_prop_data_return = cc_format_prop_data( executor, "module", "bk_module_type", parent_data.get_one_of_inputs("language"), supplier_account ) if not format_prop_data_return["result"]: data.set_outputs("ex_data", format_prop_data_return["message"]) return False bk_module_type = format_prop_data_return["data"].get(cc_module_info["bk_module_type"]) if not bk_module_type: data.set_outputs("ex_data", _("模块类型校验失败,请重试并填写正确的模块类型")) return False cc_module_info["bk_module_type"] = bk_module_type cc_module_infos.append(cc_module_info) for parent_id in cc_set_select: for cc_module_info in cc_module_infos: cc_kwargs = { "bk_biz_id": biz_cc_id, "bk_set_id": parent_id, "data": {"bk_parent_id": parent_id}, } cc_kwargs["data"].update(cc_module_info) cc_create_module_return = client.cc.create_module(cc_kwargs) if not cc_create_module_return["result"]: message = cc_handle_api_error("cc.create_module", cc_kwargs, cc_create_module_return) self.logger.error(message) data.set_outputs("ex_data", message) return False return True