303 lines
No EOL
9.6 KiB
Python
303 lines
No EOL
9.6 KiB
Python
from flask import Blueprint, render_template, redirect, url_for, request, flash, jsonify
|
|
from flask_login import login_required, current_user
|
|
import markdown
|
|
from app.core.models import Server, App, Subnet
|
|
from app.core.extensions import db, limiter
|
|
from datetime import datetime
|
|
|
|
bp = Blueprint('dashboard', __name__, url_prefix='/dashboard')
|
|
|
|
@bp.route('/')
|
|
@login_required
|
|
def dashboard_home():
|
|
"""Main dashboard view showing server statistics"""
|
|
server_count = Server.query.count()
|
|
app_count = App.query.count()
|
|
subnet_count = Subnet.query.count()
|
|
|
|
# Get latest added servers
|
|
latest_servers = Server.query.order_by(Server.created_at.desc()).limit(5).all()
|
|
|
|
# Get subnets with usage stats
|
|
subnets = Subnet.query.all()
|
|
for subnet in subnets:
|
|
subnet.usage_percent = subnet.used_ips / 254 * 100 if subnet.cidr.endswith('/24') else 0
|
|
|
|
return render_template(
|
|
'dashboard/index.html',
|
|
title='Dashboard',
|
|
server_count=server_count,
|
|
app_count=app_count,
|
|
subnet_count=subnet_count,
|
|
latest_servers=latest_servers,
|
|
subnets=subnets,
|
|
now=datetime.now()
|
|
)
|
|
|
|
@bp.route('/servers')
|
|
@login_required
|
|
def server_list():
|
|
"""List all servers"""
|
|
servers = Server.query.order_by(Server.hostname).all()
|
|
|
|
return render_template(
|
|
'dashboard/server_list.html',
|
|
title='Servers',
|
|
servers=servers,
|
|
now=datetime.now()
|
|
)
|
|
|
|
@bp.route('/server/<int:server_id>')
|
|
@login_required
|
|
def server_view(server_id):
|
|
"""View server details"""
|
|
server = Server.query.get_or_404(server_id)
|
|
apps = App.query.filter_by(server_id=server_id).all()
|
|
|
|
return render_template(
|
|
'dashboard/server_view.html',
|
|
title=f'Server - {server.hostname}',
|
|
server=server,
|
|
apps=apps,
|
|
markdown=markdown.markdown,
|
|
now=datetime.now()
|
|
)
|
|
|
|
@bp.route('/server/new', methods=['GET', 'POST'])
|
|
@login_required
|
|
def server_new():
|
|
"""Create a new server"""
|
|
subnets = Subnet.query.all()
|
|
|
|
if request.method == 'POST':
|
|
hostname = request.form.get('hostname')
|
|
ip_address = request.form.get('ip_address')
|
|
subnet_id = request.form.get('subnet_id')
|
|
documentation = request.form.get('documentation', '')
|
|
|
|
# Basic validation
|
|
if not hostname or not ip_address or not subnet_id:
|
|
flash('Please fill in all required fields', 'danger')
|
|
return render_template(
|
|
'dashboard/server_form.html',
|
|
title='New Server',
|
|
subnets=subnets,
|
|
now=datetime.now()
|
|
)
|
|
|
|
# Check if hostname or IP already exists
|
|
if Server.query.filter_by(hostname=hostname).first():
|
|
flash('Hostname already exists', 'danger')
|
|
return render_template(
|
|
'dashboard/server_form.html',
|
|
title='New Server',
|
|
subnets=subnets,
|
|
now=datetime.now()
|
|
)
|
|
|
|
if Server.query.filter_by(ip_address=ip_address).first():
|
|
flash('IP address already exists', 'danger')
|
|
return render_template(
|
|
'dashboard/server_form.html',
|
|
title='New Server',
|
|
subnets=subnets,
|
|
now=datetime.now()
|
|
)
|
|
|
|
# Create new server
|
|
server = Server(
|
|
hostname=hostname,
|
|
ip_address=ip_address,
|
|
subnet_id=subnet_id,
|
|
documentation=documentation
|
|
)
|
|
|
|
db.session.add(server)
|
|
db.session.commit()
|
|
|
|
flash('Server created successfully', 'success')
|
|
return redirect(url_for('dashboard.server_view', server_id=server.id))
|
|
|
|
return render_template(
|
|
'dashboard/server_form.html',
|
|
title='New Server',
|
|
subnets=subnets,
|
|
now=datetime.now()
|
|
)
|
|
|
|
@bp.route('/server/<int:server_id>/edit', methods=['GET', 'POST'])
|
|
@login_required
|
|
def server_edit(server_id):
|
|
"""Edit an existing server"""
|
|
server = Server.query.get_or_404(server_id)
|
|
|
|
if request.method == 'POST':
|
|
hostname = request.form.get('hostname')
|
|
ip_address = request.form.get('ip_address')
|
|
subnet_id = request.form.get('subnet_id')
|
|
|
|
if not hostname or not ip_address or not subnet_id:
|
|
flash('All fields are required', 'danger')
|
|
return redirect(url_for('dashboard.server_edit', server_id=server_id))
|
|
|
|
# Check if hostname changed and already exists
|
|
if hostname != server.hostname and Server.query.filter_by(hostname=hostname).first():
|
|
flash('Hostname already exists', 'danger')
|
|
return redirect(url_for('dashboard.server_edit', server_id=server_id))
|
|
|
|
# Check if IP changed and already exists
|
|
if ip_address != server.ip_address and Server.query.filter_by(ip_address=ip_address).first():
|
|
flash('IP address already exists', 'danger')
|
|
return redirect(url_for('dashboard.server_edit', server_id=server_id))
|
|
|
|
# Update server
|
|
server.hostname = hostname
|
|
server.ip_address = ip_address
|
|
server.subnet_id = subnet_id
|
|
|
|
db.session.commit()
|
|
|
|
flash('Server updated successfully', 'success')
|
|
return redirect(url_for('dashboard.server_view', server_id=server.id))
|
|
|
|
# GET request - show form with current values
|
|
subnets = Subnet.query.all()
|
|
return render_template(
|
|
'dashboard/server_edit.html',
|
|
title=f'Edit Server - {server.hostname}',
|
|
server=server,
|
|
subnets=subnets
|
|
)
|
|
|
|
@bp.route('/server/<int:server_id>/delete', methods=['POST'])
|
|
@login_required
|
|
def server_delete(server_id):
|
|
"""Delete a server"""
|
|
server = Server.query.get_or_404(server_id)
|
|
|
|
# Delete all apps associated with this server
|
|
App.query.filter_by(server_id=server_id).delete()
|
|
|
|
# Delete the server
|
|
db.session.delete(server)
|
|
db.session.commit()
|
|
|
|
flash('Server deleted successfully', 'success')
|
|
return redirect(url_for('dashboard.dashboard_home'))
|
|
|
|
@bp.route('/app/new', methods=['GET', 'POST'])
|
|
@login_required
|
|
def app_new():
|
|
"""Create a new application"""
|
|
servers = Server.query.all()
|
|
|
|
if request.method == 'POST':
|
|
name = request.form.get('name')
|
|
server_id = request.form.get('server_id')
|
|
documentation = request.form.get('documentation', '')
|
|
|
|
# Basic validation
|
|
if not name or not server_id:
|
|
flash('Please fill in all required fields', 'danger')
|
|
return render_template(
|
|
'dashboard/app_form.html',
|
|
title='New Application',
|
|
servers=servers,
|
|
now=datetime.now()
|
|
)
|
|
|
|
app = App(
|
|
name=name,
|
|
server_id=server_id,
|
|
documentation=documentation
|
|
)
|
|
db.session.add(app)
|
|
db.session.commit()
|
|
|
|
flash('Application created successfully', 'success')
|
|
return redirect(url_for('dashboard.server_view', server_id=server_id))
|
|
|
|
return render_template(
|
|
'dashboard/app_form.html',
|
|
title='New Application',
|
|
servers=servers,
|
|
now=datetime.now()
|
|
)
|
|
|
|
@bp.route('/app/<int:app_id>', methods=['GET'])
|
|
@login_required
|
|
def app_view(app_id):
|
|
"""View a specific application"""
|
|
app = App.query.get_or_404(app_id)
|
|
server = Server.query.get(app.server_id)
|
|
|
|
return render_template(
|
|
'dashboard/app_view.html',
|
|
title=f'Application - {app.name}',
|
|
app=app,
|
|
server=server,
|
|
markdown=markdown.markdown,
|
|
now=datetime.now()
|
|
)
|
|
|
|
@bp.route('/app/<int:app_id>/edit', methods=['GET', 'POST'])
|
|
@login_required
|
|
def app_edit(app_id):
|
|
"""Edit an existing application"""
|
|
app = App.query.get_or_404(app_id)
|
|
|
|
if request.method == 'POST':
|
|
name = request.form.get('name')
|
|
server_id = request.form.get('server_id')
|
|
documentation = request.form.get('documentation', '')
|
|
|
|
# Process ports
|
|
ports = []
|
|
port_numbers = request.form.getlist('port[]')
|
|
port_types = request.form.getlist('port_type[]')
|
|
port_descs = request.form.getlist('port_desc[]')
|
|
|
|
for i in range(len(port_numbers)):
|
|
if port_numbers[i]:
|
|
port = {
|
|
'port': int(port_numbers[i]),
|
|
'type': port_types[i] if i < len(port_types) else 'tcp',
|
|
'desc': port_descs[i] if i < len(port_descs) else '',
|
|
'status': 'open'
|
|
}
|
|
ports.append(port)
|
|
|
|
# Update app
|
|
app.name = name
|
|
app.server_id = server_id
|
|
app.documentation = documentation
|
|
app.ports = ports
|
|
|
|
db.session.commit()
|
|
|
|
flash('Application updated successfully', 'success')
|
|
return redirect(url_for('dashboard.app_view', app_id=app.id))
|
|
|
|
# GET request - show form with current values
|
|
servers = Server.query.all()
|
|
|
|
return render_template(
|
|
'dashboard/app_edit.html',
|
|
title=f'Edit Application - {app.name}',
|
|
app=app,
|
|
servers=servers,
|
|
use_editor=True
|
|
)
|
|
|
|
@bp.route('/app/<int:app_id>/delete', methods=['POST'])
|
|
@login_required
|
|
def app_delete(app_id):
|
|
"""Delete an application"""
|
|
app = App.query.get_or_404(app_id)
|
|
server_id = app.server_id
|
|
|
|
db.session.delete(app)
|
|
db.session.commit()
|
|
|
|
flash('Application deleted successfully', 'success')
|
|
return redirect(url_for('dashboard.server_view', server_id=server_id)) |