fix(agent): auto-register agents with pool_id from cluster_id

PROBLEM:
- Agents registered with pool_id = NULL
- UI doesn't show agents without pool assignment
- Auto-healing only works when server_statuses present
- New agents with empty HAProxy config never get pool_id

ROOT CAUSE:
- Agent auto-register INSERT excluded pool_id column
- Auto-healing (line 1417-1422) only triggers inside 'if server_statuses:' block
- Fresh agents send no server_statuses → auto-healing never runs
- Agent sits with pool_id = NULL indefinitely

ANALYSIS:
- Previous commit 1f9d8c2 added auto-healing for edge case (cluster before pool)
- But auto-healing has conditional prerequisite: server_statuses must exist
- New agents: empty HAProxy config → no server_statuses → no healing
- This was working before because agents had config from start

SOLUTION:
- Extract pool_id from cluster_id during registration
- Query haproxy_clusters for pool_id using heartbeat's cluster_id
- Insert agent with pool_id immediately (no wait for auto-heal)
- Two auto-register paths fixed: with API key + without API key

EDGE CASES HANDLED:
1. cluster_id missing → pool_id = NULL → auto-healing fallback 
2. cluster deleted → pool_id = NULL → auto-healing fallback 
3. cluster pool_id NULL → pool_id = NULL → auto-healing works 
4. Old agent script → no cluster_id → auto-healing works 

COMPATIBILITY:
- Auto-healing preserved (line 1417-1422 untouched)
- Two mechanisms work together harmoniously
- Backward compatible with existing agents
- No breaking changes

IMPACT:
- New agents visible in UI immediately
- Faster registration (no wait for auto-heal)
- Reduced heartbeat cycles to full functionality
- Better user experience

TESTING REQUIRED:
1. Delete agent from database
2. Install fresh agent with cluster_id in config
3. Verify pool_id populated on registration
4. Verify agent appears in UI immediately
5. Verify existing agents unaffected
This commit is contained in:
Taylan Bakırcıoğlu
2025-11-18 19:11:20 +03:00
committed by taylanbakircioglu
parent 132b59bcd7
commit 8418025744
+30 -10
View File
@@ -1244,12 +1244,22 @@ async def agent_heartbeat_by_name(
# Auto-register new agent
logger.info(f"Agent '{agent_name}' not found. Auto-registering...")
try:
# Get pool_id from cluster_id if provided in heartbeat
pool_id_from_cluster = None
if heartbeat_dict.get('cluster_id'):
cluster_pool = await conn.fetchrow("""
SELECT pool_id FROM haproxy_clusters WHERE id = $1
""", heartbeat_dict['cluster_id'])
if cluster_pool:
pool_id_from_cluster = cluster_pool['pool_id']
logger.info(f"Auto-register: Got pool_id {pool_id_from_cluster} from cluster_id {heartbeat_dict['cluster_id']}")
agent_id = await conn.fetchval("""
INSERT INTO agents (name, status, last_seen, api_key)
VALUES ($1, 'online', CURRENT_TIMESTAMP, $2) RETURNING id
""", agent_name, x_api_key)
logger.info(f"Auto-registered new agent '{agent_name}' with ID {agent_id}")
agent = {'id': agent_id, 'pool_id': None}
INSERT INTO agents (name, status, last_seen, api_key, pool_id)
VALUES ($1, 'online', CURRENT_TIMESTAMP, $2, $3) RETURNING id
""", agent_name, x_api_key, pool_id_from_cluster)
logger.info(f"Auto-registered new agent '{agent_name}' with ID {agent_id} and pool_id {pool_id_from_cluster}")
agent = {'id': agent_id, 'pool_id': pool_id_from_cluster}
except Exception as e:
await close_database_connection(conn)
logger.error(f"Failed to auto-register agent '{agent_name}': {e}", exc_info=True)
@@ -1258,12 +1268,22 @@ async def agent_heartbeat_by_name(
# Auto-register new agent without API key
logger.info(f"Agent '{agent_name}' not found. Auto-registering...")
try:
# Get pool_id from cluster_id if provided in heartbeat
pool_id_from_cluster = None
if heartbeat_dict.get('cluster_id'):
cluster_pool = await conn.fetchrow("""
SELECT pool_id FROM haproxy_clusters WHERE id = $1
""", heartbeat_dict['cluster_id'])
if cluster_pool:
pool_id_from_cluster = cluster_pool['pool_id']
logger.info(f"Auto-register: Got pool_id {pool_id_from_cluster} from cluster_id {heartbeat_dict['cluster_id']}")
agent_id = await conn.fetchval("""
INSERT INTO agents (name, status, last_seen)
VALUES ($1, 'online', CURRENT_TIMESTAMP) RETURNING id
""", agent_name)
logger.info(f"Auto-registered new agent '{agent_name}' with ID {agent_id}")
agent = {'id': agent_id, 'pool_id': None}
INSERT INTO agents (name, status, last_seen, pool_id)
VALUES ($1, 'online', CURRENT_TIMESTAMP, $2) RETURNING id
""", agent_name, pool_id_from_cluster)
logger.info(f"Auto-registered new agent '{agent_name}' with ID {agent_id} and pool_id {pool_id_from_cluster}")
agent = {'id': agent_id, 'pool_id': pool_id_from_cluster}
except Exception as e:
await close_database_connection(conn)
logger.error(f"Failed to auto-register agent '{agent_name}': {e}", exc_info=True)