root / snf-cyclades-app / synnefo / tools / cloud.py @ 65462ca9
History | View | Annotate | Download (19.8 kB)
1 | ab756200 | Giorgos Verigakis | #!/usr/bin/env python
|
---|---|---|---|
2 | ab756200 | Giorgos Verigakis | |
3 | adee02b8 | Giorgos Verigakis | # Copyright 2011 GRNET S.A. All rights reserved.
|
4 | 38d247df | Kostas Papadimitriou | #
|
5 | adee02b8 | Giorgos Verigakis | # Redistribution and use in source and binary forms, with or
|
6 | adee02b8 | Giorgos Verigakis | # without modification, are permitted provided that the following
|
7 | adee02b8 | Giorgos Verigakis | # conditions are met:
|
8 | 38d247df | Kostas Papadimitriou | #
|
9 | adee02b8 | Giorgos Verigakis | # 1. Redistributions of source code must retain the above
|
10 | adee02b8 | Giorgos Verigakis | # copyright notice, this list of conditions and the following
|
11 | adee02b8 | Giorgos Verigakis | # disclaimer.
|
12 | 38d247df | Kostas Papadimitriou | #
|
13 | adee02b8 | Giorgos Verigakis | # 2. Redistributions in binary form must reproduce the above
|
14 | adee02b8 | Giorgos Verigakis | # copyright notice, this list of conditions and the following
|
15 | adee02b8 | Giorgos Verigakis | # disclaimer in the documentation and/or other materials
|
16 | adee02b8 | Giorgos Verigakis | # provided with the distribution.
|
17 | 38d247df | Kostas Papadimitriou | #
|
18 | adee02b8 | Giorgos Verigakis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
19 | adee02b8 | Giorgos Verigakis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
20 | adee02b8 | Giorgos Verigakis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
21 | adee02b8 | Giorgos Verigakis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
22 | adee02b8 | Giorgos Verigakis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
23 | adee02b8 | Giorgos Verigakis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
24 | adee02b8 | Giorgos Verigakis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
25 | adee02b8 | Giorgos Verigakis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
26 | adee02b8 | Giorgos Verigakis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
27 | adee02b8 | Giorgos Verigakis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
28 | adee02b8 | Giorgos Verigakis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29 | adee02b8 | Giorgos Verigakis | # POSSIBILITY OF SUCH DAMAGE.
|
30 | 38d247df | Kostas Papadimitriou | #
|
31 | adee02b8 | Giorgos Verigakis | # The views and conclusions contained in the software and
|
32 | adee02b8 | Giorgos Verigakis | # documentation are those of the authors and should not be
|
33 | adee02b8 | Giorgos Verigakis | # interpreted as representing official policies, either expressed
|
34 | adee02b8 | Giorgos Verigakis | # or implied, of GRNET S.A.
|
35 | adee02b8 | Giorgos Verigakis | |
36 | fe29fb25 | Giorgos Verigakis | from httplib import HTTPConnection, HTTPSConnection |
37 | ab756200 | Giorgos Verigakis | from optparse import OptionParser |
38 | ab756200 | Giorgos Verigakis | from os.path import basename |
39 | ab756200 | Giorgos Verigakis | from sys import argv, exit |
40 | fe29fb25 | Giorgos Verigakis | from urlparse import urlparse |
41 | ab756200 | Giorgos Verigakis | |
42 | ab756200 | Giorgos Verigakis | import json |
43 | ab756200 | Giorgos Verigakis | |
44 | ab756200 | Giorgos Verigakis | |
45 | fe29fb25 | Giorgos Verigakis | DEFAULT_API_URL = 'http://127.0.0.1:8000/api/v1.1'
|
46 | 40777cc8 | Giorgos Verigakis | |
47 | ebc913dc | Giorgos Verigakis | MARGIN = 14
|
48 | ab756200 | Giorgos Verigakis | |
49 | ab756200 | Giorgos Verigakis | commands = {} |
50 | ab756200 | Giorgos Verigakis | |
51 | ab756200 | Giorgos Verigakis | def command_name(name): |
52 | ab756200 | Giorgos Verigakis | def decorator(cls): |
53 | ab756200 | Giorgos Verigakis | commands[name] = cls |
54 | ab756200 | Giorgos Verigakis | return cls
|
55 | ab756200 | Giorgos Verigakis | return decorator
|
56 | ab756200 | Giorgos Verigakis | |
57 | ab756200 | Giorgos Verigakis | |
58 | d44c236b | Giorgos Verigakis | def print_addresses(networks): |
59 | d44c236b | Giorgos Verigakis | for i, net in enumerate(networks): |
60 | ebc913dc | Giorgos Verigakis | key = 'addresses:'.rjust(MARGIN + 1) if i == 0 else ' ' * (MARGIN + 1) |
61 | d44c236b | Giorgos Verigakis | addr = ''
|
62 | d44c236b | Giorgos Verigakis | if 'values' in net: |
63 | d44c236b | Giorgos Verigakis | addr = '[%s]' % ' '.join(ip['addr'] for ip in net['values']) |
64 | 38d247df | Kostas Papadimitriou | |
65 | 207b70d5 | Giorgos Verigakis | val = '%s/%s %s %s' % (net['id'], net['name'], net['mac'], addr) |
66 | 46e42692 | Giorgos Verigakis | if 'firewallProfile' in net: |
67 | 46e42692 | Giorgos Verigakis | val += ' - %s' % net['firewallProfile'] |
68 | d44c236b | Giorgos Verigakis | print '%s %s' % (key, val) |
69 | ab756200 | Giorgos Verigakis | |
70 | ab756200 | Giorgos Verigakis | def print_dict(d, show_empty=True): |
71 | ab756200 | Giorgos Verigakis | for key, val in sorted(d.items()): |
72 | ab756200 | Giorgos Verigakis | if key == 'metadata': |
73 | ab756200 | Giorgos Verigakis | val = ', '.join('%s="%s"' % x for x in val['values'].items()) |
74 | 0269afd6 | Giorgos Verigakis | elif key == 'addresses': |
75 | d44c236b | Giorgos Verigakis | print_addresses(val['values'])
|
76 | d44c236b | Giorgos Verigakis | continue
|
77 | 0269afd6 | Giorgos Verigakis | elif key == 'servers': |
78 | 0269afd6 | Giorgos Verigakis | val = ', '.join(str(server_id) for server_id in val['values']) |
79 | ab756200 | Giorgos Verigakis | if val or show_empty: |
80 | ebc913dc | Giorgos Verigakis | print '%s: %s' % (key.rjust(MARGIN), val) |
81 | ab756200 | Giorgos Verigakis | |
82 | ab756200 | Giorgos Verigakis | |
83 | ab756200 | Giorgos Verigakis | class Command(object): |
84 | ab756200 | Giorgos Verigakis | def __init__(self, argv): |
85 | ab756200 | Giorgos Verigakis | parser = OptionParser() |
86 | fe29fb25 | Giorgos Verigakis | parser.add_option('--apiurl',
|
87 | fe29fb25 | Giorgos Verigakis | dest='apiurl',
|
88 | fe29fb25 | Giorgos Verigakis | metavar='URL',
|
89 | fe29fb25 | Giorgos Verigakis | default=DEFAULT_API_URL, |
90 | ab756200 | Giorgos Verigakis | help='use api API')
|
91 | fe29fb25 | Giorgos Verigakis | parser.add_option('--token',
|
92 | fe29fb25 | Giorgos Verigakis | dest='token',
|
93 | fe29fb25 | Giorgos Verigakis | metavar='TOKEN',
|
94 | fe29fb25 | Giorgos Verigakis | help='use user token TOKEN')
|
95 | fe29fb25 | Giorgos Verigakis | parser.add_option('-v',
|
96 | fe29fb25 | Giorgos Verigakis | action='store_true',
|
97 | fe29fb25 | Giorgos Verigakis | dest='verbose',
|
98 | fe29fb25 | Giorgos Verigakis | default=False,
|
99 | ab756200 | Giorgos Verigakis | help='use verbose output')
|
100 | ab756200 | Giorgos Verigakis | self.add_options(parser)
|
101 | ab756200 | Giorgos Verigakis | options, args = parser.parse_args(argv) |
102 | 38d247df | Kostas Papadimitriou | |
103 | ab756200 | Giorgos Verigakis | # Add options to self
|
104 | ab756200 | Giorgos Verigakis | for opt in parser.option_list: |
105 | ab756200 | Giorgos Verigakis | key = opt.dest |
106 | ab756200 | Giorgos Verigakis | if key:
|
107 | ab756200 | Giorgos Verigakis | val = getattr(options, key)
|
108 | ab756200 | Giorgos Verigakis | setattr(self, key, val) |
109 | 38d247df | Kostas Papadimitriou | |
110 | ab756200 | Giorgos Verigakis | self.execute(*args)
|
111 | 38d247df | Kostas Papadimitriou | |
112 | ab756200 | Giorgos Verigakis | def add_options(self, parser): |
113 | ab756200 | Giorgos Verigakis | pass
|
114 | 38d247df | Kostas Papadimitriou | |
115 | ab756200 | Giorgos Verigakis | def execute(self, *args): |
116 | ab756200 | Giorgos Verigakis | pass
|
117 | 38d247df | Kostas Papadimitriou | |
118 | ab756200 | Giorgos Verigakis | def http_cmd(self, method, path, body=None, expected_status=200): |
119 | fe29fb25 | Giorgos Verigakis | p = urlparse(self.apiurl)
|
120 | fe29fb25 | Giorgos Verigakis | if p.scheme == 'https': |
121 | fe29fb25 | Giorgos Verigakis | conn = HTTPSConnection(p.netloc) |
122 | fe29fb25 | Giorgos Verigakis | else:
|
123 | fe29fb25 | Giorgos Verigakis | conn = HTTPConnection(p.netloc) |
124 | ab756200 | Giorgos Verigakis | |
125 | ab756200 | Giorgos Verigakis | kwargs = {} |
126 | fe29fb25 | Giorgos Verigakis | kwargs['headers'] = {'X-Auth-Token': self.token} |
127 | ab756200 | Giorgos Verigakis | if body:
|
128 | 40777cc8 | Giorgos Verigakis | kwargs['headers']['Content-Type'] = 'application/json' |
129 | ab756200 | Giorgos Verigakis | kwargs['body'] = body
|
130 | fe29fb25 | Giorgos Verigakis | conn.request(method, p.path + path, **kwargs) |
131 | ab756200 | Giorgos Verigakis | |
132 | ab756200 | Giorgos Verigakis | resp = conn.getresponse() |
133 | ab756200 | Giorgos Verigakis | if self.verbose: |
134 | ab756200 | Giorgos Verigakis | print '%d %s' % (resp.status, resp.reason) |
135 | ab756200 | Giorgos Verigakis | for key, val in resp.getheaders(): |
136 | ab756200 | Giorgos Verigakis | print '%s: %s' % (key.capitalize(), val) |
137 | ab756200 | Giorgos Verigakis | print
|
138 | ab756200 | Giorgos Verigakis | |
139 | ab756200 | Giorgos Verigakis | buf = resp.read() or '{}' |
140 | 0269afd6 | Giorgos Verigakis | try:
|
141 | 0269afd6 | Giorgos Verigakis | reply = json.loads(buf) |
142 | 0269afd6 | Giorgos Verigakis | except ValueError: |
143 | 0269afd6 | Giorgos Verigakis | print 'Invalid response from the server.' |
144 | 0269afd6 | Giorgos Verigakis | if self.verbose: |
145 | 0269afd6 | Giorgos Verigakis | print buf
|
146 | 0269afd6 | Giorgos Verigakis | exit(1) |
147 | ab756200 | Giorgos Verigakis | |
148 | 4cf8adf8 | Vangelis Koukis | # If the response status is not the expected one,
|
149 | 4cf8adf8 | Vangelis Koukis | # assume an error has occured and treat the body
|
150 | 4cf8adf8 | Vangelis Koukis | # as a cloudfault.
|
151 | ab756200 | Giorgos Verigakis | if resp.status != expected_status:
|
152 | ab756200 | Giorgos Verigakis | if len(reply) == 1: |
153 | ab756200 | Giorgos Verigakis | key = reply.keys()[0]
|
154 | ab756200 | Giorgos Verigakis | val = reply[key] |
155 | d8e50a39 | Giorgos Verigakis | print '%s: %s' % (key, val.get('message', '')) |
156 | ab756200 | Giorgos Verigakis | if self.verbose: |
157 | ab756200 | Giorgos Verigakis | print val.get('details', '') |
158 | 0269afd6 | Giorgos Verigakis | else:
|
159 | 0269afd6 | Giorgos Verigakis | print 'Invalid response from the server.' |
160 | 0269afd6 | Giorgos Verigakis | exit(1) |
161 | ab756200 | Giorgos Verigakis | |
162 | ab756200 | Giorgos Verigakis | return reply
|
163 | ab756200 | Giorgos Verigakis | |
164 | ab756200 | Giorgos Verigakis | def http_get(self, path, expected_status=200): |
165 | ab756200 | Giorgos Verigakis | return self.http_cmd('GET', path, None, expected_status) |
166 | 38d247df | Kostas Papadimitriou | |
167 | ab756200 | Giorgos Verigakis | def http_post(self, path, body, expected_status=202): |
168 | ab756200 | Giorgos Verigakis | return self.http_cmd('POST', path, body, expected_status) |
169 | ab756200 | Giorgos Verigakis | |
170 | ab756200 | Giorgos Verigakis | def http_put(self, path, body, expected_status=204): |
171 | ab756200 | Giorgos Verigakis | return self.http_cmd('PUT', path, body, expected_status) |
172 | ab756200 | Giorgos Verigakis | |
173 | ab756200 | Giorgos Verigakis | def http_delete(self, path, expected_status=204): |
174 | ab756200 | Giorgos Verigakis | return self.http_cmd('DELETE', path, None, expected_status) |
175 | ab756200 | Giorgos Verigakis | |
176 | ab756200 | Giorgos Verigakis | |
177 | ab756200 | Giorgos Verigakis | @command_name('ls') |
178 | ab756200 | Giorgos Verigakis | class ListServers(Command): |
179 | ab756200 | Giorgos Verigakis | description = 'list servers'
|
180 | 38d247df | Kostas Papadimitriou | |
181 | ab756200 | Giorgos Verigakis | def add_options(self, parser): |
182 | ab756200 | Giorgos Verigakis | parser.add_option('-l', action='store_true', dest='detail', default=False, |
183 | ab756200 | Giorgos Verigakis | help='show detailed output')
|
184 | ab756200 | Giorgos Verigakis | parser.add_option('-a', action='store_true', dest='show_empty', default=False, |
185 | ab756200 | Giorgos Verigakis | help='include empty values')
|
186 | 38d247df | Kostas Papadimitriou | |
187 | ab756200 | Giorgos Verigakis | def execute(self): |
188 | fe29fb25 | Giorgos Verigakis | path = '/servers/detail' if self.detail else '/servers' |
189 | ab756200 | Giorgos Verigakis | reply = self.http_get(path)
|
190 | ab756200 | Giorgos Verigakis | |
191 | ab756200 | Giorgos Verigakis | for server in reply['servers']['values']: |
192 | ab756200 | Giorgos Verigakis | id = server.pop('id')
|
193 | ab756200 | Giorgos Verigakis | name = server.pop('name')
|
194 | ab756200 | Giorgos Verigakis | if self.detail: |
195 | ab756200 | Giorgos Verigakis | print '%d %s' % (id, name) |
196 | ab756200 | Giorgos Verigakis | print_dict(server, self.show_empty)
|
197 | ab756200 | Giorgos Verigakis | print
|
198 | ab756200 | Giorgos Verigakis | else:
|
199 | ab756200 | Giorgos Verigakis | print '%3d %s' % (id, name) |
200 | ab756200 | Giorgos Verigakis | |
201 | ab756200 | Giorgos Verigakis | |
202 | ab756200 | Giorgos Verigakis | @command_name('info') |
203 | ab756200 | Giorgos Verigakis | class GetServerDetails(Command): |
204 | ab756200 | Giorgos Verigakis | description = 'get server details'
|
205 | ab756200 | Giorgos Verigakis | syntax = '<server id>'
|
206 | 38d247df | Kostas Papadimitriou | |
207 | ab756200 | Giorgos Verigakis | def add_options(self, parser): |
208 | ab756200 | Giorgos Verigakis | parser.add_option('-a', action='store_true', dest='show_empty', default=False, |
209 | ab756200 | Giorgos Verigakis | help='include empty values')
|
210 | 38d247df | Kostas Papadimitriou | |
211 | ab756200 | Giorgos Verigakis | def execute(self, server_id): |
212 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d' % int(server_id) |
213 | ab756200 | Giorgos Verigakis | reply = self.http_get(path)
|
214 | ab756200 | Giorgos Verigakis | server = reply['server']
|
215 | ab756200 | Giorgos Verigakis | server.pop('id')
|
216 | ab756200 | Giorgos Verigakis | print_dict(server, self.show_empty)
|
217 | 38d247df | Kostas Papadimitriou | |
218 | ab756200 | Giorgos Verigakis | |
219 | ab756200 | Giorgos Verigakis | @command_name('create') |
220 | ab756200 | Giorgos Verigakis | class CreateServer(Command): |
221 | ab756200 | Giorgos Verigakis | description = 'create server'
|
222 | ab756200 | Giorgos Verigakis | syntax = '<server name>'
|
223 | 38d247df | Kostas Papadimitriou | |
224 | ab756200 | Giorgos Verigakis | def add_options(self, parser): |
225 | ab756200 | Giorgos Verigakis | parser.add_option('-f', dest='flavor', metavar='FLAVOR_ID', default=1, |
226 | ab756200 | Giorgos Verigakis | help='use flavor FLAVOR_ID')
|
227 | ab756200 | Giorgos Verigakis | parser.add_option('-i', dest='image', metavar='IMAGE_ID', default=1, |
228 | ab756200 | Giorgos Verigakis | help='use image IMAGE_ID')
|
229 | 38d247df | Kostas Papadimitriou | |
230 | ab756200 | Giorgos Verigakis | def execute(self, name): |
231 | fe29fb25 | Giorgos Verigakis | server = { |
232 | fe29fb25 | Giorgos Verigakis | 'name': name,
|
233 | fe29fb25 | Giorgos Verigakis | 'flavorRef': self.flavor, |
234 | fe29fb25 | Giorgos Verigakis | 'imageRef': self.image} |
235 | ab756200 | Giorgos Verigakis | body = json.dumps({'server': server})
|
236 | fe29fb25 | Giorgos Verigakis | reply = self.http_post('/servers', body) |
237 | ab756200 | Giorgos Verigakis | server = reply['server']
|
238 | ab756200 | Giorgos Verigakis | print_dict(server) |
239 | ab756200 | Giorgos Verigakis | |
240 | ab756200 | Giorgos Verigakis | |
241 | ab756200 | Giorgos Verigakis | @command_name('rename') |
242 | ab756200 | Giorgos Verigakis | class UpdateServerName(Command): |
243 | ab756200 | Giorgos Verigakis | description = 'update server name'
|
244 | ab756200 | Giorgos Verigakis | syntax = '<server id> <new name>'
|
245 | 38d247df | Kostas Papadimitriou | |
246 | ab756200 | Giorgos Verigakis | def execute(self, server_id, name): |
247 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d' % int(server_id) |
248 | ab756200 | Giorgos Verigakis | body = json.dumps({'server': {'name': name}}) |
249 | ab756200 | Giorgos Verigakis | self.http_put(path, body)
|
250 | ab756200 | Giorgos Verigakis | |
251 | ab756200 | Giorgos Verigakis | |
252 | ab756200 | Giorgos Verigakis | @command_name('delete') |
253 | ab756200 | Giorgos Verigakis | class DeleteServer(Command): |
254 | ab756200 | Giorgos Verigakis | description = 'delete server'
|
255 | ab756200 | Giorgos Verigakis | syntax = '<server id>'
|
256 | 38d247df | Kostas Papadimitriou | |
257 | ab756200 | Giorgos Verigakis | def execute(self, server_id): |
258 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d' % int(server_id) |
259 | ab756200 | Giorgos Verigakis | self.http_delete(path)
|
260 | ab756200 | Giorgos Verigakis | |
261 | ab756200 | Giorgos Verigakis | |
262 | ab756200 | Giorgos Verigakis | @command_name('reboot') |
263 | ab756200 | Giorgos Verigakis | class RebootServer(Command): |
264 | ab756200 | Giorgos Verigakis | description = 'reboot server'
|
265 | ab756200 | Giorgos Verigakis | syntax = '<server id>'
|
266 | 38d247df | Kostas Papadimitriou | |
267 | ab756200 | Giorgos Verigakis | def add_options(self, parser): |
268 | ab756200 | Giorgos Verigakis | parser.add_option('-f', action='store_true', dest='hard', default=False, |
269 | ab756200 | Giorgos Verigakis | help='perform a hard reboot')
|
270 | 38d247df | Kostas Papadimitriou | |
271 | ab756200 | Giorgos Verigakis | def execute(self, server_id): |
272 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d/action' % int(server_id) |
273 | ab756200 | Giorgos Verigakis | type = 'HARD' if self.hard else 'SOFT' |
274 | ab756200 | Giorgos Verigakis | body = json.dumps({'reboot': {'type': type}}) |
275 | ab756200 | Giorgos Verigakis | self.http_post(path, body)
|
276 | 38d247df | Kostas Papadimitriou | |
277 | ab756200 | Giorgos Verigakis | |
278 | ab756200 | Giorgos Verigakis | @command_name('start') |
279 | ab756200 | Giorgos Verigakis | class StartServer(Command): |
280 | ab756200 | Giorgos Verigakis | description = 'start server'
|
281 | ab756200 | Giorgos Verigakis | syntax = '<server id>'
|
282 | 38d247df | Kostas Papadimitriou | |
283 | ab756200 | Giorgos Verigakis | def execute(self, server_id): |
284 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d/action' % int(server_id) |
285 | ab756200 | Giorgos Verigakis | body = json.dumps({'start': {}})
|
286 | ab756200 | Giorgos Verigakis | self.http_post(path, body)
|
287 | ab756200 | Giorgos Verigakis | |
288 | ab756200 | Giorgos Verigakis | |
289 | ab756200 | Giorgos Verigakis | @command_name('shutdown') |
290 | ab756200 | Giorgos Verigakis | class StartServer(Command): |
291 | ab756200 | Giorgos Verigakis | description = 'shutdown server'
|
292 | ab756200 | Giorgos Verigakis | syntax = '<server id>'
|
293 | 38d247df | Kostas Papadimitriou | |
294 | ab756200 | Giorgos Verigakis | def execute(self, server_id): |
295 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d/action' % int(server_id) |
296 | ab756200 | Giorgos Verigakis | body = json.dumps({'shutdown': {}})
|
297 | ab756200 | Giorgos Verigakis | self.http_post(path, body)
|
298 | ab756200 | Giorgos Verigakis | |
299 | ab756200 | Giorgos Verigakis | |
300 | 09471611 | Vangelis Koukis | @command_name('console') |
301 | 09471611 | Vangelis Koukis | class ServerConsole(Command): |
302 | 09471611 | Vangelis Koukis | description = 'get VNC console'
|
303 | 09471611 | Vangelis Koukis | syntax = '<server id>'
|
304 | 38d247df | Kostas Papadimitriou | |
305 | 09471611 | Vangelis Koukis | def execute(self, server_id): |
306 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d/action' % int(server_id) |
307 | 529178b1 | Giorgos Verigakis | body = json.dumps({'console': {'type': 'vnc'}}) |
308 | 4cf8adf8 | Vangelis Koukis | reply = self.http_cmd('POST', path, body, 200) |
309 | 529178b1 | Giorgos Verigakis | print_dict(reply['console'])
|
310 | 09471611 | Vangelis Koukis | |
311 | 09471611 | Vangelis Koukis | |
312 | 91826390 | Giorgos Verigakis | @command_name('profile') |
313 | 91826390 | Giorgos Verigakis | class SetFirewallProfile(Command): |
314 | 91826390 | Giorgos Verigakis | description = 'set the firewall profile'
|
315 | 91826390 | Giorgos Verigakis | syntax = '<server id> <profile>'
|
316 | 38d247df | Kostas Papadimitriou | |
317 | 91826390 | Giorgos Verigakis | def execute(self, server_id, profile): |
318 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d/action' % int(server_id) |
319 | 91826390 | Giorgos Verigakis | body = json.dumps({'firewallProfile': {'profile': profile}}) |
320 | 91826390 | Giorgos Verigakis | self.http_cmd('POST', path, body, 202) |
321 | 91826390 | Giorgos Verigakis | |
322 | 91826390 | Giorgos Verigakis | |
323 | ab756200 | Giorgos Verigakis | @command_name('lsaddr') |
324 | ab756200 | Giorgos Verigakis | class ListAddresses(Command): |
325 | ab756200 | Giorgos Verigakis | description = 'list server addresses'
|
326 | ab756200 | Giorgos Verigakis | syntax = '<server id> [network]'
|
327 | 38d247df | Kostas Papadimitriou | |
328 | ab756200 | Giorgos Verigakis | def execute(self, server_id, network=None): |
329 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d/ips' % int(server_id) |
330 | ab756200 | Giorgos Verigakis | if network:
|
331 | ab756200 | Giorgos Verigakis | path += '/%s' % network
|
332 | ab756200 | Giorgos Verigakis | reply = self.http_get(path)
|
333 | 38d247df | Kostas Papadimitriou | |
334 | ab756200 | Giorgos Verigakis | addresses = [reply['network']] if network else reply['addresses']['values'] |
335 | d44c236b | Giorgos Verigakis | print_addresses(addresses) |
336 | ab756200 | Giorgos Verigakis | |
337 | ab756200 | Giorgos Verigakis | |
338 | ab756200 | Giorgos Verigakis | @command_name('lsflv') |
339 | ab756200 | Giorgos Verigakis | class ListFlavors(Command): |
340 | ab756200 | Giorgos Verigakis | description = 'list flavors'
|
341 | 38d247df | Kostas Papadimitriou | |
342 | ab756200 | Giorgos Verigakis | def add_options(self, parser): |
343 | ab756200 | Giorgos Verigakis | parser.add_option('-l', action='store_true', dest='detail', default=False, |
344 | ab756200 | Giorgos Verigakis | help='show detailed output')
|
345 | 38d247df | Kostas Papadimitriou | |
346 | ab756200 | Giorgos Verigakis | def execute(self): |
347 | fe29fb25 | Giorgos Verigakis | path = '/flavors/detail' if self.detail else '/flavors' |
348 | ab756200 | Giorgos Verigakis | reply = self.http_get(path)
|
349 | 38d247df | Kostas Papadimitriou | |
350 | ab756200 | Giorgos Verigakis | for flavor in reply['flavors']['values']: |
351 | ab756200 | Giorgos Verigakis | id = flavor.pop('id')
|
352 | ab756200 | Giorgos Verigakis | name = flavor.pop('name')
|
353 | ab756200 | Giorgos Verigakis | details = ' '.join('%s=%s' % item for item in sorted(flavor.items())) |
354 | ab756200 | Giorgos Verigakis | print '%3d %s %s' % (id, name, details) |
355 | ab756200 | Giorgos Verigakis | |
356 | ab756200 | Giorgos Verigakis | |
357 | d8e50a39 | Giorgos Verigakis | @command_name('flvinfo') |
358 | ab756200 | Giorgos Verigakis | class GetFlavorDetails(Command): |
359 | ab756200 | Giorgos Verigakis | description = 'get flavor details'
|
360 | ab756200 | Giorgos Verigakis | syntax = '<flavor id>'
|
361 | 38d247df | Kostas Papadimitriou | |
362 | ab756200 | Giorgos Verigakis | def execute(self, flavor_id): |
363 | fe29fb25 | Giorgos Verigakis | path = '/flavors/%d' % int(flavor_id) |
364 | ab756200 | Giorgos Verigakis | reply = self.http_get(path)
|
365 | 38d247df | Kostas Papadimitriou | |
366 | ab756200 | Giorgos Verigakis | flavor = reply['flavor']
|
367 | ab756200 | Giorgos Verigakis | id = flavor.pop('id')
|
368 | ab756200 | Giorgos Verigakis | name = flavor.pop('name')
|
369 | ab756200 | Giorgos Verigakis | details = ' '.join('%s=%s' % item for item in sorted(flavor.items())) |
370 | ab756200 | Giorgos Verigakis | print '%3d %s %s' % (id, name, details) |
371 | ab756200 | Giorgos Verigakis | |
372 | ab756200 | Giorgos Verigakis | |
373 | ab756200 | Giorgos Verigakis | @command_name('lsimg') |
374 | ab756200 | Giorgos Verigakis | class ListImages(Command): |
375 | ab756200 | Giorgos Verigakis | description = 'list images'
|
376 | 38d247df | Kostas Papadimitriou | |
377 | ab756200 | Giorgos Verigakis | def add_options(self, parser): |
378 | ab756200 | Giorgos Verigakis | parser.add_option('-l', action='store_true', dest='detail', default=False, |
379 | ab756200 | Giorgos Verigakis | help='show detailed output')
|
380 | 38d247df | Kostas Papadimitriou | |
381 | ab756200 | Giorgos Verigakis | def execute(self): |
382 | fe29fb25 | Giorgos Verigakis | path = '/images/detail' if self.detail else '/images' |
383 | ab756200 | Giorgos Verigakis | reply = self.http_get(path)
|
384 | 38d247df | Kostas Papadimitriou | |
385 | ab756200 | Giorgos Verigakis | for image in reply['images']['values']: |
386 | ab756200 | Giorgos Verigakis | id = image.pop('id')
|
387 | ab756200 | Giorgos Verigakis | name = image.pop('name')
|
388 | ab756200 | Giorgos Verigakis | if self.detail: |
389 | ab756200 | Giorgos Verigakis | print '%d %s' % (id, name) |
390 | ab756200 | Giorgos Verigakis | print_dict(image) |
391 | ab756200 | Giorgos Verigakis | print
|
392 | ab756200 | Giorgos Verigakis | else:
|
393 | b19653d1 | Giorgos Verigakis | print '%3d %s' % (id, name) |
394 | ab756200 | Giorgos Verigakis | |
395 | ab756200 | Giorgos Verigakis | |
396 | ab756200 | Giorgos Verigakis | @command_name('imginfo') |
397 | ab756200 | Giorgos Verigakis | class GetImageDetails(Command): |
398 | ab756200 | Giorgos Verigakis | description = 'get image details'
|
399 | ab756200 | Giorgos Verigakis | syntax = '<image id>'
|
400 | 38d247df | Kostas Papadimitriou | |
401 | ab756200 | Giorgos Verigakis | def execute(self, image_id): |
402 | fe29fb25 | Giorgos Verigakis | path = '/images/%d' % int(image_id) |
403 | ab756200 | Giorgos Verigakis | reply = self.http_get(path)
|
404 | ab756200 | Giorgos Verigakis | image = reply['image']
|
405 | ab756200 | Giorgos Verigakis | image.pop('id')
|
406 | ab756200 | Giorgos Verigakis | print_dict(image) |
407 | ab756200 | Giorgos Verigakis | |
408 | ab756200 | Giorgos Verigakis | |
409 | ab756200 | Giorgos Verigakis | @command_name('createimg') |
410 | ab756200 | Giorgos Verigakis | class CreateImage(Command): |
411 | ab756200 | Giorgos Verigakis | description = 'create image'
|
412 | ab756200 | Giorgos Verigakis | syntax = '<server id> <image name>'
|
413 | 38d247df | Kostas Papadimitriou | |
414 | ab756200 | Giorgos Verigakis | def execute(self, server_id, name): |
415 | ab756200 | Giorgos Verigakis | image = {'name': name, 'serverRef': int(server_id)} |
416 | ab756200 | Giorgos Verigakis | body = json.dumps({'image': image})
|
417 | fe29fb25 | Giorgos Verigakis | reply = self.http_post('/images', body) |
418 | ab756200 | Giorgos Verigakis | print_dict(reply['image'])
|
419 | ab756200 | Giorgos Verigakis | |
420 | ab756200 | Giorgos Verigakis | @command_name('deleteimg') |
421 | ab756200 | Giorgos Verigakis | class DeleteImage(Command): |
422 | ab756200 | Giorgos Verigakis | description = 'delete image'
|
423 | ab756200 | Giorgos Verigakis | syntax = '<image id>'
|
424 | 38d247df | Kostas Papadimitriou | |
425 | ab756200 | Giorgos Verigakis | def execute(self, image_id): |
426 | fe29fb25 | Giorgos Verigakis | path = '/images/%d' % int(image_id) |
427 | ab756200 | Giorgos Verigakis | self.http_delete(path)
|
428 | ab756200 | Giorgos Verigakis | |
429 | d8e50a39 | Giorgos Verigakis | @command_name('lsmeta') |
430 | d8e50a39 | Giorgos Verigakis | class ListServerMeta(Command): |
431 | d8e50a39 | Giorgos Verigakis | description = 'list server meta'
|
432 | d8e50a39 | Giorgos Verigakis | syntax = '<server id> [key]'
|
433 | d8e50a39 | Giorgos Verigakis | |
434 | d8e50a39 | Giorgos Verigakis | def execute(self, server_id, key=None): |
435 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d/meta' % int(server_id) |
436 | d8e50a39 | Giorgos Verigakis | if key:
|
437 | d8e50a39 | Giorgos Verigakis | path += '/' + key
|
438 | d8e50a39 | Giorgos Verigakis | reply = self.http_get(path)
|
439 | d8e50a39 | Giorgos Verigakis | if key:
|
440 | d8e50a39 | Giorgos Verigakis | print_dict(reply['meta'])
|
441 | d8e50a39 | Giorgos Verigakis | else:
|
442 | d8e50a39 | Giorgos Verigakis | print_dict(reply['metadata']['values']) |
443 | d8e50a39 | Giorgos Verigakis | |
444 | d8e50a39 | Giorgos Verigakis | @command_name('setmeta') |
445 | d8e50a39 | Giorgos Verigakis | class UpdateServerMeta(Command): |
446 | d8e50a39 | Giorgos Verigakis | description = 'update server meta'
|
447 | d8e50a39 | Giorgos Verigakis | syntax = '<server id> <key> <val>'
|
448 | d8e50a39 | Giorgos Verigakis | |
449 | d8e50a39 | Giorgos Verigakis | def execute(self, server_id, key, val): |
450 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d/meta' % int(server_id) |
451 | d8e50a39 | Giorgos Verigakis | metadata = {key: val} |
452 | d8e50a39 | Giorgos Verigakis | body = json.dumps({'metadata': metadata})
|
453 | d8e50a39 | Giorgos Verigakis | reply = self.http_post(path, body, expected_status=201) |
454 | d8e50a39 | Giorgos Verigakis | print_dict(reply['metadata'])
|
455 | d8e50a39 | Giorgos Verigakis | |
456 | d8e50a39 | Giorgos Verigakis | @command_name('addmeta') |
457 | d8e50a39 | Giorgos Verigakis | class CreateServerMeta(Command): |
458 | d8e50a39 | Giorgos Verigakis | description = 'add server meta'
|
459 | d8e50a39 | Giorgos Verigakis | syntax = '<server id> <key> <val>'
|
460 | d8e50a39 | Giorgos Verigakis | |
461 | d8e50a39 | Giorgos Verigakis | def execute(self, server_id, key, val): |
462 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d/meta/%s' % (int(server_id), key) |
463 | d8e50a39 | Giorgos Verigakis | meta = {key: val} |
464 | d8e50a39 | Giorgos Verigakis | body = json.dumps({'meta': meta})
|
465 | d8e50a39 | Giorgos Verigakis | reply = self.http_put(path, body, expected_status=201) |
466 | d8e50a39 | Giorgos Verigakis | print_dict(reply['meta'])
|
467 | d8e50a39 | Giorgos Verigakis | |
468 | d8e50a39 | Giorgos Verigakis | @command_name('delmeta') |
469 | d8e50a39 | Giorgos Verigakis | class DeleteServerMeta(Command): |
470 | d8e50a39 | Giorgos Verigakis | description = 'delete server meta'
|
471 | d8e50a39 | Giorgos Verigakis | syntax = '<server id> <key>'
|
472 | d8e50a39 | Giorgos Verigakis | |
473 | d8e50a39 | Giorgos Verigakis | def execute(self, server_id, key): |
474 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d/meta/%s' % (int(server_id), key) |
475 | d8e50a39 | Giorgos Verigakis | reply = self.http_delete(path)
|
476 | d8e50a39 | Giorgos Verigakis | |
477 | 432fc8c3 | Giorgos Verigakis | @command_name('lsimgmeta') |
478 | 432fc8c3 | Giorgos Verigakis | class ListImageMeta(Command): |
479 | 432fc8c3 | Giorgos Verigakis | description = 'list image meta'
|
480 | 432fc8c3 | Giorgos Verigakis | syntax = '<image id> [key]'
|
481 | 432fc8c3 | Giorgos Verigakis | |
482 | 432fc8c3 | Giorgos Verigakis | def execute(self, image_id, key=None): |
483 | fe29fb25 | Giorgos Verigakis | path = '/images/%d/meta' % int(image_id) |
484 | 432fc8c3 | Giorgos Verigakis | if key:
|
485 | 432fc8c3 | Giorgos Verigakis | path += '/' + key
|
486 | 432fc8c3 | Giorgos Verigakis | reply = self.http_get(path)
|
487 | 432fc8c3 | Giorgos Verigakis | if key:
|
488 | 432fc8c3 | Giorgos Verigakis | print_dict(reply['meta'])
|
489 | 432fc8c3 | Giorgos Verigakis | else:
|
490 | 432fc8c3 | Giorgos Verigakis | print_dict(reply['metadata']['values']) |
491 | 432fc8c3 | Giorgos Verigakis | |
492 | 432fc8c3 | Giorgos Verigakis | @command_name('setimgmeta') |
493 | 432fc8c3 | Giorgos Verigakis | class UpdateImageMeta(Command): |
494 | 432fc8c3 | Giorgos Verigakis | description = 'update image meta'
|
495 | 432fc8c3 | Giorgos Verigakis | syntax = '<image id> <key> <val>'
|
496 | 432fc8c3 | Giorgos Verigakis | |
497 | 432fc8c3 | Giorgos Verigakis | def execute(self, image_id, key, val): |
498 | fe29fb25 | Giorgos Verigakis | path = '/images/%d/meta' % int(image_id) |
499 | 432fc8c3 | Giorgos Verigakis | metadata = {key: val} |
500 | 432fc8c3 | Giorgos Verigakis | body = json.dumps({'metadata': metadata})
|
501 | 432fc8c3 | Giorgos Verigakis | reply = self.http_post(path, body, expected_status=201) |
502 | 432fc8c3 | Giorgos Verigakis | print_dict(reply['metadata'])
|
503 | 432fc8c3 | Giorgos Verigakis | |
504 | 432fc8c3 | Giorgos Verigakis | @command_name('addimgmeta') |
505 | 432fc8c3 | Giorgos Verigakis | class CreateImageMeta(Command): |
506 | 432fc8c3 | Giorgos Verigakis | description = 'add image meta'
|
507 | 432fc8c3 | Giorgos Verigakis | syntax = '<image id> <key> <val>'
|
508 | 432fc8c3 | Giorgos Verigakis | |
509 | 432fc8c3 | Giorgos Verigakis | def execute(self, image_id, key, val): |
510 | fe29fb25 | Giorgos Verigakis | path = '/images/%d/meta/%s' % (int(image_id), key) |
511 | 432fc8c3 | Giorgos Verigakis | meta = {key: val} |
512 | 432fc8c3 | Giorgos Verigakis | body = json.dumps({'meta': meta})
|
513 | 432fc8c3 | Giorgos Verigakis | reply = self.http_put(path, body, expected_status=201) |
514 | 432fc8c3 | Giorgos Verigakis | print_dict(reply['meta'])
|
515 | 432fc8c3 | Giorgos Verigakis | |
516 | 432fc8c3 | Giorgos Verigakis | @command_name('delimgmeta') |
517 | 432fc8c3 | Giorgos Verigakis | class DeleteImageMeta(Command): |
518 | 432fc8c3 | Giorgos Verigakis | description = 'delete image meta'
|
519 | 432fc8c3 | Giorgos Verigakis | syntax = '<image id> <key>'
|
520 | 432fc8c3 | Giorgos Verigakis | |
521 | 432fc8c3 | Giorgos Verigakis | def execute(self, image_id, key): |
522 | fe29fb25 | Giorgos Verigakis | path = '/images/%d/meta/%s' % (int(image_id), key) |
523 | 432fc8c3 | Giorgos Verigakis | reply = self.http_delete(path)
|
524 | 432fc8c3 | Giorgos Verigakis | |
525 | ab756200 | Giorgos Verigakis | |
526 | 0269afd6 | Giorgos Verigakis | @command_name('lsnet') |
527 | 0269afd6 | Giorgos Verigakis | class ListNetworks(Command): |
528 | 0269afd6 | Giorgos Verigakis | description = 'list networks'
|
529 | 0269afd6 | Giorgos Verigakis | |
530 | 0269afd6 | Giorgos Verigakis | def add_options(self, parser): |
531 | 0269afd6 | Giorgos Verigakis | parser.add_option('-l', action='store_true', dest='detail', default=False, |
532 | 0269afd6 | Giorgos Verigakis | help='show detailed output')
|
533 | 0269afd6 | Giorgos Verigakis | |
534 | 0269afd6 | Giorgos Verigakis | def execute(self): |
535 | fe29fb25 | Giorgos Verigakis | path = '/networks/detail' if self.detail else '/networks' |
536 | 0269afd6 | Giorgos Verigakis | reply = self.http_get(path)
|
537 | 0269afd6 | Giorgos Verigakis | |
538 | 0269afd6 | Giorgos Verigakis | for network in reply['networks']['values']: |
539 | b19653d1 | Giorgos Verigakis | id = network.pop('id')
|
540 | 0269afd6 | Giorgos Verigakis | name = network.pop('name')
|
541 | 0269afd6 | Giorgos Verigakis | if self.detail: |
542 | f7ace0a4 | Giorgos Verigakis | print '%s %s' % (id, name) |
543 | b19653d1 | Giorgos Verigakis | print_dict(network) |
544 | b19653d1 | Giorgos Verigakis | print
|
545 | 0269afd6 | Giorgos Verigakis | else:
|
546 | f7ace0a4 | Giorgos Verigakis | print '%3s %s' % (id, name) |
547 | 0269afd6 | Giorgos Verigakis | |
548 | 0269afd6 | Giorgos Verigakis | |
549 | 0269afd6 | Giorgos Verigakis | @command_name('createnet') |
550 | 0269afd6 | Giorgos Verigakis | class CreateNetwork(Command): |
551 | 0269afd6 | Giorgos Verigakis | description = 'create network'
|
552 | 0269afd6 | Giorgos Verigakis | syntax = '<network name>'
|
553 | 0269afd6 | Giorgos Verigakis | |
554 | 0269afd6 | Giorgos Verigakis | def execute(self, name): |
555 | 0269afd6 | Giorgos Verigakis | network = {'name': name}
|
556 | 0269afd6 | Giorgos Verigakis | body = json.dumps({'network': network})
|
557 | fe29fb25 | Giorgos Verigakis | reply = self.http_post('/networks', body) |
558 | 0269afd6 | Giorgos Verigakis | print_dict(reply['network'])
|
559 | 0269afd6 | Giorgos Verigakis | |
560 | 0269afd6 | Giorgos Verigakis | |
561 | 0269afd6 | Giorgos Verigakis | @command_name('netinfo') |
562 | 0269afd6 | Giorgos Verigakis | class GetNetworkDetails(Command): |
563 | 0269afd6 | Giorgos Verigakis | description = 'get network details'
|
564 | b19653d1 | Giorgos Verigakis | syntax = '<network id>'
|
565 | 0269afd6 | Giorgos Verigakis | |
566 | b19653d1 | Giorgos Verigakis | def execute(self, network_id): |
567 | fe29fb25 | Giorgos Verigakis | path = '/networks/%d' % int(network_id) |
568 | 0269afd6 | Giorgos Verigakis | reply = self.http_get(path)
|
569 | 0269afd6 | Giorgos Verigakis | net = reply['network']
|
570 | b19653d1 | Giorgos Verigakis | name = net.pop('id')
|
571 | 0269afd6 | Giorgos Verigakis | print_dict(net) |
572 | 0269afd6 | Giorgos Verigakis | |
573 | 0269afd6 | Giorgos Verigakis | |
574 | 0269afd6 | Giorgos Verigakis | @command_name('renamenet') |
575 | 0269afd6 | Giorgos Verigakis | class UpdateNetworkName(Command): |
576 | 0269afd6 | Giorgos Verigakis | description = 'update network name'
|
577 | b19653d1 | Giorgos Verigakis | syntax = '<network_id> <new name>'
|
578 | 0269afd6 | Giorgos Verigakis | |
579 | b19653d1 | Giorgos Verigakis | def execute(self, network_id, name): |
580 | fe29fb25 | Giorgos Verigakis | path = '/networks/%d' % int(network_id) |
581 | 0269afd6 | Giorgos Verigakis | body = json.dumps({'network': {'name': name}}) |
582 | 0269afd6 | Giorgos Verigakis | self.http_put(path, body)
|
583 | 0269afd6 | Giorgos Verigakis | |
584 | 0269afd6 | Giorgos Verigakis | |
585 | 0269afd6 | Giorgos Verigakis | @command_name('deletenet') |
586 | 0269afd6 | Giorgos Verigakis | class DeleteNetwork(Command): |
587 | 0269afd6 | Giorgos Verigakis | description = 'delete network'
|
588 | b19653d1 | Giorgos Verigakis | syntax = '<network id>'
|
589 | 0269afd6 | Giorgos Verigakis | |
590 | b19653d1 | Giorgos Verigakis | def execute(self, network_id): |
591 | fe29fb25 | Giorgos Verigakis | path = '/networks/%d' % int(network_id) |
592 | 0269afd6 | Giorgos Verigakis | self.http_delete(path)
|
593 | 0269afd6 | Giorgos Verigakis | |
594 | 0269afd6 | Giorgos Verigakis | |
595 | f7ace0a4 | Giorgos Verigakis | @command_name('connect') |
596 | 0269afd6 | Giorgos Verigakis | class AddNetwork(Command): |
597 | f7ace0a4 | Giorgos Verigakis | description = 'connect a server to a network'
|
598 | b19653d1 | Giorgos Verigakis | syntax = '<server id> <network id>'
|
599 | 0269afd6 | Giorgos Verigakis | |
600 | b19653d1 | Giorgos Verigakis | def execute(self, server_id, network_id): |
601 | fe29fb25 | Giorgos Verigakis | path = '/networks/%d/action' % int(network_id) |
602 | dca6520b | Giorgos Verigakis | body = json.dumps({'add': {'serverRef': server_id}}) |
603 | 0269afd6 | Giorgos Verigakis | self.http_post(path, body, expected_status=202) |
604 | 0269afd6 | Giorgos Verigakis | |
605 | 0269afd6 | Giorgos Verigakis | |
606 | f7ace0a4 | Giorgos Verigakis | @command_name('disconnect') |
607 | 0269afd6 | Giorgos Verigakis | class RemoveNetwork(Command): |
608 | f7ace0a4 | Giorgos Verigakis | description = 'disconnect a server from a network'
|
609 | b19653d1 | Giorgos Verigakis | syntax = '<server id> <network id>'
|
610 | 0269afd6 | Giorgos Verigakis | |
611 | b19653d1 | Giorgos Verigakis | def execute(self, server_id, network_id): |
612 | fe29fb25 | Giorgos Verigakis | path = '/networks/%s/action' % int(network_id) |
613 | dca6520b | Giorgos Verigakis | body = json.dumps({'remove': {'serverRef': server_id}}) |
614 | 0269afd6 | Giorgos Verigakis | self.http_post(path, body, expected_status=202) |
615 | 0269afd6 | Giorgos Verigakis | |
616 | 334c1b75 | Giorgos Verigakis | @command_name('stats') |
617 | 334c1b75 | Giorgos Verigakis | class ServerStats(Command): |
618 | 334c1b75 | Giorgos Verigakis | description = 'get server stats'
|
619 | 334c1b75 | Giorgos Verigakis | syntax = '<server id>'
|
620 | 334c1b75 | Giorgos Verigakis | |
621 | 334c1b75 | Giorgos Verigakis | def execute(self, server_id): |
622 | fe29fb25 | Giorgos Verigakis | path = '/servers/%d/stats' % int(server_id) |
623 | 334c1b75 | Giorgos Verigakis | reply = self.http_get(path)
|
624 | 334c1b75 | Giorgos Verigakis | stats = reply['stats']
|
625 | 334c1b75 | Giorgos Verigakis | stats.pop('serverRef')
|
626 | 334c1b75 | Giorgos Verigakis | print_dict(stats) |
627 | 334c1b75 | Giorgos Verigakis | |
628 | 0269afd6 | Giorgos Verigakis | |
629 | faae285d | Giorgos Verigakis | def print_usage(): |
630 | faae285d | Giorgos Verigakis | print 'Usage: %s <command>' % basename(argv[0]) |
631 | faae285d | Giorgos Verigakis | print
|
632 | faae285d | Giorgos Verigakis | print 'Commands:' |
633 | faae285d | Giorgos Verigakis | for name, cls in sorted(commands.items()): |
634 | faae285d | Giorgos Verigakis | description = getattr(cls, 'description', '') |
635 | faae285d | Giorgos Verigakis | print ' %s %s' % (name.ljust(12), description) |
636 | faae285d | Giorgos Verigakis | |
637 | ab756200 | Giorgos Verigakis | def main(): |
638 | ab756200 | Giorgos Verigakis | try:
|
639 | 38d247df | Kostas Papadimitriou | name = argv[1]
|
640 | ab756200 | Giorgos Verigakis | cls = commands[name] |
641 | ab756200 | Giorgos Verigakis | except (IndexError, KeyError): |
642 | faae285d | Giorgos Verigakis | print_usage() |
643 | ab756200 | Giorgos Verigakis | exit(1) |
644 | 38d247df | Kostas Papadimitriou | |
645 | ab756200 | Giorgos Verigakis | try:
|
646 | faae285d | Giorgos Verigakis | cls(argv[2:])
|
647 | ab756200 | Giorgos Verigakis | except TypeError: |
648 | ab756200 | Giorgos Verigakis | syntax = getattr(cls, 'syntax', '') |
649 | ab756200 | Giorgos Verigakis | if syntax:
|
650 | ab756200 | Giorgos Verigakis | print 'Syntax: %s %s' % (name, syntax) |
651 | ab756200 | Giorgos Verigakis | else:
|
652 | ab756200 | Giorgos Verigakis | print 'Invalid syntax' |
653 | ab756200 | Giorgos Verigakis | exit(1) |
654 | ab756200 | Giorgos Verigakis | |
655 | ab756200 | Giorgos Verigakis | |
656 | ab756200 | Giorgos Verigakis | if __name__ == '__main__': |
657 | ab756200 | Giorgos Verigakis | main() |