# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is a Kubernetes-based NTP (Network Time Protocol) monitoring system that consists of two main components: - **Reporter**: A DaemonSet that runs on each node to collect NTP metrics via chronyc - **Frontend**: A web interface that aggregates data from all reporters and displays it in a terminal-style UI ## Architecture The system follows a two-tier architecture: 1. **Reporter Service** (`reporter/`) - Python Flask application running on port 9898 - Deployed as a DaemonSet to collect metrics from every Kubernetes node - Uses `chronyc` command to query NTP status from the local chrony daemon - Exposes `/fragment.json` endpoint with node-specific NTP data 2. **Frontend Service** (`frontend/`) - Python Flask application running on port 8080 - Single replica deployment that aggregates data from all reporter pods - Renders a terminal-style UI showing NTP status across the entire cluster - Provides both HTML interface and JSON API endpoints ## Development Commands ### Building and Deploying ```bash # Build reporter image docker build -t git.dws.rip/dws/ntp/reporter:v8 reporter/ # Build frontend image docker build -t git.dws.rip/dws/ntp/frontend:v11 frontend/ # Deploy to Kubernetes kubectl apply -f manifest.yaml ``` ### Local Development ```bash # Run reporter locally (requires chrony to be installed) cd reporter && python main.py # Run frontend locally cd frontend && python main.py ``` ### Testing ```bash # Test reporter endpoint curl http://localhost:9898/fragment.json # Test frontend aggregation curl http://localhost:8080/api/fragments ``` ## Key Configuration - **Reporter Service**: Uses host network (hostNetwork: true) to access node's chrony daemon - **Environment Variables**: - `REPORTER_SERVICE`: Kubernetes service name for discovering reporter pods - `NODE_ID`, `PUBLIC_IP`, `BIND_IP`: Node-specific values from Kubernetes downward API - **Service Discovery**: Frontend uses DNS resolution to find all reporter pod IPs ## Data Flow 1. Each reporter pod runs `chronyc tracking` and `chronyc sources` commands 2. Reporter parses CSV output and exposes via `/fragment.json` 3. Frontend resolves all reporter IPs via Kubernetes DNS 4. Frontend aggregates data and renders ASCII tables in terminal UI 5. Real-time clock sync via JavaScript using server time API ## Dependencies - **Reporter**: Flask, chrony (system package) - **Frontend**: Flask, requests, texttable - Both use Python 3.10 slim base images