TNT / routes /isp_api.py
Fred808's picture
Upload 48 files
50d86e3 verified
"""
ISP API Routes
Flask routes for the Virtual ISP Stack API endpoints
"""
from flask import Blueprint, jsonify, request, Response
from flask_cors import cross_origin
import json
import time
from typing import Dict, Any
# Import core modules
from core.dhcp_server import DHCPServer
from core.nat_engine import NATEngine
from core.firewall import FirewallEngine, FirewallRule, FirewallRuleBuilder, FirewallAction, FirewallDirection
from core.tcp_engine import TCPEngine
from core.virtual_router import VirtualRouter
from core.socket_translator import SocketTranslator
from core.packet_bridge import PacketBridge
from core.session_tracker import SessionTracker, SessionType, SessionState
from core.logger import VirtualISPLogger, LogLevel, LogCategory, LogFilter
from core.openvpn_manager import OpenVPNManager, initialize_openvpn_manager, get_openvpn_manager
# Create blueprint
isp_api = Blueprint('isp_api', __name__)
# Global instances (will be initialized by main app)
dhcp_server: DHCPServer = None
nat_engine: NATEngine = None
firewall_engine: FirewallEngine = None
tcp_engine: TCPEngine = None
virtual_router: VirtualRouter = None
socket_translator: SocketTranslator = None
packet_bridge: PacketBridge = None
session_tracker: SessionTracker = None
logger: VirtualISPLogger = None
openvpn_manager: OpenVPNManager = None
def init_engines(config: Dict[str, Any]):
"""Initialize all engines with configuration"""
global dhcp_server, nat_engine, firewall_engine, tcp_engine
global virtual_router, socket_translator, packet_bridge, session_tracker, logger, openvpn_manager
# Initialize logger first
logger = VirtualISPLogger(config.get('logger', {}))
logger.start()
# Initialize core engines
dhcp_server = DHCPServer(config.get('dhcp', {}))
nat_engine = NATEngine(config.get('nat', {}))
firewall_engine = FirewallEngine(config.get('firewall', {}))
tcp_engine = TCPEngine(config.get('tcp', {}))
virtual_router = VirtualRouter(config.get('router', {}))
socket_translator = SocketTranslator(config.get('socket_translator', {}))
packet_bridge = PacketBridge(config.get('packet_bridge', {}))
session_tracker = SessionTracker(config.get('session_tracker', {}))
# Initialize OpenVPN manager
openvpn_manager = initialize_openvpn_manager(config.get('openvpn', {}))
openvpn_manager.set_isp_components(
dhcp_server=dhcp_server,
nat_engine=nat_engine,
firewall=firewall_engine,
router=virtual_router
)
# Start engines
dhcp_server.start()
nat_engine.start()
tcp_engine.start()
socket_translator.start()
session_tracker.start()
packet_bridge.start()
logger.info(LogCategory.SYSTEM, 'api', 'All engines initialized and started')
# Configuration endpoints
@isp_api.route('/config', methods=['GET'])
@cross_origin()
def get_config():
"""Get current system configuration"""
try:
config = {
'dhcp': {
'network': '10.0.0.0/24',
'range_start': '10.0.0.10',
'range_end': '10.0.0.100',
'lease_time': 3600,
'gateway': '10.0.0.1',
'dns_servers': ['8.8.8.8', '8.8.4.4']
},
'nat': {
'port_range_start': 10000,
'port_range_end': 65535,
'session_timeout': 300
},
'firewall': {
'default_policy': 'ACCEPT',
'log_blocked': True
},
'tcp': {
'initial_window': 65535,
'max_retries': 3,
'timeout': 30
}
}
return jsonify({
'status': 'success',
'config': config
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/config', methods=['POST'])
@cross_origin()
def update_config():
"""Update system configuration"""
try:
config_data = request.get_json()
# Here you would update the actual configuration
# For now, just return success
if logger:
logger.info(LogCategory.SYSTEM, 'api', 'Configuration updated', metadata=config_data)
return jsonify({
'status': 'success',
'message': 'Configuration updated successfully'
})
except Exception as e:
if logger:
logger.error(LogCategory.SYSTEM, 'api', f'Configuration update failed: {str(e)}')
return jsonify({
'status': 'error',
'message': str(e)
}), 500
# DHCP endpoints
@isp_api.route('/dhcp/leases', methods=['GET'])
@cross_origin()
def get_dhcp_leases():
"""Get DHCP lease table"""
try:
if not dhcp_server:
return jsonify({'status': 'error', 'message': 'DHCP server not initialized'}), 500
leases = dhcp_server.get_leases()
return jsonify({
'status': 'success',
'leases': leases,
'count': len(leases)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/dhcp/leases/<mac_address>', methods=['DELETE'])
@cross_origin()
def release_dhcp_lease(mac_address):
"""Release DHCP lease"""
try:
if not dhcp_server:
return jsonify({'status': 'error', 'message': 'DHCP server not initialized'}), 500
success = dhcp_server.release_lease(mac_address)
if success:
if logger:
logger.info(LogCategory.DHCP, 'api', f'Released DHCP lease for {mac_address}')
return jsonify({
'status': 'success',
'message': f'Lease for {mac_address} released'
})
else:
return jsonify({
'status': 'error',
'message': f'Lease for {mac_address} not found'
}), 404
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
# NAT endpoints
@isp_api.route('/nat/sessions', methods=['GET'])
@cross_origin()
def get_nat_sessions():
"""Get NAT session table"""
try:
if not nat_engine:
return jsonify({'status': 'error', 'message': 'NAT engine not initialized'}), 500
sessions = nat_engine.get_sessions()
return jsonify({
'status': 'success',
'sessions': sessions,
'count': len(sessions)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/nat/stats', methods=['GET'])
@cross_origin()
def get_nat_stats():
"""Get NAT statistics"""
try:
if not nat_engine:
return jsonify({'status': 'error', 'message': 'NAT engine not initialized'}), 500
stats = nat_engine.get_stats()
return jsonify({
'status': 'success',
'stats': stats
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
# Firewall endpoints
@isp_api.route('/firewall/rules', methods=['GET'])
@cross_origin()
def get_firewall_rules():
"""Get firewall rules"""
try:
if not firewall_engine:
return jsonify({'status': 'error', 'message': 'Firewall engine not initialized'}), 500
rules = firewall_engine.get_rules()
return jsonify({
'status': 'success',
'rules': rules,
'count': len(rules)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/firewall/rules', methods=['POST'])
@cross_origin()
def add_firewall_rule():
"""Add firewall rule"""
try:
if not firewall_engine:
return jsonify({'status': 'error', 'message': 'Firewall engine not initialized'}), 500
rule_data = request.get_json()
# Build rule using builder
builder = FirewallRuleBuilder(rule_data['rule_id'])
builder.set_priority(rule_data.get('priority', 100))
builder.set_action(rule_data['action'])
builder.set_direction(rule_data.get('direction', 'BOTH'))
if 'source_ip' in rule_data:
builder.set_source_ip(rule_data['source_ip'])
if 'dest_ip' in rule_data:
builder.set_dest_ip(rule_data['dest_ip'])
if 'source_port' in rule_data:
builder.set_source_port(rule_data['source_port'])
if 'dest_port' in rule_data:
builder.set_dest_port(rule_data['dest_port'])
if 'protocol' in rule_data:
builder.set_protocol(rule_data['protocol'])
if 'description' in rule_data:
builder.set_description(rule_data['description'])
rule = builder.build()
success = firewall_engine.add_rule(rule)
if success:
if logger:
logger.info(LogCategory.FIREWALL, 'api', f'Added firewall rule: {rule.rule_id}')
return jsonify({
'status': 'success',
'message': f'Rule {rule.rule_id} added successfully'
})
else:
return jsonify({
'status': 'error',
'message': f'Rule {rule.rule_id} already exists'
}), 400
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/firewall/rules/<rule_id>', methods=['DELETE'])
@cross_origin()
def delete_firewall_rule(rule_id):
"""Delete firewall rule"""
try:
if not firewall_engine:
return jsonify({'status': 'error', 'message': 'Firewall engine not initialized'}), 500
success = firewall_engine.remove_rule(rule_id)
if success:
if logger:
logger.info(LogCategory.FIREWALL, 'api', f'Deleted firewall rule: {rule_id}')
return jsonify({
'status': 'success',
'message': f'Rule {rule_id} deleted successfully'
})
else:
return jsonify({
'status': 'error',
'message': f'Rule {rule_id} not found'
}), 404
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/firewall/logs', methods=['GET'])
@cross_origin()
def get_firewall_logs():
"""Get firewall logs"""
try:
if not firewall_engine:
return jsonify({'status': 'error', 'message': 'Firewall engine not initialized'}), 500
limit = request.args.get('limit', 100, type=int)
filter_action = request.args.get('action')
logs = firewall_engine.get_logs(limit=limit, filter_action=filter_action)
return jsonify({
'status': 'success',
'logs': logs,
'count': len(logs)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/firewall/stats', methods=['GET'])
@cross_origin()
def get_firewall_stats():
"""Get firewall statistics"""
try:
if not firewall_engine:
return jsonify({'status': 'error', 'message': 'Firewall engine not initialized'}), 500
stats = firewall_engine.get_stats()
return jsonify({
'status': 'success',
'stats': stats
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
# TCP connections endpoints
@isp_api.route('/tcp/connections', methods=['GET'])
@cross_origin()
def get_tcp_connections():
"""Get TCP connections"""
try:
if not tcp_engine:
return jsonify({'status': 'error', 'message': 'TCP engine not initialized'}), 500
connections = tcp_engine.get_connections()
return jsonify({
'status': 'success',
'connections': connections,
'count': len(connections)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
# Router endpoints
@isp_api.route('/router/routes', methods=['GET'])
@cross_origin()
def get_routing_table():
"""Get routing table"""
try:
if not virtual_router:
return jsonify({'status': 'error', 'message': 'Virtual router not initialized'}), 500
routes = virtual_router.get_routing_table()
return jsonify({
'status': 'success',
'routes': routes,
'count': len(routes)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/router/interfaces', methods=['GET'])
@cross_origin()
def get_router_interfaces():
"""Get router interfaces"""
try:
if not virtual_router:
return jsonify({'status': 'error', 'message': 'Virtual router not initialized'}), 500
interfaces = virtual_router.get_interfaces()
return jsonify({
'status': 'success',
'interfaces': interfaces,
'count': len(interfaces)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/router/arp', methods=['GET'])
@cross_origin()
def get_arp_table():
"""Get ARP table"""
try:
if not virtual_router:
return jsonify({'status': 'error', 'message': 'Virtual router not initialized'}), 500
arp_table = virtual_router.get_arp_table()
return jsonify({
'status': 'success',
'arp_table': arp_table,
'count': len(arp_table)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/router/stats', methods=['GET'])
@cross_origin()
def get_router_stats():
"""Get router statistics"""
try:
if not virtual_router:
return jsonify({'status': 'error', 'message': 'Virtual router not initialized'}), 500
stats = virtual_router.get_stats()
return jsonify({
'status': 'success',
'stats': stats
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
# Bridge endpoints
@isp_api.route('/bridge/clients', methods=['GET'])
@cross_origin()
def get_bridge_clients():
"""Get bridge clients"""
try:
if not packet_bridge:
return jsonify({'status': 'error', 'message': 'Packet bridge not initialized'}), 500
clients = packet_bridge.get_clients()
return jsonify({
'status': 'success',
'clients': clients,
'count': len(clients)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/bridge/stats', methods=['GET'])
@cross_origin()
def get_bridge_stats():
"""Get bridge statistics"""
try:
if not packet_bridge:
return jsonify({'status': 'error', 'message': 'Packet bridge not initialized'}), 500
stats = packet_bridge.get_stats()
return jsonify({
'status': 'success',
'stats': stats
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
# Session tracking endpoints
@isp_api.route('/sessions', methods=['GET'])
@cross_origin()
def get_sessions():
"""Get sessions"""
try:
if not session_tracker:
return jsonify({'status': 'error', 'message': 'Session tracker not initialized'}), 500
limit = request.args.get('limit', 100, type=int)
offset = request.args.get('offset', 0, type=int)
sessions = session_tracker.get_sessions(limit=limit, offset=offset)
return jsonify({
'status': 'success',
'sessions': sessions,
'count': len(sessions)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/sessions/summary', methods=['GET'])
@cross_origin()
def get_session_summary():
"""Get session summary"""
try:
if not session_tracker:
return jsonify({'status': 'error', 'message': 'Session tracker not initialized'}), 500
summary = session_tracker.get_session_summary()
return jsonify({
'status': 'success',
'summary': summary
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
# Logging endpoints
@isp_api.route('/logs', methods=['GET'])
@cross_origin()
def get_logs():
"""Get system logs"""
try:
if not logger:
return jsonify({'status': 'error', 'message': 'Logger not initialized'}), 500
limit = request.args.get('limit', 100, type=int)
offset = request.args.get('offset', 0, type=int)
level = request.args.get('level')
category = request.args.get('category')
search = request.args.get('search')
if search:
logs = logger.search_logs(search, limit=limit)
else:
log_filter = LogFilter()
if level:
log_filter.level_filter = LogLevel(level.upper())
if category:
log_filter.category_filter = LogCategory(category.upper())
logs = logger.get_logs(limit=limit, offset=offset, log_filter=log_filter)
return jsonify({
'status': 'success',
'logs': logs,
'count': len(logs)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/logs/errors', methods=['GET'])
@cross_origin()
def get_error_logs():
"""Get recent error logs"""
try:
if not logger:
return jsonify({'status': 'error', 'message': 'Logger not initialized'}), 500
limit = request.args.get('limit', 50, type=int)
errors = logger.get_recent_errors(limit=limit)
return jsonify({
'status': 'success',
'errors': errors,
'count': len(errors)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
# System status endpoints
@isp_api.route('/status', methods=['GET'])
@cross_origin()
def get_system_status():
"""Get overall system status"""
try:
status = {
'timestamp': time.time(),
'uptime': time.time() - (time.time() - 3600), # Placeholder
'components': {
'dhcp_server': dhcp_server is not None and dhcp_server.running,
'nat_engine': nat_engine is not None and nat_engine.running,
'firewall_engine': firewall_engine is not None,
'tcp_engine': tcp_engine is not None and tcp_engine.running,
'virtual_router': virtual_router is not None,
'socket_translator': socket_translator is not None and socket_translator.running,
'packet_bridge': packet_bridge is not None and packet_bridge.running,
'session_tracker': session_tracker is not None and session_tracker.running,
'logger': logger is not None and logger.running
},
'stats': {}
}
# Collect stats from each component
if dhcp_server:
status['stats']['dhcp_leases'] = len(dhcp_server.get_leases())
if nat_engine:
nat_stats = nat_engine.get_stats()
status['stats']['nat_sessions'] = nat_stats.get('active_sessions', 0)
if firewall_engine:
fw_stats = firewall_engine.get_stats()
status['stats']['firewall_rules'] = fw_stats.get('total_rules', 0)
if tcp_engine:
tcp_connections = tcp_engine.get_connections()
status['stats']['tcp_connections'] = len(tcp_connections)
if packet_bridge:
bridge_stats = packet_bridge.get_stats()
status['stats']['bridge_clients'] = bridge_stats.get('active_clients', 0)
if session_tracker:
session_stats = session_tracker.get_stats()
status['stats']['total_sessions'] = session_stats.get('active_sessions', 0)
return jsonify({
'status': 'success',
'system_status': status
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/stats', methods=['GET'])
@cross_origin()
def get_system_stats():
"""Get comprehensive system statistics"""
try:
stats = {
'timestamp': time.time(),
'dhcp': dhcp_server.get_leases() if dhcp_server else {},
'nat': nat_engine.get_stats() if nat_engine else {},
'firewall': firewall_engine.get_stats() if firewall_engine else {},
'router': virtual_router.get_stats() if virtual_router else {},
'bridge': packet_bridge.get_stats() if packet_bridge else {},
'sessions': session_tracker.get_stats() if session_tracker else {},
'logger': logger.get_stats() if logger else {}
}
return jsonify({
'status': 'success',
'stats': stats
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
packet_bridge.start()
# OpenVPN endpoints
@isp_api.route('/openvpn/status', methods=['GET'])
@cross_origin()
def get_openvpn_status():
"""Get OpenVPN server status"""
try:
if not openvpn_manager:
return jsonify({
'status': 'error',
'message': 'OpenVPN manager not initialized'
}), 500
status = openvpn_manager.get_server_status()
return jsonify({
'status': 'success',
'openvpn_status': {
'is_running': status.is_running,
'connected_clients': status.connected_clients,
'total_bytes_received': status.total_bytes_received,
'total_bytes_sent': status.total_bytes_sent,
'uptime': status.uptime,
'server_ip': status.server_ip,
'server_port': status.server_port
}
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/openvpn/start', methods=['POST'])
@cross_origin()
def start_openvpn_server():
"""Start OpenVPN server"""
try:
if not openvpn_manager:
return jsonify({
'status': 'error',
'message': 'OpenVPN manager not initialized'
}), 500
success = openvpn_manager.start_server()
if success:
return jsonify({
'status': 'success',
'message': 'OpenVPN server started successfully'
})
else:
return jsonify({
'status': 'error',
'message': 'Failed to start OpenVPN server'
}), 500
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/openvpn/stop', methods=['POST'])
@cross_origin()
def stop_openvpn_server():
"""Stop OpenVPN server"""
try:
if not openvpn_manager:
return jsonify({
'status': 'error',
'message': 'OpenVPN manager not initialized'
}), 500
success = openvpn_manager.stop_server()
if success:
return jsonify({
'status': 'success',
'message': 'OpenVPN server stopped successfully'
})
else:
return jsonify({
'status': 'error',
'message': 'Failed to stop OpenVPN server'
}), 500
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/openvpn/clients', methods=['GET'])
@cross_origin()
def get_openvpn_clients():
"""Get connected OpenVPN clients"""
try:
if not openvpn_manager:
return jsonify({
'status': 'error',
'message': 'OpenVPN manager not initialized'
}), 500
clients = openvpn_manager.get_connected_clients()
return jsonify({
'status': 'success',
'clients': clients
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/openvpn/clients/<client_id>/disconnect', methods=['POST'])
@cross_origin()
def disconnect_openvpn_client(client_id):
"""Disconnect a specific OpenVPN client"""
try:
if not openvpn_manager:
return jsonify({
'status': 'error',
'message': 'OpenVPN manager not initialized'
}), 500
success = openvpn_manager.disconnect_client(client_id)
if success:
return jsonify({
'status': 'success',
'message': f'Client {client_id} disconnected successfully'
})
else:
return jsonify({
'status': 'error',
'message': f'Failed to disconnect client {client_id}'
}), 500
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/openvpn/config/<client_name>', methods=['GET'])
@cross_origin()
def get_client_config(client_name):
"""Generate client configuration file"""
try:
if not openvpn_manager:
return jsonify({
'status': 'error',
'message': 'OpenVPN manager not initialized'
}), 500
# Get server IP from request or use default
server_ip = request.args.get('server_ip', '127.0.0.1')
config = openvpn_manager.generate_client_config(client_name, server_ip)
if config:
return Response(
config,
mimetype='text/plain',
headers={'Content-Disposition': f'attachment; filename={client_name}.ovpn'}
)
else:
return jsonify({
'status': 'error',
'message': 'Failed to generate client configuration'
}), 500
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/openvpn/stats', methods=['GET'])
@cross_origin()
def get_openvpn_stats():
"""Get comprehensive OpenVPN statistics"""
try:
if not openvpn_manager:
return jsonify({
'status': 'error',
'message': 'OpenVPN manager not initialized'
}), 500
stats = openvpn_manager.get_statistics()
return jsonify({
'status': 'success',
'openvpn_stats': stats
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/openvpn/configs', methods=['GET'])
@cross_origin()
def list_client_configs():
"""List all stored client configurations"""
try:
if not openvpn_manager:
return jsonify({
'status': 'error',
'message': 'OpenVPN manager not initialized'
}), 500
configs = openvpn_manager.list_client_configs()
return jsonify({
'status': 'success',
'configs': configs,
'count': len(configs)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/openvpn/configs/<client_name>', methods=['GET'])
@cross_origin()
def get_stored_client_config(client_name):
"""Get stored client configuration"""
try:
if not openvpn_manager:
return jsonify({
'status': 'error',
'message': 'OpenVPN manager not initialized'
}), 500
config_content = openvpn_manager.load_client_config(client_name)
if config_content:
return Response(
config_content,
mimetype='text/plain',
headers={'Content-Disposition': f'attachment; filename={client_name}.ovpn'}
)
else:
return jsonify({
'status': 'error',
'message': f'Configuration for {client_name} not found'
}), 404
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/openvpn/configs/<client_name>', methods=['DELETE'])
@cross_origin()
def delete_stored_client_config(client_name):
"""Delete stored client configuration"""
try:
if not openvpn_manager:
return jsonify({
'status': 'error',
'message': 'OpenVPN manager not initialized'
}), 500
success = openvpn_manager.delete_client_config(client_name)
if success:
return jsonify({
'status': 'success',
'message': f'Configuration for {client_name} deleted successfully'
})
else:
return jsonify({
'status': 'error',
'message': f'Configuration for {client_name} not found'
}), 404
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
@isp_api.route('/openvpn/configs/<client_name>/generate', methods=['POST'])
@cross_origin()
def generate_and_save_client_config(client_name):
"""Generate and save client configuration"""
try:
if not openvpn_manager:
return jsonify({
'status': 'error',
'message': 'OpenVPN manager not initialized'
}), 500
# Get server IP from request or use default
server_ip = request.args.get('server_ip', '127.0.0.1')
config_content = openvpn_manager.generate_and_save_client_config(client_name, server_ip)
if config_content:
return jsonify({
'status': 'success',
'message': f'Configuration for {client_name} generated and saved successfully'
})
else:
return jsonify({
'status': 'error',
'message': f'Failed to generate configuration for {client_name}'
}), 500
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500