Merge "Add network availability zone support"
This commit is contained in:
		| @@ -4,6 +4,7 @@ Network Resources | |||||||
| .. toctree:: | .. toctree:: | ||||||
|    :maxdepth: 1 |    :maxdepth: 1 | ||||||
|  |  | ||||||
|  |    v2/availability_zone | ||||||
|    v2/extension |    v2/extension | ||||||
|    v2/floating_ip |    v2/floating_ip | ||||||
|    v2/health_monitor |    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 | # License for the specific language governing permissions and limitations | ||||||
| # under the License. | # under the License. | ||||||
|  |  | ||||||
|  | from openstack.network.v2 import availability_zone | ||||||
| from openstack.network.v2 import extension | from openstack.network.v2 import extension | ||||||
| from openstack.network.v2 import floating_ip as _floating_ip | from openstack.network.v2 import floating_ip as _floating_ip | ||||||
| from openstack.network.v2 import health_monitor as _health_monitor | from openstack.network.v2 import health_monitor as _health_monitor | ||||||
| @@ -34,6 +35,15 @@ from openstack import resource | |||||||
|  |  | ||||||
| class Proxy(proxy.BaseProxy): | 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): |     def find_extension(self, name_or_id, ignore_missing=True): | ||||||
|         """Find a single extension |         """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 |     #: The administrative state of the network, which is up ``True`` or | ||||||
|     #: down ``False``. *Type: bool* |     #: down ``False``. *Type: bool* | ||||||
|     admin_state_up = resource.prop('admin_state_up', 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. |     #: The network name. | ||||||
|     name = resource.prop('name') |     name = resource.prop('name') | ||||||
|     #: The project this network is associated with. |     #: 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`` |     #: The administrative state of the router, which is up ``True`` | ||||||
|     #: or down ``False``. *Type: bool* |     #: or down ``False``. *Type: bool* | ||||||
|     admin_state_up = resource.prop('admin_state_up', 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* |     #: The ``network_id``, for the external gateway. *Type: dict* | ||||||
|     external_gateway_info = resource.prop('external_gateway_info', type=dict) |     external_gateway_info = resource.prop('external_gateway_info', type=dict) | ||||||
|     #: The router name. |     #: 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', |     'subnets': '12', | ||||||
|     'mtu': 1400, |     'mtu': 1400, | ||||||
|     'port_security_enabled': True, |     '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['mtu'], sot.mtu) | ||||||
|         self.assertEqual(EXAMPLE['port_security_enabled'], |         self.assertEqual(EXAMPLE['port_security_enabled'], | ||||||
|                          sot.is_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): |     def test_external(self): | ||||||
|         sot = network.Network(EXAMPLE) |         sot = network.Network(EXAMPLE) | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ | |||||||
| import mock | import mock | ||||||
|  |  | ||||||
| from openstack.network.v2 import _proxy | from openstack.network.v2 import _proxy | ||||||
|  | from openstack.network.v2 import availability_zone | ||||||
| from openstack.network.v2 import extension | from openstack.network.v2 import extension | ||||||
| from openstack.network.v2 import floating_ip | from openstack.network.v2 import floating_ip | ||||||
| from openstack.network.v2 import health_monitor | from openstack.network.v2 import health_monitor | ||||||
| @@ -39,6 +40,11 @@ class TestNetworkProxy(test_proxy_base.TestProxyBase): | |||||||
|         super(TestNetworkProxy, self).setUp() |         super(TestNetworkProxy, self).setUp() | ||||||
|         self.proxy = _proxy.Proxy(self.session) |         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): |     def test_extension_find(self): | ||||||
|         self.verify_find(self.proxy.find_extension, extension.Extension) |         self.verify_find(self.proxy.find_extension, extension.Extension) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -24,6 +24,8 @@ EXAMPLE = { | |||||||
|     'tenant_id': '5', |     'tenant_id': '5', | ||||||
|     'status': '6', |     'status': '6', | ||||||
|     'routes': [], |     'routes': [], | ||||||
|  |     'availability_zone_hints': [], | ||||||
|  |     'availability_zones': [], | ||||||
| } | } | ||||||
|  |  | ||||||
| EXAMPLE_WITH_OPTIONAL = { | EXAMPLE_WITH_OPTIONAL = { | ||||||
| @@ -38,6 +40,8 @@ EXAMPLE_WITH_OPTIONAL = { | |||||||
|     'routes': [{'nexthop': '172.24.4.20', 'destination': '10.0.3.1/24'}], |     'routes': [{'nexthop': '172.24.4.20', 'destination': '10.0.3.1/24'}], | ||||||
|     'ha': True, |     'ha': True, | ||||||
|     'distributed': 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_ha) | ||||||
|         self.assertFalse(sot.is_distributed) |         self.assertFalse(sot.is_distributed) | ||||||
|         self.assertEqual(EXAMPLE['routes'], sot.routes) |         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): |     def test_make_it_with_optional(self): | ||||||
|         sot = router.Router(EXAMPLE_WITH_OPTIONAL) |         sot = router.Router(EXAMPLE_WITH_OPTIONAL) | ||||||
| @@ -82,6 +90,10 @@ class TestRouter(testtools.TestCase): | |||||||
|         self.assertEqual(EXAMPLE_WITH_OPTIONAL['distributed'], |         self.assertEqual(EXAMPLE_WITH_OPTIONAL['distributed'], | ||||||
|                          sot.is_distributed) |                          sot.is_distributed) | ||||||
|         self.assertEqual(EXAMPLE_WITH_OPTIONAL['routes'], sot.routes) |         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): |     def test_add_interface(self): | ||||||
|         sot = router.Router(EXAMPLE) |         sot = router.Router(EXAMPLE) | ||||||
|   | |||||||
| @@ -172,6 +172,15 @@ class TestProxyBase(base.TestCase): | |||||||
|                       expected_result=["result"], |                       expected_result=["result"], | ||||||
|                       **kwargs) |                       **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, |     def verify_update(self, test_method, resource_type, | ||||||
|                       mock_method="openstack.proxy.BaseProxy._update", |                       mock_method="openstack.proxy.BaseProxy._update", | ||||||
|                       expected_result="result", **kwargs): |                       expected_result="result", **kwargs): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jenkins
					Jenkins