commit a6e6fe485d6484cff4dada1ad50b03fe2c81f4b1
Author: Christos Stavrakakis <cstavr@grnet.gr>
Date:   Thu Feb 27 16:16:13 2014 +0200

    cyclades: Common function to get object by ID
    
    Create common helper function, for command line tools, to get an object
    from DB by it's ID, and raise the appropriate command error if the
    object does not exist or the ID is invalid.

diff --git a/snf-cyclades-app/synnefo/db/models.py b/snf-cyclades-app/synnefo/db/models.py
index 156367e..8d6ca7d 100644
--- a/snf-cyclades-app/synnefo/db/models.py
+++ b/snf-cyclades-app/synnefo/db/models.py
@@ -384,7 +384,7 @@ class VirtualMachine(models.Model):
         return u"<vm:%s@backend:%s>" % (self.id, self.backend_id)
 
     # Error classes
-    class InvalidBackendIdError(Exception):
+    class InvalidBackendIdError(ValueError):
         def __init__(self, value):
             self.value = value
 
@@ -587,7 +587,7 @@ class Network(models.Model):
             free += ip_pool.count_available()
         return total, free
 
-    class InvalidBackendIdError(Exception):
+    class InvalidBackendIdError(ValueError):
         def __init__(self, value):
             self.value = value
 
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/backend-modify.py b/snf-cyclades-app/synnefo/logic/management/commands/backend-modify.py
index a8fcee2..5befd67 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/backend-modify.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/backend-modify.py
@@ -1,4 +1,4 @@
-# Copyright 2012 GRNET S.A. All rights reserved.
+# Copyright 2012-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -35,7 +35,7 @@ from optparse import make_option
 from django.core.management.base import BaseCommand, CommandError
 from synnefo.db.models import Backend
 from snf_django.management.utils import parse_bool
-from synnefo.management.common import (get_backend, check_backend_credentials)
+from synnefo.management import common
 
 HYPERVISORS = [h[0] for h in Backend.HYPERVISORS]
 
@@ -82,7 +82,7 @@ class Command(BaseCommand):
         if len(args) != 1:
             raise CommandError("Please provide a backend ID")
 
-        backend = get_backend(args[0])
+        backend = common.get_resource("backend", args[0], for_update=True)
 
         # Ensure fields correspondence with options and Backend model
         credentials_changed = False
@@ -95,8 +95,10 @@ class Command(BaseCommand):
 
         if credentials_changed:
                 # check credentials, if any of them changed!
-                check_backend_credentials(backend.clustername, backend.port,
-                                          backend.username, backend.password)
+                common.check_backend_credentials(backend.clustername,
+                                                 backend.port,
+                                                 backend.username,
+                                                 backend.password)
         if options['drained']:
             backend.drained = parse_bool(options['drained'], strict=True)
         if options['offline']:
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/backend-remove.py b/snf-cyclades-app/synnefo/logic/management/commands/backend-remove.py
index efdb96f..e034813 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/backend-remove.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/backend-remove.py
@@ -1,4 +1,4 @@
-# Copyright 2011-2012 GRNET S.A. All rights reserved.
+# Copyright 2011-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -29,7 +29,7 @@
 #
 
 from django.core.management.base import BaseCommand, CommandError
-from synnefo.management.common import get_backend
+from synnefo.management import common
 from synnefo.logic import backend as backend_mod
 from synnefo.db.models import Backend
 from django.db import transaction, models
@@ -50,7 +50,7 @@ class Command(BaseCommand):
         if len(args) < 1:
             raise CommandError("Please provide a backend ID")
 
-        backend = get_backend(args[0])
+        backend = common.get_resource("backend", args[0], for_update=True)
 
         write("Trying to remove backend: %s\n" % backend.clustername)
 
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/flavor-modify.py b/snf-cyclades-app/synnefo/logic/management/commands/flavor-modify.py
index fe7bff7..4255061 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/flavor-modify.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/flavor-modify.py
@@ -1,4 +1,4 @@
-# Copyright 2012 GRNET S.A. All rights reserved.
+# Copyright 2012-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -34,7 +34,7 @@
 from optparse import make_option
 
 from django.core.management.base import BaseCommand, CommandError
-from synnefo.management.common import get_flavor
+from synnefo.management.common import get_resource
 from snf_django.management.utils import parse_bool
 
 
@@ -67,7 +67,7 @@ class Command(BaseCommand):
         if len(args) != 1:
             raise CommandError("Please provide a flavor ID")
 
-        flavor = get_flavor(args[0], for_update=True)
+        flavor = get_resource("flavor", args[0], for_update=True)
 
         deleted = options['deleted']
 
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-attach.py b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-attach.py
index d11c1f3..f5265f1 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-attach.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-attach.py
@@ -1,4 +1,4 @@
-# Copyright 2012 GRNET S.A. All rights reserved.
+# Copyright 2012-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -61,9 +61,9 @@ class Command(BaseCommand):
             raise CommandError('Please give either a server or a router id')
 
         #get the vm
-        vm = common.get_vm(device, for_update=True)
-        floating_ip = common.get_floating_ip_by_id(floating_ip_id,
-                                                   for_update=True)
+        vm = common.get_resource("server", device, for_update=True)
+        floating_ip = common.get_resource("floating-ip", floating_ip_id,
+                                          for_update=True)
         servers.create_port(vm.userid, floating_ip.network,
                             use_ipaddress=floating_ip, machine=vm)
 
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-create.py b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-create.py
index 7fe91d2..291f141 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-create.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-create.py
@@ -1,4 +1,4 @@
-# Copyright 2012 GRNET S.A. All rights reserved.
+# Copyright 2012-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -71,8 +71,9 @@ class Command(BaseCommand):
             raise CommandError("'owner' is required for floating IP creation")
 
         if network_id is not None:
-            network = util.get_network(network_id, owner, for_update=True,
-                                       non_deleted=True)
+            network = util.get_resource("network", network_id, for_update=True)
+            if network.deleted:
+                raise CommandError("Network '%s' is deleted" % network.id)
             if not network.floating_ip_pool:
                 raise CommandError("Network '%s' is not a floating IP pool."
                                    % network)
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-detach.py b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-detach.py
index 0fa8a6f..e2371a6 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-detach.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-detach.py
@@ -1,4 +1,4 @@
-# Copyright 2012 GRNET S.A. All rights reserved.
+# Copyright 2012-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -49,8 +49,8 @@ class Command(BaseCommand):
         floating_ip_id = args[0]
 
         #get the floating-ip
-        floating_ip = common.get_floating_ip_by_id(floating_ip_id,
-                                                   for_update=True)
+        floating_ip = common.get_resource("floating-ip", floating_ip_id,
+                                          for_update=True)
 
         if not floating_ip.nic:
             raise CommandError('This floating IP is not attached to a device')
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-remove.py b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-remove.py
index 3ab761a..c4fefcc 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-remove.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-remove.py
@@ -1,4 +1,4 @@
-# Copyright 2013 GRNET S.A. All rights reserved.
+# Copyright 2013-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -57,8 +57,9 @@ class Command(RemoveCommand):
         for floating_ip_id in args:
             self.stdout.write("\n")
             try:
-                floating_ip = common.get_floating_ip_by_id(floating_ip_id,
-                                                           for_update=True)
+                floating_ip = common.get_resource("floating-ip",
+                                                  floating_ip_id,
+                                                  for_update=True)
                 ips.delete_floating_ip(floating_ip)
                 self.stdout.write("Deleted floating IP '%s'.\n" %
                                   floating_ip_id)
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 85b952a..8a033f4 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/network-inspect.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/network-inspect.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2013 GRNET S.A. All rights reserved.
+# Copyright 2012-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -54,7 +54,7 @@ class Command(BaseCommand):
         if len(args) != 1:
             raise CommandError("Please provide a network ID.")
 
-        network = common.get_network(args[0])
+        network = common.get_resource("network", args[0])
         displayname = options['displayname']
 
         pprint.pprint_network(network, display_mails=displayname,
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/network-modify.py b/snf-cyclades-app/synnefo/logic/management/commands/network-modify.py
index 947ea7f..0298b1f 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/network-modify.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/network-modify.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2013 GRNET S.A. All rights reserved.
+# Copyright 2012-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -36,7 +36,7 @@ from optparse import make_option
 from django.core.management.base import BaseCommand, CommandError
 
 from synnefo.db.models import Backend
-from synnefo.management.common import (get_network, get_backend)
+from synnefo.management.common import get_resource
 from snf_django.management.utils import parse_bool
 from synnefo.logic import networks, backend as backend_mod
 from django.db import transaction
@@ -95,7 +95,7 @@ class Command(BaseCommand):
         if len(args) != 1:
             raise CommandError("Please provide a network ID")
 
-        network = get_network(args[0])
+        network = get_resource("network", args[0])
 
         new_name = options.get("name")
         if new_name is not None:
@@ -159,7 +159,7 @@ class Command(BaseCommand):
 
         add_to_backend = options["add_to_backend"]
         if add_to_backend is not None:
-            backend = get_backend(add_to_backend)
+            backend = get_resource("backend", add_to_backend)
             bnet, jobs = backend_mod.ensure_network_is_active(backend,
                                                               network.id)
             if jobs:
@@ -168,7 +168,7 @@ class Command(BaseCommand):
 
         remove_from_backend = options["remove_from_backend"]
         if remove_from_backend is not None:
-            backend = get_backend(remove_from_backend)
+            backend = get_resource("backend", remove_from_backend)
             if network.nics.filter(machine__backend=backend,
                                    machine__deleted=False).exists():
                 msg = "Cannot remove. There are still connected VMs to this"\
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/network-remove.py b/snf-cyclades-app/synnefo/logic/management/commands/network-remove.py
index 2f2b866..1e1fd5b 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/network-remove.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/network-remove.py
@@ -1,4 +1,4 @@
-# Copyright 2011-2013 GRNET S.A. All rights reserved.
+# Copyright 2011-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -32,7 +32,7 @@ from django.core.management.base import CommandError
 from snf_django.management.commands import RemoveCommand
 from snf_django.lib.api import faults
 from synnefo.logic import networks
-from synnefo.management.common import get_network, convert_api_faults
+from synnefo.management import common
 
 
 class Command(RemoveCommand):
@@ -40,7 +40,7 @@ class Command(RemoveCommand):
     args = "<Network ID> [<Network ID> ...]"
     help = "Remove a network from the Database, and Ganeti"
 
-    @convert_api_faults
+    @common.convert_api_faults
     def handle(self, *args, **options):
         if not args:
             raise CommandError("Please provide a network ID")
@@ -52,7 +52,8 @@ class Command(RemoveCommand):
         for network_id in args:
             self.stdout.write("\n")
             try:
-                network = get_network(network_id, for_update=True)
+                network = common.get_resource("network", network_id,
+                                              for_update=True)
                 self.stdout.write('Removing network: %s\n' %
                                   network.backend_id)
 
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/port-create.py b/snf-cyclades-app/synnefo/logic/management/commands/port-create.py
index aaea096..63b1cb0 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/port-create.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/port-create.py
@@ -1,4 +1,4 @@
-# Copyright 2013 GRNET S.A. All rights reserved.
+# Copyright 2013-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -127,12 +127,12 @@ class Command(BaseCommand):
         owner = None
         if server_id:
             owner = "vm"
-            vm = common.get_vm(server_id, for_update=True)
+            vm = common.get_resource("server", server_id, for_update=True)
             #if vm.router:
             #    raise CommandError("Server '%s' does not exist." % server_id)
         elif router_id:
             owner = "router"
-            vm = common.get_vm(router_id, for_update=True)
+            vm = common.get_resource("server", router_id, for_update=True)
             if not vm.router:
                 raise CommandError("Router '%s' does not exist." % router_id)
 
@@ -143,21 +143,20 @@ class Command(BaseCommand):
                 raise CommandError("Please specify the owner of the port.")
 
         # get the network
-        network = common.get_network(network_id)
+        network = common.get_resource("network", network_id)
 
         # Get either floating IP or fixed ip address
         ipaddress = None
         floating_ip_id = options["floating_ip_id"]
         ipv4_address = options["ipv4_address"]
         if floating_ip_id:
-            ipaddress = common.get_floating_ip_by_id(floating_ip_id,
-                                                     for_update=True)
+            ipaddress = common.get_resource("floating-ip", floating_ip_id,
+                                            for_update=True)
             if ipv4_address is not None and ipaddress.address != ipv4_address:
                 raise CommandError("Floating IP address '%s' is different from"
                                    " specified address '%s'" %
                                    (ipaddress.address, ipv4_address))
 
-
         # validate security groups
         sg_list = []
         if security_group_ids:
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/port-inspect.py b/snf-cyclades-app/synnefo/logic/management/commands/port-inspect.py
index 87e7a29..ebd6bf6 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/port-inspect.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/port-inspect.py
@@ -1,4 +1,4 @@
-# Copyright 2013 GRNET S.A. All rights reserved.
+# Copyright 2013-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -62,7 +62,7 @@ class Command(BaseCommand):
         if len(args) != 1:
             raise CommandError("Please provide a port ID")
 
-        port = common.get_port(args[0])
+        port = common.get_resource("port", args[0])
 
         pprint.pprint_port(port, stdout=self.stdout)
         self.stdout.write('\n\n')
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/port-remove.py b/snf-cyclades-app/synnefo/logic/management/commands/port-remove.py
index e416821..608a25b 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/port-remove.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/port-remove.py
@@ -1,4 +1,4 @@
-# Copyright 2011-2013 GRNET S.A. All rights reserved.
+# Copyright 2011-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -62,7 +62,7 @@ class Command(RemoveCommand):
         for port_id in args:
             self.stdout.write("\n")
             try:
-                port = common.get_port(port_id, for_update=True)
+                port = common.get_resource("port", port_id, for_update=True)
 
                 servers.delete_port(port)
 
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/reconcile-servers.py b/snf-cyclades-app/synnefo/logic/management/commands/reconcile-servers.py
index f2b0fbb..db38ec9 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/reconcile-servers.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/reconcile-servers.py
@@ -1,4 +1,4 @@
-# Copyright 2011-2013 GRNET S.A. All rights reserved.
+# Copyright 2011-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -39,7 +39,7 @@ import logging
 import subprocess
 from optparse import make_option
 from django.core.management.base import BaseCommand
-from synnefo.management.common import get_backend
+from synnefo.management.common import get_resource
 from synnefo.logic import reconciliation
 from snf_django.management.utils import parse_bool
 
@@ -87,7 +87,7 @@ class Command(BaseCommand):
     def handle(self, **options):
         backend_id = options['backend-id']
         if backend_id:
-            backends = [get_backend(backend_id)]
+            backends = [get_resource("backend", backend_id)]
         else:
             backends = reconciliation.get_online_backends()
 
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/server-create.py b/snf-cyclades-app/synnefo/logic/management/commands/server-create.py
index 7c60ed7..b356035 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/server-create.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/server-create.py
@@ -1,4 +1,4 @@
-# Copyright 2012 GRNET S.A. All rights reserved.
+# Copyright 2012-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -108,10 +108,10 @@ class Command(BaseCommand):
         if not image_id:
             raise CommandError("image-id is mandatory")
 
-        flavor = common.get_flavor(flavor_id)
+        flavor = common.get_resource("flavor", flavor_id)
         image = common.get_image(image_id, user_id)
         if backend_id:
-            backend = common.get_backend(backend_id)
+            backend = common.get_resource("backend", backend_id)
         else:
             backend = None
 
@@ -147,7 +147,8 @@ def parse_connections(con_list):
                     val = {"port": port_id}
                 elif con_kind == "floatingip":
                     fip_id = opt.split(":")[1]
-                    fip = common.get_floating_ip_by_id(fip_id, for_update=True)
+                    fip = common.get_resource("floating-ip", fip_id,
+                                              for_update=True)
                     val = {"uuid": fip.network_id, "fixed_ip": fip.address}
                 else:
                     raise CommandError("Unknown argument for option --port")
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/server-import.py b/snf-cyclades-app/synnefo/logic/management/commands/server-import.py
index beea38b..a3f32b2 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/server-import.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/server-import.py
@@ -129,8 +129,8 @@ class Command(BaseCommand):
 
 def import_server(instance_name, backend_id, flavor_id, image_id, user_id,
                   new_public_nic, stream=sys.stdout):
-    flavor = common.get_flavor(flavor_id)
-    backend = common.get_backend(backend_id)
+    flavor = common.get_resource("flavor", flavor_id)
+    backend = common.get_resource("backend", backend_id)
 
     backend_client = backend.get_client()
 
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/server-inspect.py b/snf-cyclades-app/synnefo/logic/management/commands/server-inspect.py
index c581728..d00b0d0 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/server-inspect.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/server-inspect.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2013 GRNET S.A. All rights reserved.
+# Copyright 2012-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -61,7 +61,7 @@ class Command(BaseCommand):
         if len(args) != 1:
             raise CommandError("Please provide a server ID")
 
-        vm = common.get_vm(args[0], for_update=True)
+        vm = common.get_resource("server", args[0], for_update=True)
 
         displayname = options['displayname']
 
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/server-list.py b/snf-cyclades-app/synnefo/logic/management/commands/server-list.py
index 4255490..66aaefa 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/server-list.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/server-list.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2013 GRNET S.A. All rights reserved.
+# Copyright 2012-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -36,7 +36,7 @@ from functools import partial
 
 from snf_django.management.commands import ListCommand
 from synnefo.db.models import VirtualMachine
-from synnefo.management.common import get_backend
+from synnefo.management.common import get_resource
 from synnefo.api.util import get_image
 from synnefo.settings import (CYCLADES_SERVICE_TOKEN as ASTAKOS_TOKEN,
                               ASTAKOS_AUTH_URL)
@@ -120,7 +120,7 @@ class Command(ListCommand):
             self.filters["suspended"] = True
 
         if options["backend_id"]:
-            backend = get_backend(options["backend_id"])
+            backend = get_resource("backend", options["backend_id"])
             self.filters["backend"] = backend.id
 
         if options["build"]:
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/server-modify.py b/snf-cyclades-app/synnefo/logic/management/commands/server-modify.py
index b7fe481..531fd4e 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/server-modify.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/server-modify.py
@@ -1,4 +1,4 @@
-# Copyright 2013 GRNET S.A. All rights reserved.
+# Copyright 2013-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -35,7 +35,7 @@ from optparse import make_option
 
 from django.db import transaction
 from django.core.management.base import BaseCommand, CommandError
-from synnefo.management.common import (get_vm, get_flavor, convert_api_faults,
+from synnefo.management.common import (get_resource, convert_api_faults,
                                        wait_server_task)
 from snf_django.management.utils import parse_bool
 from synnefo.logic import servers
@@ -93,7 +93,7 @@ class Command(BaseCommand):
         if len(args) != 1:
             raise CommandError("Please provide a server ID")
 
-        server = get_vm(args[0], for_update=True)
+        server = get_resource("server", args[0], for_update=True)
 
         new_name = options.get("name", None)
         if new_name is not None:
@@ -123,7 +123,7 @@ class Command(BaseCommand):
         wait = parse_bool(options["wait"])
         new_flavor_id = options.get("flavor")
         if new_flavor_id is not None:
-            new_flavor = get_flavor(new_flavor_id)
+            new_flavor = get_resource("flavor", new_flavor_id)
             old_flavor = server.flavor
             msg = "Resizing server '%s' from flavor '%s' to '%s'.\n"
             self.stdout.write(msg % (server, old_flavor, new_flavor))
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/server-remove.py b/snf-cyclades-app/synnefo/logic/management/commands/server-remove.py
index 86a6b9d..791dacf 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/server-remove.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/server-remove.py
@@ -1,4 +1,4 @@
-# Copyright 2013 GRNET S.A. All rights reserved.
+# Copyright 2013-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -34,7 +34,7 @@
 from optparse import make_option
 
 from django.core.management.base import CommandError
-from synnefo.management.common import (get_vm, convert_api_faults,
+from synnefo.management.common import (get_resource, convert_api_faults,
                                        wait_server_task)
 from synnefo.logic import servers
 from snf_django.management.commands import RemoveCommand
@@ -68,7 +68,7 @@ class Command(RemoveCommand):
         for server_id in args:
             self.stdout.write("\n")
             try:
-                server = get_vm(server_id)
+                server = get_resource("server", server_id, for_update=True)
 
                 self.stdout.write("Trying to remove server '%s' from backend "
                                   "'%s' \n" % (server.backend_vm_id,
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/server-show.py b/snf-cyclades-app/synnefo/logic/management/commands/server-show.py
index 6f42c73..790c650 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/server-show.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/server-show.py
@@ -1,4 +1,4 @@
-# Copyright 2012 GRNET S.A. All rights reserved.
+# Copyright 2012-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -33,7 +33,7 @@
 
 from django.core.management.base import CommandError
 from snf_django.management.commands import SynnefoCommand
-from synnefo.management.common import (format_vm_state, get_vm,
+from synnefo.management.common import (format_vm_state, get_resource,
                                        get_image)
 from snf_django.lib.astakos import UserCache
 from synnefo.settings import (CYCLADES_SERVICE_TOKEN as ASTAKOS_TOKEN,
@@ -49,7 +49,7 @@ class Command(SynnefoCommand):
         if len(args) != 1:
             raise CommandError("Please provide a server ID")
 
-        server = get_vm(args[0])
+        server = get_resource("server", args[0])
 
         flavor = '%s (%s)' % (server.flavor.id, server.flavor.name)
         userid = server.userid
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/stats-cyclades.py b/snf-cyclades-app/synnefo/logic/management/commands/stats-cyclades.py
index 87eb72f..1aa9a83 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/stats-cyclades.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/stats-cyclades.py
@@ -1,4 +1,4 @@
-# Copyright 2013 GRNET S.A. All rights reserved.
+# Copyright 2013-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -31,7 +31,6 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-
 import json
 import string
 
@@ -40,7 +39,7 @@ from optparse import make_option
 from snf_django.management.utils import pprint_table, parse_bool
 
 from snf_django.management.commands import SynnefoCommand, CommandError
-from synnefo.management.common import get_backend
+from synnefo.management.common import get_resource
 from synnefo.admin import stats as statistics
 
 
@@ -87,7 +86,7 @@ class Command(SynnefoCommand):
 
     def handle(self, *args, **options):
         if options["backend"] is not None:
-            backend = get_backend(options["backend"])
+            backend = get_resource("backend", options["backend"])
         else:
             backend = None
 
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/subnet-create.py b/snf-cyclades-app/synnefo/logic/management/commands/subnet-create.py
index ce43797..e12fded 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/subnet-create.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/subnet-create.py
@@ -1,4 +1,4 @@
-# Copyright 2013 GRNET S.A. All rights reserved.
+# Copyright 2013-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -39,8 +39,6 @@ from snf_django.management.utils import parse_bool
 from synnefo.management import pprint
 from synnefo.logic import subnets
 
-import ipaddr
-
 HELP_MSG = """
 
 Create a new subnet without authenticating the user. The limit of one
@@ -103,7 +101,7 @@ class Command(BaseCommand):
         if not cidr:
             raise CommandError("cidr is mandatory")
 
-        user_id = common.get_network(network_id).userid
+        user_id = common.get_resource("network", network_id).userid
         name = options["name"] or ""
         allocation_pools = options["allocation_pools"]
         ipversion = options["ipversion"] or 4
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/subnet-inspect.py b/snf-cyclades-app/synnefo/logic/management/commands/subnet-inspect.py
index 922fa7a..b2f7a62 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/subnet-inspect.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/subnet-inspect.py
@@ -31,7 +31,7 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from optparse import make_option
+#from optparse import make_option
 
 from django.core.management.base import BaseCommand, CommandError
 from synnefo.management import pprint, common
@@ -46,7 +46,7 @@ class Command(BaseCommand):
         if len(args) != 1:
             raise CommandError("Please provide a subnet ID.")
 
-        subnet = common.get_subnet(args[0])
+        subnet = common.get_resource("subnet", args[0])
 
         pprint.pprint_subnet_in_db(subnet, stdout=self.stdout)
         self.stdout.write("\n\n")
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/subnet-modify.py b/snf-cyclades-app/synnefo/logic/management/commands/subnet-modify.py
index 81412f9..bbbd645 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/subnet-modify.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/subnet-modify.py
@@ -1,4 +1,4 @@
-# Copyright 2013 GRNET S.A. All rights reserved.
+# Copyright 2013-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -66,8 +66,8 @@ class Command(BaseCommand):
         if not name:
             raise CommandError("--name is mandatory")
 
-        subnet = common.get_subnet(subnet_id)
-        user_id = common.get_network(subnet.network.id).userid
+        subnet = common.get_resource("subnet", subnet_id, for_update=True)
+        user_id = common.get_resource("network", subnet.network.id).userid
 
         subnets.update_subnet(sub_id=subnet_id,
                               name=name,
diff --git a/snf-cyclades-app/synnefo/management/common.py b/snf-cyclades-app/synnefo/management/common.py
index 87021e3..a9754ca 100644
--- a/snf-cyclades-app/synnefo/management/common.py
+++ b/snf-cyclades-app/synnefo/management/common.py
@@ -1,4 +1,4 @@
-# Copyright 2012 GRNET S.A. All rights reserved.
+# Copyright 2012-2014 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
@@ -35,16 +35,18 @@ from django.core.management import CommandError
 from synnefo.db.models import (Backend, VirtualMachine, Network,
                                Flavor, IPAddress, Subnet,
                                BridgePoolTable, MacPrefixPoolTable,
-                               NetworkInterface, IPAddressLog)
+                               NetworkInterface)
 from functools import wraps
 
+from django.conf import settings
 from snf_django.lib.api import faults
 from synnefo.api import util
 from synnefo.logic import backend as backend_mod
 from synnefo.logic.rapi import GanetiApiError, GanetiRapiClient
 from synnefo.logic.utils import (id_from_instance_name,
-                                 id_from_network_name)
-
+                                 id_from_network_name,
+                                 id_from_nic_name)
+from django.core.exceptions import ObjectDoesNotExist
 import logging
 log = logging.getLogger(__name__)
 
@@ -55,17 +57,52 @@ def format_vm_state(vm):
     else:
         return vm.operstate
 
+RESOURCE_MAP = {
+    "backend": Backend.objects,
+    "flavor": Flavor.objects,
+    "server": VirtualMachine.objects,
+    "network": Network.objects,
+    "subnet": Subnet.objects,
+    "port": NetworkInterface.objects,
+    "floating-ip": IPAddress.objects.filter(floating_ip=True)}
+
+
+def get_resource(name, value, for_update=False):
+    """Get object from DB based by it's ID
+
+    Helper function for getting an object from DB by it's DB and raising
+    appropriate command line errors if the object does not exist or the
+    ID is invalid.
 
-def get_backend(backend_id):
+    """
+    objects = RESOURCE_MAP[name]
+    if name == "floating-ip":
+        capital_name = "Floating IP"
+    else:
+        capital_name = name.capitalize()
+
+    if name in ["server", "network", "port"]:
+        try:
+            if value.startswith(settings.BACKEND_PREFIX_ID):
+                if name == "server":
+                    value = id_from_instance_name(value)
+                elif name == "network":
+                    value = id_from_network_name(value)
+                elif name == "port":
+                    value = id_from_nic_name(value)
+        except ValueError:
+            raise CommandError("Invalid {} ID: {}".format(capital_name, value))
+
+    if for_update:
+        objects = objects.select_for_update()
     try:
-        backend_id = int(backend_id)
-        return Backend.objects.get(id=backend_id)
-    except ValueError:
-        raise CommandError("Invalid Backend ID: %s" % backend_id)
-    except Backend.DoesNotExist:
-        raise CommandError("Backend with ID %s not found in DB. "
-                           " Use snf-manage backend-list to find"
-                           " out available backend IDs." % backend_id)
+        return objects.get(id=value)
+    except ObjectDoesNotExist:
+        msg = ("{0} with ID {1} does not exist. Use {2}-list to find out"
+               " available {2} IDs.")
+        raise CommandError(msg.format(capital_name, value, name))
+    except (ValueError, TypeError):
+        raise CommandError("Invalid {} ID: {}".format(capital_name, value))
 
 
 def get_image(image_id, user_id):
@@ -80,144 +117,6 @@ def get_image(image_id, user_id):
         raise CommandError("image-id is mandatory")
 
 
-def get_vm(server_id, for_update=False):
-    """Get a VirtualMachine object by its ID.
-
-    @type server_id: int or string
-    @param server_id: The server's DB id or the Ganeti name
-
-    """
-    try:
-        server_id = int(server_id)
-    except (ValueError, TypeError):
-        try:
-            server_id = id_from_instance_name(server_id)
-        except VirtualMachine.InvalidBackendIdError:
-            raise CommandError("Invalid server ID: %s" % server_id)
-
-    try:
-        objs = VirtualMachine.objects
-        if for_update:
-            objs = objs.select_for_update()
-        return objs.get(id=server_id)
-    except VirtualMachine.DoesNotExist:
-        raise CommandError("Server with ID %s not found in DB."
-                           " Use snf-manage server-list to find out"
-                           " available server IDs." % server_id)
-
-
-def get_network(network_id, for_update=True):
-    """Get a Network object by its ID.
-
-    @type network_id: int or string
-    @param network_id: The networks DB id or the Ganeti name
-
-    """
-
-    try:
-        network_id = int(network_id)
-    except (ValueError, TypeError):
-        try:
-            network_id = id_from_network_name(network_id)
-        except Network.InvalidBackendIdError:
-            raise CommandError("Invalid network ID: %s" % network_id)
-
-    networks = Network.objects
-    if for_update:
-        networks = networks.select_for_update()
-    try:
-        return networks.get(id=network_id)
-    except Network.DoesNotExist:
-        raise CommandError("Network with ID %s not found in DB."
-                           " Use snf-manage network-list to find out"
-                           " available network IDs." % network_id)
-
-
-def get_subnet(subnet_id, for_update=True):
-    """Get a Subnet object by its ID."""
-    try:
-        subet_id = int(subnet_id)
-    except (ValueError, TypeError):
-        raise CommandError("Invalid subnet ID: %s" % subnet_id)
-
-    try:
-        subnets = Subnet.objects
-        if for_update:
-            subnets.select_for_update()
-        return subnets.get(id=subnet_id)
-    except Subnet.DoesNotExist:
-        raise CommandError("Subnet with ID %s not found in DB."
-                           " Use snf-manage subnet-list to find out"
-                           " available subnet IDs" % subnet_id)
-
-
-def get_port(port_id, for_update=True):
-    """Get a port object by its ID."""
-    try:
-        port_id = int(port_id)
-    except (ValueError, TypeError):
-        raise CommandError("Invalid port ID: %s" % port_id)
-
-    try:
-        ports = NetworkInterface.objects
-        if for_update:
-            ports.select_for_update()
-        return ports.get(id=port_id)
-    except NetworkInterface.DoesNotExist:
-        raise CommandError("Port with ID %s not found in DB."
-                           " Use snf-manage port-list to find out"
-                           " available port IDs" % port_id)
-
-
-def get_flavor(flavor_id, for_update=False):
-    try:
-        flavor_id = int(flavor_id)
-        objs = Flavor.objects
-        if for_update:
-            objs = objs.select_for_update()
-        return objs.get(id=flavor_id)
-    except ValueError:
-        raise CommandError("Invalid flavor ID: %s", flavor_id)
-    except Flavor.DoesNotExist:
-        raise CommandError("Flavor with ID %s not found in DB."
-                           " Use snf-manage flavor-list to find out"
-                           " available flavor IDs." % flavor_id)
-
-
-def get_floating_ip_by_address(address, for_update=False):
-    try:
-        objects = IPAddress.objects
-        if for_update:
-            objects = objects.select_for_update()
-        return objects.get(floating_ip=True, address=address, deleted=False)
-    except IPAddress.DoesNotExist:
-        raise CommandError("Floating IP does not exist.")
-
-
-def get_floating_ip_log_by_address(address):
-    try:
-        objects = IPAddressLog.objects
-        return objects.filter(address=address).order_by("released_at")
-    except IPAddressLog.DoesNotExist:
-        raise CommandError("Floating IP does not exist or it hasn't be"
-                           "attached to any server yet")
-
-
-def get_floating_ip_by_id(floating_ip_id, for_update=False):
-    try:
-        floating_ip_id = int(floating_ip_id)
-    except (ValueError, TypeError):
-        raise CommandError("Invalid floating-ip ID: %s" % floating_ip_id)
-
-    try:
-        objects = IPAddress.objects
-        if for_update:
-            objects = objects.select_for_update()
-        return objects.get(floating_ip=True, id=floating_ip_id, deleted=False)
-    except IPAddress.DoesNotExist:
-        raise CommandError("Floating IP %s does not exist." % floating_ip_id)
-
-
 def check_backend_credentials(clustername, port, username, password):
     try:
         client = GanetiRapiClient(clustername, port, username, password)
diff --git a/snf-cyclades-app/synnefo/tools/add_unique_name_to_nics b/snf-cyclades-app/synnefo/tools/add_unique_name_to_nics
index 5fa3384..6f27d04 100755
--- a/snf-cyclades-app/synnefo/tools/add_unique_name_to_nics
+++ b/snf-cyclades-app/synnefo/tools/add_unique_name_to_nics
@@ -29,7 +29,7 @@ setup_environ(settings)
 
 from django.db import close_connection
 from synnefo.db.models import Backend, pooled_rapi_client
-from synnefo.management.common import get_backend
+from synnefo.management.common import get_resource
 
 import logging
 logger = logging.getLogger("migrate_nics")
@@ -67,7 +67,7 @@ def main():
     options, args = parser.parse_args()
 
     if options.backend_id:
-        backends = [get_backend(options.backend_id)]
+        backends = [get_resource("backend", options.backend_id)]
     else:
         if Backend.objects.filter(offline=True).exists():
             msg = "Can not update intances. An 'offline' backend exists."
