Commit 6992a171 authored by xiaohua guan's avatar xiaohua guan Committed by Yas Naoi
Browse files

Issue #3323705 by Xiaohua Guan, yas: Add the OpenStack Heat create form (1) (Multiple forms)

parent 7fb95e19
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -619,17 +619,18 @@ entity.openstack_quota.edit:
# OpenStack Stack.
##############################

# entity.openstack_stack.add_form:
#   route_name: entity.openstack_stack.add_form
#   title: 'Add OpenStack stack'
#   appears_on:
#     - view.openstack_stack.list
#
entity.openstack_stack.add_form:
  route_name: entity.openstack_stack.add_form
  title: 'Add OpenStack stack'
  appears_on:
    - view.openstack_stack.list

entity.openstack_stack.collection:
  route_name: view.openstack_stack.list
  title: 'List OpenStack stacks'
  appears_on:
#     - entity.openstack_stack.add_form
    - entity.openstack_stack.add_form
    - entity.openstack_stack.add_extra_form
#     - entity.openstack_stack.edit_form
    - entity.openstack_stack.delete_form
    - entity.openstack_stack.canonical
+24 −0
Original line number Diff line number Diff line
@@ -1310,6 +1310,30 @@ entity.openstack_quota.list_update.all:
    entity_type: 'openstack_quota'

# OpenStack stacks routes.
entity.openstack_stack.add_form:
  path: '/clouds/openstack/{cloud_context}/stack/add'
  defaults:
    _entity_form: 'openstack_stack.add'
    _title: 'Add OpenStack stack - template'
  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: 'add openstack stack'

entity.openstack_stack.add_extra_form:
  path: '/clouds/openstack/{cloud_context}/stack/add_extra'
  defaults:
    _entity_form: 'openstack_stack.add-extra'
    _title: 'Add OpenStack stack'
  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: 'add openstack stack'

entity.openstack_stack.list_update:
  path: '/clouds/openstack/{cloud_context}/stack/update'
  defaults:
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ use Drupal\Core\Field\BaseFieldDefinition;
 *     "form" = {
 *       "default" = "Drupal\openstack\Form\OpenStackStackEditForm",
 *       "add" = "Drupal\openstack\Form\OpenStackStackCreateForm",
 *       "add-extra" = "Drupal\openstack\Form\OpenStackStackCreateExtraForm",
 *       "edit" = "Drupal\openstack\Form\OpenStackStackEditForm",
 *       "delete" = "Drupal\openstack\Form\OpenStackStackDeleteForm",
 *       "delete-multiple-confirm" = "Drupal\openstack\Form\OpenStackStackDeleteMultipleForm",
@@ -46,6 +47,7 @@ use Drupal\Core\Field\BaseFieldDefinition;
 *   links = {
 *     "canonical" = "/clouds/openstack/{cloud_context}/stack/{openstack_stack}",
 *     "add-form" = "/clouds/openstack/{cloud_context}/stack/{openstack_stack}/add",
 *     "add-extra-form" = "/clouds/openstack/{cloud_context}/stack/{openstack_stack}/add_extra",
 *     "edit-form" = "/clouds/openstack/{cloud_context}/stack/{openstack_stack}/edit",
 *     "delete-form" = "/clouds/openstack/{cloud_context}/stack/{openstack_stack}/delete",
 *     "collection" = "/clouds/openstack/{cloud_context}/stack",
+259 −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\Core\TempStore\PrivateTempStoreFactory;
use Drupal\cloud\Service\CloudServiceInterface;
use Drupal\cloud\Traits\CloudContentEntityTrait;
use Drupal\openstack\Service\OpenStackOperationsServiceInterface;
use Drupal\openstack\Traits\OpenStackFormTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Form controller for the Stack entity create form.
 *
 * @ingroup openstack
 */
class OpenStackStackCreateExtraForm extends AwsCloudContentForm {

  use AwsCloudFormTrait;
  use CloudContentEntityTrait;
  use OpenStackFormTrait;

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

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

  /**
   * The tempstore.
   *
   * @var \Drupal\Core\TempStore\SharedTempStore
   */
  protected $tempStore;

  /**
   * OpenStackStackCreateForm 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.
   * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
   *   The tempstore factory.
   */
  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,
    PrivateTempStoreFactory $temp_store_factory) {

    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;
    $this->tempStore = $temp_store_factory->get('openstack_stack_create');
  }

  /**
   * Dependency Injection.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   Instance of ContainerInterface.
   *
   * @return OpenStackStackCreateForm
   *   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'),
      $container->get('tempstore.private')
    );
  }

  /**
   * 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;

    $weight = -50;

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

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

    $form['stack']['timeout_mins'] = [
      '#type'          => 'number',
      '#title'         => $this->t('Creation Timeout (minutes)'),
      '#description'   => $this->t('The timeout for stack creation in minutes.'),
      '#required'      => TRUE,
      '#default_value' => 60,
    ];

    $form['stack']['rollback'] = [
      '#type'          => 'checkbox',
      '#title'         => $this->t('Rollback On Failure'),
      '#description'   => $this->t('Enable rollback on create/update failure.'),
      '#required'      => FALSE,
      '#default_value' => FALSE,
    ];

    $form['stack']['template_parameters'] = [
      '#type'          => 'details',
      '#title'         => $this->t('Template Parameters'),
      '#open'          => TRUE,
    ];

    $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 {
  }

}
+321 −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\Core\TempStore\PrivateTempStoreFactory;
use Drupal\cloud\Service\CloudServiceInterface;
use Drupal\cloud\Traits\CloudContentEntityTrait;
use Drupal\openstack\Service\OpenStackOperationsServiceInterface;
use Drupal\openstack\Traits\OpenStackFormTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Form controller for the Stack entity create form.
 *
 * @ingroup openstack
 */
class OpenStackStackCreateForm extends AwsCloudContentForm {

  use AwsCloudFormTrait;
  use CloudContentEntityTrait;
  use OpenStackFormTrait;

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

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

  /**
   * The tempstore.
   *
   * @var \Drupal\Core\TempStore\SharedTempStore
   */
  protected $tempStore;

  /**
   * OpenStackStackCreateForm 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.
   * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
   *   The tempstore factory.
   */
  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,
    PrivateTempStoreFactory $temp_store_factory) {

    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;
    $this->tempStore = $temp_store_factory->get('openstack_stack_create');
  }

  /**
   * Dependency Injection.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   Instance of ContainerInterface.
   *
   * @return OpenStackStackCreateForm
   *   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'),
      $container->get('tempstore.private')
    );
  }

  /**
   * 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;

    $weight = -50;

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

    $form['stack']['template_source'] = [
      '#type'          => 'select',
      '#title'         => $this->t('Template Source'),
      '#required'      => TRUE,
      '#options'       => [
        'file'         => $this->t('File'),
        'raw'          => $this->t('Direct Input'),
        'url'          => $this->t('URL'),
      ],
    ];

    $form['stack']['template_file'] = [
      '#type'          => 'file',
      '#title'         => $this->t('Template File'),
      '#required'      => FALSE,
      '#states'        => [
        'visible' => [
          [
            ':input[name=template_source]' => ['value' => 'file'],
          ],
        ],
      ],
    ];

    $form['stack']['template_data'] = [
      '#type'          => 'textarea',
      '#title'         => $this->t('Template Data'),
      '#required'      => FALSE,
      '#states'        => [
        'visible' => [
          [
            ':input[name=template_source]' => ['value' => 'raw'],
          ],
        ],
      ],
    ];

    $form['stack']['template_url'] = [
      '#type'          => 'textfield',
      '#title'         => $this->t('Template URL'),
      '#required'      => FALSE,
      '#states'        => [
        'visible' => [
          [
            ':input[name=template_source]' => ['value' => 'url'],
          ],
        ],
      ],
    ];

    $form['stack']['environment_source'] = [
      '#type'          => 'select',
      '#title'         => $this->t('Environment Source'),
      '#required'      => FALSE,
      '#options'       => [
        'file'         => $this->t('File'),
        'raw'          => $this->t('Direct Input'),
      ],
    ];

    $form['stack']['environment_file'] = [
      '#type'          => 'file',
      '#title'         => $this->t('Environment File'),
      '#required'      => FALSE,
      '#states'        => [
        'visible' => [
          [
            ':input[name=environment_source]' => ['value' => 'file'],
          ],
        ],
      ],
    ];

    $form['stack']['environment_data'] = [
      '#type'          => 'textarea',
      '#title'         => $this->t('Environment Data'),
      '#required'      => FALSE,
      '#states'        => [
        'visible' => [
          [
            ':input[name=environment_source]' => ['value' => 'raw'],
          ],
        ],
      ],
    ];

    $this->addOthersFieldset($form, $weight++, $cloud_context);
    unset($form['others']['uid']);

    $form['actions']['submit']['#value'] = $this->t('Next');

    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 {
    $entity = $this->entity;
    $form_state->setRedirect("entity.{$entity->getEntityTypeId()}.add_extra_form", [
      'cloud_context' => $entity->getCloudContext(),
    ]);
  }

}