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:
- Shell can manage all valid command line arguments [#3716]
- Restore 2nd level command syntax in shell [#3736]
- Allow copy of deleted objects by refering to older version [#3737]
- Add image.add_member missing content-length header
Changes:
......@@ -19,13 +20,23 @@ Changes:
This operation was implemented by accident, due to the symetry between
move and copy
- 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,
manifest, upload, delete, purge, unpublish, permissions set/delete, info,
metadata set/delete, containerlimit set, versioning set, group set/delete,
upload, overwrite
- Transliterate permissions, versioning, group and metadata methods to
get-set-delete command groups
- image:
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:
......
......@@ -33,12 +33,12 @@
from kamaki.cli import command
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.cli.argument import FlagArgument, ValueArgument, KeyValueArgument
from kamaki.cli.argument import IntArgument
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(
......@@ -104,7 +104,8 @@ class image_list(_init_image):
more=FlagArgument(
'output results in pages (-n to set items per page, default 10)',
'--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):
......@@ -146,8 +147,11 @@ class image_list(_init_image):
images = self._filtered_by_owner(detail, filters, order)
else:
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']:
print_items(
images,
......@@ -171,12 +175,16 @@ class image_meta(_init_image):
- image os properties (os, fs, etc.)
"""
arguments = dict(
json_output=FlagArgument('Show results in json', ('-j', '--json'))
)
@errors.generic.all
@errors.plankton.connection
@errors.plankton.id
def _run(self, image_id):
image = self.client.get_meta(image_id)
print_dict(image)
printer = print_json if self['json_output'] else print_dict
printer(self.client.get_meta(image_id))
def main(self, image_id):
super(self.__class__, self)._run()
......@@ -200,9 +208,10 @@ class image_register(_init_image):
('-p', '--property')),
is_public=FlagArgument('mark image as public', '--public'),
size=IntArgument('set image size', '--size'),
update=FlagArgument(
'update existing image properties',
('-u', '--update'))
#update=FlagArgument(
# 'update existing image properties',
# ('-u', '--update')),
json_output=FlagArgument('Show results in json', ('-j', '--json'))
)
@errors.generic.all
......@@ -232,11 +241,9 @@ class image_register(_init_image):
params[key] = self[key]
properties = self['properties']
if self['update']:
self.client.reregister(location, name, params, properties)
else:
r = self.client.register(name, location, params, properties)
print_dict(r)
printer = print_json if self['json_output'] else print_dict
printer(self.client.register(name, location, params, properties))
def main(self, name, location):
super(self.__class__, self)._run()
......@@ -244,14 +251,14 @@ class image_register(_init_image):
@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)"""
@errors.generic.all
@errors.plankton.connection
@errors.plankton.id
def _run(self, image_id):
self.client.unregister(image_id)
self._optional_output(self.client.unregister(image_id))
def main(self, image_id):
super(self.__class__, self)._run()
......@@ -259,45 +266,64 @@ class image_unregister(_init_image):
@command(image_cmds)
class image_members(_init_image):
"""Get image members"""
class image_shared(_init_image):
"""List images shared by a member"""
arguments = dict(
json_output=FlagArgument('Show results in json', ('-j', '--json'))
)
@errors.generic.all
@errors.plankton.connection
@errors.plankton.id
def _run(self, image_id):
members = self.client.list_members(image_id)
print_items(members)
def _run(self, member):
r = self.client.list_shared(member)
if self['json_output']:
print_json(r)
else:
print_items(r, title=('image_id',))
def main(self, image_id):
def main(self, member):
super(self.__class__, self)._run()
self._run(image_id=image_id)
self._run(member)
@command(image_cmds)
class image_shared(_init_image):
"""List images shared by a member"""
class image_members(_init_image):
"""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.plankton.connection
def _run(self, member):
images = self.client.list_shared(member)
print_items(images)
@errors.plankton.id
def _run(self, image_id):
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()
self._run(member)
self._run(image_id=image_id)
@command(image_cmds)
class image_addmember(_init_image):
class image_members_add(_init_image, _optional_output_cmd):
"""Add a member to an image"""
@errors.generic.all
@errors.plankton.connection
@errors.plankton.id
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):
super(self.__class__, self)._run()
......@@ -305,14 +331,14 @@ class image_addmember(_init_image):
@command(image_cmds)
class image_delmember(_init_image):
class image_members_delete(_init_image, _optional_output_cmd):
"""Remove a member from an image"""
@errors.generic.all
@errors.plankton.connection
@errors.plankton.id
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):
super(self.__class__, self)._run()
......@@ -320,14 +346,14 @@ class image_delmember(_init_image):
@command(image_cmds)
class image_setmembers(_init_image):
class image_members_set(_init_image, _optional_output_cmd):
"""Set the members of an image"""
@errors.generic.all
@errors.plankton.connection
@errors.plankton.id
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):
super(self.__class__, self)._run()
......@@ -352,7 +378,8 @@ class image_compute_list(_init_cyclades):
more=FlagArgument(
'output results in pages (-n to set items per page, default 10)',
'--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):
......@@ -364,6 +391,9 @@ class image_compute_list(_init_cyclades):
@errors.cyclades.connection
def _run(self):
images = self.client.list_images(self['detail'])
if self['json_output']:
print_json(images)
return
if self['detail']:
self._make_results_pretty(images)
if self['more']:
......@@ -382,11 +412,18 @@ class image_compute_list(_init_cyclades):
class image_compute_info(_init_cyclades):
"""Get detailed information on an image"""
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):
image = self.client.get_image_details(image_id)
if self['json_output']:
print_json(image)
return
if 'metadata' in image:
image['metadata'] = image['metadata']['values']
print_dict(image)
......@@ -397,14 +434,14 @@ class image_compute_info(_init_cyclades):
@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)"""
@errors.generic.all
@errors.cyclades.connection
@errors.plankton.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):
super(self.__class__, self)._run()
......@@ -413,32 +450,65 @@ class image_compute_delete(_init_cyclades):
@command(image_cmds)
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.cyclades.connection
@errors.plankton.id
@errors.plankton.metadata
def _run(self, image_id, key):
r = self.client.get_image_metadata(image_id, key)
print_dict(r)
printer = print_json if self['json_output'] else print_dict
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()
self._run(image_id=image_id, key=key)
@command(image_cmds)
class image_compute_addproperty(_init_cyclades):
"""Add an OS-related property to an image"""
class image_compute_properties_add(_init_cyclades):
"""Add a property to an image"""
arguments = dict(
json_output=FlagArgument('Show results in json', ('-j', '--json'))
)
@errors.generic.all
@errors.cyclades.connection
@errors.plankton.id
@errors.plankton.metadata
def _run(self, image_id, key, val):
r = self.client.create_image_metadata(image_id, key, val)
print_dict(r)
printer = print_json if self['json_output'] else print_dict
printer(self.client.create_image_metadata(image_id, key, val))
def main(self, image_id, key, val):
super(self.__class__, self)._run()
......@@ -446,33 +516,41 @@ class image_compute_addproperty(_init_cyclades):
@command(image_cmds)
class image_compute_setproperty(_init_cyclades):
"""Update an existing property in an image"""
class image_compute_properties_set(_init_cyclades):
"""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.cyclades.connection
@errors.plankton.id
@errors.plankton.metadata
def _run(self, image_id, key, val):
metadata = {key: val}
r = self.client.update_image_metadata(image_id, **metadata)
print_dict(r)
def main(self, image_id, key, val):
def _run(self, image_id, keyvals):
metadata = dict()
for keyval in keyvals:
key, val = keyval.split('=')
metadata[key] = val
printer = print_json if self['json_output'] else print_dict
printer(self.client.update_image_metadata(image_id, **metadata))
def main(self, image_id, *key_equals_value):
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)
class image_compute_delproperty(_init_cyclades):
"""Delete a property of an image"""
class image_compute_properties_delete(_init_cyclades, _optional_output_cmd):
"""Delete a property from an image"""
@errors.generic.all
@errors.cyclades.connection
@errors.plankton.id
@errors.plankton.metadata
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):
super(self.__class__, self)._run()
......
......@@ -233,7 +233,8 @@ class ComputeClient(ComputeRestClient):
"""
: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=''):
"""
......@@ -280,4 +281,5 @@ class ComputeClient(ComputeRestClient):
:param key: (str) metadatum key
"""
command = path4url('meta', key)
self.images_delete(image_id, command)
r = self.images_delete(image_id, command)
return r.headers
......@@ -99,7 +99,7 @@ class ImageClient(Client):
return reply
def register(self, name, location, params={}, properties={}):
"""Register image put at location
"""Register an image that is uploaded at location
:param name: (str)
......@@ -133,9 +133,12 @@ class ImageClient(Client):
"""Unregister an image
:param image_id: (str)
:returns: (dict) response headers
"""
path = path4url('images', image_id)
self.delete(path, success=204)
r = self.delete(path, success=204)
return r.headers
def list_members(self, image_id):
"""
......@@ -165,7 +168,9 @@ class ImageClient(Client):
:param member: (str) user to allow access to current user's images
"""
path = path4url('images', image_id, 'members', member)
self.put(path, success=204)
self.set_header('Content-Length', len(member))
r = self.put(path, success=204)
return r.headers
def remove_member(self, image_id, member):
"""
......@@ -174,7 +179,8 @@ class ImageClient(Client):
:param member: (str) user to deprive from current user's images
"""
path = path4url('images', image_id, 'members', member)
self.delete(path, success=204)
r = self.delete(path, success=204)
return r.headers
def set_members(self, image_id, members):
"""
......@@ -184,4 +190,5 @@ class ImageClient(Client):
"""
path = path4url('images', image_id, 'members')
req = {'memberships': [{'member_id': member} for member in members]}
self.put(path, json=req, success=204)
r = self.put(path, json=req, success=204)
return r.headers
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment