diff --git a/examples/29-vpc-with-ip-family.yaml b/examples/29-vpc-with-ip-family.yaml index 46d4439781..b1824ffa25 100644 --- a/examples/29-vpc-with-ip-family.yaml +++ b/examples/29-vpc-with-ip-family.yaml @@ -7,6 +7,7 @@ kind: ClusterConfig metadata: name: cluster-2 region: eu-north-1 + version: "1.21" vpc: ipFamily: IPv6 diff --git a/pkg/apis/eksctl.io/v1alpha5/validation.go b/pkg/apis/eksctl.io/v1alpha5/validation.go index 7508e8f83f..4464ef63ee 100644 --- a/pkg/apis/eksctl.io/v1alpha5/validation.go +++ b/pkg/apis/eksctl.io/v1alpha5/validation.go @@ -14,6 +14,7 @@ import ( corev1 "k8s.io/api/core/v1" + "github.com/weaveworks/eksctl/pkg/utils" "github.com/weaveworks/eksctl/pkg/utils/taints" "k8s.io/apimachinery/pkg/util/validation" @@ -138,11 +139,6 @@ func ValidateClusterConfig(cfg *ClusterConfig) error { return errors.New("field secretsEncryption.keyARN is required for enabling secrets encryption") } - // manageSharedNodeSecurityGroupRules cannot be disabled if using eksctl managed security groups - if cfg.VPC != nil && cfg.VPC.SharedNodeSecurityGroup == "" && IsDisabled(cfg.VPC.ManageSharedNodeSecurityGroupRules) { - return errors.New("vpc.manageSharedNodeSecurityGroupRules must be enabled when using ekstcl-managed security groups") - } - return nil } @@ -177,8 +173,19 @@ func (c *ClusterConfig) ValidateVPCConfig() error { if c.IAM == nil || c.IAM != nil && IsDisabled(c.IAM.WithOIDC) { return fmt.Errorf("oidc needs to be enabled if IPv6 is set") } + + if version, err := utils.CompareVersions(c.Metadata.Version, Version1_21); err != nil { + return fmt.Errorf("failed to convert %s cluster version to semver: %w", c.Metadata.Version, err) + } else if err == nil && version == -1 { + return fmt.Errorf("cluster version must be >= %s", Version1_21) + } } } + + // manageSharedNodeSecurityGroupRules cannot be disabled if using eksctl managed security groups + if c.VPC.SharedNodeSecurityGroup == "" && IsDisabled(c.VPC.ManageSharedNodeSecurityGroupRules) { + return errors.New("vpc.manageSharedNodeSecurityGroupRules must be enabled when using ekstcl-managed security groups") + } return nil } diff --git a/pkg/apis/eksctl.io/v1alpha5/validation_test.go b/pkg/apis/eksctl.io/v1alpha5/validation_test.go index a56ff2cf25..79f4ccb056 100644 --- a/pkg/apis/eksctl.io/v1alpha5/validation_test.go +++ b/pkg/apis/eksctl.io/v1alpha5/validation_test.go @@ -542,7 +542,7 @@ var _ = Describe("ClusterConfig validation", func() { Expect(err).ToNot(HaveOccurred()) Expect(*cfg.VPC.IPFamily).To(Equal(string(api.IPV4Family))) }) - When("ipFamily is set ot IPv6", func() { + When("ipFamily is set to IPv6", func() { It("accepts that setting", func() { ipv6 := string(api.IPV6Family) cfg.VPC.IPFamily = &ipv6 @@ -554,8 +554,32 @@ var _ = Describe("ClusterConfig validation", func() { cfg.IAM = &api.ClusterIAM{ WithOIDC: api.Enabled(), } + cfg.Metadata.Version = api.Version1_21 err = cfg.ValidateVPCConfig() Expect(err).ToNot(HaveOccurred()) + cfg.Metadata.Version = "1.31" + err = cfg.ValidateVPCConfig() + Expect(err).ToNot(HaveOccurred()) + }) + }) + When("ipFamily is set ot IPv6 but version is not or too low", func() { + It("returns an error", func() { + ipv6 := string(api.IPV6Family) + cfg.VPC.IPFamily = &ipv6 + cfg.Addons = append(cfg.Addons, + &api.Addon{Name: api.KubeProxyAddon}, + &api.Addon{Name: api.CoreDNSAddon}, + &api.Addon{Name: api.VPCCNIAddon}, + ) + cfg.IAM = &api.ClusterIAM{ + WithOIDC: api.Enabled(), + } + cfg.Metadata.Version = "" + err = cfg.ValidateVPCConfig() + Expect(err).To(MatchError(ContainSubstring("failed to convert cluster version to semver: unable to parse first version"))) + cfg.Metadata.Version = api.Version1_12 + err = cfg.ValidateVPCConfig() + Expect(err).To(MatchError(ContainSubstring("cluster version must be >= 1.21"))) }) }) When("ipFamily is set ot IPv6 but no managed addons are provided", func() { diff --git a/pkg/ctl/cmdutils/configfile_test.go b/pkg/ctl/cmdutils/configfile_test.go index 6afd08c98c..93281c3542 100644 --- a/pkg/ctl/cmdutils/configfile_test.go +++ b/pkg/ctl/cmdutils/configfile_test.go @@ -156,9 +156,9 @@ var _ = Describe("cmdutils configfile", func() { } err := NewMetadataLoader(cmd).Load() + Expect(err).ToNot(HaveOccurred()) cfg := cmd.ClusterConfig - Expect(err).ToNot(HaveOccurred()) Expect(cfg.Metadata.Name).ToNot(BeEmpty()) Expect(cfg.Metadata.Region).ToNot(BeEmpty()) Expect(cfg.Metadata.Region).To(Equal(cmd.ProviderConfig.Region)) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 1de713e33b..bfe395d887 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -62,7 +62,7 @@ func IsMinVersion(minimumVersion, version string) (bool, error) { // CompareVersions compares two version strings with the usual conventions: // returns 0 if a == b // returns 1 if a > b -// returns -1 if b < a +// returns -1 if a < b func CompareVersions(a, b string) (int, error) { aVersion, err := semver.ParseTolerant(a) if err != nil { diff --git a/userdocs/src/usage/vpc-networking.md b/userdocs/src/usage/vpc-networking.md index e6e9a1519d..dc3d415127 100644 --- a/userdocs/src/usage/vpc-networking.md +++ b/userdocs/src/usage/vpc-networking.md @@ -37,6 +37,7 @@ kind: ClusterConfig metadata: name: my-test region: us-west-2 + version: "1.21" vpc: ipFamily: IPv6 # or IPv4 @@ -50,7 +51,12 @@ iam: withOIDC: true ``` -This is an in config file setting only. Managed addons need to be defined when IPv6 is set along with OIDC. +This is an in config file setting only. When IPv6 is set, the following restriction must be followed: + +- OIDC is enabled +- managed addons are defined as shows above +- version must be => 1.21 + The default value is `IPv4`. ## Change VPC CIDR