Projektarbeit-MYP/backend/network_config.py

185 lines
7.7 KiB
Python

import os
import json
import socket
import subprocess
import platform
import netifaces
import requests
from datetime import datetime
import logging
class NetworkConfig:
"""Verwaltet die Netzwerkkonfiguration für das MYP-System."""
CONFIG_FILE = 'instance/network_config.json'
DEFAULT_CONFIG = {
'backend_hostname': '192.168.0.5',
'backend_port': 5000,
'frontend_hostname': '192.168.0.106',
'frontend_port': 3000
}
def __init__(self, app=None):
"""Initialisierung der Netzwerkkonfiguration."""
self.logger = logging.getLogger('myp.network')
self.config = self.DEFAULT_CONFIG.copy()
self.last_check = None
self.backend_status = "Nicht überprüft"
self.frontend_status = "Nicht überprüft"
# Stelle sicher, dass das Verzeichnis existiert
os.makedirs(os.path.dirname(self.CONFIG_FILE), exist_ok=True)
# Lade gespeicherte Konfiguration, falls vorhanden
self.load_config()
if app:
self.init_app(app)
def init_app(self, app):
"""Initialisiert die Anwendung mit dieser Konfiguration."""
app.network_config = self
# Registriere Route für Netzwerkkonfiguration
@app.route('/admin/network-config', methods=['GET', 'POST'])
def network_config():
from flask import request, render_template, flash, redirect, url_for
# Prüfe aktuelle Status
self.check_connection_statuses()
if request.method == 'POST':
# Aktualisiere Konfiguration
self.config['backend_hostname'] = request.form.get('backend_hostname', self.DEFAULT_CONFIG['backend_hostname'])
self.config['backend_port'] = int(request.form.get('backend_port', self.DEFAULT_CONFIG['backend_port']))
self.config['frontend_hostname'] = request.form.get('frontend_hostname', self.DEFAULT_CONFIG['frontend_hostname'])
self.config['frontend_port'] = int(request.form.get('frontend_port', self.DEFAULT_CONFIG['frontend_port']))
# Speichere Konfiguration
self.save_config()
# Teste die neue Konfiguration
self.check_connection_statuses()
flash('Netzwerkkonfiguration erfolgreich gespeichert!', 'success')
return redirect(url_for('network_config'))
# Ermittle Netzwerkschnittstellen
network_interfaces = self.get_network_interfaces()
return render_template('network_config.html',
config=self.config,
backend_status=self.backend_status,
frontend_status=self.frontend_status,
last_check=self.last_check,
network_interfaces=network_interfaces,
message=request.args.get('message'),
message_type=request.args.get('message_type', 'info'))
def load_config(self):
"""Lädt die gespeicherte Konfiguration."""
try:
if os.path.exists(self.CONFIG_FILE):
with open(self.CONFIG_FILE, 'r') as f:
saved_config = json.load(f)
self.config.update(saved_config)
self.logger.info(f"Netzwerkkonfiguration geladen: {self.config}")
else:
self.logger.info(f"Keine gespeicherte Konfiguration gefunden, verwende Standardwerte: {self.config}")
except Exception as e:
self.logger.error(f"Fehler beim Laden der Netzwerkkonfiguration: {e}")
def save_config(self):
"""Speichert die aktuelle Konfiguration."""
try:
with open(self.CONFIG_FILE, 'w') as f:
json.dump(self.config, f, indent=4)
self.logger.info(f"Netzwerkkonfiguration gespeichert: {self.config}")
return True
except Exception as e:
self.logger.error(f"Fehler beim Speichern der Netzwerkkonfiguration: {e}")
return False
def get_backend_url(self):
"""Gibt die Backend-URL zurück."""
return f"http://{self.config['backend_hostname']}:{self.config['backend_port']}"
def get_frontend_url(self):
"""Gibt die Frontend-URL zurück."""
return f"http://{self.config['frontend_hostname']}:{self.config['frontend_port']}"
def check_connection_statuses(self):
"""Überprüft den Verbindungsstatus zu Backend und Frontend."""
self.last_check = datetime.now().strftime("%d.%m.%Y %H:%M:%S")
# Prüfe Backend-Verbindung
backend_url = self.get_backend_url()
try:
response = requests.get(f"{backend_url}/api/test", timeout=3)
if response.status_code == 200:
self.backend_status = "Verbunden"
else:
self.backend_status = f"Fehler: HTTP {response.status_code}"
except requests.exceptions.RequestException as e:
self.backend_status = f"Nicht erreichbar: {str(e)}"
# Prüfe Frontend-Verbindung
frontend_url = self.get_frontend_url()
try:
response = requests.get(frontend_url, timeout=3)
if response.status_code == 200:
self.frontend_status = "Verbunden"
else:
self.frontend_status = f"Fehler: HTTP {response.status_code}"
except requests.exceptions.RequestException as e:
self.frontend_status = f"Nicht erreichbar: {str(e)}"
self.logger.info(f"Verbindungsstatus - Backend: {self.backend_status}, Frontend: {self.frontend_status}")
def get_network_interfaces(self):
"""Gibt Informationen zu allen Netzwerkschnittstellen zurück."""
interfaces = []
try:
for interface in netifaces.interfaces():
if interface.startswith(('lo', 'docker', 'br-')):
continue # Ignoriere Loopback und Docker-Interfaces
addresses = []
try:
addrs = netifaces.ifaddresses(interface)
if netifaces.AF_INET in addrs:
for addr in addrs[netifaces.AF_INET]:
if 'addr' in addr:
addresses.append(addr['addr'])
except Exception as e:
self.logger.error(f"Fehler beim Ermitteln der Adresse für Interface {interface}: {e}")
if addresses:
interfaces.append({
'name': interface,
'address': ', '.join(addresses)
})
except Exception as e:
self.logger.error(f"Fehler beim Ermitteln der Netzwerkschnittstellen: {e}")
return interfaces
# Helper-Funktion zum Testen von Netzwerkverbindungen
def test_connection(host, port, timeout=2):
"""Testet eine TCP-Verbindung zu einem Host und Port."""
try:
socket.setdefaulttimeout(timeout)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.close()
return True
except Exception as e:
return False
# Helper-Funktion zum Ping eines Hosts
def ping_host(host, count=1):
"""Pingt einen Host an."""
param = '-n' if platform.system().lower() == 'windows' else '-c'
command = ['ping', param, str(count), host]
return subprocess.call(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0