traefik-frontend/app.py

135 lines
5.1 KiB
Python
Raw Normal View History

2024-07-22 18:14:12 -03:00
from flask import Flask, render_template
import re
2024-07-22 18:57:14 -03:00
import docker
import requests
2024-07-22 18:14:12 -03:00
app = Flask(__name__)
TRAEFIK_API_URL = "https://norman.lan/api/http/routers"
REGEX_PATTERNS = [r".*\.gederico\.dynu\.net"]
2024-07-23 17:32:12 -03:00
DEFAULT_GROUP_PRIORITY = 100
DEFAULT_GROUP = 'Applications'
DEFAULT_GROUP_ICON = 'fas fa-box'
DEFAULT_TITLE = 'Traefik Routers'
2024-07-22 18:14:12 -03:00
2024-07-22 18:57:14 -03:00
client = docker.from_env()
2024-07-23 17:32:12 -03:00
def get_routers(containers):
2024-07-22 18:14:12 -03:00
response = requests.get(TRAEFIK_API_URL, verify=False) # Ignore SSL certificate verification
if response.status_code == 200:
routers = response.json()
2024-07-23 17:32:12 -03:00
filtered_routers = filter_routers(routers, containers)
2024-07-22 18:14:12 -03:00
return filtered_routers
return []
2024-07-23 17:32:12 -03:00
def filter_routers(routers, containers):
2024-07-22 18:14:12 -03:00
filtered_routers = []
for router in routers:
for pattern in REGEX_PATTERNS:
if re.match(pattern, router['rule'].split('`')[1]):
2024-07-23 17:32:12 -03:00
if not is_router_hidden(router['name'], containers):
router['description'] = get_router_description(router['name'], containers)
router['display_name'] = get_router_display_name(router['name'], containers)
router['group'] = get_router_group(router['name'], containers)
filtered_routers.append(router)
2024-07-22 18:14:12 -03:00
break
return filtered_routers
2024-07-23 17:32:12 -03:00
def is_router_hidden(router_name, containers):
service_name = router_name.split('@')[0]
for container in containers:
labels = container.attrs.get('Config', {}).get('Labels', {})
hidden_label = f'traefik-frontend.http.routers.{service_name}.hidden'
if labels.get(hidden_label) == 'true':
return True
return False
def get_router_description(router_name, containers):
service_name = router_name.split('@')[0]
for container in containers:
labels = container.attrs.get('Config', {}).get('Labels', {})
description_label = f'traefik-frontend.http.routers.{service_name}.description'
if description_label in labels:
return labels[description_label]
2024-07-22 18:25:30 -03:00
return 'No description available'
2024-07-23 17:32:12 -03:00
def get_router_display_name(router_name, containers):
service_name = router_name.split('@')[0]
for container in containers:
labels = container.attrs.get('Config', {}).get('Labels', {})
display_name_label = f'traefik-frontend.http.routers.{service_name}.router_name'
if display_name_label in labels:
return labels[display_name_label].upper()
return service_name.upper()
def get_router_group(router_name, containers):
service_name = router_name.split('@')[0]
for container in containers:
labels = container.attrs.get('Config', {}).get('Labels', {})
group_label = f'traefik-frontend.http.routers.{service_name}.group'
if group_label in labels:
return labels[group_label]
return DEFAULT_GROUP
def get_groups(containers):
groups = {
DEFAULT_GROUP: {
'priority': DEFAULT_GROUP_PRIORITY,
'collapsed': False,
'routers': [],
'icon': DEFAULT_GROUP_ICON
}
}
for container in containers:
labels = container.attrs.get('Config', {}).get('Labels', {})
for label, value in labels.items():
if label.startswith('traefik-frontend.groups.'):
group_name = label.split('.')[2]
priority_label = f'traefik-frontend.groups.{group_name}.priority'
collapsed_label = f'traefik-frontend.groups.{group_name}.collapsed'
icon_label = f'traefik-frontend.groups.{group_name}.icon'
if group_name not in groups:
groups[group_name] = {
'priority': DEFAULT_GROUP_PRIORITY,
'collapsed': False,
'routers': [],
'icon': DEFAULT_GROUP_ICON
}
if priority_label in labels:
groups[group_name]['priority'] = int(labels[priority_label])
if collapsed_label in labels:
groups[group_name]['collapsed'] = labels[collapsed_label].lower() == 'true'
if icon_label in labels:
groups[group_name]['icon'] = labels[icon_label]
return groups
def get_title(containers):
for container in containers:
labels = container.attrs.get('Config', {}).get('Labels', {})
title_label = 'traefik-frontend.title'
if title_label in labels:
return labels[title_label]
return DEFAULT_TITLE
2024-07-22 18:14:12 -03:00
@app.route('/')
def index():
2024-07-23 17:32:12 -03:00
containers = client.containers.list(all=True) # Get all containers once
title = get_title(containers)
routers = get_routers(containers)
groups = get_groups(containers)
2024-07-22 18:14:12 -03:00
for router in routers:
2024-07-23 17:32:12 -03:00
group_name = router['group']
if group_name not in groups:
group_name = DEFAULT_GROUP
groups[group_name]['routers'].append(router)
sorted_groups = {k: v for k, v in sorted(groups.items(), key=lambda item: item[1]['priority']) if v['routers']}
return render_template('index.html', title=title, groups=sorted_groups)
2024-07-22 18:14:12 -03:00
if __name__ == '__main__':
2024-07-23 17:32:12 -03:00
app.run(debug=True, host='0.0.0.0')
2024-07-22 18:14:12 -03:00