Support listing availability zones

Zun has introduced an API endpoint for listing availability zones
(https://review.openstack.org/#/c/564670/). This patch is the client
side implementation. In particular, this patch does the following:
* Python API for listing availability zones
* A CLI command for listing availability zones
  (i.e. zun availability-zone-list)
* An OSC command for doing the same
  (i.e. openstack appcontainer availability zone list)

Related-Bug: #1766395
Change-Id: I6c0512816277a63bbf444d0775121bb5d964a36a
This commit is contained in:
Hongbin Lu 2018-05-31 03:49:42 +00:00
parent d24f41281b
commit fc98313850
9 changed files with 177 additions and 0 deletions

View File

@ -30,6 +30,7 @@ openstack.cli.extension =
container = zunclient.osc.plugin
openstack.container.v1 =
appcontainer_availability_zone_list = zunclient.osc.v1.availability_zones:ListAvailabilityZone
appcontainer_service_list = zunclient.osc.v1.services:ListService
appcontainer_service_delete = zunclient.osc.v1.services:DeleteService
appcontainer_service_enable = zunclient.osc.v1.services:EnableService

View File

@ -189,6 +189,13 @@ def list_containers(containers):
sortby_index=None)
def list_availability_zones(zones):
columns = ('availability_zone',)
utils.print_list(zones, columns,
{'versions': print_list_field('versions')},
sortby_index=None)
def parse_command(command):
output = []
if command:

View File

@ -0,0 +1,38 @@
# 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 oslo_log import log as logging
from osc_lib.command import command
from osc_lib import utils
def _get_client(obj, parsed_args):
obj.log.debug("take_action(%s)" % parsed_args)
return obj.app.client_manager.container
class ListAvailabilityZone(command.Lister):
"""List availability zones"""
log = logging.getLogger(__name__ + ".ListAvailabilityZones")
def get_parser(self, prog_name):
parser = super(ListAvailabilityZone, self).get_parser(prog_name)
return parser
def take_action(self, parsed_args):
client = _get_client(self, parsed_args)
zones = client.availability_zones.list()
columns = ('availability_zone',)
return (columns, (utils.get_item_properties(zone, columns)
for zone in zones))

View File

@ -0,0 +1,46 @@
# 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 testtools import matchers
from zunclient.tests.unit import utils
from zunclient.v1 import availability_zones as az
AZ1 = {'availability_zone': 'fake-az-1'}
AZ2 = {'availability_zone': 'fake-az-2'}
fake_responses = {
'/v1/availability_zones':
{
'GET': (
{},
{'availability_zones': [AZ1, AZ2]},
),
},
}
class AZManagerTest(testtools.TestCase):
def setUp(self):
super(AZManagerTest, self).setUp()
self.api = utils.FakeAPI(fake_responses)
self.mgr = az.AvailabilityZoneManager(self.api)
def test_availability_zones_list(self):
zones = self.mgr.list()
expect = [
('GET', '/v1/availability_zones', {}, None),
]
self.assertEqual(expect, self.api.calls)
self.assertThat(zones, matchers.HasLength(2))

View File

@ -0,0 +1,29 @@
# 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 mock
from zunclient.tests.unit.v1 import shell_test_base
class ShellTest(shell_test_base.TestCommandLineArgument):
@mock.patch('zunclient.v1.availability_zones.AvailabilityZoneManager.list')
def test_zun_service_list_success(self, mock_list):
self._test_arg_success('availability-zone-list')
self.assertTrue(mock_list.called)
@mock.patch('zunclient.v1.availability_zones.AvailabilityZoneManager.list')
def test_zun_service_list_failure(self, mock_list):
self._test_arg_failure('availability-zone-list --wrong',
self._unrecognized_arg_error)
self.assertFalse(mock_list.called)

View File

@ -0,0 +1,31 @@
# Copyright 2014 NEC Corporation. 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.
from zunclient.common import base
class AvailabilityZone(base.Resource):
def __repr__(self):
return "<AvailabilityZone %s>" % self._info
class AvailabilityZoneManager(base.Manager):
resource_class = AvailabilityZone
@staticmethod
def _path():
return '/v1/availability_zones'
def list(self, **kwargs):
return self._list(self._path(), "availability_zones", qparams=kwargs)

View File

@ -0,0 +1,21 @@
# Copyright 2015 NEC Corporation. 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.
from zunclient.common import utils as zun_utils
def do_availability_zone_list(cs, args):
"""Print a list of availability zones."""
zones = cs.availability_zones.list()
zun_utils.list_availability_zones(zones)

View File

@ -17,6 +17,7 @@ from keystoneauth1 import loading
from keystoneauth1 import session as ksa_session
from zunclient.common import httpclient
from zunclient.v1 import availability_zones as az
from zunclient.v1 import capsules
from zunclient.v1 import containers
from zunclient.v1 import hosts
@ -127,6 +128,7 @@ class Client(object):
self.hosts = hosts.HostManager(self.http_client)
self.versions = versions.VersionManager(self.http_client)
self.capsules = capsules.CapsuleManager(self.http_client)
self.availability_zones = az.AvailabilityZoneManager(self.http_client)
@property
def api_version(self):

View File

@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from zunclient.v1 import availability_zones_shell
from zunclient.v1 import capsules_shell
from zunclient.v1 import containers_shell
from zunclient.v1 import hosts_shell
@ -21,6 +22,7 @@ from zunclient.v1 import services_shell
from zunclient.v1 import versions_shell
COMMAND_MODULES = [
availability_zones_shell,
containers_shell,
images_shell,
services_shell,