Skip to content

Commit

Permalink
feat: IDC自动判断安装通道(devnet/oss/devcloud_idc) (closed TencentBlueKing#2348)
Browse files Browse the repository at this point in the history
  • Loading branch information
Huayeaaa committed Sep 2, 2024
1 parent a5e8332 commit 55c0d9f
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 2 deletions.
12 changes: 12 additions & 0 deletions apps/backend/components/collections/agent_new/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,18 @@ def _execute(self, data, parent_data, common_data: base.AgentCommonData):
host_id__sub_inst_id = {
host_id: sub_inst_id for sub_inst_id, host_id in common_data.sub_inst_id__host_id_map.items()
}
# 获取安装通道ID与name映射
install_channel_id_name_map: Dict[str, str] = models.InstallChannel.install_channel_id_name_map(get_cache=True)
for sub_inst_id, sub_inst_obj in common_data.sub_inst_id__sub_inst_obj_map.items():
install_channel_id: Optional[int] = sub_inst_obj.instance_info["host"].get("install_channel_id")
install_channel_name: str = install_channel_id_name_map.get(
str(install_channel_id), constants.DEFAULT_INSTALL_CHANNEL_NAME
)
# 输出安装通道日志
self.log_info(
sub_inst_ids=sub_inst_id,
log_content=_(f"选择的安装通道为:{install_channel_name}"),
)
is_uninstall = data.get_one_of_inputs("is_uninstall")
host_id_obj_map = common_data.host_id_obj_map
gse_version: str = data.get_one_of_inputs("meta", {}).get("GSE_VERSION")
Expand Down
6 changes: 6 additions & 0 deletions apps/node_man/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ class TimeUnit:
DEFAULT_CLOUD_NAME = os.environ.get("DEFAULT_CLOUD_NAME", _("直连区域"))
# 自动选择接入点ID
DEFAULT_AP_ID = int(os.environ.get("DEFAULT_AP_ID", -1))
# 自动选择安装通道ID
DEFAULT_INSTALL_CHANNEL_ID = int(os.environ.get("DEFAULT_AP_ID", -1))
# 自动选择
AUTOMATIC_CHOICE = os.environ.get("AUTOMATIC_CHOICE", _("自动选择"))
# 默认安装通道
DEFAULT_INSTALL_CHANNEL_NAME = os.environ.get("DEFAULT_INSTALL_CHANNEL_NAME", _("默认通道"))
# GSE命名空间
GSE_NAMESPACE = "nodeman"

Expand Down
29 changes: 28 additions & 1 deletion apps/node_man/handlers/install_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
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 ipaddress import IPv4Network, ip_address, ip_network
from typing import Dict, List

from django.forms import model_to_dict

from apps.node_man import models
from apps.core.concurrent.cache import FuncCacheDecorator
from apps.node_man import constants, models
from apps.utils import APIModel


Expand Down Expand Up @@ -54,3 +56,28 @@ def update(

def destroy(self, install_channel_id: int):
models.InstallChannel.objects.filter(bk_cloud_id=self.bk_cloud_id, id=install_channel_id).delete()

@staticmethod
@FuncCacheDecorator(cache_time=20 * constants.TimeUnit.MINUTE)
def get_install_channel_id_network_segment():
install_channel_id_network_segment: Dict[str, List[str]] = models.GlobalSettings.get_config(
key=models.GlobalSettings.KeyEnum.INSTALL_CHANNEL_ID_NETWORK_SEGMENT.value, default={}
)
return install_channel_id_network_segment

@classmethod
def judge_install_channel(cls, inner_ip: str):
"""
:param inner_ip: 内网IPv4地址
:return: 安装通道ID
"""
install_channel_id_network_segment: Dict[str, List[str]] = cls.get_install_channel_id_network_segment()
network_obj__install_channel_id_map: Dict[IPv4Network, int] = {
ip_network(network_segment): int(install_channel_id)
for install_channel_id, network_segments in install_channel_id_network_segment.items()
for network_segment in network_segments
}
for network_obj, install_channel_id in network_obj__install_channel_id_map.items():
if ip_address(inner_ip) in network_obj:
return install_channel_id
return None
5 changes: 5 additions & 0 deletions apps/node_man/handlers/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from apps.node_man.handlers.cloud import CloudHandler
from apps.node_man.handlers.cmdb import CmdbHandler
from apps.node_man.handlers.host import HostHandler
from apps.node_man.handlers.install_channel import InstallChannelHandler
from apps.node_man.tools import JobTools
from apps.utils import APIModel
from apps.utils.basic import filter_values, to_int_or_default
Expand Down Expand Up @@ -286,6 +287,10 @@ def install(
host["ticket"] = ticket
if host.get("ap_id"):
ap_ids.add(host["ap_id"])
install_channel_id = host.get("install_channel_id")
if install_channel_id == constants.DEFAULT_INSTALL_CHANNEL_ID and host.get("inner_ip"):
install_channel_id = InstallChannelHandler.judge_install_channel(host["inner_ip"])
host["install_channel_id"] = install_channel_id

# 如果混合了【手动安装】,【自动安装】则不允许通过
# 此处暂不合入 job validator.
Expand Down
12 changes: 12 additions & 0 deletions apps/node_man/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ class KeyEnum(Enum):
IP_CHOOSER_ENABLE_SHOW_REALTIME_AGENT_STATE = "IP_CHOOSER_ENABLE_SHOW_REALTIME_AGENT_STATE"
# IP选择器详情接口实时展示agent状态业务白名单
IP_CHOOSER_BIZ_WHITELIST = "IP_CHOOSER_BIZ_WHITELIST"
# 是否仅在直连区域开启自动选择安装通道
AUTO_SELECT_INSTALL_CHANNEL_ONLY_DIRECT_AREA = "AUTO_SELECT_INSTALL_CHANNEL_ONLY_DIRECT_AREA"
# 安装通道ID与网段列表映射
INSTALL_CHANNEL_ID_NETWORK_SEGMENT = "INSTALL_CHANNEL_ID_NETWORK_SEGMENT"

key = models.CharField(_("键"), max_length=255, db_index=True, primary_key=True)
v_json = JSONField(_("值"))
Expand Down Expand Up @@ -826,6 +830,14 @@ def install_channel_id__host_objs_map(

return result

@classmethod
@FuncCacheDecorator(cache_time=20 * constants.TimeUnit.MINUTE)
def install_channel_id_name_map(cls) -> Dict[str, str]:
all_install_channel_map = {
str(install_channel["id"]): install_channel["name"] for install_channel in cls.objects.values("id", "name")
}
return all_install_channel_map

class Meta:
verbose_name = _("安装通道(InstallChannel)")
verbose_name_plural = _("安装通道(InstallChannel)")
Expand Down
13 changes: 12 additions & 1 deletion apps/node_man/tests/test_handlers/test_install_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from apps.mock_data import common_unit, utils
from apps.node_man import constants
from apps.node_man.handlers.install_channel import InstallChannelHandler
from apps.node_man.models import InstallChannel
from apps.node_man.models import GlobalSettings, InstallChannel
from apps.node_man.tests.utils import create_install_channel
from apps.utils.unittest.testcase import CustomAPITestCase

Expand Down Expand Up @@ -65,6 +65,17 @@ def test_install_channel_destroy(self, *args, **kwargs):
)
self.assertEqual(len(InstallChannelHandler.list()), 0)

def test_judge_install_channel(self, *args, **kwargs):
# 构造安装通道与网段映射
GlobalSettings.set_config(
key=GlobalSettings.KeyEnum.INSTALL_CHANNEL_ID_NETWORK_SEGMENT.value, value={"1": ["127.0.0.0/30"]}
)
# 创建安装通道
create_install_channel(1)
inner_ip = "127.0.0.1"
res = InstallChannelHandler.judge_install_channel(inner_ip=inner_ip)
self.assertEqual(res, 1)


class InstallChannelHiddenTestCase(CustomAPITestCase):
def test_install_channel_hidden(self):
Expand Down
6 changes: 6 additions & 0 deletions apps/node_man/views/install_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from rest_framework.response import Response

from apps.generic import ModelViewSet
from apps.node_man import constants
from apps.node_man.handlers.install_channel import InstallChannelHandler
from apps.node_man.handlers.permission import InstallChannelPermission
from apps.node_man.models import InstallChannel
Expand All @@ -37,6 +38,11 @@ def get_queryset(self):
# 如果 hidden 为 False, 则返回所有未隐藏的安装通道
return InstallChannel.objects.filter(hidden=False)

def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
response.data.insert(0, {"id": constants.DEFAULT_INSTALL_CHANNEL_ID, "name": constants.AUTOMATIC_CHOICE})
return response

@swagger_auto_schema(
operation_summary="创建安装通道",
tags=INSTALL_CHANNEL_VIEW_TAGS,
Expand Down

0 comments on commit 55c0d9f

Please sign in to comment.