Commit 80e91b56 authored by Ryo Yamashita's avatar Ryo Yamashita Committed by Yas Naoi
Browse files

Issue #3300110 by Ryo Yamashita, yas: Add the function to delete AWS Cloud image in the SPA

parent 5b5385b2
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -18,6 +18,18 @@ const AWS_CLOUD_IMAGE_TEMPLATE: EntityFormTemplate[] = [
      }
    ]
  },
  {
    cloudServiceProvider: 'aws_cloud',
    entityName: 'image',
    actionType: 'delete',
    entityRecords: [
      {
        type: 'label',
        text: 'Are you sure you want to delete the {{name}} {{entityName}}?'
      },
    ],
    submitButtonLabel: 'Delete'
  },
  {
    cloudServiceProvider: 'aws_cloud',
    entityName: 'image',
+54 −0
Original line number Diff line number Diff line
@@ -893,6 +893,40 @@ entity.aws_cloud_entity.refresh:
  options:
    perm: 'edit any {entity_type_id}+edit own {entity_type_id}+list {entity_type_id}'

entity.aws_cloud_image.create:
  path: '/cloud_dashboard/aws_cloud/{cloud_context}/aws_cloud_image/{entity_id}/create'
  defaults:
    _controller: '\Drupal\aws_cloud\Controller\Ec2\ApiController::operateEntity'
    entity_type_id: aws_cloud_image
    command: create
  methods: [POST]
  requirements:
    _permission: 'add aws cloud image'

entity.aws_cloud_image.delete:
  path: '/cloud_dashboard/aws_cloud/{cloud_context}/aws_cloud_image/{entity_id}/delete'
  defaults:
    _controller: '\Drupal\aws_cloud\Controller\Ec2\ApiController::operateEntity'
    entity_type_id: aws_cloud_image
    command: delete
  methods: [POST]
  requirements:
    _permission: 'delete any aws cloud image'

entity.aws_cloud_image.edit:
  path: '/cloud_dashboard/aws_cloud/{cloud_context}/aws_cloud_image/{entity_id}/edit'
  defaults:
    _controller: '\Drupal\aws_cloud\Controller\Ec2\ApiController::operateEntity'
    entity_type_id: aws_cloud_image
    command: edit
  methods: [POST]
  requirements:
    # Use custom access that will check for cloud_context and the desired permission.
    # Desired permission is passed as an option in the "perm" variable
    _custom_access: '\Drupal\cloud\Controller\CloudConfigController::access'
  options:
      perm: 'edit any aws cloud image+edit own aws cloud image'

entity.aws_cloud_instance.instance_types:
  path: '/cloud_dashboard/aws_cloud/{cloud_context}/instance_types'
  defaults:
@@ -1041,3 +1075,23 @@ entity.aws_cloud_instance.stop:
  methods: [POST]
  requirements:
    _entity_access: 'aws_cloud_instance.stop'

entity.aws_cloud_security_group.create:
  path: '/cloud_dashboard/aws_cloud/{cloud_context}/aws_cloud_security_group/{entity_id}/create'
  defaults:
    _controller: '\Drupal\aws_cloud\Controller\Ec2\ApiController::operateEntity'
    entity_type_id: aws_cloud_security_group
    command: create
  methods: [POST]
  requirements:
    _permission: 'add aws cloud security group'

entity.aws_cloud_security_group.revoke:
  path: '/cloud_dashboard/aws_cloud/{cloud_context}/aws_cloud_security_group/{entity_id}/revoke'
  defaults:
    _controller: '\Drupal\aws_cloud\Controller\Ec2\ApiController::operateEntity'
    entity_type_id: aws_cloud_security_group
    command: revoke
  methods: [POST]
  requirements:
    _permission: 'delete any aws cloud security group'
+4 −0
Original line number Diff line number Diff line
@@ -824,6 +824,10 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
          $method_name = 'createSecurityGroup';
          break;

        case 'delete_aws_cloud_image':
          $method_name = 'deleteImage';
          break;

        case 'delete_aws_cloud_instance':
          $method_name = 'deleteInstance';
          break;
+111 −63
Original line number Diff line number Diff line
@@ -2,8 +2,20 @@

namespace Drupal\aws_cloud\Form\Ec2;

use Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface;
use Drupal\aws_cloud\Service\Ec2\Ec2ServiceInterface;
use Drupal\cloud\Plugin\cloud\config\CloudConfigPluginManagerInterface;
use Drupal\cloud\Service\EntityLinkRendererInterface;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\Messenger;
use Drupal\Core\Plugin\CachedDiscoveryClearerInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a form for deleting a Image entity.
@@ -12,11 +24,102 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
 */
class ImageDeleteForm extends AwsDeleteUpdateEntityForm {

  /**
   * The AWS Cloud Operations service.
   *
   * @var \Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface
   */
  protected $awsCloudOperationsService;

  /**
   * ImageDeleteForm constructor.
   *
   * @param \Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface $aws_cloud_operations_service
   *   The AWS Cloud Operations service.
   * @param \Drupal\openstack\Service\OpenStackServiceFactoryInterface $openstack_service_factory
   *   Object for interfacing with OpenStack Service.
   * @param \Drupal\aws_cloud\Service\Ec2\Ec2ServiceInterface $ec2_service
   *   The AWS Cloud EC2 service.
   * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
   *   The entity repository service.
   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
   *   The entity type bundle service.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   * @param \Drupal\Core\Messenger\Messenger $messenger
   *   The messenger service.
   * @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
   *   The Entity Type Manager.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cacheRender
   *   A cache backend interface instance.
   * @param \Drupal\Core\Plugin\CachedDiscoveryClearerInterface $plugin_cache_clearer
   *   A plugin cache clear instance.
   * @param \Drupal\cloud\Service\EntityLinkRendererInterface $entity_link_renderer
   *   The entity link render service.
   * @param \Drupal\cloud\Plugin\cloud\config\CloudConfigPluginManagerInterface $cloud_config_plugin_manager
   *   The cloud service provider plugin manager (CloudConfigPluginManager).
   */
  public function __construct(
    AwsCloudOperationsServiceInterface $aws_cloud_operations_service,
    Ec2ServiceInterface $ec2_service,
    EntityRepositoryInterface $entity_repository,
    EntityTypeBundleInfoInterface $entity_type_bundle_info,
    TimeInterface $time,
    Messenger $messenger,
    EntityTypeManager $entity_type_manager,
    CacheBackendInterface $cacheRender,
    CachedDiscoveryClearerInterface $plugin_cache_clearer,
    EntityLinkRendererInterface $entity_link_renderer,
    CloudConfigPluginManagerInterface $cloud_config_plugin_manager
  ) {
    parent::__construct(
      $ec2_service,
      $entity_repository,
      $entity_type_bundle_info,
      $time,
      $messenger,
      $entity_type_manager,
      $cacheRender,
      $plugin_cache_clearer,
      $entity_link_renderer,
      $cloud_config_plugin_manager
    );

    $this->awsCloudOperationsService = $aws_cloud_operations_service;
  }

  /**
   * Dependency Injection.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   Instance of ContainerInterface.
   *
   * @return OpenStackImageDeleteForm
   *   return created object.
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('aws_cloud.operations'),
      $container->get('aws_cloud.ec2'),
      $container->get('entity.repository'),
      $container->get('entity_type.bundle.info'),
      $container->get('datetime.time'),
      $container->get('messenger'),
      $container->get('entity_type.manager'),
      $container->get('cache.render'),
      $container->get('plugin.cache_clearer'),
      $container->get('entity.link_renderer'),
      $container->get('plugin.manager.cloud_config_plugin'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getDescription(): TranslatableMarkup {
    $state = $this->entity->getStatus();
    /** @var \Drupal\aws_cloud\Entity\Ec2\ImageInterface $entity */
    $entity = $this->entity;
    $state = $entity->getStatus();
    if ($state === 'pending') {
      return $this->t("Cannot delete an image in @state state.", [
        '@state' => $state,
@@ -29,7 +132,9 @@ class ImageDeleteForm extends AwsDeleteUpdateEntityForm {
   * {@inheritdoc}
   */
  public function getQuestion(): ?TranslatableMarkup {
    if ($this->entity->getStatus() === 'pending') {
    /** @var \Drupal\aws_cloud\Entity\Ec2\ImageInterface $entity */
    $entity = $this->entity;
    if ($entity->getStatus() === 'pending') {
      return NULL;
    }
    return parent::getQuestion();
@@ -40,7 +145,9 @@ class ImageDeleteForm extends AwsDeleteUpdateEntityForm {
   */
  protected function actions(array $form, FormStateInterface $form_state): array {
    $actions = parent::actions($form, $form_state);
    if ($this->entity->getStatus() === 'pending') {
    /** @var \Drupal\aws_cloud\Entity\Ec2\ImageInterface $entity */
    $entity = $this->entity;
    if ($entity->getStatus() === 'pending') {
      unset($actions['submit']);
    }
    return $actions;
@@ -50,66 +157,7 @@ class ImageDeleteForm extends AwsDeleteUpdateEntityForm {
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {

    $entity = $this->entity;
    if ($entity->getEntityTypeId() === 'aws_cloud_image'
        && !$this->updateEntitySubmitForm($form_state, $entity)) {
      return;
    }

    $this->ec2Service->setCloudContext($entity->getCloudContext());
    $this->cloudConfigPluginManager->setCloudContext($entity->getCloudContext());
    $account_id = $this->cloudConfigPluginManager->loadConfigEntity()->get('field_account_id')->value;

    // If the image is not owned by the aws user,
    // the calling for deregisterImage will be skipped for AWS Cloud
    // and it will be called for OpenStack.
    if (($entity->getEntityTypeId() === 'aws_cloud_image'
    && ($entity->getAccountId() !== $account_id))
    || ($result = $this->ec2Service->deregisterImage([
      'ImageId' => $entity->getImageId(),
    ])) !== NULL) {

      if (!empty($result['SendToWorker'])) {
        $this->messenger->addStatus($this->t('The @type @label has been deleted remotely.', [
          '@type'  => $entity->getEntityType()->getSingularLabel(),
          '@label' => $entity->getName(),
        ]));

        $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]);
        return;
      }

      $entity->delete();

      // Do not change the following message since we cannot use
      // $entity->label(), which represents 'ami_name'.
      $this->messenger->addStatus($this->t('The @type @label has been deleted.', [
        '@type'  => $entity->getEntityType()->getSingularLabel(),
        '@label' => $entity->getName(),
      ]));
      $this->logDeletionMessage();
      $this->clearCacheValues($entity->getCacheTags());
      $this->dispatchSubmitEvent($entity);
    }
    else {

      // Do not change the following message since we cannot use
      // $entity->label(), which represents 'ami_name'.
      $this->messenger->addError($this->t('The @type @label could not be deleted.', [
        '@type'  => $entity->getEntityType()->getSingularLabel(),
        '@label' => $entity->getName(),
      ]));

      $this->logger($entity->getEntityType()->getProvider())->error($this->t('@type: @label could not be deleted.', [
        '@type' => $entity->getEntityType()->getLabel(),
        '@label' => $entity->label(),
      ]), [
        'link' => $entity->toLink($this->t('View'))->toString(),
      ]);
    }

    $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]);
    $this->awsCloudOperationsService->deleteImage($this->entity, $form, $form_state);
  }

}
+66 −0
Original line number Diff line number Diff line
@@ -794,6 +794,72 @@ class AwsCloudOperationsService implements AwsCloudOperationsServiceInterface {
    }
  }

  /**
   * {@inheritdoc}
   */
  public function deleteImage(ImageInterface $entity, array $form, FormStateInterface $form_state): bool {
    $this->entity = $entity;
    if ($entity->getEntityTypeId() === 'aws_cloud_image'
        && !$this->updateEntitySubmitForm($form_state, $entity)) {
      return FALSE;
    }

    $this->ec2Service->setCloudContext($entity->getCloudContext());
    $this->cloudConfigPluginManager->setCloudContext($entity->getCloudContext());
    $account_id = $this->cloudConfigPluginManager->loadConfigEntity()->get('field_account_id')->value;

    // If the image is not owned by the aws user,
    // the calling for deregisterImage will be skipped for AWS Cloud,
    // and it will be called for OpenStack.
    if (($entity->getEntityTypeId() === 'aws_cloud_image'
    && ($entity->getAccountId() !== $account_id))
    || ($result = $this->ec2Service->deregisterImage([
      'ImageId' => $entity->getImageId(),
    ])) !== NULL) {

      if (!empty($result['SendToWorker'])) {
        $this->messenger->addStatus($this->t('The @type @label has been deleted remotely.', [
          '@type'  => $entity->getEntityType()->getSingularLabel(),
          '@label' => $entity->getName(),
        ]));

        $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]);
        return TRUE;
      }

      $entity->delete();

      // Do not change the following message since we cannot use
      // $entity->label(), which represents 'ami_name'.
      $this->messenger->addStatus($this->t('The @type @label has been deleted.', [
        '@type'  => $entity->getEntityType()->getSingularLabel(),
        '@label' => $entity->getName(),
      ]));
      $this->logDeletionMessage();
      $this->clearCacheValues($entity->getCacheTags());
      $this->dispatchSubmitEvent($entity);
    }
    else {

      // Do not change the following message since we cannot use
      // $entity->label(), which represents 'ami_name'.
      $this->messenger->addError($this->t('The @type @label could not be deleted.', [
        '@type'  => $entity->getEntityType()->getSingularLabel(),
        '@label' => $entity->getName(),
      ]));

      $this->logger($entity->getEntityType()->getProvider())->error($this->t('@type: @label could not be deleted.', [
        '@type' => $entity->getEntityType()->getLabel(),
        '@label' => $entity->label(),
      ]), [
        'link' => $entity->toLink($this->t('View'))->toString(),
      ]);
    }

    $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]);
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
Loading