Пример #1
0
    def execute(self, data, parent_data):
        operator = parent_data.get_one_of_inputs("executor")
        client = get_client_by_user(operator)
        biz_cc_id = parent_data.get_one_of_inputs("biz_cc_id")

        sa_ip_list = data.get_one_of_inputs("cc_ip_list")
        custom_property = data.get_one_of_inputs("cc_custom_property")
        host_rule = data.get_one_of_inputs("cc_hostname_rule")
        custom_rule = data.get_one_of_inputs("cc_custom_rule")

        hostname_rule = []
        if host_rule:
            hostname_rule.extend(host_rule)
        if custom_rule:
            hostname_rule.extend(custom_rule)
        if not hostname_rule:
            data.set_outputs("ex_data", _("请选择至少一种规则"))
            return False

        hostname_rule = sorted(hostname_rule,
                               key=lambda e: str(e.__getitem__("field_order")))

        ip_list = cc_get_ips_info_by_str(username=operator,
                                         biz_cc_id=biz_cc_id,
                                         ip_str=sa_ip_list,
                                         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

        # 规则中包含的自增变量个数
        inc_num = 0
        host_rule_list = []
        set_rule_list = []
        module_rule_list = []
        for rule in hostname_rule:
            if rule["field_rule_code"] == self.FileCode.host_rule and rule[
                    "field_content"] not in host_rule_list:
                host_rule_list.append(rule["field_content"])
            if rule["field_rule_code"] == self.FileCode.set_rule and rule[
                    "field_content"] not in set_rule_list:
                set_rule_list.append(rule["field_content"])
            if rule["field_rule_code"] == self.FileCode.module_rule and rule[
                    "field_content"] not in module_rule_list:
                module_rule_list.append(rule["field_content"])
            if rule["field_rule_code"] == self.FileCode.auto_var_rule:
                inc_num += 1

        # 如果集群规则不为空,拉取集群属性信息
        set_property = {}
        if set_rule_list:
            # 获取所有的集群id和模型id
            set_id_list = []
            for host_data in ip_list["ip_result"]:
                id_list = [_set["bk_set_id"] for _set in host_data["Sets"]]
                set_id_list.extend(id_list)
            set_rule_list.append("bk_set_id")
            # 查询集群的属性值
            set_kwargs = {
                "bk_biz_id": biz_cc_id,
                "bk_ids": list(set(set_id_list)),
                "fields": set_rule_list
            }
            set_result = client.cc.find_set_batch(set_kwargs)
            if not set_result.get("result"):
                error_message = handle_api_error("蓝鲸配置平台(CC)",
                                                 "cc.find_set_batch",
                                                 set_kwargs, set_result)
                data.set_outputs("ex_data", error_message)
                self.logger.error(error_message)
                return False

            for set_data in set_result["data"]:
                set_property[set_data["bk_set_id"]] = set_data

        # 如果模块规则不为空,拉取模块属性信息
        module_property = {}
        if module_rule_list:
            module_id_list = []
            for host_data in ip_list["ip_result"]:
                id_list = [
                    _module["bk_module_id"] for _module in host_data["Modules"]
                ]
                module_id_list.extend(id_list)
            module_rule_list.append("bk_module_id")
            # 查询模块的属性值
            module_kwargs = {
                "bk_biz_id": biz_cc_id,
                "bk_ids": list(set(module_id_list)),
                "fields": module_rule_list
            }
            module_result = client.cc.find_module_batch(module_kwargs)
            if not module_result.get("result"):
                error_message = handle_api_error("蓝鲸配置平台(CC)",
                                                 "cc.find_module_batch",
                                                 module_kwargs, module_result)
                data.set_outputs("ex_data", error_message)
                self.logger.error(error_message)
                return False

            for module_data in module_result["data"]:
                module_property[module_data["bk_module_id"]] = module_data

        # 数据组装,将规则连接起来,并和ip对应
        host_list = []
        # 自增变量
        inc = [-1] * inc_num
        for host in ip_list["ip_result"]:
            custom_property_value = ""
            inc_num_temp = 0
            # 主机属性
            host_kwargs = {"bk_host_id": host["HostID"]}
            host_result = client.cc.get_host_base_info(**host_kwargs)
            if not host_result.get("result"):
                error_message = handle_api_error("蓝鲸配置平台(CC)",
                                                 "cc.get_host_base_info",
                                                 host_kwargs, host_result)
                data.set_outputs("ex_data", error_message)
                self.logger.error(error_message)
                return False
            host_content = {}
            for host_prop in host_result["data"]:
                if host_prop["bk_property_id"] in host_rule_list:
                    host_content[host_prop["bk_property_id"]] = host_prop[
                        "bk_property_value"]

            for rule in hostname_rule:
                if rule["field_rule_code"] == self.FileCode.host_rule and host_content[
                        rule["field_content"]]:
                    custom_property_value += host_content[
                        rule["field_content"]]
                if rule["field_rule_code"] == self.FileCode.set_rule:
                    # 集群属性
                    set_content_list = [
                        set_property[_set["bk_set_id"]]
                        for _set in host["Sets"]
                    ]
                    for set_content in set_content_list:
                        if set_content.get(rule["field_content"]):
                            custom_property_value += set_content[
                                rule["field_content"]]
                if rule["field_rule_code"] == self.FileCode.module_rule:
                    # 模块属性
                    module_content_list = [
                        module_property[_module["bk_module_id"]]
                        for _module in host["Modules"]
                    ]
                    for module_content in module_content_list:
                        if module_content.get(rule["field_content"]):
                            custom_property_value += module_content[
                                rule["field_content"]]
                if rule["field_rule_code"] == self.FileCode.ip_type_rule:
                    custom_property_value += host["InnerIP"].replace(
                        ".", rule["field_content"])
                # 第一个自增变量
                if rule["field_rule_code"] == self.FileCode.auto_var_rule:
                    if inc[inc_num_temp] == -1:
                        inc[inc_num_temp] = int(rule["field_content"])
                    else:
                        inc[inc_num_temp] += 1
                    custom_property_value += str(inc[inc_num_temp])
                    inc_num_temp += 1
                # 自定义字符串
                if rule["field_rule_code"] == self.FileCode.custom_string:
                    custom_property_value += rule["field_content"]
            host_list.append({
                "bk_host_id": host["HostID"],
                "properties": {
                    custom_property: custom_property_value
                }
            })

        kwargs = {"update": host_list}
        result = client.cc.batch_update_host(kwargs)
        if not result["result"]:
            message = cc_handle_api_error("cc.batch_update_host", kwargs,
                                          result)
            self.logger.error(message)
            data.set_outputs("ex_data", message)
            return False

        return True
    def test_cloud_ip_format_with_multi_innerip(self):
        ip_str = "0:1.1.1.1,0:2.2.2.2\n0:3.3.3.3,0:4.4.4.4"
        get_business_host_topo_return = [
            {
                "host": {
                    "bk_host_id": 1,
                    "bk_host_innerip": "1.2.3.4,1.1.1.1",
                    "bk_cloud_id": 0
                },
                "module": [{
                    "bk_module_id": 1,
                    "bk_module_name": "module_1"
                }],
                "set": [{
                    "bk_set_id": 1,
                    "bk_set_name": "set_1"
                }],
            },
            {
                "host": {
                    "bk_host_id": 2,
                    "bk_host_innerip": "",
                    "bk_cloud_id": 0
                },
                "module": [{
                    "bk_module_id": 2,
                    "bk_module_name": "module_2"
                }],
                "set": [{
                    "bk_set_id": 2,
                    "bk_set_name": "set_2"
                }],
            },
            {
                "host": {
                    "bk_host_id": 3,
                    "bk_host_innerip": "3.3.3.3",
                    "bk_cloud_id": 0
                },
                "module": [{
                    "bk_module_id": 3,
                    "bk_module_name": "module_3"
                }],
                "set": [{
                    "bk_set_id": 3,
                    "bk_set_name": "set_3"
                }],
            },
        ]
        cmdb = MagicMock()
        cmdb.get_business_host_topo = MagicMock(
            return_value=get_business_host_topo_return)
        supplier_account_for_business = MagicMock(
            return_value=self.supplier_account)

        with patch(
                "pipeline_plugins.components.utils.sites.open.utils.supplier_account_for_business",
                supplier_account_for_business,
        ):
            with patch(
                    "pipeline_plugins.components.utils.sites.open.utils.cmdb",
                    cmdb):
                result = cc_get_ips_info_by_str(username=self.username,
                                                biz_cc_id=self.biz_cc_id,
                                                ip_str=ip_str)

        supplier_account_for_business.assert_called_once_with(self.biz_cc_id)
        cmdb.get_business_host_topo.assert_called_once_with(
            username=self.username,
            bk_biz_id=self.biz_cc_id,
            supplier_account=self.supplier_account,
            host_fields=["bk_host_innerip", "bk_host_id", "bk_cloud_id"],
            ip_list=["1.1.1.1", "2.2.2.2", "3.3.3.3", "4.4.4.4"],
        )
        self.assertEqual(result["result"], True)
        self.assertEqual(
            result["ip_result"],
            [
                {
                    "InnerIP": "1.1.1.1",
                    "HostID": 1,
                    "Source": 0,
                    "Sets": [{
                        "bk_set_id": 1,
                        "bk_set_name": "set_1"
                    }],
                    "Modules": [{
                        "bk_module_id": 1,
                        "bk_module_name": "module_1"
                    }],
                },
                {
                    "InnerIP": "3.3.3.3",
                    "HostID": 3,
                    "Source": 0,
                    "Sets": [{
                        "bk_set_id": 3,
                        "bk_set_name": "set_3"
                    }],
                    "Modules": [{
                        "bk_module_id": 3,
                        "bk_module_name": "module_3"
                    }],
                },
            ],
        )
        self.assertEqual(result["ip_count"], 2)
        self.assertEqual(set(result["invalid_ip"]), {"2.2.2.2", "4.4.4.4"})
Пример #3
0
    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 get_value(self):
        if "executor" not in self.pipeline_data or "project_id" not in self.pipeline_data:
            return "ERROR: executor and project_id of pipeline is needed"
        var_ip_selector = self.value
        username = self.pipeline_data["executor"]
        project_id = self.pipeline_data["project_id"]
        project = Project.objects.get(id=project_id)
        bk_biz_id = project.bk_biz_id if project.from_cmdb else ""
        bk_supplier_account = supplier_account_for_project(project_id)
        # 筛选集群
        filter_set = var_ip_selector["var_filter_set"]
        # 筛选模块
        filter_service_template = var_ip_selector["var_filter_module"]
        # 输入方式
        produce_method = var_ip_selector["var_ip_method"]

        if produce_method == "custom":
            # 自定义输入ip
            custom_value = var_ip_selector["var_ip_custom_value"]
            ip_filter_result = cc_get_ips_info_by_str(username, bk_biz_id,
                                                      custom_value)
            # 过滤输入的ip
            ip_filter_result_list = ",".join(
                [ip["InnerIP"] for ip in ip_filter_result["ip_result"]])
            logger.info(
                "[SetModuleIpSelector.get_value] ip_filter_result_list: %s" %
                ip_filter_result_list)

            # 根据输入获取空闲机module id
            service_template_list = get_service_template_list(
                username, bk_biz_id, bk_supplier_account)
            # 如果勾选的set中有空闲机池,则会将所有空闲机module id添加进去
            service_template_list.extend(
                get_biz_inner_module_list(
                    var_ip_selector,
                    username,
                    bk_biz_id,
                    bk_supplier_account,
                    produce_method,
                ))

            # 通过集群模块筛选的ip
            module_ids = get_module_id_list(
                bk_biz_id,
                username,
                get_set_list(username, bk_biz_id, bk_supplier_account),
                service_template_list,
                filter_set,
                filter_service_template,
                bk_supplier_account,
            )
            logger.info("[SetModuleIpSelector.get_value] module_ids: %s" %
                        module_ids)

            set_module_filter_ip_list = get_ip_list_by_module_id(
                username, bk_biz_id, bk_supplier_account, module_ids)
            # 获取在集群模块筛选的ip列表中的自定义输入ip
            data = filter_ip(ip_filter_result_list, set_module_filter_ip_list)
        elif produce_method == "select":
            set_input_method = "var_set"
            module_input_method = "var_module"

            data = get_ip_result_by_input_method(
                set_input_method,
                module_input_method,
                var_ip_selector,
                username,
                bk_biz_id,
                bk_supplier_account,
                filter_set,
                filter_service_template,
                produce_method,
                var_module_name=var_ip_selector["var_ip_manual_value"]
                ["var_module_name"],
            )
        elif produce_method == "manual":
            set_input_method = "var_manual_set"
            module_input_method = "var_manual_module"
            data = get_ip_result_by_input_method(
                set_input_method,
                module_input_method,
                var_ip_selector,
                username,
                bk_biz_id,
                bk_supplier_account,
                filter_set,
                filter_service_template,
                produce_method,
                var_module_name=var_ip_selector["var_ip_select_value"]
                ["var_module_name"],
            )

        else:
            # 输入ip方式不存在
            logger.error(
                "[SetModuleIpSelector.get_value] input ip method: {} not exit".
                format(produce_method))
            data = ""
        return data