Browse code

libnetwork: drop DatastoreConfig discovery type

The DatastoreConfig discovery type is unused. Remove the constant and
any resulting dead code. Today's biggest loser is the IPAM Allocator:
DatastoreConfig was the only type of discovery event it was listening
for, and there was no other place where a non-nil datastore could be
passed into the allocator. Strip out all the dead persistence code from
Allocator, leaving it as purely an in-memory implementation.

There is no more need to check the consistency of the allocator's
bit-sequences as there is no persistent storage for inconsistent bit
sequences to be loaded from.

Signed-off-by: Cory Snider <csnider@mirantis.com>

Cory Snider authored on 2023/01/25 08:49:24
Showing 10 changed files
... ...
@@ -16,8 +16,6 @@ type DiscoveryType int
16 16
 const (
17 17
 	// NodeDiscovery represents Node join/leave events provided by discovery
18 18
 	NodeDiscovery = iota + 1
19
-	// DatastoreConfig represents an add/remove datastore event
20
-	DatastoreConfig
21 19
 	// EncryptionKeysConfig represents the initial key(s) for performing datapath encryption
22 20
 	EncryptionKeysConfig
23 21
 	// EncryptionKeysUpdate represents an update to the datapath encryption key(s)
... ...
@@ -319,7 +319,6 @@ func (d *driver) pushLocalEndpointEvent(action, nid, eid string) {
319 319
 
320 320
 // DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
321 321
 func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
322
-	var err error
323 322
 	switch dType {
324 323
 	case discoverapi.NodeDiscovery:
325 324
 		nodeData, ok := data.(discoverapi.NodeDiscoveryData)
... ...
@@ -327,18 +326,6 @@ func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{})
327 327
 			return fmt.Errorf("invalid discovery data")
328 328
 		}
329 329
 		d.nodeJoin(nodeData.Address, nodeData.BindAddress, nodeData.Self)
330
-	case discoverapi.DatastoreConfig:
331
-		if d.store != nil {
332
-			return types.ForbiddenErrorf("cannot accept datastore configuration: Overlay driver has a datastore configured already")
333
-		}
334
-		dsc, ok := data.(discoverapi.DatastoreConfigData)
335
-		if !ok {
336
-			return types.InternalErrorf("incorrect data in datastore configuration: %v", data)
337
-		}
338
-		d.store, err = datastore.NewDataStoreFromConfig(dsc)
339
-		if err != nil {
340
-			return types.InternalErrorf("failed to initialize data store: %v", err)
341
-		}
342 330
 	case discoverapi.EncryptionKeysConfig:
343 331
 		encrData, ok := data.(discoverapi.DriverEncryptionConfig)
344 332
 		if !ok {
... ...
@@ -7,8 +7,6 @@ import (
7 7
 	"sync"
8 8
 
9 9
 	"github.com/docker/docker/libnetwork/bitseq"
10
-	"github.com/docker/docker/libnetwork/datastore"
11
-	"github.com/docker/docker/libnetwork/discoverapi"
12 10
 	"github.com/docker/docker/libnetwork/ipamapi"
13 11
 	"github.com/docker/docker/libnetwork/types"
14 12
 	"github.com/sirupsen/logrus"
... ...
@@ -17,9 +15,6 @@ import (
17 17
 const (
18 18
 	localAddressSpace  = "LocalDefault"
19 19
 	globalAddressSpace = "GlobalDefault"
20
-	// datastore keyes for ipam objects
21
-	dsConfigKey = "ipam/" + ipamapi.DefaultIPAM + "/config"
22
-	dsDataKey   = "ipam/" + ipamapi.DefaultIPAM + "/data"
23 20
 )
24 21
 
25 22
 // Allocator provides per address space ipv4/ipv6 book keeping
... ...
@@ -28,168 +23,37 @@ type Allocator struct {
28 28
 	// Separate from the addrSpace because they should not be serialized
29 29
 	predefined             map[string][]*net.IPNet
30 30
 	predefinedStartIndices map[string]int
31
-	// The (potentially serialized) address spaces
31
+	// The address spaces
32 32
 	addrSpaces map[string]*addrSpace
33
-	// stores        []datastore.Datastore
34 33
 	// Allocated addresses in each address space's subnet
35 34
 	addresses map[SubnetKey]*bitseq.Handle
36 35
 	sync.Mutex
37 36
 }
38 37
 
39 38
 // NewAllocator returns an instance of libnetwork ipam
40
-func NewAllocator(lcDs, glDs datastore.DataStore, lcAs, glAs []*net.IPNet) (*Allocator, error) {
41
-	a := &Allocator{}
42
-
43
-	// Load predefined subnet pools
44
-
45
-	a.predefined = map[string][]*net.IPNet{
46
-		localAddressSpace:  lcAs,
47
-		globalAddressSpace: glAs,
39
+func NewAllocator(lcAs, glAs []*net.IPNet) (*Allocator, error) {
40
+	a := &Allocator{
41
+		predefined: map[string][]*net.IPNet{
42
+			localAddressSpace:  lcAs,
43
+			globalAddressSpace: glAs,
44
+		},
45
+		predefinedStartIndices: map[string]int{},
46
+		addresses:              map[SubnetKey]*bitseq.Handle{},
48 47
 	}
49 48
 
50
-	// Initialize asIndices map
51
-	a.predefinedStartIndices = make(map[string]int)
52
-
53
-	// Initialize bitseq map
54
-	a.addresses = make(map[SubnetKey]*bitseq.Handle)
55
-
56
-	// Initialize address spaces
57
-	a.addrSpaces = make(map[string]*addrSpace)
58
-	for _, aspc := range []struct {
59
-		as string
60
-		ds datastore.DataStore
61
-	}{
62
-		{localAddressSpace, lcDs},
63
-		{globalAddressSpace, glDs},
64
-	} {
65
-		a.initializeAddressSpace(aspc.as, aspc.ds)
49
+	a.addrSpaces = map[string]*addrSpace{
50
+		localAddressSpace:  a.newAddressSpace(),
51
+		globalAddressSpace: a.newAddressSpace(),
66 52
 	}
67 53
 
68 54
 	return a, nil
69 55
 }
70 56
 
71
-func (a *Allocator) refresh(as string) error {
72
-	aSpace, err := a.getAddressSpaceFromStore(as)
73
-	if err != nil {
74
-		return types.InternalErrorf("error getting pools config from store: %v", err)
75
-	}
76
-
77
-	if aSpace == nil {
78
-		return nil
79
-	}
80
-
81
-	a.Lock()
82
-	a.addrSpaces[as] = aSpace
83
-	a.Unlock()
84
-
85
-	return nil
86
-}
87
-
88
-func (a *Allocator) updateBitMasks(aSpace *addrSpace) error {
89
-	var inserterList []func() error
90
-
91
-	aSpace.Lock()
92
-	for k, v := range aSpace.subnets {
93
-		if v.Range == nil {
94
-			kk := k
95
-			vv := v
96
-			inserterList = append(inserterList, func() error { return a.insertBitMask(kk, vv.Pool) })
97
-		}
98
-	}
99
-	aSpace.Unlock()
100
-
101
-	// Add the bitmasks (data could come from datastore)
102
-	for _, f := range inserterList {
103
-		if err := f(); err != nil {
104
-			return err
105
-		}
106
-	}
107
-
108
-	return nil
109
-}
110
-
111
-// Checks for and fixes damaged bitmask.
112
-func (a *Allocator) checkConsistency(as string) {
113
-	var sKeyList []SubnetKey
114
-
115
-	// Retrieve this address space's configuration and bitmasks from the datastore
116
-	a.refresh(as)
117
-	a.Lock()
118
-	aSpace, ok := a.addrSpaces[as]
119
-	a.Unlock()
120
-	if !ok {
121
-		return
122
-	}
123
-	a.updateBitMasks(aSpace)
124
-
125
-	aSpace.Lock()
126
-	for sk, pd := range aSpace.subnets {
127
-		if pd.Range != nil {
128
-			continue
129
-		}
130
-		sKeyList = append(sKeyList, sk)
131
-	}
132
-	aSpace.Unlock()
133
-
134
-	for _, sk := range sKeyList {
135
-		a.Lock()
136
-		bm := a.addresses[sk]
137
-		a.Unlock()
138
-		if err := bm.CheckConsistency(); err != nil {
139
-			logrus.Warnf("Error while running consistency check for %s: %v", sk, err)
140
-		}
141
-	}
142
-}
143
-
144
-func (a *Allocator) initializeAddressSpace(as string, ds datastore.DataStore) error {
145
-	scope := ""
146
-	if ds != nil {
147
-		scope = ds.Scope()
148
-	}
149
-
150
-	a.Lock()
151
-	if currAS, ok := a.addrSpaces[as]; ok {
152
-		if currAS.ds != nil {
153
-			a.Unlock()
154
-			return types.ForbiddenErrorf("a datastore is already configured for the address space %s", as)
155
-		}
156
-	}
157
-	a.addrSpaces[as] = &addrSpace{
57
+func (a *Allocator) newAddressSpace() *addrSpace {
58
+	return &addrSpace{
158 59
 		subnets: map[SubnetKey]*PoolData{},
159
-		id:      dsConfigKey + "/" + as,
160
-		scope:   scope,
161
-		ds:      ds,
162 60
 		alloc:   a,
163 61
 	}
164
-	a.Unlock()
165
-
166
-	a.checkConsistency(as)
167
-
168
-	return nil
169
-}
170
-
171
-// DiscoverNew informs the allocator about a new global scope datastore
172
-func (a *Allocator) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
173
-	if dType != discoverapi.DatastoreConfig {
174
-		return nil
175
-	}
176
-
177
-	dsc, ok := data.(discoverapi.DatastoreConfigData)
178
-	if !ok {
179
-		return types.InternalErrorf("incorrect data in datastore update notification: %v", data)
180
-	}
181
-
182
-	ds, err := datastore.NewDataStoreFromConfig(dsc)
183
-	if err != nil {
184
-		return err
185
-	}
186
-
187
-	return a.initializeAddressSpace(globalAddressSpace, ds)
188
-}
189
-
190
-// DiscoverDelete is a notification of no interest for the allocator
191
-func (a *Allocator) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
192
-	return nil
193 62
 }
194 63
 
195 64
 // GetDefaultAddressSpaces returns the local and global default address spaces
... ...
@@ -220,10 +84,6 @@ retry:
220 220
 		k = &SubnetKey{AddressSpace: addressSpace, Subnet: nw.String()}
221 221
 	}
222 222
 
223
-	if err := a.refresh(addressSpace); err != nil {
224
-		return "", nil, nil, err
225
-	}
226
-
227 223
 	aSpace, err := a.getAddrSpace(addressSpace)
228 224
 	if err != nil {
229 225
 		return "", nil, nil, err
... ...
@@ -238,14 +98,6 @@ retry:
238 238
 		return "", nil, nil, err
239 239
 	}
240 240
 
241
-	if err := a.writeToStore(aSpace); err != nil {
242
-		if _, ok := err.(types.RetryError); !ok {
243
-			return "", nil, nil, types.InternalErrorf("pool configuration failed because of %s", err.Error())
244
-		}
245
-
246
-		goto retry
247
-	}
248
-
249 241
 	return k.String(), nw, nil, insert()
250 242
 }
251 243
 
... ...
@@ -257,11 +109,6 @@ func (a *Allocator) ReleasePool(poolID string) error {
257 257
 		return types.BadRequestErrorf("invalid pool id: %s", poolID)
258 258
 	}
259 259
 
260
-retry:
261
-	if err := a.refresh(k.AddressSpace); err != nil {
262
-		return err
263
-	}
264
-
265 260
 	aSpace, err := a.getAddrSpace(k.AddressSpace)
266 261
 	if err != nil {
267 262
 		return err
... ...
@@ -272,13 +119,6 @@ retry:
272 272
 		return err
273 273
 	}
274 274
 
275
-	if err = a.writeToStore(aSpace); err != nil {
276
-		if _, ok := err.(types.RetryError); !ok {
277
-			return types.InternalErrorf("pool (%s) removal failed because of %v", poolID, err)
278
-		}
279
-		goto retry
280
-	}
281
-
282 275
 	return remove()
283 276
 }
284 277
 
... ...
@@ -289,7 +129,7 @@ func (a *Allocator) getAddrSpace(as string) (*addrSpace, error) {
289 289
 	defer a.Unlock()
290 290
 	aSpace, ok := a.addrSpaces[as]
291 291
 	if !ok {
292
-		return nil, types.BadRequestErrorf("cannot find address space %s (most likely the backing datastore is not configured)", as)
292
+		return nil, types.BadRequestErrorf("cannot find address space %s", as)
293 293
 	}
294 294
 	return aSpace, nil
295 295
 }
... ...
@@ -331,7 +171,6 @@ func (a *Allocator) parsePoolRequest(addressSpace, pool, subPool string, v6 bool
331 331
 func (a *Allocator) insertBitMask(key SubnetKey, pool *net.IPNet) error {
332 332
 	//logrus.Debugf("Inserting bitmask (%s, %s)", key.String(), pool.String())
333 333
 
334
-	store := a.getStore(key.AddressSpace)
335 334
 	ipVer := getAddressVersion(pool.IP)
336 335
 	ones, bits := pool.Mask.Size()
337 336
 	numAddresses := uint64(1 << uint(bits-ones))
... ...
@@ -341,8 +180,8 @@ func (a *Allocator) insertBitMask(key SubnetKey, pool *net.IPNet) error {
341 341
 		numAddresses--
342 342
 	}
343 343
 
344
-	// Generate the new address masks. AddressMask content may come from datastore
345
-	h, err := bitseq.NewHandle(dsDataKey, store, key.String(), numAddresses)
344
+	// Generate the new address masks.
345
+	h, err := bitseq.NewHandle("", nil, "", numAddresses)
346 346
 	if err != nil {
347 347
 		return err
348 348
 	}
... ...
@@ -372,7 +211,7 @@ func (a *Allocator) retrieveBitmask(k SubnetKey, n *net.IPNet) (*bitseq.Handle,
372 372
 	if !ok {
373 373
 		logrus.Debugf("Retrieving bitmask (%s, %s)", k.String(), n.String())
374 374
 		if err := a.insertBitMask(k, n); err != nil {
375
-			return nil, types.InternalErrorf("could not find bitmask in datastore for %s", k.String())
375
+			return nil, types.InternalErrorf("could not find bitmask for %s", k.String())
376 376
 		}
377 377
 		a.Lock()
378 378
 		bm = a.addresses[k]
... ...
@@ -452,10 +291,6 @@ func (a *Allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[s
452 452
 		return nil, nil, types.BadRequestErrorf("invalid pool id: %s", poolID)
453 453
 	}
454 454
 
455
-	if err := a.refresh(k.AddressSpace); err != nil {
456
-		return nil, nil, err
457
-	}
458
-
459 455
 	aSpace, err := a.getAddrSpace(k.AddressSpace)
460 456
 	if err != nil {
461 457
 		return nil, nil, err
... ...
@@ -482,7 +317,7 @@ func (a *Allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[s
482 482
 
483 483
 	bm, err := a.retrieveBitmask(k, c.Pool)
484 484
 	if err != nil {
485
-		return nil, nil, types.InternalErrorf("could not find bitmask in datastore for %s on address %v request from pool %s: %v",
485
+		return nil, nil, types.InternalErrorf("could not find bitmask for %s on address %v request from pool %s: %v",
486 486
 			k.String(), prefAddress, poolID, err)
487 487
 	}
488 488
 	// In order to request for a serial ip address allocation, callers can pass in the option to request
... ...
@@ -509,10 +344,6 @@ func (a *Allocator) ReleaseAddress(poolID string, address net.IP) error {
509 509
 		return types.BadRequestErrorf("invalid pool id: %s", poolID)
510 510
 	}
511 511
 
512
-	if err := a.refresh(k.AddressSpace); err != nil {
513
-		return err
514
-	}
515
-
516 512
 	aSpace, err := a.getAddrSpace(k.AddressSpace)
517 513
 	if err != nil {
518 514
 		return err
... ...
@@ -551,7 +382,7 @@ func (a *Allocator) ReleaseAddress(poolID string, address net.IP) error {
551 551
 
552 552
 	bm, err := a.retrieveBitmask(k, c.Pool)
553 553
 	if err != nil {
554
-		return types.InternalErrorf("could not find bitmask in datastore for %s on address %v release from pool %s: %v",
554
+		return types.InternalErrorf("could not find bitmask for %s on address %v release from pool %s: %v",
555 555
 			k.String(), address, poolID, err)
556 556
 	}
557 557
 	defer logrus.Debugf("Released address PoolID:%s, Address:%v Sequence:%s", poolID, address, bm.String())
... ...
@@ -1,70 +1,24 @@
1 1
 package ipam
2 2
 
3 3
 import (
4
-	"encoding/json"
5 4
 	"flag"
6 5
 	"fmt"
7 6
 	"math/rand"
8 7
 	"net"
9
-	"os"
10
-	"path/filepath"
11 8
 	"strconv"
12 9
 	"sync"
13 10
 	"testing"
14 11
 	"time"
15 12
 
16 13
 	"github.com/docker/docker/libnetwork/bitseq"
17
-	"github.com/docker/docker/libnetwork/datastore"
18 14
 	"github.com/docker/docker/libnetwork/ipamapi"
19 15
 	"github.com/docker/docker/libnetwork/ipamutils"
20 16
 	"github.com/docker/docker/libnetwork/types"
21
-	"github.com/docker/libkv/store"
22
-	"github.com/docker/libkv/store/boltdb"
23 17
 	"golang.org/x/sync/errgroup"
24 18
 	"gotest.tools/v3/assert"
25 19
 	is "gotest.tools/v3/assert/cmp"
26 20
 )
27 21
 
28
-var (
29
-	defaultPrefix = filepath.Join(os.TempDir(), "libnetwork", "test", "ipam")
30
-)
31
-
32
-func init() {
33
-	boltdb.Register()
34
-}
35
-
36
-// OptionBoltdbWithRandomDBFile function returns a random dir for local store backend
37
-func randomLocalStore(needStore bool) (datastore.DataStore, error) {
38
-	if !needStore {
39
-		return nil, nil
40
-	}
41
-	tmp, err := os.CreateTemp("", "libnetwork-")
42
-	if err != nil {
43
-		return nil, fmt.Errorf("Error creating temp file: %v", err)
44
-	}
45
-	if err := tmp.Close(); err != nil {
46
-		return nil, fmt.Errorf("Error closing temp file: %v", err)
47
-	}
48
-	return datastore.NewDataStore(datastore.ScopeCfg{
49
-		Client: datastore.ScopeClientCfg{
50
-			Provider: "boltdb",
51
-			Address:  filepath.Join(defaultPrefix, filepath.Base(tmp.Name())),
52
-			Config: &store.Config{
53
-				Bucket:            "libnetwork",
54
-				ConnectionTimeout: 3 * time.Second,
55
-			},
56
-		},
57
-	})
58
-}
59
-
60
-func getAllocator(store bool) (*Allocator, error) {
61
-	ds, err := randomLocalStore(store)
62
-	if err != nil {
63
-		return nil, err
64
-	}
65
-	return NewAllocator(ds, nil, ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
66
-}
67
-
68 22
 func TestInt2IP2IntConversion(t *testing.T) {
69 23
 	for i := uint64(0); i < 256*256*256; i++ {
70 24
 		var array [4]byte // new array at each cycle
... ...
@@ -122,741 +76,611 @@ func TestKeyString(t *testing.T) {
122 122
 	}
123 123
 }
124 124
 
125
-func TestPoolDataMarshal(t *testing.T) {
126
-	_, nw, err := net.ParseCIDR("172.28.30.1/24")
125
+func TestAddSubnets(t *testing.T) {
126
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
127 127
 	if err != nil {
128 128
 		t.Fatal(err)
129 129
 	}
130
+	a.addrSpaces["abc"] = a.addrSpaces[localAddressSpace]
130 131
 
131
-	p := &PoolData{
132
-		ParentKey: SubnetKey{AddressSpace: "Blue", Subnet: "172.28.0.0/16"},
133
-		Pool:      nw,
134
-		Range:     &AddressRange{Sub: &net.IPNet{IP: net.IP{172, 28, 20, 0}, Mask: net.IPMask{255, 255, 255, 0}}, Start: 0, End: 255},
135
-		RefCount:  4,
132
+	pid0, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
133
+	if err != nil {
134
+		t.Fatal("Unexpected failure in adding subnet")
136 135
 	}
137 136
 
138
-	ba, err := json.Marshal(p)
137
+	pid1, _, _, err := a.RequestPool("abc", "10.0.0.0/8", "", nil, false)
139 138
 	if err != nil {
140
-		t.Fatal(err)
139
+		t.Fatalf("Unexpected failure in adding overlapping subnets to different address spaces: %v", err)
141 140
 	}
142
-	var q PoolData
143
-	err = json.Unmarshal(ba, &q)
144
-	if err != nil {
145
-		t.Fatal(err)
141
+
142
+	if pid0 == pid1 {
143
+		t.Fatal("returned same pool id for same subnets in different namespaces")
146 144
 	}
147 145
 
148
-	if p.ParentKey != q.ParentKey || !types.CompareIPNet(p.Range.Sub, q.Range.Sub) ||
149
-		p.Range.Start != q.Range.Start || p.Range.End != q.Range.End || p.RefCount != q.RefCount ||
150
-		!types.CompareIPNet(p.Pool, q.Pool) {
151
-		t.Fatalf("\n%#v\n%#v", p, &q)
146
+	_, _, _, err = a.RequestPool("abc", "10.0.0.0/8", "", nil, false)
147
+	if err == nil {
148
+		t.Fatalf("Expected failure requesting existing subnet")
152 149
 	}
153 150
 
154
-	p = &PoolData{
155
-		ParentKey: SubnetKey{AddressSpace: "Blue", Subnet: "172.28.0.0/16"},
156
-		Pool:      nw,
157
-		RefCount:  4,
151
+	_, _, _, err = a.RequestPool("abc", "10.128.0.0/9", "", nil, false)
152
+	if err == nil {
153
+		t.Fatal("Expected failure on adding overlapping base subnet")
158 154
 	}
159 155
 
160
-	ba, err = json.Marshal(p)
156
+	_, _, _, err = a.RequestPool("abc", "10.0.0.0/8", "10.128.0.0/9", nil, false)
161 157
 	if err != nil {
162
-		t.Fatal(err)
158
+		t.Fatalf("Unexpected failure on adding sub pool: %v", err)
163 159
 	}
164
-	err = json.Unmarshal(ba, &q)
165
-	if err != nil {
166
-		t.Fatal(err)
160
+	_, _, _, err = a.RequestPool("abc", "10.0.0.0/8", "10.128.0.0/9", nil, false)
161
+	if err == nil {
162
+		t.Fatalf("Expected failure on adding overlapping sub pool")
167 163
 	}
168 164
 
169
-	if q.Range != nil {
170
-		t.Fatal("Unexpected Range")
165
+	_, _, _, err = a.RequestPool(localAddressSpace, "10.20.2.0/24", "", nil, false)
166
+	if err == nil {
167
+		t.Fatal("Failed to detect overlapping subnets")
171 168
 	}
172
-}
173
-
174
-func TestSubnetsMarshal(t *testing.T) {
175
-	for _, store := range []bool{false, true} {
176
-		a, err := getAllocator(store)
177
-		if err != nil {
178
-			t.Fatal(err)
179
-		}
180
-		pid0, _, _, err := a.RequestPool(localAddressSpace, "192.168.0.0/16", "", nil, false)
181
-		if err != nil {
182
-			t.Fatal(err)
183
-		}
184
-		pid1, _, _, err := a.RequestPool(localAddressSpace, "192.169.0.0/16", "", nil, false)
185
-		if err != nil {
186
-			t.Fatal(err)
187
-		}
188
-		_, _, err = a.RequestAddress(pid0, nil, nil)
189
-		if err != nil {
190
-			t.Fatal(err)
191
-		}
192
-
193
-		cfg, err := a.getAddrSpace(localAddressSpace)
194
-		if err != nil {
195
-			t.Fatal(err)
196
-		}
197
-
198
-		ba := cfg.Value()
199
-		if err := cfg.SetValue(ba); err != nil {
200
-			t.Fatal(err)
201
-		}
202 169
 
203
-		expIP := &net.IPNet{IP: net.IP{192, 168, 0, 2}, Mask: net.IPMask{255, 255, 0, 0}}
204
-		ip, _, err := a.RequestAddress(pid0, nil, nil)
205
-		if err != nil {
206
-			t.Fatal(err)
207
-		}
208
-		if !types.CompareIPNet(expIP, ip) {
209
-			t.Fatalf("Got unexpected ip after pool config restore: %s", ip)
210
-		}
211
-
212
-		expIP = &net.IPNet{IP: net.IP{192, 169, 0, 1}, Mask: net.IPMask{255, 255, 0, 0}}
213
-		ip, _, err = a.RequestAddress(pid1, nil, nil)
214
-		if err != nil {
215
-			t.Fatal(err)
216
-		}
217
-		if !types.CompareIPNet(expIP, ip) {
218
-			t.Fatalf("Got unexpected ip after pool config restore: %s", ip)
219
-		}
170
+	_, _, _, err = a.RequestPool(localAddressSpace, "10.128.0.0/9", "", nil, false)
171
+	if err == nil {
172
+		t.Fatal("Failed to detect overlapping subnets")
220 173
 	}
221
-}
222
-
223
-func TestAddSubnets(t *testing.T) {
224
-	for _, store := range []bool{false, true} {
225
-		a, err := getAllocator(store)
226
-		if err != nil {
227
-			t.Fatal(err)
228
-		}
229
-		a.addrSpaces["abc"] = a.addrSpaces[localAddressSpace]
230
-
231
-		pid0, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
232
-		if err != nil {
233
-			t.Fatal("Unexpected failure in adding subnet")
234
-		}
235
-
236
-		pid1, _, _, err := a.RequestPool("abc", "10.0.0.0/8", "", nil, false)
237
-		if err != nil {
238
-			t.Fatalf("Unexpected failure in adding overlapping subnets to different address spaces: %v", err)
239
-		}
240 174
 
241
-		if pid0 == pid1 {
242
-			t.Fatal("returned same pool id for same subnets in different namespaces")
243
-		}
244
-
245
-		_, _, _, err = a.RequestPool("abc", "10.0.0.0/8", "", nil, false)
246
-		if err == nil {
247
-			t.Fatalf("Expected failure requesting existing subnet")
248
-		}
249
-
250
-		_, _, _, err = a.RequestPool("abc", "10.128.0.0/9", "", nil, false)
251
-		if err == nil {
252
-			t.Fatal("Expected failure on adding overlapping base subnet")
253
-		}
254
-
255
-		_, _, _, err = a.RequestPool("abc", "10.0.0.0/8", "10.128.0.0/9", nil, false)
256
-		if err != nil {
257
-			t.Fatalf("Unexpected failure on adding sub pool: %v", err)
258
-		}
259
-		_, _, _, err = a.RequestPool("abc", "10.0.0.0/8", "10.128.0.0/9", nil, false)
260
-		if err == nil {
261
-			t.Fatalf("Expected failure on adding overlapping sub pool")
262
-		}
263
-
264
-		_, _, _, err = a.RequestPool(localAddressSpace, "10.20.2.0/24", "", nil, false)
265
-		if err == nil {
266
-			t.Fatal("Failed to detect overlapping subnets")
267
-		}
268
-
269
-		_, _, _, err = a.RequestPool(localAddressSpace, "10.128.0.0/9", "", nil, false)
270
-		if err == nil {
271
-			t.Fatal("Failed to detect overlapping subnets")
272
-		}
273
-
274
-		_, _, _, err = a.RequestPool(localAddressSpace, "1003:1:2:3:4:5:6::/112", "", nil, false)
275
-		if err != nil {
276
-			t.Fatalf("Failed to add v6 subnet: %s", err.Error())
277
-		}
175
+	_, _, _, err = a.RequestPool(localAddressSpace, "1003:1:2:3:4:5:6::/112", "", nil, false)
176
+	if err != nil {
177
+		t.Fatalf("Failed to add v6 subnet: %s", err.Error())
178
+	}
278 179
 
279
-		_, _, _, err = a.RequestPool(localAddressSpace, "1003:1:2:3::/64", "", nil, false)
280
-		if err == nil {
281
-			t.Fatal("Failed to detect overlapping v6 subnet")
282
-		}
180
+	_, _, _, err = a.RequestPool(localAddressSpace, "1003:1:2:3::/64", "", nil, false)
181
+	if err == nil {
182
+		t.Fatal("Failed to detect overlapping v6 subnet")
283 183
 	}
284 184
 }
285 185
 
286 186
 // TestDoublePoolRelease tests that releasing a pool which has already
287 187
 // been released raises an error.
288 188
 func TestDoublePoolRelease(t *testing.T) {
289
-	for _, store := range []bool{false, true} {
290
-		a, err := getAllocator(store)
291
-		assert.NilError(t, err)
189
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
190
+	assert.NilError(t, err)
292 191
 
293
-		pid0, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
294
-		assert.NilError(t, err)
192
+	pid0, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
193
+	assert.NilError(t, err)
295 194
 
296
-		err = a.ReleasePool(pid0)
297
-		assert.NilError(t, err)
195
+	err = a.ReleasePool(pid0)
196
+	assert.NilError(t, err)
298 197
 
299
-		err = a.ReleasePool(pid0)
300
-		assert.Check(t, is.ErrorContains(err, ""))
301
-	}
198
+	err = a.ReleasePool(pid0)
199
+	assert.Check(t, is.ErrorContains(err, ""))
302 200
 }
303 201
 
304 202
 func TestAddReleasePoolID(t *testing.T) {
305
-	for _, store := range []bool{false, true} {
306
-		a, err := getAllocator(store)
307
-		assert.NilError(t, err)
203
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
204
+	assert.NilError(t, err)
308 205
 
309
-		var k0, k1 SubnetKey
310
-		_, err = a.getAddrSpace(localAddressSpace)
311
-		if err != nil {
312
-			t.Fatal(err)
313
-		}
206
+	var k0, k1 SubnetKey
207
+	_, err = a.getAddrSpace(localAddressSpace)
208
+	if err != nil {
209
+		t.Fatal(err)
210
+	}
314 211
 
315
-		pid0, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
316
-		if err != nil {
317
-			t.Fatal("Unexpected failure in adding pool")
318
-		}
319
-		if err := k0.FromString(pid0); err != nil {
320
-			t.Fatal(err)
321
-		}
212
+	pid0, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
213
+	if err != nil {
214
+		t.Fatal("Unexpected failure in adding pool")
215
+	}
216
+	if err := k0.FromString(pid0); err != nil {
217
+		t.Fatal(err)
218
+	}
322 219
 
323
-		aSpace, err := a.getAddrSpace(localAddressSpace)
324
-		if err != nil {
325
-			t.Fatal(err)
326
-		}
220
+	aSpace, err := a.getAddrSpace(localAddressSpace)
221
+	if err != nil {
222
+		t.Fatal(err)
223
+	}
327 224
 
328
-		subnets := aSpace.subnets
225
+	subnets := aSpace.subnets
329 226
 
330
-		if subnets[k0].RefCount != 1 {
331
-			t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
332
-		}
227
+	if subnets[k0].RefCount != 1 {
228
+		t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
229
+	}
333 230
 
334
-		pid1, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "10.0.0.0/16", nil, false)
335
-		if err != nil {
336
-			t.Fatal("Unexpected failure in adding sub pool")
337
-		}
338
-		if err := k1.FromString(pid1); err != nil {
339
-			t.Fatal(err)
340
-		}
231
+	pid1, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "10.0.0.0/16", nil, false)
232
+	if err != nil {
233
+		t.Fatal("Unexpected failure in adding sub pool")
234
+	}
235
+	if err := k1.FromString(pid1); err != nil {
236
+		t.Fatal(err)
237
+	}
341 238
 
342
-		if pid0 == pid1 {
343
-			t.Fatalf("Incorrect poolIDs returned %s, %s", pid0, pid1)
344
-		}
239
+	if pid0 == pid1 {
240
+		t.Fatalf("Incorrect poolIDs returned %s, %s", pid0, pid1)
241
+	}
345 242
 
346
-		aSpace, err = a.getAddrSpace(localAddressSpace)
347
-		if err != nil {
348
-			t.Fatal(err)
349
-		}
243
+	aSpace, err = a.getAddrSpace(localAddressSpace)
244
+	if err != nil {
245
+		t.Fatal(err)
246
+	}
350 247
 
351
-		subnets = aSpace.subnets
352
-		if subnets[k1].RefCount != 1 {
353
-			t.Fatalf("Unexpected ref count for %s: %d", k1, subnets[k1].RefCount)
354
-		}
248
+	subnets = aSpace.subnets
249
+	if subnets[k1].RefCount != 1 {
250
+		t.Fatalf("Unexpected ref count for %s: %d", k1, subnets[k1].RefCount)
251
+	}
355 252
 
356
-		_, _, _, err = a.RequestPool(localAddressSpace, "10.0.0.0/8", "10.0.0.0/16", nil, false)
357
-		if err == nil {
358
-			t.Fatal("Expected failure in adding sub pool")
359
-		}
253
+	_, _, _, err = a.RequestPool(localAddressSpace, "10.0.0.0/8", "10.0.0.0/16", nil, false)
254
+	if err == nil {
255
+		t.Fatal("Expected failure in adding sub pool")
256
+	}
360 257
 
361
-		aSpace, err = a.getAddrSpace(localAddressSpace)
362
-		if err != nil {
363
-			t.Fatal(err)
364
-		}
258
+	aSpace, err = a.getAddrSpace(localAddressSpace)
259
+	if err != nil {
260
+		t.Fatal(err)
261
+	}
365 262
 
366
-		subnets = aSpace.subnets
263
+	subnets = aSpace.subnets
367 264
 
368
-		if subnets[k0].RefCount != 2 {
369
-			t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
370
-		}
265
+	if subnets[k0].RefCount != 2 {
266
+		t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
267
+	}
371 268
 
372
-		if err := a.ReleasePool(pid1); err != nil {
373
-			t.Fatal(err)
374
-		}
269
+	if err := a.ReleasePool(pid1); err != nil {
270
+		t.Fatal(err)
271
+	}
375 272
 
376
-		aSpace, err = a.getAddrSpace(localAddressSpace)
377
-		if err != nil {
378
-			t.Fatal(err)
379
-		}
273
+	aSpace, err = a.getAddrSpace(localAddressSpace)
274
+	if err != nil {
275
+		t.Fatal(err)
276
+	}
380 277
 
381
-		subnets = aSpace.subnets
382
-		if subnets[k0].RefCount != 1 {
383
-			t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
384
-		}
385
-		if err := a.ReleasePool(pid0); err != nil {
386
-			t.Fatal(err)
387
-		}
278
+	subnets = aSpace.subnets
279
+	if subnets[k0].RefCount != 1 {
280
+		t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
281
+	}
282
+	if err := a.ReleasePool(pid0); err != nil {
283
+		t.Fatal(err)
284
+	}
388 285
 
389
-		pid00, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
390
-		if err != nil {
391
-			t.Fatal("Unexpected failure in adding pool")
392
-		}
393
-		if pid00 != pid0 {
394
-			t.Fatal("main pool should still exist")
395
-		}
286
+	pid00, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
287
+	if err != nil {
288
+		t.Fatal("Unexpected failure in adding pool")
289
+	}
290
+	if pid00 != pid0 {
291
+		t.Fatal("main pool should still exist")
292
+	}
396 293
 
397
-		aSpace, err = a.getAddrSpace(localAddressSpace)
398
-		if err != nil {
399
-			t.Fatal(err)
400
-		}
294
+	aSpace, err = a.getAddrSpace(localAddressSpace)
295
+	if err != nil {
296
+		t.Fatal(err)
297
+	}
401 298
 
402
-		subnets = aSpace.subnets
403
-		if subnets[k0].RefCount != 1 {
404
-			t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
405
-		}
299
+	subnets = aSpace.subnets
300
+	if subnets[k0].RefCount != 1 {
301
+		t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
302
+	}
406 303
 
407
-		if err := a.ReleasePool(pid00); err != nil {
408
-			t.Fatal(err)
409
-		}
304
+	if err := a.ReleasePool(pid00); err != nil {
305
+		t.Fatal(err)
306
+	}
410 307
 
411
-		aSpace, err = a.getAddrSpace(localAddressSpace)
412
-		if err != nil {
413
-			t.Fatal(err)
414
-		}
308
+	aSpace, err = a.getAddrSpace(localAddressSpace)
309
+	if err != nil {
310
+		t.Fatal(err)
311
+	}
415 312
 
416
-		subnets = aSpace.subnets
417
-		if bp, ok := subnets[k0]; ok {
418
-			t.Fatalf("Base pool %s is still present: %v", k0, bp)
419
-		}
313
+	subnets = aSpace.subnets
314
+	if bp, ok := subnets[k0]; ok {
315
+		t.Fatalf("Base pool %s is still present: %v", k0, bp)
316
+	}
420 317
 
421
-		_, _, _, err = a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
422
-		if err != nil {
423
-			t.Fatal("Unexpected failure in adding pool")
424
-		}
318
+	_, _, _, err = a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
319
+	if err != nil {
320
+		t.Fatal("Unexpected failure in adding pool")
321
+	}
425 322
 
426
-		aSpace, err = a.getAddrSpace(localAddressSpace)
427
-		if err != nil {
428
-			t.Fatal(err)
429
-		}
323
+	aSpace, err = a.getAddrSpace(localAddressSpace)
324
+	if err != nil {
325
+		t.Fatal(err)
326
+	}
430 327
 
431
-		subnets = aSpace.subnets
432
-		if subnets[k0].RefCount != 1 {
433
-			t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
434
-		}
328
+	subnets = aSpace.subnets
329
+	if subnets[k0].RefCount != 1 {
330
+		t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
435 331
 	}
436 332
 }
437 333
 
438 334
 func TestPredefinedPool(t *testing.T) {
439
-	for _, store := range []bool{false, true} {
440
-		a, err := getAllocator(store)
441
-		assert.NilError(t, err)
335
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
336
+	assert.NilError(t, err)
442 337
 
443
-		if _, err := a.getPredefinedPool("blue", false); err == nil {
444
-			t.Fatal("Expected failure for non default addr space")
445
-		}
338
+	if _, err := a.getPredefinedPool("blue", false); err == nil {
339
+		t.Fatal("Expected failure for non default addr space")
340
+	}
446 341
 
447
-		pid, nw, _, err := a.RequestPool(localAddressSpace, "", "", nil, false)
448
-		if err != nil {
449
-			t.Fatal(err)
450
-		}
342
+	pid, nw, _, err := a.RequestPool(localAddressSpace, "", "", nil, false)
343
+	if err != nil {
344
+		t.Fatal(err)
345
+	}
451 346
 
452
-		nw2, err := a.getPredefinedPool(localAddressSpace, false)
453
-		if err != nil {
454
-			t.Fatal(err)
455
-		}
456
-		if types.CompareIPNet(nw, nw2) {
457
-			t.Fatalf("Unexpected default network returned: %s = %s", nw2, nw)
458
-		}
347
+	nw2, err := a.getPredefinedPool(localAddressSpace, false)
348
+	if err != nil {
349
+		t.Fatal(err)
350
+	}
351
+	if types.CompareIPNet(nw, nw2) {
352
+		t.Fatalf("Unexpected default network returned: %s = %s", nw2, nw)
353
+	}
459 354
 
460
-		if err := a.ReleasePool(pid); err != nil {
461
-			t.Fatal(err)
462
-		}
355
+	if err := a.ReleasePool(pid); err != nil {
356
+		t.Fatal(err)
463 357
 	}
464 358
 }
465 359
 
466 360
 func TestRemoveSubnet(t *testing.T) {
467
-	for _, store := range []bool{false, true} {
468
-		a, err := getAllocator(store)
469
-		assert.NilError(t, err)
361
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
362
+	assert.NilError(t, err)
470 363
 
471
-		a.addrSpaces["splane"] = &addrSpace{
472
-			id:      dsConfigKey + "/" + "splane",
473
-			ds:      a.addrSpaces[localAddressSpace].ds,
474
-			alloc:   a.addrSpaces[localAddressSpace].alloc,
475
-			scope:   a.addrSpaces[localAddressSpace].scope,
476
-			subnets: map[SubnetKey]*PoolData{},
477
-		}
364
+	a.addrSpaces["splane"] = &addrSpace{
365
+		alloc:   a.addrSpaces[localAddressSpace].alloc,
366
+		subnets: map[SubnetKey]*PoolData{},
367
+	}
478 368
 
479
-		input := []struct {
480
-			addrSpace string
481
-			subnet    string
482
-			v6        bool
483
-		}{
484
-			{localAddressSpace, "192.168.0.0/16", false},
485
-			{localAddressSpace, "172.17.0.0/16", false},
486
-			{localAddressSpace, "10.0.0.0/8", false},
487
-			{localAddressSpace, "2001:db8:1:2:3:4:ffff::/112", false},
488
-			{"splane", "172.17.0.0/16", false},
489
-			{"splane", "10.0.0.0/8", false},
490
-			{"splane", "2001:db8:1:2:3:4:5::/112", true},
491
-			{"splane", "2001:db8:1:2:3:4:ffff::/112", true},
492
-		}
369
+	input := []struct {
370
+		addrSpace string
371
+		subnet    string
372
+		v6        bool
373
+	}{
374
+		{localAddressSpace, "192.168.0.0/16", false},
375
+		{localAddressSpace, "172.17.0.0/16", false},
376
+		{localAddressSpace, "10.0.0.0/8", false},
377
+		{localAddressSpace, "2001:db8:1:2:3:4:ffff::/112", false},
378
+		{"splane", "172.17.0.0/16", false},
379
+		{"splane", "10.0.0.0/8", false},
380
+		{"splane", "2001:db8:1:2:3:4:5::/112", true},
381
+		{"splane", "2001:db8:1:2:3:4:ffff::/112", true},
382
+	}
493 383
 
494
-		poolIDs := make([]string, len(input))
384
+	poolIDs := make([]string, len(input))
495 385
 
496
-		for ind, i := range input {
497
-			if poolIDs[ind], _, _, err = a.RequestPool(i.addrSpace, i.subnet, "", nil, i.v6); err != nil {
498
-				t.Fatalf("Failed to apply input. Can't proceed: %s", err.Error())
499
-			}
386
+	for ind, i := range input {
387
+		if poolIDs[ind], _, _, err = a.RequestPool(i.addrSpace, i.subnet, "", nil, i.v6); err != nil {
388
+			t.Fatalf("Failed to apply input. Can't proceed: %s", err.Error())
500 389
 		}
390
+	}
501 391
 
502
-		for ind, id := range poolIDs {
503
-			if err := a.ReleasePool(id); err != nil {
504
-				t.Fatalf("Failed to release poolID %s (%d)", id, ind)
505
-			}
392
+	for ind, id := range poolIDs {
393
+		if err := a.ReleasePool(id); err != nil {
394
+			t.Fatalf("Failed to release poolID %s (%d)", id, ind)
506 395
 		}
507 396
 	}
508 397
 }
509 398
 
510 399
 func TestGetSameAddress(t *testing.T) {
511
-	for _, store := range []bool{false, true} {
512
-		a, err := getAllocator(store)
513
-		assert.NilError(t, err)
400
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
401
+	assert.NilError(t, err)
514 402
 
515
-		a.addrSpaces["giallo"] = &addrSpace{
516
-			id:      dsConfigKey + "/" + "giallo",
517
-			ds:      a.addrSpaces[localAddressSpace].ds,
518
-			alloc:   a.addrSpaces[localAddressSpace].alloc,
519
-			scope:   a.addrSpaces[localAddressSpace].scope,
520
-			subnets: map[SubnetKey]*PoolData{},
521
-		}
403
+	a.addrSpaces["giallo"] = &addrSpace{
404
+		alloc:   a.addrSpaces[localAddressSpace].alloc,
405
+		subnets: map[SubnetKey]*PoolData{},
406
+	}
522 407
 
523
-		pid, _, _, err := a.RequestPool("giallo", "192.168.100.0/24", "", nil, false)
524
-		if err != nil {
525
-			t.Fatal(err)
526
-		}
408
+	pid, _, _, err := a.RequestPool("giallo", "192.168.100.0/24", "", nil, false)
409
+	if err != nil {
410
+		t.Fatal(err)
411
+	}
527 412
 
528
-		ip := net.ParseIP("192.168.100.250")
529
-		_, _, err = a.RequestAddress(pid, ip, nil)
530
-		if err != nil {
531
-			t.Fatal(err)
532
-		}
413
+	ip := net.ParseIP("192.168.100.250")
414
+	_, _, err = a.RequestAddress(pid, ip, nil)
415
+	if err != nil {
416
+		t.Fatal(err)
417
+	}
533 418
 
534
-		_, _, err = a.RequestAddress(pid, ip, nil)
535
-		if err == nil {
536
-			t.Fatal(err)
537
-		}
419
+	_, _, err = a.RequestAddress(pid, ip, nil)
420
+	if err == nil {
421
+		t.Fatal(err)
538 422
 	}
539 423
 }
540 424
 
541 425
 func TestPoolAllocationReuse(t *testing.T) {
542
-	for _, store := range []bool{false, true} {
543
-		a, err := getAllocator(store)
544
-		assert.NilError(t, err)
426
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
427
+	assert.NilError(t, err)
545 428
 
546
-		// First get all pools until they are exhausted to
547
-		pList := []string{}
548
-		pool, _, _, err := a.RequestPool(localAddressSpace, "", "", nil, false)
549
-		for err == nil {
550
-			pList = append(pList, pool)
551
-			pool, _, _, err = a.RequestPool(localAddressSpace, "", "", nil, false)
552
-		}
553
-		nPools := len(pList)
554
-		for _, pool := range pList {
555
-			if err := a.ReleasePool(pool); err != nil {
556
-				t.Fatal(err)
557
-			}
429
+	// First get all pools until they are exhausted to
430
+	pList := []string{}
431
+	pool, _, _, err := a.RequestPool(localAddressSpace, "", "", nil, false)
432
+	for err == nil {
433
+		pList = append(pList, pool)
434
+		pool, _, _, err = a.RequestPool(localAddressSpace, "", "", nil, false)
435
+	}
436
+	nPools := len(pList)
437
+	for _, pool := range pList {
438
+		if err := a.ReleasePool(pool); err != nil {
439
+			t.Fatal(err)
558 440
 		}
441
+	}
559 442
 
560
-		// Now try to allocate then free nPool pools sequentially.
561
-		// Verify that we don't see any repeat networks even though
562
-		// we have freed them.
563
-		seen := map[string]bool{}
564
-		for i := 0; i < nPools; i++ {
565
-			pool, nw, _, err := a.RequestPool(localAddressSpace, "", "", nil, false)
566
-			if err != nil {
567
-				t.Fatal(err)
568
-			}
569
-			if _, ok := seen[nw.String()]; ok {
570
-				t.Fatalf("Network %s was reused before exhausing the pool list", nw.String())
571
-			}
572
-			seen[nw.String()] = true
573
-			if err := a.ReleasePool(pool); err != nil {
574
-				t.Fatal(err)
575
-			}
443
+	// Now try to allocate then free nPool pools sequentially.
444
+	// Verify that we don't see any repeat networks even though
445
+	// we have freed them.
446
+	seen := map[string]bool{}
447
+	for i := 0; i < nPools; i++ {
448
+		pool, nw, _, err := a.RequestPool(localAddressSpace, "", "", nil, false)
449
+		if err != nil {
450
+			t.Fatal(err)
451
+		}
452
+		if _, ok := seen[nw.String()]; ok {
453
+			t.Fatalf("Network %s was reused before exhausing the pool list", nw.String())
454
+		}
455
+		seen[nw.String()] = true
456
+		if err := a.ReleasePool(pool); err != nil {
457
+			t.Fatal(err)
576 458
 		}
577 459
 	}
578 460
 }
579 461
 
580 462
 func TestGetAddressSubPoolEqualPool(t *testing.T) {
581
-	for _, store := range []bool{false, true} {
582
-		a, err := getAllocator(store)
583
-		assert.NilError(t, err)
463
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
464
+	assert.NilError(t, err)
584 465
 
585
-		// Requesting a subpool of same size of the master pool should not cause any problem on ip allocation
586
-		pid, _, _, err := a.RequestPool(localAddressSpace, "172.18.0.0/16", "172.18.0.0/16", nil, false)
587
-		if err != nil {
588
-			t.Fatal(err)
589
-		}
466
+	// Requesting a subpool of same size of the master pool should not cause any problem on ip allocation
467
+	pid, _, _, err := a.RequestPool(localAddressSpace, "172.18.0.0/16", "172.18.0.0/16", nil, false)
468
+	if err != nil {
469
+		t.Fatal(err)
470
+	}
590 471
 
591
-		_, _, err = a.RequestAddress(pid, nil, nil)
592
-		if err != nil {
593
-			t.Fatal(err)
594
-		}
472
+	_, _, err = a.RequestAddress(pid, nil, nil)
473
+	if err != nil {
474
+		t.Fatal(err)
595 475
 	}
596 476
 }
597 477
 
598 478
 func TestRequestReleaseAddressFromSubPool(t *testing.T) {
599
-	for _, store := range []bool{false, true} {
600
-		a, err := getAllocator(store)
601
-		assert.NilError(t, err)
479
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
480
+	assert.NilError(t, err)
602 481
 
603
-		a.addrSpaces["rosso"] = &addrSpace{
604
-			id:      dsConfigKey + "/" + "rosso",
605
-			ds:      a.addrSpaces[localAddressSpace].ds,
606
-			alloc:   a.addrSpaces[localAddressSpace].alloc,
607
-			scope:   a.addrSpaces[localAddressSpace].scope,
608
-			subnets: map[SubnetKey]*PoolData{},
609
-		}
482
+	a.addrSpaces["rosso"] = &addrSpace{
483
+		alloc:   a.addrSpaces[localAddressSpace].alloc,
484
+		subnets: map[SubnetKey]*PoolData{},
485
+	}
610 486
 
611
-		poolID, _, _, err := a.RequestPool("rosso", "172.28.0.0/16", "172.28.30.0/24", nil, false)
612
-		if err != nil {
613
-			t.Fatal(err)
614
-		}
487
+	poolID, _, _, err := a.RequestPool("rosso", "172.28.0.0/16", "172.28.30.0/24", nil, false)
488
+	if err != nil {
489
+		t.Fatal(err)
490
+	}
615 491
 
616
-		var ip *net.IPNet
617
-		expected := &net.IPNet{IP: net.IP{172, 28, 30, 255}, Mask: net.IPMask{255, 255, 0, 0}}
618
-		for err == nil {
619
-			var c *net.IPNet
620
-			if c, _, err = a.RequestAddress(poolID, nil, nil); err == nil {
621
-				ip = c
622
-			}
623
-		}
624
-		if err != ipamapi.ErrNoAvailableIPs {
625
-			t.Fatal(err)
626
-		}
627
-		if !types.CompareIPNet(expected, ip) {
628
-			t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
629
-		}
630
-		rp := &net.IPNet{IP: net.IP{172, 28, 30, 97}, Mask: net.IPMask{255, 255, 0, 0}}
631
-		if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
632
-			t.Fatal(err)
633
-		}
634
-		if ip, _, err = a.RequestAddress(poolID, nil, nil); err != nil {
635
-			t.Fatal(err)
636
-		}
637
-		if !types.CompareIPNet(rp, ip) {
638
-			t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
492
+	var ip *net.IPNet
493
+	expected := &net.IPNet{IP: net.IP{172, 28, 30, 255}, Mask: net.IPMask{255, 255, 0, 0}}
494
+	for err == nil {
495
+		var c *net.IPNet
496
+		if c, _, err = a.RequestAddress(poolID, nil, nil); err == nil {
497
+			ip = c
639 498
 		}
499
+	}
500
+	if err != ipamapi.ErrNoAvailableIPs {
501
+		t.Fatal(err)
502
+	}
503
+	if !types.CompareIPNet(expected, ip) {
504
+		t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
505
+	}
506
+	rp := &net.IPNet{IP: net.IP{172, 28, 30, 97}, Mask: net.IPMask{255, 255, 0, 0}}
507
+	if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
508
+		t.Fatal(err)
509
+	}
510
+	if ip, _, err = a.RequestAddress(poolID, nil, nil); err != nil {
511
+		t.Fatal(err)
512
+	}
513
+	if !types.CompareIPNet(rp, ip) {
514
+		t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
515
+	}
640 516
 
641
-		_, _, _, err = a.RequestPool("rosso", "10.0.0.0/8", "10.0.0.0/16", nil, false)
642
-		if err != nil {
643
-			t.Fatal(err)
644
-		}
645
-		poolID, _, _, err = a.RequestPool("rosso", "10.0.0.0/16", "10.0.0.0/24", nil, false)
646
-		if err != nil {
647
-			t.Fatal(err)
648
-		}
649
-		expected = &net.IPNet{IP: net.IP{10, 0, 0, 255}, Mask: net.IPMask{255, 255, 0, 0}}
650
-		for err == nil {
651
-			var c *net.IPNet
652
-			if c, _, err = a.RequestAddress(poolID, nil, nil); err == nil {
653
-				ip = c
654
-			}
655
-		}
656
-		if err != ipamapi.ErrNoAvailableIPs {
657
-			t.Fatal(err)
658
-		}
659
-		if !types.CompareIPNet(expected, ip) {
660
-			t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
661
-		}
662
-		rp = &net.IPNet{IP: net.IP{10, 0, 0, 79}, Mask: net.IPMask{255, 255, 0, 0}}
663
-		if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
664
-			t.Fatal(err)
665
-		}
666
-		if ip, _, err = a.RequestAddress(poolID, nil, nil); err != nil {
667
-			t.Fatal(err)
668
-		}
669
-		if !types.CompareIPNet(rp, ip) {
670
-			t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
517
+	_, _, _, err = a.RequestPool("rosso", "10.0.0.0/8", "10.0.0.0/16", nil, false)
518
+	if err != nil {
519
+		t.Fatal(err)
520
+	}
521
+	poolID, _, _, err = a.RequestPool("rosso", "10.0.0.0/16", "10.0.0.0/24", nil, false)
522
+	if err != nil {
523
+		t.Fatal(err)
524
+	}
525
+	expected = &net.IPNet{IP: net.IP{10, 0, 0, 255}, Mask: net.IPMask{255, 255, 0, 0}}
526
+	for err == nil {
527
+		var c *net.IPNet
528
+		if c, _, err = a.RequestAddress(poolID, nil, nil); err == nil {
529
+			ip = c
671 530
 		}
531
+	}
532
+	if err != ipamapi.ErrNoAvailableIPs {
533
+		t.Fatal(err)
534
+	}
535
+	if !types.CompareIPNet(expected, ip) {
536
+		t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
537
+	}
538
+	rp = &net.IPNet{IP: net.IP{10, 0, 0, 79}, Mask: net.IPMask{255, 255, 0, 0}}
539
+	if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
540
+		t.Fatal(err)
541
+	}
542
+	if ip, _, err = a.RequestAddress(poolID, nil, nil); err != nil {
543
+		t.Fatal(err)
544
+	}
545
+	if !types.CompareIPNet(rp, ip) {
546
+		t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
547
+	}
672 548
 
673
-		// Request any addresses from subpool after explicit address request
674
-		unoExp, _ := types.ParseCIDR("10.2.2.0/16")
675
-		dueExp, _ := types.ParseCIDR("10.2.2.2/16")
676
-		treExp, _ := types.ParseCIDR("10.2.2.1/16")
549
+	// Request any addresses from subpool after explicit address request
550
+	unoExp, _ := types.ParseCIDR("10.2.2.0/16")
551
+	dueExp, _ := types.ParseCIDR("10.2.2.2/16")
552
+	treExp, _ := types.ParseCIDR("10.2.2.1/16")
677 553
 
678
-		if poolID, _, _, err = a.RequestPool("rosso", "10.2.0.0/16", "10.2.2.0/24", nil, false); err != nil {
679
-			t.Fatal(err)
680
-		}
681
-		tre, _, err := a.RequestAddress(poolID, treExp.IP, nil)
682
-		if err != nil {
683
-			t.Fatal(err)
684
-		}
685
-		if !types.CompareIPNet(tre, treExp) {
686
-			t.Fatalf("Unexpected address: %v", tre)
687
-		}
554
+	if poolID, _, _, err = a.RequestPool("rosso", "10.2.0.0/16", "10.2.2.0/24", nil, false); err != nil {
555
+		t.Fatal(err)
556
+	}
557
+	tre, _, err := a.RequestAddress(poolID, treExp.IP, nil)
558
+	if err != nil {
559
+		t.Fatal(err)
560
+	}
561
+	if !types.CompareIPNet(tre, treExp) {
562
+		t.Fatalf("Unexpected address: %v", tre)
563
+	}
688 564
 
689
-		uno, _, err := a.RequestAddress(poolID, nil, nil)
690
-		if err != nil {
691
-			t.Fatal(err)
692
-		}
693
-		if !types.CompareIPNet(uno, unoExp) {
694
-			t.Fatalf("Unexpected address: %v", uno)
695
-		}
565
+	uno, _, err := a.RequestAddress(poolID, nil, nil)
566
+	if err != nil {
567
+		t.Fatal(err)
568
+	}
569
+	if !types.CompareIPNet(uno, unoExp) {
570
+		t.Fatalf("Unexpected address: %v", uno)
571
+	}
696 572
 
697
-		due, _, err := a.RequestAddress(poolID, nil, nil)
698
-		if err != nil {
699
-			t.Fatal(err)
700
-		}
701
-		if !types.CompareIPNet(due, dueExp) {
702
-			t.Fatalf("Unexpected address: %v", due)
703
-		}
573
+	due, _, err := a.RequestAddress(poolID, nil, nil)
574
+	if err != nil {
575
+		t.Fatal(err)
576
+	}
577
+	if !types.CompareIPNet(due, dueExp) {
578
+		t.Fatalf("Unexpected address: %v", due)
579
+	}
704 580
 
705
-		if err = a.ReleaseAddress(poolID, uno.IP); err != nil {
706
-			t.Fatal(err)
707
-		}
708
-		uno, _, err = a.RequestAddress(poolID, nil, nil)
709
-		if err != nil {
710
-			t.Fatal(err)
711
-		}
712
-		if !types.CompareIPNet(uno, unoExp) {
713
-			t.Fatalf("Unexpected address: %v", uno)
714
-		}
581
+	if err = a.ReleaseAddress(poolID, uno.IP); err != nil {
582
+		t.Fatal(err)
583
+	}
584
+	uno, _, err = a.RequestAddress(poolID, nil, nil)
585
+	if err != nil {
586
+		t.Fatal(err)
587
+	}
588
+	if !types.CompareIPNet(uno, unoExp) {
589
+		t.Fatalf("Unexpected address: %v", uno)
590
+	}
715 591
 
716
-		if err = a.ReleaseAddress(poolID, tre.IP); err != nil {
717
-			t.Fatal(err)
718
-		}
719
-		tre, _, err = a.RequestAddress(poolID, nil, nil)
720
-		if err != nil {
721
-			t.Fatal(err)
722
-		}
723
-		if !types.CompareIPNet(tre, treExp) {
724
-			t.Fatalf("Unexpected address: %v", tre)
725
-		}
592
+	if err = a.ReleaseAddress(poolID, tre.IP); err != nil {
593
+		t.Fatal(err)
594
+	}
595
+	tre, _, err = a.RequestAddress(poolID, nil, nil)
596
+	if err != nil {
597
+		t.Fatal(err)
598
+	}
599
+	if !types.CompareIPNet(tre, treExp) {
600
+		t.Fatalf("Unexpected address: %v", tre)
726 601
 	}
727 602
 }
728 603
 
729 604
 func TestSerializeRequestReleaseAddressFromSubPool(t *testing.T) {
730 605
 	opts := map[string]string{
731 606
 		ipamapi.AllocSerialPrefix: "true"}
732
-	for _, store := range []bool{false, true} {
733
-		a, err := getAllocator(store)
734
-		assert.NilError(t, err)
607
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
608
+	assert.NilError(t, err)
735 609
 
736
-		a.addrSpaces["rosso"] = &addrSpace{
737
-			id:      dsConfigKey + "/" + "rosso",
738
-			ds:      a.addrSpaces[localAddressSpace].ds,
739
-			alloc:   a.addrSpaces[localAddressSpace].alloc,
740
-			scope:   a.addrSpaces[localAddressSpace].scope,
741
-			subnets: map[SubnetKey]*PoolData{},
742
-		}
610
+	a.addrSpaces["rosso"] = &addrSpace{
611
+		alloc:   a.addrSpaces[localAddressSpace].alloc,
612
+		subnets: map[SubnetKey]*PoolData{},
613
+	}
743 614
 
744
-		poolID, _, _, err := a.RequestPool("rosso", "172.28.0.0/16", "172.28.30.0/24", nil, false)
745
-		if err != nil {
746
-			t.Fatal(err)
747
-		}
615
+	poolID, _, _, err := a.RequestPool("rosso", "172.28.0.0/16", "172.28.30.0/24", nil, false)
616
+	if err != nil {
617
+		t.Fatal(err)
618
+	}
748 619
 
749
-		var ip *net.IPNet
750
-		expected := &net.IPNet{IP: net.IP{172, 28, 30, 255}, Mask: net.IPMask{255, 255, 0, 0}}
751
-		for err == nil {
752
-			var c *net.IPNet
753
-			if c, _, err = a.RequestAddress(poolID, nil, opts); err == nil {
754
-				ip = c
755
-			}
756
-		}
757
-		if err != ipamapi.ErrNoAvailableIPs {
758
-			t.Fatal(err)
759
-		}
760
-		if !types.CompareIPNet(expected, ip) {
761
-			t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
762
-		}
763
-		rp := &net.IPNet{IP: net.IP{172, 28, 30, 97}, Mask: net.IPMask{255, 255, 0, 0}}
764
-		if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
765
-			t.Fatal(err)
766
-		}
767
-		if ip, _, err = a.RequestAddress(poolID, nil, opts); err != nil {
768
-			t.Fatal(err)
769
-		}
770
-		if !types.CompareIPNet(rp, ip) {
771
-			t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
620
+	var ip *net.IPNet
621
+	expected := &net.IPNet{IP: net.IP{172, 28, 30, 255}, Mask: net.IPMask{255, 255, 0, 0}}
622
+	for err == nil {
623
+		var c *net.IPNet
624
+		if c, _, err = a.RequestAddress(poolID, nil, opts); err == nil {
625
+			ip = c
772 626
 		}
627
+	}
628
+	if err != ipamapi.ErrNoAvailableIPs {
629
+		t.Fatal(err)
630
+	}
631
+	if !types.CompareIPNet(expected, ip) {
632
+		t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
633
+	}
634
+	rp := &net.IPNet{IP: net.IP{172, 28, 30, 97}, Mask: net.IPMask{255, 255, 0, 0}}
635
+	if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
636
+		t.Fatal(err)
637
+	}
638
+	if ip, _, err = a.RequestAddress(poolID, nil, opts); err != nil {
639
+		t.Fatal(err)
640
+	}
641
+	if !types.CompareIPNet(rp, ip) {
642
+		t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
643
+	}
773 644
 
774
-		_, _, _, err = a.RequestPool("rosso", "10.0.0.0/8", "10.0.0.0/16", nil, false)
775
-		if err != nil {
776
-			t.Fatal(err)
777
-		}
778
-		poolID, _, _, err = a.RequestPool("rosso", "10.0.0.0/16", "10.0.0.0/24", nil, false)
779
-		if err != nil {
780
-			t.Fatal(err)
781
-		}
782
-		expected = &net.IPNet{IP: net.IP{10, 0, 0, 255}, Mask: net.IPMask{255, 255, 0, 0}}
783
-		for err == nil {
784
-			var c *net.IPNet
785
-			if c, _, err = a.RequestAddress(poolID, nil, opts); err == nil {
786
-				ip = c
787
-			}
788
-		}
789
-		if err != ipamapi.ErrNoAvailableIPs {
790
-			t.Fatal(err)
791
-		}
792
-		if !types.CompareIPNet(expected, ip) {
793
-			t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
794
-		}
795
-		rp = &net.IPNet{IP: net.IP{10, 0, 0, 79}, Mask: net.IPMask{255, 255, 0, 0}}
796
-		if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
797
-			t.Fatal(err)
798
-		}
799
-		if ip, _, err = a.RequestAddress(poolID, nil, opts); err != nil {
800
-			t.Fatal(err)
801
-		}
802
-		if !types.CompareIPNet(rp, ip) {
803
-			t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
645
+	_, _, _, err = a.RequestPool("rosso", "10.0.0.0/8", "10.0.0.0/16", nil, false)
646
+	if err != nil {
647
+		t.Fatal(err)
648
+	}
649
+	poolID, _, _, err = a.RequestPool("rosso", "10.0.0.0/16", "10.0.0.0/24", nil, false)
650
+	if err != nil {
651
+		t.Fatal(err)
652
+	}
653
+	expected = &net.IPNet{IP: net.IP{10, 0, 0, 255}, Mask: net.IPMask{255, 255, 0, 0}}
654
+	for err == nil {
655
+		var c *net.IPNet
656
+		if c, _, err = a.RequestAddress(poolID, nil, opts); err == nil {
657
+			ip = c
804 658
 		}
659
+	}
660
+	if err != ipamapi.ErrNoAvailableIPs {
661
+		t.Fatal(err)
662
+	}
663
+	if !types.CompareIPNet(expected, ip) {
664
+		t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
665
+	}
666
+	rp = &net.IPNet{IP: net.IP{10, 0, 0, 79}, Mask: net.IPMask{255, 255, 0, 0}}
667
+	if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
668
+		t.Fatal(err)
669
+	}
670
+	if ip, _, err = a.RequestAddress(poolID, nil, opts); err != nil {
671
+		t.Fatal(err)
672
+	}
673
+	if !types.CompareIPNet(rp, ip) {
674
+		t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
675
+	}
805 676
 
806
-		// Request any addresses from subpool after explicit address request
807
-		unoExp, _ := types.ParseCIDR("10.2.2.0/16")
808
-		dueExp, _ := types.ParseCIDR("10.2.2.2/16")
809
-		treExp, _ := types.ParseCIDR("10.2.2.1/16")
810
-		quaExp, _ := types.ParseCIDR("10.2.2.3/16")
811
-		fivExp, _ := types.ParseCIDR("10.2.2.4/16")
812
-		if poolID, _, _, err = a.RequestPool("rosso", "10.2.0.0/16", "10.2.2.0/24", nil, false); err != nil {
813
-			t.Fatal(err)
814
-		}
815
-		tre, _, err := a.RequestAddress(poolID, treExp.IP, opts)
816
-		if err != nil {
817
-			t.Fatal(err)
818
-		}
819
-		if !types.CompareIPNet(tre, treExp) {
820
-			t.Fatalf("Unexpected address: %v", tre)
821
-		}
677
+	// Request any addresses from subpool after explicit address request
678
+	unoExp, _ := types.ParseCIDR("10.2.2.0/16")
679
+	dueExp, _ := types.ParseCIDR("10.2.2.2/16")
680
+	treExp, _ := types.ParseCIDR("10.2.2.1/16")
681
+	quaExp, _ := types.ParseCIDR("10.2.2.3/16")
682
+	fivExp, _ := types.ParseCIDR("10.2.2.4/16")
683
+	if poolID, _, _, err = a.RequestPool("rosso", "10.2.0.0/16", "10.2.2.0/24", nil, false); err != nil {
684
+		t.Fatal(err)
685
+	}
686
+	tre, _, err := a.RequestAddress(poolID, treExp.IP, opts)
687
+	if err != nil {
688
+		t.Fatal(err)
689
+	}
690
+	if !types.CompareIPNet(tre, treExp) {
691
+		t.Fatalf("Unexpected address: %v", tre)
692
+	}
822 693
 
823
-		uno, _, err := a.RequestAddress(poolID, nil, opts)
824
-		if err != nil {
825
-			t.Fatal(err)
826
-		}
827
-		if !types.CompareIPNet(uno, unoExp) {
828
-			t.Fatalf("Unexpected address: %v", uno)
829
-		}
694
+	uno, _, err := a.RequestAddress(poolID, nil, opts)
695
+	if err != nil {
696
+		t.Fatal(err)
697
+	}
698
+	if !types.CompareIPNet(uno, unoExp) {
699
+		t.Fatalf("Unexpected address: %v", uno)
700
+	}
830 701
 
831
-		due, _, err := a.RequestAddress(poolID, nil, opts)
832
-		if err != nil {
833
-			t.Fatal(err)
834
-		}
835
-		if !types.CompareIPNet(due, dueExp) {
836
-			t.Fatalf("Unexpected address: %v", due)
837
-		}
702
+	due, _, err := a.RequestAddress(poolID, nil, opts)
703
+	if err != nil {
704
+		t.Fatal(err)
705
+	}
706
+	if !types.CompareIPNet(due, dueExp) {
707
+		t.Fatalf("Unexpected address: %v", due)
708
+	}
838 709
 
839
-		if err = a.ReleaseAddress(poolID, uno.IP); err != nil {
840
-			t.Fatal(err)
841
-		}
842
-		uno, _, err = a.RequestAddress(poolID, nil, opts)
843
-		if err != nil {
844
-			t.Fatal(err)
845
-		}
846
-		if !types.CompareIPNet(uno, quaExp) {
847
-			t.Fatalf("Unexpected address: %v", uno)
848
-		}
710
+	if err = a.ReleaseAddress(poolID, uno.IP); err != nil {
711
+		t.Fatal(err)
712
+	}
713
+	uno, _, err = a.RequestAddress(poolID, nil, opts)
714
+	if err != nil {
715
+		t.Fatal(err)
716
+	}
717
+	if !types.CompareIPNet(uno, quaExp) {
718
+		t.Fatalf("Unexpected address: %v", uno)
719
+	}
849 720
 
850
-		if err = a.ReleaseAddress(poolID, tre.IP); err != nil {
851
-			t.Fatal(err)
852
-		}
853
-		tre, _, err = a.RequestAddress(poolID, nil, opts)
854
-		if err != nil {
855
-			t.Fatal(err)
856
-		}
857
-		if !types.CompareIPNet(tre, fivExp) {
858
-			t.Fatalf("Unexpected address: %v", tre)
859
-		}
721
+	if err = a.ReleaseAddress(poolID, tre.IP); err != nil {
722
+		t.Fatal(err)
723
+	}
724
+	tre, _, err = a.RequestAddress(poolID, nil, opts)
725
+	if err != nil {
726
+		t.Fatal(err)
727
+	}
728
+	if !types.CompareIPNet(tre, fivExp) {
729
+		t.Fatalf("Unexpected address: %v", tre)
860 730
 	}
861 731
 }
862 732
 
... ...
@@ -879,69 +703,64 @@ func TestRequestSyntaxCheck(t *testing.T) {
879 879
 		as      = "green"
880 880
 	)
881 881
 
882
-	for _, store := range []bool{false, true} {
883
-		a, err := getAllocator(store)
884
-		assert.NilError(t, err)
882
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
883
+	assert.NilError(t, err)
885 884
 
886
-		a.addrSpaces[as] = &addrSpace{
887
-			id:      dsConfigKey + "/" + as,
888
-			ds:      a.addrSpaces[localAddressSpace].ds,
889
-			alloc:   a.addrSpaces[localAddressSpace].alloc,
890
-			scope:   a.addrSpaces[localAddressSpace].scope,
891
-			subnets: map[SubnetKey]*PoolData{},
892
-		}
885
+	a.addrSpaces[as] = &addrSpace{
886
+		alloc:   a.addrSpaces[localAddressSpace].alloc,
887
+		subnets: map[SubnetKey]*PoolData{},
888
+	}
893 889
 
894
-		_, _, _, err = a.RequestPool("", pool, "", nil, false)
895
-		if err == nil {
896
-			t.Fatal("Failed to detect wrong request: empty address space")
897
-		}
890
+	_, _, _, err = a.RequestPool("", pool, "", nil, false)
891
+	if err == nil {
892
+		t.Fatal("Failed to detect wrong request: empty address space")
893
+	}
898 894
 
899
-		_, _, _, err = a.RequestPool("", pool, subPool, nil, false)
900
-		if err == nil {
901
-			t.Fatal("Failed to detect wrong request: empty address space")
902
-		}
895
+	_, _, _, err = a.RequestPool("", pool, subPool, nil, false)
896
+	if err == nil {
897
+		t.Fatal("Failed to detect wrong request: empty address space")
898
+	}
903 899
 
904
-		_, _, _, err = a.RequestPool(as, "", subPool, nil, false)
905
-		if err == nil {
906
-			t.Fatal("Failed to detect wrong request: subPool specified and no pool")
907
-		}
900
+	_, _, _, err = a.RequestPool(as, "", subPool, nil, false)
901
+	if err == nil {
902
+		t.Fatal("Failed to detect wrong request: subPool specified and no pool")
903
+	}
908 904
 
909
-		pid, _, _, err := a.RequestPool(as, pool, subPool, nil, false)
910
-		if err != nil {
911
-			t.Fatalf("Unexpected failure: %v", err)
912
-		}
905
+	pid, _, _, err := a.RequestPool(as, pool, subPool, nil, false)
906
+	if err != nil {
907
+		t.Fatalf("Unexpected failure: %v", err)
908
+	}
913 909
 
914
-		_, _, err = a.RequestAddress("", nil, nil)
915
-		if err == nil {
916
-			t.Fatal("Failed to detect wrong request: no pool id specified")
917
-		}
910
+	_, _, err = a.RequestAddress("", nil, nil)
911
+	if err == nil {
912
+		t.Fatal("Failed to detect wrong request: no pool id specified")
913
+	}
918 914
 
919
-		ip := net.ParseIP("172.17.0.23")
920
-		_, _, err = a.RequestAddress(pid, ip, nil)
921
-		if err == nil {
922
-			t.Fatal("Failed to detect wrong request: requested IP from different subnet")
923
-		}
915
+	ip := net.ParseIP("172.17.0.23")
916
+	_, _, err = a.RequestAddress(pid, ip, nil)
917
+	if err == nil {
918
+		t.Fatal("Failed to detect wrong request: requested IP from different subnet")
919
+	}
924 920
 
925
-		ip = net.ParseIP("192.168.0.50")
926
-		_, _, err = a.RequestAddress(pid, ip, nil)
927
-		if err != nil {
928
-			t.Fatalf("Unexpected failure: %v", err)
929
-		}
921
+	ip = net.ParseIP("192.168.0.50")
922
+	_, _, err = a.RequestAddress(pid, ip, nil)
923
+	if err != nil {
924
+		t.Fatalf("Unexpected failure: %v", err)
925
+	}
930 926
 
931
-		err = a.ReleaseAddress("", ip)
932
-		if err == nil {
933
-			t.Fatal("Failed to detect wrong request: no pool id specified")
934
-		}
927
+	err = a.ReleaseAddress("", ip)
928
+	if err == nil {
929
+		t.Fatal("Failed to detect wrong request: no pool id specified")
930
+	}
935 931
 
936
-		err = a.ReleaseAddress(pid, nil)
937
-		if err == nil {
938
-			t.Fatal("Failed to detect wrong request: no pool id specified")
939
-		}
932
+	err = a.ReleaseAddress(pid, nil)
933
+	if err == nil {
934
+		t.Fatal("Failed to detect wrong request: no pool id specified")
935
+	}
940 936
 
941
-		err = a.ReleaseAddress(pid, ip)
942
-		if err != nil {
943
-			t.Fatalf("Unexpected failure: %v: %s, %s", err, pid, ip)
944
-		}
937
+	err = a.ReleaseAddress(pid, ip)
938
+	if err != nil {
939
+		t.Fatalf("Unexpected failure: %v: %s, %s", err, pid, ip)
945 940
 	}
946 941
 }
947 942
 
... ...
@@ -1034,24 +853,22 @@ func TestOverlappingRequests(t *testing.T) {
1034 1034
 		{[]string{"3ea1:bfa9:8691:d1c6:8c46:519b:db6d:e700/120"}, "3000::/4", false},
1035 1035
 	}
1036 1036
 
1037
-	for _, store := range []bool{false, true} {
1038
-		for _, tc := range input {
1039
-			a, err := getAllocator(store)
1040
-			assert.NilError(t, err)
1037
+	for _, tc := range input {
1038
+		a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1039
+		assert.NilError(t, err)
1041 1040
 
1042
-			// Set up some existing allocations.  This should always succeed.
1043
-			for _, env := range tc.environment {
1044
-				_, _, _, err = a.RequestPool(localAddressSpace, env, "", nil, false)
1045
-				assert.NilError(t, err)
1046
-			}
1041
+		// Set up some existing allocations.  This should always succeed.
1042
+		for _, env := range tc.environment {
1043
+			_, _, _, err = a.RequestPool(localAddressSpace, env, "", nil, false)
1044
+			assert.NilError(t, err)
1045
+		}
1047 1046
 
1048
-			// Make the test allocation.
1049
-			_, _, _, err = a.RequestPool(localAddressSpace, tc.subnet, "", nil, false)
1050
-			if tc.ok {
1051
-				assert.NilError(t, err)
1052
-			} else {
1053
-				assert.Check(t, is.ErrorContains(err, ""))
1054
-			}
1047
+		// Make the test allocation.
1048
+		_, _, _, err = a.RequestPool(localAddressSpace, tc.subnet, "", nil, false)
1049
+		if tc.ok {
1050
+			assert.NilError(t, err)
1051
+		} else {
1052
+			assert.Check(t, is.ErrorContains(err, ""))
1055 1053
 		}
1056 1054
 	}
1057 1055
 }
... ...
@@ -1074,49 +891,47 @@ func TestUnusualSubnets(t *testing.T) {
1074 1074
 		{"192.168.0.3"},
1075 1075
 	}
1076 1076
 
1077
-	for _, store := range []bool{false, true} {
1078
-		allocator, err := getAllocator(store)
1079
-		if err != nil {
1080
-			t.Fatal(err)
1081
-		}
1077
+	allocator, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1078
+	if err != nil {
1079
+		t.Fatal(err)
1080
+	}
1082 1081
 
1083
-		//
1084
-		// IPv4 /31 blocks.  See RFC 3021.
1085
-		//
1082
+	//
1083
+	// IPv4 /31 blocks.  See RFC 3021.
1084
+	//
1086 1085
 
1087
-		pool, _, _, err := allocator.RequestPool(localAddressSpace, subnet, "", nil, false)
1088
-		if err != nil {
1089
-			t.Fatal(err)
1090
-		}
1086
+	pool, _, _, err := allocator.RequestPool(localAddressSpace, subnet, "", nil, false)
1087
+	if err != nil {
1088
+		t.Fatal(err)
1089
+	}
1091 1090
 
1092
-		// Outside-the-range
1091
+	// Outside-the-range
1093 1092
 
1094
-		for _, outside := range outsideTheRangeAddresses {
1095
-			_, _, errx := allocator.RequestAddress(pool, net.ParseIP(outside.address), nil)
1096
-			if errx != ipamapi.ErrIPOutOfRange {
1097
-				t.Fatalf("Address %s failed to throw expected error: %s", outside.address, errx.Error())
1098
-			}
1093
+	for _, outside := range outsideTheRangeAddresses {
1094
+		_, _, errx := allocator.RequestAddress(pool, net.ParseIP(outside.address), nil)
1095
+		if errx != ipamapi.ErrIPOutOfRange {
1096
+			t.Fatalf("Address %s failed to throw expected error: %s", outside.address, errx.Error())
1099 1097
 		}
1098
+	}
1100 1099
 
1101
-		// Should get just these two IPs followed by exhaustion on the next request
1100
+	// Should get just these two IPs followed by exhaustion on the next request
1102 1101
 
1103
-		for _, expected := range expectedAddresses {
1104
-			got, _, errx := allocator.RequestAddress(pool, nil, nil)
1105
-			if errx != nil {
1106
-				t.Fatalf("Failed to obtain the address: %s", errx.Error())
1107
-			}
1108
-			expectedIP := net.ParseIP(expected.address)
1109
-			gotIP := got.IP
1110
-			if !gotIP.Equal(expectedIP) {
1111
-				t.Fatalf("Failed to obtain sequentialaddress. Expected: %s, Got: %s", expectedIP, gotIP)
1112
-			}
1102
+	for _, expected := range expectedAddresses {
1103
+		got, _, errx := allocator.RequestAddress(pool, nil, nil)
1104
+		if errx != nil {
1105
+			t.Fatalf("Failed to obtain the address: %s", errx.Error())
1113 1106
 		}
1114
-
1115
-		_, _, err = allocator.RequestAddress(pool, nil, nil)
1116
-		if err != ipamapi.ErrNoAvailableIPs {
1117
-			t.Fatal("Did not get expected error when pool is exhausted.")
1107
+		expectedIP := net.ParseIP(expected.address)
1108
+		gotIP := got.IP
1109
+		if !gotIP.Equal(expectedIP) {
1110
+			t.Fatalf("Failed to obtain sequentialaddress. Expected: %s, Got: %s", expectedIP, gotIP)
1118 1111
 		}
1119 1112
 	}
1113
+
1114
+	_, _, err = allocator.RequestAddress(pool, nil, nil)
1115
+	if err != ipamapi.ErrNoAvailableIPs {
1116
+		t.Fatal("Did not get expected error when pool is exhausted.")
1117
+	}
1120 1118
 }
1121 1119
 
1122 1120
 func TestRelease(t *testing.T) {
... ...
@@ -1124,64 +939,62 @@ func TestRelease(t *testing.T) {
1124 1124
 		subnet = "192.168.0.0/23"
1125 1125
 	)
1126 1126
 
1127
-	for _, store := range []bool{false, true} {
1128
-		a, err := getAllocator(store)
1129
-		assert.NilError(t, err)
1127
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1128
+	assert.NilError(t, err)
1130 1129
 
1131
-		pid, _, _, err := a.RequestPool(localAddressSpace, subnet, "", nil, false)
1132
-		if err != nil {
1133
-			t.Fatal(err)
1134
-		}
1130
+	pid, _, _, err := a.RequestPool(localAddressSpace, subnet, "", nil, false)
1131
+	if err != nil {
1132
+		t.Fatal(err)
1133
+	}
1135 1134
 
1136
-		// Allocate all addresses
1137
-		for err != ipamapi.ErrNoAvailableIPs {
1138
-			_, _, err = a.RequestAddress(pid, nil, nil)
1139
-		}
1135
+	// Allocate all addresses
1136
+	for err != ipamapi.ErrNoAvailableIPs {
1137
+		_, _, err = a.RequestAddress(pid, nil, nil)
1138
+	}
1140 1139
 
1141
-		toRelease := []struct {
1142
-			address string
1143
-		}{
1144
-			{"192.168.0.1"},
1145
-			{"192.168.0.2"},
1146
-			{"192.168.0.3"},
1147
-			{"192.168.0.4"},
1148
-			{"192.168.0.5"},
1149
-			{"192.168.0.6"},
1150
-			{"192.168.0.7"},
1151
-			{"192.168.0.8"},
1152
-			{"192.168.0.9"},
1153
-			{"192.168.0.10"},
1154
-			{"192.168.0.30"},
1155
-			{"192.168.0.31"},
1156
-			{"192.168.1.32"},
1157
-
1158
-			{"192.168.0.254"},
1159
-			{"192.168.1.1"},
1160
-			{"192.168.1.2"},
1161
-
1162
-			{"192.168.1.3"},
1163
-
1164
-			{"192.168.1.253"},
1165
-			{"192.168.1.254"},
1166
-		}
1140
+	toRelease := []struct {
1141
+		address string
1142
+	}{
1143
+		{"192.168.0.1"},
1144
+		{"192.168.0.2"},
1145
+		{"192.168.0.3"},
1146
+		{"192.168.0.4"},
1147
+		{"192.168.0.5"},
1148
+		{"192.168.0.6"},
1149
+		{"192.168.0.7"},
1150
+		{"192.168.0.8"},
1151
+		{"192.168.0.9"},
1152
+		{"192.168.0.10"},
1153
+		{"192.168.0.30"},
1154
+		{"192.168.0.31"},
1155
+		{"192.168.1.32"},
1167 1156
 
1168
-		// One by one, release the address and request again. We should get the same IP
1169
-		for i, inp := range toRelease {
1170
-			ip0 := net.ParseIP(inp.address)
1171
-			a.ReleaseAddress(pid, ip0)
1172
-			bm := a.addresses[SubnetKey{localAddressSpace, subnet, ""}]
1173
-			if bm.Unselected() != 1 {
1174
-				t.Fatalf("Failed to update free address count after release. Expected %d, Found: %d", i+1, bm.Unselected())
1175
-			}
1157
+		{"192.168.0.254"},
1158
+		{"192.168.1.1"},
1159
+		{"192.168.1.2"},
1176 1160
 
1177
-			nw, _, err := a.RequestAddress(pid, nil, nil)
1178
-			if err != nil {
1179
-				t.Fatalf("Failed to obtain the address: %s", err.Error())
1180
-			}
1181
-			ip := nw.IP
1182
-			if !ip0.Equal(ip) {
1183
-				t.Fatalf("Failed to obtain the same address. Expected: %s, Got: %s", ip0, ip)
1184
-			}
1161
+		{"192.168.1.3"},
1162
+
1163
+		{"192.168.1.253"},
1164
+		{"192.168.1.254"},
1165
+	}
1166
+
1167
+	// One by one, release the address and request again. We should get the same IP
1168
+	for i, inp := range toRelease {
1169
+		ip0 := net.ParseIP(inp.address)
1170
+		a.ReleaseAddress(pid, ip0)
1171
+		bm := a.addresses[SubnetKey{localAddressSpace, subnet, ""}]
1172
+		if bm.Unselected() != 1 {
1173
+			t.Fatalf("Failed to update free address count after release. Expected %d, Found: %d", i+1, bm.Unselected())
1174
+		}
1175
+
1176
+		nw, _, err := a.RequestAddress(pid, nil, nil)
1177
+		if err != nil {
1178
+			t.Fatalf("Failed to obtain the address: %s", err.Error())
1179
+		}
1180
+		ip := nw.IP
1181
+		if !ip0.Equal(ip) {
1182
+			t.Fatalf("Failed to obtain the same address. Expected: %s, Got: %s", ip0, ip)
1185 1183
 		}
1186 1184
 	}
1187 1185
 }
... ...
@@ -1230,27 +1043,25 @@ func assertNRequests(t *testing.T, subnet string, numReq int, lastExpectedIP str
1230 1230
 	)
1231 1231
 
1232 1232
 	lastIP := net.ParseIP(lastExpectedIP)
1233
-	for _, store := range []bool{false, true} {
1234
-		a, err := getAllocator(store)
1235
-		assert.NilError(t, err)
1233
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1234
+	assert.NilError(t, err)
1236 1235
 
1237
-		pid, _, _, err := a.RequestPool(localAddressSpace, subnet, "", nil, false)
1238
-		if err != nil {
1239
-			t.Fatal(err)
1240
-		}
1236
+	pid, _, _, err := a.RequestPool(localAddressSpace, subnet, "", nil, false)
1237
+	if err != nil {
1238
+		t.Fatal(err)
1239
+	}
1241 1240
 
1242
-		i := 0
1243
-		start := time.Now()
1244
-		for ; i < numReq; i++ {
1245
-			nw, _, err = a.RequestAddress(pid, nil, nil)
1246
-		}
1247
-		if printTime {
1248
-			fmt.Printf("\nTaken %v, to allocate %d addresses on %s\n", time.Since(start), numReq, subnet)
1249
-		}
1241
+	i := 0
1242
+	start := time.Now()
1243
+	for ; i < numReq; i++ {
1244
+		nw, _, err = a.RequestAddress(pid, nil, nil)
1245
+	}
1246
+	if printTime {
1247
+		fmt.Printf("\nTaken %v, to allocate %d addresses on %s\n", time.Since(start), numReq, subnet)
1248
+	}
1250 1249
 
1251
-		if !lastIP.Equal(nw.IP) {
1252
-			t.Fatalf("Wrong last IP. Expected %s. Got: %s (err: %v, ind: %d)", lastExpectedIP, nw.IP.String(), err, i)
1253
-		}
1250
+	if !lastIP.Equal(nw.IP) {
1251
+		t.Fatalf("Wrong last IP. Expected %s. Got: %s (err: %v, ind: %d)", lastExpectedIP, nw.IP.String(), err, i)
1254 1252
 	}
1255 1253
 }
1256 1254
 
... ...
@@ -1271,7 +1082,7 @@ func BenchmarkRequest(b *testing.B) {
1271 1271
 	for _, subnet := range subnets {
1272 1272
 		name := fmt.Sprintf("%vSubnet", subnet)
1273 1273
 		b.Run(name, func(b *testing.B) {
1274
-			a, _ := getAllocator(true)
1274
+			a, _ := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1275 1275
 			benchmarkRequest(b, a, subnet)
1276 1276
 		})
1277 1277
 	}
... ...
@@ -1285,10 +1096,7 @@ func TestAllocateRandomDeallocate(t *testing.T) {
1285 1285
 }
1286 1286
 
1287 1287
 func testAllocateRandomDeallocate(t *testing.T, pool, subPool string, num int, store bool) {
1288
-	ds, err := randomLocalStore(store)
1289
-	assert.NilError(t, err)
1290
-
1291
-	a, err := NewAllocator(ds, nil, ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1288
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1292 1289
 	if err != nil {
1293 1290
 		t.Fatal(err)
1294 1291
 	}
... ...
@@ -1350,120 +1158,15 @@ func testAllocateRandomDeallocate(t *testing.T, pool, subPool string, num int, s
1350 1350
 	}
1351 1351
 }
1352 1352
 
1353
-func TestRetrieveFromStore(t *testing.T) {
1354
-	num := 200
1355
-	ds, err := randomLocalStore(true)
1356
-	if err != nil {
1357
-		t.Fatal(err)
1358
-	}
1359
-	a, err := NewAllocator(ds, nil, ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1360
-	if err != nil {
1361
-		t.Fatal(err)
1362
-	}
1363
-	pid, _, _, err := a.RequestPool(localAddressSpace, "172.25.0.0/16", "", nil, false)
1364
-	if err != nil {
1365
-		t.Fatal(err)
1366
-	}
1367
-	for i := 0; i < num; i++ {
1368
-		if _, _, err := a.RequestAddress(pid, nil, nil); err != nil {
1369
-			t.Fatal(err)
1370
-		}
1371
-	}
1372
-
1373
-	// Restore
1374
-	a1, err := NewAllocator(ds, nil, ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1375
-	if err != nil {
1376
-		t.Fatal(err)
1377
-	}
1378
-	a1.refresh(localAddressSpace)
1379
-	db := a.DumpDatabase()
1380
-	db1 := a1.DumpDatabase()
1381
-	if db != db1 {
1382
-		t.Fatalf("Unexpected db change.\nExpected:%s\nGot:%s", db, db1)
1383
-	}
1384
-	checkDBEquality(a, a1, t)
1385
-	pid, _, _, err = a1.RequestPool(localAddressSpace, "172.25.0.0/16", "172.25.1.0/24", nil, false)
1386
-	if err != nil {
1387
-		t.Fatal(err)
1388
-	}
1389
-	for i := 0; i < num/2; i++ {
1390
-		if _, _, err := a1.RequestAddress(pid, nil, nil); err != nil {
1391
-			t.Fatal(err)
1392
-		}
1393
-	}
1394
-
1395
-	// Restore
1396
-	a2, err := NewAllocator(ds, nil, ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1397
-	if err != nil {
1398
-		t.Fatal(err)
1399
-	}
1400
-	a2.refresh(localAddressSpace)
1401
-	checkDBEquality(a1, a2, t)
1402
-	pid, _, _, err = a2.RequestPool(localAddressSpace, "172.25.0.0/16", "172.25.2.0/24", nil, false)
1403
-	if err != nil {
1404
-		t.Fatal(err)
1405
-	}
1406
-	for i := 0; i < num/2; i++ {
1407
-		if _, _, err := a2.RequestAddress(pid, nil, nil); err != nil {
1408
-			t.Fatal(err)
1409
-		}
1410
-	}
1411
-
1412
-	// Restore
1413
-	a3, err := NewAllocator(ds, nil, ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1414
-	if err != nil {
1415
-		t.Fatal(err)
1416
-	}
1417
-	a3.refresh(localAddressSpace)
1418
-	checkDBEquality(a2, a3, t)
1419
-	pid, _, _, err = a3.RequestPool(localAddressSpace, "172.26.0.0/16", "", nil, false)
1420
-	if err != nil {
1421
-		t.Fatal(err)
1422
-	}
1423
-	for i := 0; i < num/2; i++ {
1424
-		if _, _, err := a3.RequestAddress(pid, nil, nil); err != nil {
1425
-			t.Fatal(err)
1426
-		}
1427
-	}
1428
-
1429
-	// Restore
1430
-	a4, err := NewAllocator(ds, nil, ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1431
-	if err != nil {
1432
-		t.Fatal(err)
1433
-	}
1434
-	a4.refresh(localAddressSpace)
1435
-	checkDBEquality(a3, a4, t)
1436
-}
1437
-
1438
-func checkDBEquality(a1, a2 *Allocator, t *testing.T) {
1439
-	for k, cnf1 := range a1.addrSpaces[localAddressSpace].subnets {
1440
-		cnf2 := a2.addrSpaces[localAddressSpace].subnets[k]
1441
-		if cnf1.String() != cnf2.String() {
1442
-			t.Fatalf("%s\n%s", cnf1, cnf2)
1443
-		}
1444
-		if cnf1.Range == nil {
1445
-			a2.retrieveBitmask(k, cnf1.Pool)
1446
-		}
1447
-	}
1448
-
1449
-	for k, bm1 := range a1.addresses {
1450
-		bm2 := a2.addresses[k]
1451
-		if bm1.String() != bm2.String() {
1452
-			t.Fatalf("%s\n%s", bm1, bm2)
1453
-		}
1454
-	}
1455
-}
1456
-
1457 1353
 const (
1458 1354
 	numInstances = 5
1459 1355
 	first        = 0
1460
-	last         = numInstances - 1
1461 1356
 )
1462 1357
 
1463 1358
 var (
1464 1359
 	allocator *Allocator
1465 1360
 	start     = make(chan struct{})
1466
-	done      = make(chan chan struct{}, numInstances-1)
1361
+	done      sync.WaitGroup
1467 1362
 	pools     = make([]*net.IPNet, numInstances)
1468 1363
 )
1469 1364
 
... ...
@@ -1487,22 +1190,17 @@ func runParallelTests(t *testing.T, instance int) {
1487 1487
 	// The first instance creates the allocator, gives the start
1488 1488
 	// and finally checks the pools each instance was assigned
1489 1489
 	if instance == first {
1490
-		allocator, err = getAllocator(true)
1490
+		allocator, err = NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1491 1491
 		if err != nil {
1492 1492
 			t.Fatal(err)
1493 1493
 		}
1494
+		done.Add(numInstances - 1)
1494 1495
 		close(start)
1495 1496
 	}
1496 1497
 
1497 1498
 	if instance != first {
1498 1499
 		<-start
1499
-		instDone := make(chan struct{})
1500
-		done <- instDone
1501
-		defer close(instDone)
1502
-
1503
-		if instance == last {
1504
-			defer close(done)
1505
-		}
1500
+		defer done.Done()
1506 1501
 	}
1507 1502
 
1508 1503
 	_, pools[instance], _, err = allocator.RequestPool(localAddressSpace, "", "", nil, false)
... ...
@@ -1511,14 +1209,12 @@ func runParallelTests(t *testing.T, instance int) {
1511 1511
 	}
1512 1512
 
1513 1513
 	if instance == first {
1514
-		for instDone := range done {
1515
-			<-instDone
1516
-		}
1514
+		done.Wait()
1517 1515
 		// Now check each instance got a different pool
1518 1516
 		for i := 0; i < numInstances; i++ {
1519 1517
 			for j := i + 1; j < numInstances; j++ {
1520 1518
 				if types.CompareIPNet(pools[i], pools[j]) {
1521
-					t.Fatalf("Instance %d and %d were given the same predefined pool: %v", i, j, pools)
1519
+					t.Errorf("Instance %d and %d were given the same predefined pool: %v", i, j, pools)
1522 1520
 				}
1523 1521
 			}
1524 1522
 		}
... ...
@@ -1526,7 +1222,7 @@ func runParallelTests(t *testing.T, instance int) {
1526 1526
 }
1527 1527
 
1528 1528
 func TestRequestReleaseAddressDuplicate(t *testing.T) {
1529
-	a, err := getAllocator(false)
1529
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
1530 1530
 	if err != nil {
1531 1531
 		t.Fatal(err)
1532 1532
 	}
... ...
@@ -1537,10 +1233,7 @@ func TestRequestReleaseAddressDuplicate(t *testing.T) {
1537 1537
 	ips := []IP{}
1538 1538
 	allocatedIPs := []*net.IPNet{}
1539 1539
 	a.addrSpaces["rosso"] = &addrSpace{
1540
-		id:      dsConfigKey + "/" + "rosso",
1541
-		ds:      a.addrSpaces[localAddressSpace].ds,
1542 1540
 		alloc:   a.addrSpaces[localAddressSpace].alloc,
1543
-		scope:   a.addrSpaces[localAddressSpace].scope,
1544 1541
 		subnets: map[SubnetKey]*PoolData{},
1545 1542
 	}
1546 1543
 
... ...
@@ -12,6 +12,7 @@ import (
12 12
 	"time"
13 13
 
14 14
 	"github.com/docker/docker/libnetwork/ipamapi"
15
+	"github.com/docker/docker/libnetwork/ipamutils"
15 16
 	"golang.org/x/sync/errgroup"
16 17
 	"golang.org/x/sync/semaphore"
17 18
 	"gotest.tools/v3/assert"
... ...
@@ -36,15 +37,12 @@ type testContext struct {
36 36
 }
37 37
 
38 38
 func newTestContext(t *testing.T, mask int, options map[string]string) *testContext {
39
-	a, err := getAllocator(false)
39
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
40 40
 	if err != nil {
41 41
 		t.Fatal(err)
42 42
 	}
43 43
 	a.addrSpaces["giallo"] = &addrSpace{
44
-		id:      dsConfigKey + "/" + "giallo",
45
-		ds:      a.addrSpaces[localAddressSpace].ds,
46 44
 		alloc:   a.addrSpaces[localAddressSpace].alloc,
47
-		scope:   a.addrSpaces[localAddressSpace].scope,
48 45
 		subnets: map[SubnetKey]*PoolData{},
49 46
 	}
50 47
 
... ...
@@ -84,7 +82,7 @@ func (o *op) String() string {
84 84
 }
85 85
 
86 86
 func TestRequestPoolParallel(t *testing.T) {
87
-	a, err := getAllocator(false)
87
+	a, err := NewAllocator(ipamutils.GetLocalScopeDefaultNetworks(), ipamutils.GetGlobalScopeDefaultNetworks())
88 88
 	if err != nil {
89 89
 		t.Fatal(err)
90 90
 	}
91 91
deleted file mode 100644
... ...
@@ -1,125 +0,0 @@
1
-package ipam
2
-
3
-import (
4
-	"encoding/json"
5
-
6
-	"github.com/docker/docker/libnetwork/datastore"
7
-	"github.com/docker/docker/libnetwork/types"
8
-	"github.com/sirupsen/logrus"
9
-)
10
-
11
-// Key provides the Key to be used in KV Store
12
-func (aSpace *addrSpace) Key() []string {
13
-	aSpace.Lock()
14
-	defer aSpace.Unlock()
15
-	return []string{aSpace.id}
16
-}
17
-
18
-// KeyPrefix returns the immediate parent key that can be used for tree walk
19
-func (aSpace *addrSpace) KeyPrefix() []string {
20
-	aSpace.Lock()
21
-	defer aSpace.Unlock()
22
-	return []string{dsConfigKey}
23
-}
24
-
25
-// Value marshals the data to be stored in the KV store
26
-func (aSpace *addrSpace) Value() []byte {
27
-	b, err := json.Marshal(aSpace)
28
-	if err != nil {
29
-		logrus.Warnf("Failed to marshal ipam configured pools: %v", err)
30
-		return nil
31
-	}
32
-	return b
33
-}
34
-
35
-// SetValue unmarshalls the data from the KV store.
36
-func (aSpace *addrSpace) SetValue(value []byte) error {
37
-	rc := &addrSpace{subnets: make(map[SubnetKey]*PoolData)}
38
-	if err := json.Unmarshal(value, rc); err != nil {
39
-		return err
40
-	}
41
-	aSpace.subnets = rc.subnets
42
-	return nil
43
-}
44
-
45
-// Index returns the latest DB Index as seen by this object
46
-func (aSpace *addrSpace) Index() uint64 {
47
-	aSpace.Lock()
48
-	defer aSpace.Unlock()
49
-	return aSpace.dbIndex
50
-}
51
-
52
-// SetIndex method allows the datastore to store the latest DB Index into this object
53
-func (aSpace *addrSpace) SetIndex(index uint64) {
54
-	aSpace.Lock()
55
-	aSpace.dbIndex = index
56
-	aSpace.dbExists = true
57
-	aSpace.Unlock()
58
-}
59
-
60
-// Exists method is true if this object has been stored in the DB.
61
-func (aSpace *addrSpace) Exists() bool {
62
-	aSpace.Lock()
63
-	defer aSpace.Unlock()
64
-	return aSpace.dbExists
65
-}
66
-
67
-// Skip provides a way for a KV Object to avoid persisting it in the KV Store
68
-func (aSpace *addrSpace) Skip() bool {
69
-	return false
70
-}
71
-
72
-func (a *Allocator) getStore(as string) datastore.DataStore {
73
-	a.Lock()
74
-	defer a.Unlock()
75
-
76
-	if aSpace, ok := a.addrSpaces[as]; ok {
77
-		return aSpace.ds
78
-	}
79
-
80
-	return nil
81
-}
82
-
83
-func (a *Allocator) getAddressSpaceFromStore(as string) (*addrSpace, error) {
84
-	store := a.getStore(as)
85
-
86
-	// IPAM may not have a valid store. In such cases it is just in-memory state.
87
-	if store == nil {
88
-		return nil, nil
89
-	}
90
-
91
-	pc := &addrSpace{id: dsConfigKey + "/" + as, ds: store, alloc: a}
92
-	if err := store.GetObject(datastore.Key(pc.Key()...), pc); err != nil {
93
-		if err == datastore.ErrKeyNotFound {
94
-			return nil, nil
95
-		}
96
-
97
-		return nil, types.InternalErrorf("could not get pools config from store: %v", err)
98
-	}
99
-
100
-	return pc, nil
101
-}
102
-
103
-func (a *Allocator) writeToStore(aSpace *addrSpace) error {
104
-	store := aSpace.store()
105
-
106
-	// IPAM may not have a valid store. In such cases it is just in-memory state.
107
-	if store == nil {
108
-		return nil
109
-	}
110
-
111
-	err := store.PutObjectAtomic(aSpace)
112
-	if err == datastore.ErrKeyModified {
113
-		return types.RetryErrorf("failed to perform atomic write (%v). retry might fix the error", err)
114
-	}
115
-
116
-	return err
117
-}
118
-
119
-// DataScope method returns the storage scope of the datastore
120
-func (aSpace *addrSpace) DataScope() string {
121
-	aSpace.Lock()
122
-	defer aSpace.Unlock()
123
-
124
-	return aSpace.scope
125
-}
... ...
@@ -1,13 +1,11 @@
1 1
 package ipam
2 2
 
3 3
 import (
4
-	"encoding/json"
5 4
 	"fmt"
6 5
 	"net"
7 6
 	"strings"
8 7
 	"sync"
9 8
 
10
-	"github.com/docker/docker/libnetwork/datastore"
11 9
 	"github.com/docker/docker/libnetwork/ipamapi"
12 10
 	"github.com/docker/docker/libnetwork/types"
13 11
 )
... ...
@@ -29,13 +27,8 @@ type PoolData struct {
29 29
 
30 30
 // addrSpace contains the pool configurations for the address space
31 31
 type addrSpace struct {
32
-	subnets  map[SubnetKey]*PoolData
33
-	dbIndex  uint64
34
-	dbExists bool
35
-	id       string
36
-	scope    string
37
-	ds       datastore.DataStore
38
-	alloc    *Allocator
32
+	subnets map[SubnetKey]*PoolData
33
+	alloc   *Allocator
39 34
 	sync.Mutex
40 35
 }
41 36
 
... ...
@@ -51,31 +44,6 @@ func (r *AddressRange) String() string {
51 51
 	return fmt.Sprintf("Sub: %s, range [%d, %d]", r.Sub, r.Start, r.End)
52 52
 }
53 53
 
54
-// MarshalJSON returns the JSON encoding of the Range object
55
-func (r *AddressRange) MarshalJSON() ([]byte, error) {
56
-	m := map[string]interface{}{
57
-		"Sub":   r.Sub.String(),
58
-		"Start": r.Start,
59
-		"End":   r.End,
60
-	}
61
-	return json.Marshal(m)
62
-}
63
-
64
-// UnmarshalJSON decodes data into the Range object
65
-func (r *AddressRange) UnmarshalJSON(data []byte) error {
66
-	m := map[string]interface{}{}
67
-	err := json.Unmarshal(data, &m)
68
-	if err != nil {
69
-		return err
70
-	}
71
-	if r.Sub, err = types.ParseCIDR(m["Sub"].(string)); err != nil {
72
-		return err
73
-	}
74
-	r.Start = uint64(m["Start"].(float64))
75
-	r.End = uint64(m["End"].(float64))
76
-	return nil
77
-}
78
-
79 54
 // String returns the string form of the SubnetKey object
80 55
 func (s *SubnetKey) String() string {
81 56
 	k := fmt.Sprintf("%s/%s", s.AddressSpace, s.Subnet)
... ...
@@ -110,153 +78,6 @@ func (p *PoolData) String() string {
110 110
 		p.ParentKey.String(), p.Pool.String(), p.Range, p.RefCount)
111 111
 }
112 112
 
113
-// MarshalJSON returns the JSON encoding of the PoolData object
114
-func (p *PoolData) MarshalJSON() ([]byte, error) {
115
-	m := map[string]interface{}{
116
-		"ParentKey": p.ParentKey,
117
-		"RefCount":  p.RefCount,
118
-	}
119
-	if p.Pool != nil {
120
-		m["Pool"] = p.Pool.String()
121
-	}
122
-	if p.Range != nil {
123
-		m["Range"] = p.Range
124
-	}
125
-	return json.Marshal(m)
126
-}
127
-
128
-// UnmarshalJSON decodes data into the PoolData object
129
-func (p *PoolData) UnmarshalJSON(data []byte) error {
130
-	var (
131
-		err error
132
-		t   struct {
133
-			ParentKey SubnetKey
134
-			Pool      string
135
-			Range     *AddressRange `json:",omitempty"`
136
-			RefCount  int
137
-		}
138
-	)
139
-
140
-	if err = json.Unmarshal(data, &t); err != nil {
141
-		return err
142
-	}
143
-
144
-	p.ParentKey = t.ParentKey
145
-	p.Range = t.Range
146
-	p.RefCount = t.RefCount
147
-	if t.Pool != "" {
148
-		if p.Pool, err = types.ParseCIDR(t.Pool); err != nil {
149
-			return err
150
-		}
151
-	}
152
-
153
-	return nil
154
-}
155
-
156
-// MarshalJSON returns the JSON encoding of the addrSpace object
157
-func (aSpace *addrSpace) MarshalJSON() ([]byte, error) {
158
-	aSpace.Lock()
159
-	defer aSpace.Unlock()
160
-
161
-	m := map[string]interface{}{
162
-		"Scope": aSpace.scope,
163
-	}
164
-
165
-	if aSpace.subnets != nil {
166
-		s := map[string]*PoolData{}
167
-		for k, v := range aSpace.subnets {
168
-			s[k.String()] = v
169
-		}
170
-		m["Subnets"] = s
171
-	}
172
-
173
-	return json.Marshal(m)
174
-}
175
-
176
-// UnmarshalJSON decodes data into the addrSpace object
177
-func (aSpace *addrSpace) UnmarshalJSON(data []byte) error {
178
-	aSpace.Lock()
179
-	defer aSpace.Unlock()
180
-
181
-	m := map[string]interface{}{}
182
-	err := json.Unmarshal(data, &m)
183
-	if err != nil {
184
-		return err
185
-	}
186
-
187
-	aSpace.scope = datastore.LocalScope
188
-	s := m["Scope"].(string)
189
-	if s == datastore.GlobalScope {
190
-		aSpace.scope = datastore.GlobalScope
191
-	}
192
-
193
-	if v, ok := m["Subnets"]; ok {
194
-		sb, _ := json.Marshal(v)
195
-		var s map[string]*PoolData
196
-		err := json.Unmarshal(sb, &s)
197
-		if err != nil {
198
-			return err
199
-		}
200
-		for ks, v := range s {
201
-			k := SubnetKey{}
202
-			k.FromString(ks)
203
-			aSpace.subnets[k] = v
204
-		}
205
-	}
206
-
207
-	return nil
208
-}
209
-
210
-// CopyTo deep copies the pool data to the destination pooldata
211
-func (p *PoolData) CopyTo(dstP *PoolData) error {
212
-	dstP.ParentKey = p.ParentKey
213
-	dstP.Pool = types.GetIPNetCopy(p.Pool)
214
-
215
-	if p.Range != nil {
216
-		dstP.Range = &AddressRange{}
217
-		dstP.Range.Sub = types.GetIPNetCopy(p.Range.Sub)
218
-		dstP.Range.Start = p.Range.Start
219
-		dstP.Range.End = p.Range.End
220
-	}
221
-
222
-	dstP.RefCount = p.RefCount
223
-	return nil
224
-}
225
-
226
-func (aSpace *addrSpace) CopyTo(o datastore.KVObject) error {
227
-	aSpace.Lock()
228
-	defer aSpace.Unlock()
229
-
230
-	dstAspace := o.(*addrSpace)
231
-
232
-	dstAspace.id = aSpace.id
233
-	dstAspace.ds = aSpace.ds
234
-	dstAspace.alloc = aSpace.alloc
235
-	dstAspace.scope = aSpace.scope
236
-	dstAspace.dbIndex = aSpace.dbIndex
237
-	dstAspace.dbExists = aSpace.dbExists
238
-
239
-	dstAspace.subnets = make(map[SubnetKey]*PoolData)
240
-	for k, v := range aSpace.subnets {
241
-		dstAspace.subnets[k] = &PoolData{}
242
-		v.CopyTo(dstAspace.subnets[k])
243
-	}
244
-
245
-	return nil
246
-}
247
-
248
-func (aSpace *addrSpace) New() datastore.KVObject {
249
-	aSpace.Lock()
250
-	defer aSpace.Unlock()
251
-
252
-	return &addrSpace{
253
-		id:    aSpace.id,
254
-		ds:    aSpace.ds,
255
-		alloc: aSpace.alloc,
256
-		scope: aSpace.scope,
257
-	}
258
-}
259
-
260 113
 // updatePoolDBOnAdd returns a closure which will add the subnet k to the address space when executed.
261 114
 func (aSpace *addrSpace) updatePoolDBOnAdd(k SubnetKey, nw *net.IPNet, ipr *AddressRange, pdf bool) (func() error, error) {
262 115
 	aSpace.Lock()
... ...
@@ -355,10 +176,3 @@ func (aSpace *addrSpace) contains(space string, nw *net.IPNet) bool {
355 355
 	}
356 356
 	return false
357 357
 }
358
-
359
-func (aSpace *addrSpace) store() datastore.DataStore {
360
-	aSpace.Lock()
361
-	defer aSpace.Unlock()
362
-
363
-	return aSpace.ds
364
-}
... ...
@@ -4,7 +4,6 @@ package ipamapi
4 4
 import (
5 5
 	"net"
6 6
 
7
-	"github.com/docker/docker/libnetwork/discoverapi"
8 7
 	"github.com/docker/docker/libnetwork/types"
9 8
 	"github.com/docker/docker/pkg/plugingetter"
10 9
 )
... ...
@@ -59,8 +58,6 @@ var (
59 59
 // Ipam represents the interface the IPAM service plugins must implement
60 60
 // in order to allow injection/modification of IPAM database.
61 61
 type Ipam interface {
62
-	discoverapi.Discover
63
-
64 62
 	// GetDefaultAddressSpaces returns the default local and global address spaces for this ipam
65 63
 	GetDefaultAddressSpaces() (string, string, error)
66 64
 	// RequestPool returns an address pool along with its unique id. Address space is a mandatory field
... ...
@@ -22,7 +22,7 @@ func registerBuiltin(ic ipamapi.Registerer) error {
22 22
 		localAddressPool = ipamutils.GetLocalScopeDefaultNetworks()
23 23
 	}
24 24
 
25
-	a, err := ipam.NewAllocator(nil, nil, localAddressPool, ipamutils.GetGlobalScopeDefaultNetworks())
25
+	a, err := ipam.NewAllocator(localAddressPool, ipamutils.GetGlobalScopeDefaultNetworks())
26 26
 	if err != nil {
27 27
 		return err
28 28
 	}
... ...
@@ -3,7 +3,6 @@ package windowsipam
3 3
 import (
4 4
 	"net"
5 5
 
6
-	"github.com/docker/docker/libnetwork/discoverapi"
7 6
 	"github.com/docker/docker/libnetwork/ipamapi"
8 7
 	"github.com/docker/docker/libnetwork/types"
9 8
 	"github.com/sirupsen/logrus"
... ...
@@ -85,16 +84,6 @@ func (a *allocator) ReleaseAddress(poolID string, address net.IP) error {
85 85
 	return nil
86 86
 }
87 87
 
88
-// DiscoverNew informs the allocator about a new global scope datastore
89
-func (a *allocator) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
90
-	return nil
91
-}
92
-
93
-// DiscoverDelete is a notification of no interest for the allocator
94
-func (a *allocator) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
95
-	return nil
96
-}
97
-
98 88
 func (a *allocator) IsBuiltIn() bool {
99 89
 	return true
100 90
 }