feat: Extract Wild Central as standalone Go service
Extract the Central networking functionality from wild-cloud/api into a standalone service. Wild Central manages DNS (dnsmasq), gateway (HAProxy), firewall (nftables), VPN (WireGuard), TLS (certbot), security (CrowdSec), and DDNS — all the network appliance concerns. All Cloud-specific code (instances, clusters, nodes, apps, backups, operations, kubectl/talosctl tooling) has been removed. The API struct and route registration contain only Central endpoints. Tests updated to match the new API signature. Builds and all tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
83
internal/api/v1/handlers_ddns_test.go
Normal file
83
internal/api/v1/handlers_ddns_test.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestDDNSStatus_ReturnsOK verifies the status endpoint returns 200 with the
|
||||
// correct JSON structure. A freshly-created runner (not yet started) reports
|
||||
// enabled=false.
|
||||
func TestDDNSStatus_ReturnsOK(t *testing.T) {
|
||||
api, _ := setupTestAPI(t)
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/v1/ddns/status", nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
api.DDNSStatus(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var resp map[string]any
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("invalid JSON: %v", err)
|
||||
}
|
||||
|
||||
// enabled must be present and false for an unstarted runner
|
||||
enabled, exists := resp["enabled"]
|
||||
if !exists {
|
||||
t.Error("expected 'enabled' field in response")
|
||||
}
|
||||
if b, _ := enabled.(bool); b {
|
||||
t.Error("expected enabled=false for unstarted runner")
|
||||
}
|
||||
}
|
||||
|
||||
// TestDDNSStatus_HasRequiredFields verifies all status fields are present in the
|
||||
// JSON response.
|
||||
func TestDDNSStatus_HasRequiredFields(t *testing.T) {
|
||||
api, _ := setupTestAPI(t)
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/v1/ddns/status", nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
api.DDNSStatus(w, req)
|
||||
|
||||
var resp map[string]any
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("invalid JSON: %v", err)
|
||||
}
|
||||
|
||||
for _, field := range []string{"enabled", "currentIP", "lastChecked", "lastUpdated"} {
|
||||
if _, ok := resp[field]; !ok {
|
||||
t.Errorf("missing expected field %q in status response", field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestDDNSTrigger_Returns200 verifies the trigger endpoint sends to the runner's
|
||||
// channel and returns a success message.
|
||||
func TestDDNSTrigger_Returns200(t *testing.T) {
|
||||
api, _ := setupTestAPI(t)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/v1/ddns/trigger", nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
api.DDNSTrigger(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var resp map[string]any
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("invalid JSON: %v", err)
|
||||
}
|
||||
if resp["message"] == nil {
|
||||
t.Error("expected message field in response")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user