Add Cloud Map seeder discovery with VPC Lattice operator templates.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

Agents poll AETHERFORGE_CLOUD_MAP_ENDPOINT to sync know_node gossip; deploy plans attach route_via DNS hints for standalone operator registries.
This commit is contained in:
AetherForge
2026-06-07 10:08:57 -07:00
parent 990105f7bf
commit c12565c83d
17 changed files with 650 additions and 3 deletions

157
agent/deploy/cloud_map.go Normal file
View File

@@ -0,0 +1,157 @@
package deploy
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
const cloudMapEnvEndpoint = "AETHERFORGE_CLOUD_MAP_ENDPOINT"
type CloudMapRegistryDocument struct {
Namespace string `json:"namespace"`
Service string `json:"service"`
UpdatedAt string `json:"updated_at"`
Instances []CloudMapRegistryInstance `json:"instances"`
}
type CloudMapRegistryInstance struct {
AgentID string `json:"agent_id"`
DNSName string `json:"dns_name"`
IP string `json:"ip"`
FetchURL string `json:"fetch_url"`
Port int `json:"port"`
Healthy bool `json:"healthy"`
}
var cloudMapHTTPGet = func(url string) ([]byte, error) {
client := &http.Client{Timeout: 12 * time.Second}
resp, err := client.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("cloud map registry HTTP %d", resp.StatusCode)
}
return io.ReadAll(io.LimitReader(resp.Body, 1<<20))
}
func SetCloudMapHTTPGetForTest(fn func(string) ([]byte, error)) {
if fn == nil {
cloudMapHTTPGet = func(url string) ([]byte, error) {
client := &http.Client{Timeout: 12 * time.Second}
resp, err := client.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("cloud map registry HTTP %d", resp.StatusCode)
}
return io.ReadAll(io.LimitReader(resp.Body, 1<<20))
}
return
}
cloudMapHTTPGet = fn
}
func CloudMapEndpoint() string {
return strings.TrimRight(strings.TrimSpace(os.Getenv(cloudMapEnvEndpoint)), "/")
}
func normalizeCloudMapRegistry(doc CloudMapRegistryDocument) CloudMapRegistryDocument {
doc.Namespace = strings.TrimSpace(doc.Namespace)
doc.Service = strings.TrimSpace(doc.Service)
if doc.Namespace == "" {
doc.Namespace = "prod.local"
}
if doc.Service == "" {
doc.Service = "seeder"
}
return doc
}
func FetchCloudMapRegistry(endpoint string) (CloudMapRegistryDocument, error) {
endpoint = strings.TrimRight(strings.TrimSpace(endpoint), "/")
if endpoint == "" {
return CloudMapRegistryDocument{}, fmt.Errorf("cloud map endpoint required")
}
body, err := cloudMapHTTPGet(endpoint)
if err != nil {
return CloudMapRegistryDocument{}, err
}
var doc CloudMapRegistryDocument
if err := json.Unmarshal(body, &doc); err != nil {
return CloudMapRegistryDocument{}, err
}
return normalizeCloudMapRegistry(doc), nil
}
func CloudMapKnowNodeRecords(doc CloudMapRegistryDocument) []FleetGossipRecord {
doc = normalizeCloudMapRegistry(doc)
var out []FleetGossipRecord
seen := make(map[string]bool)
for _, inst := range doc.Instances {
if !inst.Healthy {
continue
}
target := strings.TrimSpace(inst.AgentID)
if target == "" {
target = strings.TrimSpace(inst.DNSName)
}
if target == "" || seen[target] {
continue
}
seen[target] = true
out = append(out, FleetGossipRecord{
Kind: FleetGossipKnowNode,
TargetAgentID: target,
Healthy: true,
})
}
return out
}
func CloudMapLANSeederHints(doc CloudMapRegistryDocument) []LANSeederHint {
doc = normalizeCloudMapRegistry(doc)
var out []LANSeederHint
for _, inst := range doc.Instances {
if !inst.Healthy {
continue
}
id := strings.TrimSpace(inst.AgentID)
if id == "" {
id = strings.TrimSpace(inst.DNSName)
}
if id == "" {
continue
}
out = append(out, LANSeederHint{
AgentID: id,
IP: strings.TrimSpace(inst.IP),
LANFallbackURL: strings.TrimSpace(inst.FetchURL),
})
}
return out
}
func SyncCloudMapRegistry(endpoint string, gossipFn func([]FleetGossipRecord)) error {
doc, err := FetchCloudMapRegistry(endpoint)
if err != nil {
return err
}
records := CloudMapKnowNodeRecords(doc)
if len(records) > 0 && gossipFn != nil {
gossipFn(records)
}
if hints := CloudMapLANSeederHints(doc); len(hints) > 0 {
localIP, _ := PrimaryLocalIPv4()
SetLANSeederHints(hints, localIP)
}
return nil
}