mirror of
https://github.com/TakeusV1/flask_ipam.git
synced 2026-10-13 17:15:33 +02:00
11 files changed
+77
-25
No files matched your search
+2
-3
@@ -10,12 +10,11 @@ app_debug = True
|
|||||||
app_maintenance = False
|
app_maintenance = False
|
||||||
|
|
||||||
app_name = 'takeus-ipam'
|
app_name = 'takeus-ipam'
|
||||||
app_version = 'V1.4'
|
app_version = 'V1.5'
|
||||||
app_release_date = '04/2025'
|
app_release_date = '04/2025'
|
||||||
app_url = "http://0.0.0.0"
|
app_url = "http://0.0.0.0"
|
||||||
|
|
||||||
app_theme = 'default' # default, lumen, simplex, zephyr
|
app_theme = ['default', 'lumen', 'simplex', 'zephyr']
|
||||||
|
|
||||||
class Configuration:
|
class Configuration:
|
||||||
# replace SECRET_KEY with value from "openssl rand -hex 32" or similar for STATIC sessions
|
# replace SECRET_KEY with value from "openssl rand -hex 32" or similar for STATIC sessions
|
||||||
# With actual configuration, every application restart, user have to re-login...
|
# With actual configuration, every application restart, user have to re-login...
|
||||||
|
|||||||
@@ -7,14 +7,17 @@ class User(UserMixin, db.Model):
|
|||||||
password = db.Column(db.String(32))
|
password = db.Column(db.String(32))
|
||||||
is_admin = db.Column(db.Boolean(),default=False)
|
is_admin = db.Column(db.Boolean(),default=False)
|
||||||
is_reado = db.Column(db.Boolean(),default=False)
|
is_reado = db.Column(db.Boolean(),default=False)
|
||||||
|
ui_theme = db.Column(db.String(16))
|
||||||
dat_last = db.Column(db.DateTime())
|
dat_last = db.Column(db.DateTime())
|
||||||
|
|
||||||
class Network(db.Model):
|
class Network(db.Model):
|
||||||
id = db.Column(db.Integer(),primary_key=True,unique=True)
|
id = db.Column(db.Integer(),primary_key=True,unique=True)
|
||||||
|
vlan_id = db.Column(db.Integer(),unique=True)
|
||||||
prefix = db.Column(db.Integer())
|
prefix = db.Column(db.Integer())
|
||||||
network_address = db.Column(db.String(16),unique=True)
|
network_address = db.Column(db.String(16),unique=True)
|
||||||
hosts = db.Column(db.Integer())
|
hosts = db.Column(db.Integer())
|
||||||
description = db.Column(db.String(32))
|
description = db.Column(db.String(32))
|
||||||
|
is_blacklisted = db.Column(db.Boolean(),default=False)
|
||||||
|
|
||||||
class Allocation(db.Model):
|
class Allocation(db.Model):
|
||||||
ipv4 = db.Column(db.String(16),primary_key=True,unique=True)
|
ipv4 = db.Column(db.String(16),primary_key=True,unique=True)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ def login():
|
|||||||
|
|
||||||
flash("Bad username or password !", 'danger')
|
flash("Bad username or password !", 'danger')
|
||||||
return render_template("auth/login.html", title="Login", form=form, bad_password=True)
|
return render_template("auth/login.html", title="Login", form=form, bad_password=True)
|
||||||
return render_template('auth/login.html', title="Login", form=form, app_theme=app_theme)
|
return render_template('auth/login.html', title="Login", form=form)
|
||||||
|
|
||||||
@auth.route("/change",methods=['GET','POST'])
|
@auth.route("/change",methods=['GET','POST'])
|
||||||
@login_required
|
@login_required
|
||||||
|
|||||||
+16
-7
@@ -20,15 +20,16 @@ def home():
|
|||||||
def dashboard():
|
def dashboard():
|
||||||
|
|
||||||
db_networks = Network.query.count()
|
db_networks = Network.query.count()
|
||||||
db_allocations = Allocation.query.filter_by(is_used=True).count()
|
|
||||||
db_inventory = Inventory.query.count()
|
db_inventory = Inventory.query.count()
|
||||||
db_users = User.query.count()
|
db_users = User.query.count()
|
||||||
available_alloc = 0
|
available_alloc = 0
|
||||||
|
db_allocations = 0
|
||||||
|
|
||||||
for available_ip in Network.query.all():
|
for network in Network.query.all():
|
||||||
available_alloc += int(available_ip.hosts)
|
if network.is_blacklisted == False:
|
||||||
|
available_alloc += int(network.hosts)
|
||||||
|
db_allocations += Allocation.query.filter_by(net_id=network.id, is_used=True).count()
|
||||||
|
|
||||||
print(app_theme)
|
|
||||||
return render_template(
|
return render_template(
|
||||||
'panel/dashboard.html',
|
'panel/dashboard.html',
|
||||||
title="Dashboard",
|
title="Dashboard",
|
||||||
@@ -41,6 +42,14 @@ def dashboard():
|
|||||||
available_alloc=available_alloc,
|
available_alloc=available_alloc,
|
||||||
db_users=db_users,
|
db_users=db_users,
|
||||||
Inventory=Inventory,
|
Inventory=Inventory,
|
||||||
navcolor='dark',
|
navcolor='dark'
|
||||||
app_theme=app_theme
|
)
|
||||||
)
|
|
||||||
|
@base.route("/theme/<string:name>",methods=['GET','POST'])
|
||||||
|
@login_required
|
||||||
|
def change_theme(name):
|
||||||
|
if name in app_theme:
|
||||||
|
current_user.ui_theme = name
|
||||||
|
db.session.commit()
|
||||||
|
return redirect(url_for('base.dashboard'))
|
||||||
|
return 'Invalid theme name', 400
|
||||||
@@ -4,7 +4,6 @@ from flask_login import login_required, current_user
|
|||||||
from app.extensions import *
|
from app.extensions import *
|
||||||
from app.models import *
|
from app.models import *
|
||||||
from app.forms import NewInventoryItem, ChangeInventoryItem
|
from app.forms import NewInventoryItem, ChangeInventoryItem
|
||||||
from app._config import app_theme
|
|
||||||
|
|
||||||
inventory = Blueprint('inventory', __name__)
|
inventory = Blueprint('inventory', __name__)
|
||||||
|
|
||||||
@@ -21,7 +20,7 @@ def add_item():
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash("Item ADDED", 'success')
|
flash("Item ADDED", 'success')
|
||||||
|
|
||||||
return render_template('panel/inventory_add.html', title='ADD ITEM', form=form, navcolor='success', app_theme=app_theme)
|
return render_template('panel/inventory_add.html', title='ADD ITEM', form=form, navcolor='success')
|
||||||
|
|
||||||
@inventory.route('/list/<int:item_type>', methods=['GET','POST'])
|
@inventory.route('/list/<int:item_type>', methods=['GET','POST'])
|
||||||
@login_required
|
@login_required
|
||||||
@@ -44,7 +43,7 @@ def list_items(item_type):
|
|||||||
else:
|
else:
|
||||||
title = 'All'
|
title = 'All'
|
||||||
|
|
||||||
return render_template('panel/inventory_view.html', title=title, item_list=db_items, current_page=item_type, navcolor='success', app_theme=app_theme)
|
return render_template('panel/inventory_view.html', title=title, item_list=db_items, current_page=item_type, navcolor='success')
|
||||||
|
|
||||||
@inventory.route('/action/<int:item_id>/<int:action>', methods=['GET','POST'])
|
@inventory.route('/action/<int:item_id>/<int:action>', methods=['GET','POST'])
|
||||||
@login_required
|
@login_required
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from flask import Blueprint, request, render_template, flash, redirect, url_for,
|
|||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from ipaddress import IPv4Network, IPv4Address
|
from ipaddress import IPv4Network, IPv4Address
|
||||||
|
|
||||||
from app._config import app_version, app_theme
|
from app._config import app_version
|
||||||
|
|
||||||
from app.extensions import *
|
from app.extensions import *
|
||||||
from app.models import *
|
from app.models import *
|
||||||
@@ -36,7 +36,7 @@ def networks():
|
|||||||
elif form.errors:
|
elif form.errors:
|
||||||
flash(form.errors, 'danger')
|
flash(form.errors, 'danger')
|
||||||
|
|
||||||
return render_template('panel/networks.html', title="Prefixes", is_networks=True, app_version=app_version, app_theme=app_theme, prefixes=networks, form=form, Allocation=Allocation, navcolor='dark')
|
return render_template('panel/networks.html', title="Prefixes", is_networks=True, app_version=app_version, prefixes=networks, form=form, Allocation=Allocation, navcolor='dark')
|
||||||
|
|
||||||
@network.route('/<int:net_id>/allocations',methods=['GET','POST'])
|
@network.route('/<int:net_id>/allocations',methods=['GET','POST'])
|
||||||
@login_required
|
@login_required
|
||||||
@@ -60,7 +60,7 @@ def allocations(net_id):
|
|||||||
db_network = Network.query.filter_by(id=net_id).first()
|
db_network = Network.query.filter_by(id=net_id).first()
|
||||||
db_allocations = db.paginate(db.select(Allocation).filter_by(net_id=net_id), per_page=session['items'] )
|
db_allocations = db.paginate(db.select(Allocation).filter_by(net_id=net_id), per_page=session['items'] )
|
||||||
|
|
||||||
return render_template('panel/allocations.html', title="Allocations", is_networks=True, app_version=app_version, app_theme=app_theme, allocations=db_allocations, network=db_network, Inventory=Inventory, active_page=active_page, next_page=next_page, prev_page=prev_page, navcolor='dark')
|
return render_template('panel/allocations.html', title="Allocations", is_networks=True, app_version=app_version, allocations=db_allocations, network=db_network, Inventory=Inventory, active_page=active_page, next_page=next_page, prev_page=prev_page, navcolor='dark')
|
||||||
|
|
||||||
## MODAL ROUTES
|
## MODAL ROUTES
|
||||||
|
|
||||||
@@ -202,6 +202,31 @@ def network_delete(net_id):
|
|||||||
flash("Network Not Found", 'danger')
|
flash("Network Not Found", 'danger')
|
||||||
return redirect(url_for('network.networks'))
|
return redirect(url_for('network.networks'))
|
||||||
|
|
||||||
|
@network.get('/<int:net_id>/blacklist/<action>')
|
||||||
|
@login_required
|
||||||
|
def network_blacklist(net_id, action):
|
||||||
|
if current_user.is_reado:
|
||||||
|
return abort(403)
|
||||||
|
|
||||||
|
db_network = Network.query.filter_by(id=net_id).first()
|
||||||
|
|
||||||
|
if db_network == None:
|
||||||
|
flash("Network Not Found", 'danger')
|
||||||
|
return redirect(url_for('network.networks'))
|
||||||
|
|
||||||
|
if action == 'blacklist':
|
||||||
|
db_network.is_blacklisted = True
|
||||||
|
db.session.commit()
|
||||||
|
flash("Network Blacklisted", 'warning')
|
||||||
|
|
||||||
|
elif action == 'unblacklist':
|
||||||
|
db_network.is_blacklisted = False
|
||||||
|
db.session.commit()
|
||||||
|
flash("Network Unblacklisted", 'success')
|
||||||
|
|
||||||
|
|
||||||
|
return redirect(url_for('network.networks'))
|
||||||
|
|
||||||
## HTMX SEARCH
|
## HTMX SEARCH
|
||||||
@network.post('/<int:net_id>/allocations/search')
|
@network.post('/<int:net_id>/allocations/search')
|
||||||
@login_required
|
@login_required
|
||||||
|
|||||||
@@ -11,11 +11,11 @@
|
|||||||
<!-- LINKS -->
|
<!-- LINKS -->
|
||||||
<link rel="icon" type="image/png" href="{{ url_for('static',filename='img/logo.png') }}" />
|
<link rel="icon" type="image/png" href="{{ url_for('static',filename='img/logo.png') }}" />
|
||||||
<link rel="stylesheet" href="{{ url_for('static',filename='css/custom.css') }}"/>
|
<link rel="stylesheet" href="{{ url_for('static',filename='css/custom.css') }}"/>
|
||||||
{% if app_theme == 'zephyr'%}
|
{% if current_user.ui_theme == 'zephyr'%}
|
||||||
<link rel="stylesheet" href="{{ url_for('static',filename='css/Bootstrap/zephyr.css') }}"/>
|
<link rel="stylesheet" href="{{ url_for('static',filename='css/Bootstrap/zephyr.css') }}"/>
|
||||||
{% elif app_theme == 'lumen' %}
|
{% elif current_user.ui_theme == 'lumen' %}
|
||||||
<link rel="stylesheet" href="{{ url_for('static',filename='css/Bootstrap/lumen.css') }}"/>
|
<link rel="stylesheet" href="{{ url_for('static',filename='css/Bootstrap/lumen.css') }}"/>
|
||||||
{% elif app_theme == 'simplex' %}
|
{% elif current_user.ui_theme == 'simplex' %}
|
||||||
<link rel="stylesheet" href="{{ url_for('static',filename='css/Bootstrap/simplex.css') }}"/>
|
<link rel="stylesheet" href="{{ url_for('static',filename='css/Bootstrap/simplex.css') }}"/>
|
||||||
{% else %}
|
{% else %}
|
||||||
<link rel="stylesheet" href="{{ url_for('static',filename='css/bootstrap.min.css') }}"/>
|
<link rel="stylesheet" href="{{ url_for('static',filename='css/bootstrap.min.css') }}"/>
|
||||||
|
|||||||
@@ -11,11 +11,11 @@
|
|||||||
<!-- LINKS -->
|
<!-- LINKS -->
|
||||||
<link rel="icon" type="image/png" href="{{ url_for('static',filename='img/logo.png') }}" />
|
<link rel="icon" type="image/png" href="{{ url_for('static',filename='img/logo.png') }}" />
|
||||||
<link rel="stylesheet" href="{{ url_for('static',filename='css/custom.css') }}"/>
|
<link rel="stylesheet" href="{{ url_for('static',filename='css/custom.css') }}"/>
|
||||||
{% if app_theme == 'zephyr' %}
|
{% if current_user.ui_theme == 'zephyr' %}
|
||||||
<link rel="stylesheet" href="{{ url_for('static',filename='css/Bootstrap/zephyr.css') }}"/>
|
<link rel="stylesheet" href="{{ url_for('static',filename='css/Bootstrap/zephyr.css') }}"/>
|
||||||
{% elif app_theme == 'lumen' %}
|
{% elif current_user.ui_theme == 'lumen' %}
|
||||||
<link rel="stylesheet" href="{{ url_for('static',filename='css/Bootstrap/lumen.css') }}"/>
|
<link rel="stylesheet" href="{{ url_for('static',filename='css/Bootstrap/lumen.css') }}"/>
|
||||||
{% elif app_theme == 'simplex' %}
|
{% elif current_user.ui_theme == 'simplex' %}
|
||||||
<link rel="stylesheet" href="{{ url_for('static',filename='css/Bootstrap/simplex.css') }}"/>
|
<link rel="stylesheet" href="{{ url_for('static',filename='css/Bootstrap/simplex.css') }}"/>
|
||||||
{% else %}
|
{% else %}
|
||||||
<link rel="stylesheet" href="{{ url_for('static',filename='css/bootstrap.min.css') }}"/>
|
<link rel="stylesheet" href="{{ url_for('static',filename='css/bootstrap.min.css') }}"/>
|
||||||
|
|||||||
@@ -30,8 +30,19 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
<div class="d-flex">
|
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
|
||||||
<a class="btn btn-outline-warning" type="submit" href="{{ url_for('auth.logout') }}">logout</a>
|
<div class="btn-group dropstart">
|
||||||
|
<button type="button" class="btn btn-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
UI
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a class="dropdown-item" href="{{ url_for('base.change_theme',name='default') }}">default</a></li>
|
||||||
|
<li><a class="dropdown-item" href="{{ url_for('base.change_theme',name='zephyr') }}">Zephyr</a></li>
|
||||||
|
<li><a class="dropdown-item" href="{{ url_for('base.change_theme',name='simplex') }}">Simplex</a></li>
|
||||||
|
<li><a class="dropdown-item" href="{{ url_for('base.change_theme',name='lumen') }}">Lumen</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<a class="btn btn-outline-warning btn-sm" type="submit" href="{{ url_for('auth.logout') }}">logout</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -28,6 +28,11 @@
|
|||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('network.allocations',net_id=network.id) }}?page=1" class="btn btn-sm btn-outline-info" style="padding-top:1px;padding-bottom:1px">Allocations</a>
|
<a href="{{ url_for('network.allocations',net_id=network.id) }}?page=1" class="btn btn-sm btn-outline-info" style="padding-top:1px;padding-bottom:1px">Allocations</a>
|
||||||
{% if current_user.is_reado == False %}
|
{% if current_user.is_reado == False %}
|
||||||
|
{% if network.is_blacklisted %}
|
||||||
|
<a href="{{ url_for('network.network_blacklist',net_id=network.id,action='unblacklist') }}" class="btn btn-sm btn-outline-warning" style="padding-top:1px;padding-bottom:1px">UnBlacklist</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ url_for('network.network_blacklist',net_id=network.id,action='blacklist') }}" class="btn btn-sm btn-outline-warning" style="padding-top:1px;padding-bottom:1px">Blacklist</a>
|
||||||
|
{% endif %}
|
||||||
<button
|
<button
|
||||||
hx-get="{{ url_for('network.network_del_modal',net_id=network.id) }}"
|
hx-get="{{ url_for('network.network_del_modal',net_id=network.id) }}"
|
||||||
hx-trigger="click"
|
hx-trigger="click"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ class User(db.Model):
|
|||||||
password = db.Column(db.String(32))
|
password = db.Column(db.String(32))
|
||||||
is_admin = db.Column(db.Boolean(),default=False)
|
is_admin = db.Column(db.Boolean(),default=False)
|
||||||
is_reado = db.Column(db.Boolean(),default=False)
|
is_reado = db.Column(db.Boolean(),default=False)
|
||||||
|
ui_theme = db.Column(db.String(16))
|
||||||
dat_last = db.Column(db.DateTime())
|
dat_last = db.Column(db.DateTime())
|
||||||
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
|
|||||||
Reference in new issue
Block a user