diff --git a/.gitignore b/.gitignore index 7dfabf6980..a4e3a83df6 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,6 @@ logs/* # Ignore social cards cache userdocs/.cache/* + +# Visual Studio Code +.vscode/ diff --git a/pkg/apis/eksctl.io/v1alpha5/addon.go b/pkg/apis/eksctl.io/v1alpha5/addon.go index 984c1861c5..40995c0f3d 100644 --- a/pkg/apis/eksctl.io/v1alpha5/addon.go +++ b/pkg/apis/eksctl.io/v1alpha5/addon.go @@ -115,7 +115,7 @@ func (a Addon) Validate() error { if a.HasPodIDsSet() { if a.CanonicalName() == PodIdentityAgentAddon { - return invalidAddonConfigErr(fmt.Sprintf("cannot set pod identity associtations for %q addon", PodIdentityAgentAddon)) + return invalidAddonConfigErr(fmt.Sprintf("cannot set pod identity associations for %q addon", PodIdentityAgentAddon)) } for i, pia := range *a.PodIdentityAssociations { diff --git a/pkg/apis/eksctl.io/v1alpha5/addon_test.go b/pkg/apis/eksctl.io/v1alpha5/addon_test.go index ca04420825..762c46f0e3 100644 --- a/pkg/apis/eksctl.io/v1alpha5/addon_test.go +++ b/pkg/apis/eksctl.io/v1alpha5/addon_test.go @@ -107,7 +107,7 @@ var _ = Describe("Addon", func() { Name: api.PodIdentityAgentAddon, PodIdentityAssociations: &[]api.PodIdentityAssociation{{}}, }, - expectedErr: "cannot set pod identity associtations for \"eks-pod-identity-agent\" addon", + expectedErr: "cannot set pod identity associations for \"eks-pod-identity-agent\" addon", }), Entry("namespace is not set", addonWithPodIDEntry{ addon: api.Addon{ diff --git a/pkg/apis/eksctl.io/v1alpha5/validation.go b/pkg/apis/eksctl.io/v1alpha5/validation.go index 078eada6bc..27698dd7e4 100644 --- a/pkg/apis/eksctl.io/v1alpha5/validation.go +++ b/pkg/apis/eksctl.io/v1alpha5/validation.go @@ -535,6 +535,15 @@ func (c *ClusterConfig) addonContainsManagedAddons(addons []string) []string { return missing } +func (c *ClusterConfig) getAddon(name string) *Addon { + for _, addon := range c.Addons { + if addon.Name == name { + return addon + } + } + return nil +} + // ValidateClusterEndpointConfig checks the endpoint configuration for potential issues func (c *ClusterConfig) ValidateClusterEndpointConfig() error { if c.VPC.ClusterEndpoints != nil { @@ -607,8 +616,26 @@ func (c *ClusterConfig) validateKubernetesNetworkConfig() error { if missing := c.addonContainsManagedAddons([]string{VPCCNIAddon, CoreDNSAddon, KubeProxyAddon}); len(missing) != 0 { return fmt.Errorf("the default core addons must be defined for IPv6; missing addon(s): %s; either define them or use EKS Auto Mode", strings.Join(missing, ", ")) } - if c.IAM == nil || c.IAM != nil && IsDisabled(c.IAM.WithOIDC) { - return fmt.Errorf("oidc needs to be enabled if IPv6 is set; either set it or use EKS Auto Mode") + + // Check if at least one credential provider (Pod identity or IRSA) is configured + if len(c.addonContainsManagedAddons([]string{PodIdentityAgentAddon})) != 0 && (c.IAM == nil || c.IAM != nil && IsDisabled(c.IAM.WithOIDC)) { + return errors.New("either pod identity or oidc needs to be enabled if IPv6 is set; set either one or use EKS Auto Mode") + } + + // If the pod identity addon is present, verify it is correctly configured for use by the VPC CNI addon + // Assuming user intends to use pod identities if the pod identity agent addon is added. + if len(c.addonContainsManagedAddons([]string{PodIdentityAgentAddon})) == 0 && !c.AddonsConfig.AutoApplyPodIdentityAssociations { + vpcCNIAddonEntry := c.getAddon(VPCCNIAddon) + + if vpcCNIAddonEntry == nil { + // should be unreachable + return errors.New("the vpc-cni addon must be defined for IPv6; either define it or use EKS Auto Mode") + } + + if !vpcCNIAddonEntry.UseDefaultPodIdentityAssociations && + (vpcCNIAddonEntry.PodIdentityAssociations == nil || len(*vpcCNIAddonEntry.PodIdentityAssociations) == 0) { + return fmt.Errorf("Set one of: addonsConfig.autoApplyPodIdentityAssociations, useDefaultPodIdentityAssociations on the vpc-cni addon, apply a custom pod identity on the vpc-cni addon") + } } } diff --git a/pkg/apis/eksctl.io/v1alpha5/validation_test.go b/pkg/apis/eksctl.io/v1alpha5/validation_test.go index ff12b876f8..afff46923f 100644 --- a/pkg/apis/eksctl.io/v1alpha5/validation_test.go +++ b/pkg/apis/eksctl.io/v1alpha5/validation_test.go @@ -1181,6 +1181,71 @@ var _ = Describe("ClusterConfig validation", func() { }) }) + When("ipFamily is set to IPV6, OIDC is disabled", func() { + JustBeforeEach(func() { + cfg.VPC.NAT = nil + cfg.IAM = &api.ClusterIAM{ + WithOIDC: api.Disabled(), + } + cfg.Addons = append(cfg.Addons, &api.Addon{Name: api.KubeProxyAddon}, &api.Addon{Name: api.CoreDNSAddon}) + }) + When("Pod identity addon is missing", func() { + It("returns an error", func() { + cfg.Addons = append(cfg.Addons, &api.Addon{Name: api.VPCCNIAddon}) + err = api.ValidateClusterConfig(cfg) + Expect(err).To(MatchError(ContainSubstring("either pod identity or oidc needs to be enabled if IPv6 is set; set either one or use EKS Auto Mode"))) + }) + }) + + When("Pod identity addon is present", func() { + JustBeforeEach(func() { + cfg.Addons = append(cfg.Addons, + &api.Addon{Name: api.PodIdentityAgentAddon}) + }) + + When("Use default pod identity associations is set", func() { + It("accepts the setting", func() { + cfg.Addons = append(cfg.Addons, &api.Addon{Name: api.VPCCNIAddon}) + cfg.AddonsConfig.AutoApplyPodIdentityAssociations = true + + err = api.ValidateClusterConfig(cfg) + Expect(err).ToNot(HaveOccurred()) + }) + }) + + When("Use default pod identity association is set on the vpc-cni addon", func() { + It("accepts the setting", func() { + cfg.Addons = append(cfg.Addons, &api.Addon{Name: api.VPCCNIAddon, UseDefaultPodIdentityAssociations: true}) + + err = api.ValidateClusterConfig(cfg) + Expect(err).ToNot(HaveOccurred()) + }) + }) + + When("The vpc-cni addon has a pod identity association configured", func() { + It("accepts the setting", func() { + cfg.Addons = append(cfg.Addons, &api.Addon{Name: api.VPCCNIAddon, + PodIdentityAssociations: &[]api.PodIdentityAssociation{{ + Namespace: "test-namespace", + ServiceAccountName: "fakeserviceaccount", + RoleARN: "fakerolearn", + }}}) + + err = api.ValidateClusterConfig(cfg) + Expect(err).ToNot(HaveOccurred()) + }) + }) + + When("The vpc-cni addon is missing a pod identity configuration", func() { + It("returns an error", func() { + cfg.Addons = append(cfg.Addons, &api.Addon{Name: api.VPCCNIAddon}) + err = api.ValidateClusterConfig(cfg) + Expect(err).To(MatchError(ContainSubstring("Set one of: addonsConfig.autoApplyPodIdentityAssociations, useDefaultPodIdentityAssociations on the vpc-cni addon, apply a custom pod identity on the vpc-cni addon"))) + }) + }) + }) + }) + When("ipFamily is set to IPv6, no managed addons are provided, but auto-mode is used", func() { It("accepts the setting", func() { cfg.VPC.NAT = nil