@@ -7,9 +7,11 @@ import (
7
7
"fmt"
8
8
"io"
9
9
"net"
10
+ "net/netip"
10
11
"os"
11
12
"time"
12
13
14
+ "go4.org/netipx"
13
15
corev1 "k8s.io/api/core/v1"
14
16
"k8s.io/apimachinery/pkg/api/errors"
15
17
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -26,7 +28,6 @@ import (
26
28
"github.com/kong/kubernetes-testing-framework/pkg/clusters/types/kind"
27
29
"github.com/kong/kubernetes-testing-framework/pkg/utils/docker"
28
30
"github.com/kong/kubernetes-testing-framework/pkg/utils/kubernetes/kubectl"
29
- "github.com/kong/kubernetes-testing-framework/pkg/utils/networking"
30
31
)
31
32
32
33
// -----------------------------------------------------------------------------
@@ -141,10 +142,8 @@ func (a *addon) DumpDiagnostics(context.Context, clusters.Cluster) (map[string][
141
142
// -----------------------------------------------------------------------------
142
143
143
144
var (
144
- defaultStartIP = net .ParseIP ("0.0.0.100" )
145
- defaultEndIP = net .ParseIP ("0.0.0.250" )
146
- metalManifest = "https://github.com/metallb/metallb/config/native?ref=v0.13.11&timeout=2m"
147
- secretKeyLen = 128
145
+ metalManifest = "https://github.com/metallb/metallb/config/native?ref=v0.13.11&timeout=2m"
146
+ secretKeyLen = 128
148
147
)
149
148
150
149
// -----------------------------------------------------------------------------
@@ -201,11 +200,15 @@ func deployMetallbForKindCluster(ctx context.Context, cluster clusters.Cluster,
201
200
202
201
func createIPAddressPool (ctx context.Context , cluster clusters.Cluster , dockerNetwork string ) error {
203
202
// get an IP range for the docker container network to use for MetalLB
204
- network , err := docker .GetDockerContainerIPNetwork (docker .GetKindContainerID (cluster .Name ()), dockerNetwork )
203
+ // this returns addresses based on the _Docker network_ the cluster runs on, not the cluster itself. this may,
204
+ // for example, return IPv4 addresses even for an IPv6-only cluster. although unsupported addresses will be listed
205
+ // in the IPAddressPool, speaker will not actually assign them if they are not compatible with the cluster network.
206
+ network , network6 , err := docker .GetDockerContainerIPNetwork (docker .GetKindContainerID (cluster .Name ()), dockerNetwork )
205
207
if err != nil {
206
208
return err
207
209
}
208
210
ipStart , ipEnd := getIPRangeForMetallb (* network )
211
+ ip6Start , ip6End := getIPRangeForMetallb (* network6 )
209
212
210
213
dynamicClient , err := dynamic .NewForConfig (cluster .Config ())
211
214
if err != nil {
@@ -228,7 +231,8 @@ func createIPAddressPool(ctx context.Context, cluster clusters.Cluster, dockerNe
228
231
},
229
232
"spec" : map [string ]interface {}{
230
233
"addresses" : []string {
231
- networking .GetIPRangeStr (ipStart , ipEnd ),
234
+ fmt .Sprintf ("%s-%s" , ipStart , ipEnd ),
235
+ fmt .Sprintf ("%s-%s" , ip6Start , ip6End ),
232
236
},
233
237
},
234
238
},
@@ -297,15 +301,24 @@ func createL2Advertisement(ctx context.Context, cluster clusters.Cluster) error
297
301
return nil
298
302
}
299
303
304
+ // TODO use netip throughout. this converts because old public APIs used net/ip instead of net/netip
305
+
300
306
// getIPRangeForMetallb provides a range of IP addresses to use for MetalLB given an IPv4 Network
301
307
//
302
- // TODO: Just choosing specific default IPs for now, need to check range validity and dynamically assign IPs.
308
+ // TODO: this just chooses the upper half of the Docker network (minus the network and broadcast addresses for the
309
+ // chosen subnet), although those IPs may be in use. Speaker will happily assign those, but they won't work.
310
+ // In practice this doesn't appear to cause many problems, since the IPs are normally not in use by KIND components
311
+ // (it appears to assign starting from the bottom of the Docker net)
303
312
//
304
313
// See: https://github.com/Kong/kubernetes-testing-framework/issues/24
305
- func getIPRangeForMetallb (network net.IPNet ) (startIP , endIP net.IP ) {
306
- startIP = networking .ConvertUint32ToIPv4 (networking .ConvertIPv4ToUint32 (network .IP ) | networking .ConvertIPv4ToUint32 (defaultStartIP ))
307
- endIP = networking .ConvertUint32ToIPv4 (networking .ConvertIPv4ToUint32 (network .IP ) | networking .ConvertIPv4ToUint32 (defaultEndIP ))
308
- return
314
+ func getIPRangeForMetallb (network net.IPNet ) (startIP , endIP netip.Addr ) {
315
+ // we trust that this is a valid prefix here because we already checked it in docker.GetDockerContainerIPNetwork
316
+ prefix := netip .MustParsePrefix (network .String ())
317
+ half := prefix .Bits () + 1
318
+ wholeRange := netipx .RangeOfPrefix (prefix )
319
+ upperHalfPrefix := netip .PrefixFrom (wholeRange .To (), half ).Masked ()
320
+ halfRange := netipx .RangeOfPrefix (upperHalfPrefix )
321
+ return halfRange .From ().Next (), halfRange .To ().Prev ()
309
322
}
310
323
311
324
// TODO: needs to be replaced with non-kubectl, just used this originally for speed.
0 commit comments