Revision fe29fb25

b/snf-tools/cloud
33 33
# interpreted as representing official policies, either expressed
34 34
# or implied, of GRNET S.A.
35 35

  
36
from httplib import HTTPConnection
36
from httplib import HTTPConnection, HTTPSConnection
37 37
from optparse import OptionParser
38 38
from os.path import basename
39 39
from sys import argv, exit
40
from urlparse import urlparse
40 41

  
41 42
import json
42 43

  
43
DEFAULT_HOST = '127.0.0.1:8000'
44
DEFAULT_API = 'v1.1'
45 44

  
46
TOKEN = '46e427d657b20defe352804f0eb6f8a2'
45
DEFAULT_API_URL = 'http://127.0.0.1:8000/api/v1.1'
46
DEFAULT_TOKEN = '46e427d657b20defe352804f0eb6f8a2'
47 47

  
48 48
MARGIN = 14
49 49

  
......
84 84
class Command(object):
85 85
    def __init__(self, argv):
86 86
        parser = OptionParser()
87
        parser.add_option('--host', dest='host', metavar='HOST', default=DEFAULT_HOST,
88
                            help='use server HOST')
89
        parser.add_option('--api', dest='api', metavar='API', default=DEFAULT_API,
87
        parser.add_option('--apiurl',
88
                            dest='apiurl',
89
                            metavar='URL',
90
                            default=DEFAULT_API_URL,
90 91
                            help='use api API')
91
        parser.add_option('-v', action='store_true', dest='verbose', default=False,
92
        parser.add_option('--token',
93
                            dest='token',
94
                            metavar='TOKEN',
95
                            default=DEFAULT_TOKEN,
96
                            help='use user token TOKEN')
97
        parser.add_option('-v',
98
                            action='store_true',
99
                            dest='verbose',
100
                            default=False,
92 101
                            help='use verbose output')
93 102
        self.add_options(parser)
94 103
        options, args = parser.parse_args(argv)
......
109 118
        pass
110 119
    
111 120
    def http_cmd(self, method, path, body=None, expected_status=200):
112
        conn = HTTPConnection(self.host)
121
        p = urlparse(self.apiurl)
122
        if p.scheme == 'https':
123
            conn = HTTPSConnection(p.netloc)
124
        else:
125
            conn = HTTPConnection(p.netloc)
113 126

  
114 127
        kwargs = {}
115
        kwargs['headers'] = {'X-Auth-Token': TOKEN}
128
        kwargs['headers'] = {'X-Auth-Token': self.token}
116 129
        if body:
117 130
            kwargs['headers']['Content-Type'] = 'application/json'
118 131
            kwargs['body'] = body
119
        conn.request(method, path, **kwargs)
132
        conn.request(method, p.path + path, **kwargs)
120 133

  
121 134
        resp = conn.getresponse()
122 135
        if self.verbose:
......
174 187
                            help='include empty values')
175 188
    
176 189
    def execute(self):
177
        path = '/api/%s/servers' % self.api
178
        if self.detail:
179
            path += '/detail'
180

  
190
        path = '/servers/detail' if self.detail else '/servers'
181 191
        reply = self.http_get(path)
182 192

  
183 193
        for server in reply['servers']['values']:
......
201 211
                            help='include empty values')
202 212
    
203 213
    def execute(self, server_id):
204
        path = '/api/%s/servers/%d' % (self.api, int(server_id))
214
        path = '/servers/%d' % int(server_id)
205 215
        reply = self.http_get(path)
206 216
        server = reply['server']
207 217
        server.pop('id')
......
220 230
                            help='use image IMAGE_ID')
221 231
    
222 232
    def execute(self, name):
223
        path = '/api/%s/servers' % self.api
224
        server = {'name': name, 'flavorRef': self.flavor, 'imageRef': self.image}
233
        server = {
234
            'name': name,
235
            'flavorRef': self.flavor,
236
            'imageRef': self.image}
225 237
        body = json.dumps({'server': server})
226
        reply = self.http_post(path, body)
238
        reply = self.http_post('/servers', body)
227 239
        server = reply['server']
228 240
        print_dict(server)
229 241

  
......
234 246
    syntax = '<server id> <new name>'
235 247
    
236 248
    def execute(self, server_id, name):
237
        path = '/api/%s/servers/%d' % (self.api, int(server_id))
249
        path = '/servers/%d' % int(server_id)
238 250
        body = json.dumps({'server': {'name': name}})
239 251
        self.http_put(path, body)
240 252

  
......
245 257
    syntax = '<server id>'
246 258
    
247 259
    def execute(self, server_id):
248
        path = '/api/%s/servers/%d' % (self.api, int(server_id))
260
        path = '/servers/%d' % int(server_id)
249 261
        self.http_delete(path)
250 262

  
251 263

  
......
259 271
                            help='perform a hard reboot')
260 272
    
261 273
    def execute(self, server_id):
262
        path = '/api/%s/servers/%d/action' % (self.api, int(server_id))
274
        path = '/servers/%d/action' % int(server_id)
263 275
        type = 'HARD' if self.hard else 'SOFT'
264 276
        body = json.dumps({'reboot': {'type': type}})
265 277
        self.http_post(path, body)
......
271 283
    syntax = '<server id>'
272 284
    
273 285
    def execute(self, server_id):
274
        path = '/api/%s/servers/%d/action' % (self.api, int(server_id))
286
        path = '/servers/%d/action' % int(server_id)
275 287
        body = json.dumps({'start': {}})
276 288
        self.http_post(path, body)
277 289

  
......
282 294
    syntax = '<server id>'
283 295
    
284 296
    def execute(self, server_id):
285
        path = '/api/%s/servers/%d/action' % (self.api, int(server_id))
297
        path = '/servers/%d/action' % int(server_id)
286 298
        body = json.dumps({'shutdown': {}})
287 299
        self.http_post(path, body)
288 300

  
......
293 305
    syntax = '<server id>'
294 306
    
295 307
    def execute(self, server_id):
296
        path = '/api/%s/servers/%d/action' % (self.api, int(server_id))
308
        path = '/servers/%d/action' % int(server_id)
297 309
        body = json.dumps({'console': {'type': 'vnc'}})
298 310
        reply = self.http_cmd('POST', path, body, 200)
299 311
        print_dict(reply['console'])
......
305 317
    syntax = '<server id> <profile>'
306 318
    
307 319
    def execute(self, server_id, profile):
308
        path = '/api/%s/servers/%d/action' % (self.api, int(server_id))
320
        path = '/servers/%d/action' % int(server_id)
309 321
        body = json.dumps({'firewallProfile': {'profile': profile}})
310 322
        self.http_cmd('POST', path, body, 202)
311 323

  
......
316 328
    syntax = '<server id> [network]'
317 329
    
318 330
    def execute(self, server_id, network=None):
319
        path = '/api/%s/servers/%d/ips' % (self.api, int(server_id))
331
        path = '/servers/%d/ips' % int(server_id)
320 332
        if network:
321 333
            path += '/%s' % network
322 334
        reply = self.http_get(path)
......
334 346
                            help='show detailed output')
335 347
    
336 348
    def execute(self):
337
        path = '/api/%s/flavors' % self.api
338
        if self.detail:
339
            path += '/detail'
349
        path = '/flavors/detail' if self.detail else '/flavors'
340 350
        reply = self.http_get(path)
341 351
        
342 352
        for flavor in reply['flavors']['values']:
......
352 362
    syntax = '<flavor id>'
353 363
    
354 364
    def execute(self, flavor_id):
355
        path = '/api/%s/flavors/%d' % (self.api, int(flavor_id))
365
        path = '/flavors/%d' % int(flavor_id)
356 366
        reply = self.http_get(path)
357 367
        
358 368
        flavor = reply['flavor']
......
371 381
                            help='show detailed output')
372 382
    
373 383
    def execute(self):
374
        path = '/api/%s/images' % self.api
375
        if self.detail:
376
            path += '/detail'
384
        path = '/images/detail' if self.detail else '/images'
377 385
        reply = self.http_get(path)
378 386
        
379 387
        for image in reply['images']['values']:
......
393 401
    syntax = '<image id>'
394 402
    
395 403
    def execute(self, image_id):
396
        path = '/api/%s/images/%d' % (self.api, int(image_id))
404
        path = '/images/%d' % int(image_id)
397 405
        reply = self.http_get(path)
398 406
        image = reply['image']
399 407
        image.pop('id')
......
406 414
    syntax = '<server id> <image name>'
407 415
    
408 416
    def execute(self, server_id, name):
409
        path = '/api/%s/images' % self.api
410 417
        image = {'name': name, 'serverRef': int(server_id)}
411 418
        body = json.dumps({'image': image})
412
        reply = self.http_post(path, body)
419
        reply = self.http_post('/images', body)
413 420
        print_dict(reply['image'])
414 421

  
415 422
@command_name('deleteimg')
......
418 425
    syntax = '<image id>'
419 426
    
420 427
    def execute(self, image_id):
421
        path = '/api/%s/images/%d' % (self.api, int(image_id))
428
        path = '/images/%d' % int(image_id)
422 429
        self.http_delete(path)
423 430

  
424 431
@command_name('lsmeta')
......
427 434
    syntax = '<server id> [key]'
428 435

  
429 436
    def execute(self, server_id, key=None):
430
        path = '/api/%s/servers/%d/meta' % (self.api, int(server_id))
437
        path = '/servers/%d/meta' % int(server_id)
431 438
        if key:
432 439
            path += '/' + key
433 440
        reply = self.http_get(path)
......
442 449
    syntax = '<server id> <key> <val>'
443 450

  
444 451
    def execute(self, server_id, key, val):
445
        path = '/api/%s/servers/%d/meta' % (self.api, int(server_id))
452
        path = '/servers/%d/meta' % int(server_id)
446 453
        metadata = {key: val}
447 454
        body = json.dumps({'metadata': metadata})
448 455
        reply = self.http_post(path, body, expected_status=201)
......
454 461
    syntax = '<server id> <key> <val>'
455 462

  
456 463
    def execute(self, server_id, key, val):
457
        path = '/api/%s/servers/%d/meta/%s' % (self.api, int(server_id), key)
464
        path = '/servers/%d/meta/%s' % (int(server_id), key)
458 465
        meta = {key: val}
459 466
        body = json.dumps({'meta': meta})
460 467
        reply = self.http_put(path, body, expected_status=201)
......
466 473
    syntax = '<server id> <key>'
467 474

  
468 475
    def execute(self, server_id, key):
469
        path = '/api/%s/servers/%d/meta/%s' % (self.api, int(server_id), key)
476
        path = '/servers/%d/meta/%s' % (int(server_id), key)
470 477
        reply = self.http_delete(path)
471 478

  
472 479
@command_name('lsimgmeta')
......
475 482
    syntax = '<image id> [key]'
476 483

  
477 484
    def execute(self, image_id, key=None):
478
        path = '/api/%s/images/%d/meta' % (self.api, int(image_id))
485
        path = '/images/%d/meta' % int(image_id)
479 486
        if key:
480 487
            path += '/' + key
481 488
        reply = self.http_get(path)
......
490 497
    syntax = '<image id> <key> <val>'
491 498

  
492 499
    def execute(self, image_id, key, val):
493
        path = '/api/%s/images/%d/meta' % (self.api, int(image_id))
500
        path = '/images/%d/meta' % int(image_id)
494 501
        metadata = {key: val}
495 502
        body = json.dumps({'metadata': metadata})
496 503
        reply = self.http_post(path, body, expected_status=201)
......
502 509
    syntax = '<image id> <key> <val>'
503 510

  
504 511
    def execute(self, image_id, key, val):
505
        path = '/api/%s/images/%d/meta/%s' % (self.api, int(image_id), key)
512
        path = '/images/%d/meta/%s' % (int(image_id), key)
506 513
        meta = {key: val}
507 514
        body = json.dumps({'meta': meta})
508 515
        reply = self.http_put(path, body, expected_status=201)
......
514 521
    syntax = '<image id> <key>'
515 522

  
516 523
    def execute(self, image_id, key):
517
        path = '/api/%s/images/%d/meta/%s' % (self.api, int(image_id), key)
524
        path = '/images/%d/meta/%s' % (int(image_id), key)
518 525
        reply = self.http_delete(path)
519 526

  
520 527

  
......
527 534
                            help='show detailed output')
528 535

  
529 536
    def execute(self):
530
        path = '/api/%s/networks' % self.api
531
        if self.detail:
532
            path += '/detail'
537
        path = '/networks/detail' if self.detail else '/networks'
533 538
        reply = self.http_get(path)
534 539

  
535 540
        for network in reply['networks']['values']:
......
549 554
    syntax = '<network name>'
550 555

  
551 556
    def execute(self, name):
552
        path = '/api/%s/networks' % self.api
553 557
        network = {'name': name}
554 558
        body = json.dumps({'network': network})
555
        reply = self.http_post(path, body)
559
        reply = self.http_post('/networks', body)
556 560
        print_dict(reply['network'])
557 561

  
558 562

  
......
562 566
    syntax = '<network id>'
563 567

  
564 568
    def execute(self, network_id):
565
        path = '/api/%s/networks/%d' % (self.api, int(network_id))
569
        path = '/networks/%d' % int(network_id)
566 570
        reply = self.http_get(path)
567 571
        net = reply['network']
568 572
        name = net.pop('id')
......
575 579
    syntax = '<network_id> <new name>'
576 580

  
577 581
    def execute(self, network_id, name):
578
        path = '/api/%s/networks/%d' % (self.api, int(network_id))
582
        path = '/networks/%d' % int(network_id)
579 583
        body = json.dumps({'network': {'name': name}})
580 584
        self.http_put(path, body)
581 585

  
......
586 590
    syntax = '<network id>'
587 591

  
588 592
    def execute(self, network_id):
589
        path = '/api/%s/networks/%d' % (self.api, int(network_id))
593
        path = '/networks/%d' % int(network_id)
590 594
        self.http_delete(path)
591 595

  
592 596

  
......
596 600
    syntax = '<server id> <network id>'
597 601

  
598 602
    def execute(self, server_id, network_id):
599
        path = '/api/%s/networks/%d/action' % (self.api, int(network_id))
603
        path = '/networks/%d/action' % int(network_id)
600 604
        body = json.dumps({'add': {'serverRef': server_id}})
601 605
        self.http_post(path, body, expected_status=202)
602 606

  
......
607 611
    syntax = '<server id> <network id>'
608 612

  
609 613
    def execute(self, server_id, network_id):
610
        path = '/api/%s/networks/%s/action' % (self.api, int(network_id))
614
        path = '/networks/%s/action' % int(network_id)
611 615
        body = json.dumps({'remove': {'serverRef': server_id}})
612 616
        self.http_post(path, body, expected_status=202)
613 617

  
......
617 621
    syntax = '<server id>'
618 622

  
619 623
    def execute(self, server_id):
620
        path = '/api/%s/servers/%d/stats' % (self.api, int(server_id))
624
        path = '/servers/%d/stats' % int(server_id)
621 625
        reply = self.http_get(path)
622 626
        stats = reply['stats']
623 627
        stats.pop('serverRef')

Also available in: Unified diff