-# Copyright 2011-2012 GRNET S.A. All rights reserved.
+# Copyright 2011-2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# or implied, of GRNET S.A.command
from traceback import print_stack, print_exc
+from astakosclient import AstakosClientException
from kamaki.clients import ClientError
from kamaki.cli.errors import CLIError, raiseCLIError, CLISyntaxError
class generic(object):
@classmethod
- def all(this, foo):
+ def all(this, func):
def _raise(self, *args, **kwargs):
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except Exception as e:
if _debug:
print_stack()
return _raise
@classmethod
- def _connection(this, foo):
+ def _connection(this, func):
def _raise(self, *args, **kwargs):
try:
- foo(self, *args, **kwargs)
+ func(self, *args, **kwargs)
except ClientError as ce:
ce_msg = ('%s' % ce).lower()
if ce.status == 401:
'* (temporary): re-run with <token> parameter'] + CLOUDNAME
@classmethod
- def load(this, foo):
+ def astakosclient(this, func):
def _raise(self, *args, **kwargs):
- r = foo(self, *args, **kwargs)
+ try:
+ r = func(self, *args, **kwargs)
+ except AstakosClientException as ace:
+ raiseCLIError(ace, 'Error in synnefo-AstakosClient')
+ return r
+ return _raise
+
+ @classmethod
+ def load(this, func):
+ def _raise(self, *args, **kwargs):
+ r = func(self, *args, **kwargs)
try:
client = getattr(self, 'client')
except AttributeError as ae:
kloger.warning(
'No permanent token (try:'
' kamaki config set cloud.default.token <tkn>)')
- if not getattr(client, 'base_url', False):
+ if not getattr(client, 'astakos_base_url', False):
msg = 'Missing synnefo authentication URL'
raise CLIError(msg, importance=3, details=[
'Check if authentication URL is correct',
return _raise
@classmethod
- def authenticate(this, foo):
+ def authenticate(this, func):
def _raise(self, *args, **kwargs):
try:
- return foo(self, *args, **kwargs)
- except ClientError as ce:
+ return func(self, *args, **kwargs)
+ except (ClientError, AstakosClientException) as ce:
if ce.status == 401:
token = kwargs.get('custom_token', 0) or self.client.token
- msg = (
- 'Authorization failed for token %s' % token
- ) if token else 'No token provided',
+ msg = ('Authorization failed for token %s' % token) if (
+ token) else 'No token provided',
details = [] if token else this._token_details
raiseCLIError(ce, msg, details=details)
raise ce
- self._raise = foo
+ self._raise = func
return _raise
class history(object):
@classmethod
- def init(this, foo):
+ def init(this, func):
def _raise(self, *args, **kwargs):
- r = foo(self, *args, **kwargs)
+ r = func(self, *args, **kwargs)
if not hasattr(self, 'history'):
raise CLIError('Failed to load history', importance=2)
return r
return _raise
@classmethod
- def _get_cmd_ids(this, foo):
+ def _get_cmd_ids(this, func):
def _raise(self, cmd_ids, *args, **kwargs):
if not cmd_ids:
raise CLISyntaxError(
'Usage: <id1|id1-id2> [id3|id3-id4] ...',
details=self.__doc__.split('\n'))
- return foo(self, cmd_ids, *args, **kwargs)
+ return func(self, cmd_ids, *args, **kwargs)
return _raise
'* get a list of network ids: /network list',
'* details of network: /network info <network id>']
+ net_types = ('CUSTOM', 'MAC_FILTERED', 'IP_LESS_ROUTED', 'PHYSICAL_VLAN')
+
@classmethod
- def connection(this, foo):
- return generic._connection(foo)
+ def connection(this, func):
+ return generic._connection(func)
@classmethod
- def date(this, foo):
+ def date(this, func):
def _raise(self, *args, **kwargs):
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ClientError as ce:
if ce.status == 400 and 'changes-since' in ('%s' % ce):
raise CLIError(
return _raise
@classmethod
- def network_id(this, foo):
+ def cluster_size(this, func):
+ def _raise(self, *args, **kwargs):
+ size = kwargs.get('size', None)
+ try:
+ size = int(size)
+ assert size > 0, 'Cluster size must be a positive integer'
+ return func(self, *args, **kwargs)
+ except ValueError as ve:
+ msg = 'Invalid cluster size value %s' % size
+ raiseCLIError(ve, msg, importance=1, details=[
+ 'Cluster size must be a positive integer'])
+ except AssertionError as ae:
+ raiseCLIError(
+ ae, 'Invalid cluster size %s' % size, importance=1)
+ except ClientError:
+ raise
+ return _raise
+
+ @classmethod
+ def network_id(this, func):
def _raise(self, *args, **kwargs):
network_id = kwargs.get('network_id', None)
try:
network_id = int(network_id)
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ValueError as ve:
msg = 'Invalid network id %s ' % network_id
- details = ['network id must be a positive integer']
+ details = 'network id must be a positive integer'
raiseCLIError(ve, msg, details=details, importance=1)
except ClientError as ce:
if network_id and ce.status == 404 and (
return _raise
@classmethod
- def network_max(this, foo):
+ def network_type(this, func):
+ def _raise(self, *args, **kwargs):
+ network_type = kwargs.get('network_type', None)
+ msg = 'Invalid network type %s.\nValid types: %s' % (
+ network_type, ' '.join(this.net_types))
+ assert network_type in this.net_types, msg
+ return func(self, *args, **kwargs)
+ return _raise
+
+ @classmethod
+ def network_max(this, func):
def _raise(self, *args, **kwargs):
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ClientError as ce:
if ce.status == 413:
msg = 'Cannot create another network',
return _raise
@classmethod
- def network_in_use(this, foo):
+ def network_in_use(this, func):
def _raise(self, *args, **kwargs):
network_id = kwargs.get('network_id', None)
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ClientError as ce:
- if network_id and ce.status == 400:
+ if network_id and ce.status in (400, ):
msg = 'Network with id %s does not exist' % network_id,
raiseCLIError(ce, msg, details=this.about_network_id)
- elif network_id or ce.status == 421:
+ elif network_id or ce.status in (421, ):
msg = 'Network with id %s is in use' % network_id,
raiseCLIError(ce, msg, details=[
- 'Disconnect all nics/VMs of this network first',
+ 'Disconnect all nics/servers of this network first',
'* to get nics: /network info %s' % network_id,
'. (under "attachments" section)',
'* to disconnect: /network disconnect <nic id>'])
return _raise
@classmethod
- def flavor_id(this, foo):
+ def flavor_id(this, func):
def _raise(self, *args, **kwargs):
flavor_id = kwargs.get('flavor_id', None)
try:
flavor_id = int(flavor_id)
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ValueError as ve:
msg = 'Invalid flavor id %s ' % flavor_id,
- details = 'Flavor id must be a positive integer',
+ details = 'Flavor id must be a positive integer'
raiseCLIError(ve, msg, details=details, importance=1)
except ClientError as ce:
if flavor_id and ce.status == 404 and (
return _raise
@classmethod
- def server_id(this, foo):
+ def server_id(this, func):
def _raise(self, *args, **kwargs):
server_id = kwargs.get('server_id', None)
try:
server_id = int(server_id)
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ValueError as ve:
- msg = 'Invalid server(VM) id %s' % server_id,
- details = ['id must be a positive integer'],
+ msg = 'Invalid virtual server id %s' % server_id,
+ details = 'Server id must be a positive integer'
raiseCLIError(ve, msg, details=details, importance=1)
except ClientError as ce:
err_msg = ('%s' % ce).lower()
) or (
ce.status == 400 and 'not found' in err_msg
):
- msg = 'server(VM) with id %s not found' % server_id,
+ msg = 'virtual server with id %s not found' % server_id,
raiseCLIError(ce, msg, details=[
- '* to get existing VM ids: /server list',
- '* to get VM details: /server info <VM id>'])
+ '* to get ids of all servers: /server list',
+ '* to get server details: /server info <server id>'])
raise
return _raise
@classmethod
- def firewall(this, foo):
+ def firewall(this, func):
def _raise(self, *args, **kwargs):
profile = kwargs.get('profile', None)
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ClientError as ce:
if ce.status == 400 and profile and (
'firewall' in ('%s' % ce).lower()
return _raise
@classmethod
- def nic_id(this, foo):
+ def nic_id(this, func):
def _raise(self, *args, **kwargs):
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ClientError as ce:
nic_id = kwargs.get('nic_id', None)
if nic_id and ce.status == 404 and (
'network interface' in ('%s' % ce).lower()
):
server_id = kwargs.get('server_id', '<no server>')
- err_msg = 'No nic %s on server(VM) with id %s' % (
+ err_msg = 'No nic %s on virtual server with id %s' % (
nic_id,
server_id)
raiseCLIError(ce, err_msg, details=[
- '* check server(VM) with id %s: /server info %s' % (
+ '* check v. server with id %s: /server info %s' % (
server_id,
server_id),
- '* list nics for server(VM) with id %s:' % server_id,
+ '* list nics for v. server with id %s:' % server_id,
' /server addr %s' % server_id])
raise
return _raise
@classmethod
- def nic_format(this, foo):
+ def nic_format(this, func):
def _raise(self, *args, **kwargs):
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except IndexError as ie:
nic_id = kwargs.get('nic_id', None)
msg = 'Invalid format for network interface (nic) %s' % nic_id
return _raise
@classmethod
- def metadata(this, foo):
+ def metadata(this, func):
def _raise(self, *args, **kwargs):
key = kwargs.get('key', None)
try:
- foo(self, *args, **kwargs)
+ func(self, *args, **kwargs)
except ClientError as ce:
if key and ce.status == 404 and (
'metadata' in ('%s' % ce).lower()
):
- raiseCLIError(ce, 'No VM metadata with key %s' % key)
+ raiseCLIError(
+ ce, 'No virtual server metadata with key %s' % key)
raise
return _raise
about_image_id = [
'How to pick a suitable image:',
'* get a list of image ids: /image list',
- '* details of image: /flavor info <image id>']
+ '* details of image: /image meta <image id>']
@classmethod
- def connection(this, foo):
- return generic._connection(foo)
+ def connection(this, func):
+ return generic._connection(func)
@classmethod
- def id(this, foo):
+ def id(this, func):
def _raise(self, *args, **kwargs):
image_id = kwargs.get('image_id', None)
try:
- foo(self, *args, **kwargs)
+ func(self, *args, **kwargs)
except ClientError as ce:
if image_id and (
ce.status == 404
return _raise
@classmethod
- def metadata(this, foo):
+ def metadata(this, func):
def _raise(self, *args, **kwargs):
key = kwargs.get('key', None)
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ClientError as ce:
ce_msg = ('%s' % ce).lower()
if ce.status == 404 or (
'For a list of containers: /file list']
@classmethod
- def connection(this, foo):
- return generic._connection(foo)
+ def connection(this, func):
+ return generic._connection(func)
@classmethod
- def account(this, foo):
+ def account(this, func):
def _raise(self, *args, **kwargs):
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ClientError as ce:
if ce.status == 403:
raiseCLIError(
return _raise
@classmethod
- def quota(this, foo):
+ def quota(this, func):
def _raise(self, *args, **kwargs):
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ClientError as ce:
if ce.status == 413:
raiseCLIError(ce, 'User quota exceeded', details=[
return _raise
@classmethod
- def container(this, foo):
+ def container(this, func):
def _raise(self, *args, **kwargs):
dst_cont = kwargs.get('dst_cont', None)
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ClientError as ce:
if ce.status == 404 and 'container' in ('%s' % ce).lower():
cont = ('%s or %s' % (
return _raise
@classmethod
- def local_path(this, foo):
+ def local_path_download(this, func):
+ def _raise(self, *args, **kwargs):
+ try:
+ return func(self, *args, **kwargs)
+ except IOError as ioe:
+ msg = 'Failed to access a local file',
+ raiseCLIError(ioe, msg, importance=2, details=[
+ 'Check if the file exists. Also check if the remote',
+ 'directories exist. All directories in a remote path',
+ 'must exist to succesfully download a container or a',
+ 'directory.',
+ 'To create a remote directory:',
+ ' [kamaki] file mkdir REMOTE_DIRECTORY_PATH'])
+ return _raise
+
+ @classmethod
+ def local_path(this, func):
def _raise(self, *args, **kwargs):
- local_path = kwargs.get('local_path', '<None>')
+ local_path = kwargs.get('local_path', None)
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except IOError as ioe:
msg = 'Failed to access file %s' % local_path,
raiseCLIError(ioe, msg, importance=2)
return _raise
@classmethod
- def object_path(this, foo):
+ def object_path(this, func):
def _raise(self, *args, **kwargs):
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ClientError as ce:
err_msg = ('%s' % ce).lower()
if (
return _raise
@classmethod
- def object_size(this, foo):
+ def object_size(this, func):
def _raise(self, *args, **kwargs):
size = kwargs.get('size', None)
start = kwargs.get('start', 0)
importance=1)
size = end - start
try:
- return foo(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
except ClientError as ce:
err_msg = ('%s' % ce).lower()
expected = 'object length is smaller than range length'