Revision a7aacf12
b/kamaki/cli/__init__.py | ||
---|---|---|
340 | 340 |
global _debug |
341 | 341 |
global kloger |
342 | 342 |
descriptions = {} |
343 |
acceptable_groups = arguments['config'].get_groups()
|
|
344 |
for cmd_group, spec in arguments['config'].get_cli_specs():
|
|
343 |
acceptable_groups = arguments['config'].groups
|
|
344 |
for cmd_group, spec in arguments['config'].cli_specs:
|
|
345 | 345 |
pkg = _load_spec_module(spec, arguments, '_commands') |
346 | 346 |
if pkg: |
347 | 347 |
cmds = getattr(pkg, '_commands') |
... | ... | |
361 | 361 |
|
362 | 362 |
def _load_all_commands(cmd_tree, arguments): |
363 | 363 |
_cnf = arguments['config'] |
364 |
for cmd_group, spec in _cnf.get_cli_specs():
|
|
364 |
for cmd_group, spec in _cnf.cli_specs:
|
|
365 | 365 |
try: |
366 | 366 |
spec_module = _load_spec_module(spec, arguments, '_commands') |
367 | 367 |
spec_commands = getattr(spec_module, '_commands') |
... | ... | |
436 | 436 |
|
437 | 437 |
|
438 | 438 |
def get_command_group(unparsed, arguments): |
439 |
groups = arguments['config'].get_groups()
|
|
439 |
groups = arguments['config'].groups
|
|
440 | 440 |
for term in unparsed: |
441 | 441 |
if term.startswith('-'): |
442 | 442 |
continue |
b/kamaki/cli/argument/__init__.py | ||
---|---|---|
98 | 98 |
class ConfigArgument(Argument): |
99 | 99 |
"""Manage a kamaki configuration (file)""" |
100 | 100 |
|
101 |
_config_file = None |
|
101 |
def __init__(self, help, parsed_name=('-c', '--config')): |
|
102 |
super(ConfigArgument, self).__init__(1, help, parsed_name, None) |
|
103 |
self.file_path = None |
|
102 | 104 |
|
103 | 105 |
@property |
104 | 106 |
def value(self): |
105 |
"""A Config object""" |
|
106 |
super(self.__class__, self).value |
|
107 |
return super(self.__class__, self).value |
|
107 |
return super(ConfigArgument, self).value |
|
108 | 108 |
|
109 | 109 |
@value.setter |
110 | 110 |
def value(self, config_file): |
111 | 111 |
if config_file: |
112 | 112 |
self._value = Config(config_file) |
113 |
self._config_file = config_file
|
|
114 |
elif self._config_file:
|
|
115 |
self._value = Config(self._config_file)
|
|
113 |
self.file_path = config_file
|
|
114 |
elif self.file_path:
|
|
115 |
self._value = Config(self.file_path)
|
|
116 | 116 |
else: |
117 | 117 |
self._value = Config() |
118 | 118 |
|
... | ... | |
120 | 120 |
"""Get a configuration setting from the Config object""" |
121 | 121 |
return self.value.get(group, term) |
122 | 122 |
|
123 |
def get_groups(self): |
|
123 |
@property |
|
124 |
def groups(self): |
|
124 | 125 |
suffix = '_cli' |
125 | 126 |
slen = len(suffix) |
126 | 127 |
return [term[:-slen] for term in self.value.keys('global') if ( |
127 | 128 |
term.endswith(suffix))] |
128 | 129 |
|
129 |
def get_cli_specs(self): |
|
130 |
@property |
|
131 |
def cli_specs(self): |
|
130 | 132 |
suffix = '_cli' |
131 | 133 |
slen = len(suffix) |
132 | 134 |
return [(k[:-slen], v) for k, v in self.value.items('global') if ( |
... | ... | |
139 | 141 |
return self.value.get_cloud(cloud, option) |
140 | 142 |
|
141 | 143 |
|
142 |
_config_arg = ConfigArgument( |
|
143 |
1, 'Path to configuration file', ('-c', '--config')) |
|
144 |
_config_arg = ConfigArgument('Path to config file') |
|
144 | 145 |
|
145 | 146 |
|
146 | 147 |
class CmdLineConfigArgument(Argument): |
b/kamaki/cli/argument/test.py | ||
---|---|---|
34 | 34 |
#from mock import patch, call |
35 | 35 |
from unittest import TestCase |
36 | 36 |
from StringIO import StringIO |
37 |
from sys import stdin, stdout |
|
37 | 38 |
#from itertools import product |
38 | 39 |
|
39 | 40 |
from kamaki.cli import argument |
41 |
from kamaki.cli.config import Config |
|
40 | 42 |
|
41 | 43 |
|
42 | 44 |
class Argument(TestCase): |
... | ... | |
85 | 87 |
del arp |
86 | 88 |
|
87 | 89 |
|
90 |
class ConfigArgument(TestCase): |
|
91 |
|
|
92 |
# A cloud name in config with a URL but no TOKEN |
|
93 |
SEMI_CLOUD = 'production' |
|
94 |
|
|
95 |
# A cloud name that is not configured in config |
|
96 |
INVALID_CLOUD = 'QWERTY_123456' |
|
97 |
|
|
98 |
def setUp(self): |
|
99 |
argument._config_arg = argument.ConfigArgument('Recovered Path') |
|
100 |
|
|
101 |
def test_value(self): |
|
102 |
c = argument._config_arg |
|
103 |
self.assertEqual(c.value, None) |
|
104 |
exp = '/some/random/path' |
|
105 |
c.value = exp |
|
106 |
self.assertTrue(isinstance(c.value, Config)) |
|
107 |
self.assertEqual(c.file_path, exp) |
|
108 |
self.assertEqual(c.value.path, exp) |
|
109 |
|
|
110 |
def test_get(self): |
|
111 |
c = argument._config_arg |
|
112 |
c.value = None |
|
113 |
self.assertEqual(c.value.get('global', 'config_cli'), 'config') |
|
114 |
|
|
115 |
def test_groups(self): |
|
116 |
c = argument._config_arg |
|
117 |
c.value = None |
|
118 |
self.assertTrue(set(c.groups).issuperset([ |
|
119 |
'image', 'config', 'history'])) |
|
120 |
|
|
121 |
def test_cli_specs(self): |
|
122 |
c = argument._config_arg |
|
123 |
c.value = None |
|
124 |
self.assertTrue(set(c.cli_specs).issuperset([ |
|
125 |
('image', 'image'), ('config', 'config'), ('history', 'history')])) |
|
126 |
|
|
127 |
def test_get_global(self): |
|
128 |
c = argument._config_arg |
|
129 |
c.value = None |
|
130 |
for k, v in ( |
|
131 |
('config_cli', 'config'), |
|
132 |
('image_cli', 'image'), |
|
133 |
('history_cli', 'history')): |
|
134 |
self.assertEqual(c.get_global(k), v) |
|
135 |
|
|
136 |
def test_get_cloud(self): |
|
137 |
"""test_get_cloud (!! hard-set SEMI/INVALID_CLOUD to run this !!)""" |
|
138 |
c = argument._config_arg |
|
139 |
c.value = None |
|
140 |
if not self.SEMI_CLOUD: |
|
141 |
stdout.write( |
|
142 |
'\n\tA cloud name set in config file with URL but no TOKEN: ') |
|
143 |
self.SEMI_CLOUD = stdin.readline()[:-1] |
|
144 |
self.assertTrue(len(c.get_cloud(self.SEMI_CLOUD, 'url')) > 0) |
|
145 |
self.assertRaises(KeyError, c.get_cloud, self.SEMI_CLOUD, 'token') |
|
146 |
|
|
147 |
if not self.INVALID_CLOUD: |
|
148 |
stdout.write('\tok\n\tA cloud name NOT in your config file: ') |
|
149 |
self.INVALID_CLOUD = stdin.readline()[:-1] |
|
150 |
self.assertRaises(KeyError, c.get_cloud, self.INVALID_CLOUD, 'url') |
|
151 |
|
|
152 |
|
|
88 | 153 |
if __name__ == '__main__': |
89 | 154 |
from sys import argv |
90 | 155 |
from kamaki.cli.test import runTestCase |
91 | 156 |
runTestCase(Argument, 'Argument', argv[1:]) |
157 |
runTestCase(ConfigArgument, 'ConfigArgument', argv[1:]) |
b/kamaki/cli/command_shell.py | ||
---|---|---|
310 | 310 |
else: |
311 | 311 |
intro = self.cmd_tree.name |
312 | 312 |
|
313 |
acceptable = parser.arguments['config'].get_groups()
|
|
313 |
acceptable = parser.arguments['config'].groups
|
|
314 | 314 |
total = self.cmd_tree.groups.keys() |
315 | 315 |
self.cmd_tree.exclude(set(total).difference(acceptable)) |
316 | 316 |
|
b/kamaki/cli/config.py | ||
---|---|---|
352 | 352 |
except NoSectionError: |
353 | 353 |
pass |
354 | 354 |
|
355 |
def remote_from_cloud(self, cloud, option):
|
|
355 |
def remove_from_cloud(self, cloud, option):
|
|
356 | 356 |
d = self.get(CLOUD_PREFIX, cloud) |
357 | 357 |
if isinstance(d, dict): |
358 | 358 |
d.pop(option) |
b/kamaki/cli/test.py | ||
---|---|---|
35 | 35 |
from inspect import getmembers, isclass |
36 | 36 |
|
37 | 37 |
from kamaki.cli.command_tree.test import Command, CommandTree |
38 |
from kamaki.cli.argument.test import Argument |
|
38 |
from kamaki.cli.argument.test import Argument, ConfigArgument
|
|
39 | 39 |
|
40 | 40 |
|
41 | 41 |
# TestCase auxiliary methods |
Also available in: Unified diff