Skip to content

Commit

Permalink
fix: IDC windows机器开通前置策略 (closed #2301)
Browse files Browse the repository at this point in the history
  • Loading branch information
v_gqpgguo authored and wyyalt committed Jul 4, 2024
1 parent 5b12f3e commit 8e98f8b
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 23 deletions.
90 changes: 68 additions & 22 deletions apps/backend/agent/solution_maker.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from apps.backend.api import constants as backend_api_constants
from apps.backend.subscription.steps.agent_adapter.base import AgentSetupInfo
from apps.core.script_manage.base import ScriptHook
from apps.core.script_manage.data import JUMP_SERVER_POLICY_SCRIPT_INFO
from apps.node_man import constants, models
from apps.utils import basic
from apps.utils.files import PathHandler
Expand Down Expand Up @@ -406,7 +407,9 @@ def get_create_pre_dirs_step(self, is_shell_adapter: bool = False) -> ExecutionS

return create_pre_dir_step

def build_script_hook_steps(self, is_shell_adapter: bool = False) -> typing.List[ExecutionSolutionStep]:
def build_need_download_script_hook_steps(
self, is_shell_adapter: bool = False
) -> typing.List[ExecutionSolutionStep]:
"""
构造脚本钩子步骤
:param is_shell_adapter: 是否需要进行 shell 适配
Expand All @@ -418,29 +421,14 @@ def build_script_hook_steps(self, is_shell_adapter: bool = False) -> typing.List
curl_cmd: str = ("curl", f"{dest_dir}curl.exe")[is_batch]

script_hook_steps: typing.List[ExecutionSolutionStep] = []
for script_hook_obj in self.script_hook_objs:
need_download_script_hook_objs: typing.List[ScriptHook] = [
script_hook_obj for script_hook_obj in self.script_hook_objs if not script_hook_obj.script_info_obj.oneline
]
for script_hook_obj in need_download_script_hook_objs:
support_cloud_id: typing.Optional[int] = script_hook_obj.script_info_obj.support_cloud_id
if support_cloud_id is not None and self.host.bk_cloud_id != support_cloud_id:
continue

if script_hook_obj.script_info_obj.oneline:
# 如果可以一行命令执行,直接执行相应的命令
script_hook_steps.append(
ExecutionSolutionStep(
step_type=constants.CommonExecutionSolutionStepType.COMMANDS.value,
description=str(script_hook_obj.script_info_obj.description),
contents=[
ExecutionSolutionStepContent(
name="run_cmd",
text=script_hook_obj.script_info_obj.oneline,
description=str(script_hook_obj.script_info_obj.description),
show_description=False,
),
],
)
)
continue

download_cmd = (
f"{curl_cmd} {self.gse_servers_info['package_url']}/{script_hook_obj.script_info_obj.path} "
f"-o {dest_dir}{script_hook_obj.script_info_obj.filename} --connect-timeout 5 -sSfg"
Expand Down Expand Up @@ -484,6 +472,59 @@ def build_script_hook_steps(self, is_shell_adapter: bool = False) -> typing.List

return script_hook_steps

def build_oneline_script_hook_steps(self) -> typing.List[ExecutionSolutionStep]:
"""
构造可直接执行的脚本钩子步骤
:return:
"""
script_hook_steps: typing.List[ExecutionSolutionStep] = []
oneline_script_hook_objs: typing.List[ScriptHook] = [
script_hook_obj for script_hook_obj in self.script_hook_objs if script_hook_obj.script_info_obj.oneline
]
for script_hook_obj in oneline_script_hook_objs:
support_cloud_id: typing.Optional[int] = script_hook_obj.script_info_obj.support_cloud_id
if support_cloud_id is not None and self.host.bk_cloud_id != support_cloud_id:
continue

# 跳板机策略特殊处理
if script_hook_obj.script_info_obj.name == JUMP_SERVER_POLICY_SCRIPT_INFO.name:
if not self.is_jump_server_policy_steps():
continue

script_hook_obj.script_info_obj.oneline = script_hook_obj.script_info_obj.oneline.format(
jump_server_lan_ip=self.gse_servers_info["jump_server"].inner_ip
)

# 如果可以一行命令执行,直接执行相应的命令
script_hook_steps.append(
ExecutionSolutionStep(
step_type=constants.CommonExecutionSolutionStepType.COMMANDS.value,
description=str(script_hook_obj.script_info_obj.description),
contents=[
ExecutionSolutionStepContent(
name="run_cmd",
text=script_hook_obj.script_info_obj.oneline,
description=str(script_hook_obj.script_info_obj.description),
show_description=False,
),
],
)
)

return script_hook_steps

def is_jump_server_policy_steps(self) -> bool:
# 非直连或非p-agent不需要开通端口策略
if not ExecutionSolutionTools.need_jump_server(self.host) or self.host.bk_cloud_id != constants.DEFAULT_CLOUD:
return False

jump_server: models.Host = self.gse_servers_info["jump_server"]
jump_server_lan_ip: str = jump_server.inner_ip or jump_server.inner_ipv6
if basic.is_v6(jump_server_lan_ip):
return False

return True

@abc.abstractmethod
def _make(self) -> ExecutionSolution:
raise NotImplementedError
Expand Down Expand Up @@ -580,10 +621,13 @@ def _make(self) -> ExecutionSolution:
execution_solution: ExecutionSolution = ExecutionSolution(
solution_type=constants.CommonExecutionSolutionType.SHELL.value,
description=str(solution_description),
steps=self.build_script_hook_steps(is_shell_adapter=True),
steps=self.build_need_download_script_hook_steps(is_shell_adapter=True),
)

if self.host.os_type == constants.OsType.WINDOWS:
# 依赖前置条件,直接下发的命令放置到依赖下载步骤之前
execution_solution.steps = self.build_oneline_script_hook_steps() + execution_solution.steps

# Windows 需要下载依赖文件
dependence_download_cmds_step: ExecutionSolutionStep = ExecutionSolutionStep(
step_type=constants.CommonExecutionSolutionStepType.COMMANDS.value,
Expand Down Expand Up @@ -722,9 +766,11 @@ def _make(self) -> ExecutionSolution:
),
steps=[
create_pre_dirs_step,
# 依赖前置条件,直接下发的命令放置到依赖下载步骤之前
*self.build_oneline_script_hook_steps(),
dependencies_step,
# 脚本的执行可能会有依赖受限,放置到依赖下载步骤之后
*self.build_script_hook_steps(),
*self.build_need_download_script_hook_steps(),
run_cmds_step,
],
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@
from apps.core.remote import exceptions
from apps.core.remote.tests import base
from apps.core.remote.tests.base import AsyncMockConn
from apps.core.script_manage.data import JUMP_SERVER_POLICY_SCRIPT_INFO
from apps.core.script_manage.handlers import ScriptManageHandler
from apps.exceptions import ApiResultError
from apps.mock_data import api_mkd
from apps.mock_data import api_mkd, common_unit
from apps.mock_data import utils as mock_data_utils
from apps.node_man import constants, models
from env.constants import GseVersion
Expand Down Expand Up @@ -1260,3 +1261,92 @@ def _do_case_assert(self, service, method, assertion, no, name, args=None, kwarg
list(failed_subscription_instance_id_reason_map.values()),
[f"管控区域 -> {self.update_cloud_id} 下无存活的 Proxy"],
)


class OpenJumpPolicyUsingChannelInDirect(InstallAgentWithInstallChannelSuccessTest):
OS_TYPE = constants.OsType.WINDOWS

def test_gen_install_channel_agent_command(self):

host = models.Host.objects.get(bk_host_id=self.obj_factory.bk_host_ids[0])
script_hook_objs = ScriptManageHandler.fetch_match_script_hook_objs(
[{"name": "jump_server_policy"}], host.os_type
)
installation_tool = gen_commands(
self.LEGACY_SETUP_INFO,
host,
mock_data_utils.JOB_TASK_PIPELINE_ID,
is_uninstall=False,
sub_inst_id=0,
script_hook_objs=script_hook_objs,
)

shell_solutions, batch_solutions = installation_tool.type__execution_solution_map["shell"].target_host_solutions

# windows shell方案 新增第二步(原来只有四步,多了一步开通跳板机策略)
self.assertEqual(len(shell_solutions.steps), 5)
self.assertEqual(
shell_solutions.steps[1].contents[0].text,
JUMP_SERVER_POLICY_SCRIPT_INFO.oneline.format(jump_server_lan_ip=common_unit.host.PROXY_INNER_IP),
)

# windows batch方案 新增第一步(原来只有三步,多了一步开通跳板机策略)
self.assertEqual(len(batch_solutions.steps), 4)
self.assertEqual(
batch_solutions.steps[1].contents[0].text,
JUMP_SERVER_POLICY_SCRIPT_INFO.oneline.format(jump_server_lan_ip=common_unit.host.PROXY_INNER_IP),
)


class OpenJumpPolicyNoUsingChannelInDirect(InstallAgent2WindowsTestCase):
@override_settings(GSE_ENVIRON_WIN_DIR=mock_data_utils.GSE_ENVIRON_WIN_DIR)
def test_batch_solution(self):
host = models.Host.objects.get(bk_host_id=self.obj_factory.bk_host_ids[0])
script_hook_objs = ScriptManageHandler.fetch_match_script_hook_objs(
[{"name": "jump_server_policy"}], host.os_type
)
agent_step_adapter: AgentStepAdapter = AgentStepAdapter(
self.obj_factory.sub_step_objs[0],
gse_version=GseVersion.V2.value,
)
installation_tool = gen_commands(
agent_step_adapter.setup_info,
host,
mock_data_utils.JOB_TASK_PIPELINE_ID,
is_uninstall=False,
sub_inst_id=0,
script_hook_objs=script_hook_objs,
)

shell_solutions = installation_tool.type__execution_solution_map["shell"]
batch_solutions = installation_tool.type__execution_solution_map["batch"]

# windows shell方案(保持原有四步)
self.assertEqual(len(shell_solutions.steps), 4)

# windows batch方案(保持原有三步)
self.assertEqual(len(batch_solutions.steps), 3)


class OpenJumpPolicyUsingChannelNotInDirect(InstallWindowsPagentTestCase):
def test_target_host_shell_solution(self):
host = models.Host.objects.get(bk_host_id=self.obj_factory.bk_host_ids[0])
script_hook_objs = ScriptManageHandler.fetch_match_script_hook_objs(
[{"name": "jump_server_policy"}], host.os_type
)
installation_tool = gen_commands(
self.LEGACY_SETUP_INFO,
host,
mock_data_utils.JOB_TASK_PIPELINE_ID,
is_uninstall=False,
sub_inst_id=0,
script_hook_objs=script_hook_objs,
)

shell_solutions, batch_solutions = installation_tool.type__execution_solution_map["shell"].target_host_solutions

# windows shell方案(保持原有四步)
self.assertEqual(len(shell_solutions.steps), 4)

# windows batch方案(保持原有三步)
self.assertEqual(len(batch_solutions.steps), 3)
16 changes: 16 additions & 0 deletions apps/core/script_manage/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,24 @@
support_cloud_id=DEFAULT_CLOUD,
)

JUMP_SERVER_POLICY_SCRIPT_INFO: base.ScriptInfo = base.ScriptInfo(
name="jump_server_policy",
filename="jump_server_policy.bat",
path="",
description=_("开通跳板机17980和17981端口"),
oneline=(
"netsh advfirewall firewall show rule name=IEOD_Outbound_NodeMan_Rule_TCP 2>&1 > NUL || "
"netsh advfirewall firewall add rule name=IEOD_Outbound_NodeMan_Rule_TCP "
'dir=out remoteip="{jump_server_lan_ip}/32" protocol=tcp remoteport="17980,17981" '
"profile=public enable=yes action=allow"
),
support_os_list=[node_man_constants.OsType.WINDOWS],
support_cloud_id=DEFAULT_CLOUD,
)

SCRIPT_NAME__INFO_OBJ_MAP: typing.Dict[str, base.ScriptInfo] = {
FIREWALL_OFF_SCRIPT_INFO.name: FIREWALL_OFF_SCRIPT_INFO,
ACTIVE_FIREWALL_POLICY_SCRIPT_INFO.name: ACTIVE_FIREWALL_POLICY_SCRIPT_INFO,
IEOD_ACTIVE_FIREWALL_POLICY_SCRIPT_INFO.name: IEOD_ACTIVE_FIREWALL_POLICY_SCRIPT_INFO,
JUMP_SERVER_POLICY_SCRIPT_INFO.name: JUMP_SERVER_POLICY_SCRIPT_INFO,
}

0 comments on commit 8e98f8b

Please sign in to comment.