Delete keys from resource values/overrides handled in fuel2
Keys deletion for values/overrides handled. Default cliff formatter used for values/overrides operations. Message on values/overrides set command added. Change-Id: Ie47ff6a1cb98764447d045816ea6472a0701dcc3 Closes-Bug: #1622600
This commit is contained in:
parent
5502205a27
commit
db53fcb187
@ -51,7 +51,9 @@ nailgun.extensions =
|
||||
tuning_box.cli =
|
||||
get = tuning_box.cli.resources:Get
|
||||
set = tuning_box.cli.resources:Set
|
||||
del = tuning_box.cli.resources:Delete
|
||||
override = tuning_box.cli.resources:Override
|
||||
rm_override = tuning_box.cli.resources:DeleteOverride
|
||||
env_create = tuning_box.cli.environments:CreateEnvironment
|
||||
env_list = tuning_box.cli.environments:ListEnvironments
|
||||
env_show = tuning_box.cli.environments:ShowEnvironment
|
||||
@ -70,7 +72,9 @@ tuning_box.cli =
|
||||
fuelclient =
|
||||
config_get = tuning_box.fuelclient:Get
|
||||
config_set = tuning_box.fuelclient:Set
|
||||
config_del = tuning_box.fuelclient:Delete
|
||||
config_override = tuning_box.fuelclient:Override
|
||||
config_rm_override = tuning_box.fuelclient:DeleteOverride
|
||||
config_env_create = tuning_box.fuelclient:CreateEnvironment
|
||||
config_env_list = tuning_box.fuelclient:ListEnvironments
|
||||
config_env_show = tuning_box.fuelclient:ShowEnvironment
|
||||
|
@ -11,9 +11,13 @@
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import six
|
||||
import yaml
|
||||
|
||||
from tuning_box.cli import base
|
||||
from cliff import show
|
||||
from fuelclient.cli import error as fc_error
|
||||
from fuelclient.common import data_utils
|
||||
|
||||
from tuning_box.cli.base import BaseCommand
|
||||
from tuning_box.cli.base import level_converter
|
||||
|
||||
@ -22,20 +26,20 @@ class ResourcesCommand(BaseCommand):
|
||||
def get_parser(self, *args, **kwargs):
|
||||
parser = super(ResourcesCommand, self).get_parser(*args, **kwargs)
|
||||
parser.add_argument(
|
||||
'--env',
|
||||
'-e', '--env',
|
||||
type=int,
|
||||
required=True,
|
||||
help="ID of environment to get data from",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--level',
|
||||
'-l', '--level',
|
||||
type=level_converter,
|
||||
default=[],
|
||||
help=("Level to get data from. Should be in format "
|
||||
"parent_level=parent1,level=value2"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--resource',
|
||||
'-r', '--resource',
|
||||
type=str,
|
||||
required=True,
|
||||
help="Name or ID of resource to get data from",
|
||||
@ -51,53 +55,59 @@ class ResourcesCommand(BaseCommand):
|
||||
)
|
||||
|
||||
|
||||
class Get(base.FormattedCommand, ResourcesCommand):
|
||||
class Get(show.ShowOne, ResourcesCommand):
|
||||
|
||||
def get_parser(self, *args, **kwargs):
|
||||
parser = super(Get, self).get_parser(*args, **kwargs)
|
||||
parser.add_argument(
|
||||
'--key',
|
||||
'-k', '--key',
|
||||
type=str,
|
||||
help="Name of key to get from the resource",
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
res = self.get_client().get(
|
||||
response = self.get_client().get(
|
||||
self.get_resource_url(parsed_args),
|
||||
params='effective',
|
||||
)
|
||||
key = parsed_args.key
|
||||
if key is None:
|
||||
return res
|
||||
value = res[key]
|
||||
if parsed_args.format != 'plain':
|
||||
return {key: value}
|
||||
if key is not None:
|
||||
result = {key: response.get(key, {})}
|
||||
else:
|
||||
return value
|
||||
result = response
|
||||
columns = sorted(result.keys())
|
||||
try:
|
||||
data = data_utils.get_display_data_single(columns, result)
|
||||
return columns, data
|
||||
except fc_error.BadDataException:
|
||||
return zip(*response.items())
|
||||
|
||||
|
||||
class Set(ResourcesCommand):
|
||||
|
||||
url_last_part = 'values'
|
||||
entity_name = 'ResourceValue'
|
||||
|
||||
def get_parser(self, *args, **kwargs):
|
||||
parser = super(Set, self).get_parser(*args, **kwargs)
|
||||
parser.add_argument(
|
||||
'--key',
|
||||
'-k', '--key',
|
||||
type=str,
|
||||
help="Name of key to set in the resource",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--value',
|
||||
'-v', '--value',
|
||||
type=str,
|
||||
help="Value for a key to set in the resource",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--type',
|
||||
'-t', '--type',
|
||||
choices=('null', 'int', 'str', 'json', 'yaml', 'bool'),
|
||||
help="Type of value passed in --value",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--format',
|
||||
'-f', '--format',
|
||||
choices=('json', 'yaml'),
|
||||
help="Format of data passed to stdin",
|
||||
)
|
||||
@ -165,6 +175,14 @@ class Set(ResourcesCommand):
|
||||
return doc
|
||||
assert False, "Shouldn't get here"
|
||||
|
||||
def get_update_message(self, parsed_args):
|
||||
if parsed_args.key is None:
|
||||
message = '{0} was set\n'.format(self.entity_name)
|
||||
else:
|
||||
message = '{0} for key {1} was set\n'.format(
|
||||
self.entity_name, parsed_args.key)
|
||||
return message
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.verify_arguments(parsed_args)
|
||||
value = self.get_value_to_set(parsed_args)
|
||||
@ -176,8 +194,50 @@ class Set(ResourcesCommand):
|
||||
resource[parsed_args.key] = value
|
||||
else:
|
||||
resource = value
|
||||
client.put(resource_url, resource)
|
||||
result = client.put(resource_url, resource)
|
||||
if result is None:
|
||||
result = self.get_update_message(parsed_args)
|
||||
self.app.stdout.write(six.text_type(result))
|
||||
|
||||
|
||||
class Delete(ResourcesCommand):
|
||||
|
||||
url_last_part = 'values'
|
||||
entity_name = 'ResourceValue'
|
||||
|
||||
def get_parser(self, *args, **kwargs):
|
||||
parser = super(Delete, self).get_parser(*args, **kwargs)
|
||||
parser.add_argument(
|
||||
'-k', '--key',
|
||||
type=str,
|
||||
help="Name of key to delete from the resource",
|
||||
required=True
|
||||
)
|
||||
return parser
|
||||
|
||||
def get_deletion_message(self, parsed_args):
|
||||
return '{0} for key {1} was deleted\n'.format(
|
||||
self.entity_name, parsed_args.key)
|
||||
|
||||
def get_resource_url(self, parsed_args, last_part='values'):
|
||||
url = super(Delete, self).get_resource_url(
|
||||
parsed_args, last_part=last_part)
|
||||
return url + '/keys/delete'
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.get_client()
|
||||
resource_url = self.get_resource_url(parsed_args, self.url_last_part)
|
||||
result = client.patch(resource_url, [[parsed_args.key]])
|
||||
if result is None:
|
||||
result = self.get_deletion_message(parsed_args)
|
||||
self.app.stdout.write(six.text_type(result))
|
||||
|
||||
|
||||
class Override(Set):
|
||||
url_last_part = 'overrides'
|
||||
entity_name = 'ResourceOverride'
|
||||
|
||||
|
||||
class DeleteOverride(Delete):
|
||||
url_last_part = 'overrides'
|
||||
entity_name = 'ResourceOverride'
|
||||
|
@ -53,10 +53,18 @@ class Set(FuelBaseCommand, resources.Set):
|
||||
pass
|
||||
|
||||
|
||||
class Delete(FuelBaseCommand, resources.Delete):
|
||||
pass
|
||||
|
||||
|
||||
class Override(FuelBaseCommand, resources.Override):
|
||||
pass
|
||||
|
||||
|
||||
class DeleteOverride(FuelBaseCommand, resources.DeleteOverride):
|
||||
pass
|
||||
|
||||
|
||||
class CreateEnvironment(FuelBaseCommand, environments.CreateEnvironment):
|
||||
pass
|
||||
|
||||
|
@ -50,13 +50,13 @@ class TestGet(testscenarios.WithScenarios, _BaseCLITest):
|
||||
for s in [
|
||||
('global,json', (
|
||||
'/environments/1/resources/1/values?effective',
|
||||
'get --env 1 --resource 1',
|
||||
'{"hello": "world"}',
|
||||
'get --env 1 --resource 1 --format=json',
|
||||
'{\n "hello": "world"\n}',
|
||||
)),
|
||||
('lowlevel,json', (
|
||||
'/environments/1/lvl1/value1/resources/1/values?effective',
|
||||
'get --env 1 --level lvl1=value1 --resource 1',
|
||||
'{"hello": "world"}',
|
||||
'get --env 1 --level lvl1=value1 --resource 1 --format=json',
|
||||
'{\n "hello": "world"\n}',
|
||||
)),
|
||||
('global,yaml', (
|
||||
'/environments/1/resources/1/values?effective',
|
||||
@ -68,21 +68,26 @@ class TestGet(testscenarios.WithScenarios, _BaseCLITest):
|
||||
'get --env 1 --level lvl1=value1 --resource 1 --format yaml',
|
||||
'hello: world\n',
|
||||
)),
|
||||
('key,plain', (
|
||||
'/environments/1/resources/1/values?effective',
|
||||
'get --env 1 --resource 1 --key hello --format plain',
|
||||
'world',
|
||||
)),
|
||||
('key,json', (
|
||||
'/environments/1/resources/1/values?effective',
|
||||
'get --env 1 --resource 1 --key hello --format json',
|
||||
'{"hello": "world"}',
|
||||
'{\n "hello": "world"\n}',
|
||||
)),
|
||||
('key,yaml', (
|
||||
'/environments/1/resources/1/values?effective',
|
||||
'get --env 1 --resource 1 --key hello --format yaml',
|
||||
'hello: world\n',
|
||||
)),
|
||||
('no_key,json', (
|
||||
'/environments/1/resources/1/values?effective',
|
||||
'get --env 1 --resource 1 --key no --format json',
|
||||
'{\n "no": {}\n}',
|
||||
)),
|
||||
('no_key,yaml', (
|
||||
'/environments/1/resources/1/values?effective',
|
||||
'get --env 1 --resource 1 --key no --format yaml',
|
||||
"'no': {}\n",
|
||||
))
|
||||
]
|
||||
]
|
||||
|
||||
@ -147,6 +152,56 @@ class TestSet(testscenarios.WithScenarios, _BaseCLITest):
|
||||
self.assertEqual(self.expected_body, req_history[-1].json())
|
||||
|
||||
|
||||
class TestDelete(testscenarios.WithScenarios, _BaseCLITest):
|
||||
scenarios = [
|
||||
(s[0],
|
||||
dict(zip(('args', 'expected_body'), s[1])))
|
||||
for s in [
|
||||
('k1', ('-k k1', "ResourceValue for key k1 was deleted\n")),
|
||||
('xx', ('-k xx', "ResourceValue for key xx was deleted\n")),
|
||||
]
|
||||
]
|
||||
|
||||
args = None
|
||||
expected_body = None
|
||||
url_last_part = 'values'
|
||||
cmd = 'del'
|
||||
|
||||
def test_delete(self):
|
||||
url = self.BASE_URL + '/environments/1/lvl1/value1/resources/1/' + \
|
||||
self.url_last_part + '/keys/delete'
|
||||
self.req_mock.patch(url)
|
||||
args = [self.cmd] + ("--env 1 --level lvl1=value1 --resource 1 " +
|
||||
self.args).split()
|
||||
self.cli.run(args)
|
||||
self.assertEqual(self.expected_body, self.cli.stdout.getvalue())
|
||||
|
||||
|
||||
class TestOverride(TestSet):
|
||||
url_last_part = 'overrides'
|
||||
cmd = 'override'
|
||||
|
||||
|
||||
class TestDeleteOverride(testscenarios.WithScenarios, _BaseCLITest):
|
||||
scenarios = [
|
||||
(s[0],
|
||||
dict(zip(('args', 'expected_body'), s[1])))
|
||||
for s in [
|
||||
('k1', ('-k k1', "ResourceOverride for key k1 was deleted\n")),
|
||||
('xx', ('-k xx', "ResourceOverride for key xx was deleted\n")),
|
||||
]
|
||||
]
|
||||
|
||||
args = None
|
||||
expected_body = None
|
||||
url_last_part = 'overrides'
|
||||
cmd = 'rm override'
|
||||
|
||||
def test_delete(self):
|
||||
url = self.BASE_URL + '/environments/1/lvl1/value1/resources/1/' + \
|
||||
self.url_last_part + '/keys/delete'
|
||||
self.req_mock.patch(url)
|
||||
args = [self.cmd] + ("--env 1 --level lvl1=value1 --resource 1 " +
|
||||
self.args).split()
|
||||
self.cli.run(args)
|
||||
self.assertEqual(self.expected_body, self.cli.stdout.getvalue())
|
||||
|
Loading…
x
Reference in New Issue
Block a user