Skip to content

Commit

Permalink
Fix/ensuring existing secrets resulting in panic(#23)
Browse files Browse the repository at this point in the history
* fix subreconciler requeue handling for setting controller reference

* add webhook validation for existing secrets

* add validation webhook test phase for existing secrets

* revise forbidden error in validate secrets webhook
  • Loading branch information
hoptical authored Nov 29, 2023
1 parent 5052540 commit 2aac745
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 3 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ Dockerfile.cross
*.swp
*.swo
*~

.vscode
vendor/

# Downloaded go release for building testing Dockerfile
testing/go*.tar.gz
# Container id files of dev env containers
Expand Down
34 changes: 34 additions & 0 deletions api/v1alpha1/s3userclaim_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ func (suc *S3UserClaim) ValidateCreate() error {

allErrs = validateQuota(suc, allErrs)

secretNames := []string{suc.Spec.AdminSecret, suc.Spec.ReadonlySecret}
allErrs = validateSecrets(secretNames, suc.Namespace, allErrs)

if len(allErrs) == 0 {
return nil
}
Expand All @@ -97,6 +100,17 @@ func (suc *S3UserClaim) ValidateUpdate(old runtime.Object) error {

allErrs = validateQuota(suc, allErrs)

// validate against updated secret names
var secretNames []string
if oldS3UserClaim.Spec.AdminSecret != suc.Spec.AdminSecret {
secretNames = append(secretNames, suc.Spec.AdminSecret)
}
if oldS3UserClaim.Spec.ReadonlySecret != suc.Spec.ReadonlySecret {
secretNames = append(secretNames, suc.Spec.ReadonlySecret)
}

allErrs = validateSecrets(secretNames, suc.Namespace, allErrs)

if len(allErrs) == 0 {
return nil
}
Expand Down Expand Up @@ -224,3 +238,23 @@ func validateAgainstClusterQuota(ctx context.Context, suc *S3UserClaim) error {

return nil
}

func validateSecrets(secretNames []string, namespace string, allErrs field.ErrorList) field.ErrorList {
ctx, cancel := context.WithTimeout(context.Background(), ValidationTimeout)
defer cancel()
for _, secretName := range secretNames {
existingSecret := &v1.Secret{}
switch err := runtimeClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: secretName}, existingSecret); {
case apierrors.IsNotFound(err):
continue
case err != nil:
allErrs = append(allErrs,
field.InternalError(field.NewPath("spec"), fmt.Errorf("error with getting secret '%s': %w", secretName, err)))
default:
allErrs = append(allErrs,
field.Forbidden(field.NewPath("spec"), fmt.Sprintf("secret %s exists", secretName)))
}
}
return allErrs

}
3 changes: 2 additions & 1 deletion internal/controllers/s3userclaim/provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,8 @@ func (r *Reconciler) ensureSecret(ctx context.Context, secret *corev1.Secret) (*
!metav1.IsControlledBy(existingSecret, r.s3UserClaim) {
existingSecret.Data = secret.Data
if err := ctrl.SetControllerReference(r.s3UserClaim, existingSecret, r.scheme); err != nil {
return nil, err
r.logger.Error(err, "failed to set controller reference", "secret name", secret.Name)
return subreconciler.Requeue()
}
if err := r.Update(ctx, existingSecret); err != nil {
r.logger.Error(err, "failed to update secret", "name", secret.Name)
Expand Down
2 changes: 1 addition & 1 deletion pkg/consts/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const (
ErrClusterQuotaNotDefined = CustomError("cluster quota is not defined")
S3UserClassImmutableErrMessage = "s3UserClass is immutable"
S3UserRefImmutableErrMessage = "s3UserRef is immutable"
S3UserRefNotFoundErrMessage = "There is no s3UserClaim regarding the defined s3UserRef"
S3UserRefNotFoundErrMessage = "there is no s3UserClaim regarding the defined s3UserRef"
ContactCloudTeamErrMessage = "please contact the cloud team"

FinalizerPrefix = "s3.snappcloud.io/"
Expand Down
3 changes: 3 additions & 0 deletions testing/e2e/04-validation-webhook.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ commands:
ignoreFailure: true
- command: kubectl apply -f s3bucket-wrong-s3userref.yaml
ignoreFailure: true
- command: kubectl apply -f create-s3user-with-existing-secret.yaml
ignoreFailure: true
- command: kubectl delete s3userclaim s3userclaim-sample -n s3-test
ignoreFailure: true
assert:
- s3bucket-ok.yaml
- 02-assert.yaml
error:
- s3bucket-wrong-s3userref.yaml
- create-s3user-with-existing-secret.yaml
16 changes: 16 additions & 0 deletions testing/e2e/create-s3user-with-existing-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Creating s3userclaim with existing secrets must be deined
apiVersion: s3.snappcloud.io/v1alpha1
kind: S3UserClaim
metadata:
name: s3userclaim-sample2
namespace: s3-test
spec:
s3UserClass: ceph-default
# existing secrets
readonlySecret: s3-sample-readonly-secret
adminSecret: s3-sample-admin-secret
quota:
maxSize: 100
maxObjects: 50
maxBuckets: 5

0 comments on commit 2aac745

Please sign in to comment.