5
5
"fmt"
6
6
"net"
7
7
"sync"
8
+
9
+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
8
10
)
9
11
10
12
var ErrSubnetAllocatorFull = fmt .Errorf ("No subnets available." )
@@ -24,14 +26,14 @@ type SubnetAllocator struct {
24
26
func NewSubnetAllocator (network string , hostBits uint32 , inUse []string ) (* SubnetAllocator , error ) {
25
27
_ , netIP , err := net .ParseCIDR (network )
26
28
if err != nil {
27
- return nil , fmt .Errorf ("Failed to parse network address: %q" , network )
29
+ return nil , fmt .Errorf ("failed to parse network address: %q" , network )
28
30
}
29
31
30
32
netMaskSize , _ := netIP .Mask .Size ()
31
33
if hostBits == 0 {
32
- return nil , fmt .Errorf ("Host capacity cannot be zero." )
34
+ return nil , fmt .Errorf ("host capacity cannot be zero." )
33
35
} else if hostBits > (32 - uint32 (netMaskSize )) {
34
- return nil , fmt .Errorf ("Subnet capacity cannot be larger than number of networks available." )
36
+ return nil , fmt .Errorf ("subnet capacity cannot be larger than number of networks available." )
35
37
}
36
38
subnetBits := 32 - uint32 (netMaskSize ) - hostBits
37
39
@@ -62,29 +64,41 @@ func NewSubnetAllocator(network string, hostBits uint32, inUse []string) (*Subne
62
64
rightMask = 0
63
65
}
64
66
65
- amap := make (map [string ]bool )
66
- for _ , netStr := range inUse {
67
- _ , nIp , err := net .ParseCIDR (netStr )
68
- if err != nil {
69
- fmt .Println ("Failed to parse network address: " , netStr )
70
- continue
71
- }
72
- if ! netIP .Contains (nIp .IP ) {
73
- fmt .Println ("Provided subnet doesn't belong to network: " , nIp )
74
- continue
75
- }
76
- amap [nIp .String ()] = true
77
- }
78
- return & SubnetAllocator {
67
+ sa := & SubnetAllocator {
79
68
network : netIP ,
80
69
hostBits : hostBits ,
81
70
leftShift : leftShift ,
82
71
leftMask : leftMask ,
83
72
rightShift : rightShift ,
84
73
rightMask : rightMask ,
85
74
next : 0 ,
86
- allocMap : amap ,
87
- }, nil
75
+ allocMap : make (map [string ]bool ),
76
+ }
77
+ for _ , netStr := range inUse {
78
+ _ , ipNet , err := net .ParseCIDR (netStr )
79
+ if err != nil {
80
+ utilruntime .HandleError (fmt .Errorf ("failed to parse network address: %s" , netStr ))
81
+ continue
82
+ }
83
+ if err = sa .AllocateNetwork (ipNet ); err != nil {
84
+ utilruntime .HandleError (err )
85
+ continue
86
+ }
87
+ }
88
+ return sa , nil
89
+ }
90
+
91
+ func (sna * SubnetAllocator ) AllocateNetwork (ipNet * net.IPNet ) error {
92
+ sna .mutex .Lock ()
93
+ defer sna .mutex .Unlock ()
94
+
95
+ if ! sna .network .Contains (ipNet .IP ) {
96
+ return fmt .Errorf ("provided subnet doesn't belong to network: %v" , ipNet )
97
+ }
98
+ if ! sna .allocMap [ipNet .String ()] {
99
+ sna .allocMap [ipNet .String ()] = true
100
+ }
101
+ return nil
88
102
}
89
103
90
104
func (sna * SubnetAllocator ) GetNetwork () (* net.IPNet , error ) {
@@ -121,17 +135,17 @@ func (sna *SubnetAllocator) GetNetwork() (*net.IPNet, error) {
121
135
func (sna * SubnetAllocator ) ReleaseNetwork (ipnet * net.IPNet ) error {
122
136
sna .mutex .Lock ()
123
137
defer sna .mutex .Unlock ()
138
+
124
139
if ! sna .network .Contains (ipnet .IP ) {
125
- return fmt .Errorf ("Provided subnet %v doesn't belong to the network %v." , ipnet , sna .network )
140
+ return fmt .Errorf ("provided subnet %v doesn't belong to the network %v." , ipnet , sna .network )
126
141
}
127
142
128
143
ipnetStr := ipnet .String ()
129
144
if ! sna .allocMap [ipnetStr ] {
130
- return fmt .Errorf ("Provided subnet %v is already available." , ipnet )
145
+ return fmt .Errorf ("provided subnet %v is already available." , ipnet )
146
+ } else {
147
+ sna .allocMap [ipnetStr ] = false
131
148
}
132
-
133
- sna .allocMap [ipnetStr ] = false
134
-
135
149
return nil
136
150
}
137
151
0 commit comments