Support passing a subnetpool for create_subnet
previously create_subnet would wrongly report that we need to set a cidr if subnetpool_id is set. Change-Id: Icf1d6364d281a0b8b3156ae6b24d7ebca80d632b
This commit is contained in:
parent
9b49ddbb48
commit
10217f5bc2
@ -457,6 +457,17 @@ class NetworkCloudMixin:
|
|||||||
"""
|
"""
|
||||||
return self.network.get_port(id)
|
return self.network.get_port(id)
|
||||||
|
|
||||||
|
def get_subnetpool(self, name_or_id):
|
||||||
|
"""Get a subnetpool by name or ID.
|
||||||
|
|
||||||
|
:param name_or_id: Name or ID of the subnetpool.
|
||||||
|
|
||||||
|
:returns: A network ``Subnetpool`` object if found, else None.
|
||||||
|
"""
|
||||||
|
return self.network.find_subnet_pool(
|
||||||
|
name_or_id=name_or_id, ignore_missing=True
|
||||||
|
)
|
||||||
|
|
||||||
def create_network(
|
def create_network(
|
||||||
self,
|
self,
|
||||||
name,
|
name,
|
||||||
@ -2308,13 +2319,16 @@ class NetworkCloudMixin:
|
|||||||
ipv6_address_mode=None,
|
ipv6_address_mode=None,
|
||||||
prefixlen=None,
|
prefixlen=None,
|
||||||
use_default_subnetpool=False,
|
use_default_subnetpool=False,
|
||||||
|
subnetpool_name_or_id=None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Create a subnet on a specified network.
|
"""Create a subnet on a specified network.
|
||||||
|
|
||||||
:param string network_name_or_id: The unique name or ID of the attached
|
:param string network_name_or_id: The unique name or ID of the attached
|
||||||
network. If a non-unique name is supplied, an exception is raised.
|
network. If a non-unique name is supplied, an exception is raised.
|
||||||
:param string cidr: The CIDR.
|
:param string cidr: The CIDR. Only one of ``cidr``,
|
||||||
|
``use_default_subnetpool`` and ``subnetpool_name_or_id`` may be
|
||||||
|
specified at the same time.
|
||||||
:param int ip_version: The IP version, which is 4 or 6.
|
:param int ip_version: The IP version, which is 4 or 6.
|
||||||
:param bool enable_dhcp: Set to ``True`` if DHCP is enabled and
|
:param bool enable_dhcp: Set to ``True`` if DHCP is enabled and
|
||||||
``False`` if disabled. Default is ``False``.
|
``False`` if disabled. Default is ``False``.
|
||||||
@ -2362,10 +2376,15 @@ class NetworkCloudMixin:
|
|||||||
:param string ipv6_address_mode: IPv6 address mode. Valid values are:
|
:param string ipv6_address_mode: IPv6 address mode. Valid values are:
|
||||||
'dhcpv6-stateful', 'dhcpv6-stateless', or 'slaac'.
|
'dhcpv6-stateful', 'dhcpv6-stateless', or 'slaac'.
|
||||||
:param string prefixlen: The prefix length to use for subnet allocation
|
:param string prefixlen: The prefix length to use for subnet allocation
|
||||||
from a subnet pool.
|
from a subnetpool.
|
||||||
:param bool use_default_subnetpool: Use the default subnetpool for
|
:param bool use_default_subnetpool: Use the default subnetpool for
|
||||||
``ip_version`` to obtain a CIDR. It is required to pass ``None`` to
|
``ip_version`` to obtain a CIDR. Only one of ``cidr``,
|
||||||
the ``cidr`` argument when enabling this option.
|
``use_default_subnetpool`` and ``subnetpool_name_or_id`` may be
|
||||||
|
specified at the same time.
|
||||||
|
:param string subnetpool_name_or_id: The unique name or id of the
|
||||||
|
subnetpool to obtain a CIDR from. Only one of ``cidr``,
|
||||||
|
``use_default_subnetpool`` and ``subnetpool_name_or_id`` may be
|
||||||
|
specified at the same time.
|
||||||
:param kwargs: Key value pairs to be passed to the Neutron API.
|
:param kwargs: Key value pairs to be passed to the Neutron API.
|
||||||
:returns: The created network ``Subnet`` object.
|
:returns: The created network ``Subnet`` object.
|
||||||
:raises: OpenStackCloudException on operation error.
|
:raises: OpenStackCloudException on operation error.
|
||||||
@ -2387,17 +2406,31 @@ class NetworkCloudMixin:
|
|||||||
'arg:disable_gateway_ip is not allowed with arg:gateway_ip'
|
'arg:disable_gateway_ip is not allowed with arg:gateway_ip'
|
||||||
)
|
)
|
||||||
|
|
||||||
if not cidr and not use_default_subnetpool:
|
uses_subnetpool = use_default_subnetpool or subnetpool_name_or_id
|
||||||
|
if not cidr and not uses_subnetpool:
|
||||||
raise exc.OpenStackCloudException(
|
raise exc.OpenStackCloudException(
|
||||||
'arg:cidr is required when a subnetpool is not used'
|
'arg:cidr is required when a subnetpool is not used'
|
||||||
)
|
)
|
||||||
|
|
||||||
if cidr and use_default_subnetpool:
|
if cidr and uses_subnetpool:
|
||||||
raise exc.OpenStackCloudException(
|
raise exc.OpenStackCloudException(
|
||||||
'arg:cidr must be set to None when use_default_subnetpool == '
|
'arg:cidr and subnetpool may not be used at the same time'
|
||||||
'True'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if use_default_subnetpool and subnetpool_name_or_id:
|
||||||
|
raise exc.OpenStackCloudException(
|
||||||
|
'arg:use_default_subnetpool and arg:subnetpool_id may not be '
|
||||||
|
'used at the same time'
|
||||||
|
)
|
||||||
|
|
||||||
|
subnetpool = None
|
||||||
|
if subnetpool_name_or_id:
|
||||||
|
subnetpool = self.get_subnetpool(subnetpool_name_or_id)
|
||||||
|
if not subnetpool:
|
||||||
|
raise exc.OpenStackCloudException(
|
||||||
|
"Subnetpool %s not found." % subnetpool_name_or_id
|
||||||
|
)
|
||||||
|
|
||||||
# Be friendly on ip_version and allow strings
|
# Be friendly on ip_version and allow strings
|
||||||
if isinstance(ip_version, str):
|
if isinstance(ip_version, str):
|
||||||
try:
|
try:
|
||||||
@ -2443,6 +2476,8 @@ class NetworkCloudMixin:
|
|||||||
subnet['prefixlen'] = prefixlen
|
subnet['prefixlen'] = prefixlen
|
||||||
if use_default_subnetpool:
|
if use_default_subnetpool:
|
||||||
subnet['use_default_subnetpool'] = True
|
subnet['use_default_subnetpool'] = True
|
||||||
|
if subnetpool:
|
||||||
|
subnet['subnetpool_id'] = subnetpool["id"]
|
||||||
|
|
||||||
return self.network.create_subnet(**subnet)
|
return self.network.create_subnet(**subnet)
|
||||||
|
|
||||||
|
@ -554,6 +554,93 @@ class TestSubnet(base.TestCase):
|
|||||||
self._compare_subnets(mock_subnet_rep, subnet)
|
self._compare_subnets(mock_subnet_rep, subnet)
|
||||||
self.assert_calls()
|
self.assert_calls()
|
||||||
|
|
||||||
|
def test_create_subnet_from_specific_subnetpool(self):
|
||||||
|
pool = [{'start': '172.16.0.2', 'end': '172.16.0.15'}]
|
||||||
|
id = '143296eb-7f47-4755-835c-488123475604'
|
||||||
|
gateway = '172.16.0.1'
|
||||||
|
dns = ['8.8.8.8']
|
||||||
|
routes = [{"destination": "0.0.0.0/0", "nexthop": "123.456.78.9"}]
|
||||||
|
mock_subnet_rep = copy.copy(self.mock_subnet_rep)
|
||||||
|
mock_subnet_rep['allocation_pools'] = pool
|
||||||
|
mock_subnet_rep['dns_nameservers'] = dns
|
||||||
|
mock_subnet_rep['host_routes'] = routes
|
||||||
|
mock_subnet_rep['gateway_ip'] = gateway
|
||||||
|
mock_subnet_rep['subnetpool_id'] = self.mock_subnetpool_rep['id']
|
||||||
|
mock_subnet_rep['cidr'] = self.subnetpool_cidr
|
||||||
|
mock_subnet_rep['id'] = id
|
||||||
|
self.register_uris(
|
||||||
|
[
|
||||||
|
dict(
|
||||||
|
method='GET',
|
||||||
|
uri=self.get_mock_url(
|
||||||
|
'network',
|
||||||
|
'public',
|
||||||
|
append=['v2.0', 'networks', self.network_name],
|
||||||
|
),
|
||||||
|
status_code=404,
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
method='GET',
|
||||||
|
uri=self.get_mock_url(
|
||||||
|
'network',
|
||||||
|
'public',
|
||||||
|
append=['v2.0', 'networks'],
|
||||||
|
qs_elements=['name=%s' % self.network_name],
|
||||||
|
),
|
||||||
|
json={'networks': [self.mock_network_rep]},
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
method='GET',
|
||||||
|
uri=self.get_mock_url(
|
||||||
|
'network',
|
||||||
|
'public',
|
||||||
|
append=[
|
||||||
|
'v2.0',
|
||||||
|
'subnetpools',
|
||||||
|
self.mock_subnetpool_rep['id'],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
json={"subnetpool": self.mock_subnetpool_rep},
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
method='POST',
|
||||||
|
uri=self.get_mock_url(
|
||||||
|
'network', 'public', append=['v2.0', 'subnets']
|
||||||
|
),
|
||||||
|
json={'subnet': mock_subnet_rep},
|
||||||
|
validate=dict(
|
||||||
|
json={
|
||||||
|
'subnet': {
|
||||||
|
'enable_dhcp': False,
|
||||||
|
'ip_version': 4,
|
||||||
|
'network_id': self.mock_network_rep['id'],
|
||||||
|
'allocation_pools': pool,
|
||||||
|
'dns_nameservers': dns,
|
||||||
|
'subnetpool_id': self.mock_subnetpool_rep[
|
||||||
|
'id'
|
||||||
|
],
|
||||||
|
'prefixlen': self.prefix_length,
|
||||||
|
'host_routes': routes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
subnet = self.cloud.create_subnet(
|
||||||
|
self.network_name,
|
||||||
|
allocation_pools=pool,
|
||||||
|
dns_nameservers=dns,
|
||||||
|
subnetpool_name_or_id=self.mock_subnetpool_rep['id'],
|
||||||
|
prefixlen=self.prefix_length,
|
||||||
|
host_routes=routes,
|
||||||
|
)
|
||||||
|
mock_subnet_rep.update(
|
||||||
|
{'prefixlen': self.prefix_length, 'use_default_subnetpool': None}
|
||||||
|
)
|
||||||
|
self._compare_subnets(mock_subnet_rep, subnet)
|
||||||
|
self.assert_calls()
|
||||||
|
|
||||||
def test_delete_subnet(self):
|
def test_delete_subnet(self):
|
||||||
self.register_uris(
|
self.register_uris(
|
||||||
[
|
[
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added support for specifying the subnetpool to use when creating subnets
|
||||||
|
(``subnetpool_name_or_id``)
|
Loading…
x
Reference in New Issue
Block a user