Commit 99729b41 authored by baldwinlouie's avatar baldwinlouie Committed by Yas Naoi
Browse files

Issue #3325391 by baldwinlouie, yas: Refactor to reassign UID for VMware entities

parent 71ec0794
Loading
Loading
Loading
Loading
+120 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ use Drupal\file\Entity\File;
use Drupal\vmware\Entity\VmwareHost;
use Drupal\vmware\Entity\VmwareVm;
use Drupal\vmware\Service\VmwareServiceException;
use Drupal\user\Entity\User;

/**
 * Implements hook_help().
@@ -567,3 +568,122 @@ function vmware_vmware_host_predelete(VmwareHost $entity): void {
function vmware_query_vmware_entity_views_access_alter(AlterableInterface $query): void {
  \Drupal::service('cloud')->buildOwnerQueryCondition($query);
}

/**
 * Implements hook_ENTITY_TYPE_predelete().
 */
function vmware_user_predelete($account): void {
  /** @var Drupal\cloud\Service\CloudService $cloud_service */
  $cloud_service = \Drupal::service('cloud');
  $entity_types = $cloud_service->getProviderEntityTypes('vmware');
  foreach ($entity_types ?: [] as $entity_type) {
    if (empty($entity_type)) {
      continue;
    }
    $ids = \Drupal::entityTypeManager()
      ->getStorage($entity_type->id())
      ->getQuery()
      ->accessCheck(TRUE)
      ->condition('uid', $account->id())
      ->execute();
    if (count($ids) === 0) {
      continue;
    }
    $cloud_service->reassignUids($ids, [
      'uid' => 0,
    ], $entity_type->id(), FALSE, $account, [
      'vmware_reassign_entity_uid_callback',
    ]);
  }
}

/**
 * Additional callback during user delete operation.
 *
 * Callback reassigns UID on the VMware side.
 *
 * @param array $entities
 *   Array of entity ids.
 * @param array $updates
 *   Array of key/values to update.
 * @param string $entity_type
 *   The entity type.
 * @param bool $revision
 *   TRUE if the entities support revisions.
 * @param Drupal\user\Entity\User $account
 *   User entity.
 * @param array|\ArrayAccess $context
 *   An array of contextual key/values.
 */
function vmware_reassign_entity_uid_callback(array $entities, array $updates, string $entity_type, bool $revision, User $account, &$context): void {
  if (count($entities) === 0) {
    return;
  }
  if (!isset($context['sandbox']['progress'])) {
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['max'] = count($entities);
    $context['sandbox']['entities'] = $entities;
  }

  try {
    $storage = \Drupal::entityTypeManager()->getStorage($entity_type);

    /** @var Drupal\vmware\Service\VmwareService $vmware_service */
    $vmware_service = \Drupal::service('vmware');
    $count = min(5, count($context['sandbox']['entities']));

    for ($i = 1; $i <= $count; $i++) {
      $entity = array_shift($context['sandbox']['entities']);
      $entity = $storage->load($entity);

      $id_method = vmware_get_id_method($entity_type);

      if (empty($id_method) || !method_exists($entity, $id_method)) {
        // Skip to next entity.
        $context['sandbox']['progress']++;
        continue;
      }

      $vmware_service->setCloudContext($entity->getCloudContext());
      $vmware_service->login();
      $vmware_service->updateTagValueCreatedByUid($entity, $entity->$id_method() ?? '');

      // Update our progress information.
      $context['sandbox']['progress']++;
    }
  }
  catch (\Exception $e) {
    \Drupal::service('cloud')->handleException($e);
    // Set progress value to max so batch processing completes.
    $context['sandbox']['progress'] = $context['sandbox']['max'];
  }

  // Inform the batch engine that we are not finished,
  // and provide an estimation of the completion level we reached.
  if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
  }
}

/**
 * Derive the get*Id() method of each entity type.
 *
 * @param string $entity_type
 *   The entity type.
 *
 * @return string
 *   The get*Id() method name.
 */
function vmware_get_id_method($entity_type): string {
  $id_class = '';
  switch ($entity_type) {
    case 'vmware_vm':
      $id_class = 'getVmId';
      break;

    default:
      // No other entities are reassigned.
      break;
  }
  return $id_class;
}