Skip to content
Snippets Groups Projects
Commit 260e2637 authored by xiaohua guan's avatar xiaohua guan Committed by Yas Naoi
Browse files

Issue #3308974 by Xiaohua Guan, yas: Create entity type OpenStack Network

parent e6bc356f
No related branches found
No related tags found
No related merge requests found
Showing
with 1055 additions and 1 deletion
......@@ -1446,3 +1446,10 @@ function openstack_update_8259() {
], 'openstack');
drupal_flush_all_caches();
}
/**
* Add entity type openstack_network.
*/
function openstack_update_8260() {
openstack_add_entity_type('openstack_network');
}
......@@ -227,6 +227,35 @@ delete own openstack network interface:
title: 'Delete own OpenStack network interface'
description: 'Allow users to delete own network interface.'
####################
# Networks
####################
add openstack network:
title: 'Add OpenStack network'
description: 'Allow users to add network.'
list openstack network:
title: 'List OpenStack network'
description: 'Allow users to list network.'
view any openstack network:
title: 'View any OpenStack network'
description: 'Allow users to view any network.'
edit any openstack network:
title: 'Edit any OpenStack network'
description: 'Allow users to edit any network.'
delete any openstack network:
title: 'Delete any OpenStack network'
description: 'Allow users to delete any network.'
view own openstack network:
title: 'View own OpenStack network'
description: 'Allow users to view own network.'
edit own openstack network:
title: 'Edit own OpenStack network'
description: 'Allow users to edit own network.'
delete own openstack network:
title: 'Delete own OpenStack network'
description: 'Allow users to delete own network.'
#############
# Floating IP
#############
......
......@@ -1029,3 +1029,23 @@ entity.openstack_volume.instances:
command: attach
requirements:
_custom_access: '\Drupal\openstack\Controller\ApiController::access'
entity.openstack_network.list_update:
path: '/clouds/openstack/{cloud_context}/network/update'
defaults:
_controller: '\Drupal\openstack\Controller\ApiController::updateNetworkList'
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 openstack network+edit own openstack network'
entity.openstack_network.list_update.all:
path: '/clouds/openstack/network/update'
defaults:
_controller: '\Drupal\openstack\Controller\ApiController::updateNetworkList'
requirements:
_custom_access: '\Drupal\cloud\Controller\CloudConfigController::checkAccessForUpdateAll'
options:
entity_type: 'openstack_network'
......@@ -324,6 +324,19 @@ class ApiController extends ControllerBase implements ApiControllerInterface {
return $this->updateResourceList('openstack_network_interface', $cloud_context);
}
/**
* Update networks.
*
* @param string $cloud_context
* Cloud context string.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* Redirect to network list.
*/
public function updateNetworkList($cloud_context = ''): RedirectResponse {
return $this->updateResourceList('openstack_network', $cloud_context);
}
/**
* Update floating ips.
*
......
<?php
namespace Drupal\openstack\Controller;
use Drupal\cloud\Traits\AccessCheckTrait;
use Drupal\cloud\Traits\CloudContentEntityTrait;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Access controller for the Network entity.
*
* @see \Drupal\openstack\Entity\Entity\OpenStackNetwork.
*/
class OpenStackNetworkAccessControlHandler extends EntityAccessControlHandler {
use AccessCheckTrait;
use CloudContentEntityTrait;
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account): AccessResultInterface {
// Get cloud service provider name.
$cloud_name = $this->getModuleNameWithWhitespace($entity);
switch ($operation) {
case 'view':
return $this->allowedIfCanAccessCloudConfigWithOwner(
$entity,
$account,
"view own {$cloud_name} network",
"view any {$cloud_name} network",
TRUE
);
}
// Unknown operation, no opinion.
return AccessResult::neutral();
}
}
<?php
namespace Drupal\openstack\Entity;
use Drupal\cloud\Entity\CloudContentEntityBase;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
/**
* Defines the OpenStack Network entity.
*
* @ingroup openstack
*
* @ContentEntityType(
* id = "openstack_network",
* id_plural = "openstack_networks",
* label = @Translation("Network"),
* label_collection = @Translation("Networks"),
* label_singular = @Translation("Network"),
* label_plural = @Translation("Networks"),
* handlers = {
* "view_builder" = "Drupal\openstack\Entity\OpenStackNetworkViewBuilder",
* "list_builder" = "Drupal\cloud\Controller\CloudContentListBuilder",
* "views_data" = "Drupal\openstack\Entity\OpenStackNetworkViewsData",
*
* "form" = {
* "default" = "Drupal\openstack\Form\OpenStackNetworkEditForm",
* "add" = "Drupal\openstack\Form\OpenStackNetworkCreateForm",
* "edit" = "Drupal\openstack\Form\OpenStackNetworkEditForm",
* "delete" = "Drupal\openstack\Form\OpenStackNetworkDeleteForm",
* "delete-multiple-confirm" = "Drupal\openstack\Form\OpenStackNetworkDeleteMultipleForm",
* },
* "route_provider" = {
* "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
* },
* "access" = "Drupal\openstack\Controller\NetworkAccessControlHandler",
* },
* base_table = "openstack_network",
* admin_permission = "administer openstack network",
* fieldable = TRUE,
* entity_keys = {
* "id" = "id",
* "label" = "name",
* "uuid" = "uuid",
* },
* links = {
* "canonical" = "/clouds/openstack/{cloud_context}/network/{openstack_network}",
* "edit-form" = "/clouds/openstack/{cloud_context}/network/{openstack_network}/edit",
* "delete-form" = "/clouds/openstack/{cloud_context}/network/{openstack_network}/delete",
* "collection" = "/clouds/openstack/{cloud_context}/network",
* "delete-multiple-form" = "/clouds/openstack/{cloud_context}/network/delete_multiple",
* },
* field_ui_base_route = "openstack_network.settings"
* )
*/
class OpenStackNetwork extends CloudContentEntityBase implements OpenStackNetworkExInterface {
/**
* {@inheritdoc}
*/
public function getNetworkId(): ?string {
return $this->get('network_id')->value;
}
/**
* {@inheritdoc}
*/
public function setNetworkId($network_id = ''): OpenStackNetworkExInterface {
return $this->set('network_id', $network_id);
}
/**
* {@inheritdoc}
*/
public function getName(): ?string {
return $this->get('name')->value;
}
/**
* {@inheritdoc}
*/
public function setName($name = ''): OpenStackNetworkExInterface {
return $this->set('name', $name);
}
/**
* {@inheritdoc}
*/
public function getProjectId(): ?string {
return $this->get('project_id')->value;
}
/**
* {@inheritdoc}
*/
public function setProjectId($project_id = ''): OpenStackNetworkExInterface {
return $this->set('project_id', $project_id);
}
/**
* {@inheritdoc}
*/
public function setStatus($status = ''): OpenStackNetworkExInterface {
return $this->set('status', $status);
}
/**
* {@inheritdoc}
*/
public function getStatus(): ?string {
return $this->get('status')->value;
}
/**
* {@inheritdoc}
*/
public function getAdminStateUp(): bool {
return $this->get('admin_state_up')->value;
}
/**
* {@inheritdoc}
*/
public function setAdminStateUp(bool $admin_state_up): OpenStackNetworkExInterface {
return $this->set('admin_state_up', $admin_state_up);
}
/**
* {@inheritdoc}
*/
public function getShared(): bool {
return $this->get('shared')->value;
}
/**
* {@inheritdoc}
*/
public function setShared(bool $shared): OpenStackNetworkExInterface {
return $this->set('shared', $shared);
}
/**
* {@inheritdoc}
*/
public function getExternal(): bool {
return $this->get('external')->value;
}
/**
* {@inheritdoc}
*/
public function setExternal(bool $external): OpenStackNetworkExInterface {
return $this->set('external', $external);
}
/**
* {@inheritdoc}
*/
public function setMtu($mtu = ''): OpenStackNetworkExInterface {
return $this->set('mtu', $mtu);
}
/**
* {@inheritdoc}
*/
public function getMtu(): ?int {
return $this->get('mtu')->value;
}
/**
* {@inheritdoc}
*/
public function setNetworkType($network_type = ''): OpenStackNetworkExInterface {
return $this->set('network_type', $network_type);
}
/**
* {@inheritdoc}
*/
public function getNetworkType(): ?string {
return $this->get('network_type')->value;
}
/**
* {@inheritdoc}
*/
public function setPhysicalNetwork($physical_network = ''): OpenStackNetworkExInterface {
return $this->set('physical_network', $physical_network);
}
/**
* {@inheritdoc}
*/
public function getPhysicalNetwork(): ?string {
return $this->get('physical_network')->value;
}
/**
* {@inheritdoc}
*/
public function setSegmentationId($segmentation_id = ''): OpenStackNetworkExInterface {
return $this->set('segmentation_id', $segmentation_id);
}
/**
* {@inheritdoc}
*/
public function getSegmentationId(): ?int {
return $this->get('segmentation_id')->value;
}
/**
* {@inheritdoc}
*/
public function setAvailabilityZones(array $availability_zones): OpenStackNetworkExInterface {
return $this->set('availability_zones', $availability_zones);
}
/**
* {@inheritdoc}
*/
public function getAvailabilityZones(): array {
return $this->get('availability_zones');
}
/**
* {@inheritdoc}
*/
public function setSubnets(array $subnets): OpenStackNetworkExInterface {
return $this->set('subnets', $subnets);
}
/**
* {@inheritdoc}
*/
public function getSubnets(): array {
return $this->get('subnets');
}
/**
* {@inheritdoc}
*/
public function getRefreshed(): int {
return $this->get('refreshed')->value;
}
/**
* {@inheritdoc}
*/
public function setRefreshed($time): OpenStackNetworkExInterface {
return $this->set('refreshed', $time);
}
/**
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type): array {
$fields['id'] = BaseFieldDefinition::create('integer')
->setLabel(t('ID'))
->setDescription(t('The ID of the Network entity.'))
->setReadOnly(TRUE);
$fields['uuid'] = BaseFieldDefinition::create('uuid')
->setLabel(t('UUID'))
->setDescription(t('The UUID of the Network entity.'))
->setReadOnly(TRUE);
$fields['cloud_context'] = BaseFieldDefinition::create('string')
->setRequired(TRUE)
->setLabel(t('Cloud service provider ID'))
->setDescription(t('A unique ID for the cloud service provider.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
]);
$fields['network_id'] = BaseFieldDefinition::create('string')
->setLabel(t('Network ID'))
->setDescription(t('The ID of the network.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['name'] = BaseFieldDefinition::create('string')
->setLabel(t('Name'))
->setDescription(t('The name of network.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['project_id'] = BaseFieldDefinition::create('string')
->setLabel(t('Project ID'))
->setDescription(t('The ID of project.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['status'] = BaseFieldDefinition::create('string')
->setLabel(t('Status'))
->setDescription(t('The status of network.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['admin_state_up'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Admin State'))
->setDescription(t('The administrative state of the network, which is up (true) or down (false).'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['shared'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Shared'))
->setDescription(t('Indicates whether this network is shared across all tenants. By default, only administrative users can change this value.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['external'] = BaseFieldDefinition::create('boolean')
->setLabel(t('External'))
->setDescription(t('Defines whether the network may be used for creation of floating IPs.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['mtu'] = BaseFieldDefinition::create('integer')
->setLabel(t('MTU'))
->setDescription(t('The maximum transmission unit (MTU) value to address fragmentation. Minimum value is 68 for IPv4, and 1280 for IPv6.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['network_type'] = BaseFieldDefinition::create('string')
->setLabel(t('Network Type'))
->setDescription(t('The type of physical network that this network is mapped to. For example, flat, vlan, vxlan, or gre. Valid values depend on a networking back-end.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['physical_network'] = BaseFieldDefinition::create('string')
->setLabel(t('Physical Network'))
->setDescription(t('The physical network where this network/segment is implemented.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['segmentation_id'] = BaseFieldDefinition::create('integer')
->setLabel(t('Segmentation ID'))
->setDescription(t('The ID of the isolated segment on the physical network. The network_type attribute defines the segmentation model.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['subnets'] = BaseFieldDefinition::create('string')
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setLabel(t('Subnets'))
->setDescription(t('The associated subnets.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['availability_zones'] = BaseFieldDefinition::create('string')
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setLabel(t('Availability Zones'))
->setDescription(t('The availability zones for the network.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'string',
'weight' => -5,
])
->setReadOnly(TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('When the entity was created.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'timestamp',
'weight' => -5,
'settings' => [
'date_format' => 'short',
],
]);
$fields['changed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Changed'))
->setDescription(t('The time that the entity was last edited.'));
$fields['refreshed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Refreshed'))
->setDescription(t('The time that the entity was last refreshed.'));
$fields['uid'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Authored by'))
->setDescription(t('Enter the user ID of the Network entity author.'))
->setRevisionable(TRUE)
->setSetting('target_type', 'user')
->setSetting('handler', 'default')
->setDefaultValueCallback('Drupal\node\Entity\Node::getCurrentUserId')
->setTranslatable(TRUE)
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'author',
'weight' => 0,
])
->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
'weight' => 5,
'settings' => [
'match_operator' => 'CONTAINS',
'match_limit' => 10,
'size' => '60',
'autocomplete_type' => 'tags',
'placeholder' => '',
],
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
return $fields;
}
}
<?php
namespace Drupal\openstack\Entity;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\user\EntityOwnerInterface;
/**
* Provides an interface defining an OpenStackNetwork entity.
*
* @ingroup openstack
*/
interface OpenStackNetworkExInterface extends ContentEntityInterface, EntityOwnerInterface {
/**
* {@inheritdoc}
*/
public function getCloudContext(): ?string;
/**
* {@inheritdoc}
*/
public function getNetworkId(): ?string;
/**
* {@inheritdoc}
*/
public function setNetworkId($network_id = ''): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function getName(): ?string;
/**
* {@inheritdoc}
*/
public function setName($name = ''): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function getProjectId(): ?string;
/**
* {@inheritdoc}
*/
public function setProjectId($project_id = ''): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function setStatus($status = ''): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function getStatus(): ?string;
/**
* {@inheritdoc}
*/
public function getAdminStateUp(): bool;
/**
* {@inheritdoc}
*/
public function setAdminStateUp(bool $admin_state_up): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function getShared(): bool;
/**
* {@inheritdoc}
*/
public function setShared(bool $shared): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function getExternal(): bool;
/**
* {@inheritdoc}
*/
public function setExternal(bool $external): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function setMtu($mtu = ''): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function getMtu(): ?int;
/**
* {@inheritdoc}
*/
public function setNetworkType($network_type = ''): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function getNetworkType(): ?string;
/**
* {@inheritdoc}
*/
public function setPhysicalNetwork($physical_network = ''): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function getPhysicalNetwork(): ?string;
/**
* {@inheritdoc}
*/
public function setSegmentationId($segmentation_id = ''): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function getSegmentationId(): ?int;
/**
* {@inheritdoc}
*/
public function setAvailabilityZones(array $availability_zones): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function getAvailabilityZones(): array;
/**
* {@inheritdoc}
*/
public function setSubnets(array $subnets): OpenStackNetworkExInterface;
/**
* {@inheritdoc}
*/
public function getSubnets(): array;
/**
* {@inheritdoc}
*/
public function created();
/**
* {@inheritdoc}
*/
public function changed();
/**
* {@inheritdoc}
*/
public function getRefreshed(): int;
/**
* {@inheritdoc}
*/
public function setRefreshed($time): OpenStackNetworkExInterface;
}
<?php
namespace Drupal\openstack\Entity;
use Drupal\aws_cloud\Entity\Ec2\AwsCloudViewBuilder;
/**
* Provides the network view builders.
*/
class OpenStackNetworkViewBuilder extends AwsCloudViewBuilder {
/**
* {@inheritdoc}
*/
protected function getFieldsetDefs(): array {
return [
[
'name' => 'network',
'title' => $this->t('Network'),
'open' => TRUE,
'fields' => [
'flavor_id',
'name',
'created',
],
],
[
'name' => 'others',
'title' => $this->t('Others'),
'open' => FALSE,
'fields' => [
'cloud_context',
'uid',
],
],
];
}
}
<?php
namespace Drupal\openstack\Entity;
use Drupal\aws_cloud\Entity\Ec2\AwsCloudViewsData;
/**
* Provides the views data for the Network entity type.
*/
class OpenStackNetworkViewsData extends AwsCloudViewsData {
/**
* {@inheritdoc}
*/
public function getViewsData(): array {
$data = parent::getViewsData();
$table_name = $this->storage->getEntityTypeId();
$fields = $this->getFieldStorageDefinitions($table_name);
$data[$table_name]['network_bulk_form'] = [
'title' => $this->t('Network operations bulk form'),
'help' => $this->t('Add a form element that lets you run operations on multiple networks.'),
'field' => [
'id' => 'network_bulk_form',
],
];
// The following is a list of fields to turn from text search to
// select list. This list can be expanded through hook_views_data_alter().
$selectable = [];
$this->addDropdownSelector($data, $table_name, $fields, $selectable);
return $data;
}
}
......@@ -12,6 +12,7 @@ use Drupal\openstack\Entity\OpenStackSecurityGroup;
use Drupal\openstack\Entity\OpenStackVolume;
use Drupal\openstack\Entity\OpenStackSnapshot;
use Drupal\openstack\Entity\OpenStackNetworkInterface;
use Drupal\openstack\Entity\OpenStackNetwork;
use Drupal\openstack\Entity\OpenStackFloatingIp;
use Drupal\openstack\Service\Rest\OpenStackService as OpenStackRestService;
......@@ -723,6 +724,80 @@ class OpenStackBatchOperations {
}
}
/**
* Update or create a network entity.
*
* @param string $cloud_context
* The cloud context.
* @param array $network
* The network interface array.
*/
public static function updateNetwork(string $cloud_context, array $network): void {
/** @var \Drupal\openstack\Service\OpenStackServiceInterface $openstack_service */
$openstack_service = \Drupal::service('openstack.factory')->get($cloud_context);
$timestamp = time();
// The tag key of the network is 'TagSet'.
// So changing the key to align to other entities.
// If this key changes to 'Tags' on OpenStack API, this block needs to be
// deleted.
if (!empty($network['TagSet'])) {
$network['Tags'] = $network['TagSet'];
}
$network_name = $network['Name'] ?? $network['NetworkId'];
$name = $openstack_service->getTagName($network, $network_name);
$uid = $openstack_service->getUidTagValue($network, 'openstack_network');
$entity_id = \Drupal::service('cloud')->getEntityId($cloud_context, 'openstack_network', 'network_id', $network['NetworkId']);
// Skip if $entity already exists, by updating 'refreshed' time.
if (!empty($entity_id)) {
/** @var \Drupal\openstack\Entity\Network $entity */
$entity = OpenStackNetwork::load($entity_id);
$entity->setName($name ?? $network['NetworkId']);
$entity->setNetworkId($network['NetworkId']);
$entity->setProjectId($network['ProjectId']);
$entity->setStatus($network['Status']);
$entity->setAdminStateUp(!empty($network['AdminStateUp']));
$entity->setShared(!empty($network['Shared']));
$entity->setExternal(!empty($network['External']));
$entity->setMtu($network['Mtu']);
$entity->setNetworkType($network['NetworkType']);
$entity->setPhysicalNetwork($network['PhysicalNetwork']);
$entity->setSegmentationId($network['SegmentationId']);
$entity->setSubnets($network['Subnets']);
$entity->setAvailabilityZones($network['AvailabilityZones']);
$entity->setOwnerById($uid > 0 ? $uid : 0);
$entity->setRefreshed($timestamp);
$entity->save();
}
else {
$entity = OpenStackNetwork::create([
'cloud_context' => $cloud_context,
'name' => $name ?? $network['NetworkId'],
'network_id' => $network['NetworkId'],
'project_id' => $network['ProjectId'],
'status' => $network['Status'],
'admin_state_up' => !empty($network['AdminStateUp']),
'shared' => !empty($network['Shared']),
'external' => !empty($network['External']),
'mtu' => $network['Mtu'],
'network_type' => $network['NetworkType'],
'physical_network' => $network['PhysicalNetwork'],
'segmentation_id' => $network['SegmentationId'],
'subnets' => $network['Subnets'],
'availability_zones' => $network['AvailabilityZones'],
'created' => $timestamp,
'changed' => $timestamp,
'refreshed' => $timestamp,
'uid' => $uid,
]);
$entity->save();
}
}
/**
* Update or create a Floating IP entity.
*
......
......@@ -244,7 +244,7 @@ class OpenStackService extends CloudServiceBase implements OpenStackServiceInter
$body = [
'auth' => [
'identity' => [
'methods' => [0 => 'password'],
'methods' => ['password'],
'password' => [
'user' => [
'name' => $this->credentials['username'],
......@@ -2383,6 +2383,66 @@ class OpenStackService extends CloudServiceBase implements OpenStackServiceInter
return $results;
}
/**
* Get network list.
*
* @param array $params
* Parameters to pass to the API.
*
* @return array
* The network list API response.
*/
public function describeNetworks(array $params = []) {
if ($this->isWorkerResource()) {
return ['SendToWorker' => TRUE];
}
$project_id = $params['project_id'];
$this->loadCredentials();
$credentials = [
'http_method' => 'get',
'endpoint' => $this->getEndpoint(OpenStackServiceInterface::NETWORK_ENDPOINT, '/networks'),
'params' => $params,
];
$response = $this->getClient($credentials);
$networks = $response['body']['networks'] ?? [];
$results['Networks'] = [];
foreach ($networks ?: [] as $network) {
if ($network['project_id'] !== $project_id && empty($network['shared'])) {
continue;
}
$subnets = [];
foreach ($network['subnets'] ?: [] as $subnet_id) {
$subnet_result = $this->describeSubnetDetail(['SubnetId' => $subnet_id]);
$subnets[] = $subnet_result['name'];
}
$results['Networks'][] = [
'NetworkId' => $network['id'] ?? NULL,
'Name' => $network['name'] ?? NULL,
'ProjectId' => $network['project_id'],
'Status' => $network['status'] === 'ACTIVE' ? 'available' : '',
'AdminStateUp' => $network['admin_state_up'] ?? FALSE,
'SubnetId' => $subnet_names ?? NULL,
'TagSet' => empty($network['tags']) ? [] : $network['tags'],
'External' => $network['router:external'],
'Shared' => $network['shared'],
'Mtu' => $network['mtu'],
'NetworkType' => $network['provider:network_type'],
'PhysicalNetwork' => $network['provider:physical_network'],
'SegmentationId' => $network['provider:segmentation_id'],
'Subnets' => $subnets,
'AvailabilityZones' => $network['availability_zones'],
];
}
return $results;
}
/**
* Create network interface.
*
......@@ -3601,6 +3661,101 @@ class OpenStackService extends CloudServiceBase implements OpenStackServiceInter
return $updated;
}
/**
* Update the OpenStackNetworks.
*
* @param array $params
* Optional parameters array.
* @param bool $clear
* TRUE to clear stale security groups.
*
* @return bool
* indicates success so failure.
*/
public function updateNetworks(array $params = [], $clear = TRUE): bool {
$entity_type = 'openstack_network';
$lock_name = $this->getLockKey($entity_type);
if (!$this->lock->acquire($lock_name)) {
return FALSE;
}
$updated = $this->updateNetworkEntities($params, $clear, $entity_type, $this->cloudContext);
$this->lock->release($lock_name);
return $updated;
}
/**
* Call API for updated entities and store them as Network entities.
*
* @param array $params
* Optional parameters array.
* @param bool $clear
* TRUE to clear stale security groups.
* @param string $entity_type
* Entity type string.
* @param string $cloud_context
* Cloud context string.
* @param bool $update
* TRUE to update info.
*
* @return bool
* indicates success so failure.
*/
public function updateNetworkEntities(array $params = [], $clear = TRUE, $entity_type = '', $cloud_context = '', $update = TRUE): bool {
if ($this->isWorkerResource()) {
return TRUE;
}
$cloud_configs = $this->entityTypeManager
->getStorage('cloud_config')
->loadByProperties([
'type' => 'openstack',
'cloud_context' => $cloud_context,
]);
/** @var \Drupal\cloud\Entity\CloudConfig $cloud_config */
$cloud_config = array_shift($cloud_configs);
$params['project_id'] = $cloud_config->get('field_project_id')->value ?? NULL;
$updated = FALSE;
$result = $this->describeNetworks($params);
if (!empty($result)) {
$all_networks = $this->cloudService->loadAllEntities($this->cloudContext, $entity_type);
$stale = [];
foreach ($all_networks ?: [] as $network) {
$stale[$network->getNetworkId()] = $network;
}
/** @var \Drupal\Core\Batch\BatchBuilder $batch_builder */
$batch_builder = $this->initBatch('Network update');
foreach ($result['Networks'] ?: [] as $network) {
// Keep track of networks that do not exist anymore
// delete them after saving the rest of the networks.
if (!empty($stale[$network['NetworkId']])) {
unset($stale[$network['NetworkId']]);
}
$batch_builder->addOperation([
OpenStackBatchOperations::class,
'updateNetwork',
], [$cloud_context, $network]);
}
$batch_builder->addOperation([
OpenStackBatchOperations::class,
'finished',
], [$entity_type, $stale, $clear]);
$this->runBatch($batch_builder);
$updated = TRUE;
}
return $updated;
}
/**
* Update the OpenStackFloatingIps.
*
......
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