diff --git a/phpunit.sample.xml.dist b/phpunit.sample.xml.dist index d2048c5f3..66bcaecd5 100644 --- a/phpunit.sample.xml.dist +++ b/phpunit.sample.xml.dist @@ -16,7 +16,7 @@ - + diff --git a/phpunit.xml.dist b/phpunit.xml.dist index e77fdd4c3..858afeee0 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -12,7 +12,7 @@ - + diff --git a/samples/Networking/v2/floatingIPs/create.php b/samples/Networking/v2/floatingIPs/create.php index 0880fbdf3..0e7aea991 100644 --- a/samples/Networking/v2/floatingIPs/create.php +++ b/samples/Networking/v2/floatingIPs/create.php @@ -12,7 +12,7 @@ 'scope' => ['project' => ['id' => '{projectId}']], ]); -$networking = $openstack->networkingV2ExtLayer3(); +$networking = $openstack->networkingV2(); $floatingIp = $networking->createFloatingIp([ "floatingNetworkId" => "{networkId}", diff --git a/samples/Networking/v2/floatingIPs/delete.php b/samples/Networking/v2/floatingIPs/delete.php index 9bbe8d0a8..b3fe53b8e 100644 --- a/samples/Networking/v2/floatingIPs/delete.php +++ b/samples/Networking/v2/floatingIPs/delete.php @@ -12,6 +12,7 @@ 'scope' => ['project' => ['id' => '{projectId}']], ]); -$openstack->networkingV2ExtLayer3() - ->getFloatingIp('{id}') - ->delete(); +$networking = $openstack->networkingV2(); +$floatIp = $networking->getFloatingIp('{id}'); + +$floatIp->delete(); diff --git a/samples/Networking/v2/floatingIPs/get.php b/samples/Networking/v2/floatingIPs/get.php index 759a3318d..d9c52ed22 100644 --- a/samples/Networking/v2/floatingIPs/get.php +++ b/samples/Networking/v2/floatingIPs/get.php @@ -12,5 +12,5 @@ 'scope' => ['project' => ['id' => '{projectId}']], ]); -$floatingIp = $openstack->networkingV2ExtLayer3() +$floatingIp = $openstack->networkingV2() ->getFloatingIp('{id}'); diff --git a/samples/Networking/v2/floatingIPs/list.php b/samples/Networking/v2/floatingIPs/list.php index 82065d955..498d064af 100644 --- a/samples/Networking/v2/floatingIPs/list.php +++ b/samples/Networking/v2/floatingIPs/list.php @@ -12,7 +12,7 @@ 'scope' => ['project' => ['id' => '{projectId}']], ]); -$floatingIps = $openstack->networkingV2ExtLayer3() +$floatingIps = $openstack->networkingV2() ->listFloatingIps(); foreach ($floatingIps as $floatingIp) { diff --git a/samples/Networking/v2/floatingIPs/update.php b/samples/Networking/v2/floatingIPs/update.php index 4813006ec..e7bba62ec 100644 --- a/samples/Networking/v2/floatingIPs/update.php +++ b/samples/Networking/v2/floatingIPs/update.php @@ -12,7 +12,7 @@ 'scope' => ['project' => ['id' => '{projectId}']], ]); -$floatingIp = $openstack->networkingV2ExtLayer3() +$floatingIp = $openstack->networkingV2() ->getFloatingIp('{id}'); $floatingIp->portId = '{newPortId}'; diff --git a/samples/Networking/v2/securityGroupRules/create.php b/samples/Networking/v2/securityGroupRules/create.php index 70ac6094f..751c03517 100644 --- a/samples/Networking/v2/securityGroupRules/create.php +++ b/samples/Networking/v2/securityGroupRules/create.php @@ -12,7 +12,7 @@ 'scope' => ['project' => ['id' => '{projectId}']] ]); -$networking = $openstack->networkingV2ExtSecGroups(); +$networking = $openstack->networkingV2(); /** @var \OpenStack\Networking\v2\Extensions\SecurityGroups\Models\SecurityGroupRule $rule */ $rule = $networking->createSecurityGroupRule([ diff --git a/samples/Networking/v2/securityGroupRules/delete.php b/samples/Networking/v2/securityGroupRules/delete.php index 52b56e5f9..99521d39f 100644 --- a/samples/Networking/v2/securityGroupRules/delete.php +++ b/samples/Networking/v2/securityGroupRules/delete.php @@ -13,7 +13,7 @@ ]); /** @var \OpenStack\Networking\v2\Extensions\SecurityGroups\Models\SecurityGroupRule $rule */ -$rule = $openstack->networkingV2ExtSecGroups() +$rule = $openstack->networkingV2() ->getSecurityGroupRule('{id}'); $rule->delete(); diff --git a/samples/Networking/v2/securityGroupRules/get.php b/samples/Networking/v2/securityGroupRules/get.php index 085e5acfd..8827700de 100644 --- a/samples/Networking/v2/securityGroupRules/get.php +++ b/samples/Networking/v2/securityGroupRules/get.php @@ -13,5 +13,5 @@ ]); /** @var \OpenStack\Networking\v2\Extensions\SecurityGroups\Models\SecurityGroupRule $rule */ -$rule = $openstack->networkingV2ExtSecGroups() +$rule = $openstack->networkingV2() ->getSecurityGroupRule('{id}'); diff --git a/samples/Networking/v2/securityGroupRules/list.php b/samples/Networking/v2/securityGroupRules/list.php index 1e9cb0341..8c574319d 100644 --- a/samples/Networking/v2/securityGroupRules/list.php +++ b/samples/Networking/v2/securityGroupRules/list.php @@ -16,16 +16,15 @@ 'scope' => ['project' => ['id' => '{projectId}']] ]); -/** @var Service $networkingExtSecGroup */ -$networkingExtSecGroup = $openstack->networkingV2ExtSecGroups(); +$networking = $openstack->networkingV2(); //List all security group rules -foreach ($networkingExtSecGroup->listSecurityGroupRules() as $rule) { +foreach ($networking->listSecurityGroupRules() as $rule) { /** @var SecurityGroupRule $rule */ } /** @var SecurityGroup $securityGroup */ -$securityGroup = $networkingExtSecGroup->getSecurityGroup(['id' => '{uuid}']); +$securityGroup = $networking->getSecurityGroup('{uuid}'); //List rules belong to a security group foreach ($securityGroup->securityGroupRules as $rule) { diff --git a/samples/Networking/v2/securityGroups/create.php b/samples/Networking/v2/securityGroups/create.php index 32ddb0f71..572626d55 100644 --- a/samples/Networking/v2/securityGroups/create.php +++ b/samples/Networking/v2/securityGroups/create.php @@ -12,7 +12,7 @@ 'scope' => ['project' => ['id' => '{projectId}']] ]); -$networking = $openstack->networkingV2ExtSecGroups(); +$networking = $openstack->networkingV2(); /** @var \OpenStack\Networking\v2\Extensions\SecurityGroups\Models\SecurityGroup $secGroup */ $secGroup = $networking->createSecurityGroup([ diff --git a/samples/Networking/v2/securityGroups/delete.php b/samples/Networking/v2/securityGroups/delete.php index 69bb2ba7a..992d813f3 100644 --- a/samples/Networking/v2/securityGroups/delete.php +++ b/samples/Networking/v2/securityGroups/delete.php @@ -12,7 +12,7 @@ 'scope' => ['project' => ['id' => '{projectId}']] ]); -$networking = $openstack->networkingV2ExtSecGroups(); +$networking = $openstack->networkingV2(); /** @var \OpenStack\Networking\v2\Extensions\SecurityGroups\Models\SecurityGroup $secGroup */ $secGroup = $networking->getSecurityGroup('{id}'); diff --git a/samples/Networking/v2/securityGroups/get.php b/samples/Networking/v2/securityGroups/get.php index 26f462783..87c7f51ce 100644 --- a/samples/Networking/v2/securityGroups/get.php +++ b/samples/Networking/v2/securityGroups/get.php @@ -12,7 +12,7 @@ 'scope' => ['project' => ['id' => '{projectId}']] ]); -$networking = $openstack->networkingV2ExtSecGroups(); +$networking = $openstack->networkingV2(); /** @var \OpenStack\Networking\v2\Extensions\SecurityGroups\Models\SecurityGroup $secGroup */ $secGroup = $networking->getSecurityGroup('{id}'); diff --git a/samples/Networking/v2/securityGroups/list.php b/samples/Networking/v2/securityGroups/list.php index 2a423f361..4be1debad 100644 --- a/samples/Networking/v2/securityGroups/list.php +++ b/samples/Networking/v2/securityGroups/list.php @@ -12,7 +12,7 @@ 'scope' => ['project' => ['id' => '{projectId}']] ]); -$networking = $openstack->networkingV2ExtSecGroups(); +$networking = $openstack->networkingV2(); $secGroups = $networking->listSecurityGroups(); diff --git a/src/Common/Service/Builder.php b/src/Common/Service/Builder.php index b9fe72c1f..55fb92bf7 100644 --- a/src/Common/Service/Builder.php +++ b/src/Common/Service/Builder.php @@ -70,8 +70,6 @@ private function getClasses($namespace) * * @param string $namespace The namespace of the service * @param array $serviceOptions The service-specific options to use - * - * @throws \Exception */ public function createService(string $namespace, array $serviceOptions = []): ServiceInterface { diff --git a/src/Networking/v2/Api.php b/src/Networking/v2/Api.php index d4cc0e39e..e9bfc27b7 100644 --- a/src/Networking/v2/Api.php +++ b/src/Networking/v2/Api.php @@ -5,6 +5,8 @@ namespace OpenStack\Networking\v2; use OpenStack\Common\Api\AbstractApi; +use OpenStack\Networking\v2\Extensions\Layer3\ApiTrait as Layer3; +use OpenStack\Networking\v2\Extensions\SecurityGroups\ApiTrait as SecurityGroup; /** * A representation of the Neutron (Nova) v2 REST API. @@ -13,6 +15,9 @@ */ class Api extends AbstractApi { + use Layer3; + use SecurityGroup; + private $pathPrefix = 'v2.0'; public function __construct() diff --git a/src/Networking/v2/Extensions/Layer3/Api.php b/src/Networking/v2/Extensions/Layer3/Api.php index b9ab45172..faab09ac6 100644 --- a/src/Networking/v2/Extensions/Layer3/Api.php +++ b/src/Networking/v2/Extensions/Layer3/Api.php @@ -4,6 +4,11 @@ use OpenStack\Common\Api\AbstractApi; +/** + * @deprecated Use Networking\v2\Api instead + * + * @internal + */ class Api extends AbstractApi { private $pathPrefix = 'v2.0'; diff --git a/src/Networking/v2/Extensions/Layer3/ApiTrait.php b/src/Networking/v2/Extensions/Layer3/ApiTrait.php new file mode 100644 index 000000000..5d7c757ac --- /dev/null +++ b/src/Networking/v2/Extensions/Layer3/ApiTrait.php @@ -0,0 +1,172 @@ + 'POST', + 'path' => $this->pathPrefix.'/floatingips', + 'jsonKey' => 'floatingip', + 'params' => [ + 'tenantId' => $this->params->tenantIdJson(), + 'floatingNetworkId' => $this->params->floatingNetworkIdJson(), + 'fixedIpAddress' => $this->params->fixedIpAddressJson(), + 'floatingIpAddress' => $this->params->floatingIpAddressJson(), + 'portId' => $this->params->portIdJson(), + ], + ]; + } + + public function getFloatingIps(): array + { + return [ + 'method' => 'GET', + 'path' => $this->pathPrefix.'/floatingips', + 'params' => [ + 'tenantId' => $this->params->queryTenantId(), + ], + ]; + } + + public function putFloatingIp(): array + { + return [ + 'method' => 'PUT', + 'path' => $this->pathPrefix.'/floatingips/{id}', + 'jsonKey' => 'floatingip', + 'params' => [ + 'id' => $this->params->idPath(), + 'floatingNetworkId' => $this->notRequired($this->params->floatingNetworkIdJson()), + 'fixedIpAddress' => $this->params->fixedIpAddressJson(), + 'floatingIpAddress' => $this->params->floatingIpAddressJson(), + 'portId' => $this->params->portIdJson(), + ], + ]; + } + + public function getFloatingIp(): array + { + return [ + 'method' => 'GET', + 'path' => $this->pathPrefix.'/floatingips/{id}', + 'params' => [ + 'id' => $this->params->idPath(), + 'portId' => $this->params->portIdJson(), + ], + ]; + } + + public function deleteFloatingIp(): array + { + return [ + 'method' => 'DELETE', + 'path' => $this->pathPrefix.'/floatingips/{id}', + 'params' => [ + 'id' => $this->params->idPath(), + ], + ]; + } + + public function postRouters(): array + { + return [ + 'method' => 'POST', + 'path' => $this->pathPrefix.'/routers', + 'jsonKey' => 'router', + 'params' => [ + 'name' => $this->params->nameJson(), + 'externalGatewayInfo' => $this->params->externalGatewayInfo(), + 'adminStateUp' => $this->params->adminStateUp(), + 'tenantId' => $this->params->tenantId(), + 'distributed' => $this->params->distributedJson(), + 'ha' => $this->params->haJson(), + ], + ]; + } + + public function getRouters(): array + { + return [ + 'method' => 'GET', + 'path' => $this->pathPrefix.'/routers', + 'params' => [ + 'name' => $this->params->queryName(), + 'tenantId' => $this->params->queryTenantId(), + ], + ]; + } + + public function putRouter(): array + { + return [ + 'method' => 'PUT', + 'path' => $this->pathPrefix.'/routers/{id}', + 'jsonKey' => 'router', + 'params' => [ + 'id' => $this->params->idPath(), + 'name' => $this->params->nameJson(), + 'externalGatewayInfo' => $this->params->externalGatewayInfo(), + 'adminStateUp' => $this->params->adminStateUp(), + ], + ]; + } + + public function getRouter(): array + { + return [ + 'method' => 'GET', + 'path' => $this->pathPrefix.'/routers/{id}', + 'params' => [ + 'id' => $this->params->idPath(), + ], + ]; + } + + public function deleteRouter(): array + { + return [ + 'method' => 'DELETE', + 'path' => $this->pathPrefix.'/routers/{id}', + 'params' => [ + 'id' => $this->params->idPath(), + ], + ]; + } + + public function putAddInterface(): array + { + return [ + 'method' => 'PUT', + 'path' => $this->pathPrefix.'/routers/{id}/add_router_interface', + 'params' => [ + 'id' => $this->params->idPath(), + 'subnetId' => $this->params->subnetId(), + 'portId' => $this->params->portIdJson(), + ], + ]; + } + + public function putRemoveInterface(): array + { + return [ + 'method' => 'PUT', + 'path' => $this->pathPrefix.'/routers/{id}/remove_router_interface', + 'params' => [ + 'id' => $this->params->idPath(), + 'subnetId' => $this->params->subnetId(), + 'portId' => $this->params->portIdJson(), + ], + ]; + } +} diff --git a/src/Networking/v2/Extensions/Layer3/Models/FloatingIp.php b/src/Networking/v2/Extensions/Layer3/Models/FloatingIp.php index 07dc0ddba..048b942b2 100644 --- a/src/Networking/v2/Extensions/Layer3/Models/FloatingIp.php +++ b/src/Networking/v2/Extensions/Layer3/Models/FloatingIp.php @@ -51,6 +51,9 @@ class FloatingIp extends OperatorResource implements Listable, Creatable, Retrie protected $resourceKey = 'floatingip'; protected $resourcesKey = 'floatingips'; + /** + * {@inheritdoc} + */ public function create(array $userOptions): Creatable { $response = $this->execute($this->api->postFloatingIps(), $userOptions); diff --git a/src/Networking/v2/Extensions/Layer3/Models/Router.php b/src/Networking/v2/Extensions/Layer3/Models/Router.php index 883c46e8a..6fcb9a265 100644 --- a/src/Networking/v2/Extensions/Layer3/Models/Router.php +++ b/src/Networking/v2/Extensions/Layer3/Models/Router.php @@ -54,6 +54,9 @@ protected function getAliases(): array ]; } + /** + * {@inheritdoc} + */ public function create(array $userOptions): Creatable { $response = $this->execute($this->api->postRouters(), $userOptions); diff --git a/src/Networking/v2/Extensions/Layer3/Params.php b/src/Networking/v2/Extensions/Layer3/Params.php index b94abd7e3..d502f61cd 100644 --- a/src/Networking/v2/Extensions/Layer3/Params.php +++ b/src/Networking/v2/Extensions/Layer3/Params.php @@ -2,9 +2,14 @@ namespace OpenStack\Networking\v2\Extensions\Layer3; +/** + * @deprecated Use Networking\v2\Params instead + * + * @internal + */ class Params extends \OpenStack\Networking\v2\Params { - public function tenantIdJson() + public function tenantIdJson(): array { return [ 'type' => self::STRING_TYPE, @@ -13,7 +18,7 @@ public function tenantIdJson() ]; } - public function floatingNetworkIdJson() + public function floatingNetworkIdJson(): array { return [ 'type' => self::STRING_TYPE, @@ -23,7 +28,7 @@ public function floatingNetworkIdJson() ]; } - public function fixedIpAddressJson() + public function fixedIpAddressJson(): array { return [ 'type' => self::STRING_TYPE, @@ -32,7 +37,7 @@ public function fixedIpAddressJson() ]; } - public function floatingIpAddressJson() + public function floatingIpAddressJson(): array { return [ 'type' => self::STRING_TYPE, @@ -41,7 +46,7 @@ public function floatingIpAddressJson() ]; } - public function portIdJson() + public function portIdJson(): array { return [ 'type' => self::STRING_TYPE, diff --git a/src/Networking/v2/Extensions/Layer3/ParamsTrait.php b/src/Networking/v2/Extensions/Layer3/ParamsTrait.php new file mode 100644 index 000000000..c201a82e7 --- /dev/null +++ b/src/Networking/v2/Extensions/Layer3/ParamsTrait.php @@ -0,0 +1,112 @@ + self::STRING_TYPE, + 'description' => 'The UUID of the network associated with the floating IP.', + 'sentAs' => 'floating_network_id', + 'required' => true, + ]; + } + + public function fixedIpAddressJson(): array + { + return [ + 'type' => self::STRING_TYPE, + 'description' => 'The fixed IP address that is associated with the floating IP. To associate the floating IP with a fixed IP at creation time, you must specify the identifier of the internal port. If an internal port has multiple associated IP addresses, the service chooses the first IP address unless you explicitly define a fixed IP address in the fixed_ip_address parameter.', + 'sentAs' => 'fixed_ip_address', + ]; + } + + public function floatingIpAddressJson(): array + { + return [ + 'type' => self::STRING_TYPE, + 'description' => 'The floating IP address.', + 'sentAs' => 'floating_ip_address', + ]; + } + + public function portIdJson(): array + { + return [ + 'type' => self::STRING_TYPE, + 'description' => 'The UUID of the port.', + 'sentAs' => 'port_id', + ]; + } + + public function enableSnatJson(): array + { + return [ + 'type' => self::BOOL_TYPE, + 'description' => 'Enable Source NAT (SNAT) attribute, a part of ext-gw-mode extension. When a gateway is attached to a router using an L3 extension, Network Address Translation (NAT) is enabled for traffic generated by subnets attached to the router.', + 'location' => self::JSON, + 'sentAs' => 'enable_snat', + ]; + } + + public function ipJson(): array + { + return [ + 'type' => self::STRING_TYPE, + ]; + } + + public function externalFixedIpsJson(): array + { + return [ + 'type' => self::ARRAY_TYPE, + 'location' => self::JSON, + 'sentAs' => 'external_fixed_ips', + 'items' => [ + 'type' => self::OBJECT_TYPE, + 'properties' => [ + 'subnetId' => $this->subnetId(), + 'ip' => $this->ipJson(), + ], + ], + ]; + } + + public function externalGatewayInfo(): array + { + return [ + 'type' => self::OBJECT_TYPE, + 'sentAs' => 'external_gateway_info', + 'properties' => [ + 'networkId' => $this->networkId(), + 'enableSnat' => $this->enableSnatJson(), + 'fixedIps' => $this->externalFixedIpsJson(), + ], + ]; + } + + public function distributedJson(): array + { + return [ + 'type' => self::BOOL_TYPE, + 'location' => self::JSON, + 'description' => 'If true, indicates a distributed router.', + ]; + } + + public function haJson(): array + { + return [ + 'type' => self::BOOL_TYPE, + 'location' => self::JSON, + 'description' => 'If true, indicates a highly-available router.', + ]; + } +} diff --git a/src/Networking/v2/Extensions/Layer3/Service.php b/src/Networking/v2/Extensions/Layer3/Service.php index c033c4b7f..6d5458094 100644 --- a/src/Networking/v2/Extensions/Layer3/Service.php +++ b/src/Networking/v2/Extensions/Layer3/Service.php @@ -8,6 +8,8 @@ /** * @property Api $api + * + * @deprecated Use Networking\v2\Service instead */ class Service extends AbstractService { diff --git a/src/Networking/v2/Extensions/Layer3/ServiceTrait.php b/src/Networking/v2/Extensions/Layer3/ServiceTrait.php new file mode 100644 index 000000000..785fca67b --- /dev/null +++ b/src/Networking/v2/Extensions/Layer3/ServiceTrait.php @@ -0,0 +1,62 @@ +model(FloatingIp::class, $info); + } + + private function router(array $info = []): Router + { + return $this->model(Router::class, $info); + } + + public function createFloatingIp(array $options): FloatingIp + { + return $this->floatingIp()->create($options); + } + + public function getFloatingIp($id): FloatingIp + { + return $this->floatingIp(['id' => $id]); + } + + /** + * @return \Generator + */ + public function listFloatingIps(array $options = []): \Generator + { + return $this->floatingIp()->enumerate($this->api->getFloatingIps(), $options); + } + + public function createRouter(array $options): Router + { + return $this->router()->create($options); + } + + public function getRouter($id): Router + { + return $this->router(['id' => $id]); + } + + /** + * @return \Generator + */ + public function listRouters(array $options = []): \Generator + { + return $this->router()->enumerate($this->api->getRouters(), $options); + } +} diff --git a/src/Networking/v2/Extensions/SecurityGroups/Api.php b/src/Networking/v2/Extensions/SecurityGroups/Api.php index e30ddc242..9f2597f94 100644 --- a/src/Networking/v2/Extensions/SecurityGroups/Api.php +++ b/src/Networking/v2/Extensions/SecurityGroups/Api.php @@ -4,6 +4,11 @@ use OpenStack\Common\Api\AbstractApi; +/** + * @deprecated Use Networking\v2\Api instead + * + * @internal + */ class Api extends AbstractApi { private $pathPrefix = 'v2.0'; diff --git a/src/Networking/v2/Extensions/SecurityGroups/ApiTrait.php b/src/Networking/v2/Extensions/SecurityGroups/ApiTrait.php new file mode 100644 index 000000000..6c7340418 --- /dev/null +++ b/src/Networking/v2/Extensions/SecurityGroups/ApiTrait.php @@ -0,0 +1,158 @@ + 'GET', + 'path' => $this->pathPrefix.'/security-groups', + 'params' => [ + 'tenantId' => $this->params->queryTenantId(), + 'name' => $this->params->filterName(), + ], + ]; + } + + /** + * Returns information about POST security-groups HTTP operation. + */ + public function postSecurityGroups(): array + { + return [ + 'method' => 'POST', + 'path' => $this->pathPrefix.'/security-groups', + 'jsonKey' => 'security_group', + 'params' => [ + 'description' => $this->params->descriptionJson(), + 'name' => $this->params->nameJson(), + ], + ]; + } + + /** + * Returns information about PUT security-groups HTTP operation. + */ + public function putSecurityGroups(): array + { + return [ + 'method' => 'PUT', + 'path' => $this->pathPrefix.'/security-groups/{id}', + 'jsonKey' => 'security_group', + 'params' => [ + 'id' => $this->params->idPath(), + 'description' => $this->params->descriptionJson(), + 'name' => $this->params->nameJson(), + ], + ]; + } + + /** + * Returns information about GET security-groups/{security_group_id} HTTP + * operation. + */ + public function getSecurityGroup(): array + { + return [ + 'method' => 'GET', + 'path' => $this->pathPrefix.'/security-groups/{id}', + 'params' => [ + 'id' => $this->params->idPath(), + ], + ]; + } + + /** + * Returns information about DELETE security-groups/{security_group_id} HTTP + * operation. + */ + public function deleteSecurityGroup(): array + { + return [ + 'method' => 'DELETE', + 'path' => $this->pathPrefix.'/security-groups/{id}', + 'params' => [ + 'id' => $this->params->idPath(), + ], + ]; + } + + /** + * Returns information about GET security-group-rules HTTP operation. + */ + public function getSecurityRules(): array + { + return [ + 'method' => 'GET', + 'path' => $this->pathPrefix.'/security-group-rules', + 'params' => [], + ]; + } + + /** + * Returns information about POST security-group-rules HTTP operation. + */ + public function postSecurityRules(): array + { + return [ + 'method' => 'POST', + 'path' => $this->pathPrefix.'/security-group-rules', + 'jsonKey' => 'security_group_rule', + 'params' => [ + 'direction' => $this->params->directionJson(), + 'ethertype' => $this->params->ethertypeJson(), + 'securityGroupId' => $this->params->securityGroupIdJson(), + 'portRangeMin' => $this->params->portRangeMinJson(), + 'portRangeMax' => $this->params->portRangeMaxJson(), + 'protocol' => $this->params->protocolJson(), + 'remoteGroupId' => $this->params->remoteGroupIdJson(), + 'remoteIpPrefix' => $this->params->remoteIpPrefixJson(), + 'tenantId' => $this->params->tenantIdJson(), + ], + ]; + } + + /** + * Returns information about DELETE + * security-group-rules/{rules-security-groups-id} HTTP operation. + */ + public function deleteSecurityRule(): array + { + return [ + 'method' => 'DELETE', + 'path' => $this->pathPrefix.'/security-group-rules/{id}', + 'params' => [ + 'id' => $this->params->idPath(), + ], + ]; + } + + /** + * Returns information about GET + * security-group-rules/{rules-security-groups-id} HTTP operation. + */ + public function getSecurityRule(): array + { + return [ + 'method' => 'GET', + 'path' => $this->pathPrefix.'/security-group-rules/{id}', + 'params' => [ + 'id' => $this->params->idPath(), + ], + ]; + } +} diff --git a/src/Networking/v2/Extensions/SecurityGroups/Models/SecurityGroup.php b/src/Networking/v2/Extensions/SecurityGroups/Models/SecurityGroup.php index 215fad49d..1b09a2e4d 100644 --- a/src/Networking/v2/Extensions/SecurityGroups/Models/SecurityGroup.php +++ b/src/Networking/v2/Extensions/SecurityGroups/Models/SecurityGroup.php @@ -59,6 +59,9 @@ protected function getAliases(): array ]; } + /** + * {@inheritdoc} + */ public function create(array $userOptions): Creatable { $response = $this->execute($this->api->postSecurityGroups(), $userOptions); diff --git a/src/Networking/v2/Extensions/SecurityGroups/Models/SecurityGroupRule.php b/src/Networking/v2/Extensions/SecurityGroups/Models/SecurityGroupRule.php index 825a2f518..4d0319dc6 100644 --- a/src/Networking/v2/Extensions/SecurityGroups/Models/SecurityGroupRule.php +++ b/src/Networking/v2/Extensions/SecurityGroups/Models/SecurityGroupRule.php @@ -80,6 +80,9 @@ class SecurityGroupRule extends OperatorResource implements Creatable, Listable, protected $resourcesKey = 'security_group_rules'; + /** + * {@inheritdoc} + */ public function create(array $userOptions): Creatable { $response = $this->execute($this->api->postSecurityRules(), $userOptions); diff --git a/src/Networking/v2/Extensions/SecurityGroups/Params.php b/src/Networking/v2/Extensions/SecurityGroups/Params.php index 88325a73e..ea700511c 100644 --- a/src/Networking/v2/Extensions/SecurityGroups/Params.php +++ b/src/Networking/v2/Extensions/SecurityGroups/Params.php @@ -2,9 +2,14 @@ namespace OpenStack\Networking\v2\Extensions\SecurityGroups; +/** + * @deprecated Use Networking\v2\Params instead + * + * @internal + */ class Params extends \OpenStack\Networking\v2\Params { - public function directionJson() + public function directionJson(): array { return [ 'type' => self::STRING_TYPE, @@ -12,7 +17,7 @@ public function directionJson() ]; } - public function ethertypeJson() + public function ethertypeJson(): array { return [ 'type' => self::STRING_TYPE, @@ -20,7 +25,7 @@ public function ethertypeJson() ]; } - public function idJson() + public function idJson(): array { return [ 'type' => self::STRING_TYPE, @@ -28,7 +33,7 @@ public function idJson() ]; } - public function portRangeMaxJson() + public function portRangeMaxJson(): array { return [ 'type' => self::STRING_TYPE, @@ -37,7 +42,7 @@ public function portRangeMaxJson() ]; } - public function portRangeMinJson() + public function portRangeMinJson(): array { return [ 'sentAs' => 'port_range_min', @@ -46,7 +51,7 @@ public function portRangeMinJson() ]; } - public function protocolJson() + public function protocolJson(): array { return [ 'type' => self::STRING_TYPE, @@ -54,7 +59,7 @@ public function protocolJson() ]; } - public function remoteGroupIdJson() + public function remoteGroupIdJson(): array { return [ 'sentAs' => 'remote_group_id', @@ -63,7 +68,7 @@ public function remoteGroupIdJson() ]; } - public function remoteIpPrefixJson() + public function remoteIpPrefixJson(): array { return [ 'sentAs' => 'remote_ip_prefix', @@ -72,7 +77,7 @@ public function remoteIpPrefixJson() ]; } - public function securityGroupIdJson() + public function securityGroupIdJson(): array { return [ 'sentAs' => 'security_group_id', @@ -81,7 +86,7 @@ public function securityGroupIdJson() ]; } - public function tenantIdJson() + public function tenantIdJson(): array { return [ 'sentAs' => 'tenant_id', diff --git a/src/Networking/v2/Extensions/SecurityGroups/ParamsTrait.php b/src/Networking/v2/Extensions/SecurityGroups/ParamsTrait.php new file mode 100644 index 000000000..90225a417 --- /dev/null +++ b/src/Networking/v2/Extensions/SecurityGroups/ParamsTrait.php @@ -0,0 +1,97 @@ + self::STRING_TYPE, + 'description' => 'Ingress or egress: the direction in which the security group rule is applied. For a compute instance, an ingress security group rule is applied to incoming (ingress) traffic for that instance. An egress rule is applied to traffic leaving the instance.', + ]; + } + + public function ethertypeJson(): array + { + return [ + 'type' => self::STRING_TYPE, + 'description' => 'Must be IPv4 or IPv6, and addresses represented in CIDR must match the ingress or egress rules.', + ]; + } + + public function idJson(): array + { + return [ + 'type' => self::STRING_TYPE, + 'description' => 'The UUID of the security group rule.', + ]; + } + + public function portRangeMaxJson(): array + { + return [ + 'type' => self::STRING_TYPE, + 'sentAs' => 'port_range_max', + 'description' => 'The maximum port number in the range that is matched by the security group rule. The port_range_min attribute constrains the port_range_max attribute. If the protocol is ICMP, this value must be an ICMP type.', + ]; + } + + public function portRangeMinJson(): array + { + return [ + 'sentAs' => 'port_range_min', + 'type' => self::STRING_TYPE, + 'description' => 'The minimum port number in the range that is matched by the security group rule. If the protocol is TCP or UDP, this value must be less than or equal to the port_range_max attribute value. If the protocol is ICMP, this value must be an ICMP type.', + ]; + } + + public function protocolJson(): array + { + return [ + 'type' => self::STRING_TYPE, + 'description' => 'The protocol that is matched by the security group rule. Value is null, icmp, icmpv6, tcp, or udp.', + ]; + } + + public function remoteGroupIdJson(): array + { + return [ + 'sentAs' => 'remote_group_id', + 'type' => self::STRING_TYPE, + 'description' => 'The remote group UUID to associate with this security group rule. You can specify either the remote_group_id or remote_ip_prefix attribute in the request body.', + ]; + } + + public function remoteIpPrefixJson(): array + { + return [ + 'sentAs' => 'remote_ip_prefix', + 'type' => self::STRING_TYPE, + 'description' => 'The remote IP prefix to associate with this security group rule. You can specify either the remote_group_id or remote_ip_prefix attribute in the request body. This attribute value matches the IP prefix as the source IP address of the IP packet.', + ]; + } + + public function securityGroupIdJson(): array + { + return [ + 'sentAs' => 'security_group_id', + 'type' => self::STRING_TYPE, + 'description' => 'The UUID of the security group.', + ]; + } + + public function filterName(): array + { + return [ + 'description' => 'Filter the list result by the human-readable name of the resource', + 'type' => self::STRING_TYPE, + 'location' => self::QUERY, + ]; + } +} diff --git a/src/Networking/v2/Extensions/SecurityGroups/Service.php b/src/Networking/v2/Extensions/SecurityGroups/Service.php index 4cc69d664..4a1b70b67 100644 --- a/src/Networking/v2/Extensions/SecurityGroups/Service.php +++ b/src/Networking/v2/Extensions/SecurityGroups/Service.php @@ -8,6 +8,10 @@ /** * @property Api $api + * + * @deprecated Use Networking\v2\Service instead + * + * @internal */ class Service extends AbstractService { diff --git a/src/Networking/v2/Extensions/SecurityGroups/ServiceTrait.php b/src/Networking/v2/Extensions/SecurityGroups/ServiceTrait.php new file mode 100644 index 000000000..0e0bd9407 --- /dev/null +++ b/src/Networking/v2/Extensions/SecurityGroups/ServiceTrait.php @@ -0,0 +1,62 @@ +model(SecurityGroup::class, $info); + } + + private function securityGroupRule(array $info = []): SecurityGroupRule + { + return $this->model(SecurityGroupRule::class, $info); + } + + /** + * @return \Generator + */ + public function listSecurityGroups(array $options = []): \Generator + { + return $this->securityGroup()->enumerate($this->api->getSecurityGroups(), $options); + } + + public function createSecurityGroup(array $options): SecurityGroup + { + return $this->securityGroup()->create($options); + } + + public function getSecurityGroup(string $id): SecurityGroup + { + return $this->securityGroup(['id' => $id]); + } + + /** + * @return \Generator + */ + public function listSecurityGroupRules(): \Generator + { + return $this->securityGroupRule()->enumerate($this->api->getSecurityRules()); + } + + public function createSecurityGroupRule(array $options): SecurityGroupRule + { + return $this->securityGroupRule()->create($options); + } + + public function getSecurityGroupRule(string $id): SecurityGroupRule + { + return $this->securityGroupRule(['id' => $id]); + } +} diff --git a/src/Networking/v2/Params.php b/src/Networking/v2/Params.php index ea0938237..2e68a505b 100644 --- a/src/Networking/v2/Params.php +++ b/src/Networking/v2/Params.php @@ -5,9 +5,14 @@ namespace OpenStack\Networking\v2; use OpenStack\Common\Api\AbstractParams; +use OpenStack\Networking\v2\Extensions\Layer3\ParamsTrait as Layer3; +use OpenStack\Networking\v2\Extensions\SecurityGroups\ParamsTrait as SecurityGroups; class Params extends AbstractParams { + use Layer3; + use SecurityGroups; + /** * Returns information about description parameter. */ @@ -719,4 +724,13 @@ public function type(): array 'description' => 'The type of health monitor. Must be one of TCP, HTTP, HTTPS', ]; } + + public function tenantIdJson(): array + { + return [ + 'type' => self::STRING_TYPE, + 'description' => 'The UUID of the tenant. Only administrative users can specify a tenant UUID other than their own.', + 'sentAs' => 'tenant_id', + ]; + } } diff --git a/src/Networking/v2/Service.php b/src/Networking/v2/Service.php index b66c63be9..03ec9c73b 100644 --- a/src/Networking/v2/Service.php +++ b/src/Networking/v2/Service.php @@ -5,13 +5,14 @@ namespace OpenStack\Networking\v2; use OpenStack\Common\Service\AbstractService; +use OpenStack\Networking\v2\Extensions\Layer3\ServiceTrait as Layer3; +use OpenStack\Networking\v2\Extensions\SecurityGroups\ServiceTrait as SecurityGroups; use OpenStack\Networking\v2\Models\LoadBalancer; use OpenStack\Networking\v2\Models\LoadBalancerHealthMonitor; use OpenStack\Networking\v2\Models\LoadBalancerListener; use OpenStack\Networking\v2\Models\LoadBalancerMember; use OpenStack\Networking\v2\Models\LoadBalancerPool; use OpenStack\Networking\v2\Models\Network; -use OpenStack\Networking\v2\Models\Pool; use OpenStack\Networking\v2\Models\Port; use OpenStack\Networking\v2\Models\Quota; use OpenStack\Networking\v2\Models\Subnet; @@ -23,6 +24,9 @@ */ class Service extends AbstractService { + use Layer3; + use SecurityGroups; + /** * Create a new network resource. * diff --git a/src/OpenStack.php b/src/OpenStack.php index 01da51fa4..05ba65acb 100644 --- a/src/OpenStack.php +++ b/src/OpenStack.php @@ -99,6 +99,8 @@ public function networkingV2(array $options = []): Networking\v2\Service * Creates a new Networking v2 Layer 3 service. * * @param array $options options that will be used in configuring the service + * + * @deprecated Use networkingV2 instead */ public function networkingV2ExtLayer3(array $options = []): Networking\v2\Extensions\Layer3\Service { @@ -111,6 +113,8 @@ public function networkingV2ExtLayer3(array $options = []): Networking\v2\Extens * Creates a new Networking v2 Layer 3 service. * * @param array $options options that will be used in configuring the service + * + * @deprecated Use networkingV2 instead */ public function networkingV2ExtSecGroups(array $options = []): Networking\v2\Extensions\SecurityGroups\Service { diff --git a/tests/sample/Compute/v2/InterfaceAttachmentTest.php b/tests/sample/Compute/v2/InterfaceAttachmentTest.php index f635bd7ba..15e4b008b 100644 --- a/tests/sample/Compute/v2/InterfaceAttachmentTest.php +++ b/tests/sample/Compute/v2/InterfaceAttachmentTest.php @@ -9,8 +9,8 @@ class InterfaceAttachmentTest extends TestCase public function testCreate() { $server = $this->createServer(); - $network = $this->getServiceNetwork()->createNetwork(['name' => $this->randomStr()]); - $this->getServiceNetwork()->createSubnet( + $network = $this->getNetworkService()->createNetwork(['name' => $this->randomStr()]); + $this->getNetworkService()->createSubnet( [ 'name' => $this->randomStr(), 'networkId' => $network->id, @@ -31,7 +31,7 @@ public function testCreate() $this->assertInstanceOf(InterfaceAttachment::class, $interfaceAttachment); $this->assertEquals($network->id, $interfaceAttachment->netId); - $port = $this->getServiceNetwork()->getPort($interfaceAttachment->portId); + $port = $this->getNetworkService()->getPort($interfaceAttachment->portId); $port->retrieve(); $server->detachInterface($interfaceAttachment->portId); diff --git a/tests/sample/Compute/v2/SecurityGroupTest.php b/tests/sample/Compute/v2/SecurityGroupTest.php index 13fc26f4b..b53d4e014 100644 --- a/tests/sample/Compute/v2/SecurityGroupTest.php +++ b/tests/sample/Compute/v2/SecurityGroupTest.php @@ -12,7 +12,7 @@ class SecurityGroupTest extends TestCase public function testAdd(): array { $createdServer = $this->createServer(); - $createdSecurityGroup = $this->getCachedService(Service::class) + $createdSecurityGroup = $this->getNetworkService() ->createSecurityGroup(['name' => $this->randomStr()]); $replacements = [ diff --git a/tests/sample/Compute/v2/ServerTest.php b/tests/sample/Compute/v2/ServerTest.php index 721e46dfd..c92ef611d 100644 --- a/tests/sample/Compute/v2/ServerTest.php +++ b/tests/sample/Compute/v2/ServerTest.php @@ -19,8 +19,8 @@ public function testCreate(): Server throw new RuntimeException('OS_FLAVOR env var must be set'); } - $network = $this->getServiceNetwork()->createNetwork(['name' => $this->randomStr()]); - $this->getServiceNetwork()->createSubnet( + $network = $this->getNetworkService()->createNetwork(['name' => $this->randomStr()]); + $this->getNetworkService()->createSubnet( [ 'name' => $this->randomStr(), 'networkId' => $network->id, @@ -355,7 +355,7 @@ public function testDelete(Server $createdServer) } foreach (array_keys($createdServer->addresses) as $networkName) { - $network = $this->getServiceNetwork()->listNetworks(['name' => $networkName])->current(); + $network = $this->getNetworkService()->listNetworks(['name' => $networkName])->current(); $this->deleteNetwork($network); } diff --git a/tests/sample/Compute/v2/TestCase.php b/tests/sample/Compute/v2/TestCase.php index 914b939c9..b24e62313 100644 --- a/tests/sample/Compute/v2/TestCase.php +++ b/tests/sample/Compute/v2/TestCase.php @@ -15,7 +15,7 @@ protected function getService(): Service return $this->getCachedService(Service::class); } - protected function getServiceNetwork(): \OpenStack\Networking\v2\Service + protected function getNetworkService(): \OpenStack\Networking\v2\Service { return $this->getCachedService(\OpenStack\Networking\v2\Service::class); } @@ -47,8 +47,8 @@ protected function createServer(): Server throw new RuntimeException('OS_FLAVOR env var must be set'); } - $network = $this->getServiceNetwork()->createNetwork(['name' => $this->randomStr()]); - $this->getServiceNetwork()->createSubnet( + $network = $this->getNetworkService()->createNetwork(['name' => $this->randomStr()]); + $this->getNetworkService()->createSubnet( [ 'name' => $this->randomStr(), 'networkId' => $network->id, @@ -82,7 +82,7 @@ protected function deleteServer(Server $server): void $server->waitUntilDeleted(); foreach (array_keys($server->addresses) as $networkName) { - $network = $this->getServiceNetwork()->listNetworks(['name' => $networkName])->current(); + $network = $this->getNetworkService()->listNetworks(['name' => $networkName])->current(); $this->deleteNetwork($network); } } @@ -93,11 +93,11 @@ protected function deleteServer(Server $server): void protected function deleteNetwork(Network $network): void { foreach ($network->subnets as $subnetId) { - $subnet = $this->getServiceNetwork()->getSubnet($subnetId); + $subnet = $this->getNetworkService()->getSubnet($subnetId); $subnet->delete(); } - foreach ($this->getServiceNetwork()->listPorts(['networkId' => $network->id]) as $port) { + foreach ($this->getNetworkService()->listPorts(['networkId' => $network->id]) as $port) { if ($port->deviceOwner) { continue; } diff --git a/tests/sample/Compute/v2/VolumeAttachmentTest.php b/tests/sample/Compute/v2/VolumeAttachmentTest.php index 1f11190f4..e1eb73dc3 100644 --- a/tests/sample/Compute/v2/VolumeAttachmentTest.php +++ b/tests/sample/Compute/v2/VolumeAttachmentTest.php @@ -71,7 +71,7 @@ public function testDetach(VolumeAttachment $createdVolumeAttachment) ); $volume = $this->getCachedService(Service::class)->getVolume($createdVolumeAttachment->volumeId); - $volume->waitUntil('available'); + $volume->waitUntil('available', 240); $this->assertEquals('available', $volume->status); $server = $this->getService()->getServer(['id' => $createdVolumeAttachment->serverId]); diff --git a/tests/sample/Networking/v2/FloatingIpTest.php b/tests/sample/Networking/v2/FloatingIpTest.php index 740846355..196f0edc5 100644 --- a/tests/sample/Networking/v2/FloatingIpTest.php +++ b/tests/sample/Networking/v2/FloatingIpTest.php @@ -49,7 +49,7 @@ public function testCreate(): FloatingIpData $data->externalNetwork->waitUntilActive(); $data->internalNetwork->waitUntilActive(); - $data->router = $this->getServiceLayer3()->createRouter([ + $data->router = $this->getService()->createRouter([ 'name' => $this->randomStr(), 'externalGatewayInfo' => [ 'networkId' => $data->externalNetwork->id, @@ -161,7 +161,7 @@ public function testDelete(FloatingIpData $data) '{id}' => $data->floatingIp->id, ]); - foreach ($this->getServiceLayer3()->listFloatingIps() as $floatingIp) { + foreach ($this->getService()->listFloatingIps() as $floatingIp) { if ($floatingIp->id == $data->floatingIp->id) { $this->fail('Floating IP still exists'); } diff --git a/tests/sample/Networking/v2/TestCase.php b/tests/sample/Networking/v2/TestCase.php index 2ac889b3c..a78c69d64 100644 --- a/tests/sample/Networking/v2/TestCase.php +++ b/tests/sample/Networking/v2/TestCase.php @@ -13,11 +13,6 @@ protected function getService(): Service return $this->getCachedService(Service::class); } - protected function getServiceLayer3(): \OpenStack\Networking\v2\Extensions\Layer3\Service - { - return $this->getCachedService(\OpenStack\Networking\v2\Extensions\Layer3\Service::class); - } - protected function sampleFile(string $path, array $replacements = []): string { return parent::sampleFile("Networking/v2/$path", $replacements); diff --git a/tests/sample/TestCase.php b/tests/sample/TestCase.php index 19d494797..79ef23131 100644 --- a/tests/sample/TestCase.php +++ b/tests/sample/TestCase.php @@ -65,12 +65,6 @@ protected function getCachedService(string $serviceType): AbstractService case \OpenStack\Networking\v2\Service::class: $service = $this->getOpenStack()->networkingV2(); break; - case \OpenStack\Networking\v2\Extensions\Layer3\Service::class: - $service = $this->getOpenStack()->networkingV2ExtLayer3(); - break; - case \OpenStack\Networking\v2\Extensions\SecurityGroups\Service::class: - $service = $this->getOpenStack()->networkingV2ExtSecGroups(); - break; case \OpenStack\ObjectStore\v1\Service::class: $service = $this->getOpenStack()->objectStoreV1(); break;