The agent's last_seen IP was showing the Docker container IP (10.244.x.x)
because conn.remote_ip returns the proxy/load balancer IP.
Changes:
- Added get_client_ip/1 helper that checks X-Forwarded-For first
- Falls back to X-Real-IP if X-Forwarded-For not present
- Falls back to conn.remote_ip as last resort
- Applied to both AgentAuth plug and AgentController heartbeat endpoint
Now correctly shows the actual external IP of the remote agent.
Changed heartbeat database update from synchronous to async using Task.start.
This reduces response time from ~20ms to <1ms by not waiting for the
database write to complete before sending the response.
The heartbeat is a fire-and-forget operation where the agent doesn't
need confirmation that the update succeeded.
In test environment, it remains synchronous to avoid DB ownership issues.
Fixed two critical issues preventing agent communication:
1. Fix Mix.env() runtime error in production
- Replace Mix.env() with Application.get_env(:towerops, :env)
- Add :env config to test.exs
- Mix module not available in production releases
2. Add Protocol Buffers support to agent API endpoints
- GET /api/v1/agent/config now accepts application/x-protobuf
- POST /api/v1/agent/heartbeat now accepts application/x-protobuf
- Added conversion functions for config/equipment/sensors/interfaces
- Maintains JSON backward compatibility as fallback
All agent controller tests passing (14 tests, 0 failures)
Add three-level agent assignment hierarchy (Equipment > Site > Organization)
allowing flexible agent deployment strategies. Agents now receive only equipment
assigned to them through direct assignment or inheritance from site/organization
defaults.
Key changes:
- Add agent_token_id to Sites table with migration
- Implement get_effective_agent_token/1 for hierarchical resolution
- Add list_agent_polling_targets/1 to return polling targets per agent
- Update API config endpoint to use hierarchical polling targets
- Add agent assignment UI to equipment, site, and organization forms
- Show agent source (direct/site/org/none) in equipment form
- Add equipment count column to agent list
- Update terminology from "poll from server" to "cloud polling"
Tests:
- Add 8 comprehensive tests for list_agent_polling_targets/1
- Add end-to-end test for hierarchical config endpoint
- All 775 tests passing