mirror of
https://github.com/apple/foundationdb.git
synced 2025-05-15 18:32:18 +08:00
Add a special IP family argument type to support multiple pod IPs on Kubernetes.
This commit is contained in:
parent
83e94781b4
commit
a7978ce009
@ -21,8 +21,10 @@ package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ProcessConfiguration models the configuration for starting a FoundationDB
|
||||
@ -63,8 +65,11 @@ type Argument struct {
|
||||
Multiplier int `json:"multiplier,omitempty"`
|
||||
|
||||
// Offset provides an offset to add to the process number for ProcessNumber
|
||||
// type argujments.
|
||||
// type arguments.
|
||||
Offset int `json:"offset,omitempty"`
|
||||
|
||||
// IPFamily provides the family to use for IPList type arguments.
|
||||
IPFamily int `json:"ipFamily,omitEmpty"`
|
||||
}
|
||||
|
||||
// ArgumentType defines the types for arguments.
|
||||
@ -84,6 +89,10 @@ const (
|
||||
// ProcessNumberArgumentType defines an argument that is calculated using
|
||||
// the number of the process in the process list.
|
||||
ProcessNumberArgumentType = "ProcessNumber"
|
||||
|
||||
// IPListArgumentType defines an argument that is a comma-separated list of
|
||||
// IP addresses, provided through an environment variable.
|
||||
IPListArgumentType = "IPList"
|
||||
)
|
||||
|
||||
// GenerateArgument processes an argument and generates its string
|
||||
@ -112,6 +121,39 @@ func (argument Argument) GenerateArgument(processNumber int, env map[string]stri
|
||||
number = number + argument.Offset
|
||||
return strconv.Itoa(number), nil
|
||||
case EnvironmentArgumentType:
|
||||
return argument.lookupEnv(env)
|
||||
case IPListArgumentType:
|
||||
envValue, err := argument.lookupEnv(env)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
ips := strings.Split(envValue, ",")
|
||||
for _, ipString := range ips {
|
||||
ip := net.ParseIP(ipString)
|
||||
if ip == nil {
|
||||
continue
|
||||
}
|
||||
switch argument.IPFamily {
|
||||
case 4:
|
||||
if ip.To4() != nil {
|
||||
return ipString, nil
|
||||
}
|
||||
case 6:
|
||||
if ip.To16() != nil && ip.To4() == nil {
|
||||
return ipString, nil
|
||||
}
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported IP family %d", argument.IPFamily)
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("could not find IP with family %d", argument.IPFamily)
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported argument type %s", argument.ArgumentType)
|
||||
}
|
||||
}
|
||||
|
||||
// lookupEnv looks up the value for an argument from the environment.
|
||||
func (argument Argument) lookupEnv(env map[string]string) (string, error) {
|
||||
var value string
|
||||
var present bool
|
||||
if env != nil {
|
||||
@ -121,12 +163,9 @@ func (argument Argument) GenerateArgument(processNumber int, env map[string]stri
|
||||
value, present = os.LookupEnv(argument.Source)
|
||||
}
|
||||
if !present {
|
||||
return "", fmt.Errorf("Missing environment variable %s", argument.Source)
|
||||
return "", fmt.Errorf("missing environment variable %s", argument.Source)
|
||||
}
|
||||
return value, nil
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported argument type %s", argument.ArgumentType)
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateArguments interprets the arguments in the process configuration and
|
||||
|
@ -120,10 +120,99 @@ func TestGeneratingArgumentForEnvironmentVariable(t *testing.T) {
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
expectedError := "Missing environment variable FDB_ZONE_ID"
|
||||
expectedError := "missing environment variable FDB_ZONE_ID"
|
||||
if err.Error() != expectedError {
|
||||
t.Logf("Expected error %s, but got error %s", expectedError, err)
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeneratingArgumentForIPList(t *testing.T) {
|
||||
argument := Argument{ArgumentType: IPListArgumentType, Source: "FDB_PUBLIC_IP", IPFamily: 4}
|
||||
|
||||
result, err := argument.GenerateArgument(1, map[string]string{"FDB_PUBLIC_IP": "127.0.0.1,::1"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if result != "127.0.0.1" {
|
||||
t.Logf("Expected result 127.0.0.1, but got result %v", result)
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
|
||||
result, err = argument.GenerateArgument(1, map[string]string{"FDB_PUBLIC_IP": "::1,127.0.0.1"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if result != "127.0.0.1" {
|
||||
t.Logf("Expected result 127.0.0.1, but got result %v", result)
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
|
||||
argument.IPFamily = 6
|
||||
|
||||
result, err = argument.GenerateArgument(1, map[string]string{"FDB_PUBLIC_IP": "127.0.0.1,::1"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if result != "::1" {
|
||||
t.Logf("Expected result ::1, but got result %v", result)
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
|
||||
result, err = argument.GenerateArgument(1, map[string]string{"FDB_PUBLIC_IP": "::1,127.0.0.1"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if result != "::1" {
|
||||
t.Logf("Expected result ::1, but got result %v", result)
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
|
||||
result, err = argument.GenerateArgument(1, map[string]string{"FDB_PUBLIC_IP": "bad,::1"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if result != "::1" {
|
||||
t.Logf("Expected result ::1, but got result %v", result)
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
|
||||
_, err = argument.GenerateArgument(1, map[string]string{"FDB_PUBLIC_IP": "127.0.0.1"})
|
||||
if err == nil {
|
||||
t.Logf("Expected error, but did not get an error")
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
expectedError := "could not find IP with family 6"
|
||||
if err.Error() != expectedError {
|
||||
t.Logf("Expected error %s, but got error %s", expectedError, err.Error())
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
|
||||
argument.IPFamily = 5
|
||||
|
||||
_, err = argument.GenerateArgument(1, map[string]string{"FDB_PUBLIC_IP": "127.0.0.1"})
|
||||
if err == nil {
|
||||
t.Logf("Expected error, but did not get an error")
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
expectedError = "unsupported IP family 5"
|
||||
if err.Error() != expectedError {
|
||||
t.Logf("Expected error %s, but got error %s", expectedError, err.Error())
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user