Revision d252a7a8
b/kamaki/cli/__init__.py | ||
---|---|---|
346 | 346 |
if pkg: |
347 | 347 |
cmds = getattr(pkg, '_commands') |
348 | 348 |
try: |
349 |
for cmd in cmds: |
|
350 |
if cmd.name in acceptable_groups: |
|
351 |
descriptions[cmd.name] = cmd.help
|
|
349 |
for cmd_tree in cmds:
|
|
350 |
if cmd_tree.name in acceptable_groups:
|
|
351 |
descriptions[cmd_tree.name] = cmd_tree.description
|
|
352 | 352 |
except TypeError: |
353 | 353 |
if _debug: |
354 | 354 |
kloger.warning( |
b/kamaki/cli/command_shell.py | ||
---|---|---|
150 | 150 |
pass |
151 | 151 |
|
152 | 152 |
def _roll_command(self, cmd_path=None): |
153 |
for subname in self.cmd_tree.get_subnames(cmd_path):
|
|
153 |
for subname in self.cmd_tree.subnames(cmd_path): |
|
154 | 154 |
self._unregister_method('do_%s' % subname) |
155 | 155 |
self._unregister_method('complete_%s' % subname) |
156 | 156 |
self._unregister_method('help_%s' % subname) |
... | ... | |
288 | 288 |
cmd_args[','.join(arg.parsed_name)] = arg.help |
289 | 289 |
print_dict(cmd_args, indent=2) |
290 | 290 |
stdout.write('%s %s' % (self.prompt, line)) |
291 |
return subcmd.get_subnames()
|
|
291 |
return subcmd.subnames() |
|
292 | 292 |
self._register_method(complete_method, 'complete_%s' % cmd.name) |
293 | 293 |
|
294 | 294 |
@property |
... | ... | |
311 | 311 |
intro = self.cmd_tree.name |
312 | 312 |
|
313 | 313 |
acceptable = parser.arguments['config'].get_groups() |
314 |
total = self.cmd_tree.get_group_names()
|
|
314 |
total = self.cmd_tree.groups.keys()
|
|
315 | 315 |
self.cmd_tree.exclude(set(total).difference(acceptable)) |
316 | 316 |
|
317 | 317 |
for subcmd in self.cmd_tree.get_subcommands(path): |
b/kamaki/cli/command_tree/__init__.py | ||
---|---|---|
101 | 101 |
return cmd, args[index:] |
102 | 102 |
|
103 | 103 |
def pretty_print(self, recursive=False): |
104 |
print('Path: %s (Name: %s) is_cmd: %s\n\thelp: %s' % ( |
|
105 |
self.path, |
|
106 |
self.name, |
|
107 |
self.is_command, |
|
108 |
self.help)) |
|
104 |
print('%s\t\t(Name: %s is_cmd: %s help: %s)' % ( |
|
105 |
self.path, self.name, self.is_command, self.help)) |
|
109 | 106 |
for cmd in self.subcommands.values(): |
110 | 107 |
cmd.pretty_print(recursive) |
111 | 108 |
|
112 | 109 |
|
113 | 110 |
class CommandTree(object): |
114 | 111 |
|
115 |
groups = {} |
|
116 |
_all_commands = {} |
|
117 |
name = None |
|
118 |
description = None |
|
119 |
|
|
120 | 112 |
def __init__(self, name, description=''): |
121 | 113 |
self.name = name |
122 | 114 |
self.description = description |
115 |
self.groups = dict() |
|
116 |
self._all_commands = dict() |
|
123 | 117 |
|
124 | 118 |
def exclude(self, groups_to_exclude=[]): |
125 | 119 |
for group in groups_to_exclude: |
... | ... | |
143 | 137 |
self._all_commands[path] = new_cmd |
144 | 138 |
cmd.add_subcmd(new_cmd) |
145 | 139 |
cmd = new_cmd |
146 |
if cmd_class: |
|
147 |
cmd.cmd_class = cmd_class |
|
148 |
if description is not None: |
|
149 |
cmd.help = description |
|
140 |
cmd.cmd_class = cmd_class or None |
|
141 |
cmd.help = description or None |
|
150 | 142 |
|
151 | 143 |
def find_best_match(self, terms): |
152 | 144 |
"""Find a command that best matches a given list of terms |
153 | 145 |
|
154 |
:param terms: (list of str) match them against paths in cmd_tree |
|
146 |
:param terms: (list of str) match against paths in cmd_tree, e.g. |
|
147 |
['aa', 'bb', 'cc'] matches aa_bb_cc |
|
155 | 148 |
|
156 |
:returns: (Command, list) the matching command, the remaining terms |
|
149 |
:returns: (Command, list) the matching command, the remaining terms or |
|
150 |
None |
|
157 | 151 |
""" |
158 | 152 |
path = [] |
159 | 153 |
for term in terms: |
... | ... | |
170 | 164 |
tdesc = new_tree.description |
171 | 165 |
self.groups.update(new_tree.groups) |
172 | 166 |
self._all_commands.update(new_tree._all_commands) |
173 |
self.set_description(tname, tdesc) |
|
167 |
try: |
|
168 |
self._all_commands[tname].help = tdesc |
|
169 |
except KeyError: |
|
170 |
self.add_command(tname, tdesc) |
|
174 | 171 |
|
175 | 172 |
def has_command(self, path): |
176 | 173 |
return path in self._all_commands |
... | ... | |
178 | 175 |
def get_command(self, path): |
179 | 176 |
return self._all_commands[path] |
180 | 177 |
|
181 |
def get_groups(self): |
|
182 |
return self.groups.values() |
|
183 |
|
|
184 |
def get_group_names(self): |
|
185 |
return self.groups.keys() |
|
186 |
|
|
187 |
def set_description(self, path, description): |
|
188 |
self._all_commands[path].help = description |
|
189 |
|
|
190 |
def get_description(self, path): |
|
191 |
return self._all_commands[path].help |
|
192 |
|
|
193 |
def get_subnames(self, path=None): |
|
178 |
def subnames(self, path=None): |
|
194 | 179 |
if path in (None, ''): |
195 |
return self.get_group_names()
|
|
180 |
return self.groups.keys()
|
|
196 | 181 |
return self._all_commands[path].subcommands.keys() |
197 | 182 |
|
198 | 183 |
def get_subcommands(self, path=None): |
199 | 184 |
return self._all_commands[path].subcommands.values() if ( |
200 |
path) else self.get_groups() |
|
201 |
|
|
202 |
def get_parent(self, path): |
|
203 |
if '_' not in path: |
|
204 |
return None |
|
205 |
terms = path.split('_') |
|
206 |
parent_path = '_'.join(terms[:-1]) |
|
207 |
return self._all_commands[parent_path] |
|
208 |
|
|
209 |
def get_closest_ancestor_command(self, path): |
|
210 |
path, sep, name = path.rpartition('_') |
|
211 |
while len(path) > 0: |
|
212 |
cmd = self._all_commands[path] |
|
213 |
if cmd.is_command: |
|
214 |
return cmd |
|
215 |
path, sep, name = path.rpartition('_') |
|
216 |
return None |
|
217 |
|
|
218 |
if '_' not in path: |
|
219 |
return None |
|
220 |
terms = path.split()[:-1] |
|
221 |
while len(terms) > 0: |
|
222 |
tmp_path = '_'.join(terms) |
|
223 |
cmd = self._all_commands[tmp_path] |
|
224 |
if cmd.is_command: |
|
225 |
return cmd |
|
226 |
terms = terms[:-1] |
|
227 |
raise KeyError('No ancestor commands') |
|
185 |
path) else self.groups.values() |
|
228 | 186 |
|
229 | 187 |
def pretty_print(self, group=None): |
230 | 188 |
if group is None: |
b/kamaki/cli/command_tree/test.py | ||
---|---|---|
165 | 165 |
|
166 | 166 |
class CommandTree(TestCase): |
167 | 167 |
|
168 |
def _add_commands(self, ctree): |
|
169 |
for cmd in self.commands: |
|
170 |
ctree.add_command(cmd.path, cmd.help, cmd.cmd_class) |
|
171 |
|
|
172 |
def _commands_are_equal(self, c1, c2): |
|
173 |
self.assertEqual(c1.path, c2.path) |
|
174 |
self.assertEqual(c1.name, c2.name) |
|
175 |
self.assertEqual(c1.cmd_class, c2.cmd_class) |
|
176 |
self.assertEqual(c1.help, c2.help) |
|
177 |
|
|
168 | 178 |
def setUp(self): |
169 | 179 |
cmd = command_tree.Command('cmd', subcommands=dict( |
170 | 180 |
cmd0a=command_tree.Command('cmd_cmd0a', subcommands=dict( |
171 | 181 |
cmd1a=command_tree.Command( |
172 | 182 |
'cmd_cmd0a_cmd1a', subcommands=dict( |
173 |
cmd2=command_tree.Command('cmd_cmd0a_cmd1a_cmd2'), |
|
174 |
) |
|
183 |
cmd2=command_tree.Command( |
|
184 |
'cmd_cmd0a_cmd1a_cmd2', cmd_class=Command) |
|
185 |
), |
|
175 | 186 |
), |
176 | 187 |
cmd1b=command_tree.Command( |
177 | 188 |
'cmd_cmd0a_cmd1b', subcommands=dict( |
178 |
cmd2=command_tree.Command('cmd_cmd0a_cmd1b_cmd2'), |
|
179 |
) |
|
189 |
cmd2=command_tree.Command( |
|
190 |
'cmd_cmd0a_cmd1b_cmd2', cmd_class=Command) |
|
191 |
), |
|
180 | 192 |
) |
181 | 193 |
)), |
182 | 194 |
cmd0b=command_tree.Command('cmd_cmd0b'), |
... | ... | |
184 | 196 |
cmd1a=command_tree.Command('cmd_cmd0c_cmd1a'), |
185 | 197 |
cmd1b=command_tree.Command( |
186 | 198 |
'cmd_cmd0c_cmd1b', subcommands=dict( |
187 |
cmd2=command_tree.Command('cmd_cmd0c_cmd1b_cmd2'), |
|
188 |
) |
|
199 |
cmd2=command_tree.Command( |
|
200 |
'cmd_cmd0c_cmd1b_cmd2', cmd_class=Command) |
|
201 |
), |
|
189 | 202 |
) |
190 | 203 |
)) |
191 | 204 |
)) |
... | ... | |
201 | 214 |
cmd.subcommands['cmd0c'].subcommands['cmd1a'], |
202 | 215 |
cmd.subcommands['cmd0c'].subcommands['cmd1b'], |
203 | 216 |
cmd.subcommands['cmd0c'].subcommands['cmd1b'].subcommands['cmd2'], |
217 |
command_tree.Command('othercmd') |
|
204 | 218 |
] |
205 | 219 |
|
206 | 220 |
def tearDown(self): |
... | ... | |
209 | 223 |
del self.commands |
210 | 224 |
|
211 | 225 |
def test___init__(self): |
212 |
ctree = command_tree.CommandTree('sampleTree', 'a sample Tree') |
|
213 |
ctree.pretty_print() |
|
226 |
name, description = 'sampleTree', 'a sample Tree' |
|
227 |
ctree = command_tree.CommandTree(name) |
|
228 |
for attr, exp in ( |
|
229 |
('groups', {}), ('_all_commands', {}), |
|
230 |
('name', name), ('description', '')): |
|
231 |
self.assertEqual(getattr(ctree, attr), exp) |
|
232 |
ctree = command_tree.CommandTree(name, description) |
|
233 |
for attr, exp in ( |
|
234 |
('groups', {}), ('_all_commands', {}), |
|
235 |
('name', name), ('description', description)): |
|
236 |
self.assertEqual(getattr(ctree, attr), exp) |
|
237 |
|
|
238 |
def test_exclude(self): |
|
239 |
ctree = command_tree.CommandTree('excludeTree', 'test exclude group') |
|
240 |
exp = dict() |
|
241 |
for cmd in self.commands[0:6]: |
|
242 |
ctree.groups[cmd.name] = cmd |
|
243 |
exp[cmd.name] = cmd |
|
244 |
self.assertEqual(exp, ctree.groups) |
|
245 |
ctree.exclude(exp.keys()[1::2]) |
|
246 |
for key in exp.keys()[1::2]: |
|
247 |
exp.pop(key) |
|
248 |
self.assertEqual(exp, ctree.groups) |
|
249 |
|
|
250 |
def test_add_command(self): |
|
251 |
ctree = command_tree.CommandTree('addCommand', 'test add_command') |
|
252 |
self._add_commands(ctree) |
|
253 |
for cmd in self.commands: |
|
254 |
self.assertTrue(cmd, ctree._all_commands) |
|
255 |
if cmd.path.count('_'): |
|
256 |
self.assertFalse(cmd.name in ctree.groups) |
|
257 |
else: |
|
258 |
self.assertTrue(cmd.name in ctree.groups) |
|
259 |
self._commands_are_equal(cmd, ctree.groups[cmd.name]) |
|
260 |
|
|
261 |
def test_find_best_match(self): |
|
262 |
ctree = command_tree.CommandTree('bestMatch', 'test find_best_match') |
|
263 |
for cmd in self.commands: |
|
264 |
terms = cmd.path.split('_') |
|
265 |
best_match, rest = ctree.find_best_match(terms) |
|
266 |
if len(terms) > 1: |
|
267 |
self.assertEqual(best_match.path, '_'.join(terms[:-1])) |
|
268 |
else: |
|
269 |
self.assertEqual(best_match, None) |
|
270 |
self.assertEqual(rest, terms[-1:]) |
|
271 |
ctree.add_command(cmd.path, cmd.help, cmd.cmd_class) |
|
272 |
best_match, rest = ctree.find_best_match(terms) |
|
273 |
self._commands_are_equal(best_match, cmd) |
|
274 |
self.assertEqual(rest, []) |
|
275 |
|
|
276 |
def test_add_tree(self): |
|
277 |
ctree = command_tree.CommandTree('tree', 'the main tree') |
|
278 |
ctree1 = command_tree.CommandTree('tree1', 'the first tree') |
|
279 |
ctree2 = command_tree.CommandTree('tree2', 'the second tree') |
|
280 |
|
|
281 |
cmds = list(self.commands) |
|
282 |
del self.commands |
|
283 |
cmds1, cmds2 = cmds[:6], cmds[6:] |
|
284 |
self.commands = cmds1 |
|
285 |
self._add_commands(ctree1) |
|
286 |
self.commands = cmds2 |
|
287 |
self._add_commands(ctree2) |
|
288 |
self.commands = cmds |
|
289 |
|
|
290 |
def check_all( |
|
291 |
p1=False, p2=False, p3=False, p4=False, p5=False, p6=False): |
|
292 |
for cmd in cmds[:6]: |
|
293 |
self.assertEquals(cmd.path in ctree._all_commands, p1) |
|
294 |
self.assertEquals(cmd.path in ctree1._all_commands, p2) |
|
295 |
if cmd.path != 'cmd': |
|
296 |
self.assertEquals(cmd.path in ctree2._all_commands, p3) |
|
297 |
for cmd in cmds[6:]: |
|
298 |
self.assertEquals(cmd.path in ctree._all_commands, p4) |
|
299 |
if cmd.path != 'cmd': |
|
300 |
self.assertEquals(cmd.path in ctree1._all_commands, p5) |
|
301 |
self.assertEquals(cmd.path in ctree2._all_commands, p6) |
|
302 |
|
|
303 |
check_all(False, True, False, False, False, True) |
|
304 |
ctree.add_tree(ctree1) |
|
305 |
check_all(True, True, False, False, False, True) |
|
306 |
ctree.add_tree(ctree2) |
|
307 |
check_all(True, True, False, True, False, True) |
|
308 |
ctree2.add_tree(ctree1) |
|
309 |
check_all(True, True, True, True, False, True) |
|
310 |
|
|
311 |
def test_has_command(self): |
|
312 |
ctree = command_tree.CommandTree('treeHasCommand', 'test has_command') |
|
313 |
for cmd in self.commands: |
|
314 |
self.assertFalse(ctree.has_command(cmd.path)) |
|
315 |
self._add_commands(ctree) |
|
316 |
for cmd in self.commands: |
|
317 |
self.assertTrue(ctree.has_command(cmd.path)) |
|
318 |
self.assertFalse(ctree.has_command('NON_EXISTING_COMMAND')) |
|
319 |
|
|
320 |
def test_get_command(self): |
|
321 |
ctree = command_tree.CommandTree('treeGetCommand', 'test get_command') |
|
322 |
for cmd in self.commands: |
|
323 |
self.assertRaises(KeyError, ctree.get_command, cmd.path) |
|
324 |
self._add_commands(ctree) |
|
325 |
for cmd in self.commands: |
|
326 |
self._commands_are_equal(ctree.get_command(cmd.path), cmd) |
|
327 |
self.assertRaises(KeyError, ctree.get_command, 'NON_EXISTNG_COMMAND') |
|
328 |
|
|
329 |
def test_subnames(self): |
|
330 |
ctree = command_tree.CommandTree('treeSubnames', 'test subnames') |
|
331 |
self.assertEqual(ctree.subnames(), []) |
|
332 |
self.assertRaises(KeyError, ctree.subnames, 'cmd') |
|
333 |
self._add_commands(ctree) |
|
334 |
for l1, l2 in ( |
|
335 |
(ctree.subnames(), ['cmd', 'othercmd']), |
|
336 |
(ctree.subnames('cmd'), ['cmd0a', 'cmd0b', 'cmd0c']), |
|
337 |
(ctree.subnames('cmd_cmd0a'), ['cmd1a', 'cmd1b']), |
|
338 |
(ctree.subnames('cmd_cmd0a_cmd1a'), ['cmd2', ]), |
|
339 |
(ctree.subnames('cmd_cmd0a_cmd1b'), ['cmd2', ]), |
|
340 |
(ctree.subnames('cmd_cmd0a_cmd1a_cmd2'), []), |
|
341 |
(ctree.subnames('cmd_cmd0a_cmd1b_cmd2'), []), |
|
342 |
(ctree.subnames('cmd_cmd0b'), []), |
|
343 |
(ctree.subnames('cmd_cmd0c'), ['cmd1a', 'cmd1b']), |
|
344 |
(ctree.subnames('cmd_cmd0c_cmd1a'), []), |
|
345 |
(ctree.subnames('cmd_cmd0c_cmd1b'), ['cmd2', ]), |
|
346 |
(ctree.subnames('cmd_cmd0c_cmd1b_cmd2'), []), |
|
347 |
(ctree.subnames('othercmd'), [])): |
|
348 |
l1.sort(), l2.sort(), self.assertEqual(l1, l2) |
|
349 |
self.assertRaises(KeyError, ctree.subnames, 'NON_EXISTNG_CMD') |
|
350 |
|
|
351 |
def test_get_subcommands(self): |
|
352 |
ctree = command_tree.CommandTree('treeSub', 'test get_subcommands') |
|
353 |
self.assertEqual(ctree.get_subcommands(), []) |
|
354 |
self.assertRaises(KeyError, ctree.get_subcommands, 'cmd') |
|
355 |
self._add_commands(ctree) |
|
356 |
for s1, l2 in ( |
|
357 |
('', ['cmd', 'othercmd']), |
|
358 |
('cmd', ['cmd0a', 'cmd0b', 'cmd0c']), |
|
359 |
('cmd_cmd0a', ['cmd1a', 'cmd1b']), |
|
360 |
('cmd_cmd0a_cmd1a', ['cmd2', ]), |
|
361 |
('cmd_cmd0a_cmd1b', ['cmd2', ]), |
|
362 |
('cmd_cmd0a_cmd1a_cmd2', []), |
|
363 |
('cmd_cmd0a_cmd1b_cmd2', []), |
|
364 |
('cmd_cmd0b', []), |
|
365 |
('cmd_cmd0c', ['cmd1a', 'cmd1b']), |
|
366 |
('cmd_cmd0c_cmd1a', []), |
|
367 |
('cmd_cmd0c_cmd1b', ['cmd2', ]), |
|
368 |
('cmd_cmd0c_cmd1b_cmd2', []), |
|
369 |
('othercmd', []) |
|
370 |
): |
|
371 |
l1 = [cmd.path for cmd in ctree.get_subcommands(s1)] |
|
372 |
l2 = ['_'.join([s1, i]) for i in l2] if s1 else l2 |
|
373 |
l1.sort(), l2.sort(), self.assertEqual(l1, l2) |
|
374 |
self.assertRaises(KeyError, ctree.get_subcommands, 'NON_EXISTNG_CMD') |
|
214 | 375 |
|
215 | 376 |
|
216 | 377 |
if __name__ == '__main__': |
b/kamaki/clients/compute/__init__.py | ||
---|---|---|
320 | 320 |
|
321 | 321 |
:param pool: (str) pool of ips to allocate from |
322 | 322 |
|
323 |
:returns: (dict) { |
|
324 |
fixed_ip: ..., id: ..., instance_id: ..., ip: ..., pool: ... |
|
325 |
} |
|
323 |
:returns: (dict) {fixed_ip: . id: . instance_id: . ip: . pool: .} |
|
326 | 324 |
""" |
327 | 325 |
json_data = dict(pool=pool) if pool else dict() |
328 | 326 |
r = self.floating_ips_post(tenant_id, json_data) |
Also available in: Unified diff