Initial commit — Server_Monitorizare_v2

This commit is contained in:
ske087
2026-04-23 15:55:46 +03:00
commit d2485e4c66
61 changed files with 13861 additions and 0 deletions

View File

@@ -0,0 +1,324 @@
"""
Device management service with CRUD operations and device monitoring
"""
import logging
from typing import List, Optional, Dict, Any
from datetime import datetime, timedelta
from sqlalchemy.orm import Session, joinedload
from sqlalchemy import desc, func, and_
from app.models import Device, LogEntry, FileUpload, InventoryGroup
from config.database_config import get_db
class DeviceService:
"""Service for managing devices and device-related operations"""
def __init__(self):
self.db = get_db()
self.logger = logging.getLogger(__name__)
# Basic CRUD Operations
def create_device(self, hostname: str, device_ip: str, nume_masa: str, **kwargs) -> Device:
"""Create a new device"""
try:
with self.db.get_session() as session:
# Check if device already exists
existing = session.query(Device).filter(
(Device.hostname == hostname) | (Device.device_ip == device_ip)
).first()
if existing:
raise ValueError(f"Device with hostname '{hostname}' or IP '{device_ip}' already exists")
device = Device(
hostname=hostname,
device_ip=device_ip,
nume_masa=nume_masa,
device_type=kwargs.get('device_type', 'unknown'),
os_version=kwargs.get('os_version'),
status=kwargs.get('status', 'active'),
location=kwargs.get('location'),
description=kwargs.get('description'),
last_seen=datetime.utcnow()
)
session.add(device)
session.commit()
session.refresh(device)
self.logger.info(f"Created device: {hostname} ({device_ip})")
return device
except Exception as e:
self.logger.error(f"Error creating device: {e}")
raise
def get_device_by_id(self, device_id: int) -> Optional[Device]:
"""Get device by ID with relationships loaded"""
try:
with self.db.get_session() as session:
return session.query(Device).options(
joinedload(Device.logs),
joinedload(Device.files),
joinedload(Device.inventory_groups)
).filter(Device.id == device_id).first()
except Exception as e:
self.logger.error(f"Error getting device {device_id}: {e}")
return None
def get_device_by_hostname(self, hostname: str) -> Optional[Device]:
"""Get device by hostname"""
try:
with self.db.get_session() as session:
return session.query(Device).filter(Device.hostname == hostname).first()
except Exception as e:
self.logger.error(f"Error getting device by hostname {hostname}: {e}")
return None
def get_device_by_ip(self, device_ip: str) -> Optional[Device]:
"""Get device by IP address"""
try:
with self.db.get_session() as session:
return session.query(Device).filter(Device.device_ip == device_ip).first()
except Exception as e:
self.logger.error(f"Error getting device by IP {device_ip}: {e}")
return None
def get_all_devices(self, status: Optional[str] = None, limit: Optional[int] = None) -> List[Device]:
"""Get all devices with optional filtering"""
try:
with self.db.get_session() as session:
query = session.query(Device).order_by(desc(Device.last_seen))
if status:
query = query.filter(Device.status == status)
if limit:
query = query.limit(limit)
return query.all()
except Exception as e:
self.logger.error(f"Error getting devices: {e}")
return []
def update_device(self, device_id: int, **kwargs) -> Optional[Device]:
"""Update device information"""
try:
with self.db.get_session() as session:
device = session.query(Device).filter(Device.id == device_id).first()
if not device:
return None
# Update allowed fields
allowed_fields = [
'hostname', 'device_ip', 'nume_masa', 'device_type',
'os_version', 'status', 'location', 'description'
]
for field, value in kwargs.items():
if field in allowed_fields and hasattr(device, field):
setattr(device, field, value)
session.commit()
session.refresh(device)
self.logger.info(f"Updated device {device_id}")
return device
except Exception as e:
self.logger.error(f"Error updating device {device_id}: {e}")
raise
def delete_device(self, device_id: int) -> bool:
"""Delete device (soft delete by setting status to inactive)"""
try:
with self.db.get_session() as session:
device = session.query(Device).filter(Device.id == device_id).first()
if not device:
return False
# Soft delete - set status to inactive
device.status = 'inactive'
session.commit()
self.logger.info(f"Soft deleted device {device_id}")
return True
except Exception as e:
self.logger.error(f"Error deleting device {device_id}: {e}")
return False
# Device Monitoring Functions
def update_device_last_seen(self, hostname: str = None, device_ip: str = None) -> Optional[Device]:
"""Update device last seen timestamp"""
try:
with self.db.get_session() as session:
device = None
if hostname:
device = session.query(Device).filter(Device.hostname == hostname).first()
elif device_ip:
device = session.query(Device).filter(Device.device_ip == device_ip).first()
if device:
device.last_seen = datetime.utcnow()
session.commit()
return device
except Exception as e:
self.logger.error(f"Error updating last seen: {e}")
return None
def get_device_statistics(self, device_id: int) -> Dict[str, Any]:
"""Get comprehensive statistics for a device"""
try:
with self.db.get_session() as session:
device = session.query(Device).filter(Device.id == device_id).first()
if not device:
return {}
# Log statistics
total_logs = session.query(LogEntry).filter(LogEntry.device_id == device_id).count()
# Logs by severity
severity_counts = session.query(
LogEntry.severity,
func.count(LogEntry.id)
).filter(
LogEntry.device_id == device_id
).group_by(LogEntry.severity).all()
# Recent activity (last 24 hours)
last_24h = datetime.utcnow() - timedelta(hours=24)
recent_logs = session.query(LogEntry).filter(
and_(LogEntry.device_id == device_id, LogEntry.timestamp >= last_24h)
).count()
# File uploads
total_files = session.query(FileUpload).filter(
FileUpload.device_id == device_id
).count()
# Last log
last_log = session.query(LogEntry).filter(
LogEntry.device_id == device_id
).order_by(desc(LogEntry.timestamp)).first()
return {
'device': device,
'total_logs': total_logs,
'severity_counts': dict(severity_counts),
'recent_logs_24h': recent_logs,
'total_files': total_files,
'last_log': last_log,
'uptime_days': (datetime.utcnow() - device.last_seen).days if device.last_seen else 0
}
except Exception as e:
self.logger.error(f"Error getting device statistics: {e}")
return {}
def get_inactive_devices(self, hours: int = 24) -> List[Device]:
"""Get devices that haven't been seen recently"""
try:
with self.db.get_session() as session:
cutoff_time = datetime.utcnow() - timedelta(hours=hours)
return session.query(Device).filter(
and_(
Device.last_seen < cutoff_time,
Device.status.in_(['active', 'maintenance'])
)
).order_by(desc(Device.last_seen)).all()
except Exception as e:
self.logger.error(f"Error getting inactive devices: {e}")
return []
def get_device_logs(self, device_id: int, limit: int = 100, severity: str = None) -> List[LogEntry]:
"""Get logs for a specific device"""
try:
with self.db.get_session() as session:
query = session.query(LogEntry).filter(
LogEntry.device_id == device_id
).order_by(desc(LogEntry.timestamp))
if severity:
query = query.filter(LogEntry.severity == severity)
return query.limit(limit).all()
except Exception as e:
self.logger.error(f"Error getting device logs: {e}")
return []
def search_devices(self, search_term: str) -> List[Device]:
"""Search devices by hostname, IP, or description"""
try:
with self.db.get_session() as session:
search_pattern = f"%{search_term}%"
return session.query(Device).filter(
(Device.hostname.like(search_pattern)) |
(Device.device_ip.like(search_pattern)) |
(Device.nume_masa.like(search_pattern)) |
(Device.location.like(search_pattern)) |
(Device.description.like(search_pattern))
).order_by(desc(Device.last_seen)).all()
except Exception as e:
self.logger.error(f"Error searching devices: {e}")
return []
# Bulk Operations
def bulk_update_status(self, device_ids: List[int], status: str) -> int:
"""Update status for multiple devices"""
try:
with self.db.get_session() as session:
updated = session.query(Device).filter(
Device.id.in_(device_ids)
).update({Device.status: status}, synchronize_session=False)
session.commit()
self.logger.info(f"Updated status for {updated} devices")
return updated
except Exception as e:
self.logger.error(f"Error bulk updating status: {e}")
return 0
def get_device_summary(self) -> Dict[str, Any]:
"""Get summary statistics for all devices"""
try:
with self.db.get_session() as session:
# Device status counts
status_counts = session.query(
Device.status,
func.count(Device.id)
).group_by(Device.status).all()
# Device type counts
type_counts = session.query(
Device.device_type,
func.count(Device.id)
).group_by(Device.device_type).all()
# Recent activity
last_24h = datetime.utcnow() - timedelta(hours=24)
devices_seen_24h = session.query(Device).filter(
Device.last_seen >= last_24h
).count()
return {
'total_devices': session.query(Device).count(),
'status_counts': dict(status_counts),
'type_counts': dict(type_counts),
'devices_seen_24h': devices_seen_24h
}
except Exception as e:
self.logger.error(f"Error getting device summary: {e}")
return {}