Allow passing list of dicts for create-vms-conf command.
Previous implementation of command "fuel2 node create-vms-conf"
didn't allow using list of dicts for --conf parameter. It required
to use multiple arguments like:
--conf '{"id": 1}' '{"id": 2}'
which is non obvious for user and inconsistent with UI (in UI
user sees list of dicts).
This patch introduces new possibility to pass parameters
as json list:
--conf '[{"id": 1}, {"id": 2}]'
Change-Id: I50e961c1afce91fd1c43d1fdcf6436a08a20c2be
Related-Bug: #1582136
Closes-Bug: #1582120
(cherry-picked from commit 298187d131
)
This commit is contained in:
parent
fa053d0768
commit
39f6f5f045
@ -13,11 +13,13 @@
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
import json
|
||||
import operator
|
||||
import os
|
||||
|
||||
import six
|
||||
|
||||
from fuelclient.cli import error
|
||||
from fuelclient.commands import base
|
||||
from fuelclient.common import data_utils
|
||||
from fuelclient import utils
|
||||
@ -167,7 +169,7 @@ class NodeCreateVMsConf(NodeMixIn, base.BaseCommand):
|
||||
help='Id of the {0}.'.format(self.entity_name))
|
||||
parser.add_argument(
|
||||
'--conf',
|
||||
type=str,
|
||||
type=json.loads,
|
||||
required=True,
|
||||
nargs='+',
|
||||
help='JSONs with VMs configuration',
|
||||
@ -176,7 +178,12 @@ class NodeCreateVMsConf(NodeMixIn, base.BaseCommand):
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
confs = utils.parse_to_list_of_dicts(parsed_args.conf)
|
||||
try:
|
||||
confs = utils.parse_to_list_of_dicts(parsed_args.conf)
|
||||
except TypeError:
|
||||
raise error.BadDataException(
|
||||
'VM configuration should be a dictionary '
|
||||
'or a list of dictionaries')
|
||||
data = self.client.node_vms_create(parsed_args.id, confs)
|
||||
msg = "{0}".format(data)
|
||||
self.app.stdout.write(msg)
|
||||
|
@ -240,3 +240,21 @@ class TestUtils(base.UnitTestCase):
|
||||
with self.assertRaisesRegexp(error.HTTPError,
|
||||
'403.*{}'.format(text)):
|
||||
client.Client().post_request('address')
|
||||
|
||||
def test_parse_to_list_of_dicts(self):
|
||||
items = utils.parse_to_list_of_dicts([{"id": 1}])
|
||||
self.assertEqual(items, [{"id": 1}])
|
||||
|
||||
items = utils.parse_to_list_of_dicts([{"id": 2}, {"id": 3}])
|
||||
self.assertEqual(items, [{"id": 2}, {"id": 3}])
|
||||
|
||||
items = utils.parse_to_list_of_dicts([[{"id": 4}]])
|
||||
self.assertEqual(items, [{"id": 4}])
|
||||
|
||||
items = utils.parse_to_list_of_dicts(
|
||||
[[{"id": 5}, {"id": 6}], {"id": 7}])
|
||||
self.assertEqual(items, [{"id": 5}, {"id": 6}, {"id": 7}])
|
||||
|
||||
self.assertRaisesRegexp(
|
||||
TypeError, 'A dict or list instance expected',
|
||||
utils.parse_to_list_of_dicts, [42])
|
||||
|
@ -161,6 +161,30 @@ node-4 ansible_host=10.20.0.5
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.node_vms_create.assert_called_once_with(node_id, config)
|
||||
|
||||
def test_node_vms_conf_create_from_list(self):
|
||||
vms_conf = '[{"id": 2}, {"id": 3}]'
|
||||
config = [{'id': 2}, {'id': 3}]
|
||||
|
||||
node_id = 42
|
||||
|
||||
args = "node create-vms-conf {0} --conf '{1}'".format(
|
||||
node_id, vms_conf)
|
||||
self.exec_command(args)
|
||||
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.node_vms_create.assert_called_once_with(node_id, config)
|
||||
|
||||
@mock.patch('argparse.ArgumentParser.error')
|
||||
def test_node_vms_conf_create_fail(self, m_error):
|
||||
vms_conf = '[{"id": '
|
||||
node_id = 42
|
||||
|
||||
args = "node create-vms-conf {0} --conf '{1}'".format(
|
||||
node_id, vms_conf)
|
||||
self.exec_command(args)
|
||||
args, _ = m_error.call_args
|
||||
self.assertIn('--conf', args[0])
|
||||
|
||||
def test_node_set_hostname(self):
|
||||
self.m_client._updatable_attributes = \
|
||||
node.NodeClient._updatable_attributes
|
||||
|
@ -17,7 +17,6 @@
|
||||
import functools
|
||||
import glob
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import six
|
||||
import subprocess
|
||||
@ -135,7 +134,7 @@ def file_exists(path):
|
||||
return os.path.lexists(path)
|
||||
|
||||
|
||||
def parse_to_list_of_dicts(str_list):
|
||||
def parse_to_list_of_dicts(items):
|
||||
"""Parse list of json strings to dictionaries
|
||||
|
||||
:param list: list of dicts and json string
|
||||
@ -143,14 +142,14 @@ def parse_to_list_of_dicts(str_list):
|
||||
|
||||
"""
|
||||
dict_list = []
|
||||
for json_str in str_list:
|
||||
if not isinstance(json_str, dict):
|
||||
try:
|
||||
json_str = json.loads(json_str)
|
||||
except Exception:
|
||||
raise error.BadDataException(
|
||||
'Not valid JSON data: {0}'.format(json_str))
|
||||
dict_list.append(json_str)
|
||||
for item in items:
|
||||
if isinstance(item, dict):
|
||||
dict_list.append(item)
|
||||
elif isinstance(item, list):
|
||||
dict_list.extend(item)
|
||||
else:
|
||||
raise TypeError(
|
||||
'A dict or list instance expected: {0}'.format(item))
|
||||
return dict_list
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user