mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 05:13:01 +00:00
Fix ensure only nameservers nodes added on schema for caddy load balancing
This commit is contained in:
parent
e95ecfb12a
commit
79a489d650
@ -19,6 +19,7 @@ type Credentials struct {
|
||||
IssuedAt time.Time `json:"issued_at"`
|
||||
LastUsedAt time.Time `json:"last_used_at,omitempty"`
|
||||
Plan string `json:"plan,omitempty"`
|
||||
NamespaceURL string `json:"namespace_url,omitempty"`
|
||||
}
|
||||
|
||||
// CredentialStore manages credentials for multiple gateways
|
||||
|
||||
@ -72,13 +72,20 @@ func PerformSimpleAuthentication(gatewayURL, wallet, namespace string) (*Credent
|
||||
return nil, fmt.Errorf("failed to request API key: %w", err)
|
||||
}
|
||||
|
||||
// Build namespace gateway URL from the gateway URL
|
||||
namespaceURL := ""
|
||||
if domain := extractDomainFromURL(gatewayURL); domain != "" {
|
||||
namespaceURL = fmt.Sprintf("https://ns-%s.%s", namespace, domain)
|
||||
}
|
||||
|
||||
// Create credentials
|
||||
creds := &Credentials{
|
||||
APIKey: apiKey,
|
||||
Namespace: namespace,
|
||||
UserID: wallet,
|
||||
Wallet: wallet,
|
||||
IssuedAt: time.Now(),
|
||||
APIKey: apiKey,
|
||||
Namespace: namespace,
|
||||
UserID: wallet,
|
||||
Wallet: wallet,
|
||||
IssuedAt: time.Now(),
|
||||
NamespaceURL: namespaceURL,
|
||||
}
|
||||
|
||||
fmt.Printf("\n🎉 Authentication successful!\n")
|
||||
|
||||
@ -156,6 +156,9 @@ func handleAuthLogin(wallet, namespace string) {
|
||||
fmt.Printf("🎯 Wallet: %s\n", creds.Wallet)
|
||||
fmt.Printf("🏢 Namespace: %s\n", creds.Namespace)
|
||||
fmt.Printf("🔑 API Key: %s\n", creds.APIKey)
|
||||
if creds.NamespaceURL != "" {
|
||||
fmt.Printf("🌐 Namespace URL: %s\n", creds.NamespaceURL)
|
||||
}
|
||||
}
|
||||
|
||||
func handleAuthLogout() {
|
||||
@ -184,6 +187,9 @@ func handleAuthWhoami() {
|
||||
fmt.Println("✅ Authenticated")
|
||||
fmt.Printf(" Wallet: %s\n", creds.Wallet)
|
||||
fmt.Printf(" Namespace: %s\n", creds.Namespace)
|
||||
if creds.NamespaceURL != "" {
|
||||
fmt.Printf(" NS Gateway: %s\n", creds.NamespaceURL)
|
||||
}
|
||||
fmt.Printf(" Issued At: %s\n", creds.IssuedAt.Format("2006-01-02 15:04:05"))
|
||||
if !creds.ExpiresAt.IsZero() {
|
||||
fmt.Printf(" Expires At: %s\n", creds.ExpiresAt.Format("2006-01-02 15:04:05"))
|
||||
@ -231,6 +237,9 @@ func handleAuthStatus() {
|
||||
fmt.Println(" Status: ✅ Authenticated")
|
||||
fmt.Printf(" Wallet: %s\n", creds.Wallet)
|
||||
fmt.Printf(" Namespace: %s\n", creds.Namespace)
|
||||
if creds.NamespaceURL != "" {
|
||||
fmt.Printf(" NS Gateway: %s\n", creds.NamespaceURL)
|
||||
}
|
||||
if !creds.ExpiresAt.IsZero() {
|
||||
fmt.Printf(" Expires: %s\n", creds.ExpiresAt.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
|
||||
@ -4,6 +4,9 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/DeBrosOfficial/network/pkg/logging"
|
||||
@ -143,8 +146,10 @@ func (n *Node) ensureBaseDNSRecords(ctx context.Context) error {
|
||||
value string
|
||||
}
|
||||
|
||||
// Base domain records (e.g., dbrs.space, *.dbrs.space) — for round-robin across all nodes
|
||||
if baseDomain != "" {
|
||||
// Base domain records (e.g., dbrs.space, *.dbrs.space) — only for nameserver nodes.
|
||||
// Only nameserver nodes run Caddy (HTTPS), so only they should appear in base domain
|
||||
// round-robin. Non-nameserver nodes would cause TLS failures for clients.
|
||||
if baseDomain != "" && n.isNameserverNode(ctx) {
|
||||
records = append(records,
|
||||
struct{ fqdn, value string }{baseDomain + ".", ipAddress},
|
||||
struct{ fqdn, value string }{"*." + baseDomain + ".", ipAddress},
|
||||
@ -176,8 +181,9 @@ func (n *Node) ensureBaseDNSRecords(ctx context.Context) error {
|
||||
n.ensureSOAAndNSRecords(ctx, baseDomain)
|
||||
}
|
||||
|
||||
// Claim an NS slot for the base domain (ns1/ns2/ns3)
|
||||
if baseDomain != "" {
|
||||
// Claim an NS slot for the base domain (ns1/ns2/ns3) — only if this node
|
||||
// was installed with --nameserver (i.e. runs Caddy + CoreDNS).
|
||||
if baseDomain != "" && n.isNameserverPreference() {
|
||||
n.claimNameserverSlot(ctx, baseDomain, ipAddress)
|
||||
}
|
||||
|
||||
@ -369,6 +375,37 @@ func (n *Node) cleanupStaleNodeRecords(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// isNameserverPreference checks if this node was installed with --nameserver flag
|
||||
// by reading the preferences.yaml file. Only nameserver nodes should claim NS slots.
|
||||
func (n *Node) isNameserverPreference() bool {
|
||||
oramaDir := filepath.Join(os.ExpandEnv(n.config.Node.DataDir), "..")
|
||||
prefsPath := filepath.Join(oramaDir, "preferences.yaml")
|
||||
data, err := os.ReadFile(prefsPath)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
// Simple check: look for "nameserver: true" in the YAML
|
||||
return strings.Contains(string(data), "nameserver: true")
|
||||
}
|
||||
|
||||
// isNameserverNode checks if this node has claimed a nameserver slot (ns1/ns2/ns3).
|
||||
// Only nameserver nodes run Caddy for HTTPS, so only they should be in base domain DNS.
|
||||
func (n *Node) isNameserverNode(ctx context.Context) bool {
|
||||
if n.rqliteAdapter == nil {
|
||||
return false
|
||||
}
|
||||
nodeID := n.GetPeerID()
|
||||
if nodeID == "" {
|
||||
return false
|
||||
}
|
||||
db := n.rqliteAdapter.GetSQLDB()
|
||||
var count int
|
||||
err := db.QueryRowContext(ctx,
|
||||
`SELECT COUNT(*) FROM dns_nameservers WHERE node_id = ?`, nodeID,
|
||||
).Scan(&count)
|
||||
return err == nil && count > 0
|
||||
}
|
||||
|
||||
// getWireGuardIP returns the IPv4 address assigned to the wg0 interface, if any
|
||||
func (n *Node) getWireGuardIP() (string, error) {
|
||||
iface, err := net.InterfaceByName("wg0")
|
||||
@ -411,5 +448,21 @@ func (n *Node) getNodeIPAddress() (string, error) {
|
||||
defer conn.Close()
|
||||
|
||||
localAddr := conn.LocalAddr().(*net.UDPAddr)
|
||||
if localAddr.IP.IsPrivate() || localAddr.IP.IsLoopback() {
|
||||
// UDP dial returned a private/loopback IP (e.g. WireGuard 10.0.0.x).
|
||||
// Fall back to scanning interfaces for a public IPv4.
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("private IP detected (%s) and failed to list interfaces: %w", localAddr.IP, err)
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && !ipnet.IP.IsPrivate() {
|
||||
if ipnet.IP.To4() != nil {
|
||||
return ipnet.IP.String(), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("private IP detected (%s) and no public IPv4 found on interfaces", localAddr.IP)
|
||||
}
|
||||
return localAddr.IP.String(), nil
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user