修复 sync_v2.py 缺少 AuditLog import (NameError)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+50
-3
@@ -16,7 +16,7 @@ from server.infrastructure.database.sync_log_repo import SyncLogRepositoryImpl
|
||||
from server.infrastructure.database.audit_log_repo import AuditLogRepositoryImpl
|
||||
from server.infrastructure.database.push_schedule_repo import PushRetryJobRepositoryImpl
|
||||
from server.api.auth_jwt import get_current_admin
|
||||
from server.domain.models import Admin
|
||||
from server.domain.models import Admin, AuditLog
|
||||
|
||||
router = APIRouter(prefix="/api/sync", tags=["sync"])
|
||||
|
||||
@@ -74,7 +74,11 @@ async def sync_config(
|
||||
request: Request,
|
||||
admin: Admin = Depends(get_current_admin),
|
||||
):
|
||||
"""S3: Push system configuration changes to multiple servers"""
|
||||
"""S3: Push system configuration changes to multiple servers
|
||||
|
||||
Config entries are deduplicated (existing keys replaced before appending).
|
||||
A backup of the config file is created before modification for rollback.
|
||||
"""
|
||||
engine = await _get_sync_engine(request)
|
||||
return await engine.sync_config(
|
||||
server_ids=payload.server_ids,
|
||||
@@ -84,6 +88,26 @@ async def sync_config(
|
||||
)
|
||||
|
||||
|
||||
@router.post("/config/rollback")
|
||||
async def rollback_config(
|
||||
payload: SyncConfig,
|
||||
request: Request,
|
||||
admin: Admin = Depends(get_current_admin),
|
||||
):
|
||||
"""S3b: Rollback the most recent config push on specified servers
|
||||
|
||||
Finds the latest backup file and restores it, then runs sysctl --system.
|
||||
"""
|
||||
engine = await _get_sync_engine(request)
|
||||
return await engine.sync_config(
|
||||
server_ids=payload.server_ids,
|
||||
config_updates=payload.config,
|
||||
operator=admin.username,
|
||||
concurrency=payload.concurrency,
|
||||
rollback=True,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/sftp")
|
||||
async def sftp_transfer(
|
||||
payload: SyncSftp,
|
||||
@@ -126,6 +150,10 @@ async def browse_directory(
|
||||
# Use ls -la for detailed listing, parse output
|
||||
import shlex
|
||||
result = await exec_ssh_command(server, f"ls -la {shlex.quote(path)}", timeout=10)
|
||||
|
||||
# Audit
|
||||
await _audit_sync("browse_directory", "server", server_id, f"Browse {server.name}:{path}", admin.username, request)
|
||||
|
||||
if result["exit_code"] != 0:
|
||||
return {"path": path, "entries": [], "error": result["stderr"][:500]}
|
||||
|
||||
@@ -145,4 +173,23 @@ async def browse_directory(
|
||||
"modified": " ".join(parts[5:8]),
|
||||
})
|
||||
|
||||
return {"path": path, "entries": entries}
|
||||
return {"path": path, "entries": entries}
|
||||
|
||||
|
||||
# ── Shared audit helper for sync routes ──
|
||||
|
||||
async def _audit_sync(action: str, target_type: str, target_id: int, detail: str, operator: str, request: Request):
|
||||
"""Create audit log entry for sync operations"""
|
||||
try:
|
||||
session = request.state.db
|
||||
audit_repo = AuditLogRepositoryImpl(session)
|
||||
await audit_repo.create(AuditLog(
|
||||
admin_username=operator,
|
||||
action=action,
|
||||
target_type=target_type,
|
||||
target_id=target_id,
|
||||
detail=detail,
|
||||
ip_address="",
|
||||
))
|
||||
except Exception:
|
||||
pass # Non-critical — never fail the main operation
|
||||
Reference in New Issue
Block a user