mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-20 19:25:52 +00:00
feat: add external networking flags to spx admin init
Add --external-mode, --external-iface, --single-nic, --external-pool,
--external-gateway, --external-prefix-len flags to admin init. Config
is now generated with the correct [network] section and per-node vpcd
external_interface/single_nic — no manual spinifex.toml editing needed.
Single-node single-NIC:
spx admin init --external-mode=pool --external-iface=eth0 --single-nic \
--external-pool=192.168.1.150-192.168.1.250 --external-gateway=192.168.1.1
Single-node two-NIC:
spx admin init --external-mode=pool --external-iface=eth1 \
--external-pool=192.168.1.150-192.168.1.250 --external-gateway=192.168.1.1
Next steps output now shows the correct setup-ovn.sh command with
matching flags.
This commit is contained in:
@@ -215,6 +215,14 @@ func init() {
|
||||
adminInitCmd.Flags().String("cluster-name", "spinifex", "NATS cluster name")
|
||||
adminInitCmd.Flags().StringSlice("services", nil, "Services this node runs (default: all). Valid: nats,predastore,viperblock,daemon,awsgw,ui")
|
||||
|
||||
// External networking flags
|
||||
adminInitCmd.Flags().String("external-mode", "", "External network mode: 'pool' (public IPs), 'nat' (outbound-only), or '' (disabled)")
|
||||
adminInitCmd.Flags().String("external-iface", "", "WAN NIC for br-external (e.g., eth0, eth1)")
|
||||
adminInitCmd.Flags().Bool("single-nic", false, "Use macvlan for external bridge (single-NIC hosts, SSH-safe)")
|
||||
adminInitCmd.Flags().String("external-pool", "", "External IP pool range as start-end (e.g., 192.168.1.150-192.168.1.250)")
|
||||
adminInitCmd.Flags().String("external-gateway", "", "WAN gateway IP (e.g., 192.168.1.1)")
|
||||
adminInitCmd.Flags().Int("external-prefix-len", 24, "External pool subnet prefix length")
|
||||
|
||||
// Flags for admin join
|
||||
adminJoinCmd.Flags().String("region", "ap-southeast-2", "Region for this node")
|
||||
adminJoinCmd.Flags().String("az", "ap-southeast-2a", "Availability zone for this node")
|
||||
@@ -528,6 +536,45 @@ func runAdminInit(cmd *cobra.Command, args []string) {
|
||||
clusterName, _ := cmd.Flags().GetString("cluster-name")
|
||||
services, _ := cmd.Flags().GetStringSlice("services")
|
||||
|
||||
// External networking flags
|
||||
externalMode, _ := cmd.Flags().GetString("external-mode")
|
||||
externalIface, _ := cmd.Flags().GetString("external-iface")
|
||||
singleNIC, _ := cmd.Flags().GetBool("single-nic")
|
||||
externalPool, _ := cmd.Flags().GetString("external-pool")
|
||||
externalGateway, _ := cmd.Flags().GetString("external-gateway")
|
||||
externalPrefixLen, _ := cmd.Flags().GetInt("external-prefix-len")
|
||||
|
||||
// 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)
|
||||
os.Exit(1)
|
||||
}
|
||||
var poolStart, poolEnd string
|
||||
if externalMode == "pool" {
|
||||
if externalPool == "" {
|
||||
fmt.Fprintf(os.Stderr, "❌ Error: --external-pool is required when --external-mode=pool (e.g., 192.168.1.150-192.168.1.250)\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
if externalGateway == "" {
|
||||
fmt.Fprintf(os.Stderr, "❌ Error: --external-gateway is required when --external-mode=pool (e.g., 192.168.1.1)\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
if externalIface == "" {
|
||||
fmt.Fprintf(os.Stderr, "❌ Error: --external-iface is required when --external-mode=pool (e.g., eth0)\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
parts := strings.SplitN(externalPool, "-", 2)
|
||||
if len(parts) != 2 || net.ParseIP(parts[0]) == nil || net.ParseIP(parts[1]) == nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ Error: --external-pool must be start-end IPs (e.g., 192.168.1.150-192.168.1.250), got: %s\n", externalPool)
|
||||
os.Exit(1)
|
||||
}
|
||||
poolStart, poolEnd = parts[0], parts[1]
|
||||
if net.ParseIP(externalGateway) == nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ Error: --external-gateway is not a valid IP: %s\n", externalGateway)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Validate IP address format
|
||||
if net.ParseIP(bindIP) == nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ Error: Invalid IP address for --bind: %s\n", bindIP)
|
||||
@@ -717,6 +764,15 @@ func runAdminInit(cmd *cobra.Command, args []string) {
|
||||
|
||||
OVNNBAddr: "tcp:127.0.0.1:6641",
|
||||
OVNSBAddr: "tcp:127.0.0.1:6642",
|
||||
|
||||
ExternalMode: externalMode,
|
||||
ExternalIface: externalIface,
|
||||
SingleNIC: singleNIC,
|
||||
PoolName: "wan",
|
||||
PoolStart: poolStart,
|
||||
PoolEnd: poolEnd,
|
||||
PoolGateway: externalGateway,
|
||||
PoolPrefixLen: externalPrefixLen,
|
||||
}
|
||||
|
||||
// Generate config files
|
||||
@@ -760,10 +816,26 @@ func runAdminInit(cmd *cobra.Command, args []string) {
|
||||
// Print success message
|
||||
fmt.Println("\n🎉 Spinifex initialization complete!")
|
||||
fmt.Println("\n📋 Next steps:")
|
||||
fmt.Println(" 1. Start services:")
|
||||
fmt.Println(" ./scripts/start-dev.sh")
|
||||
step := 1
|
||||
if externalMode != "" {
|
||||
ovnFlags := "--management --external-bridge --external-iface=" + externalIface
|
||||
if singleNIC {
|
||||
ovnFlags += " --single-nic"
|
||||
}
|
||||
fmt.Printf(" %d. Setup OVN with external bridge:\n", step)
|
||||
fmt.Printf(" ./scripts/setup-ovn.sh %s\n", ovnFlags)
|
||||
step++
|
||||
} else {
|
||||
fmt.Printf(" %d. Setup OVN:\n", step)
|
||||
fmt.Println(" ./scripts/setup-ovn.sh --management")
|
||||
step++
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Println(" 2. Test with AWS CLI:")
|
||||
fmt.Printf(" %d. Start services:\n", step)
|
||||
fmt.Println(" ./scripts/start-dev.sh")
|
||||
step++
|
||||
fmt.Println()
|
||||
fmt.Printf(" %d. Test with AWS CLI:\n", step)
|
||||
fmt.Println(" export AWS_PROFILE=spinifex")
|
||||
fmt.Println(" aws ec2 describe-instances")
|
||||
fmt.Println()
|
||||
|
||||
@@ -2,20 +2,18 @@
|
||||
version = "1.0"
|
||||
epoch = 1
|
||||
node = "{{.Node}}"
|
||||
{{- if .ExternalMode}}
|
||||
|
||||
# External network for public subnets (disabled by default).
|
||||
# Set external_mode = "pool" and define pools to enable public IPs.
|
||||
# See docs/development/feature/vpc-public-subnet.md for details.
|
||||
#
|
||||
# [network]
|
||||
# external_mode = "pool" # "pool" (public IPs), "nat" (outbound-only), or "" (disabled)
|
||||
#
|
||||
# [[network.external_pools]]
|
||||
# name = "wan"
|
||||
# range_start = "192.168.1.150"
|
||||
# range_end = "192.168.1.250"
|
||||
# gateway = "192.168.1.1"
|
||||
# prefix_len = 24
|
||||
[network]
|
||||
external_mode = "{{.ExternalMode}}"
|
||||
|
||||
[[network.external_pools]]
|
||||
name = "{{.PoolName}}"
|
||||
range_start = "{{.PoolStart}}"
|
||||
range_end = "{{.PoolEnd}}"
|
||||
gateway = "{{.PoolGateway}}"
|
||||
prefix_len = {{if .PoolPrefixLen}}{{.PoolPrefixLen}}{{else}}24{{end}}
|
||||
{{- end}}
|
||||
|
||||
[nodes.{{.Node}}]
|
||||
node = "{{.Node}}"
|
||||
@@ -55,8 +53,12 @@ shardwal = false
|
||||
[nodes.{{.Node}}.vpcd]
|
||||
ovn_nb_addr = "{{.OVNNBAddr}}"
|
||||
ovn_sb_addr = "{{.OVNSBAddr}}"
|
||||
# external_interface = "eth1" # WAN NIC for br-external (public subnets)
|
||||
# single_nic = false # true = use macvlan (single-NIC hosts, SSH-safe)
|
||||
{{- if .ExternalIface}}
|
||||
external_interface = "{{.ExternalIface}}"
|
||||
{{- if .SingleNIC}}
|
||||
single_nic = true
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
[nodes.{{.Node}}.predastore]
|
||||
host = "{{.BindIP}}:8443"
|
||||
@@ -77,4 +79,4 @@ az = "{{.AZ}}"
|
||||
{{- if .Services}}
|
||||
services = [{{range $i, $s := .Services}}{{if $i}}, {{end}}"{{$s}}"{{end}}]
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
@@ -64,6 +64,16 @@ type ConfigSettings struct {
|
||||
OVNNBAddr string
|
||||
OVNSBAddr string
|
||||
|
||||
// External networking for public subnets
|
||||
ExternalMode string // "pool", "nat", or "" (disabled)
|
||||
ExternalIface string // WAN NIC name (e.g., "eth0", "eth1")
|
||||
SingleNIC bool // Use macvlan instead of adding NIC directly
|
||||
PoolName string // External pool name (e.g., "wan")
|
||||
PoolStart string // First IP in external pool range
|
||||
PoolEnd string // Last IP in external pool range
|
||||
PoolGateway string // WAN gateway IP
|
||||
PoolPrefixLen int // Subnet prefix length (default 24)
|
||||
|
||||
// Other nodes in the cluster (for config source of truth)
|
||||
RemoteNodes []RemoteNode
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user