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

Issue #3263209 by baldwinlouie, yas: Fix VPC selection during Security Group Copy

parent edfe9c94
Loading
Loading
Loading
Loading
+57 −29
Original line number Diff line number Diff line
@@ -2,9 +2,9 @@

namespace Drupal\aws_cloud\Form\Ec2;

use Drupal\Core\Url;
use Drupal\Core\Form\FormStateInterface;
use Drupal\aws_cloud\Traits\AwsCloudFormTrait;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

/**
 * Form controller for the CloudScripting entity copy forms.
@@ -105,10 +105,48 @@ class SecurityGroupCopyForm extends SecurityGroupEditForm {
    $this->entity = $entity;
    $this->trimTextfields($form, $form_state);

    // Load to the VPC to determine whether to permissions_to_revoke Cidr and/or Ip6Cidr.
    $vpc = $this->getVpc($form_state->getValue('vpc_id'), $entity->getCloudContext());
    if (empty($vpc)) {
      // Cannot load VPC, set an error message and return.
      $form_state->setError($form, $this->t('Unable to load VPC @vpc.', [
        '@vpc' => $form_state->getValue('vpc_id'),
      ]));
      return;
    }

    $result = $this->ec2Service->createSecurityGroup([
      'GroupName' => $form_state->getValue('group_name')[0]['value'],
      'VpcId'       => $entity->getVpcId(),
      'Description' => $entity->getDescription(),
      'VpcId'       => $form_state->getValue('vpc_id'),
      'Description' => $form_state->getValue('description'),
    ]);

    $permissions_to_revoke = [];
    if (!empty($vpc->getCidrBlocks())) {
      $permissions_to_revoke[] = [
        'FromPort' => '0',
        'ToPort' => '65535',
        'IpProtocol' => '-1',
        'IpRanges' => [
          ['CidrIp' => '0.0.0.0/0'],
        ],
      ];
    }
    if (!empty($vpc->getIpv6CidrBlocks())) {
      $permissions_to_revoke[] = [
        'FromPort' => '0',
        'ToPort' => '65535',
        'IpProtocol' => '-1',
        'Ipv6Ranges' => [
          ['CidrIpv6' => '::/0'],
        ],
      ];
    }

    // Revoke the default outbound permissions.
    $this->ec2Service->revokeSecurityGroupEgress([
      'GroupId' => $result['GroupId'],
      'IpPermissions' => $permissions_to_revoke,
    ]);

    if (!empty($result['SendToWorker'])) {
@@ -116,8 +154,10 @@ class SecurityGroupCopyForm extends SecurityGroupEditForm {
    }

    if (isset($result['GroupId'])
        && ($entity->setGroupId($result['GroupId']))
        && ($entity->set('name', $form_state->getValue('group_name')[0]['value']))) {
      && $entity->setGroupId($result['GroupId'])
      && $entity->set('name', $form_state->getValue('group_name')[0]['value'])
      && $entity->set('vpc_id', $form_state->getValue('vpc_id'))
      && $entity->set('description', $form_state->getValue('description'))) {
      // Keep intentionally blank.
    }
    else {
@@ -156,7 +196,8 @@ class SecurityGroupCopyForm extends SecurityGroupEditForm {
      return;
    }

    if ($entity->save()) {
    // Set the created time right before save.
    if ($entity->set('created', time()) && $entity->save()) {

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

@@ -167,7 +208,7 @@ class SecurityGroupCopyForm extends SecurityGroupEditForm {
      $this->changeSelfGroupId($form);

      // Update Ingress and Egress permissions.
      $this->updateIngressEgressPermissions($entity, $existing_group, FALSE);
      $this->updateIngressEgressPermissions($entity, $existing_group, FALSE, FALSE);

      // Have the system refresh the security group.
      $this->ec2Service->updateSecurityGroups([
@@ -238,28 +279,15 @@ class SecurityGroupCopyForm extends SecurityGroupEditForm {
  }

  /**
   * Change Group ID in in/outbound permission.
   *
   * @param array $form
   *   The complete form array.
   * Change Group ID for inbound and outbound permissions.
   */
  private function changeSelfGroupId(array $form): void {
    foreach ($form['rules'] ?: [] as $key => $permission) {
      if (is_array($permission) && isset($permission['widget']) && !empty($permission['widget'])) {
        foreach ($permission['widget'] ?: [] as $idx => $widget) {
          if (is_array($widget)) {
            if (isset($widget['group_id']) && isset($widget['group_id']['#attributes']['readonly'])) {
              if ($key === 1) {
                $field = 'outbound_permission';
              }
              else {
                $field = 'ip_permission';
              }
              $ip_permission = $this->entity->$field->get($idx);
              $ip_permission->group_id = $this->entity->getGroupId();
              $this->entity->$field->set($idx, $ip_permission);
            }
          }
  private function changeSelfGroupId(): void {
    $funcs = ['getOutboundPermission', 'getIpPermission'];
    foreach ($funcs ?: [] as $func) {
      $permissions = $this->entity->$func();
      foreach ($permissions as $permission) {
        if (!empty($permission->getGroupId()) && $this->entity->getGroupId() != $permission->getGroupId()) {
          $permission->setGroupId($this->entity->getGroupId());
        }
      }
    }
+30 −0
Original line number Diff line number Diff line
@@ -64,6 +64,36 @@ trait AwsCloudFormTrait {
    return $options;
  }

  /**
   * Load a VPC entity using the VPC Id.
   *
   * @param string $vpc_id
   *   VPC Id to load.
   * @param string $cloud_context
   *   The cloud context to load.
   *
   * @return false|\Drupal\aws_cloud\Entity\Vpc\Vpc
   *   FALSE or the VPC entity.
   */
  protected function getVpc(string $vpc_id, string $cloud_context) {
    $vpc = FALSE;
    try {
      $vpcs = $this->entityTypeManager
        ->getStorage('aws_cloud_vpc')
        ->loadByProperties([
          'vpc_id' => $vpc_id,
          'cloud_context' => $cloud_context,
        ]);
      if (!empty($vpcs) && count($vpcs) === 1) {
        $vpc = array_shift($vpcs);
      }
    }
    catch (\Exception $e) {
      $this->handleException($e);
    }
    return $vpc;
  }

  /**
   * Get availability zone options.
   *