фикс передачи логинов в задачи
This commit is contained in:
parent
2a90c9b8dd
commit
be1e98e18a
9 changed files with 24 additions and 18 deletions
|
|
@ -7,7 +7,9 @@ and an emit() callback to write progress messages to the SSE stream.
|
|||
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any, Awaitable, Callable
|
||||
from typing import Any, Awaitable, Callable, Optional
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.models.device import Device
|
||||
from app.models.object import Object
|
||||
|
|
@ -46,6 +48,7 @@ class BaseAction(ABC):
|
|||
obj: Object,
|
||||
params: dict,
|
||||
emit: Emitter,
|
||||
db: Optional[AsyncSession] = None,
|
||||
) -> ActionResult: ...
|
||||
|
||||
def is_compatible(self, category: str) -> bool:
|
||||
|
|
@ -79,10 +82,11 @@ class CompositeAction(BaseAction):
|
|||
obj: Object,
|
||||
params: dict,
|
||||
emit: Emitter,
|
||||
db: Optional[AsyncSession] = None,
|
||||
) -> ActionResult:
|
||||
action = self._routing.get(device.category)
|
||||
if action is None:
|
||||
msg = f"[{device.ip}] Нет обработчика для категории '{device.category}'"
|
||||
await emit(msg, "error")
|
||||
return ActionResult(success=False, error=msg)
|
||||
return await action.execute(device, obj, params, emit)
|
||||
return await action.execute(device, obj, params, emit, db=db)
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@ class MikrotikGetConfigAction(BaseAction):
|
|||
params_schema = []
|
||||
|
||||
async def execute(
|
||||
self, device: Device, obj: Object, params: dict, emit: Emitter
|
||||
self, device: Device, obj: Object, params: dict, emit: Emitter, db=None
|
||||
) -> ActionResult:
|
||||
await emit(f"[{device.ip}] Running /export compact", "info")
|
||||
|
||||
result = await ssh_service.run_command(
|
||||
device, obj, "/export compact", timeout=60
|
||||
device, obj, "/export compact", timeout=60, db=db
|
||||
)
|
||||
|
||||
if not result.success and not result.stdout:
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ class MikrotikGetNTPAction(BaseAction):
|
|||
params_schema = []
|
||||
|
||||
async def execute(
|
||||
self, device: Device, obj: Object, params: dict, emit: Emitter
|
||||
self, device: Device, obj: Object, params: dict, emit: Emitter, db=None
|
||||
) -> ActionResult:
|
||||
await emit(f"[{device.ip}] /system ntp client print", "info")
|
||||
|
||||
result = await ssh_service.run_command(
|
||||
device, obj, "/system ntp client print"
|
||||
device, obj, "/system ntp client print", db=db
|
||||
)
|
||||
|
||||
if result.error:
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class MikrotikSetNTPAction(BaseAction):
|
|||
]
|
||||
|
||||
async def execute(
|
||||
self, device: Device, obj: Object, params: dict, emit: Emitter
|
||||
self, device: Device, obj: Object, params: dict, emit: Emitter, db=None
|
||||
) -> ActionResult:
|
||||
server = params.get("server", "").strip()
|
||||
if not server:
|
||||
|
|
@ -37,7 +37,7 @@ class MikrotikSetNTPAction(BaseAction):
|
|||
|
||||
for cmd in commands:
|
||||
await emit(f"[{device.ip}] {cmd}", "info")
|
||||
result = await ssh_service.run_command(device, obj, cmd)
|
||||
result = await ssh_service.run_command(device, obj, cmd, db=db)
|
||||
if result.error:
|
||||
await emit(f"[{device.ip}] Error: {result.error}", "error")
|
||||
return ActionResult(
|
||||
|
|
@ -49,7 +49,7 @@ class MikrotikSetNTPAction(BaseAction):
|
|||
)
|
||||
|
||||
# Verify
|
||||
verify = await ssh_service.run_command(device, obj, "/system ntp client print")
|
||||
verify = await ssh_service.run_command(device, obj, "/system ntp client print", db=db)
|
||||
await emit(f"[{device.ip}] Verify: {verify.stdout[:200]}", "info")
|
||||
|
||||
return ActionResult(
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@ class DebianSystemInfoAction(BaseAction):
|
|||
compatible_categories = ["server", "raspberry", "embedded", "other"]
|
||||
params_schema = []
|
||||
|
||||
async def execute(self, device: Device, obj: Object, params: dict, emit: Emitter) -> ActionResult:
|
||||
async def execute(self, device: Device, obj: Object, params: dict, emit: Emitter, db=None) -> ActionResult:
|
||||
await emit(f"[{device.ip}] Collecting system info...", "info")
|
||||
|
||||
result = await ssh_service.run_command(device, obj, _CMD, timeout=30)
|
||||
result = await ssh_service.run_command(device, obj, _CMD, timeout=30, db=db)
|
||||
|
||||
if result.error:
|
||||
await emit(f"[{device.ip}] Error: {result.error}", "error")
|
||||
|
|
|
|||
|
|
@ -26,14 +26,14 @@ class GetFileAction(BaseAction):
|
|||
]
|
||||
|
||||
async def execute(
|
||||
self, device: Device, obj: Object, params: dict, emit: Emitter
|
||||
self, device: Device, obj: Object, params: dict, emit: Emitter, db=None
|
||||
) -> ActionResult:
|
||||
path = params.get("path", "").strip()
|
||||
if not path:
|
||||
return ActionResult(success=False, error="No file path specified")
|
||||
|
||||
await emit(f"[{device.ip}] Reading {path}", "info")
|
||||
result = await ssh_service.run_command(device, obj, f"cat {path}")
|
||||
result = await ssh_service.run_command(device, obj, f"cat {path}", db=db)
|
||||
|
||||
if not result.success:
|
||||
msg = result.error or result.stderr or f"exit code {result.exit_code}"
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ class GetTimedatectlAction(BaseAction):
|
|||
compatible_categories = ["raspberry", "server"]
|
||||
params_schema = []
|
||||
|
||||
async def execute(self, device: Device, obj: Object, params: dict, emit: Emitter) -> ActionResult:
|
||||
async def execute(self, device: Device, obj: Object, params: dict, emit: Emitter, db=None) -> ActionResult:
|
||||
await emit(f"[{device.ip}] Running timedatectl...", "info")
|
||||
result = await ssh_service.run_command(device, obj, "timedatectl show --no-pager 2>/dev/null || timedatectl")
|
||||
result = await ssh_service.run_command(device, obj, "timedatectl show --no-pager 2>/dev/null || timedatectl", db=db)
|
||||
|
||||
if result.error:
|
||||
await emit(f"[{device.ip}] Error: {result.error}", "error")
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ class SSHCommandAction(BaseAction):
|
|||
{"name": "command", "type": "string", "label": "Command", "required": True},
|
||||
]
|
||||
|
||||
async def execute(self, device: Device, obj: Object, params: dict, emit: Emitter) -> ActionResult:
|
||||
async def execute(self, device: Device, obj: Object, params: dict, emit: Emitter, db=None) -> ActionResult:
|
||||
command = params.get("command", "").strip()
|
||||
if not command:
|
||||
return ActionResult(success=False, error="No command specified")
|
||||
|
||||
await emit(f"[{device.ip}] $ {command}", "info")
|
||||
result = await ssh_service.run_command(device, obj, command)
|
||||
result = await ssh_service.run_command(device, obj, command, db=db)
|
||||
|
||||
if result.error:
|
||||
await emit(f"[{device.ip}] Error: {result.error}", "error")
|
||||
|
|
|
|||
|
|
@ -134,7 +134,9 @@ async def _run_on_device(
|
|||
result_id = tr.id
|
||||
|
||||
try:
|
||||
action_result = await action.execute(device, obj, params, emit)
|
||||
async with AsyncSessionLocal() as action_db:
|
||||
async with action_db.begin():
|
||||
action_result = await action.execute(device, obj, params, emit, db=action_db)
|
||||
except Exception as exc:
|
||||
action_result_success = False
|
||||
action_stdout = ""
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue