Skip to content

Commit ce32f01

Browse files
authored
AKO won't be installed in IPv6 single-stack and IPv6 Primary dual-stack cluster (#176)
1 parent 8f0289d commit ce32f01

File tree

4 files changed

+162
-37
lines changed

4 files changed

+162
-37
lines changed

api/v1alpha1/constants.go

+12-12
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,18 @@ const (
3636
AkoPackageInstallName = "load-balancer-and-ingress-service"
3737
AkoPreferredIPAnnotation = "ako.vmware.com/load-balancer-ip"
3838

39-
AviClusterLabel = "networking.tkg.tanzu.vmware.com/avi"
40-
AviClusterDeleteConfigLabel = "networking.tkg.tanzu.vmware.com/avi-config-delete"
41-
AviClusterSecretType = "avi.cluster.x-k8s.io/secret"
42-
AviNamespace = "avi-system"
43-
AviCredentialName = "avi-controller-credentials"
44-
AviCAName = "avi-controller-ca"
45-
AviCertificateKey = "certificateAuthorityData"
46-
AviResourceCleanupReason = "AviResourceCleanup"
47-
AviResourceCleanupSucceededCondition clusterv1.ConditionType = "AviResourceCleanupSucceeded"
48-
AviUserCleanupSucceededCondition clusterv1.ConditionType = "AviUserCleanupSucceeded"
49-
AKOIpFamilyValidationSucceededCondition clusterv1.ConditionType = "AKOIpFamilyValidationSucceeded"
50-
PreTerminateAnnotation = clusterv1.PreTerminateDeleteHookAnnotationPrefix + "/avi-cleanup"
39+
AviClusterLabel = "networking.tkg.tanzu.vmware.com/avi"
40+
AviClusterDeleteConfigLabel = "networking.tkg.tanzu.vmware.com/avi-config-delete"
41+
AviClusterSecretType = "avi.cluster.x-k8s.io/secret"
42+
AviNamespace = "avi-system"
43+
AviCredentialName = "avi-controller-credentials"
44+
AviCAName = "avi-controller-ca"
45+
AviCertificateKey = "certificateAuthorityData"
46+
AviResourceCleanupReason = "AviResourceCleanup"
47+
AviResourceCleanupSucceededCondition clusterv1.ConditionType = "AviResourceCleanupSucceeded"
48+
AviUserCleanupSucceededCondition clusterv1.ConditionType = "AviUserCleanupSucceeded"
49+
ClusterIpFamilyValidationSucceededCondition clusterv1.ConditionType = "ClusterIpFamilyValidationSucceeded"
50+
PreTerminateAnnotation = clusterv1.PreTerminateDeleteHookAnnotationPrefix + "/avi-cleanup"
5151

5252
HAServiceName = "control-plane"
5353
HAServiceBootstrapClusterFinalizer = "ako-operator.networking.tkg.tanzu.vmware.com/ha"

controllers/akodeploymentconfig/cluster/cluster_controller_addon_secret.go

+26-17
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ import (
2727
runv1alpha3 "github.com/vmware-tanzu/tanzu-framework/apis/run/v1alpha3"
2828
)
2929

30+
const (
31+
IPv4IpFamily = "V4"
32+
IPv6IpFamily = "V6"
33+
DualStackIPv6Primary = "V6,V4"
34+
DualStackIPv4Primary = "V4,V6"
35+
)
36+
3037
func (r *ClusterReconciler) ReconcileAddonSecret(
3138
ctx context.Context,
3239
log logr.Logger,
@@ -59,13 +66,13 @@ func (r *ClusterReconciler) ReconcileAddonSecret(
5966
}
6067
}
6168

62-
//Stop reconciling if AKO ip family doesn't match cluster ip family
63-
if err = ValidateADCAndClusterIpFamily(cluster, obj, isVIPProvider, log); err != nil {
64-
errInfo := "Selected AKODeploymentConfig " + obj.Name + "'s IP family doesn't match cluster " + cluster.Namespace +
65-
"-" + cluster.Name + "'s ip family, stop deploying AKO into cluster " + cluster.Namespace + "-" + cluster.Name
69+
//Stop reconciling if cluster ip family doesn't satisfy the condition
70+
if err = ValidateClusterIpFamily(cluster, obj, isVIPProvider, log); err != nil {
71+
errInfo := "cluster " + cluster.Namespace +
72+
"-" + cluster.Name + "'s ip family is not allowed, stop deploying AKO into cluster " + cluster.Namespace + "-" + cluster.Name
6673
log.Error(err, errInfo)
6774
clusterCondition := &clusterv1.Condition{
68-
Type: akoov1alpha1.AKOIpFamilyValidationSucceededCondition,
75+
Type: akoov1alpha1.ClusterIpFamilyValidationSucceededCondition,
6976
Status: corev1.ConditionFalse,
7077
Message: errInfo,
7178
}
@@ -358,30 +365,32 @@ func getAKOPackageRefFromClusterBootstrap(log logr.Logger, cb *runv1alpha3.Clust
358365
return -1, nil
359366
}
360367

361-
func ValidateADCAndClusterIpFamily(cluster *clusterv1.Cluster, adc *akoov1alpha1.AKODeploymentConfig, isVIPProvider bool, log logr.Logger) error {
362-
adcIpFamily := "V4"
363-
if adc.Spec.ExtraConfigs.IpFamily != "" {
364-
adcIpFamily = adc.Spec.ExtraConfigs.IpFamily
365-
}
368+
func ValidateClusterIpFamily(cluster *clusterv1.Cluster, adc *akoov1alpha1.AKODeploymentConfig, isVIPProvider bool, log logr.Logger) error {
366369
clusterIpFamily, err := utils.GetClusterIPFamily(cluster)
367370
if err != nil {
368371
log.Error(err, "can't get cluster ip family")
369372
return err
370373
}
374+
// AKO limitations: AKO doesn't work in IPv6 single-stack and IPv6 Primary dual-stack cluster
375+
if clusterIpFamily == IPv6IpFamily || clusterIpFamily == DualStackIPv6Primary {
376+
return errors.New("AKO doesn't work in IPv6 single-stack and IPv6 Primary dual-stack cluster")
377+
}
378+
379+
adcIpFamily := IPv4IpFamily
380+
if adc.Spec.ExtraConfigs.IpFamily != "" {
381+
adcIpFamily = adc.Spec.ExtraConfigs.IpFamily
382+
}
383+
371384
// AKO limitations: AKO can't configure backend pool ip family
372385
// TODO:(chenlin) Remove validation after AKO supports configurable ip pool
373-
if (adcIpFamily == "V4" && clusterIpFamily == "V6") || (adcIpFamily == "V6" && clusterIpFamily == "V4") {
386+
if adcIpFamily == IPv6IpFamily && clusterIpFamily == IPv4IpFamily {
374387
errInfo := "AKO with IP family " + adcIpFamily + " can not work together with cluster with IP family " + clusterIpFamily
375388
return errors.New(errInfo)
376389
}
377390
// When enable avi as control plane ha, backend server shouldn't use secondary ip type
378391
// TODO:(chenlin) Remove validation after AKO supports configurable ip pool
379-
if isVIPProvider {
380-
if adcIpFamily == "V4" && clusterIpFamily == "V6,V4" {
381-
return errors.New("When enabling avi as control plane HA, AKO with IP family V4 can not work together with ipv6 primary dual-stack cluster")
382-
} else if adcIpFamily == "V6" && clusterIpFamily == "V4,V6" {
383-
return errors.New("When enabling avi as control plane HA, AKO with IP family V6 can not work together with ipv4 primary dual-stack cluster")
384-
}
392+
if isVIPProvider && adcIpFamily == IPv6IpFamily && clusterIpFamily == DualStackIPv4Primary {
393+
return errors.New("When enabling avi as control plane HA, AKO with IP family V6 can not work together with ipv4 primary dual-stack cluster")
385394
}
386395
return nil
387396
}

controllers/akodeploymentconfig/cluster/cluster_controller_unit_test.go

+123-7
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,123 @@ func unitTestAKODeploymentYaml() {
258258
})
259259
}
260260

261-
func unitTestValidateADCAndClusterIpFamily() {
261+
func unitTestValidateClusterIpFamily() {
262+
Context("Validate ipv6 cluster ip family", func() {
263+
var (
264+
akoDeploymentConfig *akoov1alpha1.AKODeploymentConfig
265+
capiCluster *clusterv1.Cluster
266+
logger logr.Logger
267+
isVIPProvider bool
268+
)
269+
270+
BeforeEach(func() {
271+
log.SetLogger(zap.New())
272+
logger = log.Log
273+
})
274+
275+
When("cluster is valid", func() {
276+
BeforeEach(func() {
277+
akoDeploymentConfig = &akoov1alpha1.AKODeploymentConfig{
278+
Spec: akoov1alpha1.AKODeploymentConfigSpec{
279+
ExtraConfigs: akoov1alpha1.ExtraConfigs{
280+
IpFamily: "V4",
281+
},
282+
},
283+
}
284+
285+
capiCluster = &clusterv1.Cluster{
286+
ObjectMeta: metav1.ObjectMeta{
287+
Name: "test-cluster",
288+
Namespace: "default",
289+
},
290+
Spec: clusterv1.ClusterSpec{
291+
ClusterNetwork: &clusterv1.ClusterNetwork{
292+
Pods: &clusterv1.NetworkRanges{
293+
CIDRBlocks: []string{"192.168.0.0/16"},
294+
},
295+
Services: &clusterv1.NetworkRanges{
296+
CIDRBlocks: []string{"192.168.0.0/16"},
297+
},
298+
},
299+
},
300+
}
301+
})
302+
303+
It("should return no error", func() {
304+
err := cluster.ValidateClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
305+
Expect(err).ShouldNot(HaveOccurred())
306+
})
307+
})
308+
309+
When("cluster is invalid single-stack IPv6", func() {
310+
BeforeEach(func() {
311+
akoDeploymentConfig = &akoov1alpha1.AKODeploymentConfig{
312+
Spec: akoov1alpha1.AKODeploymentConfigSpec{
313+
ExtraConfigs: akoov1alpha1.ExtraConfigs{
314+
IpFamily: "V4",
315+
},
316+
},
317+
}
318+
319+
capiCluster = &clusterv1.Cluster{
320+
ObjectMeta: metav1.ObjectMeta{
321+
Name: "test-cluster",
322+
Namespace: "default",
323+
},
324+
Spec: clusterv1.ClusterSpec{
325+
ClusterNetwork: &clusterv1.ClusterNetwork{
326+
Pods: &clusterv1.NetworkRanges{
327+
CIDRBlocks: []string{"2002::1234:abcd:ffff:c0a8:101/64"},
328+
},
329+
Services: &clusterv1.NetworkRanges{
330+
CIDRBlocks: []string{"2002::1234:abcd:ffff:c0a8:101/64"},
331+
},
332+
},
333+
},
334+
}
335+
})
336+
337+
It("should return no error", func() {
338+
err := cluster.ValidateClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
339+
Expect(err).Should(HaveOccurred())
340+
})
341+
})
342+
343+
When("cluster is invalid dual-stack IPv6 Primary", func() {
344+
BeforeEach(func() {
345+
akoDeploymentConfig = &akoov1alpha1.AKODeploymentConfig{
346+
Spec: akoov1alpha1.AKODeploymentConfigSpec{
347+
ExtraConfigs: akoov1alpha1.ExtraConfigs{
348+
IpFamily: "V4",
349+
},
350+
},
351+
}
352+
353+
capiCluster = &clusterv1.Cluster{
354+
ObjectMeta: metav1.ObjectMeta{
355+
Name: "test-cluster",
356+
Namespace: "default",
357+
},
358+
Spec: clusterv1.ClusterSpec{
359+
ClusterNetwork: &clusterv1.ClusterNetwork{
360+
Pods: &clusterv1.NetworkRanges{
361+
CIDRBlocks: []string{"2002::1234:abcd:ffff:c0a8:101/64, 192.168.0.0/16"},
362+
},
363+
Services: &clusterv1.NetworkRanges{
364+
CIDRBlocks: []string{"2002::1234:abcd:ffff:c0a8:101/64, 192.168.0.0/16"},
365+
},
366+
},
367+
},
368+
}
369+
})
370+
371+
It("should return no error", func() {
372+
err := cluster.ValidateClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
373+
Expect(err).Should(HaveOccurred())
374+
})
375+
})
376+
})
377+
262378
Context("Validate AKODeploymentConfig ip family and cluster ip family", func() {
263379
var (
264380
akoDeploymentConfig *akoov1alpha1.AKODeploymentConfig
@@ -335,7 +451,7 @@ func unitTestValidateADCAndClusterIpFamily() {
335451
})
336452

337453
It("should return no error", func() {
338-
err := cluster.ValidateADCAndClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
454+
err := cluster.ValidateClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
339455
Expect(err).ShouldNot(HaveOccurred())
340456
})
341457
})
@@ -383,7 +499,7 @@ func unitTestValidateADCAndClusterIpFamily() {
383499
})
384500

385501
It("should return error since cluster ip family is invalid", func() {
386-
err := cluster.ValidateADCAndClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
502+
err := cluster.ValidateClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
387503
Expect(err).Should(HaveOccurred())
388504
})
389505
})
@@ -428,7 +544,7 @@ func unitTestValidateADCAndClusterIpFamily() {
428544
})
429545

430546
It("should return error since the ipfamily combination is not supported", func() {
431-
err := cluster.ValidateADCAndClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
547+
err := cluster.ValidateClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
432548
Expect(err).Should(HaveOccurred())
433549
})
434550
})
@@ -472,7 +588,7 @@ func unitTestValidateADCAndClusterIpFamily() {
472588
})
473589

474590
It("should return error since the ipfamily combination is not supported", func() {
475-
err := cluster.ValidateADCAndClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
591+
err := cluster.ValidateClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
476592
Expect(err).Should(HaveOccurred())
477593
})
478594
})
@@ -519,7 +635,7 @@ func unitTestValidateADCAndClusterIpFamily() {
519635
})
520636

521637
It("should return error since the ipfamily combination is not supported", func() {
522-
err := cluster.ValidateADCAndClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
638+
err := cluster.ValidateClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
523639
Expect(err).Should(HaveOccurred())
524640
})
525641
})
@@ -563,7 +679,7 @@ func unitTestValidateADCAndClusterIpFamily() {
563679
})
564680

565681
It("should return error since the ipfamily combination is not supported", func() {
566-
err := cluster.ValidateADCAndClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
682+
err := cluster.ValidateClusterIpFamily(capiCluster, akoDeploymentConfig, isVIPProvider, logger)
567683
Expect(err).Should(HaveOccurred())
568684
})
569685
})

controllers/akodeploymentconfig/cluster/suite_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,5 @@ func intgTests() {
3636

3737
func unitTests() {
3838
Describe("AKO Deployment Spec generation", unitTestAKODeploymentYaml)
39-
Describe("AKODeploymentConfig and cluster ip family Validation", unitTestValidateADCAndClusterIpFamily)
39+
Describe("Cluster ip family Validation", unitTestValidateClusterIpFamily)
4040
}

0 commit comments

Comments
 (0)