From 39eb5d5fcf6bca08d4cdae8fc155d11c39c09e21 Mon Sep 17 00:00:00 2001 From: Motohiro OTSUKA Date: Wed, 26 Nov 2014 12:47:22 +0900 Subject: [PATCH] Implements basic container operations - do_container_create - do_container_list - do_container_delete - do_container_show Change-Id: I7fa57590b37df92cfbfffe2a2c69a7029bec27e7 --- magnumclient/api/containers.py | 11 ++-- magnumclient/api/shell.py | 75 ++++++++++++++++++++++++++-- magnumclient/tests/api/__init__.py | 0 magnumclient/tests/api/test_shell.py | 67 +++++++++++++++++++++++++ requirements.txt | 1 + 5 files changed, 147 insertions(+), 7 deletions(-) create mode 100644 magnumclient/tests/api/__init__.py create mode 100644 magnumclient/tests/api/test_shell.py diff --git a/magnumclient/api/containers.py b/magnumclient/api/containers.py index 2230cc9..9b8a879 100644 --- a/magnumclient/api/containers.py +++ b/magnumclient/api/containers.py @@ -18,7 +18,7 @@ from magnumclient import exceptions # FIXME: Modify correct attributes. -CREATION_ATTRIBUTES = ['description'] +CREATION_ATTRIBUTES = ['name', 'desc'] class Container(base.Resource): @@ -72,9 +72,13 @@ class ContainerManager(base.Manager): path += '?' + '&'.join(filters) if limit is None: - return self._list(self._path(path), "containers") + # TODO(yuanying): if endpoint returns "map", + # change None to response_key + return self._list(self._path(path), None) else: - return self._list_pagination(self._path(path), "containers", + # TODO(yuanying): if endpoint returns "map", + # change None to response_key + return self._list_pagination(self._path(path), None, limit=limit) def get(self, container_id): @@ -89,6 +93,7 @@ class ContainerManager(base.Manager): if key in CREATION_ATTRIBUTES: new[key] = value else: + pass raise exceptions.InvalidAttribute() return self._create(self._path(), new) diff --git a/magnumclient/api/shell.py b/magnumclient/api/shell.py index 0f375c2..3f16d41 100644 --- a/magnumclient/api/shell.py +++ b/magnumclient/api/shell.py @@ -13,6 +13,20 @@ # See the License for the specific language governing permissions and # limitations under the License. +import argparse +import json +import sys + +from magnumclient.openstack.common import cliutils as utils + + +def _print_list_field(field): + return lambda obj: ', '.join(getattr(obj, field)) + + +def _show_container(container): + utils.print_dict(container._info) + def do_bay_list(cs, args): pass @@ -62,20 +76,73 @@ def do_service_show(cs, args): pass +# +# Containers +# ~~~~~~~~~~ +# container-create [--json ] +# +# container-list +# +# container-delete --id +# +# container-show --id [--json] +# +# TODO(yuanying): container-reboot +# +# TODO(yuanying): container-stop +# +# TODO(yuanying): container-start +# +# TODO(yuanying): container-pause +# +# TODO(yuanying): container-unpause +# +# TODO(yuanying): container-logs +# +# TODO(yuanying): container-execute +# + + +@utils.arg('--json', + default=sys.stdin, + type=argparse.FileType('r'), + help='JSON representation of container.') def do_container_create(cs, args): - pass + """Create a container.""" + container = json.loads(args.json.read()) + _show_container(cs.containers.create(**container)) def do_container_list(cs, args): - pass + """Print a list of available containers.""" + containers = cs.containers.list() + columns = ('name', 'desc') + utils.print_list(containers, columns, + {'versions': _print_list_field('versions')}) +@utils.arg('--id', + metavar='', + help='ID of the container to delete.') def do_container_delete(cs, args): - pass + """Delete a cluster.""" + cs.containers.delete(args.id) +@utils.arg('--id', + metavar='', + help='ID of the container to show.') +@utils.arg('--json', + action='store_true', + default=False, + help='Print JSON representation of the container.') def do_container_show(cs, args): - pass + """Show details of a container.""" + container = cs.containers.get(args.id) + if args.json: + print(json.dumps(container._info)) + else: + _show_container(container) def do_container_reboot(cs, args): diff --git a/magnumclient/tests/api/__init__.py b/magnumclient/tests/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/magnumclient/tests/api/test_shell.py b/magnumclient/tests/api/test_shell.py new file mode 100644 index 0000000..98403df --- /dev/null +++ b/magnumclient/tests/api/test_shell.py @@ -0,0 +1,67 @@ +# 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. + +import json + +import mock + +from magnumclient.api import shell +from magnumclient.tests import base + + +container_fixture = { + "name": "container", + "desc": "container description." +} + + +class ShellTest(base.TestCase): + + def setUp(self): + super(ShellTest, self).setUp() + + def test_do_container_create(self): + client_mock = mock.MagicMock() + args = mock.MagicMock() + args.json.read.return_value = json.dumps(container_fixture) + + shell.do_container_create(client_mock, args) + client_mock.containers.create.assert_called_once_with( + **container_fixture) + + def test_do_container_list(self): + client_mock = mock.MagicMock() + args = mock.MagicMock() + + shell.do_container_list(client_mock, args) + client_mock.containers.list.assert_called_once_with() + + def test_do_container_delete(self): + client_mock = mock.MagicMock() + args = mock.MagicMock() + container_id = "container_id" + args.id = container_id + + shell.do_container_delete(client_mock, args) + client_mock.containers.delete.assert_called_once_with(container_id) + + def test_do_container_show(self): + client_mock = mock.MagicMock() + args = mock.MagicMock() + container_id = "container_id" + args.id = container_id + args.json = None + + shell.do_container_show(client_mock, args) + client_mock.containers.get.assert_called_once_with(container_id) diff --git a/requirements.txt b/requirements.txt index 7793ebb..5ee8a84 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ # The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. +argparse pbr>=0.6,!=0.7,<1.0 Babel>=1.3 oslo.config>=1.4.0 # Apache-2.0