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

Issue #3231856 by Ryo Yamashita, baldwinlouie, yas: Add a REST API to create...

Issue #3231856 by Ryo Yamashita, baldwinlouie, yas: Add a REST API to create AWS Cloud Image from AWS Cloud Instance
parent 879a4f19
No related branches found
No related tags found
No related merge requests found
......@@ -20,6 +20,7 @@ use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\views\Views;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
......@@ -716,13 +717,14 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
/**
* {@inheritdoc}
*/
public function operateInstance(string $cloud_context, string $aws_cloud_instance, string $command): JsonResponse {
public function operateInstance(Request $request, string $cloud_context, string $aws_cloud_instance, string $command): JsonResponse {
// Validation check.
$operationsCommandList = [
'start',
'stop',
'reboot',
'delete',
'create_image',
];
if (!in_array($command, $operationsCommandList, TRUE)) {
return new JsonResponse([
......@@ -742,9 +744,25 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
// Execute AWS API and save entity data.
$result = FALSE;
$parameter = NULL;
switch ($command) {
case 'create_image':
/* JSON format in request body.
* {
* imageName: string;
* noRebootFlg: boolean;
* }
*/
$parameter = json_decode($request->getContent(), TRUE);
$command = 'createImageFrom';
break;
default:
break;
}
$method_name = "${command}Instance";
if (method_exists($this->ec2OperationsService, $method_name)) {
$result = $this->ec2OperationsService->$method_name($entity);
$result = $this->ec2OperationsService->$method_name($entity, $parameter);
}
return !empty($result)
......
......@@ -5,6 +5,7 @@ namespace Drupal\aws_cloud\Controller\Ec2;
use Drupal\aws_cloud\Entity\Ec2\InstanceInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
......@@ -163,6 +164,8 @@ interface ApiControllerInterface {
/**
* Operate AWS Cloud instance.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* HTTP request.
* @param string $cloud_context
* Cloud context string.
* @param string $aws_cloud_instance
......@@ -173,6 +176,6 @@ interface ApiControllerInterface {
* @return \Symfony\Component\HttpFoundation\JsonResponse
* The JSON response.
*/
public function operateInstance(string $cloud_context, string $aws_cloud_instance, string $command): JsonResponse;
public function operateInstance(Request $request, string $cloud_context, string $aws_cloud_instance, string $command): JsonResponse;
}
......@@ -2,15 +2,105 @@
namespace Drupal\aws_cloud\Form\Ec2;
use Drupal\Core\Entity\EntityInterface;
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;
/**
* Create image from an instance.
*/
class InstanceCreateImageForm extends AwsDeleteForm {
/**
* The AWS Cloud EC2 Operation Service.
*
* @var \Drupal\aws_cloud\Service\Ec2\Ec2OperationsServiceInterface
*/
private $ec2OperationsService;
/**
* InstanceCreateImageForm 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}
*/
......@@ -81,67 +171,17 @@ class InstanceCreateImageForm extends AwsDeleteForm {
return;
}
$this->ec2Service->setCloudContext($entity->getCloudContext());
$result = $this->ec2Service->createImage([
'InstanceId' => $entity->getInstanceId(),
'Name' => $form_state->getValue('image_name'),
'NoReboot' => $form_state->getValue('no_reboot') === 0 ? FALSE : TRUE,
]);
$result = $this->ec2OperationsService->createImageFromInstance(
$entity,
[
'imageName' => $form_state->getValue('image_name'),
'noRebootFlg' => $form_state->getValue('no_reboot') === 0 ? FALSE : TRUE,
]
);
if (!empty($entity) && !empty($result['ImageId'])) {
// Call image update on this particular image.
$this->ec2Service->updateImages([
'ImageIds' => [
$result['ImageId'],
],
]);
$this->messenger->addStatus($this->t('The @type %label (%image_id) has been created.', [
'@type' => $entity->getEntityType()->getSingularLabel(),
'%label' => $entity->toLink($entity->label())->toString(),
'%image_id' => $result['ImageId'],
]));
$this->clearCacheValues($entity->getCacheTags());
$image = $this->loadNewImage($entity->getCloudContext(), $result['ImageId']);
if (!empty($image)) {
$this->dispatchSubmitEvent($image);
}
if (!empty($result)) {
$form_state->setRedirect('view.aws_cloud_image.list', ['cloud_context' => $entity->getCloudContext()]);
}
else {
$this->processOperationErrorStatus($entity, 'created');
}
}
/**
* Helper method to load image entity.
*
* @param string $cloud_context
* Cloud context.
* @param string $image_id
* Image id to load.
*
* @return null|\Drupal\Core\Entity\EntityInterface
* NULL if not found else Image entity.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
private function loadNewImage($cloud_context, $image_id): ?EntityInterface {
$entity = NULL;
$entities = $this->entityTypeManager
->getStorage('aws_cloud_image')
->loadByProperties([
'cloud_context' => $cloud_context,
'image_id' => $image_id,
]);
if (!empty($entities)) {
$entity = array_shift($entities);
}
return $entity;
}
}
......@@ -206,4 +206,74 @@ class Ec2OperationsService extends CloudServiceBase implements Ec2OperationsServ
}
}
/**
* Helper method to load image entity.
*
* @param string $cloud_context
* Cloud context.
* @param string $image_id
* Image id to load.
*
* @return null|\Drupal\Core\Entity\EntityInterface
* NULL if not found else Image entity.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
private function loadNewImage($cloud_context, $image_id): ?EntityInterface {
$entity = NULL;
$entities = $this->entityTypeManager
->getStorage('aws_cloud_image')
->loadByProperties([
'cloud_context' => $cloud_context,
'image_id' => $image_id,
]);
if (!empty($entities)) {
$entity = array_shift($entities);
}
return $entity;
}
/**
* {@inheritdoc}
*/
public function createImageFromInstance(EntityInterface $entity, array $param): bool {
$this->ec2Service->setCloudContext($entity->getCloudContext());
$imageName = $param['imageName'];
$noRebootFlg = $param['noRebootFlg'];
$result = $this->ec2Service->createImage([
'InstanceId' => $entity->getInstanceId(),
'Name' => $imageName,
'NoReboot' => $noRebootFlg,
]);
if (!empty($entity) && !empty($result['ImageId'])) {
// Call image update on this particular image.
$this->ec2Service->updateImages([
'ImageIds' => [
$result['ImageId'],
],
]);
$this->messenger->addStatus($this->t('The @type %label (%image_id) has been created.', [
'@type' => $entity->getEntityType()->getSingularLabel(),
'%label' => $entity->toLink($entity->label())->toString(),
'%image_id' => $result['ImageId'],
]));
$this->clearCacheValues($entity->getCacheTags());
$image = $this->loadNewImage($entity->getCloudContext(), $result['ImageId']);
if (!empty($image)) {
$this->dispatchSubmitEvent($image);
}
return TRUE;
}
else {
$this->processOperationErrorStatus($entity, 'created');
return FALSE;
}
}
}
......@@ -53,4 +53,17 @@ interface Ec2OperationsServiceInterface {
*/
public function deleteInstance(EntityInterface $entity): bool;
/**
* Create image from 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 createImageFromInstance(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