Fix to be able to specify the name of the resource

The segment subcommand and host subcommand can specify
 the name of the resource.

Change-Id: I3fbdbdbcc21cc0f7b13351a9970631fc994b897f
Closes-Bug: #1643759
This commit is contained in:
Takahiro Izumi 2017-01-25 18:48:51 +09:00
parent 03653f09da
commit 82cab8ee35
8 changed files with 559 additions and 32 deletions

View File

@ -20,6 +20,7 @@ import textwrap
from oslo_serialization import jsonutils
from oslo_utils import encodeutils
from oslo_utils import importutils
from oslo_utils import uuidutils
from masakariclient.common import exception as exc
from masakariclient.common.i18n import _
@ -201,3 +202,28 @@ def format_sort_filter_params(parsed_args):
queries.update(format_parameters(parsed_args.filters))
return queries
def get_uuid_by_name(manager, name, segment=None):
"""Helper methods for getting uuid of segment or host by name.
:param manager: A client manager class
:param name: The resource we are trying to find a uuid
:param segment: segment id, default None
:return: The uuid of found resource
"""
# If it cannot be found return the name.
uuid = name
if not uuidutils.is_uuid_like(name):
if segment:
items = manager.hosts(segment)
else:
items = manager.segments()
for item in items:
item_name = getattr(item, 'name')
if item_name == name:
uuid = getattr(item, 'uuid')
break
return uuid

View File

@ -15,7 +15,6 @@
from openstack import exceptions as sdk_exc
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
from masakariclient.common.i18n import _
@ -97,9 +96,11 @@ class ShowHost(command.ShowOne):
def take_action(self, parsed_args):
masakari_client = self.app.client_manager.ha
return _show_host(masakari_client,
parsed_args.segment_id,
parsed_args.host)
uuid = masakariclient_utils.get_uuid_by_name(
masakari_client,
parsed_args.host,
segment=parsed_args.segment_id)
return _show_host(masakari_client, parsed_args.segment_id, uuid)
class CreateHost(command.ShowOne):
@ -202,6 +203,10 @@ class UpdateHost(command.ShowOne):
def take_action(self, parsed_args):
masakari_client = self.app.client_manager.ha
uuid = masakariclient_utils.get_uuid_by_name(
masakari_client,
parsed_args.host,
segment=parsed_args.segment_id)
attrs = {
'name': parsed_args.name,
'type': parsed_args.type,
@ -212,12 +217,15 @@ class UpdateHost(command.ShowOne):
# Remove not specified keys
attrs = masakariclient_utils.remove_unspecified_items(attrs)
masakari_client.update_host(segment_id=parsed_args.segment_id,
host=parsed_args.host,
**attrs)
return _show_host(masakari_client,
parsed_args.segment_id,
parsed_args.host)
try:
masakari_client.update_host(
segment_id=parsed_args.segment_id, host=uuid, **attrs)
except sdk_exc.NotFoundException:
# Reraise. To unify exceptions with other functions.
raise sdk_exc.ResourceNotFound(
_('No Host found for %s') % uuid)
return _show_host(masakari_client, parsed_args.segment_id, uuid)
class DeleteHost(command.ShowOne):
@ -239,17 +247,17 @@ class DeleteHost(command.ShowOne):
def take_action(self, parsed_args):
masakari_client = self.app.client_manager.ha
masakari_client.delete_host(parsed_args.segment_id,
parsed_args.host)
uuid = masakariclient_utils.get_uuid_by_name(
masakari_client,
parsed_args.host,
segment=parsed_args.segment_id)
masakari_client.delete_host(parsed_args.segment_id, uuid, False)
print('Host deleted: %s' % parsed_args.host)
return ({}, {})
def _show_host(masakari_client, segment_id, uuid):
try:
host = masakari_client.get_host(segment_id, uuid)
except sdk_exc.ResourceNotFound:
raise exceptions.CommandError(_('Host not found: %s') % uuid)
host = masakari_client.get_host(segment_id, uuid)
formatters = {}
columns = [

View File

@ -14,7 +14,6 @@
from openstack import exceptions as sdk_exc
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
from masakariclient.common.i18n import _
@ -86,8 +85,9 @@ class ShowSegment(command.ShowOne):
def take_action(self, parsed_args):
masakari_client = self.app.client_manager.ha
return _show_segment(masakari_client,
segment_uuid=parsed_args.segment)
uuid = masakariclient_utils.get_uuid_by_name(
masakari_client, parsed_args.segment)
return _show_segment(masakari_client, segment_uuid=uuid)
class CreateSegment(command.ShowOne):
@ -167,6 +167,10 @@ class UpdateSegment(command.ShowOne):
def take_action(self, parsed_args):
masakari_client = self.app.client_manager.ha
uuid = masakariclient_utils.get_uuid_by_name(
masakari_client, parsed_args.segment)
attrs = {
'name': parsed_args.name,
'description': parsed_args.description,
@ -176,10 +180,13 @@ class UpdateSegment(command.ShowOne):
# Remove not specified keys
attrs = masakariclient_utils.remove_unspecified_items(attrs)
masakari_client.update_segment(segment=parsed_args.segment,
**attrs)
return _show_segment(masakari_client,
parsed_args.segment)
try:
masakari_client.update_segment(segment=uuid, **attrs)
# Reraise. To unify exceptions with other functions.
except sdk_exc.NotFoundException:
raise sdk_exc.ResourceNotFound(
_('No Segment found for %s') % uuid)
return _show_segment(masakari_client, uuid)
class DeleteSegment(command.Command):
@ -197,21 +204,19 @@ class DeleteSegment(command.Command):
def take_action(self, parsed_args):
masakari_client = self.app.client_manager.ha
for sid in parsed_args.segment:
try:
masakari_client.delete_segment(sid, False)
uuid = masakariclient_utils.get_uuid_by_name(
masakari_client, sid)
masakari_client.delete_segment(uuid, False)
print('Segment deleted: %s' % sid)
except Exception as ex:
print(ex)
def _show_segment(masakari_client, segment_uuid):
try:
segment = masakari_client.get_segment(segment_uuid)
except sdk_exc.ResourceNotFound:
raise exceptions.CommandError(_('Segment not found: %s'
) % segment_uuid)
segment = masakari_client.get_segment(segment_uuid)
formatters = {}
columns = [

View File

@ -196,5 +196,5 @@ class Proxy(proxy2.BaseProxy):
"""
host_id = resource2.Resource._get_id(host)
self._delete(_host.Host, segment_id=segment_id, id=host_id,
ignore_missing=ignore_missing)
return self._delete(_host.Host, host_id, segment_id=segment_id,
ignore_missing=ignore_missing)

View File

@ -0,0 +1,238 @@
# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation
#
# 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.
"""
test_masakariclient
----------------------------------
Tests for `masakariclient` module.
"""
import mock
from osc_lib import utils
from masakariclient.osc.v1.host import DeleteHost
from masakariclient.osc.v1.host import ShowHost
from masakariclient.osc.v1.host import UpdateHost
from masakariclient.tests import base
class FakeNamespace(object):
"""Fake parser object."""
def __init__(self, segment_id=None, host=None,
reserved=None, name=None, type=None,
control_attributes=None, on_maintenance=None):
super(FakeNamespace, self).__init__()
self.segment_id = segment_id
self.host = host
self.reserved = reserved
self.name = name
self.type = type
self.control_attributes = control_attributes
self.on_maintenance = on_maintenance
class FakeHosts(object):
"""Fake segment host list."""
def __init__(self, name=None, uuid=None):
super(FakeHosts, self).__init__()
self.name = name
self.uuid = uuid
class FakeHost(object):
"""Fake segment show detail."""
def __init__(self,):
super(FakeHost, self).__init__()
def to_dict(self):
return {
'reserved': 'False',
'uuid': '124aa63c-bbe1-46c3-91a9-285fac7d86c6',
'segment_id': '870da19d-37ec-41d2-a4b2-7be54b0d6ec9',
'on_maintenance': False,
'created_at': '2016-12-18T05:47:55.000000',
'control_attributes': 'control_attributes',
'updated_at': None,
'name': 'host_name',
'type': 'auto',
'id': 18,
'failover_segment_id': '187dd15a-9c1d-4bf7-9f6c-014d5bc66992',
}
class TestV1ShowHost(base.TestCase):
def setUp(self):
super(TestV1ShowHost, self).setUp()
self.app = mock.Mock()
self.app_args = mock.Mock()
self.show_host = ShowHost(self.app, self.app_args,
cmd_name='host show')
self.client_manager = mock.Mock()
self.app.client_manager.ha = self.client_manager
self.columns = [
'created_at', 'updated_at', 'uuid', 'name', 'type',
'control_attributes', 'reserved', 'on_maintenance',
'failover_segment_id',
]
# fake host list
self.dummy_hosts = []
self.dummy_hosts.append(FakeHosts(
name='host_name',
uuid='124aa63c-bbe1-46c3-91a9-285fac7d86c6'))
# fake host show
self.dummy_host = FakeHost()
@mock.patch.object(utils, 'get_dict_properties')
def test_take_action_by_uuid(self, mock_get_dict_properties):
# command param
parsed_args = FakeNamespace(
segment_id='187dd15a-9c1d-4bf7-9f6c-014d5bc66992',
host='124aa63c-bbe1-46c3-91a9-285fac7d86c6')
# return value host list
self.app.client_manager.ha.hosts.return_value = self.dummy_hosts
# return value host show
self.app.client_manager.ha.get_host.return_value = self.dummy_host
# show the host specified by uuid
self.show_host.take_action(parsed_args)
mock_get_dict_properties.assert_called_once_with(
self.dummy_host.to_dict(), self.columns, formatters={})
@mock.patch.object(utils, 'get_dict_properties')
def test_take_action_by_name(self, mock_get_dict_properties):
# command param
parsed_args = FakeNamespace(
segment_id='187dd15a-9c1d-4bf7-9f6c-014d5bc66992',
host='host_name')
# return value host list
self.app.client_manager.ha.hosts.return_value = self.dummy_hosts
# return value host show
self.app.client_manager.ha.get_host.return_value = self.dummy_host
# show the host specified by name
self.show_host.take_action(parsed_args)
mock_get_dict_properties.assert_called_once_with(
self.dummy_host.to_dict(), self.columns, formatters={})
class TestV1UpdateHost(base.TestCase):
def setUp(self):
super(TestV1UpdateHost, self).setUp()
self.app = mock.Mock()
self.app_args = mock.Mock()
self.update_host = UpdateHost(self.app, self.app_args,
cmd_name='host update')
self.client_manager = mock.Mock()
self.app.client_manager.ha = self.client_manager
self.columns = [
'created_at', 'updated_at', 'uuid', 'name', 'type',
'control_attributes', 'reserved', 'on_maintenance',
'failover_segment_id',
]
# fake host list
self.dummy_hosts = []
self.dummy_hosts.append(FakeHosts(
name='host_name',
uuid='124aa63c-bbe1-46c3-91a9-285fac7d86c6'))
# fake host show
self.dummy_host = FakeHost()
@mock.patch.object(utils, 'get_dict_properties')
def test_take_action_by_uuid(self, mock_get_dict_properties):
# command param
parsed_args = FakeNamespace(
segment_id='187dd15a-9c1d-4bf7-9f6c-014d5bc66992',
host='124aa63c-bbe1-46c3-91a9-285fac7d86c6',
reserved=True)
# return value host list
self.app.client_manager.ha.hosts.return_value = self.dummy_hosts
# return value host show
self.app.client_manager.ha.get_host.return_value = self.dummy_host
# show the host specified by uuid
self.update_host.take_action(parsed_args)
mock_get_dict_properties.assert_called_once_with(
self.dummy_host.to_dict(), self.columns, formatters={})
@mock.patch.object(utils, 'get_dict_properties')
def test_take_action_by_name(self, mock_get_dict_properties):
# command param
parsed_args = FakeNamespace(
segment_id='187dd15a-9c1d-4bf7-9f6c-014d5bc66992',
host='host_name',
reserved=True)
# return value host list
self.app.client_manager.ha.hosts.return_value = self.dummy_hosts
# return value host show
self.app.client_manager.ha.get_host.return_value = self.dummy_host
# show the host specified by name
self.update_host.take_action(parsed_args)
mock_get_dict_properties.assert_called_once_with(
self.dummy_host.to_dict(), self.columns, formatters={})
class TestV1DeleteHost(base.TestCase):
def setUp(self):
super(TestV1DeleteHost, self).setUp()
self.app = mock.Mock()
self.app_args = mock.Mock()
self.delete_host = DeleteHost(self.app, self.app_args,
cmd_name='host update')
self.client_manager = mock.Mock()
self.app.client_manager.ha = self.client_manager
self.columns = [
'created_at', 'updated_at', 'uuid', 'name', 'type',
'control_attributes', 'reserved', 'on_maintenance',
'failover_segment_id',
]
# fake host list
self.dummy_hosts = []
self.dummy_hosts.append(FakeHosts(
name='host_name',
uuid='124aa63c-bbe1-46c3-91a9-285fac7d86c6'))
# fake host show
self.dummy_host = FakeHost()
def test_take_action_by_uuid(self):
# command param
parsed_args = FakeNamespace(
segment_id='187dd15a-9c1d-4bf7-9f6c-014d5bc66992',
host='124aa63c-bbe1-46c3-91a9-285fac7d86c6')
# return value host list
self.app.client_manager.ha.hosts.return_value = self.dummy_hosts
# return value host show
self.app.client_manager.ha.get_host.return_value =\
self.dummy_host
# show the host specified by uuid
self.delete_host.take_action(parsed_args)
def test_take_action_by_name(self):
# command param
parsed_args = FakeNamespace(
segment_id='187dd15a-9c1d-4bf7-9f6c-014d5bc66992',
host='host_name')
# return value host list
self.app.client_manager.ha.hosts.return_value = self.dummy_hosts
# return value host show
self.app.client_manager.ha.get_host.return_value =\
self.dummy_host
# show the host specified by name
self.delete_host.take_action(parsed_args)

View File

@ -0,0 +1,250 @@
# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation
#
# 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.
"""
test_masakariclient
----------------------------------
Tests for `masakariclient` module.
"""
import mock
from osc_lib import utils
from masakariclient.osc.v1.segment import DeleteSegment
from masakariclient.osc.v1.segment import ShowSegment
from masakariclient.osc.v1.segment import UpdateSegment
from masakariclient.tests import base
class FakeNamespace(object):
"""Fake parser object."""
def __init__(self, segment=None, name=None,
description=None,
recovery_method=None, service_type=None):
super(FakeNamespace, self).__init__()
self.segment = segment
self.name = name
self.description = description
self.recovery_method = recovery_method
self.service_type = service_type
class FakeSegments(object):
"""Fake segment list."""
def __init__(self, name=None, uuid=None,
description=None,
recovery_method=None, service_type=None):
super(FakeSegments, self).__init__()
self.name = name
self.uuid = uuid
self.description = description
self.recovery_method = recovery_method
self.service_type = service_type
class FakeSegment(object):
"""Fake segment show detail."""
def __init__(self,):
super(FakeSegment, self).__init__()
def to_dict(self):
return {
'created_at': '2016-12-18T05:47:46.000000',
'updated_at': '2016-12-18T06:05:16.000000',
'uuid': '187dd15a-9c1d-4bf7-9f6c-014d5bc66992',
'name': 'test_segment',
'description': 'test_segment_description',
'id': 1,
'service_type': 'test_type',
'recovery_method': 'auto',
}
class TestV1ShowSegment(base.TestCase):
def setUp(self):
super(TestV1ShowSegment, self).setUp()
self.app = mock.Mock()
self.app_args = mock.Mock()
self.show_seg = ShowSegment(self.app,
self.app_args,
cmd_name='segment show')
self.client_manager = mock.Mock()
self.app.client_manager.ha = self.client_manager
self.columns = ['created_at', 'updated_at', 'uuid',
'name', 'description', 'id', 'service_type',
'recovery_method',
]
# return value segment list
self.dummy_segments = []
self.dummy_segments.append(FakeSegments(
name='segment_name',
uuid='187dd15a-9c1d-4bf7-9f6c-014d5bc66992'))
# return value segment show
self.dummy_segment = FakeSegment()
@mock.patch.object(utils, 'get_dict_properties')
def test_take_action_by_uuid(self, mock_get_dict_properties):
# command param
parsed_args = FakeNamespace(
segment='187dd15a-9c1d-4bf7-9f6c-014d5bc66992')
# return value segment list
self.app.client_manager.ha.segments.return_value =\
self.dummy_segments
# return value segment show
self.app.client_manager.ha.get_segment.return_value =\
self.dummy_segment
# show segment
self.show_seg.take_action(parsed_args)
mock_get_dict_properties.assert_called_once_with(
self.dummy_segment.to_dict(), self.columns, formatters={})
@mock.patch.object(utils, 'get_dict_properties')
def test_take_action_by_name(self, mock_get_dict_properties):
# command param
parsed_args = FakeNamespace(segment='segment_name')
# return value segment list
dummy_segments = []
dummy_segments.append(FakeSegments(
name='segment_name',
uuid='187dd15a-9c1d-4bf7-9f6c-014d5bc66992'))
self.app.client_manager.ha.segments.return_value =\
dummy_segments
# return value segment show
dummy_segment = FakeSegment()
self.app.client_manager.ha.get_segment.return_value =\
dummy_segment
# show segment
self.show_seg.take_action(parsed_args)
mock_get_dict_properties.assert_called_once_with(
dummy_segment.to_dict(), self.columns, formatters={})
class TestV1UpdateSegment(base.TestCase):
def setUp(self):
super(TestV1UpdateSegment, self).setUp()
self.app = mock.Mock()
self.app_args = mock.Mock()
self.update_seg = UpdateSegment(self.app,
self.app_args,
cmd_name='segment update')
self.client_manager = mock.Mock()
self.app.client_manager.ha = self.client_manager
self.columns = ['created_at', 'updated_at', 'uuid',
'name', 'description', 'id', 'service_type',
'recovery_method',
]
# segment list
self.dummy_segments = []
self.dummy_segments.append(FakeSegments(
name='segment_name',
uuid='187dd15a-9c1d-4bf7-9f6c-014d5bc66992',
description='FakeNamespace_description',
recovery_method='Update_recovery_method',
service_type='test_type'))
# segment data setup
self.dummy_segment = FakeSegment()
@mock.patch.object(utils, 'get_dict_properties')
def test_take_action_by_uuid(self, mock_get_dict_properties):
# command param
parsed_args = FakeNamespace(
segment='187dd15a-9c1d-4bf7-9f6c-014d5bc66992',
description='FakeNamespace_description')
# return value segment list
self.app.client_manager.ha.segments.return_value =\
self.dummy_segments
# return value segment data setup
self.app.client_manager.ha.get_segment.return_value =\
self.dummy_segment
# segment update
self.update_seg.take_action(parsed_args)
mock_get_dict_properties.assert_called_once_with(
self.dummy_segment.to_dict(), self.columns, formatters={})
@mock.patch.object(utils, 'get_dict_properties')
def test_take_action_by_name(self, mock_get_dict_properties):
# command param
parsed_args = FakeNamespace(segment='segment_name')
# return value segment list
self.app.client_manager.ha.segments.return_value =\
self.dummy_segments
# return value segment data setup
self.app.client_manager.ha.get_segment.return_value =\
self.dummy_segment
# segment update
self.update_seg.take_action(parsed_args)
mock_get_dict_properties.assert_called_once_with(
self.dummy_segment.to_dict(), self.columns, formatters={})
class TestV1DeleteSegment(base.TestCase):
def setUp(self):
super(TestV1DeleteSegment, self).setUp()
self.app = mock.Mock()
self.app_args = mock.Mock()
self.delete_seg = DeleteSegment(self.app,
self.app_args,
cmd_name='segment delete')
self.client_manager = mock.Mock()
self.app.client_manager.ha = self.client_manager
# segment list
self.dummy_segments = []
self.dummy_segments.append(FakeSegments(
name='segment_name',
uuid='187dd15a-9c1d-4bf7-9f6c-014d5bc66992',
description='FakeNamespace_description',
recovery_method='Update_recovery_method',
service_type='test_type'))
# segment
self.dummy_segment = FakeSegment()
def test_take_action_by_uuid(self):
# command param
parsed_args = FakeNamespace(
segment='187dd15a-9c1d-4bf7-9f6c-014d5bc66992')
# return_value segment list
self.app.client_manager.ha.segments.return_value =\
self.dummy_segments
# return_value segment delete
self.app.client_manager.ha.delete_segment.return_value =\
self.dummy_segment
# segment delete
self.delete_seg.take_action(parsed_args)
def test_take_action_by_name(self):
# command param
parsed_args = FakeNamespace(segment='segment_name')
# return_value segment list
self.app.client_manager.ha.segments.return_value =\
self.dummy_segments
# return_value segment delete
self.app.client_manager.ha.delete_segment.return_value =\
self.dummy_segment
# segment delete
self.delete_seg.take_action(parsed_args)