from flask import Blueprint, jsonify, request, abort from flask_login import login_required from app.core.models import Subnet, Server, App from app.core.extensions import db from app.scripts.ip_scanner import scan bp = Blueprint('api', __name__, url_prefix='/api') @bp.route('/subnets', methods=['GET']) @login_required def get_subnets(): """Get all subnets""" subnets = Subnet.query.all() result = [] for subnet in subnets: result.append({ 'id': subnet.id, 'cidr': subnet.cidr, 'location': subnet.location, 'used_ips': subnet.used_ips, 'auto_scan': subnet.auto_scan, 'created_at': subnet.created_at.strftime('%Y-%m-%d %H:%M:%S') }) return jsonify({'subnets': result}) @bp.route('/subnets/', methods=['GET']) @login_required def get_subnet(subnet_id): """Get details for a specific subnet""" subnet = Subnet.query.get_or_404(subnet_id) servers = [] for server in Server.query.filter_by(subnet_id=subnet_id).all(): servers.append({ 'id': server.id, 'hostname': server.hostname, 'ip_address': server.ip_address, 'created_at': server.created_at.strftime('%Y-%m-%d %H:%M:%S') }) result = { 'id': subnet.id, 'cidr': subnet.cidr, 'location': subnet.location, 'used_ips': subnet.used_ips, 'auto_scan': subnet.auto_scan, 'created_at': subnet.created_at.strftime('%Y-%m-%d %H:%M:%S'), 'servers': servers } return jsonify(result) @bp.route('/subnets//scan', methods=['POST']) @login_required def api_subnet_scan(subnet_id): """Scan a subnet via API""" subnet = Subnet.query.get_or_404(subnet_id) try: results = scan(subnet.cidr, save_results=True) return jsonify({ 'success': True, 'subnet': subnet.cidr, 'hosts_found': len(results), 'results': results }) except Exception as e: return jsonify({ 'success': False, 'message': f'Error scanning subnet: {str(e)}' }), 500 @bp.route('/servers', methods=['GET']) @login_required def get_servers(): """Get all servers""" servers = Server.query.all() result = [] for server in servers: result.append({ 'id': server.id, 'hostname': server.hostname, 'ip_address': server.ip_address, 'subnet_id': server.subnet_id, 'created_at': server.created_at.strftime('%Y-%m-%d %H:%M:%S') }) return jsonify({'servers': result}) @bp.route('/servers/', methods=['GET']) @login_required def get_server(server_id): """Get details for a specific server""" server = Server.query.get_or_404(server_id) apps = [] for app in App.query.filter_by(server_id=server_id).all(): apps.append({ 'id': app.id, 'name': app.name, 'created_at': app.created_at.strftime('%Y-%m-%d %H:%M:%S') }) result = { 'id': server.id, 'hostname': server.hostname, 'ip_address': server.ip_address, 'subnet_id': server.subnet_id, 'documentation': server.documentation, 'created_at': server.created_at.strftime('%Y-%m-%d %H:%M:%S'), 'ports': server.ports, 'apps': apps } return jsonify(result) @bp.route('/apps', methods=['GET']) @login_required def get_apps(): """Get all applications""" apps = App.query.all() result = [] for app in apps: result.append({ 'id': app.id, 'name': app.name, 'server_id': app.server_id, 'created_at': app.created_at.strftime('%Y-%m-%d %H:%M:%S') }) return jsonify({'apps': result}) @bp.route('/apps/', methods=['GET']) @login_required def get_app(app_id): """Get details for a specific application""" app = App.query.get_or_404(app_id) result = { 'id': app.id, 'name': app.name, 'server_id': app.server_id, 'documentation': app.documentation, 'created_at': app.created_at.strftime('%Y-%m-%d %H:%M:%S'), 'ports': app.ports } return jsonify(result) @bp.route('/status', methods=['GET']) def status(): return jsonify({'status': 'OK'}) @bp.route('/markdown-preview', methods=['POST']) def markdown_preview(): data = request.json md_content = data.get('markdown', '') html = markdown.markdown(md_content) return jsonify({'html': html}) @bp.route('/ports/suggest', methods=['GET']) def suggest_ports(): app_type = request.args.get('type', '').lower() # Common port suggestions based on app type suggestions = { 'web': [ {'port': 80, 'type': 'tcp', 'desc': 'HTTP'}, {'port': 443, 'type': 'tcp', 'desc': 'HTTPS'} ], 'database': [ {'port': 3306, 'type': 'tcp', 'desc': 'MySQL'}, {'port': 5432, 'type': 'tcp', 'desc': 'PostgreSQL'}, {'port': 1521, 'type': 'tcp', 'desc': 'Oracle'} ], 'mail': [ {'port': 25, 'type': 'tcp', 'desc': 'SMTP'}, {'port': 143, 'type': 'tcp', 'desc': 'IMAP'}, {'port': 110, 'type': 'tcp', 'desc': 'POP3'} ], 'file': [ {'port': 21, 'type': 'tcp', 'desc': 'FTP'}, {'port': 22, 'type': 'tcp', 'desc': 'SFTP/SSH'}, {'port': 445, 'type': 'tcp', 'desc': 'SMB'} ] } if app_type in suggestions: return jsonify(suggestions[app_type]) # Default suggestions return jsonify([ {'port': 80, 'type': 'tcp', 'desc': 'HTTP'}, {'port': 22, 'type': 'tcp', 'desc': 'SSH'} ])