@@ -61,9 +61,6 @@ func TestValidateLinodeVPC(t *testing.T) {
6161 ErrorSubnetRangeNotPrivate = "spec.Subnets[0].IPv4: Invalid value: \" 9.9.9.0/24\" : range must belong to a private address space as defined in RFC1918"
6262 ErrorSubnetRange = "spec.Subnets[0].IPv4: Invalid value: \" IPv4 CIDR\" : must be IPv4 range in CIDR canonical form"
6363 ErrorSubnetRangeNotIPv4 = "spec.Subnets[0].IPv4: Invalid value: \" 10.9.9.9/8\" : must be IPv4 range in CIDR canonical form"
64- ErrorIPv6RangeInvalid = "spec.IPv6Range[0].Range: Invalid value: \" 48\" : IPv6 range must be either 'auto' or start with /. Example: /52"
65- ErrorIPv6RangeInvalidChars = "spec.IPv6Range[0].Range: Invalid value: \" /a48\" : IPv6 range doesn't contain a valid number after /"
66- ErrorIPv6RangeOutOfRange = "spec.IPv6Range[0].Range: Invalid value: \" /130\" : IPv6 range must be between /0 and /128"
6764 validator = & linodeVPCValidator {}
6865 )
6966
@@ -93,40 +90,6 @@ func TestValidateLinodeVPC(t *testing.T) {
9390 require .Empty (t , errs )
9491 }),
9592 ),
96- Path (
97- Call ("valid ipv6 ranges in vpc" , func (ctx context.Context , mck Mock ) {
98- region := region
99- region .Capabilities = slices .Clone (capabilities )
100- mck .LinodeClient .EXPECT ().GetRegion (gomock .Any (), gomock .Any ()).Return (& region , nil ).AnyTimes ()
101- }),
102- Result ("success" , func (ctx context.Context , mck Mock ) {
103- vpc := vpc
104- vpc .Spec .IPv6Range = []infrav1alpha2.VPCCreateOptionsIPv6 {
105- {Range : ptr .To ("/48" )},
106- {Range : ptr .To ("/52" )},
107- {Range : ptr .To ("auto" )},
108- }
109- errs := validator .validateLinodeVPCSpec (ctx , mck .LinodeClient , vpc .Spec , SkipAPIValidation )
110- require .Empty (t , errs )
111- }),
112- ),
113- Path (
114- Call ("valid ipv6 ranges in subnets" , func (ctx context.Context , mck Mock ) {
115- region := region
116- region .Capabilities = slices .Clone (capabilities )
117- mck .LinodeClient .EXPECT ().GetRegion (gomock .Any (), gomock .Any ()).Return (& region , nil ).AnyTimes ()
118- }),
119- Result ("success" , func (ctx context.Context , mck Mock ) {
120- vpc := vpc
121- vpc .Spec .Subnets = []infrav1alpha2.VPCSubnetCreateOptions {
122- {Label : "foo" , IPv4 : "10.0.0.0/24" , IPv6Range : []infrav1alpha2.VPCSubnetCreateOptionsIPv6 {{Range : ptr .To ("/52" )}}},
123- {Label : "bar" , IPv4 : "10.0.1.0/24" , IPv6Range : []infrav1alpha2.VPCSubnetCreateOptionsIPv6 {{Range : ptr .To ("/64" )}}},
124- {Label : "buzz" , IPv4 : "10.0.2.0/24" , IPv6Range : []infrav1alpha2.VPCSubnetCreateOptionsIPv6 {{Range : ptr .To ("auto" )}}},
125- }
126- errs := validator .validateLinodeVPCSpec (ctx , mck .LinodeClient , vpc .Spec , SkipAPIValidation )
127- require .Empty (t , errs )
128- }),
129- ),
13093 ),
13194 OneOf (
13295 Path (
@@ -153,39 +116,6 @@ func TestValidateLinodeVPC(t *testing.T) {
153116 }
154117 })),
155118 ),
156- OneOf (
157- Path (
158- Call ("invalid ipv6 range" , func (ctx context.Context , mck Mock ) {
159- region := region
160- region .Capabilities = slices .Clone (capabilities )
161- mck .LinodeClient .EXPECT ().GetRegion (gomock .Any (), gomock .Any ()).Return (& region , nil ).AnyTimes ()
162- }),
163- Result ("error" , func (ctx context.Context , mck Mock ) {
164- vpc := vpc
165- vpc .Spec .IPv6Range = []infrav1alpha2.VPCCreateOptionsIPv6 {
166- {Range : ptr .To ("48" )},
167- }
168- errs := validator .validateLinodeVPCSpec (ctx , mck .LinodeClient , vpc .Spec , SkipAPIValidation )
169- for _ , err := range errs {
170- assert .ErrorContains (t , err , ErrorIPv6RangeInvalid )
171- }
172- vpc .Spec .IPv6Range = []infrav1alpha2.VPCCreateOptionsIPv6 {
173- {Range : ptr .To ("/a48" )},
174- }
175- errs = validator .validateLinodeVPCSpec (ctx , mck .LinodeClient , vpc .Spec , SkipAPIValidation )
176- for _ , err := range errs {
177- assert .ErrorContains (t , err , ErrorIPv6RangeInvalidChars )
178- }
179- vpc .Spec .IPv6Range = []infrav1alpha2.VPCCreateOptionsIPv6 {
180- {Range : ptr .To ("/130" )},
181- }
182- errs = validator .validateLinodeVPCSpec (ctx , mck .LinodeClient , vpc .Spec , SkipAPIValidation )
183- for _ , err := range errs {
184- assert .ErrorContains (t , err , ErrorIPv6RangeOutOfRange )
185- }
186- }),
187- ),
188- ),
189119 OneOf (
190120 Path (
191121 Call ("no subnet label" , func (ctx context.Context , mck Mock ) {
@@ -359,6 +289,120 @@ func TestValidateLinodeVPC(t *testing.T) {
359289 )
360290}
361291
292+ func TestValidateVPCIPv6Ranges (t * testing.T ) {
293+ t .Parallel ()
294+
295+ var (
296+ vpc = infrav1alpha2.LinodeVPC {
297+ ObjectMeta : metav1.ObjectMeta {
298+ Name : "example" ,
299+ Namespace : "example" ,
300+ },
301+ Spec : infrav1alpha2.LinodeVPCSpec {
302+ Region : "example" ,
303+ },
304+ }
305+ region = linodego.Region {ID : "test" }
306+ capabilities = []string {LinodeVPCCapability }
307+ ErrorIPv6RangeInvalid = "spec.IPv6Range[0].Range: Invalid value: \" 48\" : IPv6 range must be either 'auto' or start with /. Example: /52"
308+ ErrorIPv6RangeInvalidChars = "spec.IPv6Range[0].Range: Invalid value: \" /a48\" : IPv6 range doesn't contain a valid number after /"
309+ ErrorIPv6RangeOutOfRange = "spec.IPv6Range[0].Range: Invalid value: \" /130\" : IPv6 range must be between /0 and /128"
310+ validator = & linodeVPCValidator {}
311+ )
312+
313+ NewSuite (t , mock.MockLinodeClient {}).Run (
314+ OneOf (
315+ Path (
316+ Call ("valid ipv6 ranges in vpc" , func (ctx context.Context , mck Mock ) {
317+ region := region
318+ region .Capabilities = slices .Clone (capabilities )
319+ mck .LinodeClient .EXPECT ().GetRegion (gomock .Any (), gomock .Any ()).Return (& region , nil ).AnyTimes ()
320+ }),
321+ Result ("success" , func (ctx context.Context , mck Mock ) {
322+ vpc := vpc
323+ vpc .Spec .IPv6Range = []infrav1alpha2.VPCCreateOptionsIPv6 {
324+ {Range : ptr .To ("/48" )},
325+ {Range : ptr .To ("/52" )},
326+ {Range : ptr .To ("auto" )},
327+ }
328+ errs := validator .validateLinodeVPCSpec (ctx , mck .LinodeClient , vpc .Spec , SkipAPIValidation )
329+ require .Empty (t , errs )
330+ }),
331+ ),
332+ Path (
333+ Call ("valid ipv6 ranges in subnets" , func (ctx context.Context , mck Mock ) {
334+ region := region
335+ region .Capabilities = slices .Clone (capabilities )
336+ mck .LinodeClient .EXPECT ().GetRegion (gomock .Any (), gomock .Any ()).Return (& region , nil ).AnyTimes ()
337+ }),
338+ Result ("success" , func (ctx context.Context , mck Mock ) {
339+ vpc := vpc
340+ vpc .Spec .Subnets = []infrav1alpha2.VPCSubnetCreateOptions {
341+ {Label : "foo" , IPv4 : "10.0.0.0/24" , IPv6Range : []infrav1alpha2.VPCSubnetCreateOptionsIPv6 {{Range : ptr .To ("/52" )}}},
342+ {Label : "bar" , IPv4 : "10.0.1.0/24" , IPv6Range : []infrav1alpha2.VPCSubnetCreateOptionsIPv6 {{Range : ptr .To ("/64" )}}},
343+ {Label : "buzz" , IPv4 : "10.0.2.0/24" , IPv6Range : []infrav1alpha2.VPCSubnetCreateOptionsIPv6 {{Range : ptr .To ("auto" )}}},
344+ }
345+ errs := validator .validateLinodeVPCSpec (ctx , mck .LinodeClient , vpc .Spec , SkipAPIValidation )
346+ require .Empty (t , errs )
347+ }),
348+ ),
349+ ),
350+ OneOf (
351+ Path (
352+ Call ("ipv6 range missing /" , func (ctx context.Context , mck Mock ) {
353+ region := region
354+ region .Capabilities = slices .Clone (capabilities )
355+ mck .LinodeClient .EXPECT ().GetRegion (gomock .Any (), gomock .Any ()).Return (& region , nil ).AnyTimes ()
356+ }),
357+ Result ("error" , func (ctx context.Context , mck Mock ) {
358+ vpc := vpc
359+ vpc .Spec .IPv6Range = []infrav1alpha2.VPCCreateOptionsIPv6 {
360+ {Range : ptr .To ("48" )},
361+ }
362+ errs := validator .validateLinodeVPCSpec (ctx , mck .LinodeClient , vpc .Spec , SkipAPIValidation )
363+ for _ , err := range errs {
364+ assert .ErrorContains (t , err , ErrorIPv6RangeInvalid )
365+ }
366+ }),
367+ ),
368+ Path (
369+ Call ("ipv6 range containing chars" , func (ctx context.Context , mck Mock ) {
370+ region := region
371+ region .Capabilities = slices .Clone (capabilities )
372+ mck .LinodeClient .EXPECT ().GetRegion (gomock .Any (), gomock .Any ()).Return (& region , nil ).AnyTimes ()
373+ }),
374+ Result ("error" , func (ctx context.Context , mck Mock ) {
375+ vpc := vpc
376+ vpc .Spec .IPv6Range = []infrav1alpha2.VPCCreateOptionsIPv6 {
377+ {Range : ptr .To ("/a48" )},
378+ }
379+ errs := validator .validateLinodeVPCSpec (ctx , mck .LinodeClient , vpc .Spec , SkipAPIValidation )
380+ for _ , err := range errs {
381+ assert .ErrorContains (t , err , ErrorIPv6RangeInvalidChars )
382+ }
383+ }),
384+ ),
385+ Path (
386+ Call ("ipv6 range out of bounds" , func (ctx context.Context , mck Mock ) {
387+ region := region
388+ region .Capabilities = slices .Clone (capabilities )
389+ mck .LinodeClient .EXPECT ().GetRegion (gomock .Any (), gomock .Any ()).Return (& region , nil ).AnyTimes ()
390+ }),
391+ Result ("error" , func (ctx context.Context , mck Mock ) {
392+ vpc := vpc
393+ vpc .Spec .IPv6Range = []infrav1alpha2.VPCCreateOptionsIPv6 {
394+ {Range : ptr .To ("/130" )},
395+ }
396+ errs := validator .validateLinodeVPCSpec (ctx , mck .LinodeClient , vpc .Spec , SkipAPIValidation )
397+ for _ , err := range errs {
398+ assert .ErrorContains (t , err , ErrorIPv6RangeOutOfRange )
399+ }
400+ }),
401+ ),
402+ ),
403+ )
404+ }
405+
362406func TestValidateCreateLinodeVPC (t * testing.T ) {
363407 t .Parallel ()
364408 ctrl := gomock .NewController (t )
0 commit comments