Commit e521bceb by Kálmán Viktor

occi: handle users

parent 53fedb73
...@@ -94,7 +94,6 @@ class Category(): ...@@ -94,7 +94,6 @@ class Category():
return ret[:-1] # trailing semicolon return ret[:-1] # trailing semicolon
# TODO related, entity_type, entities
class Kind(Category): class Kind(Category):
pass pass
...@@ -150,9 +149,7 @@ class Compute(Resource): ...@@ -150,9 +149,7 @@ class Compute(Resource):
self.init_attrs() self.init_attrs()
@classmethod @classmethod
def create_object(cls, data): def create_object(cls, data, user):
# TODO user
user = User.objects.get(username="test")
template = None template = None
attributes = {} attributes = {}
links = [] links = []
...@@ -284,7 +281,7 @@ class Compute(Resource): ...@@ -284,7 +281,7 @@ class Compute(Resource):
self.attrs['occi.compute.state'] = status.get(self.instance.status, self.attrs['occi.compute.state'] = status.get(self.instance.status,
"inactive") "inactive")
def trigger_action(self, data): def trigger_action(self, data, user):
method = None method = None
action_term = None action_term = None
for d in data: for d in data:
...@@ -311,9 +308,7 @@ class Compute(Resource): ...@@ -311,9 +308,7 @@ class Compute(Resource):
user = User.objects.get(username="test") user = User.objects.get(username="test")
getattr(self.instance, operation).async(user=user) getattr(self.instance, operation).async(user=user)
def delete(self): def delete(self, user):
# TODO
user = User.objects.get(username="test")
self.instance.destroy(user=user) self.instance.destroy(user=user)
...@@ -349,7 +344,7 @@ class Storage(Resource): ...@@ -349,7 +344,7 @@ class Storage(Resource):
self.init_attrs() self.init_attrs()
@classmethod @classmethod
def create_object(cls, data): def create_object(cls, data, user):
attributes = {} attributes = {}
for d in data: for d in data:
...@@ -365,11 +360,8 @@ class Storage(Resource): ...@@ -365,11 +360,8 @@ class Storage(Resource):
if not name: if not name:
name = "disk create from OCCI at %s" % timezone.now() name = "disk create from OCCI at %s" % timezone.now()
# TODO user
user = User.objects.get(username="test")
params = { params = {
'user': user, 'user': user, # not used
'size': int(float(size) * 1024**3), # GiB to byte 'size': int(float(size) * 1024**3), # GiB to byte
'type': "qcow2-norm", 'type': "qcow2-norm",
'name': name, 'name': name,
...@@ -406,7 +398,7 @@ class Storage(Resource): ...@@ -406,7 +398,7 @@ class Storage(Resource):
self.attrs['occi.storage.state'] = "online" self.attrs['occi.storage.state'] = "online"
self.attrs['occi.storage.size'] /= 1024*1024*1024.0 self.attrs['occi.storage.size'] /= 1024*1024*1024.0
def trigger_action(self, data): def trigger_action(self, data, user):
# TODO, this is copypaste ATM # TODO, this is copypaste ATM
method = None method = None
action_term = None action_term = None
...@@ -430,14 +422,10 @@ class Storage(Resource): ...@@ -430,14 +422,10 @@ class Storage(Resource):
action = compute_action_to_operation.get(action_term) action = compute_action_to_operation.get(action_term)
operation = action.get(method) operation = action.get(method)
# TODO user
user = User.objects.get(username="test")
getattr(self.instance, operation).async(user=user) getattr(self.instance, operation).async(user=user)
def delete(self): def delete(self, user):
# TODO # random deletes? template?
user = User.objects.get(username="test")
if self.disk.instance_set.count() > 0: if self.disk.instance_set.count() > 0:
for i in self.disk.instance_set.all(): for i in self.disk.instance_set.all():
i.detach_disk(user=user, disk=self.disk) i.detach_disk(user=user, disk=self.disk)
...@@ -464,7 +452,7 @@ class StorageLink(Link): ...@@ -464,7 +452,7 @@ class StorageLink(Link):
self.disk = disk self.disk = disk
@classmethod @classmethod
def create_object(cls, data): def create_object(cls, data, user):
attributes = {} attributes = {}
for d in data: for d in data:
...@@ -477,8 +465,6 @@ class StorageLink(Link): ...@@ -477,8 +465,6 @@ class StorageLink(Link):
if not (source and target): if not (source and target):
return None return None
# TODO user
user = User.objects.get(username="test")
g = re.match(occi_attribute_link_regex % "storage", target) g = re.match(occi_attribute_link_regex % "storage", target)
disk_pk = g.group("id") disk_pk = g.group("id")
g = re.match(occi_attribute_link_regex % "vm", source) g = re.match(occi_attribute_link_regex % "vm", source)
...@@ -521,10 +507,7 @@ class StorageLink(Link): ...@@ -521,10 +507,7 @@ class StorageLink(Link):
'attrs': self.attrs, 'attrs': self.attrs,
}) })
def delete(self): def delete(self, user):
# TODO
user = User.objects.get(username="test")
if self.disk in self.instance.disks.all(): if self.disk in self.instance.disks.all():
self.instance.detach_disk(user=user, disk=self.disk) self.instance.detach_disk(user=user, disk=self.disk)
...@@ -633,7 +616,7 @@ class NetworkInterface(Link): ...@@ -633,7 +616,7 @@ class NetworkInterface(Link):
return "eth%d" % index return "eth%d" % index
@classmethod @classmethod
def create_object(cls, data): def create_object(cls, data, user):
attributes = {} attributes = {}
for d in data: for d in data:
...@@ -646,8 +629,6 @@ class NetworkInterface(Link): ...@@ -646,8 +629,6 @@ class NetworkInterface(Link):
if not (source and target): if not (source and target):
return None return None
# TODO user
user = User.objects.get(username="test")
g = re.match(occi_attribute_link_regex % "network", target) g = re.match(occi_attribute_link_regex % "network", target)
vlan_vid = g.group("id") vlan_vid = g.group("id")
g = re.match(occi_attribute_link_regex % "vm", source) g = re.match(occi_attribute_link_regex % "vm", source)
...@@ -692,10 +673,7 @@ class NetworkInterface(Link): ...@@ -692,10 +673,7 @@ class NetworkInterface(Link):
'attrs': self.attrs, 'attrs': self.attrs,
}) })
def delete(self): def delete(self, user):
# TODO
user = User.objects.get(username="test")
interface = Interface.objects.get(vlan=self.vlan, interface = Interface.objects.get(vlan=self.vlan,
instance=self.instance) instance=self.instance)
self.instance.remove_interface(user=user, interface=interface) self.instance.remove_interface(user=user, interface=interface)
...@@ -723,19 +701,7 @@ class IPNetworkInterface(Mixin): ...@@ -723,19 +701,7 @@ class IPNetworkInterface(Mixin):
}) })
"""predefined stuffs
storage attributes and actions
http://ogf.org/documents/GFD.184.pdf 3.3 (page 7)
storagelink attributes
http://ogf.org/documents/GFD.184.pdf 3.4.2 (page 10)
"""
# compute attributes and actions # compute attributes and actions
# http://ogf.org/documents/GFD.184.pdf 3.1 (page 5)
COMPUTE_ATTRS = [ COMPUTE_ATTRS = [
Attribute("occi.compute.architecture"), Attribute("occi.compute.architecture"),
Attribute("occi.compute.cores"), Attribute("occi.compute.cores"),
......
import logging
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse, Http404 from django.http import HttpResponse, Http404
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
...@@ -5,7 +8,7 @@ from django.views.decorators.csrf import csrf_exempt ...@@ -5,7 +8,7 @@ from django.views.decorators.csrf import csrf_exempt
from django.views.generic import View, DetailView from django.views.generic import View, DetailView
from firewall.models import Vlan from firewall.models import Vlan
from vm.models import Instance, InstanceTemplate from vm.models import Instance, InstanceTemplate, Interface
from storage.models import Disk from storage.models import Disk
from .occi import ( from .occi import (
...@@ -27,6 +30,8 @@ from .occi import ( ...@@ -27,6 +30,8 @@ from .occi import (
IPNETWORK_INTERFACE_MIXIN, IPNETWORK_INTERFACE_MIXIN,
) )
logger = logging.getLogger(__name__)
class CSRFExemptMixin(object): class CSRFExemptMixin(object):
@method_decorator(csrf_exempt) @method_decorator(csrf_exempt)
...@@ -77,7 +82,9 @@ class QueryInterface(CSRFExemptMixin, View): ...@@ -77,7 +82,9 @@ class QueryInterface(CSRFExemptMixin, View):
for c in COMPUTE_ACTIONS: for c in COMPUTE_ACTIONS:
response += "Category: %s\n" % c.render_values() response += "Category: %s\n" % c.render_values()
for t in InstanceTemplate.objects.all(): templates = InstanceTemplate.get_objects_with_level("user",
self.request.user)
for t in templates:
response += OsTemplate(t).render_body() response += OsTemplate(t).render_body()
return HttpResponse( return HttpResponse(
...@@ -93,8 +100,9 @@ class QueryInterface(CSRFExemptMixin, View): ...@@ -93,8 +100,9 @@ class QueryInterface(CSRFExemptMixin, View):
class ComputeInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View): class ComputeInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
vms = Instance.get_objects_with_level("user", self.request.user)
response = "\n".join([Compute(instance=i).render_location() response = "\n".join([Compute(instance=i).render_location()
for i in Instance.active.all()]) for i in vms])
return HttpResponse( return HttpResponse(
response, response,
content_type="text/plain", content_type="text/plain",
...@@ -103,7 +111,7 @@ class ComputeInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View): ...@@ -103,7 +111,7 @@ class ComputeInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
data = self.get_post_data(request) data = self.get_post_data(request)
c = Compute.create_object(data=data) c = Compute.create_object(data=data, user=self.request.user)
response = HttpResponse( response = HttpResponse(
"X-OCCI-Location: %s" % c.location, "X-OCCI-Location: %s" % c.location,
status=201, status=201,
...@@ -116,8 +124,11 @@ class VmInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, DetailView): ...@@ -116,8 +124,11 @@ class VmInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, DetailView):
model = Instance model = Instance
def get_object(self): def get_object(self):
return get_object_or_404(Instance.objects.filter(destroyed_at=None), vm = get_object_or_404(Instance.objects.filter(destroyed_at=None),
pk=self.kwargs['pk']) pk=self.kwargs['pk'])
if not vm.has_level(self.request.user, "user"):
raise PermissionDenied()
return vm
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
vm = self.get_object() vm = self.get_object()
...@@ -132,12 +143,12 @@ class VmInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, DetailView): ...@@ -132,12 +143,12 @@ class VmInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, DetailView):
action = request.GET.get("action") action = request.GET.get("action")
vm = self.get_object() vm = self.get_object()
if action: if action:
Compute(instance=vm).trigger_action(data) Compute(instance=vm).trigger_action(data, self.request.user)
return HttpResponse() return HttpResponse()
def delete(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs):
vm = self.get_object() vm = self.get_object()
Compute(instance=vm).delete() Compute(instance=vm).delete(self.request.user)
return HttpResponse() return HttpResponse()
...@@ -145,8 +156,10 @@ class VmInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, DetailView): ...@@ -145,8 +156,10 @@ class VmInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, DetailView):
class OsTplInterface(CSRFExemptMixin, View): class OsTplInterface(CSRFExemptMixin, View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
templates = InstanceTemplate.get_objects_with_level("user",
self.request.user)
response = "\n".join([OsTemplate(template=t).render_location() response = "\n".join([OsTemplate(template=t).render_location()
for t in InstanceTemplate.objects.all()]) for t in templates])
return HttpResponse( return HttpResponse(
response, response,
content_type="text/plain", content_type="text/plain",
...@@ -169,7 +182,7 @@ class StorageInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View): ...@@ -169,7 +182,7 @@ class StorageInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
data = self.get_post_data(request) data = self.get_post_data(request)
d = Storage.create_object(data=data) d = Storage.create_object(data=data, user=self.request.user)
response = HttpResponse( response = HttpResponse(
"X-OCCI-Location: %s" % d.location, "X-OCCI-Location: %s" % d.location,
status=201, status=201,
...@@ -195,11 +208,11 @@ class DiskInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, DetailView): ...@@ -195,11 +208,11 @@ class DiskInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, DetailView):
action = request.GET.get("action") action = request.GET.get("action")
disk = self.get_object() disk = self.get_object()
if action: if action:
Storage(disk=disk).trigger_action(data) Storage(disk=disk).trigger_action(data, self.request.user)
return HttpResponse() return HttpResponse()
def delete(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs):
Storage(disk=self.get_object()).delete() Storage(disk=self.get_object()).delete(self.request.user)
return HttpResponse("") return HttpResponse("")
...@@ -214,6 +227,9 @@ class StorageLinkInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View): ...@@ -214,6 +227,9 @@ class StorageLinkInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View):
if disk not in vm.disks.all(): if disk not in vm.disks.all():
raise Http404 raise Http404
if not vm.has_level(self.request.user, "user"):
raise PermissionDenied()
return vm, disk return vm, disk
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
...@@ -231,7 +247,7 @@ class StorageLinkInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View): ...@@ -231,7 +247,7 @@ class StorageLinkInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View):
return HttpResponse("", status=500) return HttpResponse("", status=500)
data = self.get_post_data(request) data = self.get_post_data(request)
sl = StorageLink.create_object(data=data) sl = StorageLink.create_object(data=data, user=self.request.user)
if sl: if sl:
response = HttpResponse( response = HttpResponse(
"X-OCCI-Location: %s" % sl.location, "X-OCCI-Location: %s" % sl.location,
...@@ -246,15 +262,16 @@ class StorageLinkInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View): ...@@ -246,15 +262,16 @@ class StorageLinkInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View):
vm, disk = self.get_vm_and_disk() vm, disk = self.get_vm_and_disk()
sl = StorageLink(instance=vm, disk=disk) sl = StorageLink(instance=vm, disk=disk)
sl.delete() sl.delete(user=self.request.user)
return HttpResponse("") return HttpResponse("")
class NetworkInterfaceView(CSRFExemptMixin, View): class NetworkInterfaceView(CSRFExemptMixin, View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
vlans = Vlan.get_objects_with_level("user", self.request.user)
response = "\n".join([Network(vlan=v).render_location() response = "\n".join([Network(vlan=v).render_location()
for v in Vlan.objects.all()]) for v in vlans])
return HttpResponse( return HttpResponse(
response, response,
content_type="text/plain", content_type="text/plain",
...@@ -269,6 +286,13 @@ class VlanInterface(CSRFExemptMixin, DetailView): ...@@ -269,6 +286,13 @@ class VlanInterface(CSRFExemptMixin, DetailView):
slug_field = 'vid' slug_field = 'vid'
slug_url_kwarg = 'vid' slug_url_kwarg = 'vid'
def get_object(self):
vlan = get_object_or_404(Vlan, vid=self.kwargs['vid'])
if not vlan.has_level(self.request.user, "user"):
raise PermissionDenied()
return vlan
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
vlan = self.get_object() vlan = self.get_object()
c = Network(vlan=vlan) c = Network(vlan=vlan)
...@@ -291,6 +315,11 @@ class CIRCLEInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View): ...@@ -291,6 +315,11 @@ class CIRCLEInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View):
pk=self.kwargs['vm_pk']) pk=self.kwargs['vm_pk'])
vlan = get_object_or_404(Vlan, vid=vlan_vid) vlan = get_object_or_404(Vlan, vid=vlan_vid)
if not vm.has_level(self.request.user, "user"):
raise PermissionDenied()
get_object_or_404(Interface, vlan=vlan, instance=vm)
return vm, vlan return vm, vlan
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
...@@ -303,12 +332,11 @@ class CIRCLEInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View): ...@@ -303,12 +332,11 @@ class CIRCLEInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
# we don't support actions for networkinterfaces # we don't support actions for networkinterfaces
# (they don't even exist in the model)
if request.GET.get("action"): if request.GET.get("action"):
return HttpResponse("", status=500) return HttpResponse("", status=500)
data = self.get_post_data(request) data = self.get_post_data(request)
sl = NetworkInterface.create_object(data=data) sl = NetworkInterface.create_object(data=data, user=self.request.user)
if sl: if sl:
response = HttpResponse( response = HttpResponse(
"X-OCCI-Location: %s" % sl.location, "X-OCCI-Location: %s" % sl.location,
...@@ -323,5 +351,5 @@ class CIRCLEInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View): ...@@ -323,5 +351,5 @@ class CIRCLEInterface(CSRFExemptMixin, OCCIPostDataAsListMixin, View):
vm, vlan = self.get_vm_and_vlan() vm, vlan = self.get_vm_and_vlan()
ni = NetworkInterface(instance=vm, vlan=vlan) ni = NetworkInterface(instance=vm, vlan=vlan)
ni.delete() ni.delete(user=self.request.user)
return HttpResponse("") return HttpResponse("")
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