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

Issue #3300392 by Ryo Yamashita, yas: Add the function to create AWS Cloud Key Pair in the SPA

parent 68702c16
Loading
Loading
Loading
Loading
+20 −0
Changes for modules/cloud_dashboard/cloud_dashboard/src/constant/form_template/aws_cloud/key_pair.ts: 20 added lines, 0 removed lines.
Original line number Diff line number Diff line
import EntityFormTemplate from 'model/EntityFormTemplate';

const AWS_CLOUD_KEY_PAIR_TEMPLATE: EntityFormTemplate[] = [
  {
    cloudServiceProvider: 'aws_cloud',
    entityName: 'key_pair',
    actionType: 'create',
    entityRecords: [
      {
        type: 'panel',
        panelName: 'Key pair',
        keyValueRecords: [
          { type: 'default', labelName: 'Key pair name', name: 'key_pair_name', defaultValue: '' }
        ]
      }
    ]
  },
]

export default AWS_CLOUD_KEY_PAIR_TEMPLATE;
+2 −0
Changes for modules/cloud_dashboard/cloud_dashboard/src/constant/form_template/entity_form_template.ts: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
import AWS_CLOUD_IMAGE_TEMPLATE from 'constant/form_template/aws_cloud/image';
import AWS_CLOUD_INSTANCE_TEMPLATE from 'constant/form_template/aws_cloud/instance';
import AWS_CLOUD_KEY_PAIR_TEMPLATE from 'constant/form_template/aws_cloud/key_pair';
import AWS_CLOUD_SECURITY_GROUP_TEMPLATE from 'constant/form_template/aws_cloud/security_group';
import K8S_DEPLOYMENT_TEMPLATE from 'constant/form_template/k8s/deployment';
import K8S_NAMESPACE_TEMPLATE from 'constant/form_template/k8s/namespace';
@@ -19,6 +20,7 @@ import VMWARE_VM_TEMPLATE from 'constant/form_template/vmware/vm';
const ENTITY_FORM_LIST = [
  ...AWS_CLOUD_IMAGE_TEMPLATE,
  ...AWS_CLOUD_INSTANCE_TEMPLATE,
  ...AWS_CLOUD_KEY_PAIR_TEMPLATE,
  ...AWS_CLOUD_SECURITY_GROUP_TEMPLATE,
  ...K8S_DEPLOYMENT_TEMPLATE,
  ...K8S_NAMESPACE_TEMPLATE,
+10 −0
Changes for modules/cloud_service_providers/aws_cloud/aws_cloud.routing.yml: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -1095,3 +1095,13 @@ entity.aws_cloud_security_group.revoke:
  methods: [POST]
  requirements:
    _permission: 'delete any aws cloud security group'

entity.aws_cloud_key_pair.create:
  path: '/cloud_dashboard/aws_cloud/{cloud_context}/aws_cloud_key_pair/{entity_id}/create'
  defaults:
    _controller: '\Drupal\aws_cloud\Controller\Ec2\ApiController::operateEntity'
    entity_type_id: aws_cloud_key_pair
    command: create
  methods: [POST]
  requirements:
    _permission: 'add aws cloud key pair'
+6 −0
Changes for modules/cloud_service_providers/aws_cloud/src/Controller/Ec2/ApiController.php: 6 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -805,6 +805,12 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
          $method_name = 'createImage';
          break;

        case 'create_aws_cloud_key_pair':
          /** @var \Drupal\aws_cloud\Entity\Ec2\KeyPairInterface $entity */
          $entity->set('key_pair_name', $request->get('key_pair_name', ''));
          $method_name = 'createKeyPair';
          break;

        case 'create_image_aws_cloud_instance':
          $form_state->set('image_name', $request->get('image_name', ''));
          $form_state->set('no_reboot', $request->get('no_reboot', 'false') === 'true');
+125 −56
Changes for modules/cloud_service_providers/aws_cloud/src/Form/Ec2/KeyPairCreateForm.php: 125 added lines, 56 removed lines.
Original line number Diff line number Diff line
@@ -2,7 +2,24 @@

namespace Drupal\aws_cloud\Form\Ec2;

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

/**
 * Form controller for the KeyPair entity create form.
@@ -11,6 +28,112 @@ use Drupal\Core\Form\FormStateInterface;
 */
class KeyPairCreateForm extends AwsCloudContentForm {

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

  /**
   * KeyPairCreateForm 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')
    );
  }

  /**
   * Overrides Drupal\Core\Entity\EntityFormController::buildForm().
   *
@@ -25,10 +148,10 @@ class KeyPairCreateForm extends AwsCloudContentForm {
   *   Array of form object.
   */
  public function buildForm(array $form, FormStateInterface $form_state, $cloud_context = ''): array {
    /** @var \Drupal\aws_cloud\Entity\Ec2\KeyPair $entity */
    $form = parent::buildForm($form, $form_state);

    $this->ec2Service->setCloudContext($cloud_context);
    /** @var \Drupal\aws_cloud\Entity\Ec2\KeyPairInterface $entity */
    $entity = $this->entity;

    $weight = -50;
@@ -67,61 +190,7 @@ class KeyPairCreateForm extends AwsCloudContentForm {
   * @throws \Drupal\aws_cloud\Service\Ec2\Ec2ServiceException
   */
  public function save(array $form, FormStateInterface $form_state): void {

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

    /** @var \Drupal\aws_cloud\Entity\Ec2\KeyPair $entity */
    $entity = $this->entity;
    $uid_key_name = $this->cloudService->getTagCreatedByUid(
      'aws_cloud',
      $entity->getCloudContext());

    $result = $this->ec2Service->createKeyPair([
      'KeyName' => $entity->getKeyPairName(),
      'TagSpecifications' => [
        [
          'ResourceType' => 'key-pair',
          'Tags' => [
            [
              'Key' => $entity->getEntityTypeId() . '_' . $uid_key_name,
              'Value' => !empty($entity->getOwner()) ? $entity->getOwner()->id() : 0,
            ],
          ],
        ],
      ],
    ]);

    if (empty($result)) {
      // Use the custom message since key pair uses 'key_pair_name' for its own
      // label.  So do not change the following code.
      $this->messenger->addStatus($this->t('The @type @label could not be created.', [
        '@type' => $entity->getEntityType()->getSingularLabel(),
        '@label' => $entity->getKeyPairName(),
      ]));
      $this->logOperationErrorMessage($entity, 'created');
      $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]);
      return;
    }

    if (!empty($result['SendToWorker'])) {
      $this->processOperationStatus($entity, 'created remotely');
      $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]);
      return;
    }

    $entity->setKeyFingerprint($result['KeyFingerprint']);
    $entity->setKeyPairId($result['KeyPairId']);
    $entity->setKeyMaterial($result['KeyMaterial']);
    $entity->save();
    $this->processOperationStatus($entity, 'created');
    $this->logOperationMessage($entity, 'created');
    $this->clearCacheValues($entity->getCacheTags());

    $form_state->setRedirect("entity.{$entity->getEntityTypeId()}.canonical", [
      'cloud_context' => $entity->getCloudContext(),
      $entity->getEntityTypeId() => $entity->id(),
    ]);
    $this->dispatchSaveEvent($entity);
    $this->awsCloudOperationsService->createKeyPair($this->entity, $form, $form_state);
  }

}
Loading