Revision cd295a1d kamaki/cli/commands/cyclades.py

b/kamaki/cli/commands/cyclades.py
33 33

  
34 34
from kamaki.cli import command
35 35
from kamaki.cli.command_tree import CommandTree
36
from kamaki.cli.utils import print_dict, print_list, print_items
36
from kamaki.cli.utils import print_dict, print_items, print_json
37 37
from kamaki.cli.errors import raiseCLIError, CLISyntaxError
38 38
from kamaki.clients.cyclades import CycladesClient, ClientError
39 39
from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument
40 40
from kamaki.cli.argument import ProgressBarArgument, DateArgument, IntArgument
41
from kamaki.cli.commands import _command_init, errors
41
from kamaki.cli.commands import _command_init, errors, _optional_output_cmd
42 42

  
43 43
from base64 import b64encode
44 44
from os.path import exists
......
94 94
        more=FlagArgument(
95 95
            'output results in pages (-n to set items per page, default 10)',
96 96
            '--more'),
97
        enum=FlagArgument('Enumerate results', '--enumerate')
97
        enum=FlagArgument('Enumerate results', '--enumerate'),
98
        json_output=FlagArgument('show output in json', ('-j', '--json'))
98 99
    )
99 100

  
100 101
    def _make_results_pretty(self, servers):
......
117 118
    @errors.cyclades.date
118 119
    def _run(self):
119 120
        servers = self.client.list_servers(self['detail'], self['since'])
121
        if self['json_output']:
122
            print_json(servers)
123
            return
120 124
        if self['detail']:
121 125
            self._make_results_pretty(servers)
122 126

  
......
145 149
    - hardware flavor and os image ids
146 150
    """
147 151

  
152
    arguments = dict(
153
        json_output=FlagArgument('show output in json', ('-j', '--json'))
154
    )
155

  
148 156
    def _print(self, server):
149 157
        addr_dict = {}
150 158
        if 'attachments' in server:
......
165 173
    @errors.cyclades.connection
166 174
    @errors.cyclades.server_id
167 175
    def _run(self, server_id):
168
        server = self.client.get_server_details(server_id)
169
        self._print(server)
176
        printer = print_json if self['json_output'] else self._print
177
        printer(self.client.get_server_details(server_id))
170 178

  
171 179
    def main(self, server_id):
172 180
        super(self.__class__, self)._run()
......
218 226

  
219 227
    arguments = dict(
220 228
        personality=PersonalityArgument(
221
            ' /// '.join(howto_personality),
222
            ('-p', '--personality'))
229
            (80 * ' ').join(howto_personality),
230
            ('-p', '--personality')),
231
        json_output=FlagArgument('show output in json', ('-j', '--json'))
223 232
    )
224 233

  
225 234
    @errors.generic.all
......
227 236
    @errors.plankton.id
228 237
    @errors.cyclades.flavor_id
229 238
    def _run(self, name, flavor_id, image_id):
230
        r = self.client.create_server(
239
        printer = print_json if self['json_output'] else print_dict
240
        printer(self.client.create_server(
231 241
            name,
232 242
            int(flavor_id),
233 243
            image_id,
234
            self['personality'])
235
        print_dict(r)
244
            self['personality']))
236 245

  
237 246
    def main(self, name, flavor_id, image_id):
238 247
        super(self.__class__, self)._run()
......
240 249

  
241 250

  
242 251
@command(server_cmds)
243
class server_rename(_init_cyclades):
252
class server_rename(_init_cyclades, _optional_output_cmd):
244 253
    """Set/update a server (VM) name
245 254
    VM names are not unique, therefore multiple servers may share the same name
246 255
    """
......
249 258
    @errors.cyclades.connection
250 259
    @errors.cyclades.server_id
251 260
    def _run(self, server_id, new_name):
252
        self.client.update_server_name(int(server_id), new_name)
261
        self._optional_output(
262
            self.client.update_server_name(int(server_id), new_name))
253 263

  
254 264
    def main(self, server_id, new_name):
255 265
        super(self.__class__, self)._run()
......
257 267

  
258 268

  
259 269
@command(server_cmds)
260
class server_delete(_init_cyclades):
270
class server_delete(_init_cyclades, _optional_output_cmd):
261 271
    """Delete a server (VM)"""
262 272

  
263 273
    @errors.generic.all
264 274
    @errors.cyclades.connection
265 275
    @errors.cyclades.server_id
266 276
    def _run(self, server_id):
267
            self.client.delete_server(int(server_id))
277
            self._optional_output(self.client.delete_server(int(server_id)))
268 278

  
269 279
    def main(self, server_id):
270 280
        super(self.__class__, self)._run()
......
272 282

  
273 283

  
274 284
@command(server_cmds)
275
class server_reboot(_init_cyclades):
285
class server_reboot(_init_cyclades, _optional_output_cmd):
276 286
    """Reboot a server (VM)"""
277 287

  
278 288
    arguments = dict(
......
283 293
    @errors.cyclades.connection
284 294
    @errors.cyclades.server_id
285 295
    def _run(self, server_id):
286
        self.client.reboot_server(int(server_id), self['hard'])
296
        self._optional_output(
297
            self.client.reboot_server(int(server_id), self['hard']))
287 298

  
288 299
    def main(self, server_id):
289 300
        super(self.__class__, self)._run()
......
291 302

  
292 303

  
293 304
@command(server_cmds)
294
class server_start(_init_cyclades):
305
class server_start(_init_cyclades, _optional_output_cmd):
295 306
    """Start an existing server (VM)"""
296 307

  
297 308
    @errors.generic.all
298 309
    @errors.cyclades.connection
299 310
    @errors.cyclades.server_id
300 311
    def _run(self, server_id):
301
        self.client.start_server(int(server_id))
312
        self._optional_output(self.client.start_server(int(server_id)))
302 313

  
303 314
    def main(self, server_id):
304 315
        super(self.__class__, self)._run()
......
306 317

  
307 318

  
308 319
@command(server_cmds)
309
class server_shutdown(_init_cyclades):
320
class server_shutdown(_init_cyclades, _optional_output_cmd):
310 321
    """Shutdown an active server (VM)"""
311 322

  
312 323
    @errors.generic.all
313 324
    @errors.cyclades.connection
314 325
    @errors.cyclades.server_id
315 326
    def _run(self, server_id):
316
        self.client.shutdown_server(int(server_id))
327
        self._optional_output(self.client.shutdown_server(int(server_id)))
317 328

  
318 329
    def main(self, server_id):
319 330
        super(self.__class__, self)._run()
......
329 340
    - password: for VNC authorization
330 341
    """
331 342

  
343
    arguments = dict(
344
        json_output=FlagArgument('show output in json', ('-j', '--json'))
345
    )
346

  
332 347
    @errors.generic.all
333 348
    @errors.cyclades.connection
334 349
    @errors.cyclades.server_id
335 350
    def _run(self, server_id):
336
        r = self.client.get_server_console(int(server_id))
337
        print_dict(r)
351
        printer = print_json if self['json_output'] else print_dict
352
        printer(self.client.get_server_console(int(server_id)))
338 353

  
339 354
    def main(self, server_id):
340 355
        super(self.__class__, self)._run()
......
343 358

  
344 359
@command(server_cmds)
345 360
class server_firewall(_init_cyclades):
361
    """Manage server (VM) firewall profiles for public networks"""
362

  
363

  
364
@command(server_cmds)
365
class server_firewall_set(_init_cyclades, _optional_output_cmd):
346 366
    """Set the server (VM) firewall profile on VMs public network
347 367
    Values for profile:
348 368
    - DISABLED: Shutdown firewall
......
355 375
    @errors.cyclades.server_id
356 376
    @errors.cyclades.firewall
357 377
    def _run(self, server_id, profile):
358
        self.client.set_firewall_profile(
359
            server_id=int(server_id),
360
            profile=('%s' % profile).upper())
378
        self._optional_output(self.client.set_firewall_profile(
379
            server_id=int(server_id), profile=('%s' % profile).upper()))
361 380

  
362 381
    def main(self, server_id, profile):
363 382
        super(self.__class__, self)._run()
......
365 384

  
366 385

  
367 386
@command(server_cmds)
387
class server_firewall_get(_init_cyclades):
388
    """Get the server (VM) firewall profile for its public network"""
389

  
390
    @errors.generic.all
391
    @errors.cyclades.connection
392
    @errors.cyclades.server_id
393
    def _run(self, server_id):
394
        print(self.client.get_firewall_profile(server_id))
395

  
396
    def main(self, server_id):
397
        super(self.__class__, self)._run()
398
        self._run(server_id=server_id)
399

  
400

  
401
@command(server_cmds)
368 402
class server_addr(_init_cyclades):
369 403
    """List the addresses of all network interfaces on a server (VM)"""
370 404

  
405
    arguments = dict(
406
        enum=FlagArgument('Enumerate results', '--enumerate'),
407
        json_output=FlagArgument('show output in json', ('-j', '--json'))
408
    )
409

  
371 410
    @errors.generic.all
372 411
    @errors.cyclades.connection
373 412
    @errors.cyclades.server_id
374 413
    def _run(self, server_id):
375 414
        reply = self.client.list_server_nics(int(server_id))
376
        print_list(reply, with_enumeration=len(reply) > 1)
415
        if self['json_output']:
416
            print_json(reply)
417
        else:
418
            print_items(
419
                reply,
420
                with_enumeration=self['enum'] and len(reply) > 1)
377 421

  
378 422
    def main(self, server_id):
379 423
        super(self.__class__, self)._run()
......
381 425

  
382 426

  
383 427
@command(server_cmds)
384
class server_meta(_init_cyclades):
385
    """Get a server's metadatum
386
    Metadata are formed as key:value pairs where key is used to retrieve them
387
    """
428
class server_metadata(_init_cyclades):
429
    """Manage Server metadata (key:value pairs of server attributes)"""
430

  
431

  
432
@command(server_cmds)
433
class server_metadata_list(_init_cyclades):
434
    """Get server metadata"""
435

  
436
    arguments = dict(
437
        json_output=FlagArgument('show output in json', ('-j', '--json'))
438
    )
388 439

  
389 440
    @errors.generic.all
390 441
    @errors.cyclades.connection
391 442
    @errors.cyclades.server_id
392 443
    @errors.cyclades.metadata
393 444
    def _run(self, server_id, key=''):
394
        r = self.client.get_server_metadata(int(server_id), key)
395
        print_dict(r)
445
        printer = print_json if self['json_output'] else print_dict
446
        printer(self.client.get_server_metadata(int(server_id), key))
396 447

  
397 448
    def main(self, server_id, key=''):
398 449
        super(self.__class__, self)._run()
......
400 451

  
401 452

  
402 453
@command(server_cmds)
403
class server_setmeta(_init_cyclades):
404
    """set server (VM) metadata
405
    Metadata are formed as key:value pairs, both needed to set one
454
class server_metadata_set(_init_cyclades):
455
    """Set / update server(VM) metadata
456
    Metadata should be given in key/value pairs in key=value format
457
    For example:
458
        /server metadata set <server id> key1=value1 key2=value2
459
    Old, unreferenced metadata will remain intact
406 460
    """
407 461

  
462
    arguments = dict(
463
        json_output=FlagArgument('show output in json', ('-j', '--json'))
464
    )
465

  
408 466
    @errors.generic.all
409 467
    @errors.cyclades.connection
410 468
    @errors.cyclades.server_id
411
    def _run(self, server_id, key, val):
412
        metadata = {key: val}
413
        r = self.client.update_server_metadata(int(server_id), **metadata)
414
        print_dict(r)
415

  
416
    def main(self, server_id, key, val):
469
    def _run(self, server_id, keyvals):
470
        metadata = dict()
471
        print('TO ANALYZE:', keyvals)
472
        for keyval in keyvals:
473
            k, sep, v = keyval.partition('=')
474
            if sep and k:
475
                metadata[k] = v
476
            else:
477
                raiseCLIError(
478
                    'Invalid piece of metadata %s' % keyval,
479
                    importance=2, details=[
480
                        'Correct metadata format: key=val',
481
                        'For example:',
482
                        '/server metadata set <server id>'
483
                        'key1=value1 key2=value2'])
484
        printer = print_json if self['json_output'] else print_dict
485
        printer(self.client.update_server_metadata(int(server_id), **metadata))
486

  
487
    def main(self, server_id, *key_equals_val):
417 488
        super(self.__class__, self)._run()
418
        self._run(server_id=server_id, key=key, val=val)
489
        self._run(server_id=server_id, keyvals=key_equals_val)
419 490

  
420 491

  
421 492
@command(server_cmds)
422
class server_delmeta(_init_cyclades):
493
class server_metadata_delete(_init_cyclades, _optional_output_cmd):
423 494
    """Delete server (VM) metadata"""
424 495

  
425 496
    @errors.generic.all
......
427 498
    @errors.cyclades.server_id
428 499
    @errors.cyclades.metadata
429 500
    def _run(self, server_id, key):
430
        self.client.delete_server_metadata(int(server_id), key)
501
        self._optional_output(
502
            self.client.delete_server_metadata(int(server_id), key))
431 503

  
432 504
    def main(self, server_id, key):
433 505
        super(self.__class__, self)._run()
......
438 510
class server_stats(_init_cyclades):
439 511
    """Get server (VM) statistics"""
440 512

  
513
    arguments = dict(
514
        json_output=FlagArgument('show output in json', ('-j', '--json'))
515
    )
516

  
441 517
    @errors.generic.all
442 518
    @errors.cyclades.connection
443 519
    @errors.cyclades.server_id
444 520
    def _run(self, server_id):
445
        r = self.client.get_server_stats(int(server_id))
446
        print_dict(r, exclude=('serverRef',))
521
        printer = print_json if self['json_output'] else print_dict
522
        printer(self.client.get_server_stats(int(server_id)))
447 523

  
448 524
    def main(self, server_id):
449 525
        super(self.__class__, self)._run()

Also available in: Unified diff