Skip to content
Snippets Groups Projects
Commit b118172b authored by Masami  Suzuki's avatar Masami Suzuki Committed by Yas Naoi
Browse files

Issue #3308495 by Masami, Ryo Yamashita, yas: Add the function to...

Issue #3308495 by Masami, Ryo Yamashita, yas: Add the function to create/delete/edit AWS Cloud Volume in the SPA
parent 1f33c6d0
No related branches found
No related tags found
No related merge requests found
Showing
with 876 additions and 386 deletions
import EntityFormTemplate from 'model/EntityFormTemplate';
const AWS_CLOUD_VOLUME_TEMPLATE: EntityFormTemplate[] = [
{
cloudServiceProvider: 'aws_cloud',
entityName: 'volume',
actionType: 'create',
entityRecords: [
{
type: 'panel',
panelName: 'Volume',
keyValueRecords: [
{ type: 'default', labelName: 'Name', name: 'name', defaultValue: '' },
{ type: 'select', labelName: 'Snapshot ID', name: 'snapshot_id',
url: '/cloud_dashboard/aws_cloud/{cloud_context}/volume_snapshot_ids',
defaultValue: '', required: true
},
{ type: 'number', labelName: 'Size (GiB)', name: 'size', defaultValue: 1, required: true },
{ type: 'select', labelName: 'Volume type', name: 'volume_type',
url: '/cloud_dashboard/aws_cloud/{cloud_context}/volume_types',
defaultValue: '', required: true
},
{ type: 'number', labelName: 'IOPS', name: 'iop', defaultValue: 1 },
{ type: 'select', labelName: 'Availability Zone', name: 'availability_zone',
url: '/cloud_dashboard/aws_cloud/{cloud_context}/availability_zone',
defaultValue: '', required: true
},
{ type: 'default', labelName: 'KMS key ID', name: 'kms_key_id', defaultValue: '' },
{ type: 'boolean', labelName: 'Encrypted', name: 'encrypted', defaultValue: true },
]
}
]
},
{
cloudServiceProvider: 'aws_cloud',
entityName: 'volume',
actionType: 'delete',
entityRecords: [
{
type: 'label',
text: 'Are you sure you want to delete the {{entityName}} {{name}}?'
},
],
submitButtonLabel: 'Delete'
},
{
cloudServiceProvider: 'aws_cloud',
entityName: 'volume',
actionType: 'edit',
entityRecords: [
{
type: 'panel',
panelName: 'Volume',
keyValueRecords: [
{ type: 'default', labelName: 'Name', name: 'name', defaultValue: '' },
{ type: 'default', labelName: 'Volume ID', name: 'volume_id', defaultValue: '', readOnly: true },
{ type: 'default', labelName: 'Instance ID', name: 'attachment_information', defaultValue: '', readOnly: true },
{ type: 'default', labelName: 'Snapshot ID', name: 'snapshot_id', defaultValue: '', readOnly: true },
{ type: 'default', labelName: 'Snapshot Name', name: 'snapshot_name', defaultValue: '', readOnly: true },
{ type: 'number', labelName: 'Size (GiB)', name: 'size', defaultValue: 1 },
{ type: 'select', labelName: 'Volume type', name: 'volume_type',
url: '/cloud_dashboard/aws_cloud/{cloud_context}/volume_types',
defaultValue: '', required: true
},
{ type: 'number', labelName: 'IOPS', name: 'iop', defaultValue: 1 },
{ type: 'default', labelName: 'Availability Zone', name: 'availability_zone', defaultValue: '', readOnly: true },
{ type: 'boolean', labelName: 'Encrypted', name: 'encrypted', defaultValue: false, labels: ['On', 'Off'], readOnly: true },
{ type: 'default', labelName: 'Status', name: 'state', defaultValue: '', readOnly: true },
{ type: 'datetime', labelName: 'Created', name: 'created', defaultValue: 0, readOnly: true },
]
}
]
},
]
export default AWS_CLOUD_VOLUME_TEMPLATE;
......@@ -11,6 +11,7 @@ import AWS_CLOUD_SUBNET_TEMPLATE from 'constant/form_template/aws_cloud/subnet';
import AWS_CLOUD_TRANSIT_GATEWAY_TEMPLATE from 'constant/form_template/aws_cloud/transit_gateway';
import AWS_CLOUD_VPC_TEMPLATE from 'constant/form_template/aws_cloud/vpc';
import AWS_CLOUD_VPC_PEERING_CONNECTION from "constant/form_template/aws_cloud/vpc_peering_connection";
import AWS_CLOUD_VOLUME_TEMPLATE from "constant/form_template/aws_cloud/volume";
import K8S_DEPLOYMENT_TEMPLATE from 'constant/form_template/k8s/deployment';
import K8S_NAMESPACE_TEMPLATE from 'constant/form_template/k8s/namespace';
import K8S_OTHER_TEMPLATE from 'constant/form_template/k8s/other';
......@@ -40,6 +41,7 @@ const ENTITY_FORM_LIST = [
...AWS_CLOUD_VPC_PEERING_CONNECTION,
...AWS_CLOUD_SUBNET_TEMPLATE,
...AWS_CLOUD_SNAPSHOT,
...AWS_CLOUD_VOLUME_TEMPLATE,
...K8S_DEPLOYMENT_TEMPLATE,
...K8S_NAMESPACE_TEMPLATE,
...K8S_POD_TEMPLATE,
......
......@@ -1566,3 +1566,68 @@ entity.aws_cloud_snapshot.delete:
_custom_access: '\Drupal\cloud\Controller\CloudConfigController::access'
options:
perm: 'delete any aws cloud snapshot+delete own aws cloud snapshot'
entity.aws_cloud_volume.create:
path: '/cloud_dashboard/aws_cloud/{cloud_context}/aws_cloud_volume/create'
defaults:
_controller: '\Drupal\aws_cloud\Controller\Ec2\ApiController::operateEntity'
entity_type_id: aws_cloud_volume
entity_id: ''
command: create
methods: [POST]
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 aws cloud volume'
entity.aws_cloud_volume.volume_snapshot_ids:
path: '/cloud_dashboard/aws_cloud/{cloud_context}/volume_snapshot_ids'
defaults:
_controller: '\Drupal\aws_cloud\Controller\Ec2\ApiController::getSnapshotOptions'
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 aws cloud volume'
entity.aws_cloud_volume.volume_types:
path: '/cloud_dashboard/aws_cloud/{cloud_context}/volume_types'
defaults:
_controller: '\Drupal\aws_cloud\Controller\Ec2\ApiController::getVolumeTypes'
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 aws cloud volume'
entity.aws_cloud_volume.delete:
path: '/cloud_dashboard/aws_cloud/{cloud_context}/aws_cloud_volume/{entity_id}/delete'
defaults:
_controller: '\Drupal\aws_cloud\Controller\Ec2\ApiController::operateEntity'
entity_type_id: aws_cloud_volume
command: delete
methods: [POST]
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: 'delete any aws cloud volume+delete own aws cloud volume'
entity.aws_cloud_volume.edit:
path: '/cloud_dashboard/aws_cloud/{cloud_context}/aws_cloud_volume/{entity_id}/edit'
defaults:
_controller: '\Drupal\aws_cloud\Controller\Ec2\ApiController::operateEntity'
entity_type_id: aws_cloud_volume
command: edit
methods: [POST]
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: 'edit any aws cloud volume+edit own aws cloud volume'
......@@ -938,6 +938,19 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
$method_name = 'createSnapshot';
break;
case 'create_aws_cloud_volume':
/** @var \Drupal\aws_cloud\Entity\Ec2\VolumeInterface $entity */
$entity->setName($request->get('name', ''));
$entity->setSnapshotId($request->get('snapshot_id', ''));
$entity->setSize($request->get('size', ''));
$entity->setVolumeType($request->get('volume_type', ''));
$entity->setIops($request->get('iop', ''));
$entity->set('availability_zone', $request->get('availability_zone', ''));
$entity->set('kms_key_id', $request->get('kms_key_id', ''));
$entity->set('encrypted', $request->get('encrypted', ''));
$method_name = 'createVolume';
break;
case 'delete_aws_cloud_elastic_ip':
$method_name = 'deleteElasticIp';
break;
......@@ -962,6 +975,10 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
$method_name = 'deleteSnapshot';
break;
case 'delete_aws_cloud_volume':
$method_name = 'deleteVolume';
break;
case 'disassociate_aws_cloud_elastic_ip':
$method_name = 'disassociateElasticIp';
break;
......@@ -1030,6 +1047,15 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
$method_name = 'editSnapshot';
break;
case 'edit_aws_cloud_volume':
/** @var \Drupal\aws_cloud\Entity\Ec2\VolumeInterface $entity */
$entity->setName($request->get('name', ''));
$entity->setSize($request->get('size', ''));
$entity->setVolumeType($request->get('volume_type', ''));
$entity->setIops($request->get('iop', ''));
$method_name = 'editVolume';
break;
case 'import_aws_cloud_key_pair':
/** @var \Drupal\aws_cloud\Entity\Ec2\KeyPairInterface $entity */
$entity->set('key_pair_name', $request->get('key_pair_name', ''));
......@@ -1731,4 +1757,58 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
return new JsonResponse($options);
}
/**
* {@inheritdoc}
*/
public function getSnapshotOptions($cloud_context): JsonResponse {
$options = [];
$params = [
'cloud_context' => $cloud_context,
];
if (!$this->currentUser->hasPermission('view any aws clcoud snapshot')) {
$params['uid'] = $this->currentUser->id();
}
$snapshots = $this->entityTypeManager
->getStorage('aws_cloud_snapshot')
->loadByProperties($params);
foreach ($snapshots ?: [] as $snapshot) {
$options[] = [
'value' => $snapshot->getSnapshotId(),
'label' => $snapshot->getName() !== $snapshot->getSnapshotId()
? "{$snapshot->getName()} ({$snapshot->getSnapshotId()})"
: $snapshot->getSnapshotId(),
];
}
return new JsonResponse($options);
}
/**
* {@inheritdoc}
*/
public function getVolumeTypes($cloud_context): JsonResponse {
$dummy_options = [
'gp2' => $this->t('General Purpose SSD (gp2)'),
'gp3' => $this->t('General Purpose SSD (gp3)'),
'io1' => $this->t('Provisioned IOPS SSD (io1)'),
'io2' => $this->t('Provisioned IOPS SSD (io2)'),
'sc1' => $this->t('Cold HDD (sc1)'),
'st1' => $this->t('Throughput Optimized HDD (st1)'),
'standard' => $this->t('Magnetic (standard)'),
];
$options = [];
foreach ($dummy_options ?: [] as $key => $option) {
$options[] = [
'value' => $key,
'label' => $option,
];
}
return new JsonResponse($options);
}
}
......@@ -318,4 +318,32 @@ interface ApiControllerInterface {
*/
public function getVolumeOptions($cloud_context): JsonResponse;
/**
* Helper function to get snapshot options.
*
* @param string $cloud_context
* Cloud context to use in the query.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* The JSON response.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getSnapshotOptions($cloud_context): JsonResponse;
/**
* Helper function to get volume types.
*
* @param string $cloud_context
* Cloud context to use in the query.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* The JSON response.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getVolumeTypes($cloud_context): JsonResponse;
}
......@@ -40,7 +40,7 @@ class SnapshotCreateForm extends AwsCloudContentForm {
protected $awsCloudOperationsService;
/**
* ElasticIpCreateForm constructor.
* SnapshotCreateForm constructor.
*
* @param \Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface $aws_cloud_operations_service
* The AWS Cloud Operations service.
......
......@@ -31,7 +31,7 @@ class SnapshotDeleteForm extends AwsDeleteUpdateEntityForm {
protected $awsCloudOperationsService;
/**
* ElasticIpDeleteForm constructor.
* SnapshotDeleteForm constructor.
*
* @param \Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface $aws_cloud_operations_service
* The AWS Cloud Operations service.
......
......@@ -36,7 +36,7 @@ class SnapshotEditForm extends AwsCloudContentForm {
protected $awsCloudOperationsService;
/**
* ElasticIpEditForm constructor.
* SnapshotEditForm constructor.
*
* @param \Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface $aws_cloud_operations_service
* The AWS Cloud Operations service.
......
......@@ -2,10 +2,27 @@
namespace Drupal\aws_cloud\Form\Ec2;
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\CloudService;
use Drupal\cloud\Service\CloudServiceInterface;
use Drupal\cloud\Service\EntityLinkRendererInterface;
use Drupal\cloud\Traits\CloudContentEntityTrait;
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;
/**
* Form controller for the Volume entity create form.
......@@ -17,6 +34,112 @@ class VolumeCreateForm extends AwsCloudContentForm {
use AwsCloudFormTrait;
use CloudContentEntityTrait;
/**
* The AWS Cloud Operations service.
*
* @var \Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface
*/
protected $awsCloudOperationsService;
/**
* VolumeCreateForm 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().
*
......@@ -201,93 +324,7 @@ class VolumeCreateForm extends AwsCloudContentForm {
* @throws \Drupal\aws_cloud\Service\Ec2\Ec2ServiceException
*/
public function save(array $form, FormStateInterface $form_state): void {
$this->trimTextfields($form, $form_state);
$entity = $this->entity;
$params = [
'Name' => $entity->getName(),
'SnapshotId' => $entity->getSnapshotId(),
'Size' => $entity->getSize(),
'AvailabilityZone' => $entity->getAvailabilityZone(),
'VolumeType' => $entity->getVolumeType(),
'Encrypted' => $entity->getEncrypted() ? TRUE : FALSE,
];
if ($entity->getVolumeType() === 'io1') {
$params['Iops'] = (int) $entity->getIops();
}
if (!empty($entity->getKmsKeyId())) {
$params['KmsKeyId'] = $entity->getKmsKeyId();
}
if (!empty($entity->getSnapshotId())) {
$params['SnapshotId'] = $entity->getSnapshotId();
}
$form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]);
$result = $this->ec2Service->createVolume($params);
if ($result === NULL) {
$this->processOperationErrorStatus($entity, 'created');
return;
}
if (!empty($result['SendToWorker'])) {
$this->processOperationStatus($entity, 'created remotely');
return;
}
if (!($entity->setVolumeId($result['VolumeId'])
&& $entity->setCreated(strtotime($result['CreateTime']))
&& $entity->setState($result['State'])
&& $entity->setSnapshotName($this->getSnapshotName($entity->getCloudContext(), $entity->getSnapshotId(), $this->getModuleName($entity)))
&& $entity->setVolumeType($result['VolumeType'])
&& $entity->save())) {
$this->processOperationErrorStatus($entity, 'created');
return;
}
$this->updateNameAndCreatedByTags($entity, $entity->getVolumeId());
$this->processOperationStatus($entity, 'created');
$this->clearCacheValues($entity->getCacheTags());
$this->dispatchSaveEvent($entity);
}
/**
* Get Snapshot Name.
*
* @param string $cloud_context
* The cloud context.
* @param string $snapshot_id
* Snapshot ID.
* @param string $module_name
* Module name.
*
* @return string
* Snapshot Name.
*/
private function getSnapshotName($cloud_context, $snapshot_id, $module_name): string {
$snapshot_name = '';
if (empty($snapshot_id)) {
return $snapshot_name;
}
$snapshots = $this->entityTypeManager
->getStorage("{$module_name}_snapshot")
->loadByProperties([
'cloud_context' => $cloud_context,
'snapshot_id' => $snapshot_id,
]);
if (empty($snapshots)) {
return $snapshot_name;
}
return array_shift($snapshots)->getName();
$this->awsCloudOperationsService->createVolume($this->entity, $form, $form_state);
}
/**
......
......@@ -2,7 +2,19 @@
namespace Drupal\aws_cloud\Form\Ec2;
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\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface;
use Drupal\aws_cloud\Service\Ec2\Ec2ServiceInterface;
use Drupal\cloud\Plugin\cloud\config\CloudConfigPluginManagerInterface;
use Drupal\cloud\Service\EntityLinkRendererInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a form for deleting a Volume entity.
......@@ -12,40 +24,91 @@ use Drupal\Core\Form\FormStateInterface;
class VolumeDeleteForm extends AwsDeleteUpdateEntityForm {
/**
* {@inheritdoc}
* The AWS Cloud Operations service.
*
* @var \Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
$entity = $this->entity;
$this->ec2Service->setCloudContext($entity->getCloudContext());
$form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]);
protected $awsCloudOperationsService;
$result = $this->ec2Service->deleteVolume([
'VolumeId' => $entity->getVolumeId(),
]);
// If $result is NULL, some error should have occurred
// when calling the AWS API.
if ($result === NULL) {
$this->processOperationErrorStatus($entity, 'deleted');
return;
}
/**
* VolumeDeleteForm 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 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\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(
AwsCloudOperationsServiceInterface $aws_cloud_operations_service,
Ec2ServiceInterface $ec2_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
);
if (!empty($result['SendToWorker'])) {
$this->messenger->addStatus($this->t('The @type @label has been deleted remotely.', [
'@type' => $entity->getEntityType()->getSingularLabel(),
'@label' => $entity->getName(),
]));
return;
}
$this->awsCloudOperationsService = $aws_cloud_operations_service;
}
$entity->delete();
/**
* {@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_type.manager'),
$container->get('cache.render'),
$container->get('plugin.cache_clearer'),
$container->get('entity.link_renderer'),
$container->get('plugin.manager.cloud_config_plugin')
);
}
$this->messenger->addStatus($this->getDeletionMessage());
$this->logDeletionMessage();
$this->clearCacheValues($entity->getCacheTags());
$this->dispatchSubmitEvent($entity);
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
$this->awsCloudOperationsService->deleteVolume($this->entity, $form, $form_state);
}
}
......@@ -2,10 +2,26 @@
namespace Drupal\aws_cloud\Form\Ec2;
use Drupal\aws_cloud\Entity\Ec2\Volume;
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;
use Drupal\cloud\Service\Util\EntityLinkWithNameHtmlGenerator;
use Drupal\cloud\Traits\CloudContentEntityTrait;
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;
/**
* Form controller for the CloudScripting entity edit forms.
......@@ -16,6 +32,112 @@ class VolumeEditForm extends AwsCloudContentForm {
use CloudContentEntityTrait;
/**
* The AWS Cloud Operations service.
*
* @var \Drupal\aws_cloud\Service\AwsCloud\AwsCloudOperationsServiceInterface
*/
protected $awsCloudOperationsService;
/**
* VolumeEditForm 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')
);
}
/**
* {@inheritdoc}
*/
......@@ -141,78 +263,7 @@ class VolumeEditForm extends AwsCloudContentForm {
* {@inheritdoc}
*/
public function save(array $form, FormStateInterface $form_state): void {
// Call copyFormItemValues() to ensure the form array is intact.
$this->copyFormItemValues($form);
$this->trimTextfields($form, $form_state);
$entity = $this->entity;
$this->ec2Service->setCloudContext($entity->getCloudContext());
$old_entity = $this->entityTypeManager
->getStorage('aws_cloud_volume')
->load($entity->id());
if ($entity->save()) {
// Delete old tags.
$this->ec2Service->deleteTags([
'Resources' => [$entity->getVolumeId()],
]);
// Update name.
$this->updateNameAndCreatedByTags($entity, $entity->getVolumeId());
// Update volume type.
if ($entity->getEntityTypeId() === 'aws_cloud_volume') {
if (!empty($entity)
&& !empty($old_entity)
&& $this->isVolumeChanged($entity, $old_entity)) {
$params = [
'VolumeId' => $entity->getVolumeId(),
'VolumeType' => $entity->getVolumeType(),
'Size' => $entity->getSize(),
];
// Only if the type is io1, the iops can be modified.
if ($entity->getVolumeType === 'io1' && $entity->getIops()) {
$params['Iops'] = $entity->getIops();
}
$this->ec2Service->modifyVolume($params);
}
}
$this->processOperationStatus($entity, 'updated');
$this->clearCacheValues($entity->getCacheTags());
$this->dispatchSaveEvent($entity);
}
else {
$this->processOperationErrorStatus($entity, 'updated');
}
$form_state->setRedirect("view.{$entity->getEntityTypeId()}.list",
[
'cloud_context' => $entity->getCloudContext(),
]);
}
/**
* Check Whether the volume changed or not.
*
* @param \Drupal\aws_cloud\Entity\Ec2\Volume $new_volume
* The new volume.
* @param \Drupal\aws_cloud\Entity\Ec2\Volume $old_volume
* The old volume.
*
* @return bool
* Whether the volume changed or not.
*/
private function isVolumeChanged(Volume $new_volume, Volume $old_volume): bool {
return $old_volume->getVolumeType() !== $new_volume->getVolumeType()
|| $old_volume->getSize() !== $new_volume->getSize()
|| $old_volume->getIops() !== $new_volume->getIops();
$this->awsCloudOperationsService->editVolume($this->entity, $form, $form_state);
}
}
......@@ -11,6 +11,7 @@ use Drupal\aws_cloud\Entity\Ec2\NetworkInterfaceInterface;
use Drupal\aws_cloud\Entity\Ec2\SecurityGroup;
use Drupal\aws_cloud\Entity\Ec2\SecurityGroupInterface;
use Drupal\aws_cloud\Entity\Ec2\SnapshotInterface;
use Drupal\aws_cloud\Entity\Ec2\VolumeInterface;
use Drupal\aws_cloud\Entity\Vpc\CarrierGatewayInterface;
use Drupal\aws_cloud\Entity\Vpc\InternetGatewayInterface;
use Drupal\aws_cloud\Entity\Vpc\SubnetInterface;
......@@ -1504,6 +1505,69 @@ class AwsCloudOperationsService implements AwsCloudOperationsServiceInterface {
return TRUE;
}
/**
* {@inheritdoc}
*/
public function createVolume(VolumeInterface $entity, array $form, FormStateInterface $form_state): bool {
$this->trimTextfields($entity, $form, $form_state);
$this->entity = $entity;
$this->ec2Service->setCloudContext($entity->getCloudContext());
$params = [
'Name' => $entity->getName(),
'SnapshotId' => $entity->getSnapshotId(),
'Size' => $entity->getSize(),
'AvailabilityZone' => $entity->getAvailabilityZone(),
'VolumeType' => $entity->getVolumeType(),
'Encrypted' => $entity->getEncrypted() ? TRUE : FALSE,
];
if ($entity->getVolumeType() === 'io1') {
$params['Iops'] = (int) $entity->getIops();
}
if (!empty($entity->getKmsKeyId())) {
$params['KmsKeyId'] = $entity->getKmsKeyId();
}
if (!empty($entity->getSnapshotId())) {
$params['SnapshotId'] = $entity->getSnapshotId();
}
$form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]);
$result = $this->ec2Service->createVolume($params);
if ($result === NULL) {
$this->processOperationErrorStatus($entity, 'created');
return FALSE;
}
if (!empty($result['SendToWorker'])) {
$this->processOperationStatus($entity, 'created remotely');
return TRUE;
}
if (!($entity->setVolumeId($result['VolumeId'])
&& $entity->setCreated(strtotime($result['CreateTime']))
&& $entity->setState($result['State'])
&& $entity->setSnapshotName($this->getSnapshotName($entity->getCloudContext(), $entity->getSnapshotId(), $this->getModuleName($entity)))
&& $entity->setVolumeType($result['VolumeType'])
&& $entity->save())) {
$this->processOperationErrorStatus($entity, 'created');
return FALSE;
}
$this->updateNameAndCreatedByTags($entity, $entity->getVolumeId());
$this->processOperationStatus($entity, 'created');
$this->clearCacheValues($entity->getCacheTags());
$this->dispatchSaveEvent($entity);
return TRUE;
}
/**
* {@inheritdoc}
*/
......@@ -1790,6 +1854,43 @@ class AwsCloudOperationsService implements AwsCloudOperationsServiceInterface {
return TRUE;
}
/**
* {@inheritdoc}
*/
public function deleteVolume(VolumeInterface $entity, array $form, FormStateInterface $form_state): bool {
$this->entity = $entity;
$this->ec2Service->setCloudContext($entity->getCloudContext());
$form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]);
$result = $this->ec2Service->deleteVolume([
'VolumeId' => $entity->getVolumeId(),
]);
// If $result is NULL, some error should have occurred
// when calling the AWS API.
if ($result === NULL) {
$this->processOperationErrorStatus($entity, 'deleted');
return FALSE;
}
if (!empty($result['SendToWorker'])) {
$this->messenger->addStatus($this->t('The @type @label has been deleted remotely.', [
'@type' => $entity->getEntityType()->getSingularLabel(),
'@label' => $entity->getName(),
]));
return TRUE;
}
$entity->delete();
$this->messenger->addStatus($this->getDeletionMessage());
$this->logDeletionMessage();
$this->clearCacheValues($entity->getCacheTags());
$this->dispatchSubmitEvent($entity);
return TRUE;
}
/**
* {@inheritdoc}
*/
......@@ -2330,6 +2431,67 @@ class AwsCloudOperationsService implements AwsCloudOperationsServiceInterface {
}
}
/**
* {@inheritdoc}
*/
public function editVolume(VolumeInterface $entity, array $form, FormStateInterface $form_state): bool {
$this->copyFormItemValues($entity, $form);
$this->trimTextfields($entity, $form, $form_state);
$this->entity = $entity;
$this->ec2Service->setCloudContext($entity->getCloudContext());
$old_entity = $this->entityTypeManager
->getStorage('aws_cloud_volume')
->load($entity->id());
if ($entity->save()) {
// Delete old tags.
$this->ec2Service->deleteTags([
'Resources' => [$entity->getVolumeId()],
]);
// Update name.
$this->updateNameAndCreatedByTags($entity, $entity->getVolumeId());
// Update volume type.
if ($entity->getEntityTypeId() === 'aws_cloud_volume') {
if (!empty($entity)
&& !empty($old_entity)
&& $this->isVolumeChanged($entity, $old_entity)) {
$params = [
'VolumeId' => $entity->getVolumeId(),
'VolumeType' => $entity->getVolumeType(),
'Size' => $entity->getSize(),
];
// Only if the type is io1, the iops can be modified.
if ($entity->getVolumeType === 'io1' && $entity->getIops()) {
$params['Iops'] = $entity->getIops();
}
$this->ec2Service->modifyVolume($params);
}
}
$this->processOperationStatus($entity, 'updated');
$this->clearCacheValues($entity->getCacheTags());
$this->dispatchSaveEvent($entity);
}
else {
$this->processOperationErrorStatus($entity, 'updated');
}
$form_state->setRedirect("view.{$entity->getEntityTypeId()}.list",
[
'cloud_context' => $entity->getCloudContext(),
]);
return TRUE;
}
/**
* {@inheritdoc}
*/
......@@ -3563,4 +3725,54 @@ class AwsCloudOperationsService implements AwsCloudOperationsServiceInterface {
$this->ec2Service->updateNetworkInterfaces();
}
/**
* Get Snapshot Name.
*
* @param string $cloud_context
* The cloud context.
* @param string $snapshot_id
* Snapshot ID.
* @param string $module_name
* Module name.
*
* @return string
* Snapshot Name.
*/
private function getSnapshotName($cloud_context, $snapshot_id, $module_name): string {
$snapshot_name = '';
if (empty($snapshot_id)) {
return $snapshot_name;
}
$snapshots = $this->entityTypeManager
->getStorage("{$module_name}_snapshot")
->loadByProperties([
'cloud_context' => $cloud_context,
'snapshot_id' => $snapshot_id,
]);
if (empty($snapshots)) {
return $snapshot_name;
}
return array_shift($snapshots)->getName();
}
/**
* Check Whether the volume changed or not.
*
* @param \Drupal\aws_cloud\Entity\Ec2\VolumeInterface $new_volume
* The new volume.
* @param \Drupal\aws_cloud\Entity\Ec2\VolumeInterface $old_volume
* The old volume.
*
* @return bool
* Whether the volume changed or not.
*/
private function isVolumeChanged(VolumeInterface $new_volume, VolumeInterface $old_volume): bool {
return $old_volume->getVolumeType() !== $new_volume->getVolumeType()
|| $old_volume->getSize() !== $new_volume->getSize()
|| $old_volume->getIops() !== $new_volume->getIops();
}
}
......@@ -11,6 +11,7 @@ use Drupal\aws_cloud\Entity\Ec2\NetworkInterfaceInterface;
use Drupal\aws_cloud\Entity\Ec2\SecurityGroup;
use Drupal\aws_cloud\Entity\Ec2\SecurityGroupInterface;
use Drupal\aws_cloud\Entity\Ec2\SnapshotInterface;
use Drupal\aws_cloud\Entity\Ec2\VolumeInterface;
use Drupal\aws_cloud\Entity\Vpc\CarrierGatewayInterface;
use Drupal\aws_cloud\Entity\Vpc\InternetGatewayInterface;
use Drupal\aws_cloud\Entity\Vpc\SubnetInterface;
......@@ -480,6 +481,21 @@ interface AwsCloudOperationsServiceInterface {
*/
public function createSnapshot(SnapshotInterface $entity, array $form, FormStateInterface $form_state): bool;
/**
* Create a Volume.
*
* @param \Drupal\aws_cloud\Entity\Ec2\VolumeInterface $entity
* The SecurityGroup entity.
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @throws \Drupal\Core\Entity\EntityStorageException
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
public function createVolume(VolumeInterface $entity, array $form, FormStateInterface $form_state): bool;
/**
* Delete an Elastic IP.
*
......@@ -576,6 +592,21 @@ interface AwsCloudOperationsServiceInterface {
*/
public function deleteSnapshot(SnapshotInterface $entity, array $form, FormStateInterface $form_state): bool;
/**
* Delete a Volume.
*
* @param \Drupal\aws_cloud\Entity\Ec2\VolumeInterface $entity
* The SecurityGroup entity.
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @throws \Drupal\Core\Entity\EntityStorageException
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
public function deleteVolume(VolumeInterface $entity, array $form, FormStateInterface $form_state): bool;
/**
* Disassociate an Elastic IP.
*
......@@ -723,6 +754,21 @@ interface AwsCloudOperationsServiceInterface {
*/
public function editSnapshot(SnapshotInterface $entity, array $form, FormStateInterface $form_state): bool;
/**
* Edit a Volume.
*
* @param \Drupal\aws_cloud\Entity\Ec2\VolumeInterface $entity
* The SecurityGroup entity.
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @throws \Drupal\Core\Entity\EntityStorageException
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
public function editVolume(VolumeInterface $entity, array $form, FormStateInterface $form_state): bool;
/**
* Get console output from AWS Cloud instance.
*
......
......@@ -3,6 +3,7 @@
namespace Drupal\openstack\Form;
use Drupal\aws_cloud\Form\Ec2\VolumeCreateForm;
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\EntityLinkRendererInterface;
......@@ -47,6 +48,8 @@ class OpenStackVolumeCreateForm extends VolumeCreateForm {
/**
* OpenStackVolumeCreateForm 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
......@@ -82,7 +85,8 @@ class OpenStackVolumeCreateForm extends VolumeCreateForm {
* @param \Drupal\openstack\Service\OpenStackOperationsServiceInterface $openstack_operations_service
* The OpenStack Operations service.
*/
public function __construct(OpenStackServiceFactoryInterface $openstack_service_factory,
public function __construct(AwsCloudOperationsServiceInterface $aws_cloud_operations_service,
OpenStackServiceFactoryInterface $openstack_service_factory,
Ec2ServiceInterface $ec2_service,
EntityRepositoryInterface $entity_repository,
EntityTypeBundleInfoInterface $entity_type_bundle_info,
......@@ -101,6 +105,7 @@ class OpenStackVolumeCreateForm extends VolumeCreateForm {
OpenStackOperationsServiceInterface $openstack_operations_service) {
parent::__construct(
$aws_cloud_operations_service,
$ec2_service,
$entity_repository,
$entity_type_bundle_info,
......@@ -133,6 +138,7 @@ class OpenStackVolumeCreateForm extends VolumeCreateForm {
*/
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'),
......
......@@ -3,6 +3,7 @@
namespace Drupal\openstack\Form;
use Drupal\aws_cloud\Form\Ec2\VolumeDeleteForm;
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\EntityLinkRendererInterface;
......@@ -42,6 +43,8 @@ class OpenStackVolumeDeleteForm extends VolumeDeleteForm {
/**
* OpenStackVolumeDeleteForm 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
......@@ -67,7 +70,8 @@ class OpenStackVolumeDeleteForm extends VolumeDeleteForm {
* @param \Drupal\openstack\Service\OpenStackOperationsServiceInterface $openstack_operations_service
* The OpenStack Operations service.
*/
public function __construct(OpenStackServiceFactoryInterface $openstack_service_factory,
public function __construct(AwsCloudOperationsServiceInterface $aws_cloud_operations_service,
OpenStackServiceFactoryInterface $openstack_service_factory,
Ec2ServiceInterface $ec2_service,
EntityRepositoryInterface $entity_repository,
EntityTypeBundleInfoInterface $entity_type_bundle_info,
......@@ -80,6 +84,7 @@ class OpenStackVolumeDeleteForm extends VolumeDeleteForm {
CloudConfigPluginManagerInterface $cloud_config_plugin_manager,
OpenStackOperationsServiceInterface $openstack_operations_service) {
parent::__construct(
$aws_cloud_operations_service,
$ec2_service,
$entity_repository,
$entity_type_bundle_info,
......@@ -106,6 +111,7 @@ class OpenStackVolumeDeleteForm extends VolumeDeleteForm {
*/
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'),
......
......@@ -4,6 +4,7 @@ namespace Drupal\openstack\Form;
use Drupal\openstack\Service\Rest\OpenStackService as OpenStackRestService;
use Drupal\aws_cloud\Form\Ec2\VolumeEditForm;
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\EntityLinkRendererInterface;
......@@ -48,6 +49,8 @@ class OpenStackVolumeEditForm extends VolumeEditForm {
/**
* OpenStackVolumeEditForm 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
......@@ -83,7 +86,8 @@ class OpenStackVolumeEditForm extends VolumeEditForm {
* @param \Drupal\openstack\Service\OpenStackOperationsServiceInterface $openstack_operations_service
* The OpenStack Operations service.
*/
public function __construct(OpenStackServiceFactoryInterface $openstack_service_factory,
public function __construct(AwsCloudOperationsServiceInterface $aws_cloud_operations_service,
OpenStackServiceFactoryInterface $openstack_service_factory,
Ec2ServiceInterface $ec2_service,
EntityRepositoryInterface $entity_repository,
EntityTypeBundleInfoInterface $entity_type_bundle_info,
......@@ -102,6 +106,7 @@ class OpenStackVolumeEditForm extends VolumeEditForm {
OpenStackOperationsServiceInterface $openstack_operations_service) {
parent::__construct(
$aws_cloud_operations_service,
$ec2_service,
$entity_repository,
$entity_type_bundle_info,
......@@ -134,6 +139,7 @@ class OpenStackVolumeEditForm extends VolumeEditForm {
*/
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'),
......
......@@ -1549,76 +1549,7 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface
$this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext());
$this->awsCloudOperationsService->setEc2Service($this->ec2Service);
return $this->createVolume($form, $form_state);
}
/**
* Create a volume.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @throws \Drupal\Core\Entity\EntityStorageException
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
private function createVolume(array &$form, FormStateInterface $form_state): bool {
/** @var \Drupal\aws_cloud\Entity\Ec2\VolumeInterface $entity */
$entity = $this->entity;
$this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state);
$params = [
'Name' => $entity->getName(),
'SnapshotId' => $entity->getSnapshotId(),
'Size' => $entity->getSize(),
'AvailabilityZone' => $entity->getAvailabilityZone(),
'VolumeType' => $entity->getVolumeType(),
'Encrypted' => $entity->getEncrypted() ? TRUE : FALSE,
];
if ($entity->getVolumeType() === 'io1') {
$params['Iops'] = (int) $entity->getIops();
}
if (!empty($entity->getKmsKeyId())) {
$params['KmsKeyId'] = $entity->getKmsKeyId();
}
if (!empty($entity->getSnapshotId())) {
$params['SnapshotId'] = $entity->getSnapshotId();
}
$form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]);
$result = $this->ec2Service->createVolume($params);
if ($result === NULL) {
$this->processOperationErrorStatus($entity, 'created');
return FALSE;
}
if (!empty($result['SendToWorker'])) {
$this->processOperationStatus($entity, 'created remotely');
return TRUE;
}
if (!($entity->setVolumeId($result['VolumeId'])
&& $entity->setCreated(strtotime($result['CreateTime']))
&& $entity->setState($result['State'])
&& $entity->setSnapshotName($this->getSnapshotName($entity->getCloudContext(), $entity->getSnapshotId(), $this->getModuleName($entity)))
&& $entity->setVolumeType($result['VolumeType'])
&& $entity->save())) {
$this->processOperationErrorStatus($entity, 'created');
return FALSE;
}
$this->awsCloudOperationsService->updateNameAndCreatedByTags($entity, $entity->getVolumeId());
$this->processOperationStatus($entity, 'created');
$this->clearCacheValues($entity->getCacheTags());
$this->dispatchSaveEvent($entity);
return TRUE;
return $this->awsCloudOperationsService->createVolume($entity, $form, $form_state);
}
/**
......@@ -1630,53 +1561,7 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface
$this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext());
$this->awsCloudOperationsService->setEc2Service($this->ec2Service);
return $this->deleteVolume($form, $form_state);
}
/**
* Delete a volume.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @throws \Drupal\Core\Entity\EntityStorageException
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
private function deleteVolume(array &$form, FormStateInterface $form_state): bool {
/** @var \Drupal\aws_cloud\Entity\Ec2\VolumeInterface $entity */
$entity = $this->entity;
$this->ec2Service->setCloudContext($entity->getCloudContext());
$form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]);
$result = $this->ec2Service->deleteVolume([
'VolumeId' => $entity->getVolumeId(),
]);
// If $result is NULL, some error should have occurred
// when calling the AWS API.
if ($result === NULL) {
$this->processOperationErrorStatus($entity, 'deleted');
return FALSE;
}
if (!empty($result['SendToWorker'])) {
$this->messenger->addStatus($this->t('The @type @label has been deleted remotely.', [
'@type' => $entity->getEntityType()->getSingularLabel(),
'@label' => $entity->getName(),
]));
return TRUE;
}
$entity->delete();
$this->messenger->addStatus($this->getDeletionMessage());
$this->logDeletionMessage();
$this->clearCacheValues($entity->getCacheTags());
$this->dispatchSubmitEvent($entity);
return TRUE;
return $this->awsCloudOperationsService->deleteVolume($entity, $form, $form_state);
}
/**
......@@ -1688,7 +1573,7 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface
$this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext());
$this->awsCloudOperationsService->setEc2Service($this->ec2Service);
$this->saveVolume($form, $form_state);
$this->awsCloudOperationsService->editVolume($entity, $form, $form_state);
// Update Volume of OpenStack REST API.
if ($this->ec2Service instanceof OpenStackRestService) {
......@@ -1700,43 +1585,6 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface
return TRUE;
}
/**
* Save a volume.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @throws \Drupal\Core\Entity\EntityStorageException
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
private function saveVolume(array &$form, FormStateInterface $form_state): bool {
/** @var \Drupal\aws_cloud\Entity\Ec2\VolumeInterface $entity */
$entity = $this->entity;
$this->awsCloudOperationsService->copyFormItemValues($entity, $form, $form_state);
$this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state);
$this->ec2Service->setCloudContext($entity->getCloudContext());
if ($entity->save()) {
$this->processOperationStatus($entity, 'updated');
$this->clearCacheValues($entity->getCacheTags());
$this->dispatchSaveEvent($entity);
}
else {
$this->processOperationErrorStatus($entity, 'updated');
return FALSE;
}
$form_state->setRedirect("view.{$entity->getEntityTypeId()}.list",
[
'cloud_context' => $entity->getCloudContext(),
]);
return TRUE;
}
/**
* {@inheritdoc}
*/
......@@ -2177,42 +2025,6 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface
return $private_ips;
}
/**
* Get Snapshot Name.
*
* @param string $cloud_context
* The cloud context.
* @param string $snapshot_id
* Snapshot ID.
* @param string $module_name
* Module name.
*
* @return string
* Snapshot Name.
*/
private function getSnapshotName($cloud_context, $snapshot_id, $module_name): string {
$snapshot_name = '';
if (empty($snapshot_id)) {
return $snapshot_name;
}
$snapshots = $this->entityTypeManager
->getStorage('openstack_snapshot')
->loadByProperties([
'cloud_context' => $cloud_context,
'snapshot_id' => $snapshot_id,
]);
if (empty($snapshots)) {
return $snapshot_name;
}
/** @var \Drupal\aws_cloud\Entity\Ec2\SnapshotInterface $snapshot */
$snapshot = array_shift($snapshots);
return $snapshot->getName();
}
/**
* {@inheritdoc}
*/
......
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