]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Making the client raise the appropriate exception if needed. Also increasing the...
authorTyler Smith <tylesmit@cisco.com>
Thu, 18 Aug 2011 19:49:20 +0000 (12:49 -0700)
committerTyler Smith <tylesmit@cisco.com>
Thu, 18 Aug 2011 19:49:20 +0000 (12:49 -0700)
quantum/client.py
quantum/common/exceptions.py

index 517ba6d6675d6950535f24e97b17c37c2138d4f6..b2459ea57d828f961c837549c91c1abb16408f22 100644 (file)
@@ -20,16 +20,32 @@ import httplib
 import socket
 import urllib
 from quantum.common.wsgi import Serializer
-
-
-class api_call(object):
+from quantum.common import exceptions
+
+EXCEPTIONS = {
+    400: exceptions.BadInputError,
+    401: exceptions.NotAuthorized,
+    420: exceptions.NetworkNotFound,
+    421: exceptions.NetworkInUse,
+    422: exceptions.NetworkNameExists,
+    430: exceptions.PortNotFound,
+    431: exceptions.StateInvalid,
+    432: exceptions.PortInUse,
+    440: exceptions.AlreadyAttached,
+    441: exceptions.AttachmentNotReady,
+}
+
+
+class ApiCall(object):
     """A Decorator to add support for format and tenant overriding"""
-    def __init__(self, f):
-        self.f = f
+    def __init__(self, function):
+        self.function = function
 
     def __get__(self, instance, owner):
         def with_params(*args, **kwargs):
-            # Temporarily set format and tenant for this request
+            """
+            Temporarily sets the format and tenant for this request
+            """
             (format, tenant) = (instance.format, instance.tenant)
 
             if 'format' in kwargs:
@@ -37,7 +53,7 @@ class api_call(object):
             if 'tenant' in kwargs:
                 instance.tenant = kwargs['tenant']
 
-            ret = self.f(instance, *args)
+            ret = self.function(instance, *args)
             (instance.format, instance.tenant) = (format, tenant)
             return ret
         return with_params
@@ -49,7 +65,7 @@ class Client(object):
 
     action_prefix = '/v0.1/tenants/{tenant_id}'
 
-    """Action query strings"""
+    # Action query strings
     networks_path = "/networks"
     network_path = "/networks/%s"
     ports_path = "/networks/%s/ports"
@@ -133,9 +149,9 @@ class Client(object):
             certs = dict((x, certs[x]) for x in certs if certs[x] != None)
 
             if self.use_ssl and len(certs):
-                c = connection_type(self.host, self.port, **certs)
+                conn = connection_type(self.host, self.port, **certs)
             else:
-                c = connection_type(self.host, self.port)
+                conn = connection_type(self.host, self.port)
 
             if self.logger:
                 self.logger.debug("Quantum Client Request:\n" \
@@ -143,7 +159,7 @@ class Client(object):
                 if body:
                     self.logger.debug(body)
 
-            c.request(method, action, body, headers)
+            conn.request(method, action, body, headers)
             res = c.getresponse()
             status_code = self.get_status_code(res)
             data = res.read()
@@ -158,6 +174,8 @@ class Client(object):
                                httplib.NO_CONTENT):
                 return self.deserialize(data, status_code)
             else:
+                if res.status in EXCEPTIONS:
+                    raise EXCEPTIONS[res.status]()
                 raise Exception("Server returned error: %s" % res.read())
 
         except (socket.error, IOError), e:
@@ -175,6 +193,10 @@ class Client(object):
             return response.status
 
     def serialize(self, data):
+        """
+        Serializes a dictionary with a single key (which can contain any
+        structure) into either xml or json
+        """
         if data is None:
             return None
         elif type(data) is dict:
@@ -184,65 +206,72 @@ class Client(object):
                                 % type(data))
 
     def deserialize(self, data, status_code):
+        """
+        Deserializes a an xml or json string into a dictionary
+        """
         if status_code == 202:
             return data
         return Serializer().deserialize(data, self.content_type())
 
     def content_type(self, format=None):
+        """
+        Returns the mime-type for either 'xml' or 'json'.  Defaults to the
+        currently set format
+        """
         if not format:
             format = self.format
         return "application/%s" % (format)
 
-    @api_call
+    @ApiCall
     def list_networks(self):
         """
         Fetches a list of all networks for a tenant
         """
         return self.do_request("GET", self.networks_path)
 
-    @api_call
+    @ApiCall
     def show_network_details(self, network):
         """
         Fetches the details of a certain network
         """
         return self.do_request("GET", self.network_path % (network))
 
-    @api_call
+    @ApiCall
     def create_network(self, body=None):
         """
         Creates a new network
         """
         return self.do_request("POST", self.networks_path, body=body)
 
-    @api_call
+    @ApiCall
     def update_network(self, network, body=None):
         """
         Updates a network
         """
         return self.do_request("PUT", self.network_path % (network), body=body)
 
-    @api_call
+    @ApiCall
     def delete_network(self, network):
         """
         Deletes the specified network
         """
         return self.do_request("DELETE", self.network_path % (network))
 
-    @api_call
+    @ApiCall
     def list_ports(self, network):
         """
         Fetches a list of ports on a given network
         """
         return self.do_request("GET", self.ports_path % (network))
 
-    @api_call
+    @ApiCall
     def show_port_details(self, network, port):
         """
         Fetches the details of a certain port
         """
         return self.do_request("GET", self.port_path % (network, port))
 
-    @api_call
+    @ApiCall
     def create_port(self, network, body=None):
         """
         Creates a new port on a given network
@@ -250,14 +279,14 @@ class Client(object):
         body = self.serialize(body)
         return self.do_request("POST", self.ports_path % (network), body=body)
 
-    @api_call
+    @ApiCall
     def delete_port(self, network, port):
         """
         Deletes the specified port from a network
         """
         return self.do_request("DELETE", self.port_path % (network, port))
 
-    @api_call
+    @ApiCall
     def set_port_state(self, network, port, body=None):
         """
         Sets the state of the specified port
@@ -265,14 +294,14 @@ class Client(object):
         return self.do_request("PUT",
             self.port_path % (network, port), body=body)
 
-    @api_call
+    @ApiCall
     def show_port_attachment(self, network, port):
         """
         Fetches the attachment-id associated with the specified port
         """
         return self.do_request("GET", self.attachment_path % (network, port))
 
-    @api_call
+    @ApiCall
     def attach_resource(self, network, port, body=None):
         """
         Sets the attachment-id of the specified port
@@ -280,7 +309,7 @@ class Client(object):
         return self.do_request("PUT",
             self.attachment_path % (network, port), body=body)
 
-    @api_call
+    @ApiCall
     def detach_resource(self, network, port):
         """
         Removes the attachment-id of the specified port
index 478ddd551bf9226ecf850edb791913ef7002979d..83fd9fabe9db89f49ec220774d1c832a00fa0120 100644 (file)
@@ -111,6 +111,10 @@ class AlreadyAttached(QuantumException):
                 "already plugged into port %(att_port_id)s")
 
 
+class AttachmentNotReady(QuantumException):
+    message = _("The attachment %(att_id)s is not ready")
+
+
 class NetworkNameExists(QuantumException):
     message = _("Unable to set network name to %(net_name). " \
                 "Network with id %(net_id) already has this name for " \