首次提交:初始化项目
This commit is contained in:
265
010-中间件/003-navigation/generator.py
Normal file
265
010-中间件/003-navigation/generator.py
Normal file
@@ -0,0 +1,265 @@
|
||||
#!/usr/bin/env python3
|
||||
import re
|
||||
import json
|
||||
import time
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
# 服务图标映射
|
||||
SERVICE_ICONS = {
|
||||
'longhorn': '💾',
|
||||
'grafana': '📊',
|
||||
'prometheus': '📈',
|
||||
'alertmanager': '🔔',
|
||||
's3': '🗄️',
|
||||
'console': '🎛️',
|
||||
'minio': '🗄️',
|
||||
'dh': '🏠',
|
||||
'test': '🧪',
|
||||
'default': '🌐'
|
||||
}
|
||||
|
||||
# 服务描述映射
|
||||
SERVICE_DESCRIPTIONS = {
|
||||
'longhorn': '分布式块存储管理',
|
||||
'grafana': '监控数据可视化',
|
||||
'prometheus': '指标监控系统',
|
||||
'alertmanager': '告警管理系统',
|
||||
's3': '对象存储 API',
|
||||
'console': 'MinIO 管理控制台',
|
||||
'minio': 'MinIO 对象存储',
|
||||
'dh': '服务导航页面',
|
||||
'test': '测试服务',
|
||||
'default': 'K3s 服务'
|
||||
}
|
||||
|
||||
def parse_caddyfile(caddyfile_path):
|
||||
"""解析 Caddyfile 并提取域名"""
|
||||
services = []
|
||||
|
||||
try:
|
||||
with open(caddyfile_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# 匹配域名配置块 (domain.com {)
|
||||
pattern = r'([a-zA-Z0-9.-]+\.u6\.net3w\.com)\s*\{'
|
||||
matches = re.findall(pattern, content)
|
||||
|
||||
for domain in matches:
|
||||
# 提取子域名前缀
|
||||
subdomain = domain.split('.')[0]
|
||||
|
||||
# 获取图标和描述
|
||||
icon = SERVICE_ICONS.get(subdomain, SERVICE_ICONS['default'])
|
||||
description = SERVICE_DESCRIPTIONS.get(subdomain, SERVICE_DESCRIPTIONS['default'])
|
||||
|
||||
# 生成服务名称
|
||||
name = subdomain.capitalize()
|
||||
if subdomain == 's3':
|
||||
name = 'MinIO S3'
|
||||
elif subdomain == 'console':
|
||||
name = 'MinIO Console'
|
||||
elif subdomain == 'dh':
|
||||
name = '导航页面'
|
||||
|
||||
services.append({
|
||||
'name': name,
|
||||
'icon': icon,
|
||||
'url': f'https://{domain}',
|
||||
'description': description
|
||||
})
|
||||
|
||||
# 排序:导航页面放最后
|
||||
services.sort(key=lambda x: (x['name'] == '导航页面', x['name']))
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error parsing Caddyfile: {e}")
|
||||
|
||||
return services
|
||||
|
||||
def generate_html(services):
|
||||
"""生成 HTML 页面"""
|
||||
|
||||
services_html = '\n'.join([
|
||||
f'''
|
||||
<a href="{service['url']}" class="service-card" target="_blank">
|
||||
<div class="service-icon">{service['icon']}</div>
|
||||
<div class="service-name">{service['name']}</div>
|
||||
<div class="service-url">{service['url']}</div>
|
||||
<div class="service-description">{service['description']}</div>
|
||||
</a>
|
||||
'''
|
||||
for service in services
|
||||
])
|
||||
|
||||
html_template = f'''<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>K3s 服务导航</title>
|
||||
<style>
|
||||
* {{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}}
|
||||
|
||||
body {{
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}}
|
||||
|
||||
.container {{
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}}
|
||||
|
||||
header {{
|
||||
text-align: center;
|
||||
color: white;
|
||||
margin-bottom: 40px;
|
||||
padding: 40px 20px;
|
||||
}}
|
||||
|
||||
h1 {{
|
||||
font-size: 3em;
|
||||
margin-bottom: 10px;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
||||
}}
|
||||
|
||||
.subtitle {{
|
||||
font-size: 1.2em;
|
||||
opacity: 0.9;
|
||||
}}
|
||||
|
||||
.services-grid {{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 40px;
|
||||
}}
|
||||
|
||||
.service-card {{
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 25px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
display: block;
|
||||
}}
|
||||
|
||||
.service-card:hover {{
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 15px 40px rgba(0,0,0,0.3);
|
||||
}}
|
||||
|
||||
.service-icon {{
|
||||
font-size: 3em;
|
||||
margin-bottom: 15px;
|
||||
}}
|
||||
|
||||
.service-name {{
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
color: #333;
|
||||
}}
|
||||
|
||||
.service-url {{
|
||||
color: #667eea;
|
||||
font-size: 0.9em;
|
||||
word-break: break-all;
|
||||
}}
|
||||
|
||||
.service-description {{
|
||||
color: #666;
|
||||
margin-top: 10px;
|
||||
font-size: 0.9em;
|
||||
}}
|
||||
|
||||
footer {{
|
||||
text-align: center;
|
||||
color: white;
|
||||
padding: 20px;
|
||||
opacity: 0.8;
|
||||
}}
|
||||
|
||||
.update-time {{
|
||||
background: rgba(255,255,255,0.2);
|
||||
padding: 10px 20px;
|
||||
border-radius: 20px;
|
||||
display: inline-block;
|
||||
margin-top: 20px;
|
||||
}}
|
||||
|
||||
.stats {{
|
||||
background: rgba(255,255,255,0.1);
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
margin-top: 20px;
|
||||
}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>🚀 K3s 服务导航</h1>
|
||||
<p class="subtitle">快速访问您的所有服务</p>
|
||||
</header>
|
||||
|
||||
<div class="services-grid">
|
||||
{services_html}
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<div class="stats">
|
||||
共 {len(services)} 个服务
|
||||
</div>
|
||||
<div class="update-time">
|
||||
最后更新: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
|
||||
return html_template
|
||||
|
||||
def main():
|
||||
caddyfile_path = '/etc/caddy/Caddyfile'
|
||||
output_path = '/usr/share/nginx/html/index.html'
|
||||
|
||||
print(f"Navigation page generator started at {datetime.now()}")
|
||||
print(f"Caddyfile path: {caddyfile_path}")
|
||||
print(f"Output path: {output_path}")
|
||||
|
||||
while True:
|
||||
try:
|
||||
# 解析 Caddyfile
|
||||
services = parse_caddyfile(caddyfile_path)
|
||||
print(f"Found {len(services)} services")
|
||||
|
||||
# 生成 HTML
|
||||
html = generate_html(services)
|
||||
|
||||
# 写入文件
|
||||
Path(output_path).parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(output_path, 'w', encoding='utf-8') as f:
|
||||
f.write(html)
|
||||
|
||||
print(f"Updated navigation page at {datetime.now()}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
# 每 5 分钟更新一次
|
||||
time.sleep(300)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user