Enhance health check functionality to support service ID lookup; update healthcheck endpoint and services-loader.js for improved service card creation
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
from flask import Flask, request, jsonify, abort
|
||||
import requests
|
||||
import os
|
||||
import xml.etree.ElementTree as ET
|
||||
import time
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@@ -13,11 +15,50 @@ def healthcheck():
|
||||
if HEALTH_TOKEN and token != HEALTH_TOKEN:
|
||||
return jsonify({'error': 'Unauthorized'}), 401
|
||||
|
||||
# New behavior: prefer service id lookup
|
||||
service_id = request.args.get('id')
|
||||
host = request.args.get('host')
|
||||
port = request.args.get('port')
|
||||
proto = request.args.get('proto', 'http')
|
||||
|
||||
if service_id:
|
||||
# Load services.xml and find service by id
|
||||
try:
|
||||
tree = ET.parse('/usr/share/nginx/html/services.xml')
|
||||
root = tree.getroot()
|
||||
except Exception as e:
|
||||
return jsonify({'error': 'unable to parse services.xml', 'detail': str(e)}), 500
|
||||
|
||||
# Find service element by id
|
||||
svc = None
|
||||
for s in root.findall('.//service'):
|
||||
sid = s.get('id') or s.get('name')
|
||||
if sid and sid == service_id:
|
||||
svc = s
|
||||
break
|
||||
if svc is None:
|
||||
return jsonify({'error': 'service id not found'}), 404
|
||||
|
||||
# Determine host/port/proto preference: local-ip > tailscale-ip root > host attr > fallback to provided host
|
||||
local_ip = svc.get('local-ip')
|
||||
root_tailscale = root.get('tailscale-ip')
|
||||
host_attr = svc.get('host')
|
||||
proto_attr = svc.get('proto') or proto
|
||||
port_attr = svc.get('port') or port
|
||||
|
||||
# prefer local-ip if present
|
||||
target_host = local_ip or root_tailscale or (host_attr.split(':')[0] if host_attr and ':' in host_attr else None) or host
|
||||
target_port = port_attr or (host_attr.split(':')[1] if host_attr and ':' in host_attr else None)
|
||||
target_proto = proto_attr
|
||||
if not target_host or not target_port:
|
||||
return jsonify({'error': 'service missing host or port mapping'}), 400
|
||||
|
||||
host = target_host
|
||||
port = target_port
|
||||
proto = target_proto
|
||||
|
||||
if not host or not port:
|
||||
return jsonify({'error': 'missing parameters, expected host and port'}), 400
|
||||
return jsonify({'error': 'missing parameters, expected host and port or id'}), 400
|
||||
|
||||
url = f"{proto}://{host}:{port}"
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
// Function to create a service card
|
||||
function createServiceCard(s, host, allServices, tailscaleIP) {
|
||||
const name = s.getAttribute('name') || s.getAttribute('id') || 'unknown';
|
||||
const serviceId = s.getAttribute('id') || name.toLowerCase().replace(/\s+/g, '-');
|
||||
const proto = s.getAttribute('proto') || 'http';
|
||||
const port = s.getAttribute('port') || '';
|
||||
const logo = s.getAttribute('logo') || '';
|
||||
@@ -122,9 +123,7 @@
|
||||
}
|
||||
}
|
||||
// Always proxy health checks via same-origin endpoint to avoid mixed-content
|
||||
const encodedHost = encodeURIComponent(parsedHost);
|
||||
const hcPort = parsedPort || (pageIsSecure ? '443' : (parsedProto === 'https' ? '443' : '80'));
|
||||
healthCheckUrl = `/healthcheck?host=${encodedHost}&port=${encodeURIComponent(hcPort)}&proto=${encodeURIComponent(parsedProto)}`;
|
||||
healthCheckUrl = `/healthcheck?id=${encodeURIComponent(serviceId)}`;
|
||||
} else {
|
||||
// Local service - use Tailscale IP if configured, otherwise current hostname
|
||||
const targetHost = localIpAttr || tailscaleIP || host;
|
||||
@@ -141,7 +140,7 @@
|
||||
} else if(tailscaleIP){
|
||||
console.log(`Service ${name}: using tailscale-ip ${tailscaleIP} for proxied health checks`);
|
||||
}
|
||||
healthCheckUrl = `/healthcheck?host=${encodedHost}&port=${encodeURIComponent(hcPort)}&proto=${encodeURIComponent(desiredProto)}`;
|
||||
healthCheckUrl = `/healthcheck?id=${encodeURIComponent(serviceId)}`;
|
||||
// Warn when site is secure but service link is HTTP and target is a private IP
|
||||
if(pageIsSecure && proto === 'http' && targetHost === tailscaleIP){
|
||||
console.warn(`Service ${name} will use HTTP at ${href}, but the page is loaded over HTTPS — mixed-content checks will prevent programmatic health checks to the service. Consider enabling TLS or providing a public hostname.`);
|
||||
|
||||
Reference in New Issue
Block a user