Skip to content

Commit

Permalink
block deletion on bucket ownership
Browse files Browse the repository at this point in the history
daanvinken committed Nov 14, 2023
1 parent 33ca832 commit 912025e
Showing 2 changed files with 61 additions and 14 deletions.
49 changes: 35 additions & 14 deletions internal/controller/cephuser/cephuser.go
Original file line number Diff line number Diff line change
@@ -59,6 +59,8 @@ const (
errVaultCleanup = "Failed to remove credentials from vault"
errFetchSecret = "unable to extract secret data '%s' from vault"
errVaultClientCreate = "failed to create vault client for storing ceph credentials"
errListBuckets = "error listing user's buckets"
errUserStillHasBuckets = "ceph user still owns buckets"

inUseFinalizer = "cephuser-in-use.ceph.radosgw.crossplane.io"
)
@@ -313,30 +315,39 @@ func (c *external) Delete(ctx context.Context, mg resource.Managed) error {
// These fmt statements should be removed in the real implementation.
fmt.Printf("Deleting: %+v\n", cr.Name)

// Radosgw also doesn't allow removal if the user has buckets.
// TODO Still I think we shouldn't just trust this
if controllerutil.RemoveFinalizer(cr, inUseFinalizer) {
err := c.kubeClient.Update(ctx, cr)
if err != nil {
c.log.Info("Failed to remove in-use finalizer on cephuser", "cephUser_uid", cr.Spec.ForProvider.UID, "error", err.Error())
return errors.Wrap(err, errDeleteCephUser)
pc := &apisv1alpha1.ProviderConfig{}
if err := c.kubeClient.Get(ctx, types.NamespacedName{Name: cr.GetProviderConfigReference().Name}, pc); err != nil {
return errors.Wrap(err, errGetPC)
}

secretPath, err := credentials.BuildCephUserSecretPath(*pc, *cr.Spec.ForProvider.UID)

hasBuckets, err := cephUserHasBuckets(c.rgwClient, cr)
if err != nil {
c.log.Info("Failed to verify if user still has buckets during deletion", "cephUser_uid", cr.Spec.ForProvider.UID, "error", err.Error())
return errors.Wrap(err, errDeleteCephUser)
}

if !hasBuckets {
if controllerutil.RemoveFinalizer(cr, inUseFinalizer) {
err := c.kubeClient.Update(ctx, cr)
if err != nil {
c.log.Info("Failed to remove in-use finalizer on cephuser", "cephUser_uid", cr.Spec.ForProvider.UID, "error", err.Error())
return errors.Wrap(err, errDeleteCephUser)
}
}
} else {
return fmt.Errorf(errUserStillHasBuckets)
}

user := radosgw.GenerateCephUserInput(cr)
err := c.rgwClient.RemoveUser(ctx, *user)
err = c.rgwClient.RemoveUser(ctx, *user)
if err != nil {
c.log.Info("Failed to remove cephUser on radosgw", "cephUser_uid", cr.Spec.ForProvider.UID, "error", err.Error())
return errors.Wrap(err, errDeleteCephUser)

}

pc := &apisv1alpha1.ProviderConfig{}
if err := c.kubeClient.Get(ctx, types.NamespacedName{Name: cr.GetProviderConfigReference().Name}, pc); err != nil {
return errors.Wrap(err, errGetPC)
}

secretPath, err := credentials.BuildCephUserSecretPath(*pc, *cr.Spec.ForProvider.UID)
err = credentials.RemoveSecretFromVault(c.vaultClient, pc.Spec.CredentialsVault, &secretPath)
if err != nil {
c.log.Info("Failed to remove credentials from Vault", "cephUser_uid", cr.Spec.ForProvider.UID, "error", err.Error())
@@ -356,3 +367,13 @@ func isAlreadyExists(err error) bool {
}
return false
}

func cephUserHasBuckets(radosgwClient *radosgw_admin.API, cephUser *v1alpha1.CephUser) (bool, error) {
buckets, err := radosgwClient.ListUsersBuckets(context.TODO(), *cephUser.Spec.ForProvider.UID)
if err != nil {
return false, errors.Wrap(err, errListBuckets)
}

// Check if the user has any buckets
return len(buckets) > 0, nil
}
26 changes: 26 additions & 0 deletions internal/credentials/vault.go
Original file line number Diff line number Diff line change
@@ -92,6 +92,32 @@ func RemoveSecretFromVault(client *vault.Client, vaultConfig v1alpha1.VaultConfi
return nil
}

func ReadSecretsFromVault(client *vault.Client, vaultConfig v1alpha1.VaultConfig, key *string) (map[string]interface{}, error) {
var secretData map[string]interface{}

if vaultConfig.KVVersion == "1" {
data, err := client.KVv1(vaultConfig.MountPath).Get(context.TODO(), *key)
if err != nil {
return nil, errors.Wrapf(err, "failed to read from vault kv1 at '%s'", vaultConfig.MountPath)
}
if data != nil {
secretData = data.Data
}
} else if vaultConfig.KVVersion == "2" {
data, err := client.KVv2(vaultConfig.MountPath).Get(context.TODO(), *key)
if err != nil {
return nil, errors.Wrapf(err, "failed to read from vault kv2 at '%s'", vaultConfig.MountPath)
}
if data != nil && data.Data != nil {
secretData = data.Data["data"].(map[string]interface{})
}
} else {
return nil, fmt.Errorf("unsupported KV version: %s", vaultConfig.KVVersion)
}

return secretData, nil
}

func BuildCephUserSecretPath(pc v1alpha1.ProviderConfig, cephUserUID string) (string, error) {
prefix := "ceph-"
if !strings.HasPrefix(pc.Name, prefix) {

0 comments on commit 912025e

Please sign in to comment.