Skip to content

Commit b3e73ff

Browse files
authored
Allow shoots to use WorkloadIdentity as DNS credentials (#1730)
1 parent 262ffb4 commit b3e73ff

File tree

4 files changed

+517
-210
lines changed

4 files changed

+517
-210
lines changed

pkg/admission/validator/secrets.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ func NewSecretValidator() extensionswebhook.Validator {
2626

2727
// Validate checks whether the given new secret contains valid AWS credentials.
2828
func (s *secret) Validate(_ context.Context, newObj, oldObj client.Object) error {
29+
return ValidateSecret(newObj, oldObj)
30+
}
31+
32+
// ValidateSecret checks whether the given new secret contains valid AWS credentials.
33+
func ValidateSecret(newObj, oldObj client.Object) error {
2934
secret, ok := newObj.(*corev1.Secret)
3035
if !ok {
3136
return fmt.Errorf("wrong object type %T", newObj)

pkg/admission/validator/shoot.go

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ import (
1313
"github.com/gardener/gardener/pkg/apis/core"
1414
gardencorehelper "github.com/gardener/gardener/pkg/apis/core/helper"
1515
gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
16+
securityv1alpha1 "github.com/gardener/gardener/pkg/apis/security/v1alpha1"
1617
"github.com/gardener/gardener/pkg/utils/gardener"
18+
"github.com/gardener/gardener/pkg/utils/kubernetes"
1719
corev1 "k8s.io/api/core/v1"
1820
apierrors "k8s.io/apimachinery/pkg/api/errors"
1921
"k8s.io/apimachinery/pkg/runtime"
@@ -241,25 +243,60 @@ func (s *shoot) validateDNS(ctx context.Context, shoot *core.Shoot) field.ErrorL
241243

242244
providerFldPath := dnsProvidersPath.Index(i)
243245

244-
if p.SecretName == nil || *p.SecretName == "" {
245-
allErrs = append(allErrs, field.Required(providerFldPath.Child("secretName"),
246-
fmt.Sprintf("secretName must be specified for %v provider", aws.DNSType)))
247-
continue
248-
}
246+
// TODO(vpnachev): Enable this validation once the extension does not support github.com/gardener/gardener < v1.135.0
247+
// if p.CredentialsRef == nil {
248+
// allErrs = append(allErrs, field.Required(providerFldPath.Child("credentialsRef"), "must be set"))
249+
// }
249250

250-
secret := &corev1.Secret{}
251-
key := client.ObjectKey{Namespace: shoot.Namespace, Name: *p.SecretName}
252-
if err := s.apiReader.Get(ctx, key, secret); err != nil {
253-
if apierrors.IsNotFound(err) {
254-
allErrs = append(allErrs, field.Invalid(providerFldPath.Child("secretName"),
255-
*p.SecretName, "referenced secret not found"))
256-
} else {
257-
allErrs = append(allErrs, field.InternalError(providerFldPath.Child("secretName"), err))
251+
if p.CredentialsRef != nil {
252+
credentialsFldPath := providerFldPath.Child("credentialsRef")
253+
254+
credentials, err := kubernetes.GetCredentialsByCrossVersionObjectReference(ctx, s.apiReader, *p.CredentialsRef, shoot.GetNamespace())
255+
if err != nil {
256+
if apierrors.IsNotFound(err) {
257+
allErrs = append(allErrs, field.NotFound(credentialsFldPath, p.CredentialsRef.String()))
258+
} else {
259+
allErrs = append(allErrs, field.InternalError(credentialsFldPath, err))
260+
}
261+
continue
258262
}
259-
continue
260-
}
261263

262-
allErrs = append(allErrs, awsvalidation.ValidateCloudProviderSecret(secret, providerFldPath)...)
264+
switch creds := credentials.(type) {
265+
case *securityv1alpha1.WorkloadIdentity:
266+
if err := ValidateWorkloadIdentity(creds, nil); err != nil {
267+
allErrs = append(allErrs, field.Invalid(credentialsFldPath, p.CredentialsRef.String(), err.Error()))
268+
}
269+
case *corev1.Secret:
270+
if err := ValidateSecret(creds, nil); err != nil {
271+
allErrs = append(allErrs, field.Invalid(credentialsFldPath, p.CredentialsRef.String(), err.Error()))
272+
}
273+
default:
274+
allErrs = append(allErrs, field.Invalid(credentialsFldPath, p.CredentialsRef.String(), "supported credentials types are Secret and WorkloadIdentity"))
275+
}
276+
} else { // TODO(vpnachev): Remove the else block once the extension does not support github.com/gardener/gardener < v1.135.0
277+
secretNameFldPath := providerFldPath.Child("secretName")
278+
if p.SecretName == nil || *p.SecretName == "" {
279+
allErrs = append(allErrs, field.Required(secretNameFldPath,
280+
fmt.Sprintf("secretName must be specified for %v provider", aws.DNSType)))
281+
continue
282+
}
283+
284+
secret := &corev1.Secret{}
285+
key := client.ObjectKey{Namespace: shoot.Namespace, Name: *p.SecretName}
286+
if err := s.apiReader.Get(ctx, key, secret); err != nil {
287+
if apierrors.IsNotFound(err) {
288+
allErrs = append(allErrs, field.Invalid(secretNameFldPath,
289+
*p.SecretName, "referenced secret not found"))
290+
} else {
291+
allErrs = append(allErrs, field.InternalError(secretNameFldPath, err))
292+
}
293+
continue
294+
}
295+
296+
if err := ValidateSecret(secret, nil); err != nil {
297+
allErrs = append(allErrs, field.Invalid(secretNameFldPath, p.SecretName, err.Error()))
298+
}
299+
}
263300
}
264301

265302
return allErrs

0 commit comments

Comments
 (0)