package registry import ( "database/sql" "fmt" "time" ) // EdgeRoute represents a public edge route managed by the master. type EdgeRoute struct { Hostname string BackendHostname string BackendPort int TLSCert string TLSKey string CreatedAt time.Time UpdatedAt time.Time } // CreateEdgeRoute inserts or replaces an edge route. func CreateEdgeRoute(db *sql.DB, hostname, backendHostname string, backendPort int, tlsCert, tlsKey string) error { _, err := db.Exec(` INSERT INTO edge_routes (hostname, backend_hostname, backend_port, tls_cert, tls_key, created_at, updated_at) VALUES (?, ?, ?, ?, ?, datetime('now'), datetime('now')) ON CONFLICT(hostname) DO UPDATE SET backend_hostname = excluded.backend_hostname, backend_port = excluded.backend_port, tls_cert = excluded.tls_cert, tls_key = excluded.tls_key, updated_at = datetime('now') `, hostname, backendHostname, backendPort, tlsCert, tlsKey) if err != nil { return fmt.Errorf("create edge route %s: %w", hostname, err) } return nil } // GetEdgeRoute returns a single edge route by hostname. func GetEdgeRoute(db *sql.DB, hostname string) (*EdgeRoute, error) { var r EdgeRoute var createdAt, updatedAt string err := db.QueryRow(` SELECT hostname, backend_hostname, backend_port, tls_cert, tls_key, created_at, updated_at FROM edge_routes WHERE hostname = ? `, hostname).Scan(&r.Hostname, &r.BackendHostname, &r.BackendPort, &r.TLSCert, &r.TLSKey, &createdAt, &updatedAt) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, fmt.Errorf("get edge route %s: %w", hostname, err) } r.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", createdAt) r.UpdatedAt, _ = time.Parse("2006-01-02 15:04:05", updatedAt) return &r, nil } // ListEdgeRoutes returns all edge routes. func ListEdgeRoutes(db *sql.DB) ([]*EdgeRoute, error) { rows, err := db.Query(` SELECT hostname, backend_hostname, backend_port, tls_cert, tls_key, created_at, updated_at FROM edge_routes ORDER BY hostname `) if err != nil { return nil, fmt.Errorf("list edge routes: %w", err) } defer func() { _ = rows.Close() }() var routes []*EdgeRoute for rows.Next() { var r EdgeRoute var createdAt, updatedAt string if err := rows.Scan(&r.Hostname, &r.BackendHostname, &r.BackendPort, &r.TLSCert, &r.TLSKey, &createdAt, &updatedAt); err != nil { return nil, fmt.Errorf("scan edge route: %w", err) } r.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", createdAt) r.UpdatedAt, _ = time.Parse("2006-01-02 15:04:05", updatedAt) routes = append(routes, &r) } return routes, rows.Err() } // DeleteEdgeRoute removes an edge route by hostname. func DeleteEdgeRoute(db *sql.DB, hostname string) error { result, err := db.Exec(`DELETE FROM edge_routes WHERE hostname = ?`, hostname) if err != nil { return fmt.Errorf("delete edge route %s: %w", hostname, err) } n, _ := result.RowsAffected() if n == 0 { return fmt.Errorf("edge route %s not found", hostname) } return nil }