Merge "OSC 4/4 Add remaining cluster commands"
This commit is contained in:
commit
49c7fcfe68
|
@ -12,13 +12,36 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from magnumclient.common import utils as magnum_utils
|
||||||
from magnumclient.i18n import _
|
from magnumclient.i18n import _
|
||||||
|
|
||||||
from osc_lib.command import command
|
from osc_lib.command import command
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
|
|
||||||
|
|
||||||
|
CLUSTER_ATTRIBUTES = [
|
||||||
|
'status',
|
||||||
|
'cluster_template_id',
|
||||||
|
'node_addresses',
|
||||||
|
'uuid',
|
||||||
|
'stack_id',
|
||||||
|
'status_reason',
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
'coe_version',
|
||||||
|
'faults',
|
||||||
|
'keypair',
|
||||||
|
'api_address',
|
||||||
|
'master_addresses',
|
||||||
|
'create_timeout',
|
||||||
|
'node_count',
|
||||||
|
'discovery_url',
|
||||||
|
'master_count',
|
||||||
|
'container_version',
|
||||||
|
'name'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class CreateCluster(command.Command):
|
class CreateCluster(command.Command):
|
||||||
_description = _("Create a cluster")
|
_description = _("Create a cluster")
|
||||||
|
|
||||||
|
@ -89,6 +112,28 @@ class CreateCluster(command.Command):
|
||||||
% cluster.uuid)
|
% cluster.uuid)
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteCluster(command.Command):
|
||||||
|
_description = _("Delete a cluster")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(DeleteCluster, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
'cluster',
|
||||||
|
nargs='+',
|
||||||
|
metavar='<cluster>',
|
||||||
|
help='ID or name of the cluster(s) to delete.')
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
self.log.debug("take_action(%s)", parsed_args)
|
||||||
|
|
||||||
|
mag_client = self.app.client_manager.container_infra
|
||||||
|
for cluster in parsed_args.cluster:
|
||||||
|
mag_client.clusters.delete(cluster)
|
||||||
|
print("Request to delete cluster %s has been accepted." % cluster)
|
||||||
|
|
||||||
|
|
||||||
class ListCluster(command.Lister):
|
class ListCluster(command.Lister):
|
||||||
_description = _("List clusters")
|
_description = _("List clusters")
|
||||||
|
|
||||||
|
@ -125,3 +170,75 @@ class ListCluster(command.Lister):
|
||||||
columns,
|
columns,
|
||||||
(utils.get_item_properties(c, columns) for c in clusters)
|
(utils.get_item_properties(c, columns) for c in clusters)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ShowCluster(command.ShowOne):
|
||||||
|
_description = _("Show a Cluster")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(ShowCluster, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
'cluster',
|
||||||
|
metavar='<cluster>',
|
||||||
|
help=_('ID or name of the cluster to show.')
|
||||||
|
)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
self.log.debug("take_action(%s)", parsed_args)
|
||||||
|
|
||||||
|
columns = CLUSTER_ATTRIBUTES
|
||||||
|
|
||||||
|
mag_client = self.app.client_manager.container_infra
|
||||||
|
cluster = mag_client.clusters.get(parsed_args.cluster)
|
||||||
|
|
||||||
|
return (columns, utils.get_item_properties(cluster, columns))
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateCluster(command.Command):
|
||||||
|
_description = _("Update a Cluster")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(UpdateCluster, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
'cluster',
|
||||||
|
metavar='<cluster>',
|
||||||
|
help=_('The name or UUID of cluster to update'))
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'op',
|
||||||
|
metavar='<op>',
|
||||||
|
choices=['add', 'replace', 'remove'],
|
||||||
|
help=_("Operations: one of 'add', 'replace' or 'remove'"))
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'attributes',
|
||||||
|
metavar='<path=value>',
|
||||||
|
nargs='+',
|
||||||
|
action='append',
|
||||||
|
default=[],
|
||||||
|
help=_(
|
||||||
|
"Attributes to add/replace or remove (only PATH is necessary "
|
||||||
|
"on remove)"))
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'--rollback',
|
||||||
|
action='store_true',
|
||||||
|
dest='rollback',
|
||||||
|
default=False,
|
||||||
|
help=_('Rollback cluster on update failure.'))
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
self.log.debug("take_action(%s)", parsed_args)
|
||||||
|
|
||||||
|
mag_client = self.app.client_manager.container_infra
|
||||||
|
|
||||||
|
patch = magnum_utils.args_array_to_patch(parsed_args.op,
|
||||||
|
parsed_args.attributes[0])
|
||||||
|
|
||||||
|
mag_client.clusters.update(parsed_args.cluster,
|
||||||
|
patch)
|
||||||
|
print("Request to update cluster %s has been accepted." %
|
||||||
|
parsed_args.cluster)
|
||||||
|
|
|
@ -190,6 +190,7 @@ class FakeCluster(object):
|
||||||
'created_at': '2017-03-16T18:40:39+00:00',
|
'created_at': '2017-03-16T18:40:39+00:00',
|
||||||
'updated_at': '2017-03-16T18:40:45+00:00',
|
'updated_at': '2017-03-16T18:40:45+00:00',
|
||||||
'coe_version': None,
|
'coe_version': None,
|
||||||
|
'faults': None,
|
||||||
'keypair': 'fakekey',
|
'keypair': 'fakekey',
|
||||||
'api_address': None,
|
'api_address': None,
|
||||||
'master_addresses': [],
|
'master_addresses': [],
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import mock
|
import mock
|
||||||
|
from mock import call
|
||||||
|
|
||||||
from magnumclient.osc.v1 import clusters as osc_clusters
|
from magnumclient.osc.v1 import clusters as osc_clusters
|
||||||
from magnumclient.tests.osc.unit.v1 import fakes as magnum_fakes
|
from magnumclient.tests.osc.unit.v1 import fakes as magnum_fakes
|
||||||
|
@ -60,26 +61,8 @@ class TestClusterCreate(TestCluster):
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = osc_clusters.CreateCluster(self.app, None)
|
self.cmd = osc_clusters.CreateCluster(self.app, None)
|
||||||
|
|
||||||
self.data = (
|
self.data = tuple(map(lambda x: getattr(self._cluster, x),
|
||||||
self._cluster.status,
|
osc_clusters.CLUSTER_ATTRIBUTES))
|
||||||
self._cluster.cluster_template_id,
|
|
||||||
self._cluster.node_addresses,
|
|
||||||
self._cluster.uuid,
|
|
||||||
self._cluster.stack_id,
|
|
||||||
self._cluster.status_reason,
|
|
||||||
self._cluster.created_at,
|
|
||||||
self._cluster.updated_at,
|
|
||||||
self._cluster.coe_version,
|
|
||||||
self._cluster.keypair,
|
|
||||||
self._cluster.api_address,
|
|
||||||
self._cluster.master_addresses,
|
|
||||||
self._cluster.create_timeout,
|
|
||||||
self._cluster.node_count,
|
|
||||||
self._cluster.discovery_url,
|
|
||||||
self._cluster.master_count,
|
|
||||||
self._cluster.container_version,
|
|
||||||
self._cluster.name
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_cluster_create_required_args_pass(self):
|
def test_cluster_create_required_args_pass(self):
|
||||||
"""Verifies required arguments."""
|
"""Verifies required arguments."""
|
||||||
|
@ -107,6 +90,52 @@ class TestClusterCreate(TestCluster):
|
||||||
self.check_parser, self.cmd, arglist, verifylist)
|
self.check_parser, self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
|
||||||
|
class TestClusterDelete(TestCluster):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestClusterDelete, self).setUp()
|
||||||
|
|
||||||
|
self.clusters_mock.delete = mock.Mock()
|
||||||
|
self.clusters_mock.delete.return_value = None
|
||||||
|
|
||||||
|
# Get the command object to test
|
||||||
|
self.cmd = osc_clusters.DeleteCluster(self.app, None)
|
||||||
|
|
||||||
|
def test_cluster_delete_one(self):
|
||||||
|
arglist = ['foo']
|
||||||
|
verifylist = [('cluster', ['foo'])]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
self.clusters_mock.delete.assert_called_with('foo')
|
||||||
|
|
||||||
|
def test_cluster_delete_multiple(self):
|
||||||
|
arglist = ['foo', 'bar']
|
||||||
|
verifylist = [('cluster', ['foo', 'bar'])]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
self.clusters_mock.delete.assert_has_calls([call('foo'), call('bar')])
|
||||||
|
|
||||||
|
def test_cluster_delete_bad_uuid(self):
|
||||||
|
arglist = ['foo']
|
||||||
|
verifylist = [('cluster', ['foo'])]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
returns = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
self.assertEqual(returns, None)
|
||||||
|
|
||||||
|
def test_cluster_delete_no_uuid(self):
|
||||||
|
arglist = []
|
||||||
|
verifylist = [('cluster', [])]
|
||||||
|
|
||||||
|
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||||
|
self.check_parser, self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
|
||||||
class TestClusterList(TestCluster):
|
class TestClusterList(TestCluster):
|
||||||
attr = dict()
|
attr = dict()
|
||||||
attr['name'] = 'fake-cluster-1'
|
attr['name'] = 'fake-cluster-1'
|
||||||
|
@ -192,3 +221,82 @@ class TestClusterList(TestCluster):
|
||||||
|
|
||||||
self.assertRaises(magnum_fakes.MagnumParseException,
|
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||||
self.check_parser, self.cmd, arglist, verifylist)
|
self.check_parser, self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
|
||||||
|
class TestClusterUpdate(TestCluster):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestClusterUpdate, self).setUp()
|
||||||
|
|
||||||
|
self.clusters_mock.update = mock.Mock()
|
||||||
|
self.clusters_mock.update.return_value = None
|
||||||
|
|
||||||
|
# Get the command object to test
|
||||||
|
self.cmd = osc_clusters.UpdateCluster(self.app, None)
|
||||||
|
|
||||||
|
def test_cluster_update_pass(self):
|
||||||
|
arglist = ['foo', 'remove', 'bar']
|
||||||
|
verifylist = [
|
||||||
|
('cluster', 'foo'),
|
||||||
|
('op', 'remove'),
|
||||||
|
('attributes', [['bar']]),
|
||||||
|
('rollback', False)
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
self.clusters_mock.update.assert_called_with(
|
||||||
|
'foo',
|
||||||
|
[{'op': 'remove', 'path': '/bar'}]
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_cluster_update_bad_op(self):
|
||||||
|
arglist = ['foo', 'bar', 'snafu']
|
||||||
|
verifylist = [
|
||||||
|
('cluster', 'foo'),
|
||||||
|
('op', 'bar'),
|
||||||
|
('attributes', ['snafu']),
|
||||||
|
('rollback', False)
|
||||||
|
]
|
||||||
|
|
||||||
|
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||||
|
self.check_parser, self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
|
||||||
|
class TestClusterShow(TestCluster):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestClusterShow, self).setUp()
|
||||||
|
|
||||||
|
attr = dict()
|
||||||
|
attr['name'] = 'fake-cluster-1'
|
||||||
|
self._cluster = magnum_fakes.FakeCluster.create_one_cluster(attr)
|
||||||
|
|
||||||
|
self.clusters_mock.get = mock.Mock()
|
||||||
|
self.clusters_mock.get.return_value = self._cluster
|
||||||
|
|
||||||
|
# Get the command object to test
|
||||||
|
self.cmd = osc_clusters.ShowCluster(self.app, None)
|
||||||
|
|
||||||
|
self.data = tuple(map(lambda x: getattr(self._cluster, x),
|
||||||
|
osc_clusters.CLUSTER_ATTRIBUTES))
|
||||||
|
|
||||||
|
def test_cluster_show_pass(self):
|
||||||
|
arglist = ['fake-cluster']
|
||||||
|
verifylist = [
|
||||||
|
('cluster', 'fake-cluster')
|
||||||
|
]
|
||||||
|
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
self.clusters_mock.get.assert_called_with('fake-cluster')
|
||||||
|
self.assertEqual(osc_clusters.CLUSTER_ATTRIBUTES, columns)
|
||||||
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
|
def test_cluster_show_no_cluster_fail(self):
|
||||||
|
arglist = []
|
||||||
|
verifylist = []
|
||||||
|
|
||||||
|
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||||
|
self.check_parser, self.cmd, arglist, verifylist)
|
||||||
|
|
|
@ -38,6 +38,9 @@ openstack.container_infra.v1 =
|
||||||
|
|
||||||
coe_cluster_create = magnumclient.osc.v1.clusters:CreateCluster
|
coe_cluster_create = magnumclient.osc.v1.clusters:CreateCluster
|
||||||
coe_cluster_list = magnumclient.osc.v1.clusters:ListCluster
|
coe_cluster_list = magnumclient.osc.v1.clusters:ListCluster
|
||||||
|
coe_cluster_delete = magnumclient.osc.v1.clusters:DeleteCluster
|
||||||
|
coe_cluster_show = magnumclient.osc.v1.clusters:ShowCluster
|
||||||
|
coe_cluster_update = magnumclient.osc.v1.clusters:UpdateCluster
|
||||||
|
|
||||||
[build_sphinx]
|
[build_sphinx]
|
||||||
source-dir = doc/source
|
source-dir = doc/source
|
||||||
|
|
Loading…
Reference in New Issue