mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
refactor(admin): remove dead --no-external flag from spx admin init (#537)
This commit is contained in:
+43
-48
@@ -334,7 +334,6 @@ func init() {
|
||||
adminInitCmd.Flags().String("external-gateway", "", "WAN gateway IP (auto-detected from default route)")
|
||||
adminInitCmd.Flags().String("gateway-ip", "", "OVN gateway router's external IP for SNAT (default: pool range_start for pool mode, required for nat mode without DHCP)")
|
||||
adminInitCmd.Flags().Int("external-prefix-len", 24, "External pool subnet prefix length (auto-detected)")
|
||||
adminInitCmd.Flags().Bool("no-external", false, "Disable external networking (overlay-only, no internet for VMs)")
|
||||
adminInitCmd.Flags().Bool("gpu-passthrough", false, "Enable VFIO GPU passthrough (sets gpu_passthrough = true in daemon config)")
|
||||
adminInitCmd.Flags().Bool("ipsec", true, "Encrypt intra-AZ Geneve via OVN native IPsec (cluster-wide); disable only for trusted single-rack lab")
|
||||
|
||||
@@ -1018,7 +1017,6 @@ func runAdminInit(cmd *cobra.Command, args []string) {
|
||||
externalGateway, _ := cmd.Flags().GetString("external-gateway")
|
||||
externalPrefixLen, _ := cmd.Flags().GetInt("external-prefix-len")
|
||||
gatewayIP, _ := cmd.Flags().GetString("gateway-ip")
|
||||
noExternal, _ := cmd.Flags().GetBool("no-external")
|
||||
gpuPassthrough, _ := cmd.Flags().GetBool("gpu-passthrough")
|
||||
ipsecEnabled, _ := cmd.Flags().GetBool("ipsec")
|
||||
|
||||
@@ -1051,59 +1049,56 @@ func runAdminInit(cmd *cobra.Command, args []string) {
|
||||
// Auto-detect network topology
|
||||
var poolStart, poolEnd string
|
||||
var detectedNet *admin.DetectedNetwork
|
||||
if !noExternal {
|
||||
detected, err := admin.DetectNetwork()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "⚠️ Network auto-detection failed: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, " Use --no-external to skip, or specify flags manually.\n")
|
||||
detected, err := admin.DetectNetwork()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "⚠️ Network auto-detection failed: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, " Use --external-mode=nat for outbound-only VMs on a non-bridgeable uplink, or specify --external-* flags manually.\n")
|
||||
} else {
|
||||
detectedNet = detected
|
||||
|
||||
// Print detected topology
|
||||
fmt.Println("\n🔍 Detected network topology:")
|
||||
fmt.Printf(" %-14s %-18s %-20s %-16s %s\n", "Interface", "IP", "Subnet", "Gateway", "Role")
|
||||
for _, iface := range detected.Interfaces {
|
||||
gw := "—"
|
||||
if iface.Gateway != "" {
|
||||
gw = iface.Gateway
|
||||
}
|
||||
fmt.Printf(" %-14s %-18s %-20s %-16s %s\n", iface.Name, iface.IP, iface.Subnet, gw, strings.ToUpper(iface.Role))
|
||||
}
|
||||
if detected.LANCount == 0 {
|
||||
fmt.Println("\n Mode: single-NIC (veth-bridged external)")
|
||||
} else {
|
||||
detectedNet = detected
|
||||
fmt.Printf("\n Mode: %d LAN + 1 WAN (veth-bridged external)\n", detected.LANCount)
|
||||
}
|
||||
|
||||
// Print detected topology
|
||||
fmt.Println("\n🔍 Detected network topology:")
|
||||
fmt.Printf(" %-14s %-18s %-20s %-16s %s\n", "Interface", "IP", "Subnet", "Gateway", "Role")
|
||||
for _, iface := range detected.Interfaces {
|
||||
gw := "—"
|
||||
if iface.Gateway != "" {
|
||||
gw = iface.Gateway
|
||||
}
|
||||
fmt.Printf(" %-14s %-18s %-20s %-16s %s\n", iface.Name, iface.IP, iface.Subnet, gw, strings.ToUpper(iface.Role))
|
||||
// Apply auto-detected values when flags not explicitly set
|
||||
if detected.WAN != nil {
|
||||
if externalIface == "" {
|
||||
externalIface = detected.WAN.Name
|
||||
}
|
||||
if detected.LANCount == 0 {
|
||||
fmt.Println("\n Mode: single-NIC (veth-bridged external)")
|
||||
} else {
|
||||
fmt.Printf("\n Mode: %d LAN + 1 WAN (veth-bridged external)\n", detected.LANCount)
|
||||
if externalGateway == "" {
|
||||
externalGateway = detected.WAN.Gateway
|
||||
}
|
||||
if !cmd.Flags().Changed("external-prefix-len") {
|
||||
externalPrefixLen = detected.WAN.PrefixLen
|
||||
}
|
||||
|
||||
// Apply auto-detected values when flags not explicitly set
|
||||
if detected.WAN != nil {
|
||||
if externalIface == "" {
|
||||
externalIface = detected.WAN.Name
|
||||
}
|
||||
if externalGateway == "" {
|
||||
externalGateway = detected.WAN.Gateway
|
||||
}
|
||||
if !cmd.Flags().Changed("external-prefix-len") {
|
||||
externalPrefixLen = detected.WAN.PrefixLen
|
||||
}
|
||||
|
||||
// Default mode: always "pool". Source defaults to "static"; if
|
||||
// --external-pool is omitted the validator below will error with
|
||||
// a SuggestPoolRange hint.
|
||||
if externalMode == "" && !cmd.Flags().Changed("external-mode") {
|
||||
if isNonBridgeableUplink(detected.WAN.Name) {
|
||||
fmt.Fprintf(os.Stderr, "\n❌ Detected WAN interface %s cannot be bridged (WiFi/cellular/PPP).\n", detected.WAN.Name)
|
||||
fmt.Fprintf(os.Stderr, " Use routed NAT mode instead (outbound-only VM networking):\n")
|
||||
fmt.Fprintf(os.Stderr, " ./scripts/setup-ovn.sh --management --nat-uplink\n")
|
||||
fmt.Fprintf(os.Stderr, " spx admin init --external-mode=nat\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
externalMode = "pool"
|
||||
// Default mode: always "pool". Source defaults to "static"; if
|
||||
// --external-pool is omitted the validator below will error with
|
||||
// a SuggestPoolRange hint.
|
||||
if externalMode == "" && !cmd.Flags().Changed("external-mode") {
|
||||
if isNonBridgeableUplink(detected.WAN.Name) {
|
||||
fmt.Fprintf(os.Stderr, "\n❌ Detected WAN interface %s cannot be bridged (WiFi/cellular/PPP).\n", detected.WAN.Name)
|
||||
fmt.Fprintf(os.Stderr, " Use routed NAT mode instead (outbound-only VM networking):\n")
|
||||
fmt.Fprintf(os.Stderr, " ./scripts/setup-ovn.sh --management --nat-uplink\n")
|
||||
fmt.Fprintf(os.Stderr, " spx admin init --external-mode=nat\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
externalMode = "pool"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate external networking flags
|
||||
if externalMode != "" && externalMode != "pool" && externalMode != "nat" {
|
||||
fmt.Fprintf(os.Stderr, "❌ Error: --external-mode must be 'pool', 'nat', or empty, got: %s\n", externalMode)
|
||||
@@ -1209,8 +1204,8 @@ func runAdminInit(cmd *cobra.Command, args []string) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Resolve the off-host advertise IP. DetectNetwork may have been skipped
|
||||
// when --no-external is set; detect lazily if we need the WAN IP.
|
||||
// Resolve the off-host advertise IP. DetectNetwork may have failed earlier;
|
||||
// detect lazily if we still need the WAN IP.
|
||||
if advertiseFlag == "" && (bindIP == "0.0.0.0" || bindIP == "127.0.0.1") && detectedNet == nil {
|
||||
if d, derr := admin.DetectNetwork(); derr == nil {
|
||||
detectedNet = d
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ Operational commands for inspecting cluster state. These fan out NATS requests t
|
||||
|
||||
| Command | Flags | Description |
|
||||
|---------|-------|-------------|
|
||||
| `spx admin init` | `--nodes`, `--node`, `--bind`, `--port`, `--region`, `--az`, `--cluster-name`, `--cluster-bind`, `--cluster-routes`, `--predastore-nodes`, `--services`, `--formation-timeout`, `--token-ttl`, `--force`, `--external-mode` (`pool` \| `nat` routed NAT for non-bridgeable uplinks, single-node; pair with `setup-ovn.sh --nat-uplink`; add `--external-pool start-end --external-gateway <ip>` or `--external-source=dhcp [--external-bind-bridge <iface>]` for a public pool with full EIP support; note: system instances (ECS/EKS/load-balancer agents) are unsupported in nat v1 — they require `pool` mode), `--no-external` | Generates root IAM credentials (AKIA-prefixed access key + secret) → creates master.key (AES-256, 32 bytes, 0600) → writes bootstrap.json (consumed on first start) → generates CA + server TLS certificates → generates join token (written to `join-token` file, displayed in join command) → creates NATS config with auth token → writes spinifex.toml, awsgw.toml, predastore.toml → configures AWS CLI `spx` profile → creates directory structure under `~/spinifex/`. `--force` on an already-initialized node is idempotent for crypto: it preserves the existing keys (master.key, predastore/viperblock encryption keys), system + admin credentials, and CA, and refreshes only the config files and the CA-signed server certificate (so a changed bind IP / SANs is picked up without breaking already-joined nodes or CA-baked AMIs). A genuine clean slate requires removing the data dirs first. |
|
||||
| `spx admin init` | `--nodes`, `--node`, `--bind`, `--port`, `--region`, `--az`, `--cluster-name`, `--cluster-bind`, `--cluster-routes`, `--predastore-nodes`, `--services`, `--formation-timeout`, `--token-ttl`, `--force`, `--external-mode` (`pool` \| `nat` routed NAT for non-bridgeable uplinks, single-node; pair with `setup-ovn.sh --nat-uplink`; add `--external-pool start-end --external-gateway <ip>` or `--external-source=dhcp [--external-bind-bridge <iface>]` for a public pool with full EIP support; note: system instances (ECS/EKS/load-balancer agents) are unsupported in nat v1 — they require `pool` mode) | Generates root IAM credentials (AKIA-prefixed access key + secret) → creates master.key (AES-256, 32 bytes, 0600) → writes bootstrap.json (consumed on first start) → generates CA + server TLS certificates → generates join token (written to `join-token` file, displayed in join command) → creates NATS config with auth token → writes spinifex.toml, awsgw.toml, predastore.toml → configures AWS CLI `spx` profile → creates directory structure under `~/spinifex/`. `--force` on an already-initialized node is idempotent for crypto: it preserves the existing keys (master.key, predastore/viperblock encryption keys), system + admin credentials, and CA, and refreshes only the config files and the CA-signed server certificate (so a changed bind IP / SANs is picked up without breaking already-joined nodes or CA-baked AMIs). A genuine clean slate requires removing the data dirs first. |
|
||||
| `spx admin join` | `--host` (required), `--node` (required), `--token` (required), `--bind`, `--port`, `--region`, `--az`, `--cluster-bind`, `--cluster-routes`, `--data-dir`, `--services` | Connects to leader node with join token (Authorization: Bearer header) → retrieves cluster configuration → configures local node to join cluster and participate in distributed operations |
|
||||
|
||||
### Version
|
||||
|
||||
Reference in New Issue
Block a user