Commit 5c5eb675 authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Apply naming scheme to image cmds

Refs: #4583

All image-property commands --> image modify --property-add/del
All image-compute commands --> imagecompute
imagecompute-property-* --> imagecompute modify --property-add/del
parent 00b1248e
......@@ -54,11 +54,10 @@ from kamaki.cli.commands import (
_optional_output_cmd, _optional_json, _name_filter, _id_filter)
image_cmds = CommandTree(
'image',
'Cyclades/Plankton API image commands\n'
'image compute:\tCyclades/Compute API image commands')
_commands = [image_cmds]
image_cmds = CommandTree('image', 'Cyclades/Plankton API image commands')
imagecompute_cmds = CommandTree(
'imagecompute', 'Cyclades/Compute API image commands')
_commands = [image_cmds, imagecompute_cmds]
howto_image_file = [
......@@ -207,6 +206,8 @@ class image_list(_init_image, _optional_json, _name_filter, _id_filter):
prop_like=KeyValueArgument(
'fliter by property key=value where value is part of actual value',
('--property-like')),
image_ID_for_members=ValueArgument(
'List members of an image', '--members-of')
)
def _filter_by_owner(self, images):
......@@ -233,10 +234,21 @@ class image_list(_init_image, _optional_json, _name_filter, _id_filter):
new_images.append(img)
return new_images
def _members(self, image_id):
members = self.client.list_members(image_id)
if not (self['json_output'] or self['output_format']):
uuids = [member['member_id'] for member in members]
usernames = self._uuids2usernames(uuids)
for member in members:
member['member_id'] += ' (%s)' % usernames[member['member_id']]
self._print(members, title=('member_id',))
@errors.generic.all
@errors.cyclades.connection
def _run(self):
super(self.__class__, self)._run()
if self['image_ID_for_members']:
return self._members(self['image_ID_for_members'])
filters = {}
for arg in set([
'container_format',
......@@ -302,7 +314,7 @@ class image_info(_init_image, _optional_json):
@command(image_cmds)
class image_modify(_init_image, _optional_json):
class image_modify(_init_image, _optional_output_cmd):
"""Add / update metadata and properties for an image
The original image preserves the values that are not affected
"""
......@@ -319,29 +331,42 @@ class image_modify(_init_image, _optional_json):
'set property in key=value form (can be repeated)',
('-p', '--property-set')),
property_to_del=RepeatableArgument(
'Delete property by key (can be repeated)', '--property-del')
'Delete property by key (can be repeated)', '--property-del'),
member_ID_to_add=RepeatableArgument(
'Add member to image (can be repeated)', '--member-add'),
member_ID_to_remove=RepeatableArgument(
'Remove a member (can be repeated)', '--member-del'),
)
required = [
'image_name', 'disk_format', 'container_format', 'status', 'publish',
'unpublish', 'property_to_set']
'unpublish', 'property_to_set', 'member_ID_to_add',
'member_ID_to_remove']
@errors.generic.all
@errors.plankton.connection
@errors.plankton.id
def _run(self, image_id):
meta = self.client.get_meta(image_id)
for k, v in self['property_to_set'].items():
meta['properties'][k.upper()] = v
for k in self['property_to_del']:
meta['properties'][k.upper()] = None
self._optional_output(self.client.update_image(
image_id,
name=self['image_name'],
disk_format=self['disk_format'],
container_format=self['container_format'],
status=self['status'],
public=self['publish'] or self['unpublish'] or None,
**meta['properties']))
for mid in self['member_ID_to_add']:
self.client.add_member(image_id, mid)
for mid in self['member_ID_to_remove']:
self.client.remove_member(image_id, mid)
if len([term for term in self.required if (
self[term] and not term.startswith('member_ID'))]) > 1:
meta = self.client.get_meta(image_id)
for k, v in self['property_to_set'].items():
meta['properties'][k.upper()] = v
for k in self['property_to_del']:
meta['properties'][k.upper()] = None
self._optional_output(self.client.update_image(
image_id,
name=self['image_name'],
disk_format=self['disk_format'],
container_format=self['container_format'],
status=self['status'],
public=self['publish'] or self['unpublish'] or None,
**meta['properties']))
if self['with_output']:
self._optional_output(self.get_image_details(image_id))
def main(self, image_id):
super(self.__class__, self)._run()
......@@ -612,101 +637,10 @@ class image_unregister(_init_image, _optional_output_cmd):
self._run(image_id=image_id)
@command(image_cmds)
class image_shared(_init_image, _optional_json):
"""List images shared by a member"""
@errors.generic.all
@errors.plankton.connection
def _run(self, member):
r = self.client.list_shared(member)
self._print(r, title=('image_id',))
def main(self, member_id_or_username):
super(self.__class__, self)._run()
self._run(member_id_or_username)
@command(image_cmds)
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, _optional_json):
"""List members of an image"""
@errors.generic.all
@errors.plankton.connection
@errors.plankton.id
def _run(self, image_id):
members = self.client.list_members(image_id)
if not (self['json_output'] or self['output_format']):
uuids = [member['member_id'] for member in members]
usernames = self._uuids2usernames(uuids)
for member in members:
member['member_id'] += ' (%s)' % usernames[member['member_id']]
self._print(members, title=('member_id',))
def main(self, image_id):
super(self.__class__, self)._run()
self._run(image_id=image_id)
@command(image_cmds)
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._optional_output(self.client.add_member(image_id, member))
def main(self, image_id, member_id):
super(self.__class__, self)._run()
self._run(image_id=image_id, member=member_id)
@command(image_cmds)
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._optional_output(self.client.remove_member(image_id, member))
def main(self, image_id, member):
super(self.__class__, self)._run()
self._run(image_id=image_id, member=member)
@command(image_cmds)
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._optional_output(self.client.set_members(image_id, members))
def main(self, image_id, *member_ids):
super(self.__class__, self)._run()
self._run(image_id=image_id, members=member_ids)
# Compute Image Commands
@command(image_cmds)
class image_compute(_init_cyclades):
"""Cyclades/Compute API image commands"""
@command(image_cmds)
class image_compute_list(
@command(imagecompute_cmds)
class imagecompute_list(
_init_cyclades, _optional_json, _name_filter, _id_filter):
"""List images"""
......@@ -785,8 +719,8 @@ class image_compute_list(
self._run()
@command(image_cmds)
class image_compute_info(_init_cyclades, _optional_json):
@command(imagecompute_cmds)
class imagecompute_info(_init_cyclades, _optional_json):
"""Get detailed information on an image"""
@errors.generic.all
......@@ -805,8 +739,8 @@ class image_compute_info(_init_cyclades, _optional_json):
self._run(image_id=image_id)
@command(image_cmds)
class image_compute_delete(_init_cyclades, _optional_output_cmd):
@command(imagecompute_cmds)
class imagecompute_delete(_init_cyclades, _optional_output_cmd):
"""Delete an image (WARNING: image file is also removed)"""
@errors.generic.all
......@@ -820,78 +754,32 @@ class image_compute_delete(_init_cyclades, _optional_output_cmd):
self._run(image_id=image_id)
@command(image_cmds)
class image_compute_properties(_init_cyclades):
"""Manage properties related to OS installation in an image"""
@command(imagecompute_cmds)
class imagecompute_modify(_init_cyclades, _optional_output_cmd):
"""Modify image properties (metadata)"""
@command(image_cmds)
class image_compute_properties_list(_init_cyclades, _optional_json):
"""List all image properties"""
arguments = dict(
property_to_add=KeyValueArgument(
'Add property in key=value format (can be repeated)',
('--property-add')),
property_to_del=RepeatableArgument(
'Delete property by key (can be repeated)',
('--property-del'))
)
required = ['property_to_add', 'property_to_del']
@errors.generic.all
@errors.cyclades.connection
@errors.plankton.id
def _run(self, image_id):
self._print(self.client.get_image_metadata(image_id), self.print_dict)
if self['property_to_add']:
self.client.update_image_metadata(
image_id, **self['property_to_add'])
for key in self['property_to_del']:
self.client.delete_image_metadata(image_id, key)
if self['with_output']:
self._optional_output(self.client.get_image_details(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, _optional_json):
"""Get an image property"""
@errors.generic.all
@errors.cyclades.connection
@errors.plankton.id
@errors.plankton.metadata
def _run(self, image_id, key):
self._print(
self.client.get_image_metadata(image_id, key), self.print_dict)
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_properties_set(_init_cyclades, _optional_json):
"""Add / update a set of properties for an image
properties must be given in the form key=value, e.v.
/image compute properties set <image-id> key1=val1 key2=val2
"""
@errors.generic.all
@errors.cyclades.connection
@errors.plankton.id
def _run(self, image_id, keyvals):
meta = dict()
for keyval in keyvals:
key, sep, val = keyval.partition('=')
meta[key] = val
self._print(
self.client.update_image_metadata(image_id, **meta),
self.print_dict)
def main(self, image_id, *key_equals_value):
super(self.__class__, self)._run()
self._run(image_id=image_id, keyvals=key_equals_value)
@command(image_cmds)
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._optional_output(self.client.delete_image_metadata(image_id, key))
def main(self, image_id, key):
super(self.__class__, self)._run()
self._run(image_id=image_id, key=key)
......@@ -222,9 +222,7 @@ class subnet_list(_init_network, _optional_json, _name_filter, _id_filter):
detail=FlagArgument('show detailed output', ('-l', '--details')),
more=FlagArgument(
'output results in pages (-n to set items per page, default 10)',
'--more'),
user_id=ValueArgument(
'show only subnets belonging to user with this id', '--user-id')
'--more')
)
def _filter_by_user_id(self, nets):
......@@ -234,12 +232,11 @@ class subnet_list(_init_network, _optional_json, _name_filter, _id_filter):
@errors.generic.all
@errors.cyclades.connection
def _run(self):
detail = self['detail'] or self['user_id']
nets = self.client.list_subnets()
nets = self._filter_by_user_id(nets)
nets = self._filter_by_name(nets)
nets = self._filter_by_id(nets)
if detail and not self['detail']:
if not self['detail']:
nets = [dict(
id=n['id'], name=n['name'], links=n['links']) for n in nets]
kwargs = dict()
......
......@@ -91,6 +91,7 @@ DEFAULTS = {
'port_cli': 'network',
'ip_cli': 'cyclades',
'image_cli': 'image',
'imagecompute_cli': 'image',
'config_cli': 'config',
'history_cli': 'history'
# Optional command specs:
......
......@@ -244,7 +244,7 @@ class AstakosClient(Client):
self._validate_token(token)
uuid = self._uuids[token]
astakos = self._astakos[uuid]
if set(uuids).difference(self._uuids2usernames[uuid]):
if set(uuids or []).difference(self._uuids2usernames[uuid]):
self._uuids2usernames[uuid].update(astakos.get_usernames(uuids))
return self._uuids2usernames[uuid]
......@@ -254,6 +254,6 @@ class AstakosClient(Client):
self._validate_token(token)
uuid = self._uuids[token]
astakos = self._astakos[uuid]
if set(usernames).difference(self._usernames2uuids[uuid]):
if set(usernames or []).difference(self._usernames2uuids[uuid]):
self._usernames2uuids[uuid].update(astakos.get_uuids(usernames))
return self._usernames2uuids[uuid]
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