Loading modules/cloud_service_providers/openstack/openstack.routing.yml +14 −0 Original line number Diff line number Diff line Loading @@ -1033,6 +1033,20 @@ entity.openstack_volume.instances: requirements: _custom_access: '\Drupal\openstack\Controller\ApiController::access' entity.openstack_cloud_launch_template.edit: path: '/cloud_dashboard/openstack/{cloud_context}/cloud_launch_template/{entity_id}/edit' defaults: _controller: '\Drupal\openstack\Controller\ApiController::operateEntity' entity_type_id: cloud_launch_template 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 cloud server templates+edit own cloud server templates' entity.openstack_floating_ip.network_interface_ids: path: '/cloud_dashboard/openstack/{cloud_context}/network_interface_ids' defaults: Loading modules/cloud_service_providers/openstack/openstack.services.yml +1 −1 Original line number Diff line number Diff line Loading @@ -24,4 +24,4 @@ services: openstack.operations: class: Drupal\openstack\Service\OpenStackOperationsService arguments: ['@aws_cloud.openstack.operations', '@plugin.manager.cloud_config_plugin', '@cloud', '@openstack.ec2', '@entity_type.manager', '@messenger', '@openstack.factory', '@request_stack', '@entity.link_renderer'] arguments: ['@aws_cloud.openstack.operations', '@plugin.manager.cloud_config_plugin', '@cloud', '@openstack.ec2', '@entity_type.manager', '@messenger', '@openstack.factory', '@request_stack', '@current_route_match', '@entity.link_renderer'] modules/cloud_service_providers/openstack/src/Controller/ApiController.php +4 −0 Original line number Diff line number Diff line Loading @@ -713,6 +713,10 @@ class ApiController extends ControllerBase implements ApiControllerInterface { $method_name = 'detachOpenStackVolume'; break; case 'edit_openstack_cloud_launch_template': $method_name = 'editOpenStackCloudLaunchTemplate'; break; } // Execute the process. Loading modules/cloud_service_providers/openstack/src/Service/OpenStackOperationsService.php +232 −13 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ use Drupal\cloud\Plugin\cloud\config\CloudConfigPluginManagerInterface; use Drupal\cloud\Service\CloudServiceInterface; use Drupal\cloud\Service\EntityLinkRendererInterface; use Drupal\cloud\Entity\CloudContentEntityBase; use Drupal\cloud\Entity\CloudLaunchTemplateInterface; use Drupal\cloud\Traits\CloudContentEntityTrait; use Drupal\Core\Entity\EntityDeleteFormTrait; use Drupal\Core\Entity\EntityInterface; Loading @@ -24,6 +25,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\Messenger; use Drupal\Core\Render\Markup; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\openstack\Entity\OpenStackNetworkExInterface; use Drupal\openstack\Entity\OpenStackPortInterface; use Drupal\openstack\Entity\OpenStackRouterInterface; Loading Loading @@ -106,6 +108,13 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface */ protected $requestStack; /** * Route match object. * * @var \Drupal\Core\Routing\RouteMatchInterface */ protected $routeMatch; /** * OpenStackOperationsService constructor. * Loading @@ -125,6 +134,8 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface * Object for interfacing with OpenStack Service. * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack * Request stack object. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * Route match object. * @param \Drupal\cloud\Service\EntityLinkRendererInterface $entity_link_renderer * The entity link render service. */ Loading @@ -137,6 +148,7 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface Messenger $messenger, OpenStackServiceFactoryInterface $openstack_service_factory, RequestStack $request_stack, RouteMatchInterface $route_match, EntityLinkRendererInterface $entity_link_renderer ) { $this->awsCloudOperationsService = $aws_cloud_operations_service; Loading @@ -147,6 +159,7 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface $this->messenger = $messenger; $this->openStackServiceFactory = $openstack_service_factory; $this->requestStack = $request_stack; $this->routeMatch = $route_match; $this->entityLinkRenderer = $entity_link_renderer; } Loading Loading @@ -776,7 +789,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface * {@inheritdoc} */ public function createOpenStackNetwork(OpenStackNetworkExInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -830,7 +845,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface * {@inheritdoc} */ public function createOpenStackSubnet(OpenStackSubnetInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -940,7 +957,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface * {@inheritdoc} */ public function createOpenStackPort(OpenStackPortInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -1023,7 +1042,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface * {@inheritdoc} */ public function createOpenStackRouter(OpenStackRouterInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -1088,7 +1109,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface * {@inheritdoc} */ public function addOpenStackRouterInterface(OpenStackRouterInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $form_state->setRedirect('view.openstack_port.router_interface', [ Loading @@ -1102,6 +1125,7 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface 'cloud_context' => $entity->getCloudContext(), 'subnet_id' => $form_state->getValue('subnet_id'), ]); /** @var \Drupal\openstack\Entity\OpenStackSubnet $subnet */ $subnet = reset($subnets); $ip_address = $form_state->getValue('ip_address'); Loading Loading @@ -1230,7 +1254,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function editOpenStackNetwork(OpenStackNetworkExInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -1286,7 +1312,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function editOpenStackSubnet(OpenStackSubnetInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -1402,7 +1430,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function editOpenStackPort(OpenStackPortInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -1478,7 +1508,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function editOpenStackRouter(OpenStackRouterInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -1552,7 +1584,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function deleteOpenStackNetwork(OpenStackNetworkExInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]); Loading Loading @@ -1589,7 +1623,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function deleteOpenStackSubnet(OpenStackSubnetInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]); Loading Loading @@ -1626,7 +1662,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function deleteOpenStackPort(OpenStackPortInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]); Loading Loading @@ -1663,7 +1701,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function deleteOpenStackRouter(OpenStackRouterInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]); Loading Loading @@ -2834,4 +2874,183 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface } } /** * {@inheritdoc} */ public function editOpenStackCloudLaunchTemplate(CloudLaunchTemplateInterface $entity, array &$form, FormStateInterface $form_state): bool { try { $this->alterCloudLaunchTemplateEditForm($entity, $form, $form_state); return $this->submitCloudLaunchTemplateEditForm($entity, $form, $form_state); } catch (\Exception $e) { $this->handleException($e); $this->processOperationErrorStatus($entity, 'edited'); return FALSE; } } /** * Common alter function for edit and add forms. * * @param \Drupal\cloud\Entity\CloudLaunchTemplateInterface $entity * The CloudLaunchTemplate entity. * @param array $form * Array of form object. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. */ private function alterCloudLaunchTemplateCommonForm(CloudLaunchTemplateInterface $entity, array &$form, FormStateInterface $form_state) { $this->cloudService->reorderForm($form, openstack_launch_template_field_orders()); $cloud_context = $this->routeMatch->getParameter('cloud_context'); /** @var \Drupal\openstack\Service\OpenStackServiceInterface $openstack_service */ $openstack_ec2_service = $this->openStackServiceFactory->isEc2ServiceType('cloud_config', $cloud_context); if (empty($openstack_ec2_service)) { $form['instance']['field_min_count']['#access'] = FALSE; $form['instance']['field_max_count']['#access'] = FALSE; $form['ami']['field_kernel_id']['#access'] = FALSE; $form['ami']['field_ram']['#access'] = FALSE; $form['network']['field_openstack_vpc']['#access'] = FALSE; $form['network']['field_openstack_subnet']['#access'] = FALSE; unset($form['options']); } $form['field_instance_type']['widget']['#default_value'] = ['m1.nano']; $form['field_instance_type']['#access'] = FALSE; if (!empty($openstack_ec2_service)) { $form['instance']['field_flavor']['widget']['#default_value'] = '1'; $form['instance']['field_flavor']['#access'] = FALSE; $form['network']['field_openstack_vpc']['widget']['#ajax'] = [ 'callback' => 'openstack_ajax_callback_get_fields', ]; $vpc_id = '_none'; if (!empty($form['network']['field_openstack_vpc']['widget']['#default_value'])) { $vpc_id = $form['network']['field_openstack_vpc']['widget']['#default_value'][0]; } // If validation happened, we should get vpc_id from user input. $user_input = $form_state->getUserInput(); if (!empty($user_input['field_openstack_vpc'])) { $vpc_id = $user_input['field_openstack_vpc']; } /** @var \Drupal\Core\Entity\EntityFormInterface $form_object */ $form_object = $form_state->getFormObject(); $server_template = $entity->createDuplicate(); $form_object->setEntity($server_template); $subnet_options = openstack_get_subnet_options_by_vpc_id($vpc_id, $form_object->getEntity()); $form['#attached']['library'][] = 'openstack/openstack_form'; $form['#attached']['drupalSettings']['openstack']['field_openstack_subnet_default_values'] = array_keys($subnet_options); $security_group_options = openstack_get_security_group_options_by_vpc_id($vpc_id); $security_group_default_values = array_map(static function ($id) { return (string) $id; }, array_keys($security_group_options)); $form['#attached']['drupalSettings']['openstack']['field_openstack_security_group_default_values'] = $security_group_default_values; } // Hide labels of field_tags. $form['tags']['field_tags']['widget']['#title'] = NULL; if (empty($openstack_ec2_service)) { $form['#validate'][] = 'openstack_form_cloud_launch_template_form_validate'; } } /** * Implements hook_form_FORM_ID_alter(). * * @param \Drupal\cloud\Entity\CloudLaunchTemplateInterface $entity * The CloudLaunchTemplate entity. * @param array $form * Array of form object. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. */ private function alterCloudLaunchTemplateEditForm(CloudLaunchTemplateInterface $entity, array &$form, FormStateInterface $form_state) { $this->alterCloudLaunchTemplateCommonForm($entity, $form, $form_state); // Hide new revision checkbox. $form['new_revision']['#access'] = FALSE; // Disable name field. $form['instance']['name']['#disabled'] = TRUE; /** @var \Drupal\Core\Entity\EntityFormInterface $form_object */ $form_object = $form_state->getFormObject(); /** @var \Drupal\cloud\Entity\CloudLaunchTemplateInterface $server_template */ $server_template = $form_object->getEntity(); $cloud_context = $server_template->getCloudContext(); $openstack_service = $this->openStackServiceFactory->isEc2ServiceType('cloud_config', $cloud_context); if (empty($openstack_service)) { // Overwrite function ::save. $form['actions']['submit']['#submit'][1] = 'openstack_form_cloud_launch_template_openstack_edit_form_submit'; } } /** * Submit function for form cloud_launch_template_aws_cloud_edit_form. * * @param \Drupal\cloud\Entity\CloudLaunchTemplateInterface $entity * The CloudLaunchTemplate entity. * @param array $form * Array of form object. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. * * @return bool * TRUE when the process succeeds. */ private function submitCloudLaunchTemplateEditForm(CloudLaunchTemplateInterface $entity, array &$form, FormStateInterface $form_state): bool { /** @var \Drupal\Core\Entity\EntityFormInterface $form_object */ $form_object = $form_state->getFormObject(); /** @var \Drupal\cloud\Entity\CloudLaunchTemplateInterface $server_template */ $server_template = $form_object->getEntity(); $cloud_context = $server_template->getCloudContext(); $form_values = $form_state->getValues(); $uid = $form_values['uid'][0]['target_id'] ?? 0; /** @var \Drupal\openstack\Service\OpenStackServiceInterface|\Drupal\cloud\Service\CloudResourceTagInterface $openstack_service */ $openstack_service = $this->openStackServiceFactory->get($cloud_context); $uid_key_name = $openstack_service->getTagKeyCreatedByUid( 'openstack', $cloud_context, intval($uid) ); $form_tags = ($server_template->hasField('field_tags') && !$server_template->get('field_tags')->isEmpty()) ? $server_template->get('field_tags')->getValue() : []; // Update tags if authored id is changed. foreach ($form_tags ?: [] as $form_tag) { $item_key = $form_tag['item_key']; if ($form_tag['item_key'] === $uid_key_name) { $tags[] = ['item_key' => $item_key, 'item_value' => $uid]; } } $server_template->set('field_tags', $tags); $server_template->save(); $this->processOperationStatus($server_template, 'updated'); $form_state->setRedirect( 'entity.cloud_launch_template.canonical', [ 'cloud_context' => $cloud_context, 'cloud_launch_template' => $server_template->id(), ] ); return TRUE; } } modules/cloud_service_providers/openstack/src/Service/OpenStackOperationsServiceInterface.php +16 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ use Drupal\aws_cloud\Entity\Ec2\NetworkInterfaceInterface; use Drupal\aws_cloud\Entity\Ec2\SecurityGroupInterface; use Drupal\aws_cloud\Entity\Ec2\SnapshotInterface; use Drupal\aws_cloud\Entity\Ec2\VolumeInterface; use Drupal\cloud\Entity\CloudLaunchTemplateInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\openstack\Entity\OpenStackNetworkExInterface; use Drupal\openstack\Entity\OpenStackPortInterface; Loading Loading @@ -730,4 +731,19 @@ interface OpenStackOperationsServiceInterface { */ public function detachOpenStackVolume(VolumeInterface $entity, array &$form, FormStateInterface $form_state): bool; /** * Edit an OpenStack CloudLaunchTemplate. * * @param \Drupal\cloud\Entity\CloudLaunchTemplateInterface $entity * The CloudLaunchTemplate entity. * @param array $form * Array of form object. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. * * @return bool * TRUE when the process succeeds. */ public function editOpenStackCloudLaunchTemplate(CloudLaunchTemplateInterface $entity, array &$form, FormStateInterface $form_state): bool; } Loading
modules/cloud_service_providers/openstack/openstack.routing.yml +14 −0 Original line number Diff line number Diff line Loading @@ -1033,6 +1033,20 @@ entity.openstack_volume.instances: requirements: _custom_access: '\Drupal\openstack\Controller\ApiController::access' entity.openstack_cloud_launch_template.edit: path: '/cloud_dashboard/openstack/{cloud_context}/cloud_launch_template/{entity_id}/edit' defaults: _controller: '\Drupal\openstack\Controller\ApiController::operateEntity' entity_type_id: cloud_launch_template 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 cloud server templates+edit own cloud server templates' entity.openstack_floating_ip.network_interface_ids: path: '/cloud_dashboard/openstack/{cloud_context}/network_interface_ids' defaults: Loading
modules/cloud_service_providers/openstack/openstack.services.yml +1 −1 Original line number Diff line number Diff line Loading @@ -24,4 +24,4 @@ services: openstack.operations: class: Drupal\openstack\Service\OpenStackOperationsService arguments: ['@aws_cloud.openstack.operations', '@plugin.manager.cloud_config_plugin', '@cloud', '@openstack.ec2', '@entity_type.manager', '@messenger', '@openstack.factory', '@request_stack', '@entity.link_renderer'] arguments: ['@aws_cloud.openstack.operations', '@plugin.manager.cloud_config_plugin', '@cloud', '@openstack.ec2', '@entity_type.manager', '@messenger', '@openstack.factory', '@request_stack', '@current_route_match', '@entity.link_renderer']
modules/cloud_service_providers/openstack/src/Controller/ApiController.php +4 −0 Original line number Diff line number Diff line Loading @@ -713,6 +713,10 @@ class ApiController extends ControllerBase implements ApiControllerInterface { $method_name = 'detachOpenStackVolume'; break; case 'edit_openstack_cloud_launch_template': $method_name = 'editOpenStackCloudLaunchTemplate'; break; } // Execute the process. Loading
modules/cloud_service_providers/openstack/src/Service/OpenStackOperationsService.php +232 −13 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ use Drupal\cloud\Plugin\cloud\config\CloudConfigPluginManagerInterface; use Drupal\cloud\Service\CloudServiceInterface; use Drupal\cloud\Service\EntityLinkRendererInterface; use Drupal\cloud\Entity\CloudContentEntityBase; use Drupal\cloud\Entity\CloudLaunchTemplateInterface; use Drupal\cloud\Traits\CloudContentEntityTrait; use Drupal\Core\Entity\EntityDeleteFormTrait; use Drupal\Core\Entity\EntityInterface; Loading @@ -24,6 +25,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\Messenger; use Drupal\Core\Render\Markup; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\openstack\Entity\OpenStackNetworkExInterface; use Drupal\openstack\Entity\OpenStackPortInterface; use Drupal\openstack\Entity\OpenStackRouterInterface; Loading Loading @@ -106,6 +108,13 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface */ protected $requestStack; /** * Route match object. * * @var \Drupal\Core\Routing\RouteMatchInterface */ protected $routeMatch; /** * OpenStackOperationsService constructor. * Loading @@ -125,6 +134,8 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface * Object for interfacing with OpenStack Service. * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack * Request stack object. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * Route match object. * @param \Drupal\cloud\Service\EntityLinkRendererInterface $entity_link_renderer * The entity link render service. */ Loading @@ -137,6 +148,7 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface Messenger $messenger, OpenStackServiceFactoryInterface $openstack_service_factory, RequestStack $request_stack, RouteMatchInterface $route_match, EntityLinkRendererInterface $entity_link_renderer ) { $this->awsCloudOperationsService = $aws_cloud_operations_service; Loading @@ -147,6 +159,7 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface $this->messenger = $messenger; $this->openStackServiceFactory = $openstack_service_factory; $this->requestStack = $request_stack; $this->routeMatch = $route_match; $this->entityLinkRenderer = $entity_link_renderer; } Loading Loading @@ -776,7 +789,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface * {@inheritdoc} */ public function createOpenStackNetwork(OpenStackNetworkExInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -830,7 +845,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface * {@inheritdoc} */ public function createOpenStackSubnet(OpenStackSubnetInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -940,7 +957,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface * {@inheritdoc} */ public function createOpenStackPort(OpenStackPortInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -1023,7 +1042,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface * {@inheritdoc} */ public function createOpenStackRouter(OpenStackRouterInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -1088,7 +1109,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface * {@inheritdoc} */ public function addOpenStackRouterInterface(OpenStackRouterInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $form_state->setRedirect('view.openstack_port.router_interface', [ Loading @@ -1102,6 +1125,7 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface 'cloud_context' => $entity->getCloudContext(), 'subnet_id' => $form_state->getValue('subnet_id'), ]); /** @var \Drupal\openstack\Entity\OpenStackSubnet $subnet */ $subnet = reset($subnets); $ip_address = $form_state->getValue('ip_address'); Loading Loading @@ -1230,7 +1254,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function editOpenStackNetwork(OpenStackNetworkExInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -1286,7 +1312,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function editOpenStackSubnet(OpenStackSubnetInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -1402,7 +1430,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function editOpenStackPort(OpenStackPortInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -1478,7 +1508,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function editOpenStackRouter(OpenStackRouterInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $this->awsCloudOperationsService->trimTextfields($entity, $form, $form_state); Loading Loading @@ -1552,7 +1584,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function deleteOpenStackNetwork(OpenStackNetworkExInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]); Loading Loading @@ -1589,7 +1623,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function deleteOpenStackSubnet(OpenStackSubnetInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]); Loading Loading @@ -1626,7 +1662,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function deleteOpenStackPort(OpenStackPortInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]); Loading Loading @@ -1663,7 +1701,9 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface public function deleteOpenStackRouter(OpenStackRouterInterface $entity, array &$form, FormStateInterface $form_state): bool { $this->entity = $entity; $this->ec2Service = $this->openStackServiceFactory->get($entity->getCloudContext()); /** @var Drupal\openstack\Service\Rest\OpenStackService $ec2_service */ $ec2_service = $this->openStackServiceFactory->get($entity->getCloudContext()); $this->ec2Service = $ec2_service; $this->awsCloudOperationsService->setEc2Service($this->ec2Service); $form_state->setRedirect("view.{$entity->getEntityTypeId()}.list", ['cloud_context' => $entity->getCloudContext()]); Loading Loading @@ -2834,4 +2874,183 @@ class OpenStackOperationsService implements OpenStackOperationsServiceInterface } } /** * {@inheritdoc} */ public function editOpenStackCloudLaunchTemplate(CloudLaunchTemplateInterface $entity, array &$form, FormStateInterface $form_state): bool { try { $this->alterCloudLaunchTemplateEditForm($entity, $form, $form_state); return $this->submitCloudLaunchTemplateEditForm($entity, $form, $form_state); } catch (\Exception $e) { $this->handleException($e); $this->processOperationErrorStatus($entity, 'edited'); return FALSE; } } /** * Common alter function for edit and add forms. * * @param \Drupal\cloud\Entity\CloudLaunchTemplateInterface $entity * The CloudLaunchTemplate entity. * @param array $form * Array of form object. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. */ private function alterCloudLaunchTemplateCommonForm(CloudLaunchTemplateInterface $entity, array &$form, FormStateInterface $form_state) { $this->cloudService->reorderForm($form, openstack_launch_template_field_orders()); $cloud_context = $this->routeMatch->getParameter('cloud_context'); /** @var \Drupal\openstack\Service\OpenStackServiceInterface $openstack_service */ $openstack_ec2_service = $this->openStackServiceFactory->isEc2ServiceType('cloud_config', $cloud_context); if (empty($openstack_ec2_service)) { $form['instance']['field_min_count']['#access'] = FALSE; $form['instance']['field_max_count']['#access'] = FALSE; $form['ami']['field_kernel_id']['#access'] = FALSE; $form['ami']['field_ram']['#access'] = FALSE; $form['network']['field_openstack_vpc']['#access'] = FALSE; $form['network']['field_openstack_subnet']['#access'] = FALSE; unset($form['options']); } $form['field_instance_type']['widget']['#default_value'] = ['m1.nano']; $form['field_instance_type']['#access'] = FALSE; if (!empty($openstack_ec2_service)) { $form['instance']['field_flavor']['widget']['#default_value'] = '1'; $form['instance']['field_flavor']['#access'] = FALSE; $form['network']['field_openstack_vpc']['widget']['#ajax'] = [ 'callback' => 'openstack_ajax_callback_get_fields', ]; $vpc_id = '_none'; if (!empty($form['network']['field_openstack_vpc']['widget']['#default_value'])) { $vpc_id = $form['network']['field_openstack_vpc']['widget']['#default_value'][0]; } // If validation happened, we should get vpc_id from user input. $user_input = $form_state->getUserInput(); if (!empty($user_input['field_openstack_vpc'])) { $vpc_id = $user_input['field_openstack_vpc']; } /** @var \Drupal\Core\Entity\EntityFormInterface $form_object */ $form_object = $form_state->getFormObject(); $server_template = $entity->createDuplicate(); $form_object->setEntity($server_template); $subnet_options = openstack_get_subnet_options_by_vpc_id($vpc_id, $form_object->getEntity()); $form['#attached']['library'][] = 'openstack/openstack_form'; $form['#attached']['drupalSettings']['openstack']['field_openstack_subnet_default_values'] = array_keys($subnet_options); $security_group_options = openstack_get_security_group_options_by_vpc_id($vpc_id); $security_group_default_values = array_map(static function ($id) { return (string) $id; }, array_keys($security_group_options)); $form['#attached']['drupalSettings']['openstack']['field_openstack_security_group_default_values'] = $security_group_default_values; } // Hide labels of field_tags. $form['tags']['field_tags']['widget']['#title'] = NULL; if (empty($openstack_ec2_service)) { $form['#validate'][] = 'openstack_form_cloud_launch_template_form_validate'; } } /** * Implements hook_form_FORM_ID_alter(). * * @param \Drupal\cloud\Entity\CloudLaunchTemplateInterface $entity * The CloudLaunchTemplate entity. * @param array $form * Array of form object. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. */ private function alterCloudLaunchTemplateEditForm(CloudLaunchTemplateInterface $entity, array &$form, FormStateInterface $form_state) { $this->alterCloudLaunchTemplateCommonForm($entity, $form, $form_state); // Hide new revision checkbox. $form['new_revision']['#access'] = FALSE; // Disable name field. $form['instance']['name']['#disabled'] = TRUE; /** @var \Drupal\Core\Entity\EntityFormInterface $form_object */ $form_object = $form_state->getFormObject(); /** @var \Drupal\cloud\Entity\CloudLaunchTemplateInterface $server_template */ $server_template = $form_object->getEntity(); $cloud_context = $server_template->getCloudContext(); $openstack_service = $this->openStackServiceFactory->isEc2ServiceType('cloud_config', $cloud_context); if (empty($openstack_service)) { // Overwrite function ::save. $form['actions']['submit']['#submit'][1] = 'openstack_form_cloud_launch_template_openstack_edit_form_submit'; } } /** * Submit function for form cloud_launch_template_aws_cloud_edit_form. * * @param \Drupal\cloud\Entity\CloudLaunchTemplateInterface $entity * The CloudLaunchTemplate entity. * @param array $form * Array of form object. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. * * @return bool * TRUE when the process succeeds. */ private function submitCloudLaunchTemplateEditForm(CloudLaunchTemplateInterface $entity, array &$form, FormStateInterface $form_state): bool { /** @var \Drupal\Core\Entity\EntityFormInterface $form_object */ $form_object = $form_state->getFormObject(); /** @var \Drupal\cloud\Entity\CloudLaunchTemplateInterface $server_template */ $server_template = $form_object->getEntity(); $cloud_context = $server_template->getCloudContext(); $form_values = $form_state->getValues(); $uid = $form_values['uid'][0]['target_id'] ?? 0; /** @var \Drupal\openstack\Service\OpenStackServiceInterface|\Drupal\cloud\Service\CloudResourceTagInterface $openstack_service */ $openstack_service = $this->openStackServiceFactory->get($cloud_context); $uid_key_name = $openstack_service->getTagKeyCreatedByUid( 'openstack', $cloud_context, intval($uid) ); $form_tags = ($server_template->hasField('field_tags') && !$server_template->get('field_tags')->isEmpty()) ? $server_template->get('field_tags')->getValue() : []; // Update tags if authored id is changed. foreach ($form_tags ?: [] as $form_tag) { $item_key = $form_tag['item_key']; if ($form_tag['item_key'] === $uid_key_name) { $tags[] = ['item_key' => $item_key, 'item_value' => $uid]; } } $server_template->set('field_tags', $tags); $server_template->save(); $this->processOperationStatus($server_template, 'updated'); $form_state->setRedirect( 'entity.cloud_launch_template.canonical', [ 'cloud_context' => $cloud_context, 'cloud_launch_template' => $server_template->id(), ] ); return TRUE; } }
modules/cloud_service_providers/openstack/src/Service/OpenStackOperationsServiceInterface.php +16 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ use Drupal\aws_cloud\Entity\Ec2\NetworkInterfaceInterface; use Drupal\aws_cloud\Entity\Ec2\SecurityGroupInterface; use Drupal\aws_cloud\Entity\Ec2\SnapshotInterface; use Drupal\aws_cloud\Entity\Ec2\VolumeInterface; use Drupal\cloud\Entity\CloudLaunchTemplateInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\openstack\Entity\OpenStackNetworkExInterface; use Drupal\openstack\Entity\OpenStackPortInterface; Loading Loading @@ -730,4 +731,19 @@ interface OpenStackOperationsServiceInterface { */ public function detachOpenStackVolume(VolumeInterface $entity, array &$form, FormStateInterface $form_state): bool; /** * Edit an OpenStack CloudLaunchTemplate. * * @param \Drupal\cloud\Entity\CloudLaunchTemplateInterface $entity * The CloudLaunchTemplate entity. * @param array $form * Array of form object. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. * * @return bool * TRUE when the process succeeds. */ public function editOpenStackCloudLaunchTemplate(CloudLaunchTemplateInterface $entity, array &$form, FormStateInterface $form_state): bool; }