Skip to content

Commit cd876b7

Browse files
authored
Limit AWS DNS provider validation to primary provider (#1684)
1 parent fe23ff7 commit cd876b7

File tree

2 files changed

+127
-4
lines changed

2 files changed

+127
-4
lines changed

pkg/admission/validator/shoot.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ func (s *shoot) validateDNS(ctx context.Context, shoot *core.Shoot) field.ErrorL
234234
continue
235235
}
236236

237+
// Check if this is the primary provider
238+
if p.Primary == nil || !*p.Primary {
239+
continue // Skip non-primary providers
240+
}
241+
237242
providerFldPath := dnsProvidersPath.Index(i)
238243

239244
if p.SecretName == nil || *p.SecretName == "" {

pkg/admission/validator/shoot_test.go

Lines changed: 122 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ var _ = Describe("Shoot validator", func() {
618618
c.EXPECT().Get(ctx, cloudProfileKey, &gardencorev1beta1.CloudProfile{}).SetArg(2, *cloudProfile)
619619
shoot.Spec.DNS = &core.DNS{
620620
Providers: []core.DNSProvider{
621-
{Type: ptr.To(aws.DNSType)}, // secretName missing
621+
{Type: ptr.To(aws.DNSType), Primary: ptr.To(true)}, // secretName missing
622622
},
623623
}
624624

@@ -633,7 +633,7 @@ var _ = Describe("Shoot validator", func() {
633633
c.EXPECT().Get(ctx, cloudProfileKey, &gardencorev1beta1.CloudProfile{}).SetArg(2, *cloudProfile)
634634
shoot.Spec.DNS = &core.DNS{
635635
Providers: []core.DNSProvider{
636-
{Type: ptr.To(aws.DNSType), SecretName: ptr.To("dns-secret")},
636+
{Type: ptr.To(aws.DNSType), SecretName: ptr.To("dns-secret"), Primary: ptr.To(true)},
637637
},
638638
}
639639
reader.EXPECT().Get(ctx, client.ObjectKey{Namespace: namespace, Name: "dns-secret"},
@@ -651,7 +651,7 @@ var _ = Describe("Shoot validator", func() {
651651
c.EXPECT().Get(ctx, cloudProfileKey, &gardencorev1beta1.CloudProfile{}).SetArg(2, *cloudProfile)
652652
shoot.Spec.DNS = &core.DNS{
653653
Providers: []core.DNSProvider{
654-
{Type: ptr.To(aws.DNSType), SecretName: ptr.To("dns-secret")},
654+
{Type: ptr.To(aws.DNSType), SecretName: ptr.To("dns-secret"), Primary: ptr.To(true)},
655655
},
656656
}
657657
invalidSecret := &corev1.Secret{
@@ -676,7 +676,7 @@ var _ = Describe("Shoot validator", func() {
676676
c.EXPECT().Get(ctx, cloudProfileKey, &gardencorev1beta1.CloudProfile{}).SetArg(2, *cloudProfile)
677677
shoot.Spec.DNS = &core.DNS{
678678
Providers: []core.DNSProvider{
679-
{Type: ptr.To(aws.DNSType), SecretName: ptr.To("dns-secret")},
679+
{Type: ptr.To(aws.DNSType), SecretName: ptr.To("dns-secret"), Primary: ptr.To(true)},
680680
},
681681
}
682682
validSecret := &corev1.Secret{
@@ -694,6 +694,124 @@ var _ = Describe("Shoot validator", func() {
694694
err := shootValidator.Validate(ctx, shoot, nil)
695695
Expect(err).NotTo(HaveOccurred())
696696
})
697+
698+
It("should skip validation for non-primary aws-dns provider", func() {
699+
c.EXPECT().Get(ctx, cloudProfileKey, &gardencorev1beta1.CloudProfile{}).SetArg(2, *cloudProfile)
700+
shoot.Spec.DNS = &core.DNS{
701+
Providers: []core.DNSProvider{
702+
{Type: ptr.To(aws.DNSType), Primary: ptr.To(false), SecretName: ptr.To("dns-secret")},
703+
},
704+
}
705+
// No reader.EXPECT() call - secret should not be fetched for non-primary provider
706+
707+
err := shootValidator.Validate(ctx, shoot, nil)
708+
Expect(err).NotTo(HaveOccurred())
709+
})
710+
711+
It("should skip validation for aws-dns provider with Primary=nil", func() {
712+
c.EXPECT().Get(ctx, cloudProfileKey, &gardencorev1beta1.CloudProfile{}).SetArg(2, *cloudProfile)
713+
shoot.Spec.DNS = &core.DNS{
714+
Providers: []core.DNSProvider{
715+
{Type: ptr.To(aws.DNSType), Primary: nil, SecretName: ptr.To("dns-secret")},
716+
},
717+
}
718+
// No reader.EXPECT() call - secret should not be fetched when Primary is nil
719+
720+
err := shootValidator.Validate(ctx, shoot, nil)
721+
Expect(err).NotTo(HaveOccurred())
722+
})
723+
724+
It("should validate only primary provider when multiple aws-dns providers exist", func() {
725+
c.EXPECT().Get(ctx, cloudProfileKey, &gardencorev1beta1.CloudProfile{}).SetArg(2, *cloudProfile)
726+
shoot.Spec.DNS = &core.DNS{
727+
Providers: []core.DNSProvider{
728+
{Type: ptr.To(aws.DNSType), Primary: ptr.To(false), SecretName: ptr.To("non-primary-secret")},
729+
{Type: ptr.To(aws.DNSType), Primary: ptr.To(true), SecretName: ptr.To("primary-secret")},
730+
{Type: ptr.To(aws.DNSType), Primary: ptr.To(false), SecretName: ptr.To("another-non-primary")},
731+
},
732+
}
733+
// Only the primary secret should be validated
734+
validSecret := &corev1.Secret{
735+
ObjectMeta: metav1.ObjectMeta{Name: "primary-secret", Namespace: namespace},
736+
Data: map[string][]byte{
737+
aws.DNSAccessKeyID: []byte("AKIAIOSFODNN7EXAMPLE"),
738+
aws.DNSSecretAccessKey: []byte("wJalrXUtnFEMI/K7MDEN+/=PxRfiCYEXAMPLEKEY"),
739+
},
740+
}
741+
reader.EXPECT().Get(ctx, client.ObjectKey{Namespace: namespace, Name: "primary-secret"},
742+
&corev1.Secret{}).
743+
SetArg(2, *validSecret).
744+
Return(nil)
745+
746+
err := shootValidator.Validate(ctx, shoot, nil)
747+
Expect(err).NotTo(HaveOccurred())
748+
})
749+
750+
It("should validate primary provider even when mixed with other provider types", func() {
751+
c.EXPECT().Get(ctx, cloudProfileKey, &gardencorev1beta1.CloudProfile{}).SetArg(2, *cloudProfile)
752+
shoot.Spec.DNS = &core.DNS{
753+
Providers: []core.DNSProvider{
754+
{Type: ptr.To("cloudflare"), Primary: ptr.To(false), SecretName: ptr.To("cloudflare-secret")},
755+
{Type: ptr.To(aws.DNSType), Primary: ptr.To(true), SecretName: ptr.To("aws-secret")},
756+
{Type: ptr.To("google-clouddns"), Primary: ptr.To(false), SecretName: ptr.To("gcp-secret")},
757+
},
758+
}
759+
validSecret := &corev1.Secret{
760+
ObjectMeta: metav1.ObjectMeta{Name: "aws-secret", Namespace: namespace},
761+
Data: map[string][]byte{
762+
aws.DNSAccessKeyID: []byte("AKIAIOSFODNN7EXAMPLE"),
763+
aws.DNSSecretAccessKey: []byte("wJalrXUtnFEMI/K7MDEN+/=PxRfiCYEXAMPLEKEY"),
764+
},
765+
}
766+
reader.EXPECT().Get(ctx, client.ObjectKey{Namespace: namespace, Name: "aws-secret"},
767+
&corev1.Secret{}).
768+
SetArg(2, *validSecret).
769+
Return(nil)
770+
771+
err := shootValidator.Validate(ctx, shoot, nil)
772+
Expect(err).NotTo(HaveOccurred())
773+
})
774+
775+
It("should return error for invalid primary provider secret among multiple providers", func() {
776+
c.EXPECT().Get(ctx, cloudProfileKey, &gardencorev1beta1.CloudProfile{}).SetArg(2, *cloudProfile)
777+
shoot.Spec.DNS = &core.DNS{
778+
Providers: []core.DNSProvider{
779+
{Type: ptr.To(aws.DNSType), Primary: ptr.To(false), SecretName: ptr.To("non-primary-secret")},
780+
{Type: ptr.To(aws.DNSType), Primary: ptr.To(true), SecretName: ptr.To("primary-secret")},
781+
},
782+
}
783+
invalidSecret := &corev1.Secret{
784+
ObjectMeta: metav1.ObjectMeta{Name: "primary-secret", Namespace: namespace},
785+
Data: map[string][]byte{
786+
aws.DNSAccessKeyID: []byte("AKIAIOSFODNN7EXAMPLE"),
787+
// Missing secretAccessKey
788+
},
789+
}
790+
reader.EXPECT().Get(ctx, client.ObjectKey{Namespace: namespace, Name: "primary-secret"},
791+
&corev1.Secret{}).
792+
SetArg(2, *invalidSecret).
793+
Return(nil)
794+
795+
err := shootValidator.Validate(ctx, shoot, nil)
796+
Expect(err).To(ConsistOf(PointTo(MatchFields(IgnoreExtras, Fields{
797+
"Type": Equal(field.ErrorTypeRequired),
798+
"Field": Equal("spec.dns.providers[1].data[secretAccessKey]"),
799+
}))))
800+
})
801+
802+
It("should succeed when no aws-dns providers have Primary=true", func() {
803+
c.EXPECT().Get(ctx, cloudProfileKey, &gardencorev1beta1.CloudProfile{}).SetArg(2, *cloudProfile)
804+
shoot.Spec.DNS = &core.DNS{
805+
Providers: []core.DNSProvider{
806+
{Type: ptr.To(aws.DNSType), Primary: ptr.To(false), SecretName: ptr.To("secret1")},
807+
{Type: ptr.To(aws.DNSType), Primary: ptr.To(false), SecretName: ptr.To("secret2")},
808+
},
809+
}
810+
// No reader.EXPECT() calls - no secrets should be validated
811+
812+
err := shootValidator.Validate(ctx, shoot, nil)
813+
Expect(err).NotTo(HaveOccurred())
814+
})
697815
})
698816

699817
Context("Workerless Shoot", func() {

0 commit comments

Comments
 (0)