remove_colors()
_silent = arguments['silent'].value
_setup_logging(_silent, _debug, _verbose, _include)
+ global_url = arguments['config'].get('global', 'url')
+ global_token = arguments['config'].get('global', 'token')
+ from kamaki.clients.astakos import AstakosClient as AuthCachedClient
+ return AuthCachedClient(global_url, global_token)
def _load_spec_module(spec, arguments, module):
- spec_name = arguments['config'].get(spec, 'cli')
- if spec_name is None:
+ #spec_name = arguments['config'].get('cli', spec)
+ if not spec:
return None
pkg = None
for location in cmd_spec_locations:
- location += spec_name if location == '' else '.%s' % spec_name
+ location += spec if location == '' else '.%s' % spec
try:
pkg = __import__(location, fromlist=[module])
return pkg
- except ImportError:
+ except ImportError as ie:
continue
+ if not pkg:
+ kloger.debug('Loading cmd grp %s failed: %s' % (spec, ie))
return pkg
global _debug
global kloger
descriptions = {}
- for spec in arguments['config'].get_groups():
+ for cmd_group, spec in arguments['config'].get_cli_specs():
pkg = _load_spec_module(spec, arguments, '_commands')
if pkg:
- cmds = None
- try:
- _cnf = arguments['config']
- cmds = [cmd for cmd in getattr(pkg, '_commands') if _cnf.get(
- cmd.name, 'cli')]
- except AttributeError:
- if _debug:
- kloger.warning('No description for %s' % spec)
+ cmds = getattr(pkg, '_commands')
+ #try:
+ # #_cnf = arguments['config']
+ # #cmds = [cmd for cmd in getattr(pkg, '_commands') if _cnf.get(
+ # # 'cli', cmd.name)]
+ #except AttributeError:
+ # if _debug:
+ # kloger.warning('No description for %s' % cmd_group)
try:
for cmd in cmds:
descriptions[cmd.name] = cmd.description
except TypeError:
if _debug:
- kloger.warning('no cmd specs in module %s' % spec)
+ kloger.warning(
+ 'No cmd description for module %s' % cmd_group)
elif _debug:
- kloger.warning('Loading of %s cmd spec failed' % spec)
+ kloger.warning('Loading of %s cmd spec failed' % cmd_group)
print('\nOptions:\n - - - -')
print_dict(descriptions)
def _load_all_commands(cmd_tree, arguments):
_cnf = arguments['config']
- specs = [spec for spec in _cnf.get_groups() if _cnf.get(spec, 'cli')]
- for spec in specs:
+ #specs = [spec for spec in _cnf.get_groups() if _cnf.get(spec, 'cli')]
+ for cmd_group, spec in _cnf.get_cli_specs():
try:
spec_module = _load_spec_module(spec, arguments, '_commands')
spec_commands = getattr(spec_module, '_commands')
except AttributeError:
if _debug:
global kloger
- kloger.warning('No valid description for %s' % spec)
+ kloger.warning('No valid description for %s' % cmd_group)
continue
for spec_tree in spec_commands:
- if spec_tree.name == spec:
+ if spec_tree.name == cmd_group:
cmd_tree.add_tree(spec_tree)
break
errmsg = red(errmsg)
stdout.write(errmsg)
for errmsg in cli_err.details:
- print('| %s' % errmsg)
+ print('| %s' % errmsg)
def exec_cmd(instance, cmd_args, help_method):
# CLI Choice:
-def run_one_cmd(exe_string, parser):
+def run_one_cmd(exe_string, parser, auth_base):
global _history
_history = History(
parser.arguments['config'].get('history', 'file'))
_history.add(' '.join([exe_string] + argv[1:]))
from kamaki.cli import one_command
- one_command.run(parser, _help)
+ one_command.run(auth_base, parser, _help)
-def run_shell(exe_string, parser):
+def run_shell(exe_string, parser, auth_base):
from command_shell import _init_shell
shell = _init_shell(exe_string, parser)
_load_all_commands(shell.cmd_tree, parser.arguments)
- shell.run(parser)
+ shell.run(auth_base, parser)
def main():
filelog = logger.add_file_logger(__name__.split('.')[0])
filelog.info('* Initial Call *\n%s\n- - -' % ' '.join(argv))
- _init_session(parser.arguments)
+ auth_base = _init_session(parser.arguments)
from kamaki.cli.utils import suggest_missing
suggest_missing()
if parser.unparsed:
- run_one_cmd(exe, parser)
+ run_one_cmd(exe, parser, auth_base)
elif _help:
parser.parser.print_help()
_groups_help(parser.arguments)
else:
- run_shell(exe, parser)
+ run_shell(exe, parser, auth_base)
except CLIError as err:
print_error_message(err)
if _debug:
return self.value.get(group, term)
def get_groups(self):
- return self.value.apis()
+ return self.value.keys('cli')
+
+ def get_cli_specs(self):
+ return self.value.items('cli')
_config_arg = ConfigArgument(
1, 'Path to configuration file',
_context_stack = []
_prompt_stack = []
_parser = None
+ auth_base = None
undoc_header = 'interactive shell commands:'
if subcmd.path == 'history_run':
instance = cls(
dict(cmd_parser.arguments),
- self.cmd_tree)
+ cmd_tree=self.cmd_tree)
else:
- instance = cls(dict(cmd_parser.arguments))
+ instance = cls(
+ dict(cmd_parser.arguments), self.auth_base)
cmd_parser.update_arguments(instance.arguments)
- #instance.arguments.pop('config')
cmd_parser.arguments = instance.arguments
cmd_parser.syntax = '%s %s' % (
subcmd.path.replace('_', ' '), cls.syntax)
hdr = tmp_partition[0].strip()
return '%s commands:' % hdr
- def run(self, parser, path=''):
+ def run(self, auth_base, parser, path=''):
+ self.auth_base = auth_base
self._parser = parser
self._history = History(
parser.arguments['config'].get('history', 'file'))
class _command_init(object):
- def __init__(self, arguments={}):
+ def __init__(self, arguments={}, auth_base=None):
if hasattr(self, 'arguments'):
arguments.update(self.arguments)
if isinstance(self, _optional_output_cmd):
self.config = self['config']
except KeyError:
pass
+ self.auth_base = auth_base or getattr(self, 'auth_base', None)
def _set_log_params(self):
try:
# or implied, of GRNET S.A.command
from kamaki.cli import command
-from kamaki.clients.astakos import AstakosClient
+#from kamaki.clients.astakos import AstakosClient
from kamaki.cli.commands import _command_init, errors, _optional_json
from kamaki.cli.command_tree import CommandTree
@errors.generic.all
@errors.user.load
def _run(self):
- token = self.config.get('user', 'token')\
- or self.config.get('global', 'token')
- base_url = self.config.get('user', 'url')\
- or self.config.get('global', 'url')
- self.client = AstakosClient(base_url=base_url, token=token)
+ #token = self.config.get('user', 'token')\
+ # or self.config.get('global', 'token')
+ #base_url = self.config.get('global', 'url')
+ #self.client = AstakosClient(base_url=base_url, token=token)
+ self.client = self.auth_base
self._set_log_params()
self._update_max_threads()
@errors.user.authenticate
def _run(self, custom_token=None):
super(self.__class__, self)._run()
- self._print(
- [self.client.authenticate(custom_token)],
- title=('uuid', 'name',), with_redundancy=True)
+ r = self.auth_base.authenticate(custom_token)
+ self._print([r], title=('uuid', 'name',), with_redundancy=True)
def main(self, custom_token=None):
self._run(custom_token)
about_options = '\nAbout options:\
\n. syntax: [group.]option\
- \n. example: file.account\
+ \n. example: file.uuid\
\n. special case: <option> is equivalent to global.<option>\
\n. configuration file syntax:\
\n. [group]\
def _run(self, service='compute'):
token = self.config.get(service, 'token')\
or self.config.get('global', 'token')
- base_url = self.config.get(service, 'url')\
- or self.config.get('global', 'url')
+ cyclades_endpoints = self.auth_base.get_service_endpoints(
+ self.config.get('cyclades', 'type'),
+ self.config.get('cyclades', 'version'))
+ base_url = cyclades_endpoints['publicURL']
self.client = CycladesClient(base_url=base_url, token=token)
self._set_log_params()
self._update_max_threads()
return _raise
@classmethod
- def _connection(this, foo, base_url):
+ def _connection(this, foo):
def _raise(self, *args, **kwargs):
try:
foo(self, *args, **kwargs)
' to get current token: /config get [server.]token'])
elif ce.status in range(-12, 200) + [302, 401, 403, 500]:
raiseCLIError(ce, importance=3, details=[
- 'Check if service is up or set to url %s' % base_url,
- ' to get url: /config get %s' % base_url,
- ' to set url: /config set %s <URL>' % base_url])
+ 'Check if serviceis up'])
elif ce.status == 404 and 'kamakihttpresponse' in ce_msg:
client = getattr(self, 'client', None)
if not client:
url = getattr(client, 'base_url', '<empty>')
msg = 'Invalid service url %s' % url
raiseCLIError(ce, msg, details=[
- 'Please, check if service url is correctly set',
- '* to get current url: /config get compute.url',
- '* to set url: /config set compute.url <URL>'])
+ 'Check if authentication url is correct',
+ ' check current url: /config get url',
+ ' set new auth. url: /config set url'])
raise
return _raise
_token_details = [
'To check default token: /config get token',
'If set/update a token:',
- '* (permanent): /config set token <token>',
- '* (temporary): re-run with <token> parameter']
+ '* (permanent): /config set token <token>',
+ '* (temporary): re-run with <token> parameter']
@classmethod
def load(this, foo):
kloger.warning(
'No permanent token (try: kamaki config set token <tkn>)')
if not getattr(client, 'base_url', False):
- msg = 'Missing astakos server URL'
+ msg = 'Missing synnefo URL'
raise CLIError(msg, importance=3, details=[
- 'Check if user.url is set correctly',
- 'To get astakos url: /config get user.url',
- 'To set astakos url: /config set user.url <URL>'])
+ 'Check if authentication url is correct',
+ ' check current url: /config get url',
+ ' set new auth. url: /config set url'])
return r
return _raise
@classmethod
def connection(this, foo):
- return generic._connection(foo, 'compute.url')
+ return generic._connection(foo)
@classmethod
def date(this, foo):
@classmethod
def connection(this, foo):
- return generic._connection(foo, 'image.url')
+ return generic._connection(foo)
@classmethod
def id(this, foo):
@classmethod
def connection(this, foo):
- return generic._connection(foo, 'file.url')
+ return generic._connection(foo)
@classmethod
def account(this, foo):
_cmd_tree = None
- def __init__(self, arguments={}, cmd_tree=None):
+ def __init__(self, arguments={}, auth_base=None, cmd_tree=None):
super(self.__class__, self).__init__(arguments)
self._cmd_tree = cmd_tree
token = self.config.get('image', 'token')\
or self.config.get('compute', 'token')\
or self.config.get('global', 'token')
+ plankton_endpoints = self.auth_base.get_service_endpoints(
+ self.config.get('plankton', 'type'),
+ self.config.get('plankton', 'version'))
+ base_url = plankton_endpoints['publicURL']
base_url = self.config.get('image', 'url')\
or self.config.get('compute', 'url')\
or self.config.get('global', 'url')
def _get_pithos_client(self, container):
if self['no_metafile_upload']:
return None
- purl = self.config.get('file', 'url')
+ pithos_endpoints = self.auth_base.get_service_endpoints(
+ self.config.get('pithos', 'type'),
+ self.config.get('pithos', 'version'))
+ purl = pithos_endpoints['publicURL']
ptoken = self.client.token
return PithosClient(purl, ptoken, self._get_uuid(), container)
def _run(self):
self.token = self.config.get('file', 'token')\
or self.config.get('global', 'token')
- self.base_url = self.config.get('file', 'url')\
- or self.config.get('global', 'url')
+ pithos_endpoints = self.auth_base.get_service_endpoints(
+ self.config.get('pithos', 'type'),
+ self.config.get('pithos', 'version'))
+ self.base_url = pithos_endpoints['publicURL']
self._set_account()
self.container = self.config.get('file', 'container')\
or self.config.get('global', 'container')
self._run()
def _set_account(self):
- user = AstakosClient(self.config.get('user', 'url'), self.token)
- self.account = self['account'] or user.term('uuid')
-
- """Backwards compatibility"""
- self.account = self.account\
- or self.config.get('file', 'account')\
- or self.config.get('global', 'account')
+ self.account = self.auth_base.user_term('uuid', self.token)
class _file_account_command(_pithos_init):
"""Base class for account level storage commands"""
- def __init__(self, arguments={}):
- super(_file_account_command, self).__init__(arguments)
+ def __init__(self, arguments={}, auth_base=None):
+ super(_file_account_command, self).__init__(arguments, auth_base)
self['account'] = ValueArgument(
'Set user account (not permanent)',
('-A', '--account'))
container = None
path = None
- def __init__(self, arguments={}):
- super(_file_container_command, self).__init__(arguments)
+ def __init__(self, arguments={}, auth_base=None):
+ super(_file_container_command, self).__init__(arguments, auth_base)
self['container'] = ValueArgument(
'Set container to work with (temporary)',
('-C', '--container'))
suffix_replace=ValueArgument('', '--suffix-to-replace', default=''),
)
- def __init__(self, arguments={}):
+ def __init__(self, arguments={}, auth_base=None):
self.arguments.update(arguments)
- super(_source_destination_command, self).__init__(self.arguments)
+ super(_source_destination_command, self).__init__(
+ self.arguments, auth_base)
def _run(self, source_container___path, path_is_optional=False):
super(_source_destination_command, self)._run(
('-R', '--recursive'))
)
- def __init__(self, arguments={}):
- super(self.__class__, self).__init__(arguments)
+ def __init__(self, arguments={}, auth_base=None):
+ super(self.__class__, self).__init__(arguments, auth_base)
self['delimiter'] = DelimiterArgument(
self,
parsed_name='--delimiter',
class _astakos_init(_command_init):
- def __init__(self, arguments=dict()):
- super(_astakos_init, self).__init__(arguments)
+ def __init__(self, arguments=dict(), auth_base=None):
+ super(_astakos_init, self).__init__(arguments, auth_base)
self['token'] = ValueArgument('Custom token', '--token')
@errors.generic.all
or self.config.get('astakos', 'token')\
or self.config.get('user', 'token')\
or self.config.get('global', 'token')
- base_url = self.config.get('astakos', 'url')\
- or self.config.get('user', 'url')\
- or self.config.get('global', 'url')
+ astakos_endpoints = self.auth_base.get_service_endpoints(
+ self.config.get('astakos', 'type'),
+ self.config.get('astakos', 'version'))
+ base_url = astakos_endpoints['publicURL']
self.client = AstakosClient(base_url, logger=log)
self._set_log_params()
self._update_max_threads()
for option, val in options.items():
self.set(section, option, val)
+ def _get_dict(self, section, include_defaults=True):
+ try:
+ d = dict(DEFAULTS[section]) if include_defaults else {}
+ except KeyError:
+ d = {}
+ try:
+ d.update(RawConfigParser.items(self, section))
+ except NoSectionError:
+ pass
+ return d
+
def reload(self):
self = self.__init__(self.path)
- def apis(self):
- return [api for api in self.sections() if api != 'global']
-
def get(self, section, option):
value = self._overrides.get(section, {}).get(option)
if value is not None:
except NoSectionError:
pass
+ def keys(self, section, include_defaults=True):
+ d = self._get_dict(section, include_defaults)
+ return d.keys()
+
def items(self, section, include_defaults=True):
- try:
- d = dict(DEFAULTS[section]) if include_defaults else {}
- except KeyError:
- d = {}
- try:
- d.update(RawConfigParser.items(self, section))
- except NoSectionError:
- pass
+ d = self._get_dict(section, include_defaults)
return d.items()
def override(self, section, option, value):
return None
-def run(parser, _help):
+def run(auth_base, parser, _help):
group = get_command_group(list(parser.unparsed), parser.arguments)
if not group:
parser.parser.print_help()
global _best_match
_best_match = []
- spec_module = _load_spec_module(group, parser.arguments, '_commands')
+ group_spec = parser.arguments['config'].get('cli', group)
+ spec_module = _load_spec_module(group_spec, parser.arguments, '_commands')
if spec_module is None:
raise CLIUnknownCommand(
'Could not find specs for %s commands' % group,
exit(0)
cls = cmd.get_class()
- executable = cls(parser.arguments)
+ executable = cls(parser.arguments, auth_base)
parser.update_arguments(executable.arguments)
#parsed, unparsed = parse_known_args(parser, executable.arguments)
for term in _best_match:
from logging import getLogger
-
-
class AstakosClient(Client):
"""Synnefo Astakos API client"""
def term(self, key, token=None):
"""Get (cached) term, from user credentials"""
+ return self.user_term(key, token)
+
+ def user_term(self, key, token=None):
+ """Get (cached) term, from user credentials"""
return self.user_info(token).get(key, None)