Merge "Add availability-zone-list command"
This commit is contained in:
		| @@ -558,3 +558,58 @@ class FakeHTTPClient(base_client.HTTPClient): | ||||
|     def put_os_services_disable(self, body, **kw): | ||||
|         return (200, {}, {'host': body['host'], 'binary': body['binary'], | ||||
|                 'status': 'enabled'}) | ||||
|  | ||||
|     def get_os_availability_zone(self, **kw): | ||||
|         return (200, {}, { | ||||
|             "availabilityZoneInfo": [ | ||||
|                 { | ||||
|                     "zoneName": "zone-1", | ||||
|                     "zoneState": {"available": True}, | ||||
|                     "hosts": None, | ||||
|                 }, | ||||
|                 { | ||||
|                     "zoneName": "zone-2", | ||||
|                     "zoneState": {"available": False}, | ||||
|                     "hosts": None, | ||||
|                 }, | ||||
|                 ] | ||||
|         }) | ||||
|  | ||||
|     def get_os_availability_zone_detail(self, **kw): | ||||
|         return (200, {}, { | ||||
|             "availabilityZoneInfo": [ | ||||
|                 { | ||||
|                     "zoneName": "zone-1", | ||||
|                     "zoneState": {"available": True}, | ||||
|                     "hosts": { | ||||
|                         "fake_host-1": { | ||||
|                             "cinder-volume": { | ||||
|                                 "active": True, | ||||
|                                 "available": True, | ||||
|                                 "updated_at": | ||||
|                                 datetime(2012, 12, 26, 14, 45, 25, 0) | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     "zoneName": "internal", | ||||
|                     "zoneState": {"available": True}, | ||||
|                     "hosts": { | ||||
|                         "fake_host-1": { | ||||
|                             "cinder-sched": { | ||||
|                                 "active": True, | ||||
|                                 "available": True, | ||||
|                                 "updated_at": | ||||
|                                 datetime(2012, 12, 26, 14, 45, 24, 0) | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     "zoneName": "zone-2", | ||||
|                     "zoneState": {"available": False}, | ||||
|                     "hosts": None, | ||||
|                 }, | ||||
|                 ] | ||||
|         }) | ||||
|   | ||||
							
								
								
									
										87
									
								
								cinderclient/tests/v1/test_availability_zone.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								cinderclient/tests/v1/test_availability_zone.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| # Copyright 2011-2013 OpenStack Foundation | ||||
| # Copyright 2013 IBM Corp. | ||||
| # All Rights Reserved. | ||||
| # | ||||
| #    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 cinderclient.v1 import availability_zones | ||||
| from cinderclient.v1 import shell | ||||
| from cinderclient.tests import utils | ||||
| from cinderclient.tests.v1 import fakes | ||||
|  | ||||
|  | ||||
| cs = fakes.FakeClient() | ||||
|  | ||||
|  | ||||
| class AvailabilityZoneTest(utils.TestCase): | ||||
|  | ||||
|     def _assertZone(self, zone, name, status): | ||||
|         self.assertEqual(zone.zoneName, name) | ||||
|         self.assertEqual(zone.zoneState, status) | ||||
|  | ||||
|     def test_list_availability_zone(self): | ||||
|         zones = cs.availability_zones.list(detailed=False) | ||||
|         cs.assert_called('GET', '/os-availability-zone') | ||||
|  | ||||
|         for zone in zones: | ||||
|             self.assertTrue(isinstance(zone, | ||||
|                                        availability_zones.AvailabilityZone)) | ||||
|  | ||||
|         self.assertEqual(2, len(zones)) | ||||
|  | ||||
|         l0 = [six.u('zone-1'), six.u('available')] | ||||
|         l1 = [six.u('zone-2'), six.u('not available')] | ||||
|  | ||||
|         z0 = shell._treeizeAvailabilityZone(zones[0]) | ||||
|         z1 = shell._treeizeAvailabilityZone(zones[1]) | ||||
|  | ||||
|         self.assertEqual((len(z0), len(z1)), (1, 1)) | ||||
|  | ||||
|         self._assertZone(z0[0], l0[0], l0[1]) | ||||
|         self._assertZone(z1[0], l1[0], l1[1]) | ||||
|  | ||||
|     def test_detail_availability_zone(self): | ||||
|         zones = cs.availability_zones.list(detailed=True) | ||||
|         cs.assert_called('GET', '/os-availability-zone/detail') | ||||
|  | ||||
|         for zone in zones: | ||||
|             self.assertTrue(isinstance(zone, | ||||
|                                        availability_zones.AvailabilityZone)) | ||||
|  | ||||
|         self.assertEqual(3, len(zones)) | ||||
|  | ||||
|         l0 = [six.u('zone-1'), six.u('available')] | ||||
|         l1 = [six.u('|- fake_host-1'), six.u('')] | ||||
|         l2 = [six.u('| |- cinder-volume'), | ||||
|               six.u('enabled :-) 2012-12-26 14:45:25')] | ||||
|         l3 = [six.u('internal'), six.u('available')] | ||||
|         l4 = [six.u('|- fake_host-1'), six.u('')] | ||||
|         l5 = [six.u('| |- cinder-sched'), | ||||
|               six.u('enabled :-) 2012-12-26 14:45:24')] | ||||
|         l6 = [six.u('zone-2'), six.u('not available')] | ||||
|  | ||||
|         z0 = shell._treeizeAvailabilityZone(zones[0]) | ||||
|         z1 = shell._treeizeAvailabilityZone(zones[1]) | ||||
|         z2 = shell._treeizeAvailabilityZone(zones[2]) | ||||
|  | ||||
|         self.assertEqual((len(z0), len(z1), len(z2)), (3, 3, 1)) | ||||
|  | ||||
|         self._assertZone(z0[0], l0[0], l0[1]) | ||||
|         self._assertZone(z0[1], l1[0], l1[1]) | ||||
|         self._assertZone(z0[2], l2[0], l2[1]) | ||||
|         self._assertZone(z1[0], l3[0], l3[1]) | ||||
|         self._assertZone(z1[1], l4[0], l4[1]) | ||||
|         self._assertZone(z1[2], l5[0], l5[1]) | ||||
|         self._assertZone(z2[0], l6[0], l6[1]) | ||||
| @@ -105,6 +105,10 @@ class ShellTest(utils.TestCase): | ||||
|         self.run_command('list --all-tenants=1') | ||||
|         self.assert_called('GET', '/volumes/detail?all_tenants=1') | ||||
|  | ||||
|     def test_list_availability_zone(self): | ||||
|         self.run_command('availability-zone-list') | ||||
|         self.assert_called('GET', '/os-availability-zone') | ||||
|  | ||||
|     def test_show(self): | ||||
|         self.run_command('show 1234') | ||||
|         self.assert_called('GET', '/volumes/1234') | ||||
|   | ||||
| @@ -565,3 +565,58 @@ class FakeHTTPClient(base_client.HTTPClient): | ||||
|     def put_os_services_disable(self, body, **kw): | ||||
|         return (200, {}, {'host': body['host'], 'binary': body['binary'], | ||||
|                 'status': 'enabled'}) | ||||
|  | ||||
|     def get_os_availability_zone(self, **kw): | ||||
|         return (200, {}, { | ||||
|             "availabilityZoneInfo": [ | ||||
|                 { | ||||
|                     "zoneName": "zone-1", | ||||
|                     "zoneState": {"available": True}, | ||||
|                     "hosts": None, | ||||
|                 }, | ||||
|                 { | ||||
|                     "zoneName": "zone-2", | ||||
|                     "zoneState": {"available": False}, | ||||
|                     "hosts": None, | ||||
|                 }, | ||||
|                 ] | ||||
|         }) | ||||
|  | ||||
|     def get_os_availability_zone_detail(self, **kw): | ||||
|         return (200, {}, { | ||||
|             "availabilityZoneInfo": [ | ||||
|                 { | ||||
|                     "zoneName": "zone-1", | ||||
|                     "zoneState": {"available": True}, | ||||
|                     "hosts": { | ||||
|                         "fake_host-1": { | ||||
|                             "cinder-volume": { | ||||
|                                 "active": True, | ||||
|                                 "available": True, | ||||
|                                 "updated_at": | ||||
|                                 datetime(2012, 12, 26, 14, 45, 25, 0) | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     "zoneName": "internal", | ||||
|                     "zoneState": {"available": True}, | ||||
|                     "hosts": { | ||||
|                         "fake_host-1": { | ||||
|                             "cinder-sched": { | ||||
|                                 "active": True, | ||||
|                                 "available": True, | ||||
|                                 "updated_at": | ||||
|                                 datetime(2012, 12, 26, 14, 45, 24, 0) | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     "zoneName": "zone-2", | ||||
|                     "zoneState": {"available": False}, | ||||
|                     "hosts": None, | ||||
|                 }, | ||||
|                 ] | ||||
|         }) | ||||
|   | ||||
							
								
								
									
										87
									
								
								cinderclient/tests/v2/test_availability_zone.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								cinderclient/tests/v2/test_availability_zone.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| # Copyright 2011-2013 OpenStack Foundation | ||||
| # Copyright 2013 IBM Corp. | ||||
| # All Rights Reserved. | ||||
| # | ||||
| #    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 cinderclient.v1 import availability_zones | ||||
| from cinderclient.v1 import shell | ||||
| from cinderclient.tests import utils | ||||
| from cinderclient.tests.v1 import fakes | ||||
|  | ||||
|  | ||||
| cs = fakes.FakeClient() | ||||
|  | ||||
|  | ||||
| class AvailabilityZoneTest(utils.TestCase): | ||||
|  | ||||
|     def _assertZone(self, zone, name, status): | ||||
|         self.assertEqual(zone.zoneName, name) | ||||
|         self.assertEqual(zone.zoneState, status) | ||||
|  | ||||
|     def test_list_availability_zone(self): | ||||
|         zones = cs.availability_zones.list(detailed=False) | ||||
|         cs.assert_called('GET', '/os-availability-zone') | ||||
|  | ||||
|         for zone in zones: | ||||
|             self.assertTrue(isinstance(zone, | ||||
|                                        availability_zones.AvailabilityZone)) | ||||
|  | ||||
|         self.assertEqual(2, len(zones)) | ||||
|  | ||||
|         l0 = [six.u('zone-1'), six.u('available')] | ||||
|         l1 = [six.u('zone-2'), six.u('not available')] | ||||
|  | ||||
|         z0 = shell._treeizeAvailabilityZone(zones[0]) | ||||
|         z1 = shell._treeizeAvailabilityZone(zones[1]) | ||||
|  | ||||
|         self.assertEqual((len(z0), len(z1)), (1, 1)) | ||||
|  | ||||
|         self._assertZone(z0[0], l0[0], l0[1]) | ||||
|         self._assertZone(z1[0], l1[0], l1[1]) | ||||
|  | ||||
|     def test_detail_availability_zone(self): | ||||
|         zones = cs.availability_zones.list(detailed=True) | ||||
|         cs.assert_called('GET', '/os-availability-zone/detail') | ||||
|  | ||||
|         for zone in zones: | ||||
|             self.assertTrue(isinstance(zone, | ||||
|                                        availability_zones.AvailabilityZone)) | ||||
|  | ||||
|         self.assertEqual(3, len(zones)) | ||||
|  | ||||
|         l0 = [six.u('zone-1'), six.u('available')] | ||||
|         l1 = [six.u('|- fake_host-1'), six.u('')] | ||||
|         l2 = [six.u('| |- cinder-volume'), | ||||
|               six.u('enabled :-) 2012-12-26 14:45:25')] | ||||
|         l3 = [six.u('internal'), six.u('available')] | ||||
|         l4 = [six.u('|- fake_host-1'), six.u('')] | ||||
|         l5 = [six.u('| |- cinder-sched'), | ||||
|               six.u('enabled :-) 2012-12-26 14:45:24')] | ||||
|         l6 = [six.u('zone-2'), six.u('not available')] | ||||
|  | ||||
|         z0 = shell._treeizeAvailabilityZone(zones[0]) | ||||
|         z1 = shell._treeizeAvailabilityZone(zones[1]) | ||||
|         z2 = shell._treeizeAvailabilityZone(zones[2]) | ||||
|  | ||||
|         self.assertEqual((len(z0), len(z1), len(z2)), (3, 3, 1)) | ||||
|  | ||||
|         self._assertZone(z0[0], l0[0], l0[1]) | ||||
|         self._assertZone(z0[1], l1[0], l1[1]) | ||||
|         self._assertZone(z0[2], l2[0], l2[1]) | ||||
|         self._assertZone(z1[0], l3[0], l3[1]) | ||||
|         self._assertZone(z1[1], l4[0], l4[1]) | ||||
|         self._assertZone(z1[2], l5[0], l5[1]) | ||||
|         self._assertZone(z2[0], l6[0], l6[1]) | ||||
| @@ -83,6 +83,10 @@ class ShellTest(utils.TestCase): | ||||
|         self.run_command('list --all-tenants=1') | ||||
|         self.assert_called('GET', '/volumes/detail?all_tenants=1') | ||||
|  | ||||
|     def test_list_availability_zone(self): | ||||
|         self.run_command('availability-zone-list') | ||||
|         self.assert_called('GET', '/os-availability-zone') | ||||
|  | ||||
|     def test_show(self): | ||||
|         self.run_command('show 1234') | ||||
|         self.assert_called('GET', '/volumes/1234') | ||||
|   | ||||
							
								
								
									
										42
									
								
								cinderclient/v1/availability_zones.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								cinderclient/v1/availability_zones.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| # Copyright 2011-2013 OpenStack Foundation | ||||
| # Copyright 2013 IBM Corp. | ||||
| # All Rights Reserved. | ||||
| # | ||||
| #    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. | ||||
|  | ||||
| """Availability Zone interface (v1 extension)""" | ||||
|  | ||||
| from cinderclient import base | ||||
|  | ||||
|  | ||||
| class AvailabilityZone(base.Resource): | ||||
|     NAME_ATTR = 'display_name' | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return "<AvailabilityZone: %s>" % self.zoneName | ||||
|  | ||||
|  | ||||
| class AvailabilityZoneManager(base.ManagerWithFind): | ||||
|     """Manage :class:`AvailabilityZone` resources.""" | ||||
|     resource_class = AvailabilityZone | ||||
|  | ||||
|     def list(self, detailed=False): | ||||
|         """Get a list of all availability zones | ||||
|  | ||||
|         :rtype: list of :class:`AvailabilityZone` | ||||
|         """ | ||||
|         if detailed is True: | ||||
|             return self._list("/os-availability-zone/detail", | ||||
|                               "availabilityZoneInfo") | ||||
|         else: | ||||
|             return self._list("/os-availability-zone", "availabilityZoneInfo") | ||||
| @@ -14,6 +14,7 @@ | ||||
| #    under the License. | ||||
|  | ||||
| from cinderclient import client | ||||
| from cinderclient.v1 import availability_zones | ||||
| from cinderclient.v1 import limits | ||||
| from cinderclient.v1 import quota_classes | ||||
| from cinderclient.v1 import quotas | ||||
| @@ -64,6 +65,8 @@ class Client(object): | ||||
|         self.restores = volume_backups_restore.VolumeBackupRestoreManager(self) | ||||
|         self.transfers = volume_transfers.VolumeTransferManager(self) | ||||
|         self.services = services.ServiceManager(self) | ||||
|         self.availability_zones = \ | ||||
|             availability_zones.AvailabilityZoneManager(self) | ||||
|  | ||||
|         # Add in any extensions... | ||||
|         if extensions: | ||||
|   | ||||
| @@ -18,12 +18,14 @@ | ||||
| from __future__ import print_function | ||||
|  | ||||
| import argparse | ||||
| import copy | ||||
| import os | ||||
| import sys | ||||
| import time | ||||
|  | ||||
| from cinderclient import exceptions | ||||
| from cinderclient import utils | ||||
| from cinderclient.v1 import availability_zones | ||||
|  | ||||
|  | ||||
| def _poll_for_status(poll_fn, obj_id, action, final_ok_states, | ||||
| @@ -108,6 +110,11 @@ def _translate_volume_snapshot_keys(collection): | ||||
|     _translate_keys(collection, convert) | ||||
|  | ||||
|  | ||||
| def _translate_availability_zone_keys(collection): | ||||
|     convert = [('zoneName', 'name'), ('zoneState', 'status')] | ||||
|     _translate_keys(collection, convert) | ||||
|  | ||||
|  | ||||
| def _extract_metadata(args): | ||||
|     metadata = {} | ||||
|     for metadatum in args.metadata: | ||||
| @@ -863,3 +870,63 @@ def do_service_enable(cs, args): | ||||
| def do_service_disable(cs, args): | ||||
|     """Disable the service.""" | ||||
|     cs.services.disable(args.host, args.binary) | ||||
|  | ||||
|  | ||||
| def _treeizeAvailabilityZone(zone): | ||||
|     """Build a tree view for availability zones.""" | ||||
|     AvailabilityZone = availability_zones.AvailabilityZone | ||||
|  | ||||
|     az = AvailabilityZone(zone.manager, | ||||
|                           copy.deepcopy(zone._info), zone._loaded) | ||||
|     result = [] | ||||
|  | ||||
|     # Zone tree view item | ||||
|     az.zoneName = zone.zoneName | ||||
|     az.zoneState = ('available' | ||||
|                     if zone.zoneState['available'] else 'not available') | ||||
|     az._info['zoneName'] = az.zoneName | ||||
|     az._info['zoneState'] = az.zoneState | ||||
|     result.append(az) | ||||
|  | ||||
|     if getattr(zone, "hosts", None) and zone.hosts is not None: | ||||
|         for (host, services) in zone.hosts.items(): | ||||
|             # Host tree view item | ||||
|             az = AvailabilityZone(zone.manager, | ||||
|                                   copy.deepcopy(zone._info), zone._loaded) | ||||
|             az.zoneName = '|- %s' % host | ||||
|             az.zoneState = '' | ||||
|             az._info['zoneName'] = az.zoneName | ||||
|             az._info['zoneState'] = az.zoneState | ||||
|             result.append(az) | ||||
|  | ||||
|             for (svc, state) in services.items(): | ||||
|                 # Service tree view item | ||||
|                 az = AvailabilityZone(zone.manager, | ||||
|                                       copy.deepcopy(zone._info), zone._loaded) | ||||
|                 az.zoneName = '| |- %s' % svc | ||||
|                 az.zoneState = '%s %s %s' % ( | ||||
|                                'enabled' if state['active'] else 'disabled', | ||||
|                                ':-)' if state['available'] else 'XXX', | ||||
|                                state['updated_at']) | ||||
|                 az._info['zoneName'] = az.zoneName | ||||
|                 az._info['zoneState'] = az.zoneState | ||||
|                 result.append(az) | ||||
|     return result | ||||
|  | ||||
|  | ||||
| @utils.service_type('volume') | ||||
| def do_availability_zone_list(cs, _args): | ||||
|     """List all the availability zones.""" | ||||
|     try: | ||||
|         availability_zones = cs.availability_zones.list() | ||||
|     except exceptions.Forbidden as e:  # policy doesn't allow probably | ||||
|         try: | ||||
|             availability_zones = cs.availability_zones.list(detailed=False) | ||||
|         except Exception: | ||||
|             raise e | ||||
|  | ||||
|     result = [] | ||||
|     for zone in availability_zones: | ||||
|         result += _treeizeAvailabilityZone(zone) | ||||
|     _translate_availability_zone_keys(result) | ||||
|     utils.print_list(result, ['Name', 'Status']) | ||||
|   | ||||
							
								
								
									
										42
									
								
								cinderclient/v2/availability_zones.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								cinderclient/v2/availability_zones.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| # Copyright 2011-2013 OpenStack Foundation | ||||
| # Copyright 2013 IBM Corp. | ||||
| # All Rights Reserved. | ||||
| # | ||||
| #    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. | ||||
|  | ||||
| """Availability Zone interface (v2 extension)""" | ||||
|  | ||||
| from cinderclient import base | ||||
|  | ||||
|  | ||||
| class AvailabilityZone(base.Resource): | ||||
|     NAME_ATTR = 'display_name' | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return "<AvailabilityZone: %s>" % self.zoneName | ||||
|  | ||||
|  | ||||
| class AvailabilityZoneManager(base.ManagerWithFind): | ||||
|     """Manage :class:`AvailabilityZone` resources.""" | ||||
|     resource_class = AvailabilityZone | ||||
|  | ||||
|     def list(self, detailed=False): | ||||
|         """Get a list of all availability zones | ||||
|  | ||||
|         :rtype: list of :class:`AvailabilityZone` | ||||
|         """ | ||||
|         if detailed is True: | ||||
|             return self._list("/os-availability-zone/detail", | ||||
|                               "availabilityZoneInfo") | ||||
|         else: | ||||
|             return self._list("/os-availability-zone", "availabilityZoneInfo") | ||||
| @@ -14,6 +14,7 @@ | ||||
| #    under the License. | ||||
|  | ||||
| from cinderclient import client | ||||
| from cinderclient.v1 import availability_zones | ||||
| from cinderclient.v2 import limits | ||||
| from cinderclient.v2 import quota_classes | ||||
| from cinderclient.v2 import quotas | ||||
| @@ -62,6 +63,8 @@ class Client(object): | ||||
|         self.restores = volume_backups_restore.VolumeBackupRestoreManager(self) | ||||
|         self.transfers = volume_transfers.VolumeTransferManager(self) | ||||
|         self.services = services.ServiceManager(self) | ||||
|         self.availability_zones = \ | ||||
|             availability_zones.AvailabilityZoneManager(self) | ||||
|  | ||||
|         # Add in any extensions... | ||||
|         if extensions: | ||||
|   | ||||
| @@ -16,6 +16,7 @@ | ||||
| from __future__ import print_function | ||||
|  | ||||
| import argparse | ||||
| import copy | ||||
| import os | ||||
| import sys | ||||
| import time | ||||
| @@ -24,6 +25,7 @@ import six | ||||
|  | ||||
| from cinderclient import exceptions | ||||
| from cinderclient import utils | ||||
| from cinderclient.v2 import availability_zones | ||||
|  | ||||
|  | ||||
| def _poll_for_status(poll_fn, obj_id, action, final_ok_states, | ||||
| @@ -102,6 +104,11 @@ def _translate_volume_snapshot_keys(collection): | ||||
|     _translate_keys(collection, convert) | ||||
|  | ||||
|  | ||||
| def _translate_availability_zone_keys(collection): | ||||
|     convert = [('zoneName', 'name'), ('zoneState', 'status')] | ||||
|     _translate_keys(collection, convert) | ||||
|  | ||||
|  | ||||
| def _extract_metadata(args): | ||||
|     metadata = {} | ||||
|     for metadatum in args.metadata[0]: | ||||
| @@ -948,3 +955,63 @@ def do_service_enable(cs, args): | ||||
| def do_service_disable(cs, args): | ||||
|     """Disable the service.""" | ||||
|     cs.services.disable(args.host, args.binary) | ||||
|  | ||||
|  | ||||
| def _treeizeAvailabilityZone(zone): | ||||
|     """Build a tree view for availability zones.""" | ||||
|     AvailabilityZone = availability_zones.AvailabilityZone | ||||
|  | ||||
|     az = AvailabilityZone(zone.manager, | ||||
|                           copy.deepcopy(zone._info), zone._loaded) | ||||
|     result = [] | ||||
|  | ||||
|     # Zone tree view item | ||||
|     az.zoneName = zone.zoneName | ||||
|     az.zoneState = ('available' | ||||
|                     if zone.zoneState['available'] else 'not available') | ||||
|     az._info['zoneName'] = az.zoneName | ||||
|     az._info['zoneState'] = az.zoneState | ||||
|     result.append(az) | ||||
|  | ||||
|     if getattr(zone, "hosts", None) and zone.hosts is not None: | ||||
|         for (host, services) in zone.hosts.items(): | ||||
|             # Host tree view item | ||||
|             az = AvailabilityZone(zone.manager, | ||||
|                                   copy.deepcopy(zone._info), zone._loaded) | ||||
|             az.zoneName = '|- %s' % host | ||||
|             az.zoneState = '' | ||||
|             az._info['zoneName'] = az.zoneName | ||||
|             az._info['zoneState'] = az.zoneState | ||||
|             result.append(az) | ||||
|  | ||||
|             for (svc, state) in services.items(): | ||||
|                 # Service tree view item | ||||
|                 az = AvailabilityZone(zone.manager, | ||||
|                                       copy.deepcopy(zone._info), zone._loaded) | ||||
|                 az.zoneName = '| |- %s' % svc | ||||
|                 az.zoneState = '%s %s %s' % ( | ||||
|                                'enabled' if state['active'] else 'disabled', | ||||
|                                ':-)' if state['available'] else 'XXX', | ||||
|                                state['updated_at']) | ||||
|                 az._info['zoneName'] = az.zoneName | ||||
|                 az._info['zoneState'] = az.zoneState | ||||
|                 result.append(az) | ||||
|     return result | ||||
|  | ||||
|  | ||||
| @utils.service_type('volume') | ||||
| def do_availability_zone_list(cs, _args): | ||||
|     """List all the availability zones.""" | ||||
|     try: | ||||
|         availability_zones = cs.availability_zones.list() | ||||
|     except exceptions.Forbidden as e:  # policy doesn't allow probably | ||||
|         try: | ||||
|             availability_zones = cs.availability_zones.list(detailed=False) | ||||
|         except Exception: | ||||
|             raise e | ||||
|  | ||||
|     result = [] | ||||
|     for zone in availability_zones: | ||||
|         result += _treeizeAvailabilityZone(zone) | ||||
|     _translate_availability_zone_keys(result) | ||||
|     utils.print_list(result, ['Name', 'Status']) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jenkins
					Jenkins