This commit is contained in:
Takeus committed 2025-02-18 15:29:27 +01:00
1 parent eefc23fad8
commit 06b7efd58b
12 files changed
+483 -73

No files matched your search

+23 -5
View File
@@ -1,6 +1,6 @@
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, IntegerField, SelectField from wtforms import StringField, PasswordField, IntegerField, SelectField, TextAreaField
from wtforms.validators import DataRequired, Length, IPAddress, NumberRange from wtforms.validators import DataRequired, Length, IPAddress
class LoginForm(FlaskForm): class LoginForm(FlaskForm):
username = StringField(validators=[DataRequired(),Length(max=128)]) username = StringField(validators=[DataRequired(),Length(max=128)])
@@ -15,10 +15,12 @@ class NewUserForm(FlaskForm):
username = StringField(validators=[DataRequired(),Length(max=128)]) username = StringField(validators=[DataRequired(),Length(max=128)])
password = PasswordField(validators=[DataRequired(),Length(max=128)]) password = PasswordField(validators=[DataRequired(),Length(max=128)])
is_admin = SelectField(choices=[(0,'No'),(1,'Yes')],validators=[DataRequired()]) is_admin = SelectField(choices=[(0,'No'),(1,'Yes')],validators=[DataRequired()])
is_readonly = SelectField(choices=[(0,'No'),(1,'Yes')],validators=[DataRequired()])
class ChangePasswordForm(FlaskForm): class ChangePasswordForm(FlaskForm):
password = PasswordField(validators=[DataRequired(),Length(max=128)]) password = PasswordField(validators=[DataRequired(),Length(max=128)])
is_admin = SelectField(choices=[(0,'No'),(1,'Yes')],validators=[DataRequired()]) is_admin = SelectField(choices=[(0,'No'),(1,'Yes')],validators=[DataRequired()])
is_readonly = SelectField(choices=[(0,'No'),(1,'Yes')],validators=[DataRequired()])
class ChangeAllocationForm(FlaskForm): class ChangeAllocationForm(FlaskForm):
hostname = StringField(validators=[Length(max=128)]) hostname = StringField(validators=[Length(max=128)])
@@ -26,6 +28,22 @@ class ChangeAllocationForm(FlaskForm):
is_special = SelectField(choices=[(0,'None'),(1,'DHCP'),(2,'Gateway')],validators=[DataRequired()],label='Special USE ?') is_special = SelectField(choices=[(0,'None'),(1,'DHCP'),(2,'Gateway')],validators=[DataRequired()],label='Special USE ?')
class NewInventoryItem(FlaskForm): class NewInventoryItem(FlaskForm):
item_name = StringField(validators=[DataRequired(),Length(max=128)]) item_name = StringField(validators=[DataRequired(),Length(max=64)])
item_desc = PasswordField(validators=[Length(max=128)]) item_desc = StringField(validators=[Length(max=64)])
item_type = SelectField(choices=[(1,'Computer'),(2,'Server'),(3,'Virtual Machine'), (4,'Network Device'), (0,'Other')],validators=[DataRequired()]) item_type = SelectField(choices=[(1,'Computer'),(2,'Server'),(3,'Virtual Machine'), (4,'Network Device'), (0,'Other')],validators=[DataRequired()])
class ChangeInventoryItem(FlaskForm):
item_name = StringField(validators=[DataRequired(),Length(max=64)])
item_desc = StringField(validators=[Length(max=64)])
item_type = SelectField(choices=[(1,'Computer'),(2,'Server'),(3,'Virtual Machine'), (4,'Network Device'), (0,'Other')],validators=[DataRequired()])
# Hardware Information
item_model = StringField(validators=[Length(max=64)])
item_manufacturer = StringField(validators=[Length(max=64)])
item_serial_number = StringField(validators=[Length(max=64)])
# Network Information
item_os = StringField(validators=[Length(max=64)])
item_location = StringField(validators=[Length(max=64)])
item_owner = StringField(validators=[Length(max=64)])
item_contact = StringField(validators=[Length(max=64)])
# Allocation(s)
item_ip_allocations = StringField()
+4 -1
View File
@@ -6,6 +6,7 @@ class User(UserMixin, db.Model):
username = db.Column(db.String(16)) username = db.Column(db.String(16))
password = db.Column(db.String(32),unique=True) password = db.Column(db.String(32),unique=True)
is_admin = db.Column(db.Boolean(),default=False) is_admin = db.Column(db.Boolean(),default=False)
is_reado = db.Column(db.Boolean(),default=False)
dat_last = db.Column(db.DateTime()) dat_last = db.Column(db.DateTime())
class Network(db.Model): class Network(db.Model):
@@ -40,4 +41,6 @@ class Inventory(db.Model):
host_os = db.Column(db.String(64)) host_os = db.Column(db.String(64))
host_location = db.Column(db.String(64)) host_location = db.Column(db.String(64))
host_owner = db.Column(db.String(64)) host_owner = db.Column(db.String(64))
host_contact = db.Column(db.String(64)) host_contact = db.Column(db.String(64))
## Allocation(s)
host_allocations = db.Column(db.Text())
+7 -1
View File
@@ -26,10 +26,13 @@ def home():
return redirect(url_for('admin.home')) return redirect(url_for('admin.home'))
is_admin = False is_admin = False
is_readonly = False
if int(form.is_admin.data) == 1: if int(form.is_admin.data) == 1:
is_admin = True is_admin = True
if int(form.is_readonly.data) == 1:
is_readonly = True
db.session.add(User(username=form.username.data, password=generate_password_hash(form.password.data), is_admin=is_admin)) db.session.add(User(username=form.username.data, password=generate_password_hash(form.password.data), is_admin=is_admin, is_reado=is_readonly))
db.session.commit() db.session.commit()
flash("User Created", 'success') flash("User Created", 'success')
return redirect(url_for('admin.home')) return redirect(url_for('admin.home'))
@@ -67,8 +70,11 @@ def user_modal_edit(user_id):
if form.validate_on_submit() and request.method == 'POST': if form.validate_on_submit() and request.method == 'POST':
user.password = generate_password_hash(form.password.data) user.password = generate_password_hash(form.password.data)
user.is_admin = False user.is_admin = False
user.is_reado = False
if int(form.is_admin.data) == 1: if int(form.is_admin.data) == 1:
user.is_admin = True user.is_admin = True
if int(form.is_readonly.data) == 1:
user.is_reado = True
db.session.commit() db.session.commit()
flash("Informations Changed", 'success') flash("Informations Changed", 'success')
return redirect(url_for('admin.home')) return redirect(url_for('admin.home'))
+198 -11
View File
@@ -1,19 +1,18 @@
from datetime import datetime from flask import Blueprint, request, render_template, flash, redirect, url_for, abort
from flask import Blueprint, request, render_template, flash, redirect, url_for, session
from flask_login import login_required, current_user from flask_login import login_required, current_user
from ipaddress import IPv4Network, IPv4Address
from app._config import app_version
from app.extensions import * from app.extensions import *
from app.models import * from app.models import *
from app.forms import NewInventoryItem from app.forms import NewInventoryItem, ChangeInventoryItem
inventory = Blueprint('inventory', __name__) inventory = Blueprint('inventory', __name__)
@inventory.route('/add', methods=['GET','POST']) @inventory.route('/add', methods=['GET','POST'])
@login_required @login_required
def add_item(): def add_item():
if current_user.is_reado:
return abort(403)
form = NewInventoryItem() form = NewInventoryItem()
if form.validate_on_submit() and request.method == 'POST': if form.validate_on_submit() and request.method == 'POST':
add_net = Inventory(host_type=int(form.item_type.data),host_name=str(form.item_name.data),host_desc=str(form.item_desc.data)) add_net = Inventory(host_type=int(form.item_type.data),host_name=str(form.item_name.data),host_desc=str(form.item_desc.data))
@@ -21,22 +20,210 @@ 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) 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
def list_items(item_type): def list_items(item_type):
db_items = Inventory.query.filter_by(host_type=item_type).all() if item_type == 5:
return render_template('panel/inventory_view.html', Title='View Items', item_list=db_items) db_items = Inventory.query.all()
else:
db_items = Inventory.query.filter_by(host_type=item_type).all()
if item_type == 0:
title = 'Others'
elif item_type == 1:
title = 'Computers'
elif item_type == 2:
title = 'Servers'
elif item_type == 3:
title = 'VM\'s'
elif item_type == 4:
title = 'Network'
else:
title = 'All'
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
def action_item(item_id,action): def action_item(item_id,action):
if current_user.is_reado:
return abort(403)
if action == 1: if action == 1:
db_item = Inventory.query.filter_by(id=item_id).first() db_item = Inventory.query.filter_by(id=item_id).first()
db_allocs = Allocation.query.filter_by(device_id=db_item.id).all()
# Delete Link Allocation(s)
if db_allocs != []:
for alloc in db_allocs:
alloc.device_id = None
db.session.delete(db_item) db.session.delete(db_item)
db.session.commit() db.session.commit()
return redirect(url_for('base.dashboard')) return redirect(url_for('inventory.list_items',item_type=request.args.get('page', type=int)))
## MODAL ROUTES
@inventory.get('/<int:item_id>/view_modal')
@login_required
def item_view_modal(item_id):
db_item = Inventory.query.filter_by(id=item_id).first()
modal = {
'title': f'Informations of <b>{db_item.host_name}</b> ({db_item.id})',
'modal_type': 'infos',
'color': 'info',
'action': 'delete',
'action_text': 'Delete',
'action_url': url_for('inventory.action_item',item_id=item_id,action=1)
}
if db_item.host_type == 0:
host_type = 'Others'
elif db_item.host_type == 1:
host_type = 'Computers'
elif db_item.host_type == 2:
host_type = 'Servers'
elif db_item.host_type == 3:
host_type = 'VM\'s'
elif db_item.host_type == 4:
host_type = 'Network'
else:
host_type = 'Error'
informations = [
('Type',host_type,'col-6'),
('Name',db_item.host_name,'col-6'),
('Description',db_item.host_desc,'col-6'),
('Model',db_item.host_model,'col-6'),
('Manufacturer',db_item.host_manufacturer,'col-6'),
('SerialNumber',db_item.host_serialnumber,'col-6'),
('OS',db_item.host_os,'col-6'),
('Location',db_item.host_location,'col-6'),
('Owner',db_item.host_owner,'col-6'),
('Contact',db_item.host_contact,'col-6'),
('Allocations',db_item.host_allocations,'col-12'),
]
return render_template('panel/_modal.html', modal=modal, item_id=item_id, informations=informations, old_page=request.args.get('page', type=int), pagination_active=True)
@inventory.get('/<int:item_id>/del_modal')
@login_required
def item_del_modal(item_id):
db_item = Inventory.query.filter_by(id=item_id).first()
modal = {
'title': 'Delete Item',
'body': f'Are you sure you want to delete <b>{db_item.host_name}</b> ?',
'color': 'danger',
'action': 'delete',
'action_text': 'Delete',
'action_url': url_for('inventory.action_item',item_id=item_id,action=1)
}
return render_template('panel/_modal.html', modal=modal, item_id=item_id, old_page=request.args.get('page', type=int), pagination_active=True)
@inventory.route('/<int:item_id>/edit_modal', methods=['GET','POST'])
@login_required
def item_edit_modal(item_id):
if current_user.is_reado:
return abort(403)
db_item = Inventory.query.filter_by(id=item_id).first()
form = ChangeInventoryItem()
if form.validate_on_submit() and request.method == 'POST':
db_item.host_type = form.item_type.data
db_item.host_name = form.item_name.data
# Description
if form.item_desc.data != '' and form.item_desc.data != 'None':
db_item.host_desc = form.item_desc.data
else:
db_item.host_desc = None
# Model
if form.item_model.data != '' and form.item_model.data != 'None':
db_item.host_model = form.item_model.data
else:
db_item.host_model = None
# Serial Number
if form.item_serial_number.data != '' and form.item_serial_number.data != 'None':
db_item.host_serialnumber = form.item_serial_number.data
else:
db_item.host_serialnumber = None
# OS
if form.item_os.data != '' and form.item_os.data != 'None':
db_item.host_os = form.item_os.data
else:
db_item.host_os = None
# Location
if form.item_location.data != '' and form.item_location.data != 'None':
db_item.host_location = form.item_location.data
else:
db_item.host_location = None
# Owner
if form.item_owner.data != '' and form.item_owner.data != 'None':
db_item.host_owner = form.item_owner.data
else:
db_item.host_owner = None
# Contact
if form.item_contact.data != '' and form.item_contact.data != 'None':
db_item.host_contact = form.item_contact.data
else:
db_item.host_contact = None
# Allocations
db_existing_allocs = Allocation.query.filter_by(device_id=db_item.id).all()
# Unlink old Allocation(s)
if db_existing_allocs != []:
for alloc in db_existing_allocs:
alloc.device_id = None
if form.item_ip_allocations.data != '' and form.item_ip_allocations.data != 'None':
allocs = form.item_ip_allocations.data.split(',')
put_allocs_db = ""
for alloc in allocs:
db_alloc = Allocation.query.filter_by(ipv4=alloc).first()
if db_alloc != None:
put_allocs_db += db_alloc.ipv4+','
db_alloc.device_id = db_item.id
elif allocs[-1] == '':
pass
else:
flash('Unknown IPv4', 'warning')
return redirect(url_for('inventory.list_items',item_type=request.args.get('page', type=int)))
db_item.host_allocations = put_allocs_db
else:
db_item.host_allocations = None
db.session.commit()
flash("Item Updated", 'success')
return redirect(url_for('inventory.list_items',item_type=request.args.get('page', type=int)))
# Setting default values
form.item_name.default = db_item.host_name
form.item_desc.default = db_item.host_desc
form.item_type.default = db_item.host_type
form.item_model.default =db_item.host_model
form.item_manufacturer.default = db_item.host_manufacturer
form.item_serial_number.default = db_item.host_serialnumber
form.item_os.default = db_item.host_os
form.item_location.default = db_item.host_location
form.item_owner.default = db_item.host_owner
form.item_contact.default = db_item.host_contact
form.item_ip_allocations.default = db_item.host_allocations
form.process()
modal = {
'title': 'Update Item',
'body': f'Change informations for <b>{db_item.host_name}</b>.',
'color': 'primary',
'modal_type': 'form',
'action_text': 'Save',
'form_url': url_for('inventory.item_edit_modal',item_id=item_id),
'inventory':True,
}
return render_template('panel/_modal.html', modal=modal, form=form, old_page=request.args.get('page', type=int), pagination_active=True)
+43 -21
View File
@@ -1,5 +1,4 @@
from datetime import datetime from flask import Blueprint, request, render_template, flash, redirect, url_for, session, abort
from flask import Blueprint, request, render_template, flash, redirect, url_for, session
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
@@ -16,25 +15,26 @@ network = Blueprint('network', __name__)
def networks(): def networks():
networks = Network.query.all() networks = Network.query.all()
form = NewPrefixForm() form = NewPrefixForm()
if request.method == 'POST' and form.validate_on_submit(): if current_user.is_reado == False:
try: if request.method == 'POST' and form.validate_on_submit():
network = IPv4Network(f"{str(form.subnet.data)}/{str(form.prefix.data)}", False) try:
network = IPv4Network(f"{str(form.subnet.data)}/{str(form.prefix.data)}", False)
add_net = Network(network_address=str(network.network_address),prefix=network.prefixlen,hosts=network.num_addresses-2,description=str(form.description.data))
db.session.add(add_net) add_net = Network(network_address=str(network.network_address),prefix=network.prefixlen,hosts=network.num_addresses-2,description=str(form.description.data))
db.session.commit() db.session.add(add_net)
db.session.commit()
for ip in network.hosts():
db.session.add(Allocation(ipv4=str(ip), net_id=add_net.id)) for ip in network.hosts():
db.session.add(Allocation(ipv4=str(ip), net_id=add_net.id))
db.session.commit()
return redirect(url_for('network.networks')) db.session.commit()
return redirect(url_for('network.networks'))
except:
flash("Invalid Subnet or Prefix", 'danger') except:
return redirect(url_for('network.networks')) flash("Invalid Subnet or Prefix", 'danger')
elif form.errors: return redirect(url_for('network.networks'))
flash(form.errors, 'danger') elif form.errors:
flash(form.errors, 'danger')
return render_template('panel/networks.html', title="Prefixes", is_networks=True, app_version=app_version, 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')
@@ -95,6 +95,9 @@ def allocation_del_modal(net_id,ipv4):
@network.route('/<int:net_id>/allocations/<string:ipv4>/edit_modal', methods=['GET','POST']) @network.route('/<int:net_id>/allocations/<string:ipv4>/edit_modal', methods=['GET','POST'])
@login_required @login_required
def allocation_edit_modal(net_id, ipv4): def allocation_edit_modal(net_id, ipv4):
if current_user.is_reado:
return abort(403)
db_alloc = Allocation.query.filter_by(ipv4=ipv4).first() db_alloc = Allocation.query.filter_by(ipv4=ipv4).first()
form = ChangeAllocationForm() form = ChangeAllocationForm()
@@ -130,15 +133,28 @@ def allocation_edit_modal(net_id, ipv4):
'action_text': 'Save', 'action_text': 'Save',
'form_url': url_for('network.allocation_edit_modal',net_id=db_alloc.net_id,ipv4=db_alloc.ipv4), 'form_url': url_for('network.allocation_edit_modal',net_id=db_alloc.net_id,ipv4=db_alloc.ipv4),
} }
old_page = request.args.get('page', type=int) old_page = request.args.get('page', type=int)
if old_page == 0: if old_page == 0:
old_page = 1 old_page = 1
form.hostname.default = db_alloc.hostname
form.description.default = db_alloc.description
if db_alloc.is_dhcp:
form.is_special.default = 1
elif db_alloc.is_gateway:
form.is_special.default = 2
form.process()
return render_template('panel/_modal.html', modal=modal, form=form, old_page=old_page, pagination_active=True) return render_template('panel/_modal.html', modal=modal, form=form, old_page=old_page, pagination_active=True)
## MODIFICATION ROUTES ## MODIFICATION ROUTES
@network.get('/<int:net_id>/allocations/<string:ipv4>/unallocate') @network.get('/<int:net_id>/allocations/<string:ipv4>/unallocate')
@login_required @login_required
def allocation_delete(net_id,ipv4): def allocation_delete(net_id,ipv4):
if current_user.is_reado:
return abort(403)
db_alloc = Allocation.query.filter_by(net_id=net_id,ipv4=ipv4).first() db_alloc = Allocation.query.filter_by(net_id=net_id,ipv4=ipv4).first()
db_alloc.is_used = False db_alloc.is_used = False
db_alloc.hostname = None db_alloc.hostname = None
@@ -152,6 +168,9 @@ def allocation_delete(net_id,ipv4):
@network.get('/<int:net_id>/allocations/<string:ipv4>/decom/<int:action>') @network.get('/<int:net_id>/allocations/<string:ipv4>/decom/<int:action>')
@login_required @login_required
def allocation_decom(net_id,ipv4,action): def allocation_decom(net_id,ipv4,action):
if current_user.is_reado:
return abort(403)
db_alloc = Allocation.query.filter_by(net_id=net_id,ipv4=ipv4).first() db_alloc = Allocation.query.filter_by(net_id=net_id,ipv4=ipv4).first()
if action == 1: if action == 1:
db_alloc.is_decom = True db_alloc.is_decom = True
@@ -163,6 +182,9 @@ def allocation_decom(net_id,ipv4,action):
@network.get('/<int:net_id>/delete') @network.get('/<int:net_id>/delete')
@login_required @login_required
def network_delete(net_id): def network_delete(net_id):
if current_user.is_reado:
return abort(403)
db_network = Network.query.filter_by(id=net_id).first() db_network = Network.query.filter_by(id=net_id).first()
db_alloc = Allocation.query.filter_by(net_id=db_network.id).all() db_alloc = Allocation.query.filter_by(net_id=db_network.id).all()
+6
View File
@@ -22,6 +22,7 @@
<th>ID</th> <th>ID</th>
<th>Username</th> <th>Username</th>
<th>Admin User</th> <th>Admin User</th>
<th>RO</th>
<th>Last Connection</th> <th>Last Connection</th>
<th>Actions</th> <th>Actions</th>
</tr> </tr>
@@ -32,6 +33,7 @@
<td>{{user.id}}</td> <td>{{user.id}}</td>
<td>{{user.username}}</td> <td>{{user.username}}</td>
<td>{{user.is_admin}}</td> <td>{{user.is_admin}}</td>
<td>{{user.is_reado}}</td>
<td>{% if user.dat_last != None %}{{user.dat_last.strftime('%Y-%m-%d %H:%M:%S')}}{%else%}N/A{%endif%}</td> <td>{% if user.dat_last != None %}{{user.dat_last.strftime('%Y-%m-%d %H:%M:%S')}}{%else%}N/A{%endif%}</td>
<td> <td>
<button <button
@@ -80,6 +82,10 @@
<label class="form-label">Is Admin?</label> <label class="form-label">Is Admin?</label>
{{ form.is_admin(class="form-control") }} {{ form.is_admin(class="form-control") }}
</div> </div>
<div class="mb-3">
<label class="form-label">Is Readonly?</label>
{{ form.is_readonly(class="form-control") }}
</div>
<button type="submit" class="btn btn-secondary w-100">Submit</button> <button type="submit" class="btn btn-secondary w-100">Submit</button>
</form> </form>
</div> </div>
+50 -3
View File
@@ -1,5 +1,5 @@
{% if modal.modal_type == 'form' %} {% if modal.modal_type == 'form' %}
<div class="modal-dialog modal-dialog-centered"> <div class="modal-dialog">
<form method="post" action="{{modal.form_url}}{% if pagination_active %}?page={{old_page}}{%endif%}"> <form method="post" action="{{modal.form_url}}{% if pagination_active %}?page={{old_page}}{%endif%}">
{{ form.csrf_token }} {{ form.csrf_token }}
<div class="modal-content"> <div class="modal-content">
@@ -8,8 +8,29 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
{% if modal.inventory %}
{{ modal.body|safe }}<hr>
<div class="row">
{% for entry in form %}
{% if entry.id != 'csrf_token' %}
{% if entry.id == 'item_ip_allocations' %}
<div class="col-12">
{{ entry.label(class="form-label") }}<br>
{{ entry(class="form-control",placeholder='192.168.1.1,192.168.1.2 (separate with ,)') }}
</div>
{% else %}
<div class="col-6">
<div class="mb-2">
{{ entry.label(class="form-label") }}<br>
{{ entry(class="form-control") }}
</div>
</div>
{% endif %}
{% endif %}
{% endfor %}
</div>
{% else %}
<p> <p>
{{ modal.body|safe }}<hr>
{% for entry in form %} {% for entry in form %}
{% if entry.id != 'csrf_token' %} {% if entry.id != 'csrf_token' %}
<div class="mb-3"> <div class="mb-3">
@@ -19,6 +40,7 @@
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</p> </p>
{% endif %}
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
@@ -27,11 +49,36 @@
</div> </div>
</form> </form>
</div> </div>
{% elif modal.modal_type == 'infos' %}
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title text-{{modal.color}}">{{ modal.title|safe }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row">
{% for info in informations %}
<div class="{{info[2]}}">
<div class="mb-3">
<label for="{{info[0]}}">{{info[0]}}</label>
<input class="form-control" type="text" id="{{info[0]}}" value="{{info[1]}}" readonly>
<!--{{ key }} : {{ value }}-->
</div>
</div>
{% endfor %}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
{% else %} {% else %}
<div class="modal-dialog modal-dialog-centered"> <div class="modal-dialog modal-dialog-centered">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title text-{{modal.color}}">{{ modal.title }}</h5> <h5 class="modal-title text-{{modal.color}}">{{ modal.title|safe }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
+2 -1
View File
@@ -20,7 +20,8 @@
<li><a class="dropdown-item" href="{{ url_for('inventory.list_items',item_type=3) }}"><i class="bi bi-server"></i> Virtual Machines</a></li> <li><a class="dropdown-item" href="{{ url_for('inventory.list_items',item_type=3) }}"><i class="bi bi-server"></i> Virtual Machines</a></li>
<li><a class="dropdown-item" href="{{ url_for('inventory.list_items',item_type=4) }}"><i class="bi bi-ethernet"></i> Networks Devices</a></li> <li><a class="dropdown-item" href="{{ url_for('inventory.list_items',item_type=4) }}"><i class="bi bi-ethernet"></i> Networks Devices</a></li>
<li><a class="dropdown-item" href="{{ url_for('inventory.list_items',item_type=0) }}"><i class="bi bi-collection"></i> Others</a></li> <li><a class="dropdown-item" href="{{ url_for('inventory.list_items',item_type=0) }}"><i class="bi bi-collection"></i> Others</a></li>
<li><a class="dropdown-item" href="{{ url_for('inventory.add_item') }}"><i class="bi bi-plus-circle"></i> ADD NEW</a></li> <li><a class="dropdown-item" href="{{ url_for('inventory.list_items',item_type=5) }}"><i class="bi bi-collection"></i> All</a></li>
{% if current_user.is_reado == False %}<li><a class="dropdown-item" href="{{ url_for('inventory.add_item') }}"><i class="bi bi-plus-circle"></i> ADD NEW</a></li>{% endif %}
</ul> </ul>
</li> </li>
{% if current_user.is_admin %} {% if current_user.is_admin %}
+12 -1
View File
@@ -5,7 +5,16 @@
<td>{{allocation.description}}</td> <td>{{allocation.description}}</td>
<td> <td>
{% if Inventory.query.filter_by(id=allocation.device_id).first() %} {% if Inventory.query.filter_by(id=allocation.device_id).first() %}
<a href="{{Inventory.query.filter_by(id=allocation.device_id).first().id}}" style="text-decoration:none;">link</a> <button
hx-get="{{ url_for('inventory.item_view_modal',item_id=allocation.device_id) }}"
hx-trigger="click"
hx-target="#modal-view"
data-bs-toggle="modal"
data-bs-target="#modal-view"
class="btn btn-sm btn-outline-primary"
style="padding-top:1px;padding-bottom:1px"
> Details
</button>
{% else %} {% else %}
N/A N/A
{% endif %} {% endif %}
@@ -13,6 +22,7 @@
<td>{{allocation.is_dhcp}}</td> <td>{{allocation.is_dhcp}}</td>
<td>{{allocation.is_gateway}}</td> <td>{{allocation.is_gateway}}</td>
<td>{{allocation.is_decom}}</td> <td>{{allocation.is_decom}}</td>
{% if current_user.is_reado == False %}
<td> <td>
{% if allocation.is_used %} {% if allocation.is_used %}
<button <button
@@ -53,5 +63,6 @@
</button> </button>
{% endif %} {% endif %}
</td> </td>
{% endif %}
</tr> </tr>
{% endfor %} {% endfor %}
+12 -3
View File
@@ -18,7 +18,7 @@
</div> </div>
<!-- IPV4 TABLE --> <!-- IPV4 TABLE -->
<div class="col-12"> <div class="col-12">
<table class="table table-striped table-hover table-sm"> <table class="table table-hover table-sm">
<thead> <thead>
<tr> <tr>
<th scope="col">IPv4</th> <th scope="col">IPv4</th>
@@ -27,8 +27,8 @@
<th scope="col">Device</th> <th scope="col">Device</th>
<th scope="col">DHCP</th> <th scope="col">DHCP</th>
<th scope="col">GATEWAY</th> <th scope="col">GATEWAY</th>
<th scope="col">DECOM</th> <th scope="col">DECOM</th>
<th scope="col">Actions</th> {% if current_user.is_reado == False %}<th scope="col">Actions</th>{% endif %}
</tr> </tr>
</thead> </thead>
<tbody id="search-results"> <tbody id="search-results">
@@ -73,4 +73,13 @@
<div class="modal-content"></div> <div class="modal-content"></div>
</div> </div>
</div> </div>
<div id="modal-view"
class="modal modal-blur fade"
style="display: none"
aria-hidden="false"
tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
<div class="modal-content"></div>
</div>
</div>
{% endblock %} {% endblock %}
+121 -25
View File
@@ -2,36 +2,132 @@
{% block content %} {% block content %}
{% include 'panel/_nav.html' %} {% include 'panel/_nav.html' %}
{% include 'panel/_flash.html' %} {% include 'panel/_flash.html' %}
<div class="container" style="margin-top:5vh;"> <div class="container" style="margin-top:4vh;">
<div class="row"> <div class="row">
<div class="col-2"></div> <div class="col-2"></div>
<div class="col-8"> <div class="col-8">
<table class="table table-striped table-hover table-sm"> <h1>{{title}}</h1>
<thead> <div class="card shadow-sm">
<tr> <div class="card-body">
<th scope="col">ID</th> <table class="table table-hover table-sm">
<th scope="col">Hostname</th> <thead>
<th scope="col">Description</th> <tr>
<th scope="col">Type</th> <th scope="col">ID</th>
<th scope="col">Actions</th> <th scope="col">Hostname</th>
</tr> <th scope="col">Description</th>
</thead> <th scope="col">Type</th>
<tbody> <th scope="col">Owner</th>
{% for item in item_list %} <th scope="col">Allocation(s)</th>
<tr> <th scope="col">Actions</th>
<td>{{item.id}}</td> </tr>
<td>{{item.host_name}}</td> </thead>
<td>{{item.host_desc}}</td> <tbody>
<td>{{item.host_type}}</td> {% for item in item_list %}
<td> <tr>
<a href="{{ url_for('inventory.action_item',action=1,item_id=item.id) }}?page={{active_page}}" class="btn btn-sm btn-outline-danger" style="padding-top:1px;padding-bottom:1px">Delete</a> <th scope="row">{{item.id}}</th>
</td> <td>{{item.host_name}}</td>
</tr> <td>{{item.host_desc}}</td>
{% endfor %} {% if item.host_type == 1 %}
</tbody> <td><i class="bi bi-pc-display"></i> (PC)</td>
</table> {% elif item.host_type == 2 %}
<td><i class="bi bi-server"></i> (SRV)</td>
{% elif item.host_type == 3 %}
<td><i class="bi bi-server"></i> (VM)</td>
{% elif item.host_type == 4 %}
<td><i class="bi bi-ethernet"></i> (NT)</td>
{% elif item.host_type == 0 %}
<td>Other</td>
{% endif %}
<!--
{% if 'WINDOWS' in item.host_os|upper or 'WS' in item.host_os|upper %}
<td><i class="bi bi-windows"></i> {{item.host_os}}</td>
{% elif 'UBUNTU' in item.host_os|upper %}
<td><i class="bi bi-ubuntu"></i> {{item.host_os}}</td>
{% elif 'MACOS' in item.host_os|upper or 'APPLE' in item.host_os|upper %}
<td><i class="bi bi-apple"></i> {{item.host_os}}</td>
{% else %}
<td>{{item.host_os}}</td>
{% endif %}
-->
<td>{{item.host_owner}}</td>
<td>
{% if item.host_allocations != None %}
{% set alloc_count = item.host_allocations.split(',')|length-1 %}
{{alloc_count}}
{% else %}
{{item.host_allocations}}
{% endif %}
</td>
<td>
<button
hx-get="{{ url_for('inventory.item_view_modal',item_id=item.id) }}?page={{current_page}}"
hx-trigger="click"
hx-target="#modal-view"
data-bs-toggle="modal"
data-bs-target="#modal-view"
class="btn btn-sm btn-outline-info"
style="padding-top:1px;padding-bottom:1px"
> Details
</button>
{% if current_user.is_reado == False %}
<button
hx-get="{{ url_for('inventory.item_edit_modal',item_id=item.id) }}?page={{current_page}}"
hx-trigger="click"
hx-target="#modal-edit"
data-bs-toggle="modal"
data-bs-target="#modal-edit"
class="btn btn-sm btn-outline-primary"
style="padding-top:1px;padding-bottom:1px"
> Edit
</button>
<button
hx-get="{{ url_for('inventory.item_del_modal',item_id=item.id) }}?page={{current_page}}"
hx-trigger="click"
hx-target="#modal-del"
data-bs-toggle="modal"
data-bs-target="#modal-del"
class="btn btn-sm btn-outline-danger"
style="padding-top:1px;padding-bottom:1px"
> Delete
</button>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div> </div>
<div class="col-2"></div> <div class="col-2"></div>
</div> </div>
</div> </div>
<!-- MODAL -->
<div id="modal-del"
class="modal modal-blur fade"
style="display: none"
aria-hidden="false"
tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
<div class="modal-content"></div>
</div>
</div>
<div id="modal-edit"
class="modal modal-blur fade"
style="display: none"
aria-hidden="false"
tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
<div class="modal-content"></div>
</div>
</div>
<div id="modal-view"
class="modal modal-blur fade"
style="display: none"
aria-hidden="false"
tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
<div class="modal-content"></div>
</div>
</div>
{% endblock %} {% endblock %}
+5 -1
View File
@@ -5,7 +5,7 @@
<div class="container" style="margin-top:5vh;"> <div class="container" style="margin-top:5vh;">
<div class="row"> <div class="row">
<!-- PREFIXES TABLE --> <!-- PREFIXES TABLE -->
<div class="col-9"> <div class="col-{% if current_user.is_reado == False %}9{% else %}12{% endif %}">
<table class="table table-striped table-hover"> <table class="table table-striped table-hover">
<thead> <thead>
<tr> <tr>
@@ -27,6 +27,7 @@
<td><b>{{network.description}}</b></td> <td><b>{{network.description}}</b></td>
<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 %}
<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"
@@ -37,6 +38,7 @@
style="padding-top:1px;padding-bottom:1px" style="padding-top:1px;padding-bottom:1px"
> Delete > Delete
</button> </button>
{% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
@@ -44,6 +46,7 @@
</table> </table>
</div> </div>
<!-- PREFIX FORM --> <!-- PREFIX FORM -->
{% if current_user.is_reado == False %}
<div class="col-3"> <div class="col-3">
<div class="card p-4 shadow rounded-3"> <div class="card p-4 shadow rounded-3">
<h2 class="text-center mb-4">Add Network</h2> <h2 class="text-center mb-4">Add Network</h2>
@@ -65,6 +68,7 @@
</form> </form>
</div> </div>
</div> </div>
{% endif %}
</div> </div>
</div> </div>
<!-- MODAL --> <!-- MODAL -->