Merge "Add network availability zone support"
This commit is contained in:
@@ -4,6 +4,7 @@ Network Resources
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
v2/availability_zone
|
||||
v2/extension
|
||||
v2/floating_ip
|
||||
v2/health_monitor
|
||||
|
||||
12
doc/source/users/resources/network/v2/availability_zone.rst
Normal file
12
doc/source/users/resources/network/v2/availability_zone.rst
Normal file
@@ -0,0 +1,12 @@
|
||||
openstack.network.v2.availability_zone
|
||||
======================================
|
||||
|
||||
.. automodule:: openstack.network.v2.availability_zone
|
||||
|
||||
The AvailabilityZone Class
|
||||
--------------------------
|
||||
|
||||
The ``AvailabilityZone`` class inherits from :class:`~openstack.resource.Resource`.
|
||||
|
||||
.. autoclass:: openstack.network.v2.availability_zone.AvailabilityZone
|
||||
:members:
|
||||
@@ -10,6 +10,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack.network.v2 import availability_zone
|
||||
from openstack.network.v2 import extension
|
||||
from openstack.network.v2 import floating_ip as _floating_ip
|
||||
from openstack.network.v2 import health_monitor as _health_monitor
|
||||
@@ -34,6 +35,15 @@ from openstack import resource
|
||||
|
||||
class Proxy(proxy.BaseProxy):
|
||||
|
||||
def availability_zones(self):
|
||||
"""Return a generator of availability zones
|
||||
|
||||
:returns: A generator of availability zone objects
|
||||
:rtype:
|
||||
:class:`~openstack.network.v2.availability_zone.AvailabilityZone`
|
||||
"""
|
||||
return self._list(availability_zone.AvailabilityZone, paginated=False)
|
||||
|
||||
def find_extension(self, name_or_id, ignore_missing=True):
|
||||
"""Find a single extension
|
||||
|
||||
|
||||
37
openstack/network/v2/availability_zone.py
Normal file
37
openstack/network/v2/availability_zone.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack.network import network_service
|
||||
from openstack import resource as _resource
|
||||
|
||||
|
||||
class AvailabilityZone(_resource.Resource):
|
||||
resource_key = 'availability_zone'
|
||||
resources_key = 'availability_zones'
|
||||
base_path = '/availability_zones'
|
||||
service = network_service.NetworkService()
|
||||
|
||||
# capabilities
|
||||
allow_create = False
|
||||
allow_retrieve = False
|
||||
allow_update = False
|
||||
allow_delete = False
|
||||
allow_list = True
|
||||
|
||||
# Properties
|
||||
#: Name of the availability zone.
|
||||
name = _resource.prop('name')
|
||||
#: Type of resource for the availability zone, such as ``network``.
|
||||
resource = _resource.prop('resource')
|
||||
#: State of the availability zone, either ``available`` or
|
||||
#: ``unavailable``.
|
||||
state = _resource.prop('state')
|
||||
@@ -31,6 +31,12 @@ class Network(resource.Resource):
|
||||
#: The administrative state of the network, which is up ``True`` or
|
||||
#: down ``False``. *Type: bool*
|
||||
admin_state_up = resource.prop('admin_state_up', type=bool)
|
||||
#: Availability zone hints to use when scheduling the network.
|
||||
#: *Type: list of availability zone names*
|
||||
availability_zone_hints = resource.prop('availability_zone_hints')
|
||||
#: Availability zones for the network.
|
||||
#: *Type: list of availability zone names*
|
||||
availability_zones = resource.prop('availability_zones')
|
||||
#: The network name.
|
||||
name = resource.prop('name')
|
||||
#: The project this network is associated with.
|
||||
|
||||
@@ -32,6 +32,12 @@ class Router(resource.Resource):
|
||||
#: The administrative state of the router, which is up ``True``
|
||||
#: or down ``False``. *Type: bool*
|
||||
admin_state_up = resource.prop('admin_state_up', type=bool)
|
||||
#: Availability zone hints to use when scheduling the router.
|
||||
#: *Type: list of availability zone names*
|
||||
availability_zone_hints = resource.prop('availability_zone_hints')
|
||||
#: Availability zones for the router.
|
||||
#: *Type: list of availability zone names*
|
||||
availability_zones = resource.prop('availability_zones')
|
||||
#: The ``network_id``, for the external gateway. *Type: dict*
|
||||
external_gateway_info = resource.prop('external_gateway_info', type=dict)
|
||||
#: The router name.
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import six
|
||||
|
||||
from openstack.tests.functional import base
|
||||
|
||||
|
||||
class TestAvailabilityZone(base.BaseFunctionalTest):
|
||||
|
||||
def test_list(self):
|
||||
availability_zones = list(self.conn.network.availability_zones())
|
||||
self.assertGreater(len(availability_zones), 0)
|
||||
|
||||
for az in availability_zones:
|
||||
self.assertIsInstance(az.name, six.string_types)
|
||||
self.assertIsInstance(az.resource, six.string_types)
|
||||
self.assertIsInstance(az.state, six.string_types)
|
||||
45
openstack/tests/unit/network/v2/test_availability_zone.py
Normal file
45
openstack/tests/unit/network/v2/test_availability_zone.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import testtools
|
||||
|
||||
from openstack.network.v2 import availability_zone
|
||||
|
||||
IDENTIFIER = 'IDENTIFIER'
|
||||
EXAMPLE = {
|
||||
'id': IDENTIFIER,
|
||||
'name': '1',
|
||||
'resource': '2',
|
||||
'state': '3',
|
||||
}
|
||||
|
||||
|
||||
class TestAvailabilityZone(testtools.TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
sot = availability_zone.AvailabilityZone()
|
||||
self.assertEqual('availability_zone', sot.resource_key)
|
||||
self.assertEqual('availability_zones', sot.resources_key)
|
||||
self.assertEqual('/availability_zones', sot.base_path)
|
||||
self.assertEqual('network', sot.service.service_type)
|
||||
self.assertFalse(sot.allow_create)
|
||||
self.assertFalse(sot.allow_retrieve)
|
||||
self.assertFalse(sot.allow_update)
|
||||
self.assertFalse(sot.allow_delete)
|
||||
self.assertTrue(sot.allow_list)
|
||||
|
||||
def test_make_it(self):
|
||||
sot = availability_zone.AvailabilityZone(EXAMPLE)
|
||||
self.assertEqual(EXAMPLE['id'], sot.id)
|
||||
self.assertEqual(EXAMPLE['name'], sot.name)
|
||||
self.assertEqual(EXAMPLE['resource'], sot.resource)
|
||||
self.assertEqual(EXAMPLE['state'], sot.state)
|
||||
@@ -30,6 +30,8 @@ EXAMPLE = {
|
||||
'subnets': '12',
|
||||
'mtu': 1400,
|
||||
'port_security_enabled': True,
|
||||
'availability_zone_hints': ['15', '16'],
|
||||
'availability_zones': ['16'],
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +69,10 @@ class TestNetwork(testtools.TestCase):
|
||||
self.assertEqual(EXAMPLE['mtu'], sot.mtu)
|
||||
self.assertEqual(EXAMPLE['port_security_enabled'],
|
||||
sot.is_port_security_enabled)
|
||||
self.assertEqual(EXAMPLE['availability_zone_hints'],
|
||||
sot.availability_zone_hints)
|
||||
self.assertEqual(EXAMPLE['availability_zones'],
|
||||
sot.availability_zones)
|
||||
|
||||
def test_external(self):
|
||||
sot = network.Network(EXAMPLE)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import mock
|
||||
|
||||
from openstack.network.v2 import _proxy
|
||||
from openstack.network.v2 import availability_zone
|
||||
from openstack.network.v2 import extension
|
||||
from openstack.network.v2 import floating_ip
|
||||
from openstack.network.v2 import health_monitor
|
||||
@@ -39,6 +40,11 @@ class TestNetworkProxy(test_proxy_base.TestProxyBase):
|
||||
super(TestNetworkProxy, self).setUp()
|
||||
self.proxy = _proxy.Proxy(self.session)
|
||||
|
||||
def test_availability_zones(self):
|
||||
self.verify_list_no_kwargs(self.proxy.availability_zones,
|
||||
availability_zone.AvailabilityZone,
|
||||
paginated=False)
|
||||
|
||||
def test_extension_find(self):
|
||||
self.verify_find(self.proxy.find_extension, extension.Extension)
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ EXAMPLE = {
|
||||
'tenant_id': '5',
|
||||
'status': '6',
|
||||
'routes': [],
|
||||
'availability_zone_hints': [],
|
||||
'availability_zones': [],
|
||||
}
|
||||
|
||||
EXAMPLE_WITH_OPTIONAL = {
|
||||
@@ -38,6 +40,8 @@ EXAMPLE_WITH_OPTIONAL = {
|
||||
'routes': [{'nexthop': '172.24.4.20', 'destination': '10.0.3.1/24'}],
|
||||
'ha': True,
|
||||
'distributed': True,
|
||||
'availability_zone_hints': ['zone-1', 'zone-2'],
|
||||
'availability_zones': ['zone-2'],
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +71,10 @@ class TestRouter(testtools.TestCase):
|
||||
self.assertFalse(sot.is_ha)
|
||||
self.assertFalse(sot.is_distributed)
|
||||
self.assertEqual(EXAMPLE['routes'], sot.routes)
|
||||
self.assertEqual(EXAMPLE['availability_zone_hints'],
|
||||
sot.availability_zone_hints)
|
||||
self.assertEqual(EXAMPLE['availability_zones'],
|
||||
sot.availability_zones)
|
||||
|
||||
def test_make_it_with_optional(self):
|
||||
sot = router.Router(EXAMPLE_WITH_OPTIONAL)
|
||||
@@ -82,6 +90,10 @@ class TestRouter(testtools.TestCase):
|
||||
self.assertEqual(EXAMPLE_WITH_OPTIONAL['distributed'],
|
||||
sot.is_distributed)
|
||||
self.assertEqual(EXAMPLE_WITH_OPTIONAL['routes'], sot.routes)
|
||||
self.assertEqual(EXAMPLE_WITH_OPTIONAL['availability_zone_hints'],
|
||||
sot.availability_zone_hints)
|
||||
self.assertEqual(EXAMPLE_WITH_OPTIONAL['availability_zones'],
|
||||
sot.availability_zones)
|
||||
|
||||
def test_add_interface(self):
|
||||
sot = router.Router(EXAMPLE)
|
||||
|
||||
@@ -172,6 +172,15 @@ class TestProxyBase(base.TestCase):
|
||||
expected_result=["result"],
|
||||
**kwargs)
|
||||
|
||||
def verify_list_no_kwargs(self, test_method, resource_type,
|
||||
paginated=False,
|
||||
mock_method="openstack.proxy.BaseProxy._list"):
|
||||
self._verify2(mock_method, test_method,
|
||||
method_kwargs={},
|
||||
expected_args=[resource_type],
|
||||
expected_kwargs={"paginated": paginated},
|
||||
expected_result=["result"])
|
||||
|
||||
def verify_update(self, test_method, resource_type,
|
||||
mock_method="openstack.proxy.BaseProxy._update",
|
||||
expected_result="result", **kwargs):
|
||||
|
||||
Reference in New Issue
Block a user