mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
fix: auto-detect primary IP for admin init --bind default
Bare `spx admin init` used a 127.0.0.1 default that kept awsgw on loopback only, so system VMs on br-mgmt could never reach it. Auto-detect the default-route source IPv4 instead, which keeps TLS cert SANs specific (still not a wildcard). Dev-install scripts now pass --bind 127.0.0.1 explicitly to preserve loopback-only behavior on laptops. Closes mulga-siv-7.
This commit is contained in:
@@ -239,7 +239,7 @@ func init() {
|
|||||||
adminInitCmd.Flags().Int("nodes", 3, "Number of nodes to expect for cluster")
|
adminInitCmd.Flags().Int("nodes", 3, "Number of nodes to expect for cluster")
|
||||||
adminInitCmd.Flags().String("host", "", "Leader node to join (if not specified, tries multicast discovery)")
|
adminInitCmd.Flags().String("host", "", "Leader node to join (if not specified, tries multicast discovery)")
|
||||||
adminInitCmd.Flags().Int("port", 4432, "Port to bind cluster services on")
|
adminInitCmd.Flags().Int("port", 4432, "Port to bind cluster services on")
|
||||||
adminInitCmd.Flags().String("bind", "127.0.0.1", "IP address to bind services to (e.g., 10.11.12.1 for multi-node)")
|
adminInitCmd.Flags().String("bind", "", "IP address to bind services to (default: auto-detect primary non-loopback IPv4; e.g., 10.11.12.1 for multi-node)")
|
||||||
adminInitCmd.Flags().String("cluster-bind", "", "IP address to bind NATS cluster services to (e.g., 10.11.12.1 for multi-node)")
|
adminInitCmd.Flags().String("cluster-bind", "", "IP address to bind NATS cluster services to (e.g., 10.11.12.1 for multi-node)")
|
||||||
adminInitCmd.Flags().String("cluster-routes", "", "NATS cluster hosts for routing specify multiple with comma (e.g., 10.11.12.1:4248,10.11.12.2:4248 for multi-node)")
|
adminInitCmd.Flags().String("cluster-routes", "", "NATS cluster hosts for routing specify multiple with comma (e.g., 10.11.12.1:4248,10.11.12.2:4248 for multi-node)")
|
||||||
adminInitCmd.Flags().String("predastore-nodes", "", "Comma-separated IPs for multi-node Predastore cluster (e.g., 10.11.12.1,10.11.12.2,10.11.12.3). Requires >= 3 nodes.")
|
adminInitCmd.Flags().String("predastore-nodes", "", "Comma-separated IPs for multi-node Predastore cluster (e.g., 10.11.12.1,10.11.12.2,10.11.12.3). Requires >= 3 nodes.")
|
||||||
@@ -607,6 +607,15 @@ func runAdminInit(cmd *cobra.Command, args []string) {
|
|||||||
nodes, _ := cmd.Flags().GetInt("nodes")
|
nodes, _ := cmd.Flags().GetInt("nodes")
|
||||||
port, _ := cmd.Flags().GetInt("port")
|
port, _ := cmd.Flags().GetInt("port")
|
||||||
bindIP, _ := cmd.Flags().GetString("bind")
|
bindIP, _ := cmd.Flags().GetString("bind")
|
||||||
|
if bindIP == "" {
|
||||||
|
bindIP = admin.DiscoverPrimaryIP()
|
||||||
|
if bindIP == "" {
|
||||||
|
fmt.Fprintf(os.Stderr, "❌ Error: could not auto-detect primary IP. Pass --bind explicitly.\n")
|
||||||
|
fmt.Fprintf(os.Stderr, " Detected local IPs: %v\n", admin.DiscoverLocalIPs())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Printf("Auto-detected --bind=%s (pass --bind to override)\n", bindIP)
|
||||||
|
}
|
||||||
clusterBind, _ := cmd.Flags().GetString("cluster-bind")
|
clusterBind, _ := cmd.Flags().GetString("cluster-bind")
|
||||||
clusterRoutesStr, _ := cmd.Flags().GetString("cluster-routes")
|
clusterRoutesStr, _ := cmd.Flags().GetString("cluster-routes")
|
||||||
var clusterRoutes []string
|
var clusterRoutes []string
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ echo "=== Setting up OVN ==="
|
|||||||
sudo /usr/local/share/spinifex/setup-ovn.sh --management
|
sudo /usr/local/share/spinifex/setup-ovn.sh --management
|
||||||
|
|
||||||
echo "=== Initializing ==="
|
echo "=== Initializing ==="
|
||||||
sudo spx admin init --force --region ap-southeast-2 --az ap-southeast-2a --node node1 --nodes 1
|
sudo spx admin init --force --bind 127.0.0.1 --region ap-southeast-2 --az ap-southeast-2a --node node1 --nodes 1
|
||||||
|
|
||||||
echo "=== Installing CA certificate ==="
|
echo "=== Installing CA certificate ==="
|
||||||
sudo cp /etc/spinifex/ca.pem /usr/local/share/ca-certificates/spinifex-ca.crt
|
sudo cp /etc/spinifex/ca.pem /usr/local/share/ca-certificates/spinifex-ca.crt
|
||||||
|
|||||||
@@ -176,5 +176,5 @@ echo " make reinstall # Changed a .service file? Re-run full setup"
|
|||||||
echo ""
|
echo ""
|
||||||
echo "Legacy workflow (deprecated, retained for pseudo-multinode CI only):"
|
echo "Legacy workflow (deprecated, retained for pseudo-multinode CI only):"
|
||||||
echo " ./scripts/setup-ovn.sh --management"
|
echo " ./scripts/setup-ovn.sh --management"
|
||||||
echo " sudo ./bin/spx admin init --region ap-southeast-2 --az ap-southeast-2a --node node1 --nodes 1"
|
echo " sudo ./bin/spx admin init --bind 127.0.0.1 --region ap-southeast-2 --az ap-southeast-2a --node node1 --nodes 1"
|
||||||
echo " ./scripts/start-dev.sh"
|
echo " ./scripts/start-dev.sh"
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ echo "Re-initializing OVN"
|
|||||||
./scripts/setup-ovn.sh --management $SETUP_OVN_FLAGS
|
./scripts/setup-ovn.sh --management $SETUP_OVN_FLAGS
|
||||||
|
|
||||||
echo "Initializing platform"
|
echo "Initializing platform"
|
||||||
ADMIN_INIT_ARGS="--region $REGION --az ${REGION}a --node node1 --nodes 1"
|
ADMIN_INIT_ARGS="--bind 127.0.0.1 --region $REGION --az ${REGION}a --node node1 --nodes 1"
|
||||||
|
|
||||||
# External networking mode: set EXTERNAL_MODE=nat for NAT/DHCP mode (outbound-only),
|
# External networking mode: set EXTERNAL_MODE=nat for NAT/DHCP mode (outbound-only),
|
||||||
# or leave unset / EXTERNAL_MODE=pool for pool mode (per-VM public IPs).
|
# or leave unset / EXTERNAL_MODE=pool for pool mode (per-VM public IPs).
|
||||||
|
|||||||
@@ -517,6 +517,24 @@ func GenerateCACert(caCertPath, caKeyPath string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DiscoverPrimaryIP returns the host's default-route source IPv4, determined
|
||||||
|
// via a UDP-dial probe against TEST-NET-1 (RFC 5737). No packet is sent — the
|
||||||
|
// kernel picks the outbound interface for the given destination and we read
|
||||||
|
// its source address back off the socket. Returns "" when no usable default
|
||||||
|
// route exists or the resolved source is a loopback.
|
||||||
|
func DiscoverPrimaryIP() string {
|
||||||
|
conn, err := net.Dial("udp4", "192.0.2.1:9")
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
addr, ok := conn.LocalAddr().(*net.UDPAddr)
|
||||||
|
if !ok || addr.IP == nil || addr.IP.IsLoopback() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return addr.IP.String()
|
||||||
|
}
|
||||||
|
|
||||||
// DiscoverLocalIPs enumerates all non-loopback network interface addresses on
|
// DiscoverLocalIPs enumerates all non-loopback network interface addresses on
|
||||||
// this machine and returns them as strings. Link-local addresses are excluded.
|
// this machine and returns them as strings. Link-local addresses are excluded.
|
||||||
func DiscoverLocalIPs() []string {
|
func DiscoverLocalIPs() []string {
|
||||||
|
|||||||
@@ -443,6 +443,21 @@ func TestDiscoverLocalIPs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDiscoverPrimaryIP(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
ip := DiscoverPrimaryIP()
|
||||||
|
if ip == "" {
|
||||||
|
t.Skip("no default-route interface available in this environment")
|
||||||
|
}
|
||||||
|
parsed := net.ParseIP(ip)
|
||||||
|
require.NotNil(t, parsed, "returned IP should be parseable: %s", ip)
|
||||||
|
assert.False(t, parsed.IsLoopback(), "should not return loopback: %s", ip)
|
||||||
|
assert.False(t, parsed.IsUnspecified(), "should not return 0.0.0.0: %s", ip)
|
||||||
|
|
||||||
|
locals := DiscoverLocalIPs()
|
||||||
|
assert.Contains(t, locals, ip, "primary IP should appear in local interface list")
|
||||||
|
}
|
||||||
|
|
||||||
func TestDiscoverHostname(t *testing.T) {
|
func TestDiscoverHostname(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
hostname := DiscoverHostname()
|
hostname := DiscoverHostname()
|
||||||
|
|||||||
Reference in New Issue
Block a user