Stage SMB CF/CFE inputs for Windows Agent
This commit is contained in:
@@ -44,6 +44,7 @@ async def html5_ai_structure_run(
|
|||||||
prepare: Callable[..., dict[str, Any]],
|
prepare: Callable[..., dict[str, Any]],
|
||||||
work_root: Path,
|
work_root: Path,
|
||||||
start_binary_job: Callable[..., Any] | None = None,
|
start_binary_job: Callable[..., Any] | None = None,
|
||||||
|
stage_binary_input: Callable[..., Any] | None = None,
|
||||||
save_run_state: Callable[[str, dict[str, Any]], None] | None = None,
|
save_run_state: Callable[[str, dict[str, Any]], None] | None = None,
|
||||||
load_credentials: Callable[[str], SmbCredentials | None] | None = None,
|
load_credentials: Callable[[str], SmbCredentials | None] | None = None,
|
||||||
save_credentials: Callable[[str, SmbCredentials], None] | None = None,
|
save_credentials: Callable[[str, SmbCredentials], None] | None = None,
|
||||||
@@ -85,11 +86,26 @@ async def html5_ai_structure_run(
|
|||||||
if binary_match is not None:
|
if binary_match is not None:
|
||||||
if start_binary_job is None or save_run_state is None:
|
if start_binary_job is None or save_run_state is None:
|
||||||
return render_html5_ai_structure_error("Сервис подготовки CF/CFE через Windows Agent не подключен.")
|
return render_html5_ai_structure_error("Сервис подготовки CF/CFE через Windows Agent не подключен.")
|
||||||
|
binary_input_path = input_path
|
||||||
|
if is_unc_path(input_path) and local_input.exists() and stage_binary_input is not None:
|
||||||
|
try:
|
||||||
|
binary_input_path = await stage_binary_input(
|
||||||
|
project_id=project_id,
|
||||||
|
effective_project_id=effective_project_id,
|
||||||
|
local_input=local_input,
|
||||||
|
username=username,
|
||||||
|
password=password,
|
||||||
|
domain=domain or None,
|
||||||
|
)
|
||||||
|
except HTTPException as error:
|
||||||
|
return render_html5_ai_structure_error(str(error.detail))
|
||||||
|
except RuntimeError as error:
|
||||||
|
return render_html5_ai_structure_error(str(error))
|
||||||
try:
|
try:
|
||||||
job = await start_binary_job(
|
job = await start_binary_job(
|
||||||
project_id=project_id,
|
project_id=project_id,
|
||||||
effective_project_id=effective_project_id,
|
effective_project_id=effective_project_id,
|
||||||
input_path=input_path,
|
input_path=binary_input_path,
|
||||||
detected_binary_relative_path=binary_match.get("relative_path"),
|
detected_binary_relative_path=binary_match.get("relative_path"),
|
||||||
detected_binary_relative_paths=binary_match.get("binary_relative_paths"),
|
detected_binary_relative_paths=binary_match.get("binary_relative_paths"),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ from api_server.snapshot_module_service import (
|
|||||||
module_sources_for_object as _snapshot_module_sources_for_object,
|
module_sources_for_object as _snapshot_module_sources_for_object,
|
||||||
snapshot_bsl_completion_items as _snapshot_bsl_completion_items,
|
snapshot_bsl_completion_items as _snapshot_bsl_completion_items,
|
||||||
)
|
)
|
||||||
from api_server.smb_paths import is_unc_path
|
from api_server.smb_paths import copy_local_tree_to_smb, is_unc_path
|
||||||
from api_server.time_utils import current_timestamp as _current_timestamp
|
from api_server.time_utils import current_timestamp as _current_timestamp
|
||||||
from impact_engine import object_impact, routine_impact
|
from impact_engine import object_impact, routine_impact
|
||||||
from incremental_indexer import rebuild_changed_file
|
from incremental_indexer import rebuild_changed_file
|
||||||
@@ -657,6 +657,39 @@ async def _queue_ai_structure_agent_step(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def _stage_ai_structure_binary_input_for_agent(
|
||||||
|
*,
|
||||||
|
project_id: str,
|
||||||
|
effective_project_id: str,
|
||||||
|
local_input: Path,
|
||||||
|
username: str,
|
||||||
|
password: str,
|
||||||
|
domain: str | None = None,
|
||||||
|
) -> str:
|
||||||
|
settings = _project_settings_or_404(project_id)
|
||||||
|
agent_id = _agent_id_for_source(settings, ImportSourceKind.CF_FILE)
|
||||||
|
if not agent_id:
|
||||||
|
raise HTTPException(status_code=400, detail="В настройках проекта не выбран Windows Agent для CF/CFE.")
|
||||||
|
agent_status = _agent_status_with_liveness(_agent_statuses.get(agent_id, AgentStatus(agent_id=agent_id)))
|
||||||
|
roots = [str(item).strip() for item in getattr(agent_status, "network_roots", []) if str(item).strip()]
|
||||||
|
if not roots:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400,
|
||||||
|
detail=f"У Windows Agent {agent_id} не настроены доступные сетевые корни для staging CF/CFE.",
|
||||||
|
)
|
||||||
|
if not local_input.exists():
|
||||||
|
raise HTTPException(status_code=404, detail=f"Сервер не нашел локальную копию входных файлов: {local_input}")
|
||||||
|
stage_root = ntpath.join(roots[0], "SFERA", "ai-structure-staging", f"{effective_project_id}-{uuid4().hex}")
|
||||||
|
copy_local_tree_to_smb(
|
||||||
|
source=local_input,
|
||||||
|
target=stage_root,
|
||||||
|
username=username,
|
||||||
|
password=password,
|
||||||
|
domain=domain or None,
|
||||||
|
)
|
||||||
|
return stage_root
|
||||||
|
|
||||||
|
|
||||||
async def _start_ai_structure_agent_job(
|
async def _start_ai_structure_agent_job(
|
||||||
*,
|
*,
|
||||||
project_id: str,
|
project_id: str,
|
||||||
@@ -2117,6 +2150,7 @@ async def html5_project_ai_structure_run(project_id: str, request: Request) -> R
|
|||||||
prepare=_prepare_ai_structure,
|
prepare=_prepare_ai_structure,
|
||||||
work_root=_storage.root / "ai_structure_work",
|
work_root=_storage.root / "ai_structure_work",
|
||||||
start_binary_job=_start_ai_structure_agent_job,
|
start_binary_job=_start_ai_structure_agent_job,
|
||||||
|
stage_binary_input=_stage_ai_structure_binary_input_for_agent,
|
||||||
save_run_state=_save_ai_structure_agent_run,
|
save_run_state=_save_ai_structure_agent_run,
|
||||||
load_credentials=_load_ai_structure_smb_credentials,
|
load_credentials=_load_ai_structure_smb_credentials,
|
||||||
save_credentials=_save_ai_structure_smb_credentials,
|
save_credentials=_save_ai_structure_smb_credentials,
|
||||||
|
|||||||
@@ -2091,6 +2091,10 @@ def test_html5_ai_structure_routes_unc_directory_with_cf_through_windows_agent(m
|
|||||||
started.update(kwargs)
|
started.update(kwargs)
|
||||||
return FakeJob()
|
return FakeJob()
|
||||||
|
|
||||||
|
async def fake_stage_binary_input(**kwargs):
|
||||||
|
started["staged_from"] = kwargs["local_input"]
|
||||||
|
return r"\\192.168.220.220\mst\SFERA\ai-structure-staging\unc-demo"
|
||||||
|
|
||||||
saved_runs: dict[str, dict[str, object]] = {}
|
saved_runs: dict[str, dict[str, object]] = {}
|
||||||
|
|
||||||
monkeypatch.setattr(controller, "copy_smb_tree_to_local", fake_copy_smb_tree_to_local)
|
monkeypatch.setattr(controller, "copy_smb_tree_to_local", fake_copy_smb_tree_to_local)
|
||||||
@@ -2108,15 +2112,17 @@ def test_html5_ai_structure_routes_unc_directory_with_cf_through_windows_agent(m
|
|||||||
prepare=lambda **_: {},
|
prepare=lambda **_: {},
|
||||||
work_root=tmp_path / "work",
|
work_root=tmp_path / "work",
|
||||||
start_binary_job=fake_start_binary_job,
|
start_binary_job=fake_start_binary_job,
|
||||||
|
stage_binary_input=fake_stage_binary_input,
|
||||||
save_run_state=lambda job_id, payload: saved_runs.setdefault(job_id, payload),
|
save_run_state=lambda job_id, payload: saved_runs.setdefault(job_id, payload),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
assert "Windows Agent" in html
|
assert "Windows Agent" in html
|
||||||
assert copied_targets
|
assert copied_targets
|
||||||
assert started["input_path"] == r"\\192.168.220.200\mst\1c\MARKA\CODEX\CF"
|
assert started["input_path"] == r"\\192.168.220.220\mst\SFERA\ai-structure-staging\unc-demo"
|
||||||
assert started["detected_binary_relative_path"] == "base.cf"
|
assert started["detected_binary_relative_path"] == "base.cf"
|
||||||
assert started["detected_binary_relative_paths"] == ["base.cf"]
|
assert started["detected_binary_relative_paths"] == ["base.cf"]
|
||||||
|
assert started["staged_from"] == copied_targets[0][1]
|
||||||
assert "agent-import-test" in saved_runs
|
assert "agent-import-test" in saved_runs
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user