Skip to content
Snippets Groups Projects
Commit 759a204f authored by Ryo Yamashita's avatar Ryo Yamashita Committed by Yas Naoi
Browse files

Issue #3231862 by Ryo Yamashita, yas: Add a REST API to associate an Elastic...

Issue #3231862 by Ryo Yamashita, yas: Add a REST API to associate an Elastic IP for AWS Cloud Instance
parent 2b1f5ed2
No related branches found
No related tags found
No related merge requests found
......@@ -725,6 +725,7 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
'reboot',
'delete',
'create_image',
'associate_elastic_ip',
];
if (!in_array($command, $operationsCommandList, TRUE)) {
return new JsonResponse([
......@@ -757,6 +758,17 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
$command = 'createImageFrom';
break;
case 'associate_elastic_ip':
/* JSON format in request body.
* {
* allocationId: string;
* networkInterfaceId: string;
* }
*/
$parameter = json_decode($request->getContent(), TRUE);
$command = 'associateElasticIpFor';
break;
default:
break;
}
......
......@@ -4,8 +4,20 @@ namespace Drupal\aws_cloud\Form\Ec2;
use Drupal\aws_cloud\Entity\Ec2\ElasticIp;
use Drupal\aws_cloud\Entity\Ec2\NetworkInterface;
use Drupal\aws_cloud\Service\Ec2\Ec2OperationsServiceInterface;
use Drupal\aws_cloud\Service\Ec2\Ec2ServiceInterface;
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\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\StringTranslation\TranslatableMarkup;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Associate an Elastic IP form.
......@@ -14,6 +26,85 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
*/
class InstanceAssociateElasticIpForm extends AwsDeleteForm {
/**
* The AWS Cloud EC2 Operation Service.
*
* @var \Drupal\aws_cloud\Service\Ec2\Ec2OperationsServiceInterface
*/
private $ec2OperationsService;
/**
* InstanceDeleteForm constructor.
*
* @param \Drupal\aws_cloud\Service\Ec2\Ec2ServiceInterface $ec2_service
* The AWS Cloud EC2 Service.
* @param \Drupal\aws_cloud\Service\Ec2\Ec2OperationsServiceInterface $ec2_operations_service
* The AWS Cloud EC2 Operations API 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\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\Service\EntityLinkRendererInterface $entity_link_renderer
* The entity link render service.
* @param \Drupal\cloud\Plugin\cloud\config\CloudConfigPluginManagerInterface $cloud_config_plugin_manager
* The cloud service provider plugin manager (CloudConfigPluginManager).
*/
public function __construct(Ec2ServiceInterface $ec2_service,
Ec2OperationsServiceInterface $ec2_operations_service,
EntityRepositoryInterface $entity_repository,
EntityTypeBundleInfoInterface $entity_type_bundle_info,
TimeInterface $time,
Messenger $messenger,
EntityTypeManager $entity_type_manager,
CacheBackendInterface $cacheRender,
CachedDiscoveryClearerInterface $plugin_cache_clearer,
EntityLinkRendererInterface $entity_link_renderer,
CloudConfigPluginManagerInterface $cloud_config_plugin_manager) {
parent::__construct(
$ec2_service,
$entity_repository,
$entity_type_bundle_info,
$time,
$messenger,
$entity_type_manager,
$cacheRender,
$plugin_cache_clearer,
$entity_link_renderer,
$cloud_config_plugin_manager
);
$this->ec2OperationsService = $ec2_operations_service;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('aws_cloud.ec2'),
$container->get('aws_cloud.ec2_operations'),
$container->get('entity.repository'),
$container->get('entity_type.bundle.info'),
$container->get('datetime.time'),
$container->get('messenger'),
$container->get('entity_type.manager'),
$container->get('cache.render'),
$container->get('plugin.cache_clearer'),
$container->get('entity.link_renderer'),
$container->get('plugin.manager.cloud_config_plugin')
);
}
/**
* {@inheritdoc}
*/
......@@ -66,33 +157,14 @@ class InstanceAssociateElasticIpForm extends AwsDeleteForm {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
$this->ec2Service->setCloudContext($this->entity->getCloudContext());
$allocation_id = $form_state->getValue('allocation_id');
$network_interface_id = $form_state->getValue('network_interface_id');
$result = $this->ec2Service->associateAddress([
'AllocationId' => $allocation_id,
'NetworkInterfaceId' => $network_interface_id,
]);
$this->ec2OperationsService->associateElasticIpForInstance(
$this->entity,
[
'allocationId' => $form_state->getValue('allocation_id'),
'networkInterfaceId' => $form_state->getValue('network_interface_id'),
]
);
if ($result !== NULL) {
$this->ec2Service->updateElasticIps();
$this->ec2Service->updateInstances();
$this->ec2Service->updateNetworkInterfaces();
$elastic_ip = $this->getElasticIp($allocation_id, $this->entity->getCloudContext());
if ($elastic_ip !== FALSE) {
$this->messenger->addStatus($this->t('Elastic IP @ip_address associated with @private_ip for instance: @instance', [
'@ip_address' => $elastic_ip->getPublicIp(),
'@instance' => $this->entity->getName(),
'@private_ip' => $elastic_ip->getPrivateIpAddress(),
]));
$this->clearCacheValues($this->entity->getCacheTags());
}
}
else {
$this->messenger->addError($this->t('Unable to associate Elastic IP.'));
}
$form_state->setRedirect('entity.aws_cloud_instance.canonical', [
'cloud_context' => $this->entity->getCloudContext(),
'aws_cloud_instance' => $this->entity->id(),
......@@ -156,32 +228,4 @@ class InstanceAssociateElasticIpForm extends AwsDeleteForm {
return $elastic_ips;
}
/**
* Helper function that loads an aws_cloud_elastic_ip entity.
*
* @param string $allocation_id
* The allocation ID to look up.
* @param string $cloud_context
* The cloud context.
*
* @return \Drupal\aws_cloud\Entity\Ec2\ElasticIp
* The loaded aws_cloud_elastic_ip entity.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
private function getElasticIp($allocation_id, $cloud_context): ElasticIp {
$elastic_ip = FALSE;
$results = $this->entityTypeManager
->getStorage('aws_cloud_elastic_ip')
->loadByProperties([
'allocation_id' => $allocation_id,
'cloud_context' => $cloud_context,
]);
if (count($results) === 1) {
$elastic_ip = array_shift($results);
}
return $elastic_ip;
}
}
......@@ -2,6 +2,7 @@
namespace Drupal\aws_cloud\Service\Ec2;
use Drupal\aws_cloud\Entity\Ec2\ElasticIp;
use Drupal\Core\Entity\EntityDeleteFormTrait;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
......@@ -235,6 +236,34 @@ class Ec2OperationsService extends CloudServiceBase implements Ec2OperationsServ
return $entity;
}
/**
* Helper function that loads an aws_cloud_elastic_ip entity.
*
* @param string $allocation_id
* The allocation ID to look up.
* @param string $cloud_context
* The cloud context.
*
* @return \Drupal\aws_cloud\Entity\Ec2\ElasticIp
* The loaded aws_cloud_elastic_ip entity.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
private function getElasticIp($allocation_id, $cloud_context): ElasticIp {
$elastic_ip = FALSE;
$results = $this->entityTypeManager
->getStorage('aws_cloud_elastic_ip')
->loadByProperties([
'allocation_id' => $allocation_id,
'cloud_context' => $cloud_context,
]);
if (count($results) === 1) {
$elastic_ip = array_shift($results);
}
return $elastic_ip;
}
/**
* {@inheritdoc}
*/
......@@ -276,4 +305,42 @@ class Ec2OperationsService extends CloudServiceBase implements Ec2OperationsServ
}
}
/**
* {@inheritdoc}
*/
public function associateElasticIpForInstance(EntityInterface $entity, array $param): bool {
$this->ec2Service->setCloudContext($entity->getCloudContext());
$allocation_id = $param['allocationId'];
$network_interface_id = $param['networkInterfaceId'];
$result = $this->ec2Service->associateAddress([
'AllocationId' => $allocation_id,
'NetworkInterfaceId' => $network_interface_id,
]);
if ($result !== NULL) {
$this->ec2Service->updateElasticIps();
$this->ec2Service->updateInstances();
$this->ec2Service->updateNetworkInterfaces();
$elastic_ip = $this->getElasticIp($allocation_id, $entity->getCloudContext());
if ($elastic_ip !== FALSE) {
$this->messenger->addStatus($this->t('Elastic IP @ip_address associated with @private_ip for instance: @instance', [
'@ip_address' => $elastic_ip->getPublicIp(),
'@instance' => $entity->getName(),
'@private_ip' => $elastic_ip->getPrivateIpAddress(),
]));
$this->clearCacheValues($entity->getCacheTags());
return TRUE;
}
else {
return FALSE;
}
}
else {
$this->messenger->addError($this->t('Unable to associate Elastic IP.'));
return FALSE;
}
}
}
......@@ -66,4 +66,17 @@ interface Ec2OperationsServiceInterface {
*/
public function createImageFromInstance(EntityInterface $entity, array $param): bool;
/**
* Associate an Elastic IP for AWS Cloud instance.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The AWS Cloud instance entity.
* @param array $param
* Parameter.
*
* @return bool
* TRUE when the process succeeds.
*/
public function associateElasticIpForInstance(EntityInterface $entity, array $param): bool;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment