This commit is contained in:
Constantin
2025-09-12 23:04:52 +03:00
commit 2277b11563
127 changed files with 23640 additions and 0 deletions
+302
View File
@@ -0,0 +1,302 @@
#!/usr/bin/env python3
"""
Cell Manager for Personal Internet Cell
Handles overall cell configuration and service orchestration
"""
from network_manager import NetworkManager
from wireguard_manager import WireGuardManager
from peer_registry import PeerRegistry
from email_manager import EmailManager
from calendar_manager import CalendarManager
from file_manager import FileManager
from routing_manager import RoutingManager
from vault_manager import VaultManager
from container_manager import ContainerManager
from datetime import datetime
import json
import logging
from pathlib import Path
from typing import Dict, List, Any
from base_service_manager import BaseServiceManager
logger = logging.getLogger(__name__)
class CellManager(BaseServiceManager):
"""Manages overall cell configuration and service orchestration"""
def __init__(self, config_path=None, data_dir: str = '/app/data', config_dir: str = '/app/config'):
super().__init__('cell', data_dir, config_dir)
import os
self.config_path = Path(config_path or os.environ.get('CELL_CONFIG_PATH', 'cell_config.json'))
# Initialize all service managers
self.network_manager = NetworkManager(data_dir, config_dir)
self.wireguard_manager = WireGuardManager(data_dir, config_dir)
self.peer_registry = PeerRegistry()
self.email_manager = EmailManager(data_dir, config_dir)
self.calendar_manager = CalendarManager(data_dir, config_dir)
self.file_manager = FileManager(data_dir, config_dir)
self.routing_manager = RoutingManager(data_dir, config_dir)
self.vault_manager = VaultManager(config_dir, data_dir)
self.container_manager = ContainerManager(data_dir, config_dir)
self._peers = []
self._uptime = 3600
# Load config from file if exists
if self.config_path.exists():
with open(self.config_path, 'r') as f:
self.config = json.load(f)
else:
self.cell_name = os.environ.get("CELL_NAME", "personal-internet-cell")
self.domain = os.environ.get("DOMAIN", f"{self.cell_name}.cell")
self.ip_range = os.environ.get("IP_RANGE", "10.0.0.0/24")
self.wireguard_port = int(os.environ.get("WIREGUARD_PORT", 51820))
self.dns_port = int(os.environ.get("DNS_PORT", 53))
self.dhcp_range = os.environ.get("DHCP_RANGE", "10.0.0.100-10.0.200")
self.config = {
"cell_name": self.cell_name,
"domain": self.domain,
"ip_range": self.ip_range,
"wireguard_port": self.wireguard_port,
"dns_port": self.dns_port,
"dhcp_range": self.dhcp_range,
"created_at": datetime.utcnow().isoformat()
}
# Always update attributes from config
for k, v in self.config.items():
setattr(self, k, v)
def get_status(self) -> Dict[str, Any]:
"""Get cell service status"""
try:
services_status = self.get_services_status()
# Count healthy services
healthy_services = 0
total_services = len(services_status)
for service_name, status in services_status.items():
if status.get('running', False):
healthy_services += 1
status = {
'running': healthy_services > 0,
'status': 'online' if healthy_services > 0 else 'offline',
'cell_name': self.config["cell_name"],
'domain': self.config["domain"],
'ip_range': self.config["ip_range"],
'wireguard_port': self.config["wireguard_port"],
'dns_port': self.config["dns_port"],
'dhcp_range': self.config["dhcp_range"],
'uptime': self._uptime,
'peers_count': len(self._peers),
'healthy_services': healthy_services,
'total_services': total_services,
'services': services_status,
'timestamp': datetime.utcnow().isoformat()
}
return status
except Exception as e:
return self.handle_error(e, "get_status")
def test_connectivity(self) -> Dict[str, Any]:
"""Test cell service connectivity"""
try:
# Test all service managers connectivity
network_test = self.network_manager.test_connectivity()
wireguard_test = self.wireguard_manager.test_connectivity()
email_test = self.email_manager.test_connectivity()
calendar_test = self.calendar_manager.test_connectivity()
files_test = self.file_manager.test_connectivity()
routing_test = self.routing_manager.test_connectivity()
vault_test = self.vault_manager.test_connectivity()
container_test = self.container_manager.test_connectivity()
# Calculate overall success
all_tests = [
network_test, wireguard_test, email_test, calendar_test,
files_test, routing_test, vault_test, container_test
]
successful_tests = sum(1 for test in all_tests if test.get('success', False))
total_tests = len(all_tests)
results = {
'network': network_test,
'wireguard': wireguard_test,
'email': email_test,
'calendar': calendar_test,
'files': files_test,
'routing': routing_test,
'vault': vault_test,
'container': container_test,
'success': successful_tests > 0,
'successful_tests': successful_tests,
'total_tests': total_tests,
'timestamp': datetime.utcnow().isoformat()
}
return results
except Exception as e:
return self.handle_error(e, "test_connectivity")
def save_config(self):
"""Save cell configuration"""
try:
with open(self.config_path, 'w') as f:
json.dump(self.config, f, indent=2)
self.logger.info("Cell configuration saved")
return True
except Exception as e:
self.logger.error(f"Error saving cell configuration: {e}")
return False
def get_config(self) -> Dict[str, Any]:
"""Get cell configuration"""
return {
"cell_name": self.cell_name,
"domain": self.domain,
"ip_range": self.ip_range,
"wireguard_port": self.wireguard_port,
"dns_port": self.dns_port,
"dhcp_range": self.dhcp_range
}
def update_config(self, config: Dict[str, Any]) -> Dict[str, Any]:
"""Update cell configuration"""
try:
# Update config attributes from dict
for k, v in config.items():
if hasattr(self, k):
setattr(self, k, v)
self.config[k] = v
# Save updated config
self.save_config()
return {"status": "updated", "message": "Configuration updated successfully"}
except Exception as e:
return {"status": "error", "message": f"Failed to update configuration: {str(e)}"}
def get_peers(self) -> List[Dict[str, Any]]:
"""Get all peers"""
return self._peers
def add_peer(self, peer: Dict[str, Any]) -> tuple[bool, str]:
"""Add a new peer"""
try:
# Simulate validation: must have name, ip, public_key
if not all(k in peer for k in ("name", "ip", "public_key")):
return False, "Missing required fields"
# Prevent duplicate peer names
if any(p['name'] == peer['name'] for p in self._peers):
return False, "Peer already exists"
self._peers.append(peer)
self.logger.info(f"Added peer: {peer['name']}")
return True, "Peer added successfully"
except Exception as e:
self.logger.error(f"Error adding peer: {e}")
return False, f"Error adding peer: {str(e)}"
def remove_peer(self, name: str) -> tuple[bool, str]:
"""Remove a peer"""
try:
for i, p in enumerate(self._peers):
if p['name'] == name:
del self._peers[i]
self.logger.info(f"Removed peer: {name}")
return True, "Peer removed successfully"
return False, "Peer not found"
except Exception as e:
self.logger.error(f"Error removing peer {name}: {e}")
return False, f"Error removing peer: {str(e)}"
def get_services_status(self) -> Dict[str, Any]:
"""Get status of all services"""
try:
return {
"network": self.network_manager.get_status(),
"wireguard": self.wireguard_manager.get_status(),
"email": self.email_manager.get_status(),
"calendar": self.calendar_manager.get_status(),
"files": self.file_manager.get_status(),
"routing": self.routing_manager.get_status(),
"vault": self.vault_manager.get_status(),
"container": self.container_manager.get_status()
}
except Exception as e:
self.logger.error(f"Error getting services status: {e}")
return {}
def get_uptime(self) -> int:
"""Get cell uptime"""
return self._uptime
def restart_all_services(self) -> Dict[str, Any]:
"""Restart all services"""
try:
results = {}
# Restart each service manager
services = {
'network': self.network_manager,
'wireguard': self.wireguard_manager,
'email': self.email_manager,
'calendar': self.calendar_manager,
'files': self.file_manager,
'routing': self.routing_manager,
'vault': self.vault_manager,
'container': self.container_manager
}
for service_name, service_manager in services.items():
try:
success = service_manager.restart_service()
results[service_name] = {
'success': success,
'message': f"Service {'restarted' if success else 'failed to restart'}"
}
except Exception as e:
results[service_name] = {
'success': False,
'message': f"Error restarting service: {str(e)}"
}
return {
'success': any(r.get('success', False) for r in results.values()),
'results': results,
'timestamp': datetime.utcnow().isoformat()
}
except Exception as e:
return self.handle_error(e, "restart_all_services")
def get_health_summary(self) -> Dict[str, Any]:
"""Get comprehensive health summary"""
try:
services_status = self.get_services_status()
connectivity = self.test_connectivity()
# Calculate health metrics
healthy_services = sum(1 for status in services_status.values() if status.get('running', False))
total_services = len(services_status)
health_percentage = (healthy_services / total_services * 100) if total_services > 0 else 0
return {
'overall_health': 'healthy' if health_percentage >= 80 else 'degraded' if health_percentage >= 50 else 'unhealthy',
'health_percentage': round(health_percentage, 2),
'healthy_services': healthy_services,
'total_services': total_services,
'services_status': services_status,
'connectivity': connectivity,
'uptime': self._uptime,
'peers_count': len(self._peers),
'timestamp': datetime.utcnow().isoformat()
}
except Exception as e:
return self.handle_error(e, "get_health_summary")