Revision 844a6bdb

b/kamaki/cli/__init__.py
222 222

  
223 223

  
224 224
def _init_session(arguments, is_non_API=False):
225
    """
226
    :returns: (AuthCachedClient, str) authenticator and cloud remote name
227
    """
225 228
    global _help
226 229
    _help = arguments['help'].value
227 230
    global _debug
......
242 245
    _setup_logging(_silent, _debug, _verbose, _include)
243 246

  
244 247
    if _help or is_non_API:
245
        return None
248
        return None, None
246 249

  
247 250
    cloud = arguments['cloud'].value or 'default'
248 251
    if not cloud in _cnf.value.keys('remote'):
......
253 256
                'single authentication URL and token:',
254 257
                '  kamaki config set remote.%s.url <URL>' % cloud,
255 258
                '  kamaki config set remote.%s.token <t0k3n>' % cloud])
256
    url = _cnf.get_remote(cloud, 'url')
257
    if not url:
258
        kloger.warning(
259
            'WARNING: No remote.%s.url, use service urls instead' % cloud)
260
        return cloud
261
    token = _cnf.get_remote(cloud, 'token')
262
    if not token:
263
        raise CLIError(
264
            'No authentication token provided for %s cloud' % cloud,
265
            importance=3, details=[
266
                'Get and set a token for %s cloud:' % cloud,
267
                '  kamaki config set remote.%s.token <t0k3n>' % cloud])
259
    auth_args = dict()
260
    for term in ('url', 'token'):
261
        auth_args[term] = _cnf.get_remote(cloud, term)
262
        if not auth_args[term]:
263
            raise CLIError(
264
                'No authentication %s provided for %s cloud' % (term, cloud),
265
                importance=3, details=[
266
                    'Get and set a %s for %s cloud:' % (term, cloud),
267
                    '  kamaki config set remote.%s.%s <t0k3n>' % (term, cloud)
268
                ])
268 269

  
269 270
    from kamaki.clients.astakos import AstakosClient as AuthCachedClient
270 271
    try:
271
        return AuthCachedClient(url, token)
272
        return AuthCachedClient(auth_args['url'], auth_args['token']), cloud
272 273
    except AssertionError as ae:
273
        kloger.warning(
274
            'WARNING: Failed to load auth_url %s [ %s ]' % (url, ae))
275
        return None
274
        kloger.warning('WARNING: Failed to load authenticator [%s]' % ae)
275
        return None, cloud
276 276

  
277 277

  
278 278
def _load_spec_module(spec, arguments, module):
......
417 417

  
418 418
#  CLI Choice:
419 419

  
420
def run_one_cmd(exe_string, parser, auth_base):
420
def run_one_cmd(exe_string, parser, auth_base, cloud):
421 421
    global _history
422 422
    _history = History(
423 423
        parser.arguments['config'].get_global('history_file'))
424 424
    _history.add(' '.join([exe_string] + argv[1:]))
425 425
    from kamaki.cli import one_command
426
    one_command.run(auth_base, parser, _help)
426
    one_command.run(auth_base, cloud, parser, _help)
427 427

  
428 428

  
429
def run_shell(exe_string, parser, auth_base):
429
def run_shell(exe_string, parser, auth_base, cloud):
430 430
    from command_shell import _init_shell
431 431
    shell = _init_shell(exe_string, parser)
432 432
    _load_all_commands(shell.cmd_tree, parser.arguments)
433
    shell.run(auth_base, parser)
433
    shell.run(auth_base, cloud, parser)
434 434

  
435 435

  
436 436
def is_non_API(parser):
......
458 458
        filelog = logger.add_file_logger(__name__.split('.')[0])
459 459
        filelog.info('* Initial Call *\n%s\n- - -' % ' '.join(argv))
460 460

  
461
        remote_base = _init_session(parser.arguments, is_non_API(parser))
461
        auth_base, cloud = _init_session(parser.arguments, is_non_API(parser))
462 462

  
463 463
        from kamaki.cli.utils import suggest_missing
464 464
        suggest_missing()
465 465

  
466 466
        if parser.unparsed:
467
            run_one_cmd(exe, parser, remote_base)
467
            run_one_cmd(exe, parser, auth_base, cloud)
468 468
        elif _help:
469 469
            parser.parser.print_help()
470 470
            _groups_help(parser.arguments)
471 471
        else:
472
            run_shell(exe, parser, remote_base)
472
            run_shell(exe, parser, auth_base, cloud)
473 473
    except CLIError as err:
474 474
        print_error_message(err)
475 475
        if _debug:
b/kamaki/cli/command_shell.py
298 298
        hdr = tmp_partition[0].strip()
299 299
        return '%s commands:' % hdr
300 300

  
301
    def run(self, auth_base, parser, path=''):
301
    def run(self, auth_base, cloud, parser, path=''):
302 302
        self.auth_base = auth_base
303
        self.cloud = cloud
303 304
        self._parser = parser
304 305
        self._history = History(
305 306
            parser.arguments['config'].get_global('history_file'))
b/kamaki/cli/commands/__init__.py
34 34
from kamaki.cli.logger import get_logger
35 35
from kamaki.cli.utils import print_json, print_items
36 36
from kamaki.cli.argument import FlagArgument
37
from kamaki.cli.errors import CLIError
38
from kamaki.clients import Client
39 37

  
40 38
log = get_logger(__name__)
41 39

  
42 40

  
43 41
class _command_init(object):
44 42

  
45
    def __init__(self, arguments={}, auth_base_or_remote=None):
43
    def __init__(self, arguments={}, auth_base=None, cloud=None):
46 44
        if hasattr(self, 'arguments'):
47 45
            arguments.update(self.arguments)
48 46
        if isinstance(self, _optional_output_cmd):
......
54 52
            self.config = self['config']
55 53
        except KeyError:
56 54
            pass
57
        if isinstance(auth_base_or_remote, Client):
58
            self.auth_base = auth_base_or_remote
59
        elif not getattr(self, 'auth_base', None):
60
            self.remote = auth_base_or_remote
61
            if not self.remote:
62
                raise CLIError('CRITICAL: No cloud specified', 3)
55
        self.auth_base = auth_base or getattr(self, 'auth_base', None)
56
        self.cloud = cloud or getattr(self, 'cloud', None)
63 57

  
64 58
    def _set_log_params(self):
65 59
        try:
b/kamaki/cli/commands/config.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
from sys import stdout
35

  
34 36
from kamaki.cli import command
35 37
from kamaki.cli.argument import FlagArgument
36 38
from kamaki.cli.commands import _command_init, errors
37 39
from kamaki.cli.command_tree import CommandTree
40
from kamaki.cli.errors import CLIError, CLISyntaxError
38 41

  
39 42
config_cmds = CommandTree('config', 'Kamaki configurations')
40 43
_commands = [config_cmds]
......
64 67
        for section in sorted(self.config.sections()):
65 68
            items = self.config.items(section)
66 69
            for key, val in sorted(items):
67
                print('%s.%s = %s' % (section, key, val))
70
                if section in ('remote',):
71
                    prefix = '%s.%s' % (section, key)
72
                    for k, v in val.items():
73
                        print('%s..%s = %s' % (prefix, k, v))
74
                else:
75
                    print('%s.%s = %s' % (section, key, val))
68 76

  
69 77
    def main(self):
70 78
        self._run()
......
79 87
    @errors.generic.all
80 88
    def _run(self, option):
81 89
        section, sep, key = option.rpartition('.')
82
        section = section or 'global'
83
        value = self.config.get(section, key)
84
        if value:
90
        if not sep:
91
            match = False
92
            for k in self.config.keys(key):
93
                match = True
94
                if option != 'remote':
95
                    stdout.write('%s.%s =' % (option, k))
96
                self._run('%s.%s' % (option, k))
97
            if match:
98
                return
99
            section = 'global'
100
        prefix = 'remote.'
101
        get, section = (
102
            self.config.get_remote, section[len(prefix):]) if (
103
                section.startswith(prefix)) else (self.config.get, section)
104
        value = get(section, key)
105
        if isinstance(value, dict):
106
            for k, v in value.items():
107
                print('%s.%s.%s = %s' % (section, key, k, v))
108
        elif value:
85 109
            print(value)
86 110

  
87 111
    def main(self, option):
......
97 121
    @errors.generic.all
98 122
    def _run(self, option, value):
99 123
        section, sep, key = option.rpartition('.')
100
        section = section or 'global'
101
        self.config.set(section, key, value)
124
        prefix = 'remote.'
125
        if section.startswith(prefix):
126
            self.config.set_remote(section[len(prefix):], key, value)
127
        elif section in ('remote',):
128
            raise CLISyntaxError(
129
                'Invalid syntax for cloud definition', importance=2, details=[
130
                    'To define a cloud remote "%s"' % key,
131
                    'set the cloud\'s authentication url and token:',
132
                    '  /config set remote.%s.url <URL>' % key,
133
                    '  /config set remote.%s.token <t0k3n>' % key])
134
        else:
135
            section = section or 'global'
136
            self.config.set(section, key, value)
102 137
        self.config.write()
103 138
        self.config.reload()
104 139

  
......
123 158
    def _run(self, option):
124 159
        section, sep, key = option.rpartition('.')
125 160
        section = section or 'global'
126
        self.config.remove_option(section, key, self['default'])
161
        prefix = 'remote.'
162
        if section.startswith(prefix):
163
            remote = section[len(prefix):]
164
            try:
165
                self.config.remove_from_remote(remote, key)
166
            except KeyError:
167
                raise CLIError('Field %s does not exist' % option)
168
        else:
169
            self.config.remove_option(section, key, self['default'])
127 170
        self.config.write()
128 171
        self.config.reload()
129 172

  
b/kamaki/cli/commands/errors.py
50 50
                if _debug:
51 51
                    print_stack()
52 52
                    print_exc(e)
53
                raiseCLIError(e)
53
                if isinstance(e, CLIError):
54
                    raiseCLIError(e)
55
                raiseCLIError(e, details=['%s, -d for debug info' % type(e)])
54 56
        return _raise
55 57

  
56 58
    @classmethod
b/kamaki/cli/config.py
248 248

  
249 249
    def set_remote(self, remote, option, value):
250 250
        try:
251
            d = self.get('remote', remote)
251
            d = self.get('remote', remote) or dict()
252 252
        except KeyError:
253
            pass
253
            d = dict()
254 254
        d[option] = value
255 255
        self.set('remote', remote, d)
256 256

  
......
299 299
        except NoSectionError:
300 300
            pass
301 301

  
302
    def remove_from_remote(self, remote, option):
303
        d = self.get('remote', remote)
304
        if isinstance(d, dict):
305
            d.pop(option)
306

  
302 307
    def keys(self, section, include_defaults=True):
303 308
        d = self._get_dict(section, include_defaults)
304 309
        return d.keys()
b/kamaki/cli/one_command.py
55 55
    return None
56 56

  
57 57

  
58
def run(remote_base, parser, _help):
58
def run(remote_base, cloud, parser, _help):
59 59
    group = get_command_group(list(parser.unparsed), parser.arguments)
60 60
    if not group:
61 61
        parser.parser.print_help()

Also available in: Unified diff