Skip to content

Commit

Permalink
Merge pull request #108 from wleese/sd_endpoint
Browse files Browse the repository at this point in the history
allow setting the service discovery endpoint
  • Loading branch information
tgross committed Apr 22, 2016
2 parents 92bea4f + 11246af commit 292ff51
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ The `interfaces` parameter allows for one or more specifications to be used when
- `fdc6:238c:c4bc::/48` : Match the first IP that is contained within the IPv6 Network
- `inet` : Match the first IPv4 Address (excluding `127.0.0.0/8`)
- `inet6` : Match the first IPv6 Address (excluding `::1/128`)
- `static: 192.168.1.100` : Use this Address. Useful for all cases where the IP is not visible in the container

Interfaces and their IP addresses are ordered alphabetically by interface name, then by IP address (lexicographically by bytes).

Expand Down
27 changes: 27 additions & 0 deletions utils/ips.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ func GetIP(specList []string) (string, error) {
func findIPWithSpecs(specs []interfaceSpec, interfaceIPs []interfaceIP) (string, error) {
// Find the interface matching the name given
for _, spec := range specs {
// Static IP given
origSpec, ok := spec.(staticInterfaceSpec)
if ok {
return origSpec.IP.String(), nil
}
index := 0
iface := ""
for _, iip := range interfaceIPs {
Expand Down Expand Up @@ -122,6 +127,18 @@ type inetInterfaceSpec struct {
IPv6 bool
}

// -- matches static
type staticInterfaceSpec struct {
Spec string
Name string
IP net.IP
}

func (s staticInterfaceSpec) Match(index int, iip interfaceIP) bool {
// Never matches
return false
}

func (s inetInterfaceSpec) Match(index int, iip interfaceIP) bool {
if s.Name != "*" && s.Name != iip.Name {
return false
Expand Down Expand Up @@ -187,6 +204,16 @@ func parseInterfaceSpec(spec string) (interfaceSpec, error) {
if spec == "inet6" {
return inetInterfaceSpec{Spec: spec, Name: "*", IPv6: true}, nil
}
if strings.HasPrefix(spec, "static:") {
ip := strings.SplitAfter(spec, "static:")
if _, err := strconv.Atoi(ip[1]); err != nil {
nip := net.ParseIP(ip[1])
if nip == nil {
return nil, fmt.Errorf("Unable to parse static ip %s in %s", ip[0], spec)
}
return staticInterfaceSpec{Spec: spec, Name: "static", IP: nip}, nil
}
}

if match := ifaceSpec.FindStringSubmatch(spec); match != nil {
name := match[1]
Expand Down
30 changes: 25 additions & 5 deletions utils/ips_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ func TestGetIp(t *testing.T) {
if ip, err := GetIP([]string{"interface-does-not-exist"}); err == nil {
t.Errorf("Expected interface not found, but instead got an IP: %s", ip)
}
if ip, _ := GetIP([]string{"static:192.168.1.100", "lo"}); ip != "192.168.1.100" {
t.Errorf("Expected to find static ip 192.168.1.100, but found: %s", ip)
}
}

func TestInterfaceIpsLoopback(t *testing.T) {
Expand Down Expand Up @@ -125,11 +128,12 @@ func TestInterfaceIpsError(t *testing.T) {

func TestInterfaceSpecParse(t *testing.T) {
// Test Error Cases
testSpecError(t, "") // Nothing
testSpecError(t, "!") // Nonsense
testSpecError(t, "127.0.0.1") // No Network
testSpecError(t, "eth0:inet5") // Invalid IP Version
testSpecError(t, "eth0[-1]") // Invalid Index
testSpecError(t, "") // Nothing
testSpecError(t, "!") // Nonsense
testSpecError(t, "127.0.0.1") // No Network
testSpecError(t, "eth0:inet5") // Invalid IP Version
testSpecError(t, "eth0[-1]") // Invalid Index
testSpecError(t, "static:abcdef") // Invalid IP

// Test Interface Case
testSpecInterfaceName(t, "eth0", "eth0", false, -1)
Expand All @@ -138,6 +142,7 @@ func TestInterfaceSpecParse(t *testing.T) {
testSpecInterfaceName(t, "eth0[2]", "eth0", false, 2)
testSpecInterfaceName(t, "inet", "*", false, -1)
testSpecInterfaceName(t, "inet6", "*", true, -1)
testSpecInterfaceName(t, "static:192.168.1.100", "static", false, 1)

// Test CIDR Case
testSpecCIDR(t, "10.0.0.0/16")
Expand All @@ -155,6 +160,17 @@ func testSpecInterfaceName(t *testing.T, specStr string, name string, ipv6 bool,
if err != nil {
t.Errorf("Expected parse to succeed, but got error: %s", err)
}
if name == "static" {
staticSpec, ok := spec.(staticInterfaceSpec)
if !ok {
t.Errorf("Expected %s to parse as staticInterfaceSpec", spec)
return
}
if staticSpec.Name != "static" {
t.Errorf("Expected to parse interface name static but got %s", staticSpec.Name)
}
return
}
if index < 0 {
inetSpec, ok := spec.(inetInterfaceSpec)
if !ok {
Expand Down Expand Up @@ -208,6 +224,9 @@ func TestFindIPWithSpecs(t *testing.T) {
testIPSpec(t, iips, "127.0.0.1", "lo")
testIPSpec(t, iips, "::1", "lo:inet6")

// Static
testIPSpec(t, iips, "192.168.1.100", "static:192.168.1.100")

// Interface Name
testIPSpec(t, iips, "10.2.0.1", "eth0")
testIPSpec(t, iips, "10.2.0.1", "eth0:inet")
Expand Down Expand Up @@ -300,6 +319,7 @@ func getTestIPs() []interfaceIP {
newInterfaceIP("eth2", "fdc6:238c:c4bc::1"),
newInterfaceIP("lo", "::1"),
newInterfaceIP("lo", "127.0.0.1"),
newInterfaceIP("static:192.168.1.100", "192.168.1.100"),
}
}

Expand Down

0 comments on commit 292ff51

Please sign in to comment.