Commit 89a8569d by Czémán Arnold

occi: add user network support

parent e43cc43e
......@@ -119,8 +119,11 @@ class Compute(Resource):
storages.append(Storage(disk))
for storage in storages:
links.append(StorageLink(self, storage).as_dict())
nics = [NetworkInterface(self, Network(nic.vlan))
for nic in self.vm.interface_set.all()]
nics = []
for nic in self.vm.interface_set.all():
net = nic.vxlan if nic.vxlan else nic.vlan
type = "vxlan" if nic.vxlan else "vlan"
nics.append(NetworkInterface(self, Network(net, type)))
for networkinterface in nics:
links.append(networkinterface.as_dict())
return links
......@@ -346,10 +349,15 @@ class StorageLink(Link):
class Network(Resource):
""" OCCI 1.2 - Infrastructure extension - Network """
def __init__(self, vlan):
def __init__(self, vlan, type="vlan"):
self.type = type
id = str(vlan.pk)
if self.type == "vxlan":
id = "x" + id
super(Network, self).__init__(
"http://schemas.ogf.org/occi/infrastructure#network",
str(vlan.pk),
id,
title=vlan.name,
)
self.vlan = vlan
self.actions = action_list_for_resource(NETWORK_ACTIONS)
......@@ -360,14 +368,19 @@ class Network(Resource):
def set_attributes(self):
attributes = {}
attributes["occi.network.vlan"] = self.vlan.vid
if self.type == "vxlan":
attributes["occi.network.vlan"] = self.vlan.vlan.vid
attributes["occi.network.label"] = self.vlan.vni
else:
attributes["occi.network.vlan"] = self.vlan.vid
attributes["occi.network.state"] = "active"
attributes["occi.network.state.message"] = (
"The network instance is active.")
attributes["occi.network.address"] = unicode(self.vlan.network4)
attributes["occi.network.gateway"] = unicode(self.vlan.network4.ip)
attributes["occi.network.allocation"] = (
"static" if self.vlan.dhcp_pool == "" else "dynamic")
if self.type == "vlan" and self.vlan.managed:
attributes["occi.network.address"] = unicode(self.vlan.network4)
attributes["occi.network.gateway"] = unicode(self.vlan.network4.ip)
attributes["occi.network.allocation"] = (
"static" if self.vlan.dhcp_pool == "" else "dynamic")
return attributes
def invoke_action(self, user, action, attributes):
......@@ -394,7 +407,10 @@ class NetworkInterface(Link):
)
self.compute = compute
self.network = network
self.interface = compute.vm.interface_set.get(vlan=network.vlan)
if network.type == "vxlan":
self.interface = compute.vm.interface_set.get(vxlan=network.vlan)
else:
self.interface = compute.vm.interface_set.get(vlan=network.vlan)
self.mixins = [
("http://schemas.ogf.org/occi/infrastructure/networkinterface#" +
"ipnetworkinterface"),
......@@ -410,7 +426,8 @@ class NetworkInterface(Link):
self.removeport(user, attributes)
else:
raise OcciActionInvocationError(message="Undefined action.")
self.__init__(Compute(self.compute.vm), Network(self.network.vlan))
self.__init__(Compute(self.compute.vm),
Network(self.network.vlan, self.network.type))
def addport(self, user, attributes):
if "port" not in attributes or "protocol" not in attributes:
......@@ -444,8 +461,11 @@ class NetworkInterface(Link):
def set_attributes(self):
attributes = {}
attributes["occi.networkinterface.interface"] = (
self.interface.vlan.name)
if self.network.type == "vxlan":
intfname = self.interface.vxlan.name
else:
intfname = self.interface.vlan.name
attributes["occi.networkinterface.interface"] = intfname
attributes["occi.networkinterface.mac"] = unicode(self.interface.mac)
attributes["occi.networkinterface.state"] = "active"
attributes["occi.networkinterface.state.message"] = (
......@@ -453,12 +473,12 @@ class NetworkInterface(Link):
if self.interface.host:
attributes["occi.networkinterface.address"] = (
unicode(self.interface.host.ipv4))
attributes["occi.networkinterface.gateway"] = (
unicode(self.interface.vlan.network4.ip))
attributes["occi.networkinterface.allocation"] = (
self.network.attributes["occi.network.allocation"])
attributes["org.circlecloud.occi.networkinterface.ports"] = (
self.get_open_ports())
attributes["occi.networkinterface.gateway"] = (
unicode(self.interface.vlan.network4.ip))
attributes["occi.networkinterface.allocation"] = (
self.network.attributes["occi.network.allocation"])
attributes["org.circlecloud.occi.networkinterface.ports"] = (
self.get_open_ports())
return attributes
def get_open_ports(self):
......
......@@ -35,12 +35,18 @@ urlpatterns = [
url(r'^storage/$', OcciStorageCollectionView.as_view()),
url(r'^storage/(?P<id>\d+)/$', OcciStorageView.as_view()),
url(r'^network/$', OcciNetworkCollectionView.as_view()),
url(r'^network/(?P<id>\d+)/$', OcciNetworkView.as_view()),
url(r'^network/(?P<id>\d+)/$', OcciNetworkView.as_view(),
kwargs={'type': 'vlan'}),
url(r'^network/x(?P<id>\d+)/$', OcciNetworkView.as_view(),
kwargs={'type': 'vxlan'}),
url(r'^storagelink/$', OcciStoragelinkCollectionView.as_view()),
url(r'^storagelink/compute(?P<computeid>\d+)-storage(?P<storageid>\d+)/$',
OcciStoragelinkView.as_view()),
url(r'^networkinterface/$', OcciNetworkInterfaceCollectionView.as_view()),
url(r'^networkinterface/compute(?P<computeid>\d+)-network(?P<networkid>' +
r'\d+)/$',
OcciNetworkInterfaceView.as_view()),
url((r'^networkinterface/compute(?P<computeid>\d+)-'
r'network(?P<networkid>\d+)/$'),
OcciNetworkInterfaceView.as_view(), kwargs={'type': 'vlan'}),
url((r'^networkinterface/compute(?P<computeid>\d+)-'
r'networkx(?P<networkid>\d+)/$'),
OcciNetworkInterfaceView.as_view(), kwargs={'type': 'vxlan'}),
]
......@@ -28,6 +28,7 @@ from django.shortcuts import get_object_or_404
from vm.models.instance import Instance, InstanceTemplate
from storage.models import Disk
from firewall.models import Vlan
from network.models import Vxlan
from occi.forms import OcciAuthForm
from occi.infrastructure import (Compute, Storage, Network, StorageLink,
NetworkInterface,)
......@@ -295,27 +296,32 @@ class OcciStorageView(OcciViewMixin, View):
class OcciNetworkCollectionView(OcciViewMixin, View):
def get(self, request, *args, **kwargs):
vlans = (Vlan.get_objects_with_level("owner", request.user))
vlans = Vlan.get_objects_with_level("owner", request.user)
vxlans = Vxlan.get_objects_with_level("owner", request.user)
json = {"resources": []}
for vlan in vlans:
json["resources"].append(Network(vlan).as_dict())
json["resources"].append(Network(vlan, type="vlan").as_dict())
for vxlan in vxlans:
json["resources"].append(Network(vxlan, type="vxlan").as_dict())
return occi_response(json)
class OcciNetworkView(OcciViewMixin, View):
""" View of a compute instance """
def get_vlan_object(self, user, vlanid):
def get_vlan_object(self, user, kwargs):
type = kwargs.get("type", "vlan")
model = Vxlan if type == "vxlan" else Vlan
try:
vlan = get_object_or_404(Vlan.get_objects_with_level(
"user", user), pk=vlanid)
object = get_object_or_404(model.get_objects_with_level(
"user", user), pk=kwargs["id"])
except Http404:
raise OcciResourceInstanceNotExist()
return Network(vlan)
return Network(object, type=type)
def get(self, request, *args, **kwargs):
try:
network = self.get_vlan_object(request.user, kwargs["id"])
network = self.get_vlan_object(request.user, kwargs)
except OcciResourceInstanceNotExist as e:
return e.response
return occi_response(network.as_dict(), charset="utf-8")
......@@ -331,7 +337,7 @@ class OcciNetworkView(OcciViewMixin, View):
status=400
)
try:
network = self.get_vlan_object(request.user, kwargs["id"])
network = self.get_vlan_object(request.user, kwargs)
except OcciResourceInstanceNotExist as e:
return e.response
try:
......@@ -378,9 +384,13 @@ class OcciNetworkInterfaceCollectionView(OcciViewMixin, View):
def get(self, request, *args, **kwargs):
vms = (Instance.get_objects_with_level("owner", request.user)
.filter(destroyed_at=None))
links = [NetworkInterface(Compute(vm),
Network(nwi.vlan)).as_dict()
for vm in vms for nwi in vm.interface_set.all()]
links = []
for vm in vms:
for nwi in vm.interface_set.all():
net = nwi.vxlan if nwi.vxlan else nwi.vlan
type = "vxlan" if nwi.vxlan else "vlan"
links = NetworkInterface(Compute(vm),
Network(net, type)).as_dict()
return occi_response({"links": links})
......@@ -395,26 +405,32 @@ class OcciNetworkInterfaceView(OcciViewMixin, View):
raise OcciResourceInstanceNotExist()
return Compute(vm)
def get_network_object(self, user, vlanid):
def get_network_object(self, user, id, type):
model = Vxlan if type == "vxlan" else Vlan
try:
vlan = get_object_or_404(Vlan.get_objects_with_level(
"user", user), pk=vlanid)
object = get_object_or_404(model.get_objects_with_level(
"user", user), pk=id)
except Http404:
raise OcciResourceInstanceNotExist()
return Network(vlan)
return Network(object, type)
def get_networkinterface_object(self, user, vmid, vlanid):
def get_networkinterface_object(self, user, kwargs):
vmid = kwargs["computeid"]
netid = kwargs["networkid"]
type = kwargs["type"]
compute = self.get_compute_object(user, vmid)
try:
interface = compute.vm.interface_set.get(vlan__pk=vlanid)
if type == "vxlan":
net = compute.vm.interface_set.get(vxlan__pk=netid).vxlan
else:
net = compute.vm.interface_set.get(vlan__pk=netid).vlan
except Exception:
raise OcciResourceInstanceNotExist()
return NetworkInterface(compute, Network(interface.vlan))
return NetworkInterface(compute, Network(net, type))
def get(self, request, *args, **kwargs):
try:
nic = self.get_networkinterface_object(
request.user, kwargs["computeid"], kwargs["networkid"])
nic = self.get_networkinterface_object(request.user, kwargs)
except OcciResourceInstanceNotExist as e:
return e.response
return occi_response(nic.as_dict())
......@@ -423,8 +439,7 @@ class OcciNetworkInterfaceView(OcciViewMixin, View):
requestData = json.loads(request.body.decode("utf-8"))
if "action" in requestData:
try:
nif = self.get_networkinterface_object(
request.user, kwargs["computeid"], kwargs["networkid"])
nif = self.get_networkinterface_object(request.user, kwargs)
except OcciResourceInstanceNotExist as e:
return e.response
try:
......@@ -437,10 +452,16 @@ class OcciNetworkInterfaceView(OcciViewMixin, View):
return OcciActionInvocationError().response
def put(self, request, *args, **kwargs):
netid = kwargs["network"]
nettype = kwargs["type"]
compute = self.get_compute_object(request.user, kwargs["computeid"])
network = self.get_network_object(request.user, kwargs["networkid"])
network = self.get_network_object(request.user, netid, nettype)
try:
compute.vm.add_interface(user=request.user, vlan=network.vlan)
if nettype == "vxlan":
compute.vm.add_user_interface(user=request.user,
vxlan=network.vlan)
else:
compute.vm.add_interface(user=request.user, vlan=network.vlan)
except HumanReadableException as e:
return OcciResourceCreationError(
message=e.get_user_text()).response
......@@ -450,10 +471,15 @@ class OcciNetworkInterfaceView(OcciViewMixin, View):
return occi_response(nif.as_dict())
def delete(self, request, *args, **kwargs):
netid = kwargs["network"]
nettype = kwargs["type"]
compute = self.get_compute_object(request.user, kwargs["computeid"])
network = self.get_network_object(request.user, kwargs["networkid"])
network = self.get_network_object(request.user, netid, nettype)
try:
interface = compute.vm.interface_set.get(vlan=network.vlan)
if nettype == "vxlan":
interface = compute.vm.interface_set.get(vxlan=network.vlan)
else:
interface = compute.vm.interface_set.get(vlan=network.vlan)
except Exception:
return OcciResourceInstanceNotExist().response
try:
......@@ -461,7 +487,12 @@ class OcciNetworkInterfaceView(OcciViewMixin, View):
from vm.models.network import Interface
hc = Host.objects.filter(mac=interface.host.mac).count()
ic = Interface.objects.filter(host__mac=interface.host.mac).count()
compute.vm.remove_interface(user=request.user, interface=interface)
if nettype == "vxlan":
compute.vm.remove_user_interface(user=request.user,
interface=interface)
else:
compute.vm.remove_interface(user=request.user,
interface=interface)
except HumanReadableException as e:
return OcciResourceDeletionError(
message=e.get_user_text()).response
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment