Statistics
| Branch: | Tag: | Revision:

root / tools / snf-admin @ ca8f8081

History | View | Annotate | Download (11 kB)

1 8cdde414 Giorgos Verigakis
#!/usr/bin/env python
2 8cdde414 Giorgos Verigakis
3 8cdde414 Giorgos Verigakis
# Copyright 2011 GRNET S.A. All rights reserved.
4 8cdde414 Giorgos Verigakis
# 
5 8cdde414 Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
6 8cdde414 Giorgos Verigakis
# without modification, are permitted provided that the following
7 8cdde414 Giorgos Verigakis
# conditions are met:
8 8cdde414 Giorgos Verigakis
# 
9 8cdde414 Giorgos Verigakis
#   1. Redistributions of source code must retain the above
10 8cdde414 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
11 8cdde414 Giorgos Verigakis
#      disclaimer.
12 8cdde414 Giorgos Verigakis
# 
13 8cdde414 Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
14 8cdde414 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
15 8cdde414 Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
16 8cdde414 Giorgos Verigakis
#      provided with the distribution.
17 8cdde414 Giorgos Verigakis
# 
18 8cdde414 Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 8cdde414 Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 8cdde414 Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 8cdde414 Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 8cdde414 Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 8cdde414 Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 8cdde414 Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 8cdde414 Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 8cdde414 Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 8cdde414 Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 8cdde414 Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 8cdde414 Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
30 8cdde414 Giorgos Verigakis
# 
31 8cdde414 Giorgos Verigakis
# The views and conclusions contained in the software and
32 8cdde414 Giorgos Verigakis
# documentation are those of the authors and should not be
33 8cdde414 Giorgos Verigakis
# interpreted as representing official policies, either expressed
34 8cdde414 Giorgos Verigakis
# or implied, of GRNET S.A.
35 8cdde414 Giorgos Verigakis
36 8cdde414 Giorgos Verigakis
from django.core.management import setup_environ
37 8cdde414 Giorgos Verigakis
try:
38 8cdde414 Giorgos Verigakis
    from synnefo import settings
39 8cdde414 Giorgos Verigakis
except ImportError:
40 8cdde414 Giorgos Verigakis
    raise Exception("Cannot import settings, make sure PYTHONPATH contains "
41 8cdde414 Giorgos Verigakis
                    "the parent directory of the Synnefo Django project.")
42 8cdde414 Giorgos Verigakis
setup_environ(settings)
43 8cdde414 Giorgos Verigakis
44 8cdde414 Giorgos Verigakis
import inspect
45 8cdde414 Giorgos Verigakis
import logging
46 8cdde414 Giorgos Verigakis
import sys
47 8cdde414 Giorgos Verigakis
48 8cdde414 Giorgos Verigakis
from collections import defaultdict
49 8cdde414 Giorgos Verigakis
from optparse import OptionParser
50 8cdde414 Giorgos Verigakis
from os.path import basename
51 8cdde414 Giorgos Verigakis
52 8cdde414 Giorgos Verigakis
from synnefo.db import models
53 8cdde414 Giorgos Verigakis
54 8cdde414 Giorgos Verigakis
55 8cdde414 Giorgos Verigakis
def get_user(uid):
56 8cdde414 Giorgos Verigakis
    try:
57 8cdde414 Giorgos Verigakis
        uid = int(uid)
58 8cdde414 Giorgos Verigakis
        return models.SynnefoUser.objects.get(id=uid)
59 8cdde414 Giorgos Verigakis
        servers = servers.filter(owner=user)
60 8cdde414 Giorgos Verigakis
    except ValueError:
61 8cdde414 Giorgos Verigakis
        return None
62 8cdde414 Giorgos Verigakis
    except models.SynnefoUser.DoesNotExist:
63 8cdde414 Giorgos Verigakis
        return None
64 8cdde414 Giorgos Verigakis
65 8cdde414 Giorgos Verigakis
def print_dict(d, exclude=()):
66 ca8f8081 Giorgos Verigakis
    if not d:
67 ca8f8081 Giorgos Verigakis
        return
68 8cdde414 Giorgos Verigakis
    margin = max(len(key) for key in d) + 1
69 8cdde414 Giorgos Verigakis
70 8cdde414 Giorgos Verigakis
    for key, val in sorted(d.items()):
71 8cdde414 Giorgos Verigakis
        if key in exclude:
72 8cdde414 Giorgos Verigakis
            continue
73 8cdde414 Giorgos Verigakis
        print '%s: %s' % (key.rjust(margin), val)
74 8cdde414 Giorgos Verigakis
75 8cdde414 Giorgos Verigakis
def print_items(items, detail=False):
76 8cdde414 Giorgos Verigakis
    for item in items:
77 8cdde414 Giorgos Verigakis
        print '%d %s' % (item.id, item.name)
78 8cdde414 Giorgos Verigakis
        if detail:
79 8cdde414 Giorgos Verigakis
            print_dict(item.__dict__, exclude=('id', 'name', '_state'))
80 8cdde414 Giorgos Verigakis
            print
81 8cdde414 Giorgos Verigakis
82 8cdde414 Giorgos Verigakis
83 8cdde414 Giorgos Verigakis
class Command(object):
84 8cdde414 Giorgos Verigakis
    category = ''
85 8cdde414 Giorgos Verigakis
    name = ''
86 8cdde414 Giorgos Verigakis
    syntax = ''
87 8cdde414 Giorgos Verigakis
    description = ''
88 8cdde414 Giorgos Verigakis
    
89 8cdde414 Giorgos Verigakis
    def __init__(self, argv):
90 8cdde414 Giorgos Verigakis
        parser = OptionParser()
91 8cdde414 Giorgos Verigakis
        parser.usage = '%%prog %s %s %s' % (self.category, self.name,
92 8cdde414 Giorgos Verigakis
                                            self.syntax)
93 8cdde414 Giorgos Verigakis
        self.add_options(parser)
94 8cdde414 Giorgos Verigakis
        options, self.args = parser.parse_args(argv)
95 8cdde414 Giorgos Verigakis
        
96 8cdde414 Giorgos Verigakis
        # Add options to self
97 8cdde414 Giorgos Verigakis
        for opt in parser.option_list:
98 8cdde414 Giorgos Verigakis
            key = opt.dest
99 8cdde414 Giorgos Verigakis
            if key:
100 8cdde414 Giorgos Verigakis
                val = getattr(options, key)
101 8cdde414 Giorgos Verigakis
                setattr(self, key, val)
102 8cdde414 Giorgos Verigakis
        
103 8cdde414 Giorgos Verigakis
        ch = logging.StreamHandler()
104 8cdde414 Giorgos Verigakis
        ch.setFormatter(logging.Formatter('%(message)s'))
105 8cdde414 Giorgos Verigakis
        logger = logging.getLogger()
106 8cdde414 Giorgos Verigakis
        logger.addHandler(ch)
107 8cdde414 Giorgos Verigakis
        level = logging.WARNING
108 8cdde414 Giorgos Verigakis
        logger.setLevel(level)
109 8cdde414 Giorgos Verigakis
        
110 8cdde414 Giorgos Verigakis
        self.parser = parser
111 8cdde414 Giorgos Verigakis
    
112 8cdde414 Giorgos Verigakis
    def add_options(self, parser):
113 8cdde414 Giorgos Verigakis
        pass
114 8cdde414 Giorgos Verigakis
    
115 8cdde414 Giorgos Verigakis
    def execute(self):
116 8cdde414 Giorgos Verigakis
        try:
117 8cdde414 Giorgos Verigakis
            self.main(*self.args)
118 8cdde414 Giorgos Verigakis
        except TypeError:
119 8cdde414 Giorgos Verigakis
            self.parser.print_help()
120 8cdde414 Giorgos Verigakis
121 8cdde414 Giorgos Verigakis
122 8cdde414 Giorgos Verigakis
class ListServers(Command):
123 8cdde414 Giorgos Verigakis
    category = 'server'
124 ca8f8081 Giorgos Verigakis
    name = 'list'
125 8cdde414 Giorgos Verigakis
    syntax = '[server id]'
126 8cdde414 Giorgos Verigakis
    description = 'list servers'
127 8cdde414 Giorgos Verigakis
    
128 8cdde414 Giorgos Verigakis
    def add_options(self, parser):
129 8cdde414 Giorgos Verigakis
        parser.add_option('-a', action='store_true', dest='show_deleted',
130 8cdde414 Giorgos Verigakis
                        default=False, help='also list deleted servers')
131 8cdde414 Giorgos Verigakis
        parser.add_option('-l', action='store_true', dest='detail',
132 8cdde414 Giorgos Verigakis
                        default=False, help='show detailed output')
133 8cdde414 Giorgos Verigakis
        parser.add_option('-u', dest='uid', metavar='UID',
134 8cdde414 Giorgos Verigakis
                            help='show servers of user with id UID')
135 8cdde414 Giorgos Verigakis
    
136 8cdde414 Giorgos Verigakis
    def main(self, server_id=None):
137 8cdde414 Giorgos Verigakis
        servers = models.VirtualMachine.objects.order_by('id')
138 8cdde414 Giorgos Verigakis
        if server_id:
139 8cdde414 Giorgos Verigakis
            servers = servers.filter(id=server_id)
140 8cdde414 Giorgos Verigakis
        if not self.show_deleted:
141 8cdde414 Giorgos Verigakis
            servers = servers.filter(deleted=False)
142 8cdde414 Giorgos Verigakis
        if self.uid:
143 8cdde414 Giorgos Verigakis
            user = get_user(self.uid)
144 8cdde414 Giorgos Verigakis
            if user:
145 8cdde414 Giorgos Verigakis
                servers = servers.filter(owner=user)
146 8cdde414 Giorgos Verigakis
            else:
147 8cdde414 Giorgos Verigakis
                print 'Unknown user id'
148 8cdde414 Giorgos Verigakis
                return
149 8cdde414 Giorgos Verigakis
        
150 8cdde414 Giorgos Verigakis
        print_items(servers, self.detail)
151 8cdde414 Giorgos Verigakis
152 8cdde414 Giorgos Verigakis
153 8cdde414 Giorgos Verigakis
class ListUsers(Command):
154 8cdde414 Giorgos Verigakis
    category = 'user'
155 ca8f8081 Giorgos Verigakis
    name = 'list'
156 8cdde414 Giorgos Verigakis
    syntax = '[user id]'
157 8cdde414 Giorgos Verigakis
    description = 'list users'
158 8cdde414 Giorgos Verigakis
    
159 8cdde414 Giorgos Verigakis
    def add_options(self, parser):
160 8cdde414 Giorgos Verigakis
        parser.add_option('-l', action='store_true', dest='detail',
161 8cdde414 Giorgos Verigakis
                        default=False, help='show detailed output')
162 8cdde414 Giorgos Verigakis
    
163 8cdde414 Giorgos Verigakis
    def main(self, user_id=None):
164 8cdde414 Giorgos Verigakis
        if user_id:
165 8cdde414 Giorgos Verigakis
            users = [models.SynnefoUser.objects.get(id=user_id)]
166 8cdde414 Giorgos Verigakis
        else:
167 8cdde414 Giorgos Verigakis
            users = models.SynnefoUser.objects.order_by('id')
168 8cdde414 Giorgos Verigakis
        print_items(users, self.detail)
169 8cdde414 Giorgos Verigakis
170 8cdde414 Giorgos Verigakis
171 8cdde414 Giorgos Verigakis
class ListImages(Command):
172 8cdde414 Giorgos Verigakis
    category = 'image'
173 ca8f8081 Giorgos Verigakis
    name = 'list'
174 8cdde414 Giorgos Verigakis
    syntax = '[image id]'
175 8cdde414 Giorgos Verigakis
    description = 'list images'
176 8cdde414 Giorgos Verigakis
    
177 8cdde414 Giorgos Verigakis
    def add_options(self, parser):
178 8cdde414 Giorgos Verigakis
        parser.add_option('-l', action='store_true', dest='detail',
179 8cdde414 Giorgos Verigakis
                        default=False, help='show detailed output')
180 8cdde414 Giorgos Verigakis
    
181 8cdde414 Giorgos Verigakis
    def main(self, image_id=None):
182 8cdde414 Giorgos Verigakis
        if image_id:
183 8cdde414 Giorgos Verigakis
            images = [models.Image.objects.get(id=image_id)]
184 8cdde414 Giorgos Verigakis
        else:
185 8cdde414 Giorgos Verigakis
            images = models.Image.objects.order_by('id')
186 8cdde414 Giorgos Verigakis
        print_items(images, self.detail)
187 8cdde414 Giorgos Verigakis
188 8cdde414 Giorgos Verigakis
189 8cdde414 Giorgos Verigakis
class RegisterImage(Command):
190 8cdde414 Giorgos Verigakis
    category = 'image'
191 8cdde414 Giorgos Verigakis
    name = 'register'
192 8cdde414 Giorgos Verigakis
    syntax = '<name> <backend id>'
193 8cdde414 Giorgos Verigakis
    description = 'register an image'
194 8cdde414 Giorgos Verigakis
    
195 8cdde414 Giorgos Verigakis
    def add_options(self, parser):
196 ca8f8081 Giorgos Verigakis
        parser.add_option('--public', action='store_true', dest='public',
197 8cdde414 Giorgos Verigakis
                            default=False, help='make image public')
198 8cdde414 Giorgos Verigakis
        parser.add_option('-u', dest='uid', metavar='UID',
199 8cdde414 Giorgos Verigakis
                            help='assign image to user with id UID')
200 8cdde414 Giorgos Verigakis
    
201 8cdde414 Giorgos Verigakis
    def main(self, name, backend_id):
202 8cdde414 Giorgos Verigakis
        user = None
203 8cdde414 Giorgos Verigakis
        if self.uid:
204 8cdde414 Giorgos Verigakis
            user = get_user(self.uid)
205 8cdde414 Giorgos Verigakis
            if not user:
206 8cdde414 Giorgos Verigakis
                print 'Unknown user id'
207 8cdde414 Giorgos Verigakis
                return
208 8cdde414 Giorgos Verigakis
        
209 8cdde414 Giorgos Verigakis
        image = models.Image.objects.create(
210 8cdde414 Giorgos Verigakis
            name=name,
211 8cdde414 Giorgos Verigakis
            state='ACTIVE',
212 8cdde414 Giorgos Verigakis
            owner=user,
213 8cdde414 Giorgos Verigakis
            backend_id=backend_id,
214 8cdde414 Giorgos Verigakis
            public=self.public)
215 8cdde414 Giorgos Verigakis
216 8cdde414 Giorgos Verigakis
217 8cdde414 Giorgos Verigakis
class ModifyImage(Command):
218 8cdde414 Giorgos Verigakis
    category = 'image'
219 8cdde414 Giorgos Verigakis
    name = 'modify'
220 8cdde414 Giorgos Verigakis
    syntax = '<image id>'
221 8cdde414 Giorgos Verigakis
    description = 'modify an image'
222 8cdde414 Giorgos Verigakis
    
223 8cdde414 Giorgos Verigakis
    def add_options(self, parser):
224 8cdde414 Giorgos Verigakis
        parser.add_option('-b', dest='backend_id', metavar='BACKEND_ID',
225 8cdde414 Giorgos Verigakis
                            help='set image backend id')
226 8cdde414 Giorgos Verigakis
        parser.add_option('-f', dest='format', metavar='FORMAT',
227 8cdde414 Giorgos Verigakis
                            help='set image format')
228 8cdde414 Giorgos Verigakis
        parser.add_option('-n', dest='name', metavar='NAME',
229 8cdde414 Giorgos Verigakis
                            help='set image name')
230 ca8f8081 Giorgos Verigakis
        parser.add_option('--public', action='store_true', dest='public',
231 8cdde414 Giorgos Verigakis
                            default=False, help='make image public')
232 ca8f8081 Giorgos Verigakis
        parser.add_option('--nopublic', action='store_true', dest='private',
233 8cdde414 Giorgos Verigakis
                            default=False, help='make image private')
234 8cdde414 Giorgos Verigakis
        parser.add_option('-s', dest='state', metavar='STATE',
235 8cdde414 Giorgos Verigakis
                            default=False, help='set image state')
236 8cdde414 Giorgos Verigakis
        parser.add_option('-u', dest='uid', metavar='UID',
237 8cdde414 Giorgos Verigakis
                            help='assign image to user with id UID')
238 8cdde414 Giorgos Verigakis
    
239 8cdde414 Giorgos Verigakis
    def main(self, image_id):
240 8cdde414 Giorgos Verigakis
        try:
241 8cdde414 Giorgos Verigakis
            image = models.Image.objects.get(id=image_id)
242 8cdde414 Giorgos Verigakis
        except:
243 8cdde414 Giorgos Verigakis
            print 'Image not found'
244 8cdde414 Giorgos Verigakis
            return
245 8cdde414 Giorgos Verigakis
        
246 8cdde414 Giorgos Verigakis
        if self.backend_id:
247 8cdde414 Giorgos Verigakis
            image.backend_id = self.backend_id
248 8cdde414 Giorgos Verigakis
        if self.format:
249 8cdde414 Giorgos Verigakis
            image.format = format
250 8cdde414 Giorgos Verigakis
        if self.name:
251 8cdde414 Giorgos Verigakis
            image.name = self.name
252 8cdde414 Giorgos Verigakis
        if self.public:
253 8cdde414 Giorgos Verigakis
            image.public = True
254 8cdde414 Giorgos Verigakis
        if self.private:
255 8cdde414 Giorgos Verigakis
            image.public = False
256 8cdde414 Giorgos Verigakis
        if self.state:
257 8cdde414 Giorgos Verigakis
            image.state = self.state
258 8cdde414 Giorgos Verigakis
        if self.uid:
259 8cdde414 Giorgos Verigakis
            image.owner = get_user(self.uid)
260 8cdde414 Giorgos Verigakis
        
261 8cdde414 Giorgos Verigakis
        image.save()
262 8cdde414 Giorgos Verigakis
263 8cdde414 Giorgos Verigakis
264 ca8f8081 Giorgos Verigakis
class ModifyImageMeta(Command):
265 ca8f8081 Giorgos Verigakis
    category = 'image'
266 ca8f8081 Giorgos Verigakis
    name = 'meta'
267 ca8f8081 Giorgos Verigakis
    syntax = '<image id> [key[=val]]'
268 ca8f8081 Giorgos Verigakis
    description = 'get and manipulate image metadata'
269 ca8f8081 Giorgos Verigakis
    
270 ca8f8081 Giorgos Verigakis
    def main(self, image_id, arg=''):
271 ca8f8081 Giorgos Verigakis
        try:
272 ca8f8081 Giorgos Verigakis
            image = models.Image.objects.get(id=image_id)
273 ca8f8081 Giorgos Verigakis
        except:
274 ca8f8081 Giorgos Verigakis
            print 'Image not found'
275 ca8f8081 Giorgos Verigakis
            return
276 ca8f8081 Giorgos Verigakis
        
277 ca8f8081 Giorgos Verigakis
        key, sep, val = arg.partition('=')
278 ca8f8081 Giorgos Verigakis
        if not sep:
279 ca8f8081 Giorgos Verigakis
            val = None
280 ca8f8081 Giorgos Verigakis
        
281 ca8f8081 Giorgos Verigakis
        if not key:
282 ca8f8081 Giorgos Verigakis
            metadata = {}
283 ca8f8081 Giorgos Verigakis
            for meta in image.imagemetadata_set.order_by('meta_key'):
284 ca8f8081 Giorgos Verigakis
                metadata[meta.meta_key] = meta.meta_value
285 ca8f8081 Giorgos Verigakis
            print_dict(metadata)
286 ca8f8081 Giorgos Verigakis
            return
287 ca8f8081 Giorgos Verigakis
        
288 ca8f8081 Giorgos Verigakis
        try:
289 ca8f8081 Giorgos Verigakis
            meta = image.imagemetadata_set.get(meta_key=key)
290 ca8f8081 Giorgos Verigakis
        except models.ImageMetadata.DoesNotExist:
291 ca8f8081 Giorgos Verigakis
            meta = None
292 ca8f8081 Giorgos Verigakis
        
293 ca8f8081 Giorgos Verigakis
        if val is None:
294 ca8f8081 Giorgos Verigakis
            if meta:
295 ca8f8081 Giorgos Verigakis
                print_dict({key: meta.meta_value})
296 ca8f8081 Giorgos Verigakis
            return
297 ca8f8081 Giorgos Verigakis
        
298 ca8f8081 Giorgos Verigakis
        if val:
299 ca8f8081 Giorgos Verigakis
            if not meta:
300 ca8f8081 Giorgos Verigakis
                meta = image.imagemetadata_set.create(meta_key=key)
301 ca8f8081 Giorgos Verigakis
            meta.meta_value = val
302 ca8f8081 Giorgos Verigakis
            meta.save()
303 ca8f8081 Giorgos Verigakis
        else:
304 ca8f8081 Giorgos Verigakis
            # Delete if val is empty
305 ca8f8081 Giorgos Verigakis
            if meta:
306 ca8f8081 Giorgos Verigakis
                meta.delete()
307 ca8f8081 Giorgos Verigakis
308 ca8f8081 Giorgos Verigakis
309 8cdde414 Giorgos Verigakis
def print_categories(exe, categories):
310 8cdde414 Giorgos Verigakis
    print 'Usage: %s <category> <command>' % exe
311 8cdde414 Giorgos Verigakis
    print
312 8cdde414 Giorgos Verigakis
    print 'Categories:'
313 8cdde414 Giorgos Verigakis
    for category in sorted(categories):
314 8cdde414 Giorgos Verigakis
        print '  %s' % category
315 8cdde414 Giorgos Verigakis
316 8cdde414 Giorgos Verigakis
def print_commands(exe, commands):
317 8cdde414 Giorgos Verigakis
    print 'Usage: %s <command>' % exe
318 8cdde414 Giorgos Verigakis
    print
319 8cdde414 Giorgos Verigakis
    print 'Commands:'
320 8cdde414 Giorgos Verigakis
    for command, cls in sorted(commands.items()):
321 8cdde414 Giorgos Verigakis
        print '  %s %s' % (command.ljust(10), cls.description)
322 8cdde414 Giorgos Verigakis
323 8cdde414 Giorgos Verigakis
324 8cdde414 Giorgos Verigakis
def main():
325 8cdde414 Giorgos Verigakis
    categories = defaultdict(dict)
326 8cdde414 Giorgos Verigakis
    module = sys.modules[__name__]
327 8cdde414 Giorgos Verigakis
    for name, cls in inspect.getmembers(module, inspect.isclass):
328 8cdde414 Giorgos Verigakis
        if issubclass(cls, Command) and cls != Command:
329 8cdde414 Giorgos Verigakis
            categories[cls.category][cls.name] = cls
330 8cdde414 Giorgos Verigakis
    
331 8cdde414 Giorgos Verigakis
    argv = list(sys.argv)
332 8cdde414 Giorgos Verigakis
    exe = basename(argv.pop(0))
333 8cdde414 Giorgos Verigakis
    snf, sep, rest = exe.partition('-')
334 8cdde414 Giorgos Verigakis
    if snf == 'snf' and sep and rest != 'admin':
335 8cdde414 Giorgos Verigakis
        category = rest
336 8cdde414 Giorgos Verigakis
        if category not in categories:
337 8cdde414 Giorgos Verigakis
            print 'Invalid alias'
338 8cdde414 Giorgos Verigakis
            sys.exit(1)
339 8cdde414 Giorgos Verigakis
    else:
340 8cdde414 Giorgos Verigakis
        category = argv.pop(0) if argv else None
341 8cdde414 Giorgos Verigakis
        if category:
342 8cdde414 Giorgos Verigakis
            exe = '%s %s' % (exe, category)
343 8cdde414 Giorgos Verigakis
    
344 8cdde414 Giorgos Verigakis
    if not category or category not in categories:
345 8cdde414 Giorgos Verigakis
        print_categories(exe, categories)
346 8cdde414 Giorgos Verigakis
        sys.exit(1)
347 8cdde414 Giorgos Verigakis
    
348 8cdde414 Giorgos Verigakis
    command = argv.pop(0) if argv else None
349 8cdde414 Giorgos Verigakis
    
350 8cdde414 Giorgos Verigakis
    if not command or command not in categories[category]:
351 8cdde414 Giorgos Verigakis
        print_commands(exe, categories[category])
352 8cdde414 Giorgos Verigakis
        sys.exit(1)
353 8cdde414 Giorgos Verigakis
    
354 8cdde414 Giorgos Verigakis
    cls = categories[category][command]
355 8cdde414 Giorgos Verigakis
    cmd = cls(argv)
356 8cdde414 Giorgos Verigakis
    cmd.execute()
357 8cdde414 Giorgos Verigakis
358 8cdde414 Giorgos Verigakis
359 8cdde414 Giorgos Verigakis
if __name__ == '__main__':
360 8cdde414 Giorgos Verigakis
    main()