Eradicate the last vestiges of CIDR in Allocator
This commit is contained in:
1 parent
e21f66db0a
commit
fa0b0042b2
7 files changed
+47
-50
No files matched your search
@@ -49,19 +49,15 @@ func (cidr CIDR) Size() Offset { return 1 << uint(32-cidr.PrefixLen) }
|
||||
// End is exclusive, same as in Range
|
||||
func (cidr CIDR) End() Address { return Add(cidr.Start, cidr.Size()) }
|
||||
func (cidr CIDR) Range() Range { return Range{Start: cidr.Start, End: Add(cidr.Start, cidr.Size())} }
|
||||
func (cidr CIDR) HostRange() Range {
|
||||
// Respect RFC1122 exclusions of first and last addresses
|
||||
return Range{Start: cidr.Start + 1, End: cidr.End() - 1}
|
||||
}
|
||||
|
||||
func (cidr CIDR) String() string {
|
||||
return fmt.Sprintf("%s/%d", cidr.Start.String(), cidr.PrefixLen)
|
||||
}
|
||||
|
||||
func (cidr1 CIDR) Overlaps(cidr2 CIDR) bool {
|
||||
return !(cidr1.Start >= cidr2.End() || cidr1.End() <= cidr2.Start)
|
||||
}
|
||||
|
||||
func (cidr CIDR) Contains(addr Address) bool {
|
||||
return addr >= cidr.Start && addr < cidr.End()
|
||||
}
|
||||
|
||||
// FromIP4 converts an ipv4 address to our integer address type
|
||||
func FromIP4(ip4 net.IP) (r Address) {
|
||||
for _, b := range ip4.To4() {
|
||||
|
||||
+5
-7
@@ -178,22 +178,20 @@ func hasBeenCancelled(cancelChan <-chan bool) func() bool {
|
||||
|
||||
// Allocate (Sync) - get IP address for container with given name
|
||||
// if there isn't any space we block indefinitely
|
||||
func (alloc *Allocator) Allocate(ident string, subnet address.CIDR, cancelChan <-chan bool) (address.CIDR, error) {
|
||||
func (alloc *Allocator) Allocate(ident string, r address.Range, cancelChan <-chan bool) (address.Address, error) {
|
||||
resultChan := make(chan allocateResult)
|
||||
// Respect RFC1122 exclusions of first and last addresses
|
||||
r := address.Range{Start: subnet.Start + 1, End: subnet.End() - 1}
|
||||
op := &allocate{r: r, resultChan: resultChan, ident: ident,
|
||||
hasBeenCancelled: hasBeenCancelled(cancelChan)}
|
||||
alloc.doOperation(op, &alloc.pendingAllocates)
|
||||
result := <-resultChan
|
||||
return address.CIDR{Start: result.addr, PrefixLen: subnet.PrefixLen}, result.err
|
||||
return result.addr, result.err
|
||||
}
|
||||
|
||||
func (alloc *Allocator) Lookup(ident string, subnet address.CIDR) (address.CIDR, error) {
|
||||
func (alloc *Allocator) Lookup(ident string, r address.Range) (address.Address, error) {
|
||||
resultChan := make(chan allocateResult)
|
||||
alloc.actionChan <- func() {
|
||||
for _, addr := range alloc.owned[ident] {
|
||||
if subnet.Contains(addr) {
|
||||
if r.Contains(addr) {
|
||||
resultChan <- allocateResult{addr: addr}
|
||||
return
|
||||
}
|
||||
@@ -201,7 +199,7 @@ func (alloc *Allocator) Lookup(ident string, subnet address.CIDR) (address.CIDR,
|
||||
resultChan <- allocateResult{err: fmt.Errorf("lookup: no address found")}
|
||||
}
|
||||
result := <-resultChan
|
||||
return address.CIDR{Start: result.addr, PrefixLen: subnet.PrefixLen}, result.err
|
||||
return result.addr, result.err
|
||||
}
|
||||
|
||||
// Claim an address that we think we should own (Sync)
|
||||
|
||||
+13
-13
@@ -27,8 +27,8 @@ func TestAllocFree(t *testing.T) {
|
||||
universe = "10.0.3.0/26"
|
||||
subnet1 = "10.0.3.0/28"
|
||||
subnet2 = "10.0.3.32/28"
|
||||
testAddr1 = "10.0.3.1/28"
|
||||
testAddr2 = "10.0.3.33/28"
|
||||
testAddr1 = "10.0.3.1"
|
||||
testAddr2 = "10.0.3.33"
|
||||
spaceSize = 62 // 64 IP addresses in /26, minus .0 and .63
|
||||
)
|
||||
|
||||
@@ -38,31 +38,31 @@ func TestAllocFree(t *testing.T) {
|
||||
_, cidr2, _ := address.ParseCIDR(subnet2)
|
||||
|
||||
alloc.claimRingForTesting()
|
||||
addr1, err := alloc.Allocate(container1, cidr1, nil)
|
||||
addr1, err := alloc.Allocate(container1, cidr1.HostRange(), nil)
|
||||
wt.AssertNoErr(t, err)
|
||||
wt.AssertEqualString(t, addr1.String(), testAddr1, "address")
|
||||
|
||||
addr2, err := alloc.Allocate(container1, cidr2, nil)
|
||||
addr2, err := alloc.Allocate(container1, cidr2.HostRange(), nil)
|
||||
wt.AssertNoErr(t, err)
|
||||
wt.AssertEqualString(t, addr2.String(), testAddr2, "address")
|
||||
|
||||
// Ask for another address for a different container and check it's different
|
||||
addr1b, _ := alloc.Allocate(container2, cidr1, nil)
|
||||
addr1b, _ := alloc.Allocate(container2, cidr1.HostRange(), nil)
|
||||
if addr1b.String() == testAddr1 {
|
||||
t.Fatalf("Expected different address but got %s", addr1b.String())
|
||||
}
|
||||
|
||||
// Ask for the first container again and we should get the same addresses again
|
||||
addr1a, _ := alloc.Allocate(container1, cidr1, nil)
|
||||
addr1a, _ := alloc.Allocate(container1, cidr1.HostRange(), nil)
|
||||
wt.AssertEqualString(t, addr1a.String(), testAddr1, "address")
|
||||
addr2a, _ := alloc.Allocate(container1, cidr2, nil)
|
||||
addr2a, _ := alloc.Allocate(container1, cidr2.HostRange(), nil)
|
||||
wt.AssertEqualString(t, addr2a.String(), testAddr2, "address")
|
||||
|
||||
// Now delete the first container, and we should get its addresses back
|
||||
wt.AssertSuccess(t, alloc.Delete(container1))
|
||||
addr3, _ := alloc.Allocate(container3, cidr1, nil)
|
||||
addr3, _ := alloc.Allocate(container3, cidr1.HostRange(), nil)
|
||||
wt.AssertEqualString(t, addr3.String(), testAddr1, "address")
|
||||
addr4, _ := alloc.Allocate(container3, cidr2, nil)
|
||||
addr4, _ := alloc.Allocate(container3, cidr2.HostRange(), nil)
|
||||
wt.AssertEqualString(t, addr4.String(), testAddr2, "address")
|
||||
|
||||
alloc.ContainerDied(container2)
|
||||
@@ -134,7 +134,7 @@ func TestAllocatorClaim(t *testing.T) {
|
||||
container2 = "baddf00d"
|
||||
container3 = "b01df00d"
|
||||
universe = "10.0.3.0/30"
|
||||
testAddr1 = "10.0.3.1/30" // first address allocated should be .1 because .0 is network addr
|
||||
testAddr1 = "10.0.3.1" // first address allocated should be .1 because .0 is network addr
|
||||
)
|
||||
|
||||
alloc, subnet := makeAllocatorWithMockGossip(t, "01:00:00:01:00:00", universe, 1)
|
||||
@@ -384,7 +384,7 @@ func TestAllocatorFuzz(t *testing.T) {
|
||||
alloc := allocs[res.alloc]
|
||||
//common.Info.Printf("Freeing %s (%s) on allocator %d", res.name, addr, res.alloc)
|
||||
|
||||
oldAddr, _, err := address.ParseCIDR(addr)
|
||||
oldAddr, err := address.ParseIP(addr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -406,8 +406,8 @@ func TestAllocatorFuzz(t *testing.T) {
|
||||
//common.Info.Printf("Asking for %s on allocator %d again", addr, res.alloc)
|
||||
|
||||
newAddr, _ := alloc.Allocate(res.name, subnet, nil)
|
||||
oldAddr, _, _ := address.ParseCIDR(addr)
|
||||
if newAddr.Start != oldAddr {
|
||||
oldAddr, _ := address.ParseIP(addr)
|
||||
if newAddr != oldAddr {
|
||||
panic(fmt.Sprintf("Got different address for repeat request for %s: %s != %s", res.name, newAddr, oldAddr))
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -41,21 +41,21 @@ func (alloc *Allocator) HandleHTTP(router *mux.Router, defaultSubnet address.CID
|
||||
badRequest(w, err)
|
||||
return
|
||||
}
|
||||
addr, err := alloc.Lookup(vars["id"], subnet)
|
||||
addr, err := alloc.Lookup(vars["id"], subnet.HostRange())
|
||||
if err != nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
fmt.Fprint(w, addr)
|
||||
fmt.Fprintf(w, "%s/%d", addr, subnet.PrefixLen)
|
||||
})
|
||||
|
||||
router.Methods("GET").Path("/ip/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
addr, err := alloc.Lookup(mux.Vars(r)["id"], defaultSubnet)
|
||||
addr, err := alloc.Lookup(mux.Vars(r)["id"], defaultSubnet.HostRange())
|
||||
if err != nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
fmt.Fprint(w, addr)
|
||||
fmt.Fprintf(w, "%s/%d", addr, defaultSubnet.PrefixLen)
|
||||
})
|
||||
|
||||
router.Methods("POST").Path("/ip/{id}/{ip}/{prefixlen}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -72,25 +72,25 @@ func (alloc *Allocator) HandleHTTP(router *mux.Router, defaultSubnet address.CID
|
||||
badRequest(w, fmt.Errorf("Invalid subnet %s - bits after network prefix are not all zero", cidrStr))
|
||||
return
|
||||
}
|
||||
addr, err := alloc.Allocate(ident, cidr, closedChan)
|
||||
addr, err := alloc.Allocate(ident, cidr.HostRange(), closedChan)
|
||||
if err != nil {
|
||||
badRequest(w, fmt.Errorf("Unable to allocate: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprint(w, addr)
|
||||
fmt.Fprintf(w, "%s/%d", addr, cidr.PrefixLen)
|
||||
})
|
||||
|
||||
router.Methods("POST").Path("/ip/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
closedChan := w.(http.CloseNotifier).CloseNotify()
|
||||
ident := mux.Vars(r)["id"]
|
||||
newAddr, err := alloc.Allocate(ident, defaultSubnet, closedChan)
|
||||
newAddr, err := alloc.Allocate(ident, defaultSubnet.HostRange(), closedChan)
|
||||
if err != nil {
|
||||
badRequest(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprint(w, newAddr)
|
||||
fmt.Fprintf(w, "%s/%d", newAddr, defaultSubnet.PrefixLen)
|
||||
})
|
||||
|
||||
router.Methods("DELETE").Path("/ip/{id}/{ip}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
+9
-6
@@ -80,8 +80,9 @@ func TestHttp(t *testing.T) {
|
||||
testAddr2 = "10.2.0.1/16"
|
||||
)
|
||||
|
||||
alloc, subnet := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", universe, 1)
|
||||
port := listenHTTP(alloc, subnet)
|
||||
alloc, _ := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", universe, 1)
|
||||
_, cidr, _ := address.ParseCIDR(universe)
|
||||
port := listenHTTP(alloc, cidr)
|
||||
alloc.claimRingForTesting()
|
||||
|
||||
// Allocate an address in each subnet, and check we got what we expected
|
||||
@@ -120,9 +121,10 @@ func TestBadHttp(t *testing.T) {
|
||||
testCIDR1 = "10.0.0.0/8"
|
||||
)
|
||||
|
||||
alloc, subnet := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1)
|
||||
alloc, _ := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1)
|
||||
defer alloc.Stop()
|
||||
port := listenHTTP(alloc, subnet)
|
||||
_, cidr, _ := address.ParseCIDR(testCIDR1)
|
||||
port := listenHTTP(alloc, cidr)
|
||||
|
||||
alloc.claimRingForTesting()
|
||||
cidr1 := HTTPPost(t, allocURL(port, testCIDR1, containerID))
|
||||
@@ -155,10 +157,11 @@ func impTestHTTPCancel(t *testing.T) {
|
||||
testCIDR1 = "10.0.3.0/29"
|
||||
)
|
||||
|
||||
alloc, subnet := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1)
|
||||
alloc, _ := makeAllocatorWithMockGossip(t, "08:00:27:01:c3:9a", testCIDR1, 1)
|
||||
defer alloc.Stop()
|
||||
alloc.claimRingForTesting()
|
||||
port := listenHTTP(alloc, subnet)
|
||||
_, cidr, _ := address.ParseCIDR(testCIDR1)
|
||||
port := listenHTTP(alloc, cidr)
|
||||
|
||||
// Stop the alloc so nothing actually works
|
||||
unpause := alloc.pause()
|
||||
|
||||
@@ -128,7 +128,7 @@ func CheckAllExpectedMessagesSent(allocs ...*Allocator) {
|
||||
}
|
||||
}
|
||||
|
||||
func makeAllocator(name string, cidrStr string, quorum uint) (*Allocator, address.CIDR) {
|
||||
func makeAllocator(name string, cidrStr string, quorum uint) (*Allocator, address.Range) {
|
||||
peername, err := router.PeerNameFromString(name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -142,10 +142,10 @@ func makeAllocator(name string, cidrStr string, quorum uint) (*Allocator, addres
|
||||
alloc := NewAllocator(peername, router.PeerUID(rand.Int63()),
|
||||
"nick-"+name, cidr.Range(), quorum)
|
||||
|
||||
return alloc, cidr
|
||||
return alloc, cidr.HostRange()
|
||||
}
|
||||
|
||||
func makeAllocatorWithMockGossip(t *testing.T, name string, universeCIDR string, quorum uint) (*Allocator, address.CIDR) {
|
||||
func makeAllocatorWithMockGossip(t *testing.T, name string, universeCIDR string, quorum uint) (*Allocator, address.Range) {
|
||||
alloc, subnet := makeAllocator(name, universeCIDR, quorum)
|
||||
gossip := &mockGossipComms{t: t, name: name}
|
||||
alloc.SetInterfaces(gossip)
|
||||
@@ -162,10 +162,10 @@ func (alloc *Allocator) claimRingForTesting(allocs ...*Allocator) {
|
||||
alloc.space.AddRanges(alloc.ring.OwnedRanges())
|
||||
}
|
||||
|
||||
func (alloc *Allocator) NumFreeAddresses(subnet address.CIDR) address.Offset {
|
||||
func (alloc *Allocator) NumFreeAddresses(r address.Range) address.Offset {
|
||||
resultChan := make(chan address.Offset)
|
||||
alloc.actionChan <- func() {
|
||||
resultChan <- alloc.space.NumFreeAddressesInRange(address.MakeRange(subnet.Start+1, subnet.Size()-2))
|
||||
resultChan <- alloc.space.NumFreeAddressesInRange(r)
|
||||
}
|
||||
return <-resultChan
|
||||
}
|
||||
@@ -287,11 +287,11 @@ func (client TestGossipRouterClient) GossipBroadcast(update router.GossipData) e
|
||||
return client.router.GossipBroadcast(update)
|
||||
}
|
||||
|
||||
func makeNetworkOfAllocators(size int, cidr string) ([]*Allocator, TestGossipRouter, address.CIDR) {
|
||||
func makeNetworkOfAllocators(size int, cidr string) ([]*Allocator, TestGossipRouter, address.Range) {
|
||||
|
||||
gossipRouter := TestGossipRouter{make(map[router.PeerName]chan gossipMessage), 0.0}
|
||||
allocs := make([]*Allocator, size)
|
||||
var subnet address.CIDR
|
||||
var subnet address.Range
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
var alloc *Allocator
|
||||
|
||||
+1
-1
@@ -214,7 +214,7 @@ func createAllocator(router *weave.Router, apiPath string, ipRangeStr string, de
|
||||
defaultSubnet := ipRange
|
||||
if defaultSubnetStr != "" {
|
||||
defaultSubnet = parseAndCheckCIDR(defaultSubnetStr)
|
||||
if !ipRange.Overlaps(defaultSubnet) {
|
||||
if !ipRange.Range().Overlaps(defaultSubnet.Range()) {
|
||||
log.Fatalf("Default subnet %s out of bounds: %s", defaultSubnet, ipRange)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user