batman
This commit is contained in:
commit
66f9ce3614
33 changed files with 2271 additions and 0 deletions
8
app/core/__init__.py
Normal file
8
app/core/__init__.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
"""
|
||||
Core functionality blueprint for the NetViz application.
|
||||
"""
|
||||
from flask import Blueprint
|
||||
|
||||
core_bp = Blueprint("core", __name__)
|
||||
|
||||
from app.core import routes # noqa
|
95
app/core/forms.py
Normal file
95
app/core/forms.py
Normal file
|
@ -0,0 +1,95 @@
|
|||
"""
|
||||
Forms for the core functionality of the NetViz application.
|
||||
"""
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, TextAreaField, IntegerField, SelectField, SubmitField
|
||||
from wtforms.validators import DataRequired, Length, Optional, NumberRange, ValidationError
|
||||
import ipaddress
|
||||
|
||||
|
||||
class NetworkForm(FlaskForm):
|
||||
"""Form for creating and editing networks."""
|
||||
name = StringField("Network Name", validators=[
|
||||
DataRequired(),
|
||||
Length(min=3, max=128)
|
||||
])
|
||||
description = TextAreaField("Description", validators=[Optional()])
|
||||
submit = SubmitField("Save Network")
|
||||
|
||||
|
||||
class SubnetForm(FlaskForm):
|
||||
"""Form for creating and editing subnets."""
|
||||
name = StringField("Subnet Name", validators=[
|
||||
DataRequired(),
|
||||
Length(min=3, max=128)
|
||||
])
|
||||
cidr = StringField("CIDR Notation", validators=[DataRequired()])
|
||||
vlan = IntegerField("VLAN ID", validators=[
|
||||
Optional(),
|
||||
NumberRange(min=0, max=4095)
|
||||
])
|
||||
description = TextAreaField("Description", validators=[Optional()])
|
||||
submit = SubmitField("Save Subnet")
|
||||
|
||||
def validate_cidr(self, cidr):
|
||||
"""Validate CIDR notation."""
|
||||
try:
|
||||
ipaddress.IPv4Network(cidr.data, strict=False)
|
||||
except ValueError:
|
||||
try:
|
||||
ipaddress.IPv6Network(cidr.data, strict=False)
|
||||
except ValueError:
|
||||
raise ValidationError("Invalid CIDR notation. Example formats: 192.168.1.0/24 or 2001:db8::/64")
|
||||
|
||||
|
||||
class DeviceForm(FlaskForm):
|
||||
"""Form for creating and editing devices."""
|
||||
name = StringField("Device Name", validators=[
|
||||
DataRequired(),
|
||||
Length(min=3, max=128)
|
||||
])
|
||||
ip_address = StringField("IP Address", validators=[Optional()])
|
||||
mac_address = StringField("MAC Address", validators=[Optional()])
|
||||
device_type = SelectField("Device Type", choices=[
|
||||
("server", "Server"),
|
||||
("router", "Router"),
|
||||
("switch", "Switch"),
|
||||
("firewall", "Firewall"),
|
||||
("client", "Client"),
|
||||
("other", "Other")
|
||||
])
|
||||
os = StringField("Operating System", validators=[Optional()])
|
||||
subnet_id = SelectField("Subnet", coerce=int, validators=[Optional()])
|
||||
description = TextAreaField("Description", validators=[Optional()])
|
||||
submit = SubmitField("Save Device")
|
||||
|
||||
def validate_ip_address(self, ip_address):
|
||||
"""Validate IP address format."""
|
||||
if ip_address.data:
|
||||
try:
|
||||
ipaddress.ip_address(ip_address.data)
|
||||
except ValueError:
|
||||
raise ValidationError("Invalid IP address format")
|
||||
|
||||
|
||||
class FirewallRuleForm(FlaskForm):
|
||||
"""Form for creating and editing firewall rules."""
|
||||
name = StringField("Rule Name", validators=[
|
||||
DataRequired(),
|
||||
Length(min=3, max=128)
|
||||
])
|
||||
source = StringField("Source", validators=[DataRequired()])
|
||||
destination = StringField("Destination", validators=[DataRequired()])
|
||||
protocol = SelectField("Protocol", choices=[
|
||||
("any", "Any"),
|
||||
("tcp", "TCP"),
|
||||
("udp", "UDP"),
|
||||
("icmp", "ICMP")
|
||||
])
|
||||
port_range = StringField("Port Range", validators=[Optional()])
|
||||
action = SelectField("Action", choices=[
|
||||
("allow", "Allow"),
|
||||
("deny", "Deny")
|
||||
])
|
||||
description = TextAreaField("Description", validators=[Optional()])
|
||||
submit = SubmitField("Save Rule")
|
151
app/core/routes.py
Normal file
151
app/core/routes.py
Normal file
|
@ -0,0 +1,151 @@
|
|||
"""
|
||||
Core routes for the NetViz application.
|
||||
"""
|
||||
from flask import render_template, redirect, url_for, flash, request, current_app, abort
|
||||
from flask_login import login_required, current_user
|
||||
|
||||
from app.core import core_bp
|
||||
from app.core.forms import NetworkForm, SubnetForm, DeviceForm, FirewallRuleForm
|
||||
from app.models.network import Network, Subnet, Device, FirewallRule
|
||||
from app.extensions import db
|
||||
from app.utils.visualization import generate_network_diagram
|
||||
|
||||
|
||||
@core_bp.route("/")
|
||||
def index():
|
||||
"""Landing page route."""
|
||||
if current_user.is_authenticated:
|
||||
networks = Network.query.filter_by(user_id=current_user.id).all()
|
||||
return render_template("core/dashboard.html", networks=networks)
|
||||
|
||||
return render_template("core/index.html")
|
||||
|
||||
|
||||
@core_bp.route("/dashboard")
|
||||
@login_required
|
||||
def dashboard():
|
||||
"""User dashboard route."""
|
||||
networks = Network.query.filter_by(user_id=current_user.id).all()
|
||||
return render_template("core/dashboard.html", networks=networks)
|
||||
|
||||
|
||||
# Network CRUD routes
|
||||
@core_bp.route("/networks/new", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def create_network():
|
||||
"""Create a new network."""
|
||||
form = NetworkForm()
|
||||
|
||||
if form.validate_on_submit():
|
||||
network = Network(
|
||||
name=form.name.data,
|
||||
description=form.description.data,
|
||||
user_id=current_user.id
|
||||
)
|
||||
|
||||
db.session.add(network)
|
||||
db.session.commit()
|
||||
|
||||
flash("Network created successfully", "success")
|
||||
return redirect(url_for("core.view_network", network_id=network.id))
|
||||
|
||||
return render_template("core/network_form.html", form=form, title="Create Network")
|
||||
|
||||
|
||||
@core_bp.route("/networks/<int:network_id>")
|
||||
@login_required
|
||||
def view_network(network_id):
|
||||
"""View a network and its details."""
|
||||
network = Network.query.get_or_404(network_id)
|
||||
|
||||
# Check if the user owns this network
|
||||
if network.user_id != current_user.id:
|
||||
abort(403)
|
||||
|
||||
# Generate network visualization
|
||||
diagram = generate_network_diagram(network)
|
||||
|
||||
return render_template(
|
||||
"core/network_view.html",
|
||||
network=network,
|
||||
diagram=diagram,
|
||||
subnets=network.subnets,
|
||||
devices=network.devices,
|
||||
firewall_rules=network.firewall_rules
|
||||
)
|
||||
|
||||
|
||||
@core_bp.route("/networks/<int:network_id>/edit", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def edit_network(network_id):
|
||||
"""Edit an existing network."""
|
||||
network = Network.query.get_or_404(network_id)
|
||||
|
||||
# Check if the user owns this network
|
||||
if network.user_id != current_user.id:
|
||||
abort(403)
|
||||
|
||||
form = NetworkForm(obj=network)
|
||||
|
||||
if form.validate_on_submit():
|
||||
network.name = form.name.data
|
||||
network.description = form.description.data
|
||||
|
||||
db.session.commit()
|
||||
|
||||
flash("Network updated successfully", "success")
|
||||
return redirect(url_for("core.view_network", network_id=network.id))
|
||||
|
||||
return render_template("core/network_form.html", form=form, title="Edit Network", network=network)
|
||||
|
||||
|
||||
@core_bp.route("/networks/<int:network_id>/delete", methods=["POST"])
|
||||
@login_required
|
||||
def delete_network(network_id):
|
||||
"""Delete a network."""
|
||||
network = Network.query.get_or_404(network_id)
|
||||
|
||||
# Check if the user owns this network
|
||||
if network.user_id != current_user.id:
|
||||
abort(403)
|
||||
|
||||
db.session.delete(network)
|
||||
db.session.commit()
|
||||
|
||||
flash("Network deleted successfully", "success")
|
||||
return redirect(url_for("core.dashboard"))
|
||||
|
||||
|
||||
# Subnet routes
|
||||
@core_bp.route("/networks/<int:network_id>/subnets/new", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def create_subnet(network_id):
|
||||
"""Create a new subnet within a network."""
|
||||
network = Network.query.get_or_404(network_id)
|
||||
|
||||
# Check if the user owns this network
|
||||
if network.user_id != current_user.id:
|
||||
abort(403)
|
||||
|
||||
form = SubnetForm()
|
||||
|
||||
if form.validate_on_submit():
|
||||
subnet = Subnet(
|
||||
name=form.name.data,
|
||||
cidr=form.cidr.data,
|
||||
vlan=form.vlan.data,
|
||||
description=form.description.data,
|
||||
network_id=network.id
|
||||
)
|
||||
|
||||
db.session.add(subnet)
|
||||
db.session.commit()
|
||||
|
||||
flash("Subnet created successfully", "success")
|
||||
return redirect(url_for("core.view_network", network_id=network.id))
|
||||
|
||||
return render_template("core/subnet_form.html", form=form, title="Create Subnet", network=network)
|
||||
|
||||
|
||||
# Similar routes for devices, firewall rules, etc.
|
||||
# For brevity, not all routes are shown here but would follow the same pattern
|
Loading…
Add table
Add a link
Reference in a new issue