Syncing with lp:quantum
This commit is contained in:
commit
9c805ac851
|
@ -240,7 +240,7 @@ def api_plug_iface(client, *args):
|
|||
res = client.attach_resource(nid, pid, data)
|
||||
except Exception, e:
|
||||
LOG.error("Failed to plug iface \"%s\" to port \"%s\": %s" % (vid,
|
||||
pid, output))
|
||||
pid, e))
|
||||
return
|
||||
LOG.debug(res)
|
||||
print "Plugged interface \"%s\" to port:%s on network:%s" % (vid, pid, nid)
|
||||
|
@ -386,6 +386,6 @@ if __name__ == "__main__":
|
|||
commands[cmd]["api_func"](client, *args)
|
||||
else:
|
||||
quantum = QuantumManager()
|
||||
manager = quantum.get_manager()
|
||||
manager = quantum.get_plugin()
|
||||
commands[cmd]["func"](manager, *args)
|
||||
sys.exit(0)
|
||||
|
|
|
@ -20,16 +20,32 @@ import httplib
|
|||
import socket
|
||||
import urllib
|
||||
from quantum.common.wsgi import Serializer
|
||||
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 api_call(object):
|
||||
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,8 +159,8 @@ class Client(object):
|
|||
if body:
|
||||
self.logger.debug(body)
|
||||
|
||||
c.request(method, action, body, headers)
|
||||
res = c.getresponse()
|
||||
conn.request(method, action, body, headers)
|
||||
res = conn.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
|
||||
|
|
|
@ -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 " \
|
||||
|
|
|
@ -15,106 +15,45 @@
|
|||
# under the License.
|
||||
# @author: Dan Wendlandt, Nicira Networks, Inc.
|
||||
|
||||
import httplib
|
||||
import logging as LOG
|
||||
import json
|
||||
import socket
|
||||
import sys
|
||||
import urllib
|
||||
|
||||
from quantum.manager import QuantumManager
|
||||
from optparse import OptionParser
|
||||
from quantum.common.wsgi import Serializer
|
||||
from quantum.cli import MiniClient
|
||||
import sys
|
||||
|
||||
from quantum.client import Client
|
||||
from quantum.manager import QuantumManager
|
||||
|
||||
FORMAT = "json"
|
||||
CONTENT_TYPE = "application/" + FORMAT
|
||||
|
||||
|
||||
def delete_all_nets(client, tenant_id):
|
||||
res = client.do_request(tenant_id, 'GET', "/networks." + FORMAT)
|
||||
resdict = json.loads(res.read())
|
||||
LOG.debug(resdict)
|
||||
for n in resdict["networks"]:
|
||||
def delete_all_nets(client):
|
||||
res = client.list_networks()
|
||||
for n in res["networks"]:
|
||||
nid = n["id"]
|
||||
|
||||
res = client.do_request(tenant_id, 'GET',
|
||||
"/networks/%s/ports.%s" % (nid, FORMAT))
|
||||
output = res.read()
|
||||
if res.status != 200:
|
||||
LOG.error("Failed to list ports: %s" % output)
|
||||
continue
|
||||
rd = json.loads(output)
|
||||
LOG.debug(rd)
|
||||
for port in rd["ports"]:
|
||||
pid = port["id"]
|
||||
|
||||
data = {'port': {'attachment-id': ''}}
|
||||
body = Serializer().serialize(data, CONTENT_TYPE)
|
||||
res = client.do_request(tenant_id, 'DELETE',
|
||||
"/networks/%s/ports/%s/attachment.%s" % \
|
||||
(nid, pid, FORMAT), body=body)
|
||||
output = res.read()
|
||||
LOG.debug(output)
|
||||
if res.status != 202:
|
||||
LOG.error("Failed to unplug iface from port \"%s\": %s" % (vid,
|
||||
pid, output))
|
||||
continue
|
||||
LOG.info("Unplugged interface from port:%s on network:%s" % (pid,
|
||||
nid))
|
||||
|
||||
res = client.do_request(tenant_id, 'DELETE',
|
||||
"/networks/%s/ports/%s.%s" % (nid, pid, FORMAT))
|
||||
output = res.read()
|
||||
if res.status != 202:
|
||||
LOG.error("Failed to delete port: %s" % output)
|
||||
continue
|
||||
pres = client.list_ports(nid)
|
||||
for port in pres["ports"]:
|
||||
pid = port['id']
|
||||
client.detach_resource(nid, pid)
|
||||
client.delete_port(nid, pid)
|
||||
print "Deleted Virtual Port:%s " \
|
||||
"on Virtual Network:%s" % (pid, nid)
|
||||
|
||||
res = client.do_request(tenant_id, 'DELETE',
|
||||
"/networks/" + nid + "." + FORMAT)
|
||||
status = res.status
|
||||
if status != 202:
|
||||
Log.error("Failed to delete network: %s" % nid)
|
||||
output = res.read()
|
||||
print output
|
||||
else:
|
||||
print "Deleted Virtual Network with ID:%s" % nid
|
||||
client.delete_network(nid)
|
||||
print "Deleted Virtual Network with ID:%s" % nid
|
||||
|
||||
|
||||
def create_net_with_attachments(net_name, iface_ids):
|
||||
def create_net_with_attachments(client, net_name, iface_ids):
|
||||
data = {'network': {'net-name': '%s' % net_name}}
|
||||
body = Serializer().serialize(data, CONTENT_TYPE)
|
||||
res = client.do_request(tenant_id, 'POST',
|
||||
"/networks." + FORMAT, body=body)
|
||||
rd = json.loads(res.read())
|
||||
LOG.debug(rd)
|
||||
nid = rd["networks"]["network"]["id"]
|
||||
res = client.create_network(data)
|
||||
nid = res["networks"]["network"]["id"]
|
||||
print "Created a new Virtual Network %s with ID:%s" % (net_name, nid)
|
||||
|
||||
for iface_id in iface_ids:
|
||||
res = client.do_request(tenant_id, 'POST',
|
||||
"/networks/%s/ports.%s" % (nid, FORMAT))
|
||||
output = res.read()
|
||||
if res.status != 200:
|
||||
LOG.error("Failed to create port: %s" % output)
|
||||
continue
|
||||
rd = json.loads(output)
|
||||
new_port_id = rd["ports"]["port"]["id"]
|
||||
res = client.create_port(nid)
|
||||
new_port_id = res["ports"]["port"]["id"]
|
||||
print "Created Virtual Port:%s " \
|
||||
"on Virtual Network:%s" % (new_port_id, nid)
|
||||
data = {'port': {'attachment-id': '%s' % iface_id}}
|
||||
body = Serializer().serialize(data, CONTENT_TYPE)
|
||||
res = client.do_request(tenant_id, 'PUT',
|
||||
"/networks/%s/ports/%s/attachment.%s" %\
|
||||
(nid, new_port_id, FORMAT), body=body)
|
||||
output = res.read()
|
||||
LOG.debug(output)
|
||||
if res.status != 202:
|
||||
LOG.error("Failed to plug iface \"%s\" to port \"%s\": %s" % \
|
||||
(iface_id, new_port_id, output))
|
||||
continue
|
||||
client.attach_resource(nid, new_port_id, data)
|
||||
print "Plugged interface \"%s\" to port:%s on network:%s" % \
|
||||
(iface_id, new_port_id, nid)
|
||||
|
||||
|
@ -149,7 +88,6 @@ if __name__ == "__main__":
|
|||
|
||||
if len(args) < 1:
|
||||
parser.print_help()
|
||||
help()
|
||||
sys.exit(1)
|
||||
|
||||
nets = {}
|
||||
|
@ -163,12 +101,13 @@ if __name__ == "__main__":
|
|||
|
||||
print "nets: %s" % str(nets)
|
||||
|
||||
client = MiniClient(options.host, options.port, options.ssl)
|
||||
client = Client(options.host, options.port, options.ssl,
|
||||
format='json', tenant=tenant_id)
|
||||
|
||||
if options.delete:
|
||||
delete_all_nets(client, tenant_id)
|
||||
delete_all_nets(client)
|
||||
|
||||
for net_name, iface_ids in nets.items():
|
||||
create_net_with_attachments(net_name, iface_ids)
|
||||
create_net_with_attachments(client, net_name, iface_ids)
|
||||
|
||||
sys.exit(0)
|
||||
|
|
Loading…
Reference in New Issue