From 9a053a4b59fe3f114bd6946829a058cf6b57eec4 Mon Sep 17 00:00:00 2001 From: Justin SB Date: Mon, 3 Nov 2014 08:04:42 -0800 Subject: [PATCH 1/5] Initial ipv6 / iptables work --- cmd/proxy/proxy.go | 6 ++++- pkg/proxy/proxier.go | 14 +++++++--- pkg/proxy/proxier_test.go | 4 +++ pkg/util/iptables/iptables.go | 32 ++++++++++++++++++---- pkg/util/iptables/iptables_test.go | 43 +++++++++++++++++++++--------- 5 files changed, 77 insertions(+), 22 deletions(-) diff --git a/cmd/proxy/proxy.go b/cmd/proxy/proxy.go index b9c3fdb1d9c..2d0e6c9734a 100644 --- a/cmd/proxy/proxy.go +++ b/cmd/proxy/proxy.go @@ -100,8 +100,12 @@ func main() { } } + protocol := iptables.ProtocolIpv4 + if net.IP(bindAddress).To4() == nil { + protocol = iptables.ProtocolIpv6 + } loadBalancer := proxy.NewLoadBalancerRR() - proxier := proxy.NewProxier(loadBalancer, net.IP(bindAddress), iptables.New(exec.New())) + proxier := proxy.NewProxier(loadBalancer, net.IP(bindAddress), iptables.New(exec.New(), protocol)) // Wire proxier to handle changes to services serviceConfig.RegisterHandler(proxier) // And wire loadBalancer to handle changes to endpoints to services diff --git a/pkg/proxy/proxier.go b/pkg/proxy/proxier.go index 3e6479085f7..91de74c1d70 100644 --- a/pkg/proxy/proxier.go +++ b/pkg/proxy/proxier.go @@ -529,8 +529,11 @@ func iptablesFlush(ipt iptables.Interface) error { } // Used below. -var zeroIP = net.ParseIP("0.0.0.0") -var localhostIP = net.ParseIP("127.0.0.1") +var zeroIPv4 = net.ParseIP("0.0.0.0") +var localhostIPv4 = net.ParseIP("127.0.0.1") + +var zeroIPv6 = net.ParseIP("::0") +var localhostIPv6 = net.ParseIP("::1") // Build a slice of iptables args for a portal rule. func iptablesPortalArgs(destIP net.IP, destPort int, proxyIP net.IP, proxyPort int, service string) []string { @@ -558,10 +561,13 @@ func iptablesPortalArgs(destIP net.IP, destPort int, proxyIP net.IP, proxyPort i // Unfortunately, I don't know of any way to listen on some (N > 1) // interfaces but not ALL interfaces, short of doing it manually, and // this is simpler than that. - if proxyIP.Equal(zeroIP) || proxyIP.Equal(localhostIP) { + if proxyIP.Equal(zeroIPv4) || proxyIP.Equal(zeroIPv6) || + proxyIP.Equal(localhostIPv4) || proxyIP.Equal(localhostIPv6) { + // TODO: Can we REDIRECT with IPv6? args = append(args, "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", proxyPort)) } else { - args = append(args, "-j", "DNAT", "--to-destination", fmt.Sprintf("%s:%d", proxyIP.String(), proxyPort)) + // TODO: Can we DNAT with IPv6? + args = append(args, "-j", "DNAT", "--to-destination", net.JoinHostPort(proxyIP.String(), strconv.Itoa(proxyPort))) } return args } diff --git a/pkg/proxy/proxier_test.go b/pkg/proxy/proxier_test.go index 196a4d5e71e..410c7bb1f6a 100644 --- a/pkg/proxy/proxier_test.go +++ b/pkg/proxy/proxier_test.go @@ -93,6 +93,10 @@ func (fake *fakeIptables) DeleteRule(table iptables.Table, chain iptables.Chain, return nil } +func (fake *fakeIptables) IsIpv6() bool { + return false +} + var tcpServerPort string var udpServerPort string diff --git a/pkg/util/iptables/iptables.go b/pkg/util/iptables/iptables.go index 5253c2d200b..d4dab06df32 100644 --- a/pkg/util/iptables/iptables.go +++ b/pkg/util/iptables/iptables.go @@ -34,8 +34,17 @@ type Interface interface { EnsureRule(table Table, chain Chain, args ...string) (bool, error) // DeleteRule checks if the specified rule is present and, if so, deletes it. DeleteRule(table Table, chain Chain, args ...string) error + // IsIpv6 returns true if this is managing ipv6 tables + IsIpv6() bool } +type Protocol bool + +const ( + ProtocolIpv4 Protocol = false + ProtocolIpv6 Protocol = true +) + type Table string const ( @@ -51,13 +60,14 @@ const ( // runner implements Interface in terms of exec("iptables"). type runner struct { - mu sync.Mutex - exec utilexec.Interface + mu sync.Mutex + exec utilexec.Interface + protocol Protocol } // New returns a new Interface which will exec iptables. -func New(exec utilexec.Interface) Interface { - return &runner{exec: exec} +func New(exec utilexec.Interface, protocol Protocol) Interface { + return &runner{exec: exec, protocol: protocol} } // EnsureChain is part of Interface. @@ -135,8 +145,20 @@ func (runner *runner) DeleteRule(table Table, chain Chain, args ...string) error return nil } +func (runner *runner) IsIpv6() bool { + return runner.protocol == ProtocolIpv6 +} + +func (runner *runner) iptablesCommand() string { + if runner.IsIpv6() { + return "ip6tables" + } else { + return "iptables" + } +} + func (runner *runner) run(op operation, args []string) ([]byte, error) { - const iptablesCmd = "iptables" + iptablesCmd := runner.iptablesCommand() fullArgs := append([]string{string(op)}, args...) glog.V(1).Infof("running iptables %s %v", string(op), args) diff --git a/pkg/util/iptables/iptables_test.go b/pkg/util/iptables/iptables_test.go index f027ab351b0..34bdc99f521 100644 --- a/pkg/util/iptables/iptables_test.go +++ b/pkg/util/iptables/iptables_test.go @@ -23,7 +23,17 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/util/exec" ) -func TestEnsureChain(t *testing.T) { +func getIptablesCommand(protocol Protocol) string { + if protocol == ProtocolIpv4 { + return "iptables" + } + if protocol == ProtocolIpv6 { + return "ip6tables" + } + panic("Unknown protocol") +} + +func testEnsureChain(t *testing.T, protocol Protocol) { fcmd := exec.FakeCmd{ CombinedOutputScript: []exec.FakeCombinedOutputAction{ // Success. @@ -41,7 +51,7 @@ func TestEnsureChain(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec) + runner := New(&fexec, protocol) // Success. exists, err := runner.EnsureChain(TableNAT, Chain("FOOBAR")) if err != nil { @@ -53,7 +63,8 @@ func TestEnsureChain(t *testing.T) { if fcmd.CombinedOutputCalls != 1 { t.Errorf("expected 1 CombinedOutput() call, got %d", fcmd.CombinedOutputCalls) } - if !util.NewStringSet(fcmd.CombinedOutputLog[0]...).HasAll("iptables", "-t", "nat", "-N", "FOOBAR") { + cmd := getIptablesCommand(protocol) + if !util.NewStringSet(fcmd.CombinedOutputLog[0]...).HasAll(cmd, "-t", "nat", "-N", "FOOBAR") { t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[0]) } // Exists. @@ -71,6 +82,14 @@ func TestEnsureChain(t *testing.T) { } } +func TestEnsureChainIpv4(t *testing.T) { + testEnsureChain(t, ProtocolIpv4) +} + +func TestEnsureChainIpv6(t *testing.T) { + testEnsureChain(t, ProtocolIpv6) +} + func TestFlushChain(t *testing.T) { fcmd := exec.FakeCmd{ CombinedOutputScript: []exec.FakeCombinedOutputAction{ @@ -86,7 +105,7 @@ func TestFlushChain(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec) + runner := New(&fexec, ProtocolIpv4) // Success. err := runner.FlushChain(TableNAT, Chain("FOOBAR")) if err != nil { @@ -118,7 +137,7 @@ func TestEnsureRuleAlreadyExists(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec) + runner := New(&fexec, ProtocolIpv4) exists, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123") if err != nil { t.Errorf("expected success, got %+v", err) @@ -150,7 +169,7 @@ func TestEnsureRuleNew(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec) + runner := New(&fexec, ProtocolIpv4) exists, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123") if err != nil { t.Errorf("expected success, got %+v", err) @@ -179,7 +198,7 @@ func TestEnsureRuleErrorChecking(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec) + runner := New(&fexec, ProtocolIpv4) _, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123") if err == nil { t.Errorf("expected failure") @@ -205,7 +224,7 @@ func TestEnsureRuleErrorCreating(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec) + runner := New(&fexec, ProtocolIpv4) _, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123") if err == nil { t.Errorf("expected failure") @@ -228,7 +247,7 @@ func TestDeleteRuleAlreadyExists(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec) + runner := New(&fexec, ProtocolIpv4) err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123") if err != nil { t.Errorf("expected success, got %+v", err) @@ -257,7 +276,7 @@ func TestDeleteRuleNew(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec) + runner := New(&fexec, ProtocolIpv4) err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123") if err != nil { t.Errorf("expected success, got %+v", err) @@ -283,7 +302,7 @@ func TestDeleteRuleErrorChecking(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec) + runner := New(&fexec, ProtocolIpv4) err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123") if err == nil { t.Errorf("expected failure") @@ -309,7 +328,7 @@ func TestDeleteRuleErrorCreating(t *testing.T) { func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, }, } - runner := New(&fexec) + runner := New(&fexec, ProtocolIpv4) err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123") if err == nil { t.Errorf("expected failure") From 8e70a664e894113d4c262667d00bf345e198e316 Mon Sep 17 00:00:00 2001 From: Justin SB Date: Tue, 4 Nov 2014 06:33:34 -0800 Subject: [PATCH 2/5] Extend container_bridge.py (salt lib) to support IPv6 --- .../saltbase/salt/_states/container_bridge.py | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/cluster/saltbase/salt/_states/container_bridge.py b/cluster/saltbase/salt/_states/container_bridge.py index 63158926c25..ed64d71dd10 100644 --- a/cluster/saltbase/salt/_states/container_bridge.py +++ b/cluster/saltbase/salt/_states/container_bridge.py @@ -34,11 +34,22 @@ def ensure(name, cidr, mtu=1460): ''' ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''} - iptables_rule = { - 'table': 'nat', - 'chain': 'POSTROUTING', - 'rule': '-o eth0 -j MASQUERADE \! -d 10.0.0.0/8' - } + # This is a little hacky. I should probably import a real library for this + # but this'll work for now. + try: + cidr_network = ipaddr.IPNetwork(cidr, strict=True) + except Exception: + raise salt.exceptions.SaltInvocationError( + 'Invalid CIDR \'{0}\''.format(cidr)) + + if cidr_network.version == 4: + iptables_rule = { + 'table': 'nat', + 'chain': 'POSTROUTING', + 'rule': '-o eth0 -j MASQUERADE \! -d 10.0.0.0/8' + } + else: + iptables_rule = None def bridge_exists(name): 'Determine if a bridge exists already.' @@ -90,20 +101,15 @@ def ensure(name, cidr, mtu=1460): ret['details'] = {} # This module function is strange and returns True if the rule exists. # If not, it returns a string with the error from the call to iptables. - ret['iptables_rule_exists'] = \ - __salt__['iptables.check'](**iptables_rule) == True + if iptables_rule: + ret['iptables_rule_exists'] = \ + __salt__['iptables.check'](**iptables_rule) == True + else: + ret['iptables_rule_exists'] = True return ret - # This is a little hacky. I should probably import a real library for this - # but this'll work for now. - try: - cidr_network = ipaddr.IPv4Network(cidr, strict=True) - except Exception: - raise salt.exceptions.SaltInvocationError( - 'Invalid CIDR \'{0}\''.format(cidr)) - desired_network = '{0}/{1}'.format( - str(ipaddr.IPv4Address(cidr_network._ip + 1)), + str(ipaddr.IPAddress(cidr_network._ip + 1)), str(cidr_network.prefixlen)) current_state = get_current_state() @@ -147,7 +153,7 @@ def ensure(name, cidr, mtu=1460): __salt__['cmd.run']( 'ip link set dev {0} up'.format(name)) new_state = get_current_state() - if not new_state['iptables_rule_exists']: + if iptables_rule and not new_state['iptables_rule_exists']: __salt__['iptables.append'](**iptables_rule) new_state = get_current_state() From ddaa716de10cd02913e0f3dff4d2ed7e91fa9417 Mon Sep 17 00:00:00 2001 From: Justin SB Date: Tue, 4 Nov 2014 14:12:59 -0800 Subject: [PATCH 3/5] Allow specification of docker daemon args --- cluster/saltbase/salt/docker/docker-defaults | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cluster/saltbase/salt/docker/docker-defaults b/cluster/saltbase/salt/docker/docker-defaults index 1317593c272..115a0bb2475 100644 --- a/cluster/saltbase/salt/docker/docker-defaults +++ b/cluster/saltbase/salt/docker/docker-defaults @@ -1 +1,6 @@ -DOCKER_OPTS="--bridge cbr0 --iptables=false --ip-masq=false -r=false" +{% if grains.docker_opts is defined %} + {% set docker_opts = grains.docker_opts %} +{% else %} + {% set docker_opts = "" %} +{% endif %} +DOCKER_OPTS="{{docker_opts}} --bridge cbr0 --iptables=false --ip-masq=false -r=false" From 04313ff1734ca23ebf690ca150389e588ce7d1c8 Mon Sep 17 00:00:00 2001 From: Justin SB Date: Thu, 6 Nov 2014 21:26:26 -0800 Subject: [PATCH 4/5] Create ip_allocator that copes with IPv6 It uses a set (via a map) of allocated IPs --- pkg/registry/service/ip_allocator.go | 195 ++++++++++++++-------- pkg/registry/service/ip_allocator_test.go | 66 ++------ pkg/registry/service/rest_test.go | 8 + 3 files changed, 145 insertions(+), 124 deletions(-) diff --git a/pkg/registry/service/ip_allocator.go b/pkg/registry/service/ip_allocator.go index 947c0a64534..21f475b3061 100644 --- a/pkg/registry/service/ip_allocator.go +++ b/pkg/registry/service/ip_allocator.go @@ -18,17 +18,67 @@ package service import ( "fmt" + math_rand "math/rand" "net" "sync" + "time" "github.com/golang/glog" ) type ipAllocator struct { - subnet *net.IPNet - // TODO: This could be smarter, but for now a bitmap will suffice. lock sync.Mutex // protects 'used' - used []byte // a bitmap of allocated IPs + + subnet net.IPNet + ipSpaceSize int64 // Size of subnet, or -1 if it does not fit in an int64 + used ipAddrSet + randomAttempts int + + random *math_rand.Rand +} + +type ipAddrSet struct { + // We are pretty severely restricted in the types of things we can use as a key + ips map[string]bool +} + +func (s *ipAddrSet) Init() { + s.ips = map[string]bool{} +} + +// Adds to the ipAddrSet; returns true iff it was added (was not already in set) +func (s *ipAddrSet) Size() int { + return len(s.ips) +} + +func (s *ipAddrSet) Contains(ip net.IP) bool { + key := ip.String() + exists := s.ips[key] + return exists +} + +// Adds to the ipAddrSet; returns true iff it was added (was not already in set) +func (s *ipAddrSet) Add(ip net.IP) bool { + key := ip.String() + exists := s.ips[key] + if exists { + return false + } + s.ips[key] = true + return true +} + +// Removes from the ipAddrSet; returns true iff it was removed (was already in set) +func (s *ipAddrSet) Remove(ip net.IP) bool { + key := ip.String() + exists := s.ips[key] + if !exists { + return false + } + delete(s.ips, key) + // TODO: We probably should add this IP to an 'embargo' list for a limited amount of time + + return true } // The smallest number of IPs we accept. @@ -40,20 +90,42 @@ func newIPAllocator(subnet *net.IPNet) *ipAllocator { return nil } + seed := time.Now().UTC().UnixNano() + r := math_rand.New(math_rand.NewSource(seed)) + + ipSpaceSize := int64(-1) ones, bits := subnet.Mask.Size() - // TODO: some settings with IPv6 address could cause this to take - // an excessive amount of memory. - numIps := 1 << uint(bits-ones) - if numIps < minIPSpace { - glog.Errorf("IPAllocator requires at least %d IPs", minIPSpace) - return nil + if (bits-ones) < 63 { + ipSpaceSize = int64(1)<>= 8 - offset += result / 256 // carry + offset += result/256 // carry } return out } -// Subtract two IPs, returning the difference as an offset - used or splitting an IP into -// network addr and host addr parts. -func ipSub(lhs, rhs net.IP) int { - // If they are not the same length, normalize them. Make copies because net.IP is - // a slice underneath. Sneaky sneaky. - lhs = simplifyIP(lhs) - rhs = simplifyIP(rhs) - if len(lhs) != len(rhs) { - lhs = copyIP(lhs).To16() - rhs = copyIP(rhs).To16() - } - offset := 0 - borrow := 0 - // Loop from most-significant to least. - for i := range lhs { - offset <<= 8 - result := (int(lhs[i]) - borrow) - int(rhs[i]) - if result < 0 { - borrow = 1 - } else { - borrow = 0 - } - offset += result - } - return offset -} - // Get the optimal slice for an IP. IPv4 addresses will come back in a 4 byte slice. IPv6 // addresses will come back in a 16 byte slice. Non-IP arguments will produce nil. func simplifyIP(in net.IP) net.IP { @@ -176,9 +234,6 @@ func (ipa *ipAllocator) Release(ip net.IP) error { if !ipa.subnet.Contains(ip) { return fmt.Errorf("IP %s does not fall within subnet %s", ip, ipa.subnet) } - offset := ipSub(ip, ipa.subnet.IP) - i := offset / 8 - m := byte(1 << byte(offset%8)) - ipa.used[i] &^= m + ipa.used.Remove(ip) return nil } diff --git a/pkg/registry/service/ip_allocator_test.go b/pkg/registry/service/ip_allocator_test.go index db5147806f1..677015de31c 100644 --- a/pkg/registry/service/ip_allocator_test.go +++ b/pkg/registry/service/ip_allocator_test.go @@ -36,13 +36,16 @@ func TestNew(t *testing.T) { if ipa == nil { t.Errorf("expected non-nil") } - if len(ipa.used) != 128 { // a /22 has 1024 IPs, 8 per byte = 128 - t.Errorf("wrong size for ipa.used") + if ipa.ipSpaceSize != 1024 { + t.Errorf("wrong size for ipa.ipSpaceSize") } - if ipa.used[0] != 0x01 { + if ipa.used.Size() != 2 { + t.Errorf("wrong size() for ipa.used") + } + if !ipa.used.Contains(net.ParseIP("93.76.0.0")) { t.Errorf("network address was not reserved") } - if ipa.used[127] != 0x80 { + if !ipa.used.Contains(net.ParseIP("93.76.3.255")) { t.Errorf("broadcast address was not reserved") } } @@ -68,6 +71,9 @@ func TestAllocateNext(t *testing.T) { _, ipnet, _ := net.ParseCIDR("93.76.0.0/22") ipa := newIPAllocator(ipnet) + // Turn off random allocation attempts, so we just allocate in sequence + ipa.randomAttempts = 0 + ip1, err := ipa.AllocateNext() if err != nil { t.Error(err) @@ -128,6 +134,8 @@ func TestRelease(t *testing.T) { _, ipnet, _ := net.ParseCIDR("93.76.0.0/24") ipa := newIPAllocator(ipnet) + ipa.randomAttempts = 0 + err := ipa.Release(net.ParseIP("1.2.3.4")) if err == nil { t.Errorf("Expected an error") @@ -172,31 +180,6 @@ func TestRelease(t *testing.T) { } } -func TestFFS(t *testing.T) { - _, err := ffs(0) - if err == nil { - t.Errorf("Expected error") - } - - testCases := []struct { - value byte - expected uint - }{ - {0x01, 0}, {0x02, 1}, {0x04, 2}, {0x08, 3}, - {0x10, 4}, {0x20, 5}, {0x40, 6}, {0x80, 7}, - {0x22, 1}, {0xa0, 5}, {0xfe, 1}, {0xff, 0}, - } - for _, tc := range testCases { - r, err := ffs(tc.value) - if err != nil { - t.Error(err) - } - if r != tc.expected { - t.Errorf("Expected %d, got %d", tc.expected, r) - } - } -} - func TestIPAdd(t *testing.T) { testCases := []struct { ip string @@ -223,31 +206,6 @@ func TestIPAdd(t *testing.T) { } } -func TestIPSub(t *testing.T) { - testCases := []struct { - lhs string - rhs string - expected int - }{ - {"1.2.3.0", "1.2.3.0", 0}, - {"1.2.3.1", "1.2.3.0", 1}, - {"1.2.3.255", "1.2.3.0", 255}, - {"1.2.4.0", "1.2.3.0", 256}, - {"1.2.4.0", "1.2.3.255", 1}, - {"1.2.4.1", "1.2.3.0", 257}, - {"1.3.3.0", "1.2.3.0", 65536}, - {"1.2.3.5", "1.2.3.4", 1}, - {"0.0.0.0", "0.0.0.1", -1}, - {"0.0.1.0", "0.0.0.1", 255}, - } - for _, tc := range testCases { - r := ipSub(net.ParseIP(tc.lhs), net.ParseIP(tc.rhs)) - if r != tc.expected { - t.Errorf("Expected %v, got %v", tc.expected, r) - } - } -} - func TestCopyIP(t *testing.T) { ip1 := net.ParseIP("1.2.3.4") ip2 := copyIP(ip1) diff --git a/pkg/registry/service/rest_test.go b/pkg/registry/service/rest_test.go index 0ddf6435fcc..4533b53f816 100644 --- a/pkg/registry/service/rest_test.go +++ b/pkg/registry/service/rest_test.go @@ -44,6 +44,8 @@ func TestServiceRegistryCreate(t *testing.T) { fakeCloud := &cloud.FakeCloud{} machines := []string{"foo", "bar", "baz"} storage := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t)) + storage.portalMgr.randomAttempts = 0 + svc := &api.Service{ Port: 6502, ObjectMeta: api.ObjectMeta{Name: "foo"}, @@ -414,6 +416,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) { fakeCloud := &cloud.FakeCloud{} machines := []string{"foo", "bar", "baz"} rest := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t)) + rest.portalMgr.randomAttempts = 0 svc1 := &api.Service{ Port: 6502, @@ -467,6 +470,7 @@ func TestServiceRegistryIPReallocation(t *testing.T) { fakeCloud := &cloud.FakeCloud{} machines := []string{"foo", "bar", "baz"} rest := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t)) + rest.portalMgr.randomAttempts = 0 svc1 := &api.Service{ Port: 6502, @@ -509,6 +513,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) { fakeCloud := &cloud.FakeCloud{} machines := []string{"foo", "bar", "baz"} rest := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t)) + rest.portalMgr.randomAttempts = 0 svc := &api.Service{ Port: 6502, @@ -561,6 +566,7 @@ func TestServiceRegistryIPExternalLoadBalancer(t *testing.T) { fakeCloud := &cloud.FakeCloud{} machines := []string{"foo", "bar", "baz"} rest := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t)) + rest.portalMgr.randomAttempts = 0 svc := &api.Service{ Port: 6502, @@ -588,6 +594,7 @@ func TestServiceRegistryIPReloadFromStorage(t *testing.T) { fakeCloud := &cloud.FakeCloud{} machines := []string{"foo", "bar", "baz"} rest1 := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t)) + rest1.portalMgr.randomAttempts = 0 svc := &api.Service{ Port: 6502, @@ -607,6 +614,7 @@ func TestServiceRegistryIPReloadFromStorage(t *testing.T) { // This will reload from storage, finding the previous 2 rest2 := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t)) + rest2.portalMgr.randomAttempts = 0 svc = &api.Service{ Port: 6502, From b19170f33576c7d0dc64f9ff70faa44718bf2ba8 Mon Sep 17 00:00:00 2001 From: Justin SB Date: Fri, 7 Nov 2014 06:34:18 -0800 Subject: [PATCH 5/5] gofmt --- pkg/registry/service/ip_allocator.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/registry/service/ip_allocator.go b/pkg/registry/service/ip_allocator.go index 21f475b3061..6fb288c1b1f 100644 --- a/pkg/registry/service/ip_allocator.go +++ b/pkg/registry/service/ip_allocator.go @@ -95,8 +95,8 @@ func newIPAllocator(subnet *net.IPNet) *ipAllocator { ipSpaceSize := int64(-1) ones, bits := subnet.Mask.Size() - if (bits-ones) < 63 { - ipSpaceSize = int64(1)<>= 8 - offset += result/256 // carry + offset += result / 256 // carry } return out }