Commit f5f35422 authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Apply option outputs to image commands + renames

- Add image.add_member missing content-length header
- Rename image-[add|del]member commands to members-[add|delete]
- Remove update option from image-register
- In image-compute split properties to properties-list and properties-get
- Add optional output to methods
 * image: unregister, members add/delete/set
 * image compute: delete, properties delete
- Transliterate methods to list-get-set-delete command groups:
 * image: members, member
 * image compute: properties

Refs :#3756 #3732
parent 915b99b5
...@@ -6,6 +6,7 @@ Bug Fixes: ...@@ -6,6 +6,7 @@ Bug Fixes:
- Shell can manage all valid command line arguments [#3716] - Shell can manage all valid command line arguments [#3716]
- Restore 2nd level command syntax in shell [#3736] - Restore 2nd level command syntax in shell [#3736]
- Allow copy of deleted objects by refering to older version [#3737] - Allow copy of deleted objects by refering to older version [#3737]
- Add image.add_member missing content-length header
Changes: Changes:
...@@ -19,13 +20,23 @@ Changes: ...@@ -19,13 +20,23 @@ Changes:
This operation was implemented by accident, due to the symetry between This operation was implemented by accident, due to the symetry between
move and copy move and copy
- Rename file-meta commands to file-metadata - Rename file-meta commands to file-metadata
- Add optional output for file methods [#3756, #3732]: - Rename image-[add|del]member commands to members-[add|delete]
- Remove update option from imagre-register
- In image-compute split properties to properties-list and properties-get
- Add optional output to methods[#3756, #3732]:
- file:
mkdir, touch, create, move, copy, move, append, truncate, overwrite, mkdir, touch, create, move, copy, move, append, truncate, overwrite,
manifest, upload, delete, purge, unpublish, permissions set/delete, info, manifest, upload, delete, purge, unpublish, permissions set/delete, info,
metadata set/delete, containerlimit set, versioning set, group set/delete, metadata set/delete, containerlimit set, versioning set, group set/delete,
upload, overwrite upload, overwrite
- Transliterate permissions, versioning, group and metadata methods to - image:
get-set-delete command groups unregister, members add/delete/set
-image compute:
delete, properties delete
- Transliterate methods to list-get-set-delete command groups:
- file: permissions, versioning, group and metadata
- image: members, member
- image compute: properties
Features: Features:
......
...@@ -33,12 +33,12 @@ ...@@ -33,12 +33,12 @@
from kamaki.cli import command from kamaki.cli import command
from kamaki.cli.command_tree import CommandTree from kamaki.cli.command_tree import CommandTree
from kamaki.cli.utils import print_dict, print_items from kamaki.cli.utils import print_dict, print_items, print_json
from kamaki.clients.image import ImageClient from kamaki.clients.image import ImageClient
from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument
from kamaki.cli.argument import IntArgument from kamaki.cli.argument import IntArgument
from kamaki.cli.commands.cyclades import _init_cyclades from kamaki.cli.commands.cyclades import _init_cyclades
from kamaki.cli.commands import _command_init, errors from kamaki.cli.commands import _command_init, errors, _optional_output_cmd
image_cmds = CommandTree( image_cmds = CommandTree(
...@@ -104,7 +104,8 @@ class image_list(_init_image): ...@@ -104,7 +104,8 @@ class image_list(_init_image):
more=FlagArgument( more=FlagArgument(
'output results in pages (-n to set items per page, default 10)', 'output results in pages (-n to set items per page, default 10)',
'--more'), '--more'),
enum=FlagArgument('Enumerate results', '--enumerate') enum=FlagArgument('Enumerate results', '--enumerate'),
json_output=FlagArgument('Show results in json', ('-j', '--json'))
) )
def _filtered_by_owner(self, detail, *list_params): def _filtered_by_owner(self, detail, *list_params):
...@@ -146,8 +147,11 @@ class image_list(_init_image): ...@@ -146,8 +147,11 @@ class image_list(_init_image):
images = self._filtered_by_owner(detail, filters, order) images = self._filtered_by_owner(detail, filters, order)
else: else:
images = self.client.list_public(detail, filters, order) images = self.client.list_public(detail, filters, order)
images = self._filtered_by_name(images)
if self['json_output']:
print_json(images)
return
images = self._filtered_by_name(images)
if self['more']: if self['more']:
print_items( print_items(
images, images,
...@@ -171,12 +175,16 @@ class image_meta(_init_image): ...@@ -171,12 +175,16 @@ class image_meta(_init_image):
- image os properties (os, fs, etc.) - image os properties (os, fs, etc.)
""" """
arguments = dict(
json_output=FlagArgument('Show results in json', ('-j', '--json'))
)
@errors.generic.all @errors.generic.all
@errors.plankton.connection @errors.plankton.connection
@errors.plankton.id @errors.plankton.id
def _run(self, image_id): def _run(self, image_id):
image = self.client.get_meta(image_id) printer = print_json if self['json_output'] else print_dict
print_dict(image) printer(self.client.get_meta(image_id))
def main(self, image_id): def main(self, image_id):
super(self.__class__, self)._run() super(self.__class__, self)._run()
...@@ -200,9 +208,10 @@ class image_register(_init_image): ...@@ -200,9 +208,10 @@ class image_register(_init_image):
('-p', '--property')), ('-p', '--property')),
is_public=FlagArgument('mark image as public', '--public'), is_public=FlagArgument('mark image as public', '--public'),
size=IntArgument('set image size', '--size'), size=IntArgument('set image size', '--size'),
update=FlagArgument( #update=FlagArgument(
'update existing image properties', # 'update existing image properties',
('-u', '--update')) # ('-u', '--update')),
json_output=FlagArgument('Show results in json', ('-j', '--json'))
) )
@errors.generic.all @errors.generic.all
...@@ -232,11 +241,9 @@ class image_register(_init_image): ...@@ -232,11 +241,9 @@ class image_register(_init_image):
params[key] = self[key] params[key] = self[key]
properties = self['properties'] properties = self['properties']
if self['update']:
self.client.reregister(location, name, params, properties) printer = print_json if self['json_output'] else print_dict
else: printer(self.client.register(name, location, params, properties))
r = self.client.register(name, location, params, properties)
print_dict(r)
def main(self, name, location): def main(self, name, location):
super(self.__class__, self)._run() super(self.__class__, self)._run()
...@@ -244,14 +251,14 @@ class image_register(_init_image): ...@@ -244,14 +251,14 @@ class image_register(_init_image):
@command(image_cmds) @command(image_cmds)
class image_unregister(_init_image): class image_unregister(_init_image, _optional_output_cmd):
"""Unregister an image (does not delete the image file)""" """Unregister an image (does not delete the image file)"""
@errors.generic.all @errors.generic.all
@errors.plankton.connection @errors.plankton.connection
@errors.plankton.id @errors.plankton.id
def _run(self, image_id): def _run(self, image_id):
self.client.unregister(image_id) self._optional_output(self.client.unregister(image_id))
def main(self, image_id): def main(self, image_id):
super(self.__class__, self)._run() super(self.__class__, self)._run()
...@@ -259,45 +266,64 @@ class image_unregister(_init_image): ...@@ -259,45 +266,64 @@ class image_unregister(_init_image):
@command(image_cmds) @command(image_cmds)
class image_members(_init_image): class image_shared(_init_image):
"""Get image members""" """List images shared by a member"""
arguments = dict(
json_output=FlagArgument('Show results in json', ('-j', '--json'))
)
@errors.generic.all @errors.generic.all
@errors.plankton.connection @errors.plankton.connection
@errors.plankton.id def _run(self, member):
def _run(self, image_id): r = self.client.list_shared(member)
members = self.client.list_members(image_id) if self['json_output']:
print_items(members) print_json(r)
else:
print_items(r, title=('image_id',))
def main(self, image_id): def main(self, member):
super(self.__class__, self)._run() super(self.__class__, self)._run()
self._run(image_id=image_id) self._run(member)
@command(image_cmds) @command(image_cmds)
class image_shared(_init_image): class image_members(_init_image):
"""List images shared by a member""" """Manage members. Members of an image are users who can modify it"""
@command(image_cmds)
class image_members_list(_init_image):
"""List members of an image"""
arguments = dict(
json_output=FlagArgument('Show results in json', ('-j', '--json'))
)
@errors.generic.all @errors.generic.all
@errors.plankton.connection @errors.plankton.connection
def _run(self, member): @errors.plankton.id
images = self.client.list_shared(member) def _run(self, image_id):
print_items(images) members = self.client.list_members(image_id)
if self['json_output']:
print_json(members)
else:
print_items(members, title=('member_id',), with_redundancy=True)
def main(self, member): def main(self, image_id):
super(self.__class__, self)._run() super(self.__class__, self)._run()
self._run(member) self._run(image_id=image_id)
@command(image_cmds) @command(image_cmds)
class image_addmember(_init_image): class image_members_add(_init_image, _optional_output_cmd):
"""Add a member to an image""" """Add a member to an image"""
@errors.generic.all @errors.generic.all
@errors.plankton.connection @errors.plankton.connection
@errors.plankton.id @errors.plankton.id
def _run(self, image_id=None, member=None): def _run(self, image_id=None, member=None):
self.client.add_member(image_id, member) self._optional_output(self.client.add_member(image_id, member))
def main(self, image_id, member): def main(self, image_id, member):
super(self.__class__, self)._run() super(self.__class__, self)._run()
...@@ -305,14 +331,14 @@ class image_addmember(_init_image): ...@@ -305,14 +331,14 @@ class image_addmember(_init_image):
@command(image_cmds) @command(image_cmds)
class image_delmember(_init_image): class image_members_delete(_init_image, _optional_output_cmd):
"""Remove a member from an image""" """Remove a member from an image"""
@errors.generic.all @errors.generic.all
@errors.plankton.connection @errors.plankton.connection
@errors.plankton.id @errors.plankton.id
def _run(self, image_id=None, member=None): def _run(self, image_id=None, member=None):
self.client.remove_member(image_id, member) self._optional_output(self.client.remove_member(image_id, member))
def main(self, image_id, member): def main(self, image_id, member):
super(self.__class__, self)._run() super(self.__class__, self)._run()
...@@ -320,14 +346,14 @@ class image_delmember(_init_image): ...@@ -320,14 +346,14 @@ class image_delmember(_init_image):
@command(image_cmds) @command(image_cmds)
class image_setmembers(_init_image): class image_members_set(_init_image, _optional_output_cmd):
"""Set the members of an image""" """Set the members of an image"""
@errors.generic.all @errors.generic.all
@errors.plankton.connection @errors.plankton.connection
@errors.plankton.id @errors.plankton.id
def _run(self, image_id, members): def _run(self, image_id, members):
self.client.set_members(image_id, members) self._optional_output(self.client.set_members(image_id, members))
def main(self, image_id, *members): def main(self, image_id, *members):
super(self.__class__, self)._run() super(self.__class__, self)._run()
...@@ -352,7 +378,8 @@ class image_compute_list(_init_cyclades): ...@@ -352,7 +378,8 @@ class image_compute_list(_init_cyclades):
more=FlagArgument( more=FlagArgument(
'output results in pages (-n to set items per page, default 10)', 'output results in pages (-n to set items per page, default 10)',
'--more'), '--more'),
enum=FlagArgument('Enumerate results', '--enumerate') enum=FlagArgument('Enumerate results', '--enumerate'),
json_output=FlagArgument('Show results in json', ('-j', '--json'))
) )
def _make_results_pretty(self, images): def _make_results_pretty(self, images):
...@@ -364,6 +391,9 @@ class image_compute_list(_init_cyclades): ...@@ -364,6 +391,9 @@ class image_compute_list(_init_cyclades):
@errors.cyclades.connection @errors.cyclades.connection
def _run(self): def _run(self):
images = self.client.list_images(self['detail']) images = self.client.list_images(self['detail'])
if self['json_output']:
print_json(images)
return
if self['detail']: if self['detail']:
self._make_results_pretty(images) self._make_results_pretty(images)
if self['more']: if self['more']:
...@@ -382,11 +412,18 @@ class image_compute_list(_init_cyclades): ...@@ -382,11 +412,18 @@ class image_compute_list(_init_cyclades):
class image_compute_info(_init_cyclades): class image_compute_info(_init_cyclades):
"""Get detailed information on an image""" """Get detailed information on an image"""
arguments = dict(
json_output=FlagArgument('Show results in json', ('-j', '--json'))
)
@errors.generic.all @errors.generic.all
@errors.cyclades.connection @errors.cyclades.connection
@errors.plankton.id @errors.plankton.id
def _run(self, image_id): def _run(self, image_id):
image = self.client.get_image_details(image_id) image = self.client.get_image_details(image_id)
if self['json_output']:
print_json(image)
return
if 'metadata' in image: if 'metadata' in image:
image['metadata'] = image['metadata']['values'] image['metadata'] = image['metadata']['values']
print_dict(image) print_dict(image)
...@@ -397,14 +434,14 @@ class image_compute_info(_init_cyclades): ...@@ -397,14 +434,14 @@ class image_compute_info(_init_cyclades):
@command(image_cmds) @command(image_cmds)
class image_compute_delete(_init_cyclades): class image_compute_delete(_init_cyclades, _optional_output_cmd):
"""Delete an image (WARNING: image file is also removed)""" """Delete an image (WARNING: image file is also removed)"""
@errors.generic.all @errors.generic.all
@errors.cyclades.connection @errors.cyclades.connection
@errors.plankton.id @errors.plankton.id
def _run(self, image_id): def _run(self, image_id):
self.client.delete_image(image_id) self._optional_output(self.client.delete_image(image_id))
def main(self, image_id): def main(self, image_id):
super(self.__class__, self)._run() super(self.__class__, self)._run()
...@@ -413,32 +450,65 @@ class image_compute_delete(_init_cyclades): ...@@ -413,32 +450,65 @@ class image_compute_delete(_init_cyclades):
@command(image_cmds) @command(image_cmds)
class image_compute_properties(_init_cyclades): class image_compute_properties(_init_cyclades):
"""Get properties related to OS installation in an image""" """Manage proeprties related to OS installation in an image"""
@command(image_cmds)
class image_compute_properties_list(_init_cyclades):
"""List all image properties"""
arguments = dict(
json_output=FlagArgument('Show results in json', ('-j', '--json'))
)
@errors.generic.all
@errors.cyclades.connection
@errors.plankton.id
def _run(self, image_id):
printer = print_json if self['json_output'] else print_dict
printer(self.client.get_image_metadata(image_id))
def main(self, image_id):
super(self.__class__, self)._run()
self._run(image_id=image_id)
@command(image_cmds)
class image_compute_properties_get(_init_cyclades):
"""Get an image property"""
arguments = dict(
json_output=FlagArgument('Show results in json', ('-j', '--json'))
)
@errors.generic.all @errors.generic.all
@errors.cyclades.connection @errors.cyclades.connection
@errors.plankton.id @errors.plankton.id
@errors.plankton.metadata @errors.plankton.metadata
def _run(self, image_id, key): def _run(self, image_id, key):
r = self.client.get_image_metadata(image_id, key) printer = print_json if self['json_output'] else print_dict
print_dict(r) printer(self.client.get_image_metadata(image_id, key))
def main(self, image_id, key=''): def main(self, image_id, key):
super(self.__class__, self)._run() super(self.__class__, self)._run()
self._run(image_id=image_id, key=key) self._run(image_id=image_id, key=key)
@command(image_cmds) @command(image_cmds)
class image_compute_addproperty(_init_cyclades): class image_compute_properties_add(_init_cyclades):
"""Add an OS-related property to an image""" """Add a property to an image"""
arguments = dict(
json_output=FlagArgument('Show results in json', ('-j', '--json'))
)
@errors.generic.all @errors.generic.all
@errors.cyclades.connection @errors.cyclades.connection
@errors.plankton.id @errors.plankton.id
@errors.plankton.metadata @errors.plankton.metadata
def _run(self, image_id, key, val): def _run(self, image_id, key, val):
r = self.client.create_image_metadata(image_id, key, val) printer = print_json if self['json_output'] else print_dict
print_dict(r) printer(self.client.create_image_metadata(image_id, key, val))
def main(self, image_id, key, val): def main(self, image_id, key, val):
super(self.__class__, self)._run() super(self.__class__, self)._run()
...@@ -446,33 +516,41 @@ class image_compute_addproperty(_init_cyclades): ...@@ -446,33 +516,41 @@ class image_compute_addproperty(_init_cyclades):
@command(image_cmds) @command(image_cmds)
class image_compute_setproperty(_init_cyclades): class image_compute_properties_set(_init_cyclades):
"""Update an existing property in an image""" """Add / update a set of properties for an image
proeprties must be given in the form key=value, e.v.
/image compute properties set <image-id> key1=val1 key2=val2
"""
arguments = dict(
json_output=FlagArgument('Show results in json', ('-j', '--json'))
)
@errors.generic.all @errors.generic.all
@errors.cyclades.connection @errors.cyclades.connection
@errors.plankton.id @errors.plankton.id
@errors.plankton.metadata def _run(self, image_id, keyvals):
def _run(self, image_id, key, val): metadata = dict()
metadata = {key: val} for keyval in keyvals:
r = self.client.update_image_metadata(image_id, **metadata) key, val = keyval.split('=')
print_dict(r) metadata[key] = val
printer = print_json if self['json_output'] else print_dict
def main(self, image_id, key, val): printer(self.client.update_image_metadata(image_id, **metadata))
def main(self, image_id, *key_equals_value):
super(self.__class__, self)._run() super(self.__class__, self)._run()
self._run(image_id=image_id, key=key, val=val) self._run(image_id=image_id, keyvals=key_equals_value)
@command(image_cmds) @command(image_cmds)
class image_compute_delproperty(_init_cyclades): class image_compute_properties_delete(_init_cyclades, _optional_output_cmd):
"""Delete a property of an image""" """Delete a property from an image"""
@errors.generic.all @errors.generic.all
@errors.cyclades.connection @errors.cyclades.connection
@errors.plankton.id @errors.plankton.id
@errors.plankton.metadata @errors.plankton.metadata
def _run(self, image_id, key): def _run(self, image_id, key):
self.client.delete_image_metadata(image_id, key) self._optional_output(self.client.delete_image_metadata(image_id, key))
def main(self, image_id, key): def main(self, image_id, key):
super(self.__class__, self)._run() super(self.__class__, self)._run()
......
...@@ -233,7 +233,8 @@ class ComputeClient(ComputeRestClient): ...@@ -233,7 +233,8 @@ class ComputeClient(ComputeRestClient):
""" """
:param image_id: (str) :param image_id: (str)
""" """
self.images_delete(image_id) r = self.images_delete(image_id)
return r.headers
def get_image_metadata(self, image_id, key=''): def get_image_metadata(self, image_id, key=''):
""" """
...@@ -280,4 +281,5 @@ class ComputeClient(ComputeRestClient): ...@@ -280,4 +281,5 @@ class ComputeClient(ComputeRestClient):
:param key: (str) metadatum key :param key: (str) metadatum key
""" """
command = path4url('meta', key) command = path4url('meta', key)
self.images_delete(image_id, command) r = self.images_delete(image_id, command)
return r.headers