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

Issue #3310457 by baldwinlouie, yas, Ryo Yamashita, sekinet: Add the function...

Issue #3310457 by baldwinlouie, yas, Ryo Yamashita, sekinet: Add the function to edit AWS Subnet in the SPA
parent 74aaaafb
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -26,6 +26,28 @@ const AWS_CLOUD_SUBNET_TEMPLATE: EntityFormTemplate[] = [
        ]
      }
    ]
  },
  {
    cloudServiceProvider: 'aws_cloud',
    entityName: 'subnet',
    actionType: 'edit',
    entityRecords: [
      {
        type: 'panel',
        panelName: 'Subnet',
        keyValueRecords: [
          { type: 'default', labelName: 'Name', name: 'name', defaultValue: '', required: true },
          { type: 'default', labelName: 'CIDR Block', name: 'cidr_block', defaultValue: '', readOnly: true },
          { type: 'default', labelName: 'Subnet ID', name: 'subnet_id', defaultValue: '', readOnly: true },
          { type: 'default', labelName: 'VPC ID', name: 'vpc_id', defaultValue: '', readOnly: true },
          { type: 'default', labelName: 'Availability Zone', name: 'availability_zone', defaultValue: '', readOnly: true },
          { type: 'default', labelName: 'State', name: 'state', defaultValue: '', readOnly: true },
          { type: 'default', labelName: 'AWS account ID', name: 'account_id', defaultValue: '', readOnly: true },
          { type: 'datetime', labelName: 'Created', name: 'created', defaultValue: 0, readOnly: true },
          {type: 'key-value', labelName: 'Tags', name: 'tags', defaultValue: [] },
        ]
      }
    ]
  }
]

+14 −0
Original line number Diff line number Diff line
@@ -1603,6 +1603,20 @@ entity.aws_cloud_subnet.create:
  requirements:
    _permission: 'add aws cloud subnet'

entity.aws_cloud_subnet.edit:
  path: '/cloud_dashboard/aws_cloud/{cloud_context}/aws_cloud_subnet/{entity_id}/edit'
  defaults:
    _controller: '\Drupal\aws_cloud\Controller\Ec2\ApiController::operateEntity'
    entity_type_id: aws_cloud_subnet
    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 subnet+edit own aws cloud subnet'

entity.aws_cloud_vpc_peering_connection.create:
  path: '/cloud_dashboard/aws_cloud/{cloud_context}/aws_cloud_vpc_peering_connection/create'
  defaults:
+15 −2
Original line number Diff line number Diff line
@@ -923,6 +923,7 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
          $entity->setAutoAcceptSharedAttachments(filter_var($request->get('auto_accept_shared_attachments', FALSE), FILTER_VALIDATE_BOOLEAN));
          $entity->setAssociationDefaultRouteTableId($request->get('association_default_route_table_id', ''));
          $entity->setPropagationDefaultRouteTableId($request->get('propagation_default_route_table_id', ''));
          $entity->set('tags', json_decode($request->get('tags', '[]'), TRUE));
          $method_name = 'editTransitGateway';
          break;

@@ -945,6 +946,18 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
          $method_name = 'createSubnet';
          break;

        case 'edit_aws_cloud_subnet':
          /** @var \Drupal\aws_cloud\Entity\Vpc\SubnetInterface $entity */
          $entity->setName($request->get('name', ''));
          $entity->setVpcId($request->get('vpc_id', ''));
          $entity->setAvailabilityZone($request->get('availability_zone', ''));
          $entity->setCidrBlock($request->get('cidr_block', ''));
          $entity->setState($request->get('state', ''));
          $entity->setAccountId($request->get('account_id', ''));
          $entity->setTags(json_decode($request->get('tags', '[]'), TRUE));
          $method_name = 'editSubnet';
          break;

        case 'create_aws_cloud_internet_gateway':
          /** @var \Drupal\aws_cloud\Entity\Vpc\InternetGatewayInterface $entity */
          $entity->setName($request->get('name', ''));
@@ -1171,7 +1184,7 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
          $entity->setCarrierGatewayId($request->get('carrier_gateway_id', ''));
          $entity->setState($request->get('state', ''));
          $entity->setVpcId($vpc_id);
          $form_state->set('tags', json_decode($request->get('tags', '[]'), TRUE));
          $entity->set('tags', json_decode($request->get('tags', '[]'), TRUE));
          $method_name = 'editCarrierGateway';
          break;

@@ -1183,7 +1196,7 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
          $entity->setInternetGatewayId($request->get('internet_gateway_id', ''));
          $entity->setState($request->get('state', ''));
          $entity->setVpcId($vpc_id);
          $form_state->set('tags', json_decode($request->get('tags', '[]'), TRUE));
          $entity->set('tags', json_decode($request->get('tags', '[]'), TRUE));
          $method_name = 'editInternetGateway';
          break;

+124 −42
Original line number Diff line number Diff line
@@ -3,9 +3,26 @@
namespace Drupal\aws_cloud\Form\Vpc;

use Drupal\aws_cloud\Form\Ec2\AwsCloudContentForm;
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\CloudServiceInterface;
use Drupal\cloud\Service\EntityLinkRendererInterface;
use Drupal\cloud\Service\Util\EntityLinkWithNameHtmlGenerator;
use Drupal\cloud\Traits\CloudContentEntityTrait;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\Messenger;
use Drupal\Core\Plugin\CachedDiscoveryClearerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Form controller for the Subnet entity edit forms.
@@ -16,6 +33,112 @@ class SubnetEditForm extends AwsCloudContentForm {

  use CloudContentEntityTrait;

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

  /**
   * CarrierGatewayEditForm constructor.
   *
   * @param \Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface $aws_cloud_operations_service
   *   The AWS Cloud Operations service.
   * @param \Drupal\aws_cloud\Service\Ec2\Ec2ServiceInterface $ec2_service
   *   The AWS Cloud or OpenStack 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\cloud\Service\EntityLinkRendererInterface $entity_link_renderer
   *   The entity link render service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $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\Plugin\cloud\config\CloudConfigPluginManagerInterface $cloud_config_plugin_manager
   *   The cloud service provider plugin manager (CloudConfigPluginManager).
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current user.
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match.
   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
   *   The date formatter.
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The general renderer.
   * @param \Drupal\cloud\Service\CloudServiceInterface $cloud_service
   *   The Cloud service.
   */
  public function __construct(
    AwsCloudOperationsServiceInterface $aws_cloud_operations_service,
    Ec2ServiceInterface $ec2_service,
    EntityRepositoryInterface $entity_repository,
    EntityTypeBundleInfoInterface $entity_type_bundle_info,
    TimeInterface $time,
    Messenger $messenger,
    EntityLinkRendererInterface $entity_link_renderer,
    EntityTypeManagerInterface $entity_type_manager,
    CacheBackendInterface $cacheRender,
    CachedDiscoveryClearerInterface $plugin_cache_clearer,
    CloudConfigPluginManagerInterface $cloud_config_plugin_manager,
    AccountInterface $current_user,
    RouteMatchInterface $route_match,
    DateFormatterInterface $date_formatter,
    RendererInterface $renderer,
    CloudServiceInterface $cloud_service
  ) {
    parent::__construct(
      $ec2_service,
      $entity_repository,
      $entity_type_bundle_info,
      $time,
      $messenger,
      $entity_link_renderer,
      $entity_type_manager,
      $cacheRender,
      $plugin_cache_clearer,
      $cloud_config_plugin_manager,
      $current_user,
      $route_match,
      $date_formatter,
      $renderer,
      $cloud_service
    );

    $this->awsCloudOperationsService = $aws_cloud_operations_service;
  }

  /**
   * {@inheritdoc}
   */
  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.link_renderer'),
      $container->get('entity_type.manager'),
      $container->get('cache.render'),
      $container->get('plugin.cache_clearer'),
      $container->get('plugin.manager.cloud_config_plugin'),
      $container->get('current_user'),
      $container->get('current_route_match'),
      $container->get('date.formatter'),
      $container->get('renderer'),
      $container->get('cloud')
    );
  }

  /**
   * {@inheritdoc}
   */
@@ -111,48 +234,7 @@ class SubnetEditForm extends AwsCloudContentForm {
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state): void {
    // Call copyFormItemValues() to ensure the form array is intact.
    $this->copyFormItemValues($form);

    $this->trimTextfields($form, $form_state);

    $entity = $this->entity;

    $form_state->setRedirect('view.aws_cloud_subnet.list', [
      'cloud_context' => $entity->getCloudContext(),
    ]);

    $this->ec2Service->setCloudContext($entity->getCloudContext());

    // Delete old tags.
    $this->ec2Service->deleteTags([
      'Resources' => [$entity->getSubnetId()],
    ]);

    // Update tags.
    $tag_map = [];
    foreach ($entity->getTags() ?: [] as $tag) {
      $tag_map[$tag['item_key']] = $tag['item_value'];
    }
    $this->setTagsInAws($entity->getSubnetId(), $tag_map);

    $this->updateNameAndCreatedByTags($entity, $entity->getSubnetId());

    if ($this->isCloudConfigRemote()) {
      $this->processOperationStatus($entity, 'updated remotely');
      return;
    }

    $entity->save();

    // Update the VPC.
    $this->ec2Service->updateSubnets([
      'SubnetId' => $entity->getSubnetId(),
    ], FALSE);

    $this->processOperationStatus($entity, 'updated');
    $this->clearCacheValues($entity->getCacheTags());
    $this->dispatchSaveEvent($entity);
    $this->awsCloudOperationsService->editSubnet($this->entity, $form, $form_state);
  }

}
+61 −0
Original line number Diff line number Diff line
@@ -255,6 +255,13 @@ class AwsCloudOperationsService implements AwsCloudOperationsServiceInterface {
    $this->ec2Service->setCloudContext($entity->getCloudContext());
    $tags = [];
    foreach ($tag_map ?: [] as $key => $value) {
      // Do not try to set tags that start with `aws:`.  Those
      // are reserved tags that are non-editable.
      // See the following for more information:
      // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html
      if (strpos($key, 'aws:') === 0) {
        continue;
      }
      $tags[] = [
        'Key' => $key,
        'Value' => $value,
@@ -1325,6 +1332,60 @@ class AwsCloudOperationsService implements AwsCloudOperationsServiceInterface {
    }
  }

  /**
   * {@inheritdoc}
   */
  public function editSubnet(SubnetInterface $entity, array &$form, FormStateInterface $form_state): bool {
    try {
      // Call copyFormItemValues() to ensure the form array is intact.
      $this->copyFormItemValues($entity, $form);

      $this->trimTextfields($entity, $form, $form_state);

      $form_state->setRedirect('view.aws_cloud_subnet.list', [
        'cloud_context' => $entity->getCloudContext(),
      ]);

      $this->ec2Service->setCloudContext($entity->getCloudContext());

      // Delete old tags.
      $this->ec2Service->deleteTags([
        'Resources' => [$entity->getSubnetId()],
      ]);

      // Update tags.
      $tag_map = [];
      foreach ($entity->getTags() ?: [] as $tag) {
        $tag_map[$tag['item_key']] = $tag['item_value'];
      }
      $this->setTagsInAws($entity, $entity->getSubnetId(), $tag_map);

      $this->updateNameAndCreatedByTags($entity, $entity->getSubnetId());

      if ($this->isCloudConfigRemote($entity)) {
        $this->processOperationStatus($entity, 'updated remotely');
        return TRUE;
      }

      $entity->save();

      // Update the VPC.
      $this->ec2Service->updateSubnets([
        'SubnetId' => $entity->getSubnetId(),
      ], FALSE);

      $this->processOperationStatus($entity, 'updated');
      $this->clearCacheValues($entity->getCacheTags());
      $this->dispatchSaveEvent($entity);
      return TRUE;
    }
    catch (\Exception $e) {
      $this->handleException($e);
      $this->processOperationErrorStatus($entity, 'created');
      return FALSE;
    }
  }

  /**
   * {@inheritdoc}
   */
Loading