185 lines
7.7 KiB
Python
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 |