Commit 2de41646 authored by xiaohua guan's avatar xiaohua guan Committed by Yas Naoi
Browse files

Issue #3309788 by Xiaohua Guan, yas: Add the OpenStack Network Edit Form

parent dfcdba2d
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -34,11 +34,27 @@ class OpenStackNetworkAccessControlHandler extends EntityAccessControlHandler {
          $entity,
          $account,
          "view own {$cloud_name} network",
          "view any {$cloud_name} network",
          TRUE
          "view any {$cloud_name} network"
        );

      case 'update':
      case 'edit':
        return $this->allowedIfCanAccessCloudConfigWithOwner(
          $entity,
          $account,
          "edit own {$cloud_name} network",
          "edit any {$cloud_name} network"
        );

      case 'delete':
        return $this->allowedIfCanAccessCloudConfigWithOwner(
          $entity,
          $account,
          "delete own {$cloud_name} network",
          "delete any {$cloud_name} network"
        );
    }

    // Unknown operation, no opinion.
    return AccessResult::neutral();
  }
+2 −2
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ use Drupal\openstack\Service\OpenStackOperationsServiceInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Form controller for the NetworkInterface entity create form.
 * Form controller for the Network entity create form.
 *
 * @ingroup openstack
 */
@@ -138,7 +138,7 @@ class OpenStackNetworkCreateForm extends AwsCloudContentForm {
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   Instance of ContainerInterface.
   *
   * @return OpenStackNetworkInterfaceCreateForm
   * @return OpenStackNetworkCreateForm
   *   return created object.
   */
  public static function create(ContainerInterface $container) {
+245 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\openstack\Form;

use Drupal\openstack\Service\OpenStackServiceFactoryInterface;
use Drupal\aws_cloud\Form\Ec2\AwsCloudContentForm;
use Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface;
use Drupal\aws_cloud\Service\Ec2\Ec2ServiceInterface;
use Drupal\aws_cloud\Traits\AwsCloudFormTrait;
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\Datetime\DateFormatterInterface;
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\Render\Renderer;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\cloud\Service\CloudServiceInterface;
use Drupal\cloud\Traits\CloudContentEntityTrait;
use Drupal\openstack\Service\OpenStackOperationsServiceInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Form controller for the Network entity edit form.
 *
 * @ingroup openstack
 */
class OpenStackNetworkEditForm extends AwsCloudContentForm {

  use AwsCloudFormTrait;
  use CloudContentEntityTrait;

  /**
   * The OpenStack Service Factory.
   *
   * @var \Drupal\openstack\Service\OpenStackServiceFactoryInterface
   */
  protected $openStackServiceFactory;

  /**
   * The OpenStack operations Service.
   *
   * @var \Drupal\openstack\Service\OpenStackOperationsServiceInterface
   */
  protected $openStackOperationsService;

  /**
   * OpenStackNetworkCreateForm 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 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\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\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\Renderer $renderer
   *   The general renderer.
   * @param \Drupal\cloud\Service\CloudServiceInterface $cloud_service
   *   The Cloud service.
   * @param \Drupal\openstack\Service\OpenStackOperationsServiceInterface $openstack_operations_service
   *   The OpenStack Operations service.
   */
  public function __construct(
    AwsCloudOperationsServiceInterface $aws_cloud_operations_service,
    OpenStackServiceFactoryInterface $openstack_service_factory,
    Ec2ServiceInterface $ec2_service,
    EntityRepositoryInterface $entity_repository,
    EntityTypeBundleInfoInterface $entity_type_bundle_info,
    TimeInterface $time,
    Messenger $messenger,
    EntityLinkRendererInterface $entity_link_renderer,
    EntityTypeManager $entity_type_manager,
    CacheBackendInterface $cacheRender,
    CachedDiscoveryClearerInterface $plugin_cache_clearer,
    CloudConfigPluginManagerInterface $cloud_config_plugin_manager,
    AccountInterface $current_user,
    RouteMatchInterface $route_match,
    DateFormatterInterface $date_formatter,
    Renderer $renderer,
    CloudServiceInterface $cloud_service,
    OpenStackOperationsServiceInterface $openstack_operations_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->openStackServiceFactory = $openstack_service_factory;
    $this->openStackOperationsService = $openstack_operations_service;
  }

  /**
   * Dependency Injection.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   Instance of ContainerInterface.
   *
   * @return OpenStackNetworkEditForm
   *   return created object.
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('aws_cloud.operations'),
      $container->get('openstack.factory'),
      $container->get('openstack.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'),
      $container->get('openstack.operations')
    );
  }

  /**
   * Overrides Drupal\Core\Entity\EntityFormController::buildForm().
   *
   * @param array $form
   *   Array of form object.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   * @param string $cloud_context
   *   A cloud_context string value from URL "path".
   *
   * @return array
   *   Array of form object.
   */
  public function buildForm(array $form, FormStateInterface $form_state, $cloud_context = ''): array {
    // Switch OpenStack EC2 or REST service based on $cloud_context.
    $this->ec2Service = $this->openStackServiceFactory->get($cloud_context);
    $form = parent::buildForm($form, $form_state, $cloud_context);
    $entity = $this->entity;

    $entity = $this->entity;
    if (!$this->updateEntityBuildForm($entity)) {
      return $this->redirectUrl;
    }

    $weight = -50;

    $form['network'] = [
      '#type' => 'details',
      '#title' => $this->t('@title', ['@title' => $entity->getEntityType()->getSingularLabel()]),
      '#open' => TRUE,
      '#weight' => $weight++,
    ];

    $form['network']['name'] = [
      '#type'          => 'textfield',
      '#title'         => $this->t('Name'),
      '#maxlength'     => 255,
      '#size'          => 60,
      '#default_value' => $entity->label(),
      '#weight'        => -5,
      '#required'      => TRUE,
    ];

    $form['network']['admin_state_up'] = [
      '#type'          => 'checkbox',
      '#title'         => $this->t('Admin state up'),
      '#description'   => $this->t('The administrative state of the network, which is up (true) or down (false).'),
      '#default_value' => $entity->getAdminStateUp(),
      '#weight'        => -5,
      '#required'      => FALSE,
    ];

    $form['network']['shared'] = [
      '#type'          => 'checkbox',
      '#title'         => $this->t('Shared'),
      '#description'   => $this->t('Indicates whether this resource is shared across all projects.'),
      '#default_value' => $entity->getShared(),
      '#weight'        => -5,
      '#required'      => FALSE,
    ];

    $this->addOthersFieldset($form, $weight++, $cloud_context);

    return $form;
  }

  /**
   * Submit handler.
   *
   * @param array $form
   *   Array of form object.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   */
  public function save(array $form, FormStateInterface $form_state): void {
    $this->openStackOperationsService->editOpenStackNetwork($this->entity, $form, $form_state);
  }

}
+53 −0
Original line number Diff line number Diff line
@@ -850,6 +850,59 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface
    }
  }

  /**
   * {@inheritdoc}
   */
  public function editOpenStackNetwork(OpenStackNetworkExInterface $entity, array &$form, FormStateInterface $form_state): bool {
    $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext());
    $this->awsCloudOperationsService->setEc2Service($this->ec2Service);

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

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

    $zone_names = [];
    foreach ($entity->getAvailabilityZones() ?: [] as $availability_zone) {
      $zone_names[] = array_keys($availability_zone)[0];
    }

    $this->ec2Service->setCloudContext($entity->getCloudContext());
    $result = $this->ec2Service->updateNetwork([
      'NetworkId' => $entity->getNetworkId(),
      'Name' => $entity->getName(),
      'AdminStateUp' => $entity->getAdminStateUp(),
      'Shared' => $entity->getShared(),
    ]);

    if ($result === NULL) {
      $this->processOperationErrorStatus($entity, 'updated');
      return FALSE;
    }

    if (!empty($result['SendToWorker'])) {
      $this->processOperationStatus($entity, 'updated remotely');
      return TRUE;
    }

    $entity->save();

    if ($this->ec2Service instanceof OpenStackRestService) {
      $this->awsCloudOperationsService->updateNameAndCreatedByTags($entity, $entity->getNetworkId());
    }

    // Update the Network entity.
    $this->ec2Service->updateNetworks([
      'NetworkId' => $entity->getNetworkId(),
    ]);

    $this->processOperationStatus($entity, 'updated');

    $this->clearCacheValues($entity->getCacheTags());
    $this->dispatchSaveEvent($entity);

    return TRUE;
  }

  /**
   * Save a Network Interface.
   *
+15 −0
Original line number Diff line number Diff line
@@ -243,6 +243,21 @@ interface OpenStackOperationsServiceInterface {
   */
  public function editOpenStackNetworkInterface(NetworkInterfaceInterface $entity, array &$form, FormStateInterface $form_state): bool;

  /**
   * Edit an OpenStack Network.
   *
   * @param \Drupal\openstack\Entity\OpenStackNetworkExInterface $entity
   *   The OpenStack network entity.
   * @param array $form
   *   Array of form object.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   *
   * @return bool
   *   TRUE when the process succeeds.
   */
  public function editOpenStackNetwork(OpenStackNetworkExInterface $entity, array &$form, FormStateInterface $form_state): bool;

  /**
   * Create an OpenStack floating IP.
   *
Loading