Merge "Add network availability zone support"

This commit is contained in:
Jenkins
2016-01-16 00:17:29 +00:00
committed by Gerrit Code Review
12 changed files with 177 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ Network Resources
.. toctree::
:maxdepth: 1
v2/availability_zone
v2/extension
v2/floating_ip
v2/health_monitor

View 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:

View File

@@ -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

View 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')

View File

@@ -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.

View File

@@ -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.

View File

@@ -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)

View 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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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):