Add nodegroup CRUD commands
The commands added are: * openstack coe nodegroup create <params> <cluster> <nodegroup> * openstack coe nodegroup delete <cluster> <nodegroup> * openstack coe nodegroup update <op> <params> <cluster> <nodegroup> Depends-On: I4ad60994ad6b4cb9cac18129557e1e87e61ae98c Change-Id: I98b662b5a95f16d80852e3b30683c75e78acb3e5
This commit is contained in:
parent
69be0ac44e
commit
934cf54854
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from magnumclient.common import utils as magnum_utils
|
||||
from magnumclient.i18n import _
|
||||
|
||||
from osc_lib.command import command
|
||||
@ -33,10 +34,133 @@ NODEGROUP_ATTRIBUTES = [
|
||||
'role',
|
||||
'max_node_count',
|
||||
'min_node_count',
|
||||
'is_default'
|
||||
'is_default',
|
||||
'stack_id',
|
||||
'status',
|
||||
'status_reason'
|
||||
]
|
||||
|
||||
|
||||
class CreateNodeGroup(command.Command):
|
||||
_description = _("Create a nodegroup")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateNodeGroup, self).get_parser(prog_name)
|
||||
# NOTE: All arguments are positional and, if not provided
|
||||
# with a default, required.
|
||||
parser.add_argument('--docker-volume-size',
|
||||
dest='docker_volume_size',
|
||||
type=int,
|
||||
metavar='<docker-volume-size>',
|
||||
help=('The size in GB for the docker volume to '
|
||||
'use.'))
|
||||
parser.add_argument('--labels',
|
||||
metavar='<KEY1=VALUE1,KEY2=VALUE2;KEY3=VALUE3...>',
|
||||
action='append',
|
||||
help=_('Arbitrary labels in the form of key=value'
|
||||
'pairs to associate with a nodegroup. '
|
||||
'May be used multiple times.'))
|
||||
parser.add_argument('cluster',
|
||||
metavar='<cluster>',
|
||||
help='Name of the nodegroup to create.')
|
||||
parser.add_argument('name',
|
||||
metavar='<name>',
|
||||
help='Name of the nodegroup to create.')
|
||||
parser.add_argument('--node-count',
|
||||
dest='node_count',
|
||||
type=int,
|
||||
default=1,
|
||||
metavar='<node-count>',
|
||||
help='The nodegroup node count.')
|
||||
parser.add_argument('--min-nodes',
|
||||
dest='min_node_count',
|
||||
type=int,
|
||||
default=1,
|
||||
metavar='<min-nodes>',
|
||||
help='The nodegroup minimum node count.')
|
||||
parser.add_argument('--max-nodes',
|
||||
dest='max_node_count',
|
||||
type=int,
|
||||
default=None,
|
||||
metavar='<max-nodes>',
|
||||
help='The nodegroup maximum node count.')
|
||||
parser.add_argument('--role',
|
||||
dest='role',
|
||||
type=str,
|
||||
default='worker',
|
||||
metavar='<role>',
|
||||
help=('The role of the nodegroup'))
|
||||
parser.add_argument(
|
||||
'--image',
|
||||
metavar='<image>',
|
||||
help=_('The name or UUID of the base image to customize for the '
|
||||
'NodeGroup.'))
|
||||
parser.add_argument(
|
||||
'--flavor',
|
||||
metavar='<flavor>',
|
||||
help=_('The nova flavor name or UUID to use when launching the '
|
||||
'nodes in this NodeGroup.'))
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)", parsed_args)
|
||||
|
||||
mag_client = self.app.client_manager.container_infra
|
||||
args = {
|
||||
'name': parsed_args.name,
|
||||
'node_count': parsed_args.node_count,
|
||||
'max_node_count': parsed_args.max_node_count,
|
||||
'min_node_count': parsed_args.min_node_count,
|
||||
'role': parsed_args.role,
|
||||
}
|
||||
|
||||
if parsed_args.labels is not None:
|
||||
args['labels'] = magnum_utils.handle_labels(parsed_args.labels)
|
||||
|
||||
if parsed_args.docker_volume_size is not None:
|
||||
args['docker_volume_size'] = parsed_args.docker_volume_size
|
||||
|
||||
if parsed_args.flavor is not None:
|
||||
args['flavor_id'] = parsed_args.flavor
|
||||
|
||||
if parsed_args.image is not None:
|
||||
args['image_id'] = parsed_args.image
|
||||
|
||||
cluster_id = parsed_args.cluster
|
||||
nodegroup = mag_client.nodegroups.create(cluster_id, **args)
|
||||
print("Request to create nodegroup %s accepted"
|
||||
% nodegroup.uuid)
|
||||
|
||||
|
||||
class DeleteNodeGroup(command.Command):
|
||||
_description = _("Delete a nodegroup")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteNodeGroup, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'cluster',
|
||||
metavar='<cluster>',
|
||||
help=_('ID or name of the cluster where the nodegroup(s) '
|
||||
'belong(s).'))
|
||||
parser.add_argument(
|
||||
'nodegroup',
|
||||
nargs='+',
|
||||
metavar='<nodegroup>',
|
||||
help='ID or name of the nodegroup(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
|
||||
cluster_id = parsed_args.cluster
|
||||
for ng in parsed_args.nodegroup:
|
||||
mag_client.nodegroups.delete(cluster_id, ng)
|
||||
print("Request to delete nodegroup %s has been accepted." % ng)
|
||||
|
||||
|
||||
class ListNodeGroup(command.Lister):
|
||||
_description = _("List nodegroups")
|
||||
|
||||
@ -72,7 +196,8 @@ class ListNodeGroup(command.Lister):
|
||||
self.log.debug("take_action(%s)", parsed_args)
|
||||
|
||||
mag_client = self.app.client_manager.container_infra
|
||||
columns = ['uuid', 'name', 'flavor_id', 'node_count', 'role']
|
||||
columns = ['uuid', 'name', 'flavor_id', 'image_id', 'node_count',
|
||||
'status', 'role']
|
||||
cluster_id = parsed_args.cluster
|
||||
nodegroups = mag_client.nodegroups.list(cluster_id,
|
||||
limit=parsed_args.limit,
|
||||
@ -112,3 +237,50 @@ class ShowNodeGroup(command.ShowOne):
|
||||
parsed_args.nodegroup)
|
||||
|
||||
return (columns, utils.get_item_properties(nodegroup, columns))
|
||||
|
||||
|
||||
class UpdateNodeGroup(command.Command):
|
||||
_description = _("Update a Nodegroup")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UpdateNodeGroup, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'cluster',
|
||||
metavar='<cluster>',
|
||||
help=_('ID or name of the cluster where the nodegroup belongs.'))
|
||||
parser.add_argument(
|
||||
'nodegroup',
|
||||
metavar='<nodegroup>',
|
||||
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)"))
|
||||
|
||||
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])
|
||||
|
||||
cluster_id = parsed_args.cluster
|
||||
mag_client.nodegroups.update(cluster_id, parsed_args.nodegroup,
|
||||
patch)
|
||||
print("Request to update nodegroup %s has been accepted." %
|
||||
parsed_args.nodegroup)
|
||||
|
@ -332,7 +332,10 @@ class FakeNodeGroup(object):
|
||||
'role': 'worker',
|
||||
'max_node_count': 10,
|
||||
'min_node_count': 1,
|
||||
'is_default': False
|
||||
'is_default': False,
|
||||
'stack_id': '3a369884-b6ba-484f-fake-stackb718aff',
|
||||
'status': 'CREATE_COMPLETE',
|
||||
'status_reason': 'None'
|
||||
}
|
||||
|
||||
# Overwrite default attributes.
|
||||
|
@ -13,7 +13,9 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
import mock
|
||||
from mock import call
|
||||
|
||||
from magnumclient.osc.v1 import nodegroups as osc_nodegroups
|
||||
from magnumclient.tests.osc.unit.v1 import fakes as magnum_fakes
|
||||
@ -26,6 +28,176 @@ class TestNodeGroup(magnum_fakes.TestMagnumClientOSCV1):
|
||||
self.ng_mock = self.app.client_manager.container_infra.nodegroups
|
||||
|
||||
|
||||
class TestNodeGroupCreate(TestNodeGroup):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNodeGroupCreate, self).setUp()
|
||||
self.nodegroup = magnum_fakes.FakeNodeGroup.create_one_nodegroup()
|
||||
|
||||
self.ng_mock.create = mock.Mock()
|
||||
self.ng_mock.create.return_value = self.nodegroup
|
||||
|
||||
self.ng_mock.get = mock.Mock()
|
||||
self.ng_mock.get.return_value = copy.deepcopy(self.nodegroup)
|
||||
|
||||
self.ng_mock.update = mock.Mock()
|
||||
self.ng_mock.update.return_value = self.nodegroup
|
||||
|
||||
self._default_args = {
|
||||
'name': 'fake-nodegroup',
|
||||
'node_count': 1,
|
||||
'role': 'worker',
|
||||
'min_node_count': 1,
|
||||
'max_node_count': None,
|
||||
}
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = osc_nodegroups.CreateNodeGroup(self.app, None)
|
||||
|
||||
self.data = tuple(map(lambda x: getattr(self.nodegroup, x),
|
||||
osc_nodegroups.NODEGROUP_ATTRIBUTES))
|
||||
|
||||
def test_nodegroup_create_required_args_pass(self):
|
||||
"""Verifies required arguments."""
|
||||
|
||||
arglist = [
|
||||
self.nodegroup.cluster_id,
|
||||
self.nodegroup.name
|
||||
]
|
||||
verifylist = [
|
||||
('cluster', self.nodegroup.cluster_id),
|
||||
('name', self.nodegroup.name)
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.ng_mock.create.assert_called_with(self.nodegroup.cluster_id,
|
||||
**self._default_args)
|
||||
|
||||
def test_nodegroup_create_missing_required_arg(self):
|
||||
"""Verifies missing required arguments."""
|
||||
|
||||
arglist = [
|
||||
self.nodegroup.name
|
||||
]
|
||||
verifylist = [
|
||||
('name', self.nodegroup.name)
|
||||
]
|
||||
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||
self.check_parser, self.cmd, arglist, verifylist)
|
||||
|
||||
def test_nodegroup_create_with_labels(self):
|
||||
"""Verifies labels are properly parsed when given as argument."""
|
||||
|
||||
expected_args = self._default_args
|
||||
expected_args['labels'] = {
|
||||
'arg1': 'value1', 'arg2': 'value2'
|
||||
}
|
||||
|
||||
arglist = [
|
||||
'--labels', 'arg1=value1',
|
||||
'--labels', 'arg2=value2',
|
||||
self.nodegroup.cluster_id,
|
||||
self.nodegroup.name
|
||||
]
|
||||
verifylist = [
|
||||
('labels', ['arg1=value1', 'arg2=value2']),
|
||||
('name', self.nodegroup.name),
|
||||
('cluster', self.nodegroup.cluster_id)
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.ng_mock.create.assert_called_with(self.nodegroup.cluster_id,
|
||||
**expected_args)
|
||||
|
||||
|
||||
class TestNodeGroupDelete(TestNodeGroup):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNodeGroupDelete, self).setUp()
|
||||
|
||||
self.ng_mock.delete = mock.Mock()
|
||||
self.ng_mock.delete.return_value = None
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = osc_nodegroups.DeleteNodeGroup(self.app, None)
|
||||
|
||||
def test_nodegroup_delete_one(self):
|
||||
arglist = ['foo', 'fake-nodegroup']
|
||||
verifylist = [
|
||||
('cluster', 'foo'),
|
||||
('nodegroup', ['fake-nodegroup'])
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.ng_mock.delete.assert_called_with('foo', 'fake-nodegroup')
|
||||
|
||||
def test_nodegroup_delete_multiple(self):
|
||||
arglist = ['foo', 'fake-nodegroup1', 'fake-nodegroup2']
|
||||
verifylist = [
|
||||
('cluster', 'foo'),
|
||||
('nodegroup', ['fake-nodegroup1', 'fake-nodegroup2'])
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.ng_mock.delete.assert_has_calls(
|
||||
[call('foo', 'fake-nodegroup1'), call('foo', 'fake-nodegroup2')]
|
||||
)
|
||||
|
||||
def test_nodegroup_delete_no_args(self):
|
||||
arglist = []
|
||||
verifylist = [
|
||||
('cluster', ''),
|
||||
('nodegroup', [])
|
||||
]
|
||||
|
||||
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||
self.check_parser, self.cmd, arglist, verifylist)
|
||||
|
||||
|
||||
class TestNodeGroupUpdate(TestNodeGroup):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNodeGroupUpdate, self).setUp()
|
||||
|
||||
self.ng_mock.update = mock.Mock()
|
||||
self.ng_mock.update.return_value = None
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = osc_nodegroups.UpdateNodeGroup(self.app, None)
|
||||
|
||||
def test_nodegroup_update_pass(self):
|
||||
arglist = ['foo', 'ng1', 'remove', 'bar']
|
||||
verifylist = [
|
||||
('cluster', 'foo'),
|
||||
('nodegroup', 'ng1'),
|
||||
('op', 'remove'),
|
||||
('attributes', [['bar']])
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.ng_mock.update.assert_called_with(
|
||||
'foo', 'ng1',
|
||||
[{'op': 'remove', 'path': '/bar'}]
|
||||
)
|
||||
|
||||
def test_nodegroup_update_bad_op(self):
|
||||
arglist = ['cluster', 'ng1', 'foo', 'bar']
|
||||
verifylist = [
|
||||
('cluster', 'cluster'),
|
||||
('nodegroup', 'ng1'),
|
||||
('op', 'foo'),
|
||||
('attributes', ['bar'])
|
||||
]
|
||||
|
||||
self.assertRaises(magnum_fakes.MagnumParseException,
|
||||
self.check_parser, self.cmd, arglist, verifylist)
|
||||
|
||||
|
||||
class TestNodeGroupShow(TestNodeGroup):
|
||||
|
||||
def setUp(self):
|
||||
@ -81,14 +253,17 @@ class TestNodeGroupList(TestNodeGroup):
|
||||
|
||||
nodegroup = magnum_fakes.FakeNodeGroup.create_one_nodegroup()
|
||||
|
||||
columns = ['uuid', 'name', 'flavor_id', 'node_count', 'role']
|
||||
columns = ['uuid', 'name', 'flavor_id', 'image_id', 'node_count',
|
||||
'status', 'role']
|
||||
|
||||
datalist = (
|
||||
(
|
||||
nodegroup.uuid,
|
||||
nodegroup.name,
|
||||
nodegroup.flavor_id,
|
||||
nodegroup.image_id,
|
||||
nodegroup.node_count,
|
||||
nodegroup.status,
|
||||
nodegroup.role,
|
||||
),
|
||||
)
|
||||
|
@ -13,9 +13,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
|
||||
import testtools
|
||||
from testtools import matchers
|
||||
|
||||
from magnumclient import exceptions
|
||||
from magnumclient.tests import utils
|
||||
from magnumclient.v1 import nodegroups
|
||||
|
||||
@ -53,6 +56,17 @@ NODEGROUP2 = {
|
||||
'min_node_count': 1
|
||||
}
|
||||
|
||||
CREATE_NODEGROUP = copy.deepcopy(NODEGROUP1)
|
||||
del CREATE_NODEGROUP['id']
|
||||
del CREATE_NODEGROUP['uuid']
|
||||
del CREATE_NODEGROUP['node_addresses']
|
||||
del CREATE_NODEGROUP['is_default']
|
||||
del CREATE_NODEGROUP['cluster_id']
|
||||
|
||||
UPDATED_NODEGROUP = copy.deepcopy(NODEGROUP1)
|
||||
NEW_NODE_COUNT = 9
|
||||
UPDATED_NODEGROUP['node_count'] = NEW_NODE_COUNT
|
||||
|
||||
|
||||
fake_responses = {
|
||||
'/v1/clusters/test/nodegroups/':
|
||||
@ -61,6 +75,10 @@ fake_responses = {
|
||||
{},
|
||||
{'nodegroups': [NODEGROUP1, NODEGROUP2]},
|
||||
),
|
||||
'POST': (
|
||||
{},
|
||||
CREATE_NODEGROUP,
|
||||
),
|
||||
},
|
||||
'/v1/clusters/test/nodegroups/%s' % NODEGROUP1['id']:
|
||||
{
|
||||
@ -68,13 +86,36 @@ fake_responses = {
|
||||
{},
|
||||
NODEGROUP1
|
||||
),
|
||||
'DELETE': (
|
||||
{},
|
||||
None,
|
||||
),
|
||||
'PATCH': (
|
||||
{},
|
||||
UPDATED_NODEGROUP,
|
||||
),
|
||||
},
|
||||
'/v1/clusters/test/nodegroups/%s/?rollback=True' % NODEGROUP1['id']:
|
||||
{
|
||||
'PATCH': (
|
||||
{},
|
||||
UPDATED_NODEGROUP,
|
||||
),
|
||||
},
|
||||
'/v1/clusters/test/nodegroups/%s' % NODEGROUP1['name']:
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
NODEGROUP1
|
||||
),
|
||||
'DELETE': (
|
||||
{},
|
||||
None,
|
||||
),
|
||||
'PATCH': (
|
||||
{},
|
||||
UPDATED_NODEGROUP,
|
||||
),
|
||||
},
|
||||
'/v1/clusters/test/nodegroups/?limit=2':
|
||||
{
|
||||
@ -222,3 +263,71 @@ class NodeGroupManagerTest(testtools.TestCase):
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(NODEGROUP1['name'], nodegroup.name)
|
||||
|
||||
def test_nodegroup_delete_by_id(self):
|
||||
nodegroup = self.mgr.delete(self.cluster_id, NODEGROUP1['id'])
|
||||
expect = [
|
||||
('DELETE', self.base_path + '%s' % NODEGROUP1['id'], {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertIsNone(nodegroup)
|
||||
|
||||
def test_nodegroup_delete_by_name(self):
|
||||
nodegroup = self.mgr.delete(self.cluster_id, NODEGROUP1['name'])
|
||||
expect = [
|
||||
('DELETE', self.base_path + '%s' % NODEGROUP1['name'], {}, None),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertIsNone(nodegroup)
|
||||
|
||||
def test_nodegroup_update(self):
|
||||
patch = {'op': 'replace',
|
||||
'value': NEW_NODE_COUNT,
|
||||
'path': '/node_count'}
|
||||
nodegroup = self.mgr.update(self.cluster_id, id=NODEGROUP1['id'],
|
||||
patch=patch)
|
||||
expect = [
|
||||
('PATCH', self.base_path + '%s' % NODEGROUP1['id'], {}, patch),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertEqual(NEW_NODE_COUNT, nodegroup.node_count)
|
||||
|
||||
def test_nodegroup_create(self):
|
||||
nodegroup = self.mgr.create(self.cluster_id, **CREATE_NODEGROUP)
|
||||
expect = [
|
||||
('POST', self.base_path, {}, CREATE_NODEGROUP),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertTrue(nodegroup)
|
||||
|
||||
def test_nodegroup_create_with_docker_volume_size(self):
|
||||
ng_with_volume_size = dict()
|
||||
ng_with_volume_size.update(CREATE_NODEGROUP)
|
||||
ng_with_volume_size['docker_volume_size'] = 20
|
||||
nodegroup = self.mgr.create(self.cluster_id, **ng_with_volume_size)
|
||||
expect = [
|
||||
('POST', self.base_path, {}, ng_with_volume_size),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertTrue(nodegroup)
|
||||
|
||||
def test_nodegroup_create_with_labels(self):
|
||||
ng_with_labels = dict()
|
||||
ng_with_labels.update(CREATE_NODEGROUP)
|
||||
ng_with_labels['labels'] = "key=val"
|
||||
nodegroup = self.mgr.create(self.cluster_id, **ng_with_labels)
|
||||
expect = [
|
||||
('POST', self.base_path, {}, ng_with_labels),
|
||||
]
|
||||
self.assertEqual(expect, self.api.calls)
|
||||
self.assertTrue(nodegroup)
|
||||
|
||||
def test_nodegroup_create_fail(self):
|
||||
CREATE_NODEGROUP_FAIL = copy.deepcopy(CREATE_NODEGROUP)
|
||||
CREATE_NODEGROUP_FAIL["wrong_key"] = "wrong"
|
||||
self.assertRaisesRegex(exceptions.InvalidAttribute,
|
||||
("Key must be in %s" %
|
||||
','.join(nodegroups.CREATION_ATTRIBUTES)),
|
||||
self.mgr.create, self.cluster_id,
|
||||
**CREATE_NODEGROUP_FAIL)
|
||||
self.assertEqual([], self.api.calls)
|
||||
|
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
from magnumclient.common import utils
|
||||
from magnumclient import exceptions
|
||||
from magnumclient.v1 import baseunit
|
||||
|
||||
|
||||
@ -65,3 +66,19 @@ class NodeGroupManager(baseunit.BaseTemplateManager):
|
||||
return self._list(self._path(cluster_id, id=id))[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def create(self, cluster_id, **kwargs):
|
||||
new = {}
|
||||
for (key, value) in kwargs.items():
|
||||
if key in CREATION_ATTRIBUTES:
|
||||
new[key] = value
|
||||
else:
|
||||
raise exceptions.InvalidAttribute(
|
||||
"Key must be in %s" % ",".join(CREATION_ATTRIBUTES))
|
||||
return self._create(self._path(cluster_id), new)
|
||||
|
||||
def delete(self, cluster_id, id):
|
||||
return self._delete(self._path(cluster_id, id=id))
|
||||
|
||||
def update(self, cluster_id, id, patch):
|
||||
return self._update(self._path(cluster_id, id=id), patch)
|
||||
|
@ -59,7 +59,9 @@ openstack.container_infra.v1 =
|
||||
|
||||
coe_nodegroup_list = magnumclient.osc.v1.nodegroups:ListNodeGroup
|
||||
coe_nodegroup_show = magnumclient.osc.v1.nodegroups:ShowNodeGroup
|
||||
|
||||
coe_nodegroup_create = magnumclient.osc.v1.nodegroups:CreateNodeGroup
|
||||
coe_nodegroup_delete = magnumclient.osc.v1.nodegroups:DeleteNodeGroup
|
||||
coe_nodegroup_update = magnumclient.osc.v1.nodegroups:UpdateNodeGroup
|
||||
|
||||
[compile_catalog]
|
||||
directory = magnumclient/locale
|
||||
|
Loading…
x
Reference in New Issue
Block a user