199 lines
No EOL
5.7 KiB
Python
199 lines
No EOL
5.7 KiB
Python
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/<int:subnet_id>', 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/<int:subnet_id>/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/<int:server_id>', 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/<int:app_id>', 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'}
|
|
]) |