improved start sequence, fixed user update

This commit is contained in:
2025-04-09 09:48:02 -04:00
parent ae4cd12f97
commit e53e5004e1
6 changed files with 126 additions and 61 deletions

2
.gitignore vendored
View File

@@ -6,3 +6,5 @@ __pycache__/
instance/ instance/
.vscode/ .vscode/
.DS_Store .DS_Store
docker-compose.yml

View File

@@ -68,49 +68,62 @@ def add_user(mac_address, description, vlan_id):
cursor.close() cursor.close()
conn.close() conn.close()
def update_user_description(mac_address, description): def update_user(mac_address, description, vlan_id):
"""Update the description field of a user identified by MAC address.""" """Update both description and VLAN ID for a given MAC address."""
conn = get_connection() conn = get_connection()
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("UPDATE users SET description = %s WHERE mac_address = %s", (description, mac_address.lower())) cursor.execute(
"UPDATE users SET description = %s, vlan_id = %s WHERE mac_address = %s",
(description, vlan_id, mac_address.lower())
)
conn.commit() conn.commit()
cursor.close() cursor.close()
conn.close() conn.close()
# def update_user_description(mac_address, description):
# """Update the description field of a user identified by MAC address."""
# conn = get_connection()
# cursor = conn.cursor()
# cursor.execute("UPDATE users SET description = %s WHERE mac_address = %s", (description, mac_address.lower()))
# conn.commit()
# cursor.close()
# conn.close()
# Note: This function seems redundant with update_user_description. Included as per instructions. # Note: This function seems redundant with update_user_description. Included as per instructions.
def update_description(mac_address, description): # def update_description(mac_address, description):
"""Update the description for a given MAC address in the users table.""" # """Update the description for a given MAC address in the users table."""
conn = get_connection() # conn = get_connection()
cursor = conn.cursor() # cursor = conn.cursor()
cursor.execute( # cursor.execute(
"UPDATE users SET description = %s WHERE mac_address = %s", # "UPDATE users SET description = %s WHERE mac_address = %s",
(description, mac_address.lower()) # (description, mac_address.lower())
) # )
conn.commit() # conn.commit()
cursor.close() # cursor.close()
conn.close() # conn.close()
def update_user_vlan(mac_address, vlan_id): # def update_user_vlan(mac_address, vlan_id):
"""Update the VLAN ID for a given MAC address in the users table.""" # """Update the VLAN ID for a given MAC address in the users table."""
conn = get_connection() # conn = get_connection()
cursor = conn.cursor() # cursor = conn.cursor()
cursor.execute("UPDATE users SET vlan_id = %s WHERE mac_address = %s", (vlan_id, mac_address.lower())) # cursor.execute("UPDATE users SET vlan_id = %s WHERE mac_address = %s", (vlan_id, mac_address.lower()))
conn.commit() # conn.commit()
cursor.close() # cursor.close()
conn.close() # conn.close()
# Note: This function seems redundant with update_user_vlan. Included as per instructions. # # Note: This function seems redundant with update_user_vlan. Included as per instructions.
def update_vlan(mac_address, vlan_id): # def update_vlan(mac_address, vlan_id):
"""Update the VLAN ID for a given MAC address in the users table.""" # """Update the VLAN ID for a given MAC address in the users table."""
conn = get_connection() # conn = get_connection()
cursor = conn.cursor() # cursor = conn.cursor()
cursor.execute( # cursor.execute(
"UPDATE users SET vlan_id = %s WHERE mac_address = %s", # "UPDATE users SET vlan_id = %s WHERE mac_address = %s",
(vlan_id, mac_address.lower()) # (vlan_id, mac_address.lower())
) # )
conn.commit() # conn.commit()
cursor.close() # cursor.close()
conn.close() # conn.close()
def delete_user(mac_address): def delete_user(mac_address):
"""Remove a user from the database by their MAC address.""" """Remove a user from the database by their MAC address."""

View File

@@ -31,31 +31,28 @@
<tr> <tr>
<td>{{ entry.mac_address }}</td> <td>{{ entry.mac_address }}</td>
<!-- Form spans Description and Actions columns --> <form method="POST" action="{{ url_for('user.update_user_route') }}">
<form method="POST" action="{{ url_for('user.update_description_route') }}"> <input type="hidden" name="mac_address" value="{{ entry.mac_address }}">
<td> <td>
<input type="hidden" name="mac_address" value="{{ entry.mac_address }}">
<input type="text" name="description" value="{{ entry.description or '' }}"> <input type="text" name="description" value="{{ entry.description or '' }}">
</td> </td>
<td>{{ entry.vendor or "..." }}</td> <td>{{ entry.vendor or "..." }}</td>
<td> <td>
<form method="POST" action="{{ url_for('user.update_vlan_route') }}" class="inline-form"> <select name="group_id">
<input type="hidden" name="mac_address" value="{{ entry.mac_address }}"> {% for group in available_groups %}
<select name="group_id" onchange="this.form.submit()"> <option value="{{ group.vlan_id }}" {% if group.vlan_id == entry.vlan_id %}selected{% endif %}>
{% for group in available_groups %} VLAN {{ group.vlan_id }}{% if group.description %} - {{ group.description }}{% endif %}
<option value="{{ group.vlan_id }}" {% if group.vlan_id == entry.vlan_id %}selected{% endif %}> </option>
VLAN {{ group.vlan_id }}{% if group.description %} - {{ group.description }}{% endif %} {% endfor %}
</option> </select>
{% endfor %}
</select>
</form>
</td> </td>
<td> <td>
<button type="submit" title="Save">💾</button> <button type="submit" title="Save">💾</button>
</form> <!-- Closing the description form here --> </form>
<form method="POST" action="{{ url_for('user.delete') }}" style="display:inline;"> <form method="POST" action="{{ url_for('user.delete') }}" style="display:inline;">
<input type="hidden" name="mac_address" value="{{ entry.mac_address }}"> <input type="hidden" name="mac_address" value="{{ entry.mac_address }}">

View File

@@ -1,5 +1,13 @@
from flask import Blueprint, render_template, request, redirect, url_for, flash from flask import Blueprint, render_template, request, redirect, url_for, flash
from db_interface import get_all_users, get_all_groups, add_user, update_description, update_vlan, delete_user, refresh_vendors, get_user_by_mac from db_interface import (
get_all_users,
get_all_groups,
add_user,
update_user,
delete_user,
refresh_vendors,
get_user_by_mac
)
user = Blueprint('user', __name__, url_prefix='/user') user = Blueprint('user', __name__, url_prefix='/user')
@@ -19,21 +27,28 @@ def add():
add_user(mac, desc, group_id) add_user(mac, desc, group_id)
return redirect(url_for('user.user_list')) return redirect(url_for('user.user_list'))
@user.route('/update_user', methods=['POST'])
@user.route('/update_description', methods=['POST']) def update_user_route():
def update_description_route():
mac = request.form['mac_address'] mac = request.form['mac_address']
desc = request.form.get('description', '') desc = request.form.get('description', '')
update_description(mac, desc) vlan_id = request.form['group_id']
update_user(mac, desc, vlan_id)
return redirect(url_for('user.user_list')) return redirect(url_for('user.user_list'))
# @user.route('/update_description', methods=['POST'])
# def update_description_route():
# mac = request.form['mac_address']
# desc = request.form.get('description', '')
# update_description(mac, desc)
# return redirect(url_for('user.user_list'))
@user.route('/update_vlan', methods=['POST'])
def update_vlan_route(): # @user.route('/update_vlan', methods=['POST'])
mac = request.form['mac_address'] # def update_vlan_route():
group_id = request.form['group_id'] # mac = request.form['mac_address']
update_vlan(mac, group_id) # group_id = request.form['group_id']
return redirect(url_for('user.user_list')) # update_vlan(mac, group_id)
# return redirect(url_for('user.user_list'))
@user.route('/delete', methods=['POST']) @user.route('/delete', methods=['POST'])

View File

@@ -18,5 +18,7 @@ COPY . .
# Expose RADIUS port (UDP) # Expose RADIUS port (UDP)
EXPOSE 1812/udp EXPOSE 1812/udp
COPY wait-for-db.py .
# Run the RADIUS service # Run the RADIUS service
CMD ["python", "main.py"] CMD ["sh", "-c", "python wait-for-db.py && python main.py"]

36
radius/wait-for-db.py Normal file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/env python3
import time
import os
import mysql.connector
from mysql.connector import Error
host = os.getenv("DB_HOST", "db")
port = int(os.getenv("DB_PORT", "3306"))
user = os.getenv("DB_USER")
password = os.getenv("DB_PASSWORD")
database = os.getenv("DB_NAME")
timeout = 60 # seconds
start_time = time.time()
print(f"⏳ Waiting for DB at {host}:{port} to be ready...")
while True:
try:
conn = mysql.connector.connect(
host=host,
port=port,
user=user,
password=password,
database=database
)
if conn.is_connected():
print("✅ Database is ready!")
conn.close()
break
except Error as e:
print(f"🛑 DB not ready yet: {e}")
time.sleep(2)
if time.time() - start_time > timeout:
print("❌ Timeout waiting for the database.")
exit(1)