Revision b0e7f310 snf-cyclades-app/synnefo/api/management/commands/server-list.py

b/snf-cyclades-app/synnefo/api/management/commands/server-list.py
1
# Copyright 2012 GRNET S.A. All rights reserved.
1
# Copyright 2012-2013 GRNET S.A. All rights reserved.
2 2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
......
33 33

  
34 34
from optparse import make_option
35 35

  
36
from django.core.management.base import BaseCommand, CommandError
37
from synnefo.management.common import (format_vm_state, get_backend, Omit,
38
                                       filter_results, pprint_table, UserCache)
39
from synnefo.api.util import get_image
36
from synnefo.webproject.management.commands import ListCommand
40 37
from synnefo.db.models import VirtualMachine
38
from synnefo.management.common import get_backend
39
from synnefo.api.util import get_image
41 40

  
42
import logging
43
log = logging.getLogger(__name__)
44

  
45
FIELDS = VirtualMachine._meta.get_all_field_names()
41
from logging import getLogger
42
log = getLogger(__name__)
46 43

  
47 44

  
48
class Command(BaseCommand):
45
class Command(ListCommand):
49 46
    help = "List servers"
50 47

  
51
    option_list = BaseCommand.option_list + (
52
        make_option(
53
            '-c',
54
            action='store_true',
55
            dest='csv',
56
            default=False,
57
            help="Use pipes to separate values"),
48
    option_list = ListCommand.option_list + (
58 49
        make_option(
59 50
            '--suspended',
60 51
            action='store_true',
......
62 53
            default=False,
63 54
            help="List only suspended servers"),
64 55
        make_option(
65
            '--build',
66
            action='store_true',
67
            dest='build',
68
            default=False,
69
            help="List only servers in the building state"),
70
        make_option(
71
            '--deleted',
72
            action='store_true',
73
            dest='deleted',
74
            default=False,
75
            help="Include deleted servers"),
76
        make_option(
77 56
            '--backend-id',
78 57
            dest='backend_id',
79 58
            help="List only servers of the specified backend"),
80 59
        make_option(
81
            '--user',
82
            dest='user',
83
            help="List only servers of the specified user (uuid or email)"),
84
        make_option(
85
            '--filter-by',
86
            dest='filter_by',
87
            help="Filter results. Comma seperated list of key `cond` val pairs"
88
                 " that displayed entries must satisfy. e.g."
89
                 " --filter-by \"operstate=STARTED,id>=22\"."
90
                 " Available keys are: %s" % ", ".join(FIELDS)),
60
            "--build",
61
            action="store_true",
62
            dest="build",
63
            default=False,
64
            help="List only servers in the building state"),
91 65
        make_option(
92
            '--displayname',
93
            action='store_true',
94
            dest='displayname',
66
            "--image-name",
67
            action="store_true",
68
            dest="image_name",
95 69
            default=False,
96
            help="Display both uuid and display name"),
70
            help="Display image name instead of image ID"),
97 71
    )
98 72

  
99
    def handle(self, *args, **options):
100
        if args:
101
            raise CommandError("Command doesn't accept any arguments")
73
    object_class = VirtualMachine
74
    deleted_field = "deleted"
75
    user_uuid_field = "userid"
102 76

  
103
        ucache = UserCache()
104

  
105
        if options['backend_id']:
106
            backend = get_backend(options['backend_id'])
107
            servers = backend.virtual_machines
108
        else:
109
            servers = VirtualMachine.objects
77
    def get_public_ip(vm):
78
        try:
79
            return vm.nics.all()[0].ipv4
80
        except IndexError:
81
            return None
110 82

  
111
        if options['deleted']:
112
            servers = servers.all()
83
    def format_vm_state(vm):
84
        if vm.operstate == "BUILD":
85
            return "BUILD(" + str(vm.buildpercentage) + "%)"
113 86
        else:
114
            servers = servers.filter(deleted=False)
115

  
116
        if options['suspended']:
117
            servers = servers.filter(suspended=True)
118

  
119
        if options['build']:
120
            servers = servers.filter(operstate='BUILD')
121

  
122
        user = options['user']
123
        if user:
124
            if '@' in user:
125
                user = ucache.get_uuid(user)
126
            servers = servers.filter(userid=user)
127

  
128
        filter_by = options['filter_by']
129
        if filter_by:
130
            servers = filter_results(servers, filter_by)
131

  
132
        displayname = options['displayname']
133

  
134
        cache = ImageCache()
135

  
136
        headers = filter(lambda x: x is not Omit,
137
                         ['id',
138
                          'name',
139
                          'owner_uuid',
140
                          'owner_name' if displayname else Omit,
141
                          'flavor',
142
                          'image',
143
                          'state',
144
                          'backend',
145
                          ])
146

  
147
        if displayname:
148
            uuids = list(set([server.userid for server in servers]))
149
            ucache.fetch_names(uuids)
150

  
151
        table = []
152
        for server in servers.order_by('id'):
153
            try:
154
                name = server.name.decode('utf8')
155
            except UnicodeEncodeError:
156
                name = server.name
157

  
158
            flavor = server.flavor.name
159

  
160
            image = cache.get_image(server.imageid, server.userid)
161

  
162
            state = format_vm_state(server)
163

  
164
            uuid = server.userid
165
            if displayname:
166
                dname = ucache.get_name(server.userid)
167

  
168
            fields = filter(lambda x: x is not Omit,
169
                            [str(server.id),
170
                             name,
171
                             uuid,
172
                             dname if displayname else Omit,
173
                             flavor,
174
                             image,
175
                             state,
176
                             str(server.backend),
177
                             ])
178
            table.append(fields)
179

  
180
        separator = " | " if options['csv'] else None
181
        pprint_table(self.stdout, table, headers, separator)
87
            return vm.operstate
88

  
89
    FIELDS = {
90
        "id": ("id", "ID of the server"),
91
        "name": ("name", "Name of the server"),
92
        "user.uuid": ("userid", "The UUID of the server's owner"),
93
        "flavor": ("flavor.name", "The name of the server's flavor"),
94
        "backend": ("backend", "The Ganeti backend that hosts the VM"),
95
        "image.id": ("imageid", "The ID of the server's image"),
96
        "image.name": ("image", "The name of the server's image"),
97
        "state": (format_vm_state, "The current state of the server"),
98
        "ip": (get_public_ip, "The public IP of the server"),
99
        "created": ("created", "The date the server was created"),
100
        "deleted": ("deleted", "Whether the server is deleted or not"),
101
        "suspended": ("suspended", "Whether the server is administratively"
102
                      " suspended"),
103
    }
104

  
105
    fields = ["id", "name", "user.uuid", "state", "flavor", "image.id",
106
              "backend"]
107

  
108
    def handle_args(self, *args, **options):
109
        if options["suspended"]:
110
            self.filters["suspended"] = True
111

  
112
        if options["backend_id"]:
113
            backend = get_backend(options["backend_id"])
114
            self.filters["backend"] = backend.id
115

  
116
        if options["build"]:
117
            self.filters["operstate"] = "BUILD"
118

  
119
        if options["image_name"]:
120
            self.fields.replace("image.id", "image.name")
121

  
122
    def handle_db_objects(self, rows, *args, **kwargs):
123
        icache = ImageCache()
124
        for vm in rows:
125
            vm.image = icache.get_image(vm.imageid, vm.userid)
182 126

  
183 127

  
184 128
class ImageCache(object):

Also available in: Unified diff