commit 4500650c320b8a9dfdbd13caf93385e1b0c3abd6
Author: Stratos Psomadakis <psomas@grnet.gr>
Date:   Wed Mar 6 14:07:49 2013 +0200

    Improve server-list usability
    
    Refs #3375

diff --git a/snf-cyclades-app/synnefo/api/management/commands/network-list.py b/snf-cyclades-app/synnefo/api/management/commands/network-list.py
index d7442aa..d8a92ca 100644
--- a/snf-cyclades-app/synnefo/api/management/commands/network-list.py
+++ b/snf-cyclades-app/synnefo/api/management/commands/network-list.py
@@ -34,7 +34,8 @@
 from optparse import make_option
 
 from django.core.management.base import BaseCommand, CommandError
-from synnefo.management.common import format_bool, filter_results, UUIDCache
+from synnefo.management.common import (format_bool, filter_results, UUIDCache,
+                                       Omit)
 from synnefo.db.models import Network
 from synnefo.management.common import pprint_table
 
@@ -60,6 +61,10 @@ class Command(BaseCommand):
             dest='public',
             default=False,
             help="List only public networks"),
+        make_option('--user',
+            dest='user',
+            help="List only networks of the specified user"
+                 " (uuid or display name"),
         make_option('--ipv6',
             action='store_true',
             dest='ipv6',
@@ -71,19 +76,19 @@ class Command(BaseCommand):
                  " that displayed entries must satisfy. e.g."
                  " --filter-by \"name=Network-1,link!=prv0\"."
                  " Available keys are: %s" % ", ".join(FIELDS)),
-        make_option(
-            '--uuids',
+        make_option('--displayname',
             action='store_true',
-            dest='use_uuids',
+            dest='displayname',
             default=False,
-            help="Display UUIDs instead of user emails"),
+            help="Display both uuid and display name"),
         )
 
     def handle(self, *args, **options):
         if args:
             raise CommandError("Command doesn't accept any arguments")
 
-        use_uuids = options["use_uuids"]
+        ucache = UUIDCache()
+
         if options['deleted']:
             networks = Network.objects.all()
         else:
@@ -92,37 +97,56 @@ class Command(BaseCommand):
         if options['public']:
             networks = networks.filter(public=True)
 
+        user = options['user']
+        if user:
+            if '@' in user:
+                user = ucache.get_user(user)
+            networks = networks.filter(userid=user)
+
         filter_by = options['filter_by']
         if filter_by:
             networks = filter_results(networks, filter_by)
 
-        headers = ['id', 'name', 'flavor', 'owner',
-                  'mac_prefix', 'dhcp', 'state', 'link', 'vms', 'public']
+        displayname = options['displayname']
+
+        headers = filter(lambda x: x is not Omit,
+                        ['id',
+                         'name',
+                         'flavor',
+                         'owner_uuid',
+                         'owner_name' if displayname else Omit,
+                         'mac_prefix',
+                         'dhcp',
+                         'state',
+                         'link',
+                         'vms',
+                         'public',
+                         ])
 
         if options['ipv6']:
             headers.extend(['IPv6 Subnet', 'IPv6 Gateway'])
         else:
             headers.extend(['IPv4 Subnet', 'IPv4 Gateway'])
 
-        if not use_uuids:
-            ucache = UUIDCache()
-
         table = []
         for network in networks.order_by("id"):
-            user = network.userid
-            if not use_uuids:
-                user = ucache.get_user(network.userid)
-
-            fields = [str(network.id),
-                      network.name,
-                      network.flavor,
-                      user or '',
-                      network.mac_prefix or '',
-                      str(network.dhcp),
-                      network.state,
-                      network.link or '',
-                      str(network.machines.count()),
-                      format_bool(network.public)]
+            uuid = network.userid
+            if displayname:
+                dname = ucache.get_user(uuid)
+
+            fields = filter(lambda x: x is not Omit,
+                            [str(network.id),
+                             network.name,
+                             network.flavor,
+                             uuid or '-',
+                             dname or '-' if displayname else Omit,
+                             network.mac_prefix or '-',
+                             str(network.dhcp),
+                             network.state,
+                             network.link or '-',
+                             str(network.machines.count()),
+                             format_bool(network.public),
+                             ])
 
             if options['ipv6']:
                 fields.extend([network.subnet6 or '', network.gateway6 or ''])
diff --git a/snf-cyclades-app/synnefo/api/management/commands/server-inspect.py b/snf-cyclades-app/synnefo/api/management/commands/server-inspect.py
index 88530c8..875f166 100644
--- a/snf-cyclades-app/synnefo/api/management/commands/server-inspect.py
+++ b/snf-cyclades-app/synnefo/api/management/commands/server-inspect.py
@@ -37,6 +37,7 @@ from django.core.management.base import BaseCommand, CommandError
 
 from synnefo.lib.utils import merge_time
 from synnefo.logic.rapi import GanetiApiError
+from synnefo.management.common import Omit
 from synnefo.management import common
 
 
@@ -61,11 +62,11 @@ class Command(BaseCommand):
             dest='jobs',
             default=False,
             help="Show non-archived jobs concerning server."),
-        make_option('--uuids',
+        make_option('--displayname',
             action='store_true',
-            dest='use_uuids',
+            dest='displayname',
             default=False,
-            help="Display UUIDs instead of user emails"),
+            help="Display both uuid and display name"),
     )
 
     def handle(self, *args, **options):
@@ -74,26 +75,33 @@ class Command(BaseCommand):
 
         vm = common.get_vm(args[0])
 
+        displayname = options['displayname']
+
+        ucache = common.UUIDCache()
+
         try:
             image = common.get_image(vm.imageid, vm.userid)['name']
         except:
             image = vm.imageid
 
         sep = '-' * 80 + '\n'
-        labels = ('name', 'owner', 'flavor', 'image', 'state', 'backend',
-                  'deleted', 'action', 'backendjobid', 'backendopcode',
-                  'backendjobstatus', 'backend_time')
-
-        user = vm.userid
-        if options['use_uuids'] is False:
-            ucache = common.UUIDCache()
-            user = ucache.get_user(vm.userid)
-
-        fields = (vm.name, user, vm.flavor.name, image,
-                  common.format_vm_state(vm), str(vm.backend),
-                  str(vm.deleted), str(vm.action), str(vm.backendjobid),
-                  str(vm.backendopcode), str(vm.backendjobstatus),
-                  str(vm.backendtime))
+        labels = filter(lambda x: x is not Omit,
+                        ['name', 'owner_uuid',
+                         'owner_name' if displayname else Omit,
+                         'flavor', 'image', 'state', 'backend', 'deleted',
+                         'action', 'backendjobid', 'backendopcode',
+                         'backendjobstatus', 'backend_time'])
+
+        uuid = vm.userid
+        if displayname:
+            dname = ucache.get_user(uuid)
+
+        fields = filter(lambda x: x is not Omit,
+                        [vm.name, uuid, dname if displayname else Omit,
+                         vm.flavor.name, image, common.format_vm_state(vm),
+                         str(vm.backend), str(vm.deleted), str(vm.action),
+                         str(vm.backendjobid), str(vm.backendopcode),
+                         str(vm.backendjobstatus), str(vm.backendtime)])
 
         self.stdout.write(sep)
         self.stdout.write('State of Server in DB\n')
diff --git a/snf-cyclades-app/synnefo/api/management/commands/server-list.py b/snf-cyclades-app/synnefo/api/management/commands/server-list.py
index 7651e4d..ee371ae 100644
--- a/snf-cyclades-app/synnefo/api/management/commands/server-list.py
+++ b/snf-cyclades-app/synnefo/api/management/commands/server-list.py
@@ -34,7 +34,7 @@
 from optparse import make_option
 
 from django.core.management.base import BaseCommand, CommandError
-from synnefo.management.common import (format_vm_state, get_backend,
+from synnefo.management.common import (format_vm_state, get_backend, Omit,
                                        filter_results, pprint_table, UUIDCache)
 from synnefo.api.util import get_image
 from synnefo.db.models import VirtualMachine
@@ -72,25 +72,28 @@ class Command(BaseCommand):
         make_option('--backend-id',
             dest='backend_id',
             help="List only servers of the specified backend"),
+        make_option('--user',
+            dest='user',
+            help="List only servers of the specified user (uuid or email)"),
         make_option('--filter-by',
             dest='filter_by',
             help="Filter results. Comma seperated list of key `cond` val pairs"
                  " that displayed entries must satisfy. e.g."
                  " --filter-by \"operstate=STARTED,id>=22\"."
                  " Available keys are: %s" % ", ".join(FIELDS)),
-        make_option(
-            '--uuids',
+        make_option('--displayname',
             action='store_true',
-            dest='use_uuids',
+            dest='displayname',
             default=False,
-            help="Display UUIDs instead of user emails"),
+            help="Display both uuid and display name"),
     )
 
     def handle(self, *args, **options):
         if args:
             raise CommandError("Command doesn't accept any arguments")
 
-        use_uuids = options["use_uuids"]
+        ucache = UUIDCache()
+
         if options['backend_id']:
             backend = get_backend(options['backend_id'])
             servers = backend.virtual_machines
@@ -108,16 +111,30 @@ class Command(BaseCommand):
         if options['build']:
             servers = servers.filter(operstate='BUILD')
 
+        user = options['user']
+        if user:
+            if '@' in user:
+                user = ucache.get_user(user)
+            servers = servers.filter(userid=user)
+
         filter_by = options['filter_by']
         if filter_by:
             servers = filter_results(servers, filter_by)
 
+        displayname = options['displayname']
+
         cache = ImageCache()
-        if not use_uuids:
-            ucache = UUIDCache()
 
-        headers = ('id', 'name', 'owner', 'flavor', 'image', 'state',
-                   'backend')
+        headers = filter(lambda x: x is not Omit,
+                        ['id',
+                         'name',
+                         'owner_uuid',
+                         'owner_name' if displayname else Omit,
+                         'flavor',
+                         'image',
+                         'state',
+                         'backend',
+                          ])
 
         table = []
         for server in servers.order_by('id'):
@@ -132,12 +149,20 @@ class Command(BaseCommand):
 
             state = format_vm_state(server)
 
-            user = server.userid
-            if not use_uuids:
-                user = ucache.get_user(server.userid)
-
-            fields = (str(server.id), name, user, flavor, image,
-                      state, str(server.backend))
+            uuid = server.userid
+            if displayname:
+                dname = ucache.get_user(server.userid)
+
+            fields = filter(lambda x: x is not Omit,
+                            [str(server.id),
+                             name,
+                             uuid,
+                             dname if displayname else Omit,
+                             flavor,
+                             image,
+                             state,
+                             str(server.backend),
+                            ])
             table.append(fields)
 
         separator = " | " if options['csv'] else None
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/network-inspect.py b/snf-cyclades-app/synnefo/logic/management/commands/network-inspect.py
index a4b6336..99562fa 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/network-inspect.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/network-inspect.py
@@ -36,7 +36,7 @@ import json
 from optparse import make_option
 
 from django.core.management.base import BaseCommand, CommandError
-from synnefo.management.common import get_network, UUIDCache
+from synnefo.management.common import get_network, UUIDCache, Omit
 
 from synnefo.db.models import (Backend, BackendNetwork,
                                pooled_rapi_client)
@@ -48,12 +48,12 @@ class Command(BaseCommand):
     help = "Inspect a network on DB and Ganeti."
 
     option_list = BaseCommand.option_list + (
-        make_option('--uuids',
+        make_option('--displayname',
             action='store_true',
-            dest='use_uuids',
+            dest='displayname',
             default=False,
-            help="Display UUIDs instead of user emails"),
-        )
+            help="Display both uuid and display name"),
+    )
 
     def handle(self, *args, **options):
         write = self.stdout.write
@@ -62,21 +62,28 @@ class Command(BaseCommand):
 
         net = get_network(args[0])
 
+        ucache = UUIDCache()
+
+        displayname = options['displayname']
+
         sep = '-' * 80 + '\n'
-        labels = ('name', 'backend-name', 'state', 'owner', 'subnet',
-                  'gateway', 'mac_prefix', 'link', 'public', 'dhcp', 'flavor',
-                  'deleted', 'action', 'pool')
-
-        user = net.userid
-        if options['use_uuids'] is False:
-            ucache = UUIDCache()
-            user = ucache.get_user(net.userid)
-
-        fields = (net.name, net.backend_id, net.state, user or '',
-                  str(net.subnet), str(net.gateway), str(net.mac_prefix),
-                  str(net.link), str(net.public),  str(net.dhcp),
-                  str(net.flavor), str(net.deleted), str(net.action),
-                  str(splitPoolMap(net.get_pool().to_map(), 64)))
+        labels = filter(lambda x: x is not Omit,
+                        ['name', 'backend-name', 'state', 'owner uuid',
+                         'owner_name' if displayname else Omit, 'subnet',
+                         'gateway', 'mac_prefix', 'link', 'public', 'dhcp',
+                         'flavor', 'deleted', 'action', 'pool'])
+
+        uuid = net.userid
+        if displayname:
+            dname = ucache.get_user(uuid)
+
+        fields = filter(lambda x: x is not Omit,
+                        [net.name, net.backend_id, net.state, uuid or '-',
+                         dname or '-' if displayname else Omit,
+                         str(net.subnet), str(net.gateway), str(net.mac_prefix),
+                         str(net.link), str(net.public),  str(net.dhcp),
+                         str(net.flavor), str(net.deleted), str(net.action),
+                         str(splitPoolMap(net.get_pool().to_map(), 64))])
 
         write(sep)
         write('State of Network in DB\n')
diff --git a/snf-cyclades-app/synnefo/management/common.py b/snf-cyclades-app/synnefo/management/common.py
index 5891014..adb07dc 100644
--- a/snf-cyclades-app/synnefo/management/common.py
+++ b/snf-cyclades-app/synnefo/management/common.py
@@ -268,6 +268,10 @@ class UUIDCache(object):
                                             uuid=uuid)
             except Exception as e:
                 log.error("Can not get display name for uuid %s: %s", uuid, e)
-                return uuid
+                self.users[uuid] = "-"
 
         return self.users[uuid]
+
+
+class Omit(object):
+    pass
