· 7 years ago · Oct 14, 2018, 04:44 AM
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import os
5import base64
6import urllib
7import hashlib
8import hmac
9import httplib
10import urlparse
11import argparse
12import json
13import xml.dom.minidom
14
15
16class CloudStackApiSignatureBuilder(object):
17
18 def __init__(self, apikey, secretkey):
19 self.apikey = apikey
20 self.secretkey = secretkey
21
22 def build(self, query_dict):
23 query_dict['apikey'] = self.apikey
24 query_list = sorted(['%s=%s' % (k, urllib.quote(v, safe=''))
25 for k, v in query_dict.items()])
26 command_str = reduce(lambda s, e: '%s&%s' % (s, e),
27 query_list, '').lower()[1:]
28 digest = hmac.new(self.secretkey, command_str, hashlib.sha1).digest()
29 return urllib.quote(base64.encodestring(digest)[:-1], safe='')
30
31
32class CloudStackApiClient(object):
33
34 def __init__(self, entrypoint, apikey, secretkey):
35 self.entrypoint = entrypoint
36 self.apikey = apikey
37 self.secretkey = secretkey
38
39 def request(self, query_dict, method='GET'):
40 if self.apikey != None and self.secretkey != None:
41 signature_builder = CloudStackApiSignatureBuilder(self.apikey,
42 self.secretkey)
43 sigunature = signature_builder.build(query_dict)
44 query_dict['signature'] = sigunature
45 query_dict['apikey'] = self.apikey
46 query_string = reduce(lambda s, (k, v): '%s&%s=%s' % (s, k, v),
47 query_dict.iteritems(), '')[1:]
48 url_parser = urlparse.urlparse(self.entrypoint)
49 connections = {'https': httplib.HTTPSConnection,
50 'http': httplib.HTTPConnection}
51 http_connection = connections[url_parser.scheme](url_parser.netloc)
52 http_connection.request(method, '%s?%s' % (url_parser.path,
53 query_string))
54 return http_connection.getresponse()
55
56
57def main(args):
58 client = CloudStackApiClient(args.entrypoint, args.apikey, args.secretkey)
59 params = {}
60 for s in args.parameters:
61 params[s.split('=')[0]] = s.split('=')[1]
62 if args.json:
63 params['response'] = 'json'
64 response = client.request(params)
65
66 print '%s %s' % (response.status, response.reason)
67 print response.msg
68 if 'response' in params and params['response'] == 'json':
69 print json.dumps(json.loads(response.read(), 'UTF-8'), indent=4)
70 else:
71 print xml.dom.minidom.parseString(response.read()).toprettyxml()
72
73
74if __name__ == '__main__':
75 description = 'The CloudStack Web Services Query HTTP API Client'
76 option_e_help = 'API entry point'
77 option_a_help = 'API key which can be taken from management WebUI'
78 option_s_help = 'SECRET key which can be taken from management WebUI'
79 option_j_help = 'JSON format'
80 parameters_help = 'key=value pairs (e.g. command=listHosts ...)'
81
82 option_e_default = os.environ.get('CLOUDSTACK_API_ENTRYPOINT')
83 option_a_default = os.environ.get('CLOUDSTACK_API_APIKEY')
84 option_s_default = os.environ.get('CLOUDSTACK_API_SECRETKEY')
85
86 arg_parser = argparse.ArgumentParser(description=description)
87 arg_parser.add_argument('-e', '--entrypoint', help=option_e_help,
88 required=False, default=option_e_default)
89 arg_parser.add_argument('-a', '--apikey', help=option_a_help,
90 required=False, default=option_a_default)
91 arg_parser.add_argument('-s', '--secretkey', help=option_s_help,
92 required=False, default=option_s_default)
93 arg_parser.add_argument('-j', '--json', help=option_j_help,
94 required=False, action='store_true')
95 arg_parser.add_argument('parameters', help=parameters_help, nargs='+')
96
97 main(arg_parser.parse_args())