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:
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
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"
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" \
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()
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:
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:
% 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
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
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
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