diff --git a/magnumclient/common/httpclient.py b/magnumclient/common/httpclient.py index ecf7e4a..3fd21e1 100644 --- a/magnumclient/common/httpclient.py +++ b/magnumclient/common/httpclient.py @@ -44,6 +44,12 @@ def _extract_error_json(body): if 'error_message' in body_json: raw_msg = body_json['error_message'] error_json = json.loads(raw_msg) + else: + error_body = body_json['errors'][0] + raw_msg = error_body['title'] + error_json = {'faultstring': error_body['title'], + 'debuginfo': error_body['detail']} + except ValueError: return {} diff --git a/magnumclient/common/utils.py b/magnumclient/common/utils.py index 6ebd49d..29c03ee 100644 --- a/magnumclient/common/utils.py +++ b/magnumclient/common/utils.py @@ -31,7 +31,7 @@ def common_filters(marker=None, limit=None, sort_key=None, sort_dir=None): :returns: list of string filters. """ filters = [] - if isinstance(limit, int) and limit > 0: + if isinstance(limit, int): filters.append('limit=%s' % limit) if marker is not None: filters.append('marker=%s' % marker) @@ -88,9 +88,9 @@ def format_labels(lbls, parse_comma=True): if parse_comma: # expect multiple invocations of --labels but fall back - # to , delimited if only one --labels is specified + # to either , or ; delimited if only one --labels is specified if len(lbls) == 1: - lbls = lbls[0].split(',') + lbls = lbls[0].replace(';', ',').split(',') labels = {} for l in lbls: diff --git a/magnumclient/tests/test_utils.py b/magnumclient/tests/test_utils.py index 122a3dd..1a17b36 100644 --- a/magnumclient/tests/test_utils.py +++ b/magnumclient/tests/test_utils.py @@ -31,7 +31,11 @@ class CommonFiltersTest(test_utils.BaseTestCase): def test_limit_0(self): result = utils.common_filters(limit=0) - self.assertEqual([], result) + self.assertEqual(['limit=0'], result) + + def test_limit_negative_number(self): + result = utils.common_filters(limit=-2) + self.assertEqual(['limit=-2'], result) def test_other(self): for key in ('marker', 'sort_key', 'sort_dir'): @@ -118,6 +122,30 @@ class FormatLabelsTest(test_utils.BaseTestCase): 'K5': 'V5' }, l) + def test_format_labels_semicolon(self): + l = utils.format_labels([ + 'K1=V1;K2=V2;' + 'K3=V3;K4=V4;' + 'K5=V5']) + self.assertEqual({'K1': 'V1', + 'K2': 'V2', + 'K3': 'V3', + 'K4': 'V4', + 'K5': 'V5' + }, l) + + def test_format_labels_mix_commas_semicolon(self): + l = utils.format_labels([ + 'K1=V1,K2=V2,' + 'K3=V3;K4=V4,' + 'K5=V5']) + self.assertEqual({'K1': 'V1', + 'K2': 'V2', + 'K3': 'V3', + 'K4': 'V4', + 'K5': 'V5' + }, l) + def test_format_labels_split(self): l = utils.format_labels([ 'K1=V1,' diff --git a/magnumclient/tests/v1/test_baymodels.py b/magnumclient/tests/v1/test_baymodels.py index c8a03f0..34087a0 100644 --- a/magnumclient/tests/v1/test_baymodels.py +++ b/magnumclient/tests/v1/test_baymodels.py @@ -112,6 +112,48 @@ fake_responses = { UPDATED_BAYMODEL, ), }, + '/v1/baymodels/?limit=2': + { + 'GET': ( + {}, + {'baymodels': [BAYMODEL1, BAYMODEL2]}, + ), + }, + '/v1/baymodels/?marker=%s' % BAYMODEL2['uuid']: + { + 'GET': ( + {}, + {'baymodels': [BAYMODEL1, BAYMODEL2]}, + ), + }, + '/v1/baymodels/?limit=2&marker=%s' % BAYMODEL2['uuid']: + { + 'GET': ( + {}, + {'baymodels': [BAYMODEL1, BAYMODEL2]}, + ), + }, + '/v1/baymodels/?sort_dir=asc': + { + 'GET': ( + {}, + {'baymodels': [BAYMODEL1, BAYMODEL2]}, + ), + }, + '/v1/baymodels/?sort_key=uuid': + { + 'GET': ( + {}, + {'baymodels': [BAYMODEL1, BAYMODEL2]}, + ), + }, + '/v1/baymodels/?sort_key=uuid&sort_dir=desc': + { + 'GET': ( + {}, + {'baymodels': [BAYMODEL2, BAYMODEL1]}, + ), + }, } @@ -130,6 +172,66 @@ class BayModelManagerTest(testtools.TestCase): self.assertEqual(expect, self.api.calls) self.assertThat(baymodels, matchers.HasLength(2)) + def _test_baymode_list_with_fileters( + self, limit=None, marker=None, + sort_key=None, sort_dir=None, + detail=False, expect=[]): + baymodels_filter = self.mgr.list(limit=limit, marker=marker, + sort_key=sort_key, + sort_dir=sort_dir, + detail=detail) + self.assertEqual(expect, self.api.calls) + self.assertThat(baymodels_filter, matchers.HasLength(2)) + + def test_baymodel_list_with_limit(self): + expect = [ + ('GET', '/v1/baymodels/?limit=2', {}, None), + ] + self._test_baymode_list_with_fileters( + limit=2, + expect=expect) + + def test_baymodel_list_with_marker(self): + expect = [ + ('GET', '/v1/baymodels/?marker=%s' % BAYMODEL2['uuid'], {}, None), + ] + self._test_baymode_list_with_fileters( + marker=BAYMODEL2['uuid'], + expect=expect) + + def test_baymodel_list_with_marker_limit(self): + expect = [ + ('GET', '/v1/baymodels/?limit=2&marker=%s' % BAYMODEL2['uuid'], + {}, None), + ] + self._test_baymode_list_with_fileters( + limit=2, marker=BAYMODEL2['uuid'], + expect=expect) + + def test_baymodel_list_with_sort_dir(self): + expect = [ + ('GET', '/v1/baymodels/?sort_dir=asc', {}, None), + ] + self._test_baymode_list_with_fileters( + sort_dir='asc', + expect=expect) + + def test_baymodel_list_with_sort_key(self): + expect = [ + ('GET', '/v1/baymodels/?sort_key=uuid', {}, None), + ] + self._test_baymode_list_with_fileters( + sort_key='uuid', + expect=expect) + + def test_baymodel_list_with_sort_key_dir(self): + expect = [ + ('GET', '/v1/baymodels/?sort_key=uuid&sort_dir=desc', {}, None), + ] + self._test_baymode_list_with_fileters( + sort_key='uuid', sort_dir='desc', + expect=expect) + def test_baymodel_show_by_id(self): baymodel = self.mgr.get(BAYMODEL1['id']) expect = [ diff --git a/magnumclient/tests/v1/test_bays.py b/magnumclient/tests/v1/test_bays.py index dfd8d65..480d0e2 100644 --- a/magnumclient/tests/v1/test_bays.py +++ b/magnumclient/tests/v1/test_bays.py @@ -96,6 +96,48 @@ fake_responses = { UPDATED_BAY, ), }, + '/v1/bays/?limit=2': + { + 'GET': ( + {}, + {'bays': [BAY1, BAY2]}, + ), + }, + '/v1/bays/?marker=%s' % BAY2['uuid']: + { + 'GET': ( + {}, + {'bays': [BAY1, BAY2]}, + ), + }, + '/v1/bays/?limit=2&marker=%s' % BAY2['uuid']: + { + 'GET': ( + {}, + {'bays': [BAY1, BAY2]}, + ), + }, + '/v1/bays/?sort_dir=asc': + { + 'GET': ( + {}, + {'bays': [BAY1, BAY2]}, + ), + }, + '/v1/bays/?sort_key=uuid': + { + 'GET': ( + {}, + {'bays': [BAY1, BAY2]}, + ), + }, + '/v1/bays/?sort_key=uuid&sort_dir=desc': + { + 'GET': ( + {}, + {'bays': [BAY2, BAY1]}, + ), + }, } @@ -114,6 +156,64 @@ class BayManagerTest(testtools.TestCase): self.assertEqual(expect, self.api.calls) self.assertThat(bays, matchers.HasLength(2)) + def _test_bay_list_with_filters(self, limit=None, marker=None, + sort_key=None, sort_dir=None, + detail=False, expect=[]): + bays_filter = self.mgr.list(limit=limit, marker=marker, + sort_key=sort_key, + sort_dir=sort_dir, + detail=detail) + self.assertEqual(expect, self.api.calls) + self.assertThat(bays_filter, matchers.HasLength(2)) + + def test_bay_list_with_limit(self): + expect = [ + ('GET', '/v1/bays/?limit=2', {}, None), + ] + self._test_bay_list_with_filters( + limit=2, + expect=expect) + + def test_bay_list_with_marker(self): + expect = [ + ('GET', '/v1/bays/?marker=%s' % BAY2['uuid'], {}, None), + ] + self._test_bay_list_with_filters( + marker=BAY2['uuid'], + expect=expect) + + def test_bay_list_with_marker_limit(self): + expect = [ + ('GET', '/v1/bays/?limit=2&marker=%s' % BAY2['uuid'], {}, None), + ] + self._test_bay_list_with_filters( + limit=2, marker=BAY2['uuid'], + expect=expect) + + def test_bay_list_with_sort_dir(self): + expect = [ + ('GET', '/v1/bays/?sort_dir=asc', {}, None), + ] + self._test_bay_list_with_filters( + sort_dir='asc', + expect=expect) + + def test_bay_list_with_sort_key(self): + expect = [ + ('GET', '/v1/bays/?sort_key=uuid', {}, None), + ] + self._test_bay_list_with_filters( + sort_key='uuid', + expect=expect) + + def test_bay_list_with_sort_key_dir(self): + expect = [ + ('GET', '/v1/bays/?sort_key=uuid&sort_dir=desc', {}, None), + ] + self._test_bay_list_with_filters( + sort_key='uuid', sort_dir='desc', + expect=expect) + def test_bay_show_by_id(self): bay = self.mgr.get(BAY1['id']) expect = [ diff --git a/magnumclient/tests/v1/test_bays_shell.py b/magnumclient/tests/v1/test_bays_shell.py index 43bb11d..9db1e55 100644 --- a/magnumclient/tests/v1/test_bays_shell.py +++ b/magnumclient/tests/v1/test_bays_shell.py @@ -25,6 +25,25 @@ class ShellTest(shell_test_base.TestCommandLineArgument): self._test_arg_success('bay-list') self.assertTrue(mock_list.called) + @mock.patch('magnumclient.v1.bays.BayManager.list') + def test_bay_list_success_with_arg(self, mock_list): + self._test_arg_success('bay-list ' + '--marker some_uuid ' + '--limit 1 ' + '--sort-dir asc ' + '--sort-key uuid') + self.assertTrue(mock_list.called) + + @mock.patch('magnumclient.v1.bays.BayManager.list') + def test_bay_list_failure_invalid_arg(self, mock_list): + _error_msg = [ + '.*?^usage: magnum bay-list ', + '.*?^error: argument --sort-dir: invalid choice: ', + ".*?^Try 'magnum help bay-list' for more information." + ] + self._test_arg_failure('bay-list --sort-dir aaa', _error_msg) + self.assertFalse(mock_list.called) + @mock.patch('magnumclient.v1.bays.BayManager.list') def test_bay_list_failure(self, mock_list): self._test_arg_failure('bay-list --wrong', diff --git a/magnumclient/tests/v1/test_client.py b/magnumclient/tests/v1/test_client.py index 2bea31a..7a6bdfb 100644 --- a/magnumclient/tests/v1/test_client.py +++ b/magnumclient/tests/v1/test_client.py @@ -129,3 +129,33 @@ class ClientTest(testtools.TestCase): project_id=None, project_name=None) http_client.assert_not_called() + + @mock.patch('magnumclient.common.httpclient.SessionClient') + @mock.patch('keystoneauth1.session.Session') + def test_init_with_endpoint_override(self, mock_session, http_client): + session = mock.Mock() + client.Client(session=session, endpoint_override='magnumurl') + mock_session.assert_not_called() + http_client.assert_called_once_with( + interface='public', + region_name=None, + service_name=None, + service_type='container', + session=session, + endpoint_override='magnumurl') + + @mock.patch('magnumclient.common.httpclient.SessionClient') + @mock.patch('keystoneauth1.session.Session') + def test_init_with_magnum_url_and_endpoint_override(self, mock_session, + http_client): + session = mock.Mock() + client.Client(session=session, magnum_url='magnumurl', + endpoint_override='magnumurl_override') + mock_session.assert_not_called() + http_client.assert_called_once_with( + interface='public', + region_name=None, + service_name=None, + service_type='container', + session=session, + endpoint_override='magnumurl') diff --git a/magnumclient/tests/v1/test_containers.py b/magnumclient/tests/v1/test_containers.py index 2a70ff5..17a8a61 100644 --- a/magnumclient/tests/v1/test_containers.py +++ b/magnumclient/tests/v1/test_containers.py @@ -198,6 +198,48 @@ fake_responses = { {'output': '/home'}, ), }, + '/v1/containers/?limit=2': + { + 'GET': ( + {}, + {'containers': [CONTAINER1, CONTAINER2]}, + ), + }, + '/v1/containers/?marker=%s' % CONTAINER2['uuid']: + { + 'GET': ( + {}, + {'containers': [CONTAINER1, CONTAINER2]}, + ), + }, + '/v1/containers/?limit=2&marker=%s' % CONTAINER2['uuid']: + { + 'GET': ( + {}, + {'containers': [CONTAINER1, CONTAINER2]}, + ), + }, + '/v1/containers/?sort_dir=asc': + { + 'GET': ( + {}, + {'containers': [CONTAINER1, CONTAINER2]}, + ), + }, + '/v1/containers/?sort_key=uuid': + { + 'GET': ( + {}, + {'containers': [CONTAINER1, CONTAINER2]}, + ), + }, + '/v1/containers/?sort_key=uuid&sort_dir=desc': + { + 'GET': ( + {}, + {'containers': [CONTAINER2, CONTAINER1]}, + ), + }, } @@ -226,6 +268,70 @@ class ContainerManagerTest(testtools.TestCase): self.assertEqual(expect, self.api.calls) self.assertThat(containers, matchers.HasLength(2)) + def _test_container_list_with_filters( + self, limit=None, marker=None, + sort_key=None, sort_dir=None, + detail=False, expect=[]): + containers_filter = self.mgr.list(limit=limit, marker=marker, + sort_key=sort_key, + sort_dir=sort_dir, + detail=detail) + self.assertEqual(expect, self.api.calls) + self.assertThat(containers_filter, matchers.HasLength(2)) + + def test_container_list_with_limit(self): + expect = [ + ('GET', '/v1/containers/?limit=2', {}, None), + ] + self._test_container_list_with_filters( + limit=2, + expect=expect) + + def test_container_list_with_marker(self): + expect = [ + ('GET', '/v1/containers/?marker=%s' % CONTAINER2['uuid'], + {}, None), + ] + self._test_container_list_with_filters( + marker=CONTAINER2['uuid'], + expect=expect) + + def test_container_list_with_marker_limit(self): + expect = [ + ('GET', '/v1/containers/?limit=2&marker=%s' % CONTAINER2['uuid'], + {}, None), + ] + self._test_container_list_with_filters( + limit=2, marker=CONTAINER2['uuid'], + expect=expect) + + def test_container_list_with_sort_dir(self): + expect = [ + ('GET', '/v1/containers/?sort_dir=asc', + {}, None), + ] + self._test_container_list_with_filters( + sort_dir='asc', + expect=expect) + + def test_container_list_with_sort_key(self): + expect = [ + ('GET', '/v1/containers/?sort_key=uuid', + {}, None), + ] + self._test_container_list_with_filters( + sort_key='uuid', + expect=expect) + + def test_container_list_with_sort_key_dir(self): + expect = [ + ('GET', '/v1/containers/?sort_key=uuid&sort_dir=desc', + {}, None), + ] + self._test_container_list_with_filters( + sort_key='uuid', sort_dir='desc', + expect=expect) + def test_container_show(self): container = self.mgr.get(CONTAINER1['id']) expect = [ @@ -262,17 +368,6 @@ class ContainerManagerTest(testtools.TestCase): self.assertEqual(expect, self.api.calls) self.assertIsNone(container) - def test_container_update(self): - patch = {'op': 'replace', - 'value': NEW_NAME, - 'path': '/name'} - container = self.mgr.update(id=CONTAINER1['id'], patch=patch) - expect = [ - ('PATCH', '/v1/containers/%s' % CONTAINER1['id'], {}, patch), - ] - self.assertEqual(expect, self.api.calls) - self.assertEqual(NEW_NAME, container.name) - def test_container_start(self): container = self.mgr.start(CONTAINER1['id']) expect = [ diff --git a/magnumclient/tests/v1/test_containers_shell.py b/magnumclient/tests/v1/test_containers_shell.py index 7cdd705..70ffaa7 100644 --- a/magnumclient/tests/v1/test_containers_shell.py +++ b/magnumclient/tests/v1/test_containers_shell.py @@ -25,6 +25,25 @@ class ShellTest(shell_test_base.TestCommandLineArgument): self._test_arg_success('container-list') self.assertTrue(mock_list.called) + @mock.patch('magnumclient.v1.containers.ContainerManager.list') + def test_container_list_success_with_arg(self, mock_list): + self._test_arg_success('container-list ' + '--marker some_uuid ' + '--limit 1 ' + '--sort-dir asc ' + '--sort-key uuid') + self.assertTrue(mock_list.called) + + @mock.patch('magnumclient.v1.containers.ContainerManager.list') + def test_container_list_failure_invalid_arg(self, mock_list): + _error_msg = [ + '.*?^usage: magnum container-list ', + '.*?^error: argument --sort-dir: invalid choice: ', + ".*?^Try 'magnum help container-list' for more information." + ] + self._test_arg_failure('container-list --sort-dir aaa', _error_msg) + self.assertFalse(mock_list.called) + @mock.patch('magnumclient.v1.containers.ContainerManager.list') def test_container_list_success_with_bay(self, mock_list): self._test_arg_success('container-list --bay bay_uuid') diff --git a/magnumclient/tests/v1/test_mservices.py b/magnumclient/tests/v1/test_mservices.py index 35e6d3a..fd835d2 100644 --- a/magnumclient/tests/v1/test_mservices.py +++ b/magnumclient/tests/v1/test_mservices.py @@ -36,6 +36,48 @@ fake_responses = { {'mservices': [SERVICE1, SERVICE2]}, ), }, + '/v1/mservices/?limit=2': + { + 'GET': ( + {}, + {'mservices': [SERVICE1, SERVICE2]}, + ), + }, + '/v1/mservices/?marker=%s' % SERVICE2['id']: + { + 'GET': ( + {}, + {'mservices': [SERVICE1, SERVICE2]}, + ), + }, + '/v1/mservices/?limit=2&marker=%s' % SERVICE2['id']: + { + 'GET': ( + {}, + {'mservices': [SERVICE2, SERVICE1]}, + ), + }, + '/v1/mservices/?sort_dir=asc': + { + 'GET': ( + {}, + {'mservices': [SERVICE1, SERVICE2]}, + ), + }, + '/v1/mservices/?sort_key=id': + { + 'GET': ( + {}, + {'mservices': [SERVICE1, SERVICE2]}, + ), + }, + '/v1/mservices/?sort_key=id&sort_dir=desc': + { + 'GET': ( + {}, + {'mservices': [SERVICE2, SERVICE1]}, + ), + }, } @@ -53,3 +95,67 @@ class MServiceManagerTest(testtools.TestCase): ] self.assertEqual(expect, self.api.calls) self.assertThat(mservices, matchers.HasLength(2)) + + def _test_coe_service_list_with_filters( + self, limit=None, marker=None, + sort_key=None, sort_dir=None, + detail=False, expect=[]): + mservices_filter = self.mgr.list(limit=limit, marker=marker, + sort_key=sort_key, + sort_dir=sort_dir, + detail=detail) + self.assertEqual(expect, self.api.calls) + self.assertThat(mservices_filter, matchers.HasLength(2)) + + def test_coe_service_list_with_limit(self): + expect = [ + ('GET', '/v1/mservices/?limit=2', {}, None), + ] + self._test_coe_service_list_with_filters( + limit=2, + expect=expect) + + def test_coe_service_list_with_marker(self): + expect = [ + ('GET', '/v1/mservices/?marker=%s' % SERVICE2['id'], + {}, None), + ] + self._test_coe_service_list_with_filters( + marker=SERVICE2['id'], + expect=expect) + + def test_coe_service_list_with_marker_limit(self): + expect = [ + ('GET', '/v1/mservices/?limit=2&marker=%s' % SERVICE2['id'], + {}, None), + ] + self._test_coe_service_list_with_filters( + limit=2, marker=SERVICE2['id'], + expect=expect) + + def test_coe_service_list_with_sort_dir(self): + expect = [ + ('GET', '/v1/mservices/?sort_dir=asc', + {}, None), + ] + self._test_coe_service_list_with_filters( + sort_dir='asc', + expect=expect) + + def test_coe_service_list_with_sort_key(self): + expect = [ + ('GET', '/v1/mservices/?sort_key=id', + {}, None), + ] + self._test_coe_service_list_with_filters( + sort_key='id', + expect=expect) + + def test_coe_service_list_with_sort_key_dir(self): + expect = [ + ('GET', '/v1/mservices/?sort_key=id&sort_dir=desc', + {}, None), + ] + self._test_coe_service_list_with_filters( + sort_key='id', sort_dir='desc', + expect=expect) diff --git a/magnumclient/v1/baymodels_shell.py b/magnumclient/v1/baymodels_shell.py index 260ea06..47a54b2 100644 --- a/magnumclient/v1/baymodels_shell.py +++ b/magnumclient/v1/baymodels_shell.py @@ -82,7 +82,7 @@ def _show_baymodel(baymodel): @utils.arg('--no-proxy', metavar='', help='The no_proxy address to use for nodes in bay.') -@utils.arg('--labels', metavar='', +@utils.arg('--labels', metavar='', action='append', default=[], help='Arbitrary labels in the form of key=value pairs ' 'to associate with a baymodel. ' @@ -132,6 +132,8 @@ def do_baymodel_delete(cs, args): for baymodel in args.baymodels: try: cs.baymodels.delete(baymodel) + print("Request to delete baymodel %s has been accepted." % + baymodel) except Exception as e: print("Delete for baymodel %(baymodel)s failed: %(e)s" % {'baymodel': baymodel, 'e': e}) diff --git a/magnumclient/v1/bays_shell.py b/magnumclient/v1/bays_shell.py index 703c64d..95fa162 100644 --- a/magnumclient/v1/bays_shell.py +++ b/magnumclient/v1/bays_shell.py @@ -21,12 +21,31 @@ def _show_bay(bay): utils.print_dict(bay._info) +@utils.arg('--marker', + metavar='', + default=None, + help='The last bay UUID of the previous page; ' + 'displays list of bays after "marker".') +@utils.arg('--limit', + metavar='', + type=int, + help='Maximum number of bays to return.') +@utils.arg('--sort-key', + metavar='', + help='Column to sort results by.') +@utils.arg('--sort-dir', + metavar='', + choices=['desc', 'asc'], + help='Direction to sort. "asc" or "desc".') def do_bay_list(cs, args): """Print a list of available bays.""" - bays = cs.bays.list() + bays = cs.bays.list(marker=args.marker, limit=args.limit, + sort_key=args.sort_key, + sort_dir=args.sort_dir) columns = ('uuid', 'name', 'node_count', 'master_count', 'status') utils.print_list(bays, columns, - {'versions': magnum_utils.print_list_field('versions')}) + {'versions': magnum_utils.print_list_field('versions')}, + sortby_index=None) @utils.arg('--name', @@ -83,6 +102,8 @@ def do_bay_delete(cs, args): for id in args.bay: try: cs.bays.delete(id) + print("Request to delete bay %s has been accepted." % + id) except Exception as e: print("Delete for bay %(bay)s failed: %(e)s" % {'bay': id, 'e': e}) diff --git a/magnumclient/v1/client.py b/magnumclient/v1/client.py index 6faad3f..2191b67 100644 --- a/magnumclient/v1/client.py +++ b/magnumclient/v1/client.py @@ -30,7 +30,8 @@ from magnumclient.v1 import services class Client(object): def __init__(self, username=None, api_key=None, project_id=None, project_name=None, auth_url=None, magnum_url=None, - endpoint_type=None, service_type='container', + endpoint_type=None, endpoint_override=None, + service_type='container', region_name=None, input_auth_token=None, session=None, password=None, auth_type='password', interface='public', service_name=None, insecure=False, @@ -46,6 +47,11 @@ class Client(object): if endpoint_type: interface = endpoint_type + # fix (yolanda): os-cloud-config is using endpoint_override + # instead of magnum_url + if endpoint_override and not magnum_url: + magnum_url = endpoint_override + if magnum_url and input_auth_token: auth_type = 'admin_token' session = None diff --git a/magnumclient/v1/containers.py b/magnumclient/v1/containers.py index bfd39cf..a377b00 100644 --- a/magnumclient/v1/containers.py +++ b/magnumclient/v1/containers.py @@ -110,9 +110,6 @@ class ContainerManager(base.Manager): def delete(self, id): return self._delete(self._path(id)) - def update(self, id, patch): - return self._update(self._path(id), patch) - def _action(self, id, action, method='PUT', qparams=None, **kwargs): if qparams: action = "%s?%s" % (action, diff --git a/magnumclient/v1/containers_shell.py b/magnumclient/v1/containers_shell.py index 7d75016..3f0b36d 100644 --- a/magnumclient/v1/containers_shell.py +++ b/magnumclient/v1/containers_shell.py @@ -60,16 +60,37 @@ def do_container_create(cs, args): _show_container(cs.containers.create(**opts)) +@utils.arg('--marker', + metavar='', + default=None, + help='The last bay UUID of the previous page; ' + 'displays list of bays after "marker".') +@utils.arg('--limit', + metavar='', + type=int, + help='Maximum number of containers to return') +@utils.arg('--sort-key', + metavar='', + help='Column to sort results by') +@utils.arg('--sort-dir', + metavar='', + choices=['desc', 'asc'], + help='Direction to sort. "asc" or "desc".') @utils.arg('--bay', metavar='', help="UUID or Name of Bay") def do_container_list(cs, args): """Print a list of available containers.""" opts = {} opts['bay_ident'] = args.bay + opts['marker'] = args.marker + opts['limit'] = args.limit + opts['sort_key'] = args.sort_key + opts['sort_dir'] = args.sort_dir containers = cs.containers.list(**opts) columns = ('uuid', 'name', 'status', 'bay_uuid') utils.print_list(containers, columns, - {'versions': magnum_utils.print_list_field('versions')}) + {'versions': magnum_utils.print_list_field('versions')}, + sortby_index=None) @utils.arg('containers', @@ -81,6 +102,8 @@ def do_container_delete(cs, args): for container in args.containers: try: cs.containers.delete(container) + print("Request to delete container %s has been accepted." % + container) except Exception as e: print("Delete for container %(container)s failed: %(e)s" % {'container': container, 'e': e}) diff --git a/magnumclient/v1/pods_shell.py b/magnumclient/v1/pods_shell.py index c0dc07d..b3858b5 100644 --- a/magnumclient/v1/pods_shell.py +++ b/magnumclient/v1/pods_shell.py @@ -109,6 +109,8 @@ def do_pod_delete(cs, args): for pod in args.pods: try: cs.pods.delete(pod, args.bay) + print("Request to delete pod %s has been accepted." % + pod) except Exception as e: print("Delete for pod %(pod)s failed: %(e)s" % {'pod': pod, 'e': e}) diff --git a/magnumclient/v1/replicationcontrollers_shell.py b/magnumclient/v1/replicationcontrollers_shell.py index beb196c..e34b350 100644 --- a/magnumclient/v1/replicationcontrollers_shell.py +++ b/magnumclient/v1/replicationcontrollers_shell.py @@ -114,6 +114,8 @@ def do_rc_delete(cs, args): for rc in args.rcs: try: cs.rcs.delete(rc, args.bay) + print("Request to delete rc %s has been accepted." % + rc) except Exception as e: print("Delete for rc %(rc)s failed: %(e)s" % {'rc': rc, 'e': e}) diff --git a/magnumclient/v1/services_shell.py b/magnumclient/v1/services_shell.py index 647d9f9..dda669b 100644 --- a/magnumclient/v1/services_shell.py +++ b/magnumclient/v1/services_shell.py @@ -102,6 +102,8 @@ def do_coe_service_delete(cs, args): for service in args.services: try: cs.services.delete(service, args.bay) + print("Request to delete service %s has been accepted." % + service) except Exception as e: print("Delete for service %(service)s failed: %(e)s" % {'service': service, 'e': e}) diff --git a/requirements.txt b/requirements.txt index 401cc91..688b8ca 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,10 +3,10 @@ # process, which may cause wedges in the gate later. pbr>=1.6 # Apache-2.0 -Babel>=1.3 # BSD +Babel!=2.3.0,!=2.3.1,!=2.3.2,!=2.3.3,>=1.3 # BSD six>=1.9.0 # MIT keystoneauth1>=2.1.0 # Apache-2.0 -stevedore>=1.5.0 # Apache-2.0 +stevedore>=1.9.0 # Apache-2.0 requests!=2.9.0,>=2.8.1 # Apache-2.0 oslo.i18n>=2.1.0 # Apache-2.0 oslo.serialization>=1.10.0 # Apache-2.0 diff --git a/test-requirements.txt b/test-requirements.txt index c70fce6..5ea3765 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -2,10 +2,10 @@ # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. hacking<0.11,>=0.10.0 -bandit>=0.17.3 # Apache-2.0 +bandit>=1.0.1 # Apache-2.0 coverage>=3.6 # Apache-2.0 discover # BSD -fixtures>=1.3.1 # Apache-2.0/BSD +fixtures<2.0,>=1.3.1 # Apache-2.0/BSD python-subunit>=0.0.18 # Apache-2.0/BSD sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0