Skip to content

Commit edb154a

Browse files
authored
feat: 配置平台(CMDB) 相关插件支持 云区域:IP #7432 (#7454)
* feat: 配置平台(CMDB) 相关插件支持 云区域:IP #7432 * feat: 配置平台(CMDB) 相关插件支持 云区域:IP #7432 * feat: 配置平台(CMDB) 相关插件支持 云区域:IP #7432 * feat: 配置平台(CMDB) 相关插件支持 云区域:IP #7432 * feat: 配置平台(CMDB) 相关插件支持 云区域:IP #7432 * feat: 配置平台(CMDB) 相关插件支持 云区域:IP #7432 * feat: 配置平台(CMDB) 相关插件支持 云区域:IP #7432 * feat: 配置平台(CMDB) 相关插件支持 云区域:IP #7432 * feat: 配置平台(CMDB) 相关插件支持 云区域:IP #7432 * feat: 配置平台(CMDB) 相关插件支持 云区域:IP #7432
1 parent f567045 commit edb154a

File tree

7 files changed

+237
-27
lines changed

7 files changed

+237
-27
lines changed

gcloud/utils/cmdb.py

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

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

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

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

140140

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

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

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

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

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

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

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

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

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

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

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

8176
# 查询主机id
82-
ip_list = data.get_one_of_inputs("cc_host_ip")
83-
host_result = self.get_host_list(executor, biz_cc_id, ip_list, supplier_account)
77+
ip_str = data.get_one_of_inputs("cc_host_ip")
78+
host_result = self.get_host_list_with_cloud_id(executor, biz_cc_id, ip_str, supplier_account)
8479
if not host_result["result"]:
8580
data.set_outputs("ex_data", host_result["message"])
8681
return False
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
4+
Edition) available.
5+
Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
6+
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
http://opensource.org/licenses/MIT
9+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10+
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
specific language governing permissions and limitations under the License.
12+
"""
13+
14+
from django.test import TestCase
15+
from mock import MagicMock, patch
16+
17+
from pipeline_plugins.components.collections.sites.open.cc.base import cc_get_host_id_by_innerip_and_cloudid
18+
19+
20+
class CCGetHostIdByCloudIdInnerIpTestCase(TestCase):
21+
def setUp(self):
22+
self.executor = "executor_token"
23+
self.bk_biz_id = "bk_biz_id_token"
24+
self.supplier_account = "supplier_account_token"
25+
self.ip_str = "1.1.1.1"
26+
27+
def test__get_business_host_return_empty(self):
28+
mock_cmdb = MagicMock()
29+
mock_cmdb.get_business_host = MagicMock(return_value=[])
30+
with patch("pipeline_plugins.components.collections.sites.open.cc.base.cmdb", mock_cmdb):
31+
data = cc_get_host_id_by_innerip_and_cloudid(
32+
self.executor, self.bk_biz_id, self.ip_str, self.supplier_account
33+
)
34+
35+
mock_cmdb.get_business_host.assert_called_once_with(
36+
self.executor, self.bk_biz_id, self.supplier_account, ["bk_host_id", "bk_host_innerip"], [self.ip_str], None
37+
)
38+
self.assertFalse(data["result"])
39+
self.assertEqual(
40+
data["message"], "IP ['1.1.1.1'] 在本业务下不存在: 请检查配置, 修复后重新执行 | cc_get_host_id_by_innerip_and_cloudid"
41+
)
42+
43+
def test__return_host_list_gt_ip_list(self):
44+
mock_cmdb = MagicMock()
45+
mock_cmdb.get_business_host = MagicMock(
46+
return_value=[
47+
{"bk_host_innerip": "1.1.1.1"},
48+
{"bk_host_innerip": "1.1.1.1"},
49+
]
50+
)
51+
with patch("pipeline_plugins.components.collections.sites.open.cc.base.cmdb", mock_cmdb):
52+
data = cc_get_host_id_by_innerip_and_cloudid(
53+
self.executor, self.bk_biz_id, self.ip_str, self.supplier_account
54+
)
55+
56+
mock_cmdb.get_business_host.assert_called_once_with(
57+
self.executor, self.bk_biz_id, self.supplier_account, ["bk_host_id", "bk_host_innerip"], [self.ip_str], None
58+
)
59+
self.assertFalse(data["result"])
60+
self.assertEqual(
61+
data["message"], "IP [1.1.1.1] 在本业务下重复: 请检查配置, 修复后重新执行 | cc_get_host_id_by_innerip_and_cloudid"
62+
)
63+
64+
def test__return_host_list_lt_cloudid_with_ip_list(self):
65+
self.ip_str = "0:1.1.1.1"
66+
mock_cmdb = MagicMock()
67+
mock_cmdb.get_business_host = MagicMock(return_value=[])
68+
with patch("pipeline_plugins.components.collections.sites.open.cc.base.cmdb", mock_cmdb):
69+
data = cc_get_host_id_by_innerip_and_cloudid(
70+
self.executor, self.bk_biz_id, self.ip_str, self.supplier_account
71+
)
72+
73+
mock_cmdb.get_business_host.assert_called_once_with(
74+
self.executor,
75+
self.bk_biz_id,
76+
self.supplier_account,
77+
["bk_host_id", "bk_host_innerip", "bk_cloud_id"],
78+
[self.ip_str.split(":")[1]],
79+
0,
80+
)
81+
self.assertFalse(data["result"])
82+
self.assertEqual(
83+
data["message"], "IP ['1.1.1.1'] 在本业务下不存在: 请检查配置, 修复后重新执行 | cc_get_host_id_by_innerip_and_cloudid"
84+
)
85+
86+
def test__ip_normal(self):
87+
mock_cmdb = MagicMock()
88+
mock_cmdb.get_business_host = MagicMock(
89+
return_value=[
90+
{"bk_host_innerip": "1.1.1.1", "bk_host_id": 1},
91+
]
92+
)
93+
with patch("pipeline_plugins.components.collections.sites.open.cc.base.cmdb", mock_cmdb):
94+
data = cc_get_host_id_by_innerip_and_cloudid(
95+
self.executor, self.bk_biz_id, self.ip_str, self.supplier_account
96+
)
97+
98+
mock_cmdb.get_business_host.assert_called_once_with(
99+
self.executor, self.bk_biz_id, self.supplier_account, ["bk_host_id", "bk_host_innerip"], [self.ip_str], None
100+
)
101+
self.assertTrue(data["result"])
102+
self.assertEqual(data["data"], ["1"])
103+
104+
def test__cloudid_with_ip_normal(self):
105+
self.ip_str = "0:1.1.1.1"
106+
mock_cmdb = MagicMock()
107+
mock_cmdb.get_business_host = MagicMock(
108+
return_value=[
109+
{"bk_host_innerip": "1.1.1.1", "bk_host_id": 1, "bk_cloud_id": 0},
110+
]
111+
)
112+
with patch("pipeline_plugins.components.collections.sites.open.cc.base.cmdb", mock_cmdb):
113+
data = cc_get_host_id_by_innerip_and_cloudid(
114+
self.executor, self.bk_biz_id, self.ip_str, self.supplier_account
115+
)
116+
117+
mock_cmdb.get_business_host.assert_called_once_with(
118+
self.executor,
119+
self.bk_biz_id,
120+
self.supplier_account,
121+
["bk_host_id", "bk_host_innerip", "bk_cloud_id"],
122+
[self.ip_str.split(":")[1]],
123+
0,
124+
)
125+
self.assertTrue(data["result"])
126+
self.assertEqual(data["data"], ["1"])

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

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

14-
from mock import MagicMock, patch
15-
1614
from django.test import TestCase
15+
from mock import MagicMock, patch
1716

1817
from pipeline_plugins.components.collections.sites.open.cc.base import cc_get_host_id_by_innerip
1918

pipeline_plugins/tests/components/collections/sites/open/cc_test/batch_update_host/test_v1_0.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
"""
1313
from django.test import TestCase
1414
from mock import MagicMock
15-
1615
from pipeline.component_framework.test import (
17-
ComponentTestMixin,
18-
ComponentTestCase,
16+
Call,
1917
CallAssertion,
18+
ComponentTestCase,
19+
ComponentTestMixin,
2020
ExecuteAssertion,
21-
Call,
2221
Patcher,
2322
)
23+
2424
from pipeline_plugins.components.collections.sites.open.cc.batch_update_host.v1_0 import CCBatchUpdateHostComponent
2525

2626

@@ -47,7 +47,9 @@ def __init__(self, batch_update_host_return=None):
4747
)
4848

4949
GET_CLIENT_BY_USER = "pipeline_plugins.components.collections.sites.open.cc.batch_update_host.v1_0.get_client_by_user"
50-
CC_GET_IPS_INFO_BY_STR = "pipeline_plugins.components.collections.sites.open.cc.base.cc_get_host_id_by_innerip"
50+
CC_GET_IPS_INFO_BY_STR = (
51+
"pipeline_plugins.components.collections.sites.open.cc.base.cc_get_host_id_by_innerip_and_cloudid"
52+
)
5153
VERIFY_HOST_PROPERTY = (
5254
"pipeline_plugins.components.collections.sites.open.cc.batch_update_host.v1_0.verify_host_property"
5355
)
@@ -126,7 +128,10 @@ def verify_host_property_fail(executor, supplier_account, language, cc_host_prop
126128
execute_assertion=ExecuteAssertion(success=True, outputs={}),
127129
schedule_assertion=None,
128130
execute_call_assertion=[
129-
CallAssertion(func=CC_GET_IPS_INFO_BY_STR, calls=[Call("executor", 1, ["1.1.1.1"], 0)],),
131+
CallAssertion(
132+
func=CC_GET_IPS_INFO_BY_STR,
133+
calls=[Call("executor", 1, "1.1.1.1", 0)],
134+
),
130135
CallAssertion(
131136
func=BATCH_UPDATE_HOST_SUCCESS_CLIENT.cc.batch_update_host,
132137
calls=[
@@ -168,7 +173,10 @@ def verify_host_property_fail(executor, supplier_account, language, cc_host_prop
168173
),
169174
schedule_assertion=None,
170175
execute_call_assertion=[
171-
CallAssertion(func=CC_GET_IPS_INFO_BY_STR, calls=[Call("executor", 1, ["1.1.1.1"], 0)],),
176+
CallAssertion(
177+
func=CC_GET_IPS_INFO_BY_STR,
178+
calls=[Call("executor", 1, "1.1.1.1", 0)],
179+
),
172180
CallAssertion(
173181
func=BATCH_UPDATE_HOST_FAIL_CLIENT.cc.batch_update_host,
174182
calls=[

0 commit comments

Comments
 (0)