Statistics
| Branch: | Tag: | Revision:

root / tools / cloud @ 432fc8c3

History | View | Annotate | Download (14.6 kB)

1 ab756200 Giorgos Verigakis
#!/usr/bin/env python
2 ab756200 Giorgos Verigakis
3 ab756200 Giorgos Verigakis
from functools import wraps
4 ab756200 Giorgos Verigakis
from httplib import HTTPConnection
5 ab756200 Giorgos Verigakis
from optparse import OptionParser
6 ab756200 Giorgos Verigakis
from os.path import basename
7 ab756200 Giorgos Verigakis
from sys import argv, exit
8 ab756200 Giorgos Verigakis
9 ab756200 Giorgos Verigakis
import json
10 ab756200 Giorgos Verigakis
11 ab756200 Giorgos Verigakis
DEFAULT_HOST = '127.0.0.1:8000'
12 d8e50a39 Giorgos Verigakis
DEFAULT_API = 'v1.1'
13 ab756200 Giorgos Verigakis
14 ab756200 Giorgos Verigakis
15 ab756200 Giorgos Verigakis
commands = {}
16 ab756200 Giorgos Verigakis
17 ab756200 Giorgos Verigakis
def command_name(name):
18 ab756200 Giorgos Verigakis
    def decorator(cls):
19 ab756200 Giorgos Verigakis
        commands[name] = cls
20 ab756200 Giorgos Verigakis
        return cls
21 ab756200 Giorgos Verigakis
    return decorator
22 ab756200 Giorgos Verigakis
23 ab756200 Giorgos Verigakis
24 ab756200 Giorgos Verigakis
def address_to_string(address):
25 ab756200 Giorgos Verigakis
    key = address['id']
26 ab756200 Giorgos Verigakis
    val = ' '.join(ip['addr'] for ip in address['values'])
27 ab756200 Giorgos Verigakis
    return '%s: %s' % (key, val)
28 ab756200 Giorgos Verigakis
29 ab756200 Giorgos Verigakis
def print_dict(d, show_empty=True):
30 ab756200 Giorgos Verigakis
    for key, val in sorted(d.items()):
31 ab756200 Giorgos Verigakis
        if key == 'metadata':
32 ab756200 Giorgos Verigakis
            val = ', '.join('%s="%s"' % x for x in val['values'].items())
33 ab756200 Giorgos Verigakis
        if key == 'addresses':
34 ab756200 Giorgos Verigakis
            val = ', '.join(address_to_string(address) for address in val['values'])
35 ab756200 Giorgos Verigakis
        if val or show_empty:
36 ab756200 Giorgos Verigakis
            print '%s: %s' % (key.rjust(12), val)
37 ab756200 Giorgos Verigakis
38 ab756200 Giorgos Verigakis
39 ab756200 Giorgos Verigakis
class Command(object):
40 ab756200 Giorgos Verigakis
    def __init__(self, argv):
41 ab756200 Giorgos Verigakis
        parser = OptionParser()
42 ab756200 Giorgos Verigakis
        parser.add_option('--host', dest='host', metavar='HOST', default=DEFAULT_HOST,
43 ab756200 Giorgos Verigakis
                            help='use server HOST')
44 ab756200 Giorgos Verigakis
        parser.add_option('--api', dest='api', metavar='API', default=DEFAULT_API,
45 ab756200 Giorgos Verigakis
                            help='use api API')
46 ab756200 Giorgos Verigakis
        parser.add_option('-v', action='store_true', dest='verbose', default=False,
47 ab756200 Giorgos Verigakis
                            help='use verbose output')
48 ab756200 Giorgos Verigakis
        self.add_options(parser)
49 ab756200 Giorgos Verigakis
        options, args = parser.parse_args(argv)
50 ab756200 Giorgos Verigakis
        
51 ab756200 Giorgos Verigakis
        # Add options to self
52 ab756200 Giorgos Verigakis
        for opt in parser.option_list:
53 ab756200 Giorgos Verigakis
            key = opt.dest
54 ab756200 Giorgos Verigakis
            if key:
55 ab756200 Giorgos Verigakis
                val = getattr(options, key)
56 ab756200 Giorgos Verigakis
                setattr(self, key, val)
57 ab756200 Giorgos Verigakis
        
58 ab756200 Giorgos Verigakis
        self.execute(*args)
59 ab756200 Giorgos Verigakis
    
60 ab756200 Giorgos Verigakis
    def add_options(self, parser):
61 ab756200 Giorgos Verigakis
        pass
62 ab756200 Giorgos Verigakis
    
63 ab756200 Giorgos Verigakis
    def execute(self, *args):
64 ab756200 Giorgos Verigakis
        pass
65 ab756200 Giorgos Verigakis
    
66 ab756200 Giorgos Verigakis
    def http_cmd(self, method, path, body=None, expected_status=200):
67 ab756200 Giorgos Verigakis
        conn = HTTPConnection(self.host)
68 ab756200 Giorgos Verigakis
69 ab756200 Giorgos Verigakis
        kwargs = {}
70 ab756200 Giorgos Verigakis
        if body:
71 ab756200 Giorgos Verigakis
            kwargs['headers'] = {'Content-Type': 'application/json'}
72 ab756200 Giorgos Verigakis
            kwargs['body'] = body
73 ab756200 Giorgos Verigakis
        conn.request(method, path, **kwargs)
74 ab756200 Giorgos Verigakis
75 ab756200 Giorgos Verigakis
        resp = conn.getresponse()
76 ab756200 Giorgos Verigakis
        if self.verbose:
77 ab756200 Giorgos Verigakis
            print '%d %s' % (resp.status, resp.reason)
78 ab756200 Giorgos Verigakis
            for key, val in resp.getheaders():
79 ab756200 Giorgos Verigakis
                print '%s: %s' % (key.capitalize(), val)
80 ab756200 Giorgos Verigakis
            print
81 ab756200 Giorgos Verigakis
82 ab756200 Giorgos Verigakis
        buf = resp.read() or '{}'
83 ab756200 Giorgos Verigakis
        reply = json.loads(buf)
84 ab756200 Giorgos Verigakis
85 ab756200 Giorgos Verigakis
        if resp.status != expected_status:
86 ab756200 Giorgos Verigakis
            if len(reply) == 1:
87 ab756200 Giorgos Verigakis
                key = reply.keys()[0]
88 ab756200 Giorgos Verigakis
                val = reply[key]
89 d8e50a39 Giorgos Verigakis
                print '%s: %s' % (key, val.get('message', ''))
90 ab756200 Giorgos Verigakis
                if self.verbose:
91 ab756200 Giorgos Verigakis
                    print val.get('details', '')
92 ab756200 Giorgos Verigakis
                exit(1)
93 ab756200 Giorgos Verigakis
94 ab756200 Giorgos Verigakis
        return reply
95 ab756200 Giorgos Verigakis
96 ab756200 Giorgos Verigakis
    def http_get(self, path, expected_status=200):
97 ab756200 Giorgos Verigakis
        return self.http_cmd('GET', path, None, expected_status)
98 ab756200 Giorgos Verigakis
    
99 ab756200 Giorgos Verigakis
    def http_post(self, path, body, expected_status=202):
100 ab756200 Giorgos Verigakis
        return self.http_cmd('POST', path, body, expected_status)
101 ab756200 Giorgos Verigakis
102 ab756200 Giorgos Verigakis
    def http_put(self, path, body, expected_status=204):
103 ab756200 Giorgos Verigakis
        return self.http_cmd('PUT', path, body, expected_status)
104 ab756200 Giorgos Verigakis
105 ab756200 Giorgos Verigakis
    def http_delete(self, path, expected_status=204):
106 ab756200 Giorgos Verigakis
        return self.http_cmd('DELETE', path, None, expected_status)
107 ab756200 Giorgos Verigakis
108 ab756200 Giorgos Verigakis
109 ab756200 Giorgos Verigakis
@command_name('ls')
110 ab756200 Giorgos Verigakis
class ListServers(Command):
111 ab756200 Giorgos Verigakis
    description = 'list servers'
112 ab756200 Giorgos Verigakis
    
113 ab756200 Giorgos Verigakis
    def add_options(self, parser):
114 ab756200 Giorgos Verigakis
        parser.add_option('-l', action='store_true', dest='detail', default=False,
115 ab756200 Giorgos Verigakis
                            help='show detailed output')
116 ab756200 Giorgos Verigakis
        parser.add_option('-a', action='store_true', dest='show_empty', default=False,
117 ab756200 Giorgos Verigakis
                            help='include empty values')
118 ab756200 Giorgos Verigakis
    
119 ab756200 Giorgos Verigakis
    def execute(self):
120 ab756200 Giorgos Verigakis
        path = '/api/%s/servers' % self.api
121 ab756200 Giorgos Verigakis
        if self.detail:
122 ab756200 Giorgos Verigakis
            path += '/detail'
123 ab756200 Giorgos Verigakis
124 ab756200 Giorgos Verigakis
        reply = self.http_get(path)
125 ab756200 Giorgos Verigakis
126 ab756200 Giorgos Verigakis
        for server in reply['servers']['values']:
127 ab756200 Giorgos Verigakis
            id = server.pop('id')
128 ab756200 Giorgos Verigakis
            name = server.pop('name')
129 ab756200 Giorgos Verigakis
            if self.detail:
130 ab756200 Giorgos Verigakis
                print '%d %s' % (id, name)
131 ab756200 Giorgos Verigakis
                print_dict(server, self.show_empty)
132 ab756200 Giorgos Verigakis
                print
133 ab756200 Giorgos Verigakis
            else:
134 ab756200 Giorgos Verigakis
                print '%3d %s' % (id, name)
135 ab756200 Giorgos Verigakis
136 ab756200 Giorgos Verigakis
137 ab756200 Giorgos Verigakis
@command_name('info')
138 ab756200 Giorgos Verigakis
class GetServerDetails(Command):
139 ab756200 Giorgos Verigakis
    description = 'get server details'
140 ab756200 Giorgos Verigakis
    syntax = '<server id>'
141 ab756200 Giorgos Verigakis
    
142 ab756200 Giorgos Verigakis
    def add_options(self, parser):
143 ab756200 Giorgos Verigakis
        parser.add_option('-a', action='store_true', dest='show_empty', default=False,
144 ab756200 Giorgos Verigakis
                            help='include empty values')
145 ab756200 Giorgos Verigakis
    
146 ab756200 Giorgos Verigakis
    def execute(self, server_id):
147 ab756200 Giorgos Verigakis
        path = '/api/%s/servers/%d' % (self.api, int(server_id))
148 ab756200 Giorgos Verigakis
        reply = self.http_get(path)
149 ab756200 Giorgos Verigakis
        server = reply['server']
150 ab756200 Giorgos Verigakis
        server.pop('id')
151 ab756200 Giorgos Verigakis
        print_dict(server, self.show_empty)
152 ab756200 Giorgos Verigakis
        
153 ab756200 Giorgos Verigakis
154 ab756200 Giorgos Verigakis
@command_name('create')
155 ab756200 Giorgos Verigakis
class CreateServer(Command):
156 ab756200 Giorgos Verigakis
    description = 'create server'
157 ab756200 Giorgos Verigakis
    syntax = '<server name>'
158 ab756200 Giorgos Verigakis
    
159 ab756200 Giorgos Verigakis
    def add_options(self, parser):
160 ab756200 Giorgos Verigakis
        parser.add_option('-f', dest='flavor', metavar='FLAVOR_ID', default=1,
161 ab756200 Giorgos Verigakis
                            help='use flavor FLAVOR_ID')
162 ab756200 Giorgos Verigakis
        parser.add_option('-i', dest='image', metavar='IMAGE_ID', default=1,
163 ab756200 Giorgos Verigakis
                            help='use image IMAGE_ID')
164 ab756200 Giorgos Verigakis
    
165 ab756200 Giorgos Verigakis
    def execute(self, name):
166 ab756200 Giorgos Verigakis
        path = '/api/%s/servers' % self.api
167 ab756200 Giorgos Verigakis
        server = {'name': name, 'flavorRef': self.flavor, 'imageRef': self.image}
168 ab756200 Giorgos Verigakis
        body = json.dumps({'server': server})
169 ab756200 Giorgos Verigakis
        reply = self.http_post(path, body)
170 ab756200 Giorgos Verigakis
        server = reply['server']
171 ab756200 Giorgos Verigakis
        server.pop('id')
172 ab756200 Giorgos Verigakis
        print_dict(server)
173 ab756200 Giorgos Verigakis
174 ab756200 Giorgos Verigakis
175 ab756200 Giorgos Verigakis
@command_name('rename')
176 ab756200 Giorgos Verigakis
class UpdateServerName(Command):
177 ab756200 Giorgos Verigakis
    description = 'update server name'
178 ab756200 Giorgos Verigakis
    syntax = '<server id> <new name>'
179 ab756200 Giorgos Verigakis
    
180 ab756200 Giorgos Verigakis
    def execute(self, server_id, name):
181 ab756200 Giorgos Verigakis
        path = '/api/%s/servers/%d' % (self.api, int(server_id))
182 ab756200 Giorgos Verigakis
        body = json.dumps({'server': {'name': name}})
183 ab756200 Giorgos Verigakis
        self.http_put(path, body)
184 ab756200 Giorgos Verigakis
185 ab756200 Giorgos Verigakis
186 ab756200 Giorgos Verigakis
@command_name('delete')
187 ab756200 Giorgos Verigakis
class DeleteServer(Command):
188 ab756200 Giorgos Verigakis
    description = 'delete server'
189 ab756200 Giorgos Verigakis
    syntax = '<server id>'
190 ab756200 Giorgos Verigakis
    
191 ab756200 Giorgos Verigakis
    def execute(self, server_id):
192 ab756200 Giorgos Verigakis
        path = '/api/%s/servers/%d' % (self.api, int(server_id))
193 ab756200 Giorgos Verigakis
        self.http_delete(path)
194 ab756200 Giorgos Verigakis
195 ab756200 Giorgos Verigakis
196 ab756200 Giorgos Verigakis
@command_name('reboot')
197 ab756200 Giorgos Verigakis
class RebootServer(Command):
198 ab756200 Giorgos Verigakis
    description = 'reboot server'
199 ab756200 Giorgos Verigakis
    syntax = '<server id>'
200 ab756200 Giorgos Verigakis
    
201 ab756200 Giorgos Verigakis
    def add_options(self, parser):
202 ab756200 Giorgos Verigakis
        parser.add_option('-f', action='store_true', dest='hard', default=False,
203 ab756200 Giorgos Verigakis
                            help='perform a hard reboot')
204 ab756200 Giorgos Verigakis
    
205 ab756200 Giorgos Verigakis
    def execute(self, server_id):
206 ab756200 Giorgos Verigakis
        path = '/api/%s/servers/%d/action' % (self.api, int(server_id))
207 ab756200 Giorgos Verigakis
        type = 'HARD' if self.hard else 'SOFT'
208 ab756200 Giorgos Verigakis
        body = json.dumps({'reboot': {'type': type}})
209 ab756200 Giorgos Verigakis
        self.http_post(path, body)
210 ab756200 Giorgos Verigakis
    
211 ab756200 Giorgos Verigakis
212 ab756200 Giorgos Verigakis
@command_name('start')
213 ab756200 Giorgos Verigakis
class StartServer(Command):
214 ab756200 Giorgos Verigakis
    description = 'start server'
215 ab756200 Giorgos Verigakis
    syntax = '<server id>'
216 ab756200 Giorgos Verigakis
    
217 ab756200 Giorgos Verigakis
    def execute(self, server_id):
218 ab756200 Giorgos Verigakis
        path = '/api/%s/servers/%d/action' % (self.api, int(server_id))
219 ab756200 Giorgos Verigakis
        body = json.dumps({'start': {}})
220 ab756200 Giorgos Verigakis
        self.http_post(path, body)
221 ab756200 Giorgos Verigakis
222 ab756200 Giorgos Verigakis
223 ab756200 Giorgos Verigakis
@command_name('shutdown')
224 ab756200 Giorgos Verigakis
class StartServer(Command):
225 ab756200 Giorgos Verigakis
    description = 'shutdown server'
226 ab756200 Giorgos Verigakis
    syntax = '<server id>'
227 ab756200 Giorgos Verigakis
    
228 ab756200 Giorgos Verigakis
    def execute(self, server_id):
229 ab756200 Giorgos Verigakis
        path = '/api/%s/servers/%d/action' % (self.api, int(server_id))
230 ab756200 Giorgos Verigakis
        body = json.dumps({'shutdown': {}})
231 ab756200 Giorgos Verigakis
        self.http_post(path, body)
232 ab756200 Giorgos Verigakis
233 ab756200 Giorgos Verigakis
234 09471611 Vangelis Koukis
@command_name('console')
235 09471611 Vangelis Koukis
class ServerConsole(Command):
236 09471611 Vangelis Koukis
    description = 'get VNC console'
237 09471611 Vangelis Koukis
    syntax = '<server id>'
238 09471611 Vangelis Koukis
    
239 09471611 Vangelis Koukis
    def add_options(self, parser):
240 09471611 Vangelis Koukis
    	pass
241 09471611 Vangelis Koukis
    
242 09471611 Vangelis Koukis
    def execute(self, server_id):
243 09471611 Vangelis Koukis
        path = '/api/%s/servers/%d/action' % (self.api, int(server_id))
244 09471611 Vangelis Koukis
        body = json.dumps({'console':{'type':'VNC'}})
245 09471611 Vangelis Koukis
        reply = self.http_post(path, body)
246 09471611 Vangelis Koukis
        print_dict(reply)
247 09471611 Vangelis Koukis
248 09471611 Vangelis Koukis
249 ab756200 Giorgos Verigakis
@command_name('lsaddr')
250 ab756200 Giorgos Verigakis
class ListAddresses(Command):
251 ab756200 Giorgos Verigakis
    description = 'list server addresses'
252 ab756200 Giorgos Verigakis
    syntax = '<server id> [network]'
253 ab756200 Giorgos Verigakis
    
254 ab756200 Giorgos Verigakis
    def execute(self, server_id, network=None):
255 ab756200 Giorgos Verigakis
        path = '/api/%s/servers/%d/ips' % (self.api, int(server_id))
256 ab756200 Giorgos Verigakis
        if network:
257 ab756200 Giorgos Verigakis
            path += '/%s' % network
258 ab756200 Giorgos Verigakis
        reply = self.http_get(path)
259 ab756200 Giorgos Verigakis
        
260 ab756200 Giorgos Verigakis
        addresses = [reply['network']] if network else reply['addresses']['values']
261 ab756200 Giorgos Verigakis
        for address in addresses:
262 ab756200 Giorgos Verigakis
            print address_to_string(address)
263 ab756200 Giorgos Verigakis
264 ab756200 Giorgos Verigakis
265 ab756200 Giorgos Verigakis
@command_name('lsflv')
266 ab756200 Giorgos Verigakis
class ListFlavors(Command):
267 ab756200 Giorgos Verigakis
    description = 'list flavors'
268 ab756200 Giorgos Verigakis
    
269 ab756200 Giorgos Verigakis
    def add_options(self, parser):
270 ab756200 Giorgos Verigakis
        parser.add_option('-l', action='store_true', dest='detail', default=False,
271 ab756200 Giorgos Verigakis
                            help='show detailed output')
272 ab756200 Giorgos Verigakis
    
273 ab756200 Giorgos Verigakis
    def execute(self):
274 ab756200 Giorgos Verigakis
        path = '/api/%s/flavors' % self.api
275 ab756200 Giorgos Verigakis
        if self.detail:
276 ab756200 Giorgos Verigakis
            path += '/detail'
277 ab756200 Giorgos Verigakis
        reply = self.http_get(path)
278 ab756200 Giorgos Verigakis
        
279 ab756200 Giorgos Verigakis
        for flavor in reply['flavors']['values']:
280 ab756200 Giorgos Verigakis
            id = flavor.pop('id')
281 ab756200 Giorgos Verigakis
            name = flavor.pop('name')
282 ab756200 Giorgos Verigakis
            details = ' '.join('%s=%s' % item for item in sorted(flavor.items()))
283 ab756200 Giorgos Verigakis
            print '%3d %s %s' % (id, name, details)
284 ab756200 Giorgos Verigakis
285 ab756200 Giorgos Verigakis
286 d8e50a39 Giorgos Verigakis
@command_name('flvinfo')
287 ab756200 Giorgos Verigakis
class GetFlavorDetails(Command):
288 ab756200 Giorgos Verigakis
    description = 'get flavor details'
289 ab756200 Giorgos Verigakis
    syntax = '<flavor id>'
290 ab756200 Giorgos Verigakis
    
291 ab756200 Giorgos Verigakis
    def execute(self, flavor_id):
292 ab756200 Giorgos Verigakis
        path = '/api/%s/flavors/%d' % (self.api, int(flavor_id))
293 ab756200 Giorgos Verigakis
        reply = self.http_get(path)
294 ab756200 Giorgos Verigakis
        
295 ab756200 Giorgos Verigakis
        flavor = reply['flavor']
296 ab756200 Giorgos Verigakis
        id = flavor.pop('id')
297 ab756200 Giorgos Verigakis
        name = flavor.pop('name')
298 ab756200 Giorgos Verigakis
        details = ' '.join('%s=%s' % item for item in sorted(flavor.items()))
299 ab756200 Giorgos Verigakis
        print '%3d %s %s' % (id, name, details)
300 ab756200 Giorgos Verigakis
301 ab756200 Giorgos Verigakis
302 ab756200 Giorgos Verigakis
@command_name('lsimg')
303 ab756200 Giorgos Verigakis
class ListImages(Command):
304 ab756200 Giorgos Verigakis
    description = 'list images'
305 ab756200 Giorgos Verigakis
    
306 ab756200 Giorgos Verigakis
    def add_options(self, parser):
307 ab756200 Giorgos Verigakis
        parser.add_option('-l', action='store_true', dest='detail', default=False,
308 ab756200 Giorgos Verigakis
                            help='show detailed output')
309 ab756200 Giorgos Verigakis
    
310 ab756200 Giorgos Verigakis
    def execute(self):
311 ab756200 Giorgos Verigakis
        path = '/api/%s/images' % self.api
312 ab756200 Giorgos Verigakis
        if self.detail:
313 ab756200 Giorgos Verigakis
            path += '/detail'
314 ab756200 Giorgos Verigakis
        reply = self.http_get(path)
315 ab756200 Giorgos Verigakis
        
316 ab756200 Giorgos Verigakis
        for image in reply['images']['values']:
317 ab756200 Giorgos Verigakis
            id = image.pop('id')
318 ab756200 Giorgos Verigakis
            name = image.pop('name')
319 ab756200 Giorgos Verigakis
            if self.detail:
320 ab756200 Giorgos Verigakis
                print '%d %s' % (id, name)
321 ab756200 Giorgos Verigakis
                print_dict(image)
322 ab756200 Giorgos Verigakis
                print
323 ab756200 Giorgos Verigakis
            else:
324 ab756200 Giorgos Verigakis
                print '%3d %s' % (id, name)        
325 ab756200 Giorgos Verigakis
326 ab756200 Giorgos Verigakis
327 ab756200 Giorgos Verigakis
@command_name('imginfo')
328 ab756200 Giorgos Verigakis
class GetImageDetails(Command):
329 ab756200 Giorgos Verigakis
    description = 'get image details'
330 ab756200 Giorgos Verigakis
    syntax = '<image id>'
331 ab756200 Giorgos Verigakis
    
332 ab756200 Giorgos Verigakis
    def execute(self, image_id):
333 ab756200 Giorgos Verigakis
        path = '/api/%s/images/%d' % (self.api, int(image_id))
334 ab756200 Giorgos Verigakis
        reply = self.http_get(path)
335 ab756200 Giorgos Verigakis
        image = reply['image']
336 ab756200 Giorgos Verigakis
        image.pop('id')
337 ab756200 Giorgos Verigakis
        print_dict(image)
338 ab756200 Giorgos Verigakis
339 ab756200 Giorgos Verigakis
340 ab756200 Giorgos Verigakis
@command_name('createimg')
341 ab756200 Giorgos Verigakis
class CreateImage(Command):
342 ab756200 Giorgos Verigakis
    description = 'create image'
343 ab756200 Giorgos Verigakis
    syntax = '<server id> <image name>'
344 ab756200 Giorgos Verigakis
    
345 ab756200 Giorgos Verigakis
    def execute(self, server_id, name):
346 ab756200 Giorgos Verigakis
        path = '/api/%s/images' % self.api
347 ab756200 Giorgos Verigakis
        image = {'name': name, 'serverRef': int(server_id)}
348 ab756200 Giorgos Verigakis
        body = json.dumps({'image': image})
349 ab756200 Giorgos Verigakis
        reply = self.http_post(path, body)
350 ab756200 Giorgos Verigakis
        print_dict(reply['image'])
351 ab756200 Giorgos Verigakis
352 ab756200 Giorgos Verigakis
@command_name('deleteimg')
353 ab756200 Giorgos Verigakis
class DeleteImage(Command):
354 ab756200 Giorgos Verigakis
    description = 'delete image'
355 ab756200 Giorgos Verigakis
    syntax = '<image id>'
356 ab756200 Giorgos Verigakis
    
357 ab756200 Giorgos Verigakis
    def execute(self, image_id):
358 ab756200 Giorgos Verigakis
        path = '/api/%s/images/%d' % (self.api, int(image_id))
359 ab756200 Giorgos Verigakis
        self.http_delete(path)
360 ab756200 Giorgos Verigakis
361 d8e50a39 Giorgos Verigakis
@command_name('lsmeta')
362 d8e50a39 Giorgos Verigakis
class ListServerMeta(Command):
363 d8e50a39 Giorgos Verigakis
    description = 'list server meta'
364 d8e50a39 Giorgos Verigakis
    syntax = '<server id> [key]'
365 d8e50a39 Giorgos Verigakis
366 d8e50a39 Giorgos Verigakis
    def execute(self, server_id, key=None):
367 d8e50a39 Giorgos Verigakis
        path = '/api/%s/servers/%d/meta' % (self.api, int(server_id))
368 d8e50a39 Giorgos Verigakis
        if key:
369 d8e50a39 Giorgos Verigakis
            path += '/' + key
370 d8e50a39 Giorgos Verigakis
        reply = self.http_get(path)
371 d8e50a39 Giorgos Verigakis
        if key:
372 d8e50a39 Giorgos Verigakis
            print_dict(reply['meta'])
373 d8e50a39 Giorgos Verigakis
        else:
374 d8e50a39 Giorgos Verigakis
            print_dict(reply['metadata']['values'])
375 d8e50a39 Giorgos Verigakis
376 d8e50a39 Giorgos Verigakis
@command_name('setmeta')
377 d8e50a39 Giorgos Verigakis
class UpdateServerMeta(Command):
378 d8e50a39 Giorgos Verigakis
    description = 'update server meta'
379 d8e50a39 Giorgos Verigakis
    syntax = '<server id> <key> <val>'
380 d8e50a39 Giorgos Verigakis
381 d8e50a39 Giorgos Verigakis
    def execute(self, server_id, key, val):
382 d8e50a39 Giorgos Verigakis
        path = '/api/%s/servers/%d/meta' % (self.api, int(server_id))
383 d8e50a39 Giorgos Verigakis
        metadata = {key: val}
384 d8e50a39 Giorgos Verigakis
        body = json.dumps({'metadata': metadata})
385 d8e50a39 Giorgos Verigakis
        reply = self.http_post(path, body, expected_status=201)
386 d8e50a39 Giorgos Verigakis
        print_dict(reply['metadata'])
387 d8e50a39 Giorgos Verigakis
388 d8e50a39 Giorgos Verigakis
@command_name('addmeta')
389 d8e50a39 Giorgos Verigakis
class CreateServerMeta(Command):
390 d8e50a39 Giorgos Verigakis
    description = 'add server meta'
391 d8e50a39 Giorgos Verigakis
    syntax = '<server id> <key> <val>'
392 d8e50a39 Giorgos Verigakis
393 d8e50a39 Giorgos Verigakis
    def execute(self, server_id, key, val):
394 d8e50a39 Giorgos Verigakis
        path = '/api/%s/servers/%d/meta/%s' % (self.api, int(server_id), key)
395 d8e50a39 Giorgos Verigakis
        meta = {key: val}
396 d8e50a39 Giorgos Verigakis
        body = json.dumps({'meta': meta})
397 d8e50a39 Giorgos Verigakis
        reply = self.http_put(path, body, expected_status=201)
398 d8e50a39 Giorgos Verigakis
        print_dict(reply['meta'])
399 d8e50a39 Giorgos Verigakis
400 d8e50a39 Giorgos Verigakis
@command_name('delmeta')
401 d8e50a39 Giorgos Verigakis
class DeleteServerMeta(Command):
402 d8e50a39 Giorgos Verigakis
    description = 'delete server meta'
403 d8e50a39 Giorgos Verigakis
    syntax = '<server id> <key>'
404 d8e50a39 Giorgos Verigakis
405 d8e50a39 Giorgos Verigakis
    def execute(self, server_id, key):
406 d8e50a39 Giorgos Verigakis
        path = '/api/%s/servers/%d/meta/%s' % (self.api, int(server_id), key)
407 d8e50a39 Giorgos Verigakis
        reply = self.http_delete(path)
408 d8e50a39 Giorgos Verigakis
409 432fc8c3 Giorgos Verigakis
@command_name('lsimgmeta')
410 432fc8c3 Giorgos Verigakis
class ListImageMeta(Command):
411 432fc8c3 Giorgos Verigakis
    description = 'list image meta'
412 432fc8c3 Giorgos Verigakis
    syntax = '<image id> [key]'
413 432fc8c3 Giorgos Verigakis
414 432fc8c3 Giorgos Verigakis
    def execute(self, image_id, key=None):
415 432fc8c3 Giorgos Verigakis
        path = '/api/%s/images/%d/meta' % (self.api, int(image_id))
416 432fc8c3 Giorgos Verigakis
        if key:
417 432fc8c3 Giorgos Verigakis
            path += '/' + key
418 432fc8c3 Giorgos Verigakis
        reply = self.http_get(path)
419 432fc8c3 Giorgos Verigakis
        if key:
420 432fc8c3 Giorgos Verigakis
            print_dict(reply['meta'])
421 432fc8c3 Giorgos Verigakis
        else:
422 432fc8c3 Giorgos Verigakis
            print_dict(reply['metadata']['values'])
423 432fc8c3 Giorgos Verigakis
424 432fc8c3 Giorgos Verigakis
@command_name('setimgmeta')
425 432fc8c3 Giorgos Verigakis
class UpdateImageMeta(Command):
426 432fc8c3 Giorgos Verigakis
    description = 'update image meta'
427 432fc8c3 Giorgos Verigakis
    syntax = '<image id> <key> <val>'
428 432fc8c3 Giorgos Verigakis
429 432fc8c3 Giorgos Verigakis
    def execute(self, image_id, key, val):
430 432fc8c3 Giorgos Verigakis
        path = '/api/%s/images/%d/meta' % (self.api, int(image_id))
431 432fc8c3 Giorgos Verigakis
        metadata = {key: val}
432 432fc8c3 Giorgos Verigakis
        body = json.dumps({'metadata': metadata})
433 432fc8c3 Giorgos Verigakis
        reply = self.http_post(path, body, expected_status=201)
434 432fc8c3 Giorgos Verigakis
        print_dict(reply['metadata'])
435 432fc8c3 Giorgos Verigakis
436 432fc8c3 Giorgos Verigakis
@command_name('addimgmeta')
437 432fc8c3 Giorgos Verigakis
class CreateImageMeta(Command):
438 432fc8c3 Giorgos Verigakis
    description = 'add image meta'
439 432fc8c3 Giorgos Verigakis
    syntax = '<image id> <key> <val>'
440 432fc8c3 Giorgos Verigakis
441 432fc8c3 Giorgos Verigakis
    def execute(self, image_id, key, val):
442 432fc8c3 Giorgos Verigakis
        path = '/api/%s/images/%d/meta/%s' % (self.api, int(image_id), key)
443 432fc8c3 Giorgos Verigakis
        meta = {key: val}
444 432fc8c3 Giorgos Verigakis
        body = json.dumps({'meta': meta})
445 432fc8c3 Giorgos Verigakis
        reply = self.http_put(path, body, expected_status=201)
446 432fc8c3 Giorgos Verigakis
        print_dict(reply['meta'])
447 432fc8c3 Giorgos Verigakis
448 432fc8c3 Giorgos Verigakis
@command_name('delimgmeta')
449 432fc8c3 Giorgos Verigakis
class DeleteImageMeta(Command):
450 432fc8c3 Giorgos Verigakis
    description = 'delete image meta'
451 432fc8c3 Giorgos Verigakis
    syntax = '<image id> <key>'
452 432fc8c3 Giorgos Verigakis
453 432fc8c3 Giorgos Verigakis
    def execute(self, image_id, key):
454 432fc8c3 Giorgos Verigakis
        path = '/api/%s/images/%d/meta/%s' % (self.api, int(image_id), key)
455 432fc8c3 Giorgos Verigakis
        reply = self.http_delete(path)
456 432fc8c3 Giorgos Verigakis
457 ab756200 Giorgos Verigakis
458 ab756200 Giorgos Verigakis
def main():
459 ab756200 Giorgos Verigakis
    try:
460 ab756200 Giorgos Verigakis
        name = argv[1]    
461 ab756200 Giorgos Verigakis
        cls = commands[name]
462 ab756200 Giorgos Verigakis
    except (IndexError, KeyError):
463 ab756200 Giorgos Verigakis
        print 'Usage: %s <command>' % basename(argv[0])
464 ab756200 Giorgos Verigakis
        print
465 ab756200 Giorgos Verigakis
        print 'Commands:'
466 ab756200 Giorgos Verigakis
        for name, cls in sorted(commands.items()):
467 ab756200 Giorgos Verigakis
            description = getattr(cls, 'description', '')
468 ab756200 Giorgos Verigakis
            print '  %s %s' % (name.ljust(12), description)
469 ab756200 Giorgos Verigakis
        exit(1)
470 ab756200 Giorgos Verigakis
    
471 ab756200 Giorgos Verigakis
    try:
472 ab756200 Giorgos Verigakis
        commands[name](argv[2:])
473 ab756200 Giorgos Verigakis
    except TypeError:
474 ab756200 Giorgos Verigakis
        syntax = getattr(cls, 'syntax', '')
475 ab756200 Giorgos Verigakis
        if syntax:
476 ab756200 Giorgos Verigakis
            print 'Syntax: %s %s' % (name, syntax)
477 ab756200 Giorgos Verigakis
        else:
478 ab756200 Giorgos Verigakis
            print 'Invalid syntax'
479 ab756200 Giorgos Verigakis
        exit(1)
480 ab756200 Giorgos Verigakis
481 ab756200 Giorgos Verigakis
482 ab756200 Giorgos Verigakis
if __name__ == '__main__':
483 ab756200 Giorgos Verigakis
    main()