Commit b1f56b18 by Kálmán Viktor

occi: basic stuff

parent 709eec33
......@@ -279,6 +279,7 @@ LOCAL_APPS = (
'manager',
'acl',
'monitor',
'occi',
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
......
......@@ -68,6 +68,7 @@ urlpatterns = patterns(
url(r'^info/support/$',
TemplateView.as_view(template_name="info/support.html"),
name="info.support"),
url(r'^occi/', include('occi.urls')),
)
......
from django.contrib.auth.models import User
from django.template.loader import render_to_string
from vm.models import Instance, Lease
from vm.models.common import ARCHITECTURES
from vm.models.instance import ACCESS_METHODS
OCCI_ADDR = "http://pc3.szgt.uni-miskolc.hu:5863/"
class Category():
"""Represents a Category object
actions needs a list of Actions
attributes needs a list of Attributes
"""
optional_arguments = ["title", "rel", "location", "attributes",
"actions", "class"]
def __init__(self, term, scheme, class_, **kwargs):
# workaround for class named keyword argument
kwargs['class'] = class_
self.term = term
self.scheme = scheme
self.class_ = class_
for k, v in kwargs.iteritems():
if k in self.optional_arguments:
setattr(self, k, v)
def render_values(self):
ret = "%s;" % self.term
simple_arguments = ["scheme", "class", "title", "rel", "location"]
for i in simple_arguments:
if hasattr(self, i):
ret += ' %s="%s";' % (i, getattr(self, i))
if hasattr(self, "attributes"):
ret += ' attributes="%s";' % " ".join(
[a.render() for a in self.attributes])
if hasattr(self, "actions"):
ret += ' actions="%s";' % " ".join(
[a.render() for a in self.actions])
return ret[:-1] # trailing semicolon
# TODO related, entity_type, entities
class Kind(Category):
pass
class Attribute():
def __init__(self, name, property=None):
self.name = name
self.property = property
def render(self):
attr = self.name
if self.property:
attr += "{%s}" % self.property
return attr
class Action(Category):
def render(self):
return "%s%s" % (self.scheme, self.term)
class Entity():
def __init__(self, id, title, kind):
self.id = id
self.title = title
self.kind = kind
class Resource(Entity):
def __init__(self, id, title, kind, summary, links):
super(Resource, self).__init__(id, title, kind)
self.summary = summary
self.links = links
class Compute(Resource):
# TODO better init, for new resources
def __init__(self, instance=None, attrs=None, **kwargs):
self.attrs = {}
if instance:
self.location = "%socci/vm/%d" % (OCCI_ADDR, instance.pk)
self.instance = instance
self.init_attrs()
elif attrs:
self.attrs = attrs
self._create_object()
translate = {
'occi.compute.architecture': "arch",
'occi.compute.cores': "num_cores",
'occi.compute.hostname': "short_hostname",
'occi.compute.speed': "priority",
'occi.compute.memory': "ram_size",
}
translate_arch = {
}
def _create_object(self):
params = {}
for a in self.attrs:
t = a.split("=")
params[self.translate.get(t[0])] = t[1]
params['lease'] = Lease.objects.all()[0]
params['priority'] = 10
params['max_ram_size'] = params['ram_size']
params['system'] = ""
params['pw'] = "killmenow"
params['arch'] = (ARCHITECTURES[0][0] if "64" in params['arch'] else
ARCHITECTURES[1][0])
params['access_method'] = ACCESS_METHODS[0][0]
params['owner'] = User.objects.get(username="test")
params['name'] = "from occi yo"
i = Instance.create(params=params, disks=[], networks=[],
req_traits=[], tags=[])
self.location = "%socci/vm/%d" % (OCCI_ADDR, i.pk)
def render_location(self):
return "X-OCCI-Location: %s" % self.location
def render_body(self):
kind = COMPUTE_KIND
return render_to_string("occi/compute.html", {
'kind': kind,
'attrs': self.attrs,
})
def init_attrs(self):
for k, v in self.translate.items():
self.attrs[k] = getattr(self.instance, v, None)
"""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
# http://ogf.org/documents/GFD.184.pdf 3.1 (page 5)
COMPUTE_ATTRS = [
Attribute("occi.compute.architecture"),
Attribute("occi.compute.cores"),
Attribute("occi.compute.hostname"),
Attribute("occi.compute.speed"),
Attribute("occi.compute.memory"),
Attribute("occi.compute.state", "immutable"),
]
COMPUTE_ACTIONS = [
Action(
"start",
"http://schemas.ogf.org/occi/infrastructure/compute/action#",
"action",
title="Start compute resource",
),
Action(
"stop",
"http://schemas.ogf.org/occi/infrastructure/compute/action#",
"action",
title="Stop compute resource",
attributes=[Attribute("method")],
),
Action(
"restart",
"http://schemas.ogf.org/occi/infrastructure/compute/action#",
"action",
title="Restart compute resource",
attributes=[Attribute("method")],
),
Action(
"suspend",
"http://schemas.ogf.org/occi/infrastructure/compute/action#",
"action",
title="Suspend compute resource",
attributes=[Attribute("method")],
),
]
COMPUTE_KIND = Kind(
term="compute",
scheme="http://schemas.ogf.org/occi/infrastructure#",
class_="kind",
title="Compute Resource type",
rel="http://schemas.ogf.org/occi/core#resource",
attributes=COMPUTE_ATTRS,
actions=COMPUTE_ACTIONS,
location="%scompute/",
)
Category: compute; scheme={{ kind.scheme }}; class="{{ kind.class }}";
{% spaceless %}
{% for k, v in attrs.items %}
X-OCCI-Attribute: {{ k }}={% if v.isdigit == False %}"{{ v }}"{% else %}{{ v }}{% endif %}{% endfor %}
{% endspaceless %}
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import
from django.conf.urls import url, patterns
from occi.views import QueryInterface, ComputeInterface, VmInterface
urlpatterns = patterns(
'',
url(r'^-/$', QueryInterface.as_view(), name="occi.query"),
url(r'^compute/$', ComputeInterface.as_view(), name="occi.compute"),
url(r'^vm/(?P<pk>\d+)/$', VmInterface.as_view(), name="occi.vm"),
)
from django.http import HttpResponse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import View, DetailView
from vm.models import Instance
from .occi import (
Compute,
COMPUTE_KIND,
COMPUTE_ACTIONS,
)
class QueryInterface(View):
def get(self, request, *args, **kwargs):
response = "Category: %s\n" % COMPUTE_KIND.render_values()
for c in COMPUTE_ACTIONS:
response += "Category: %s\n" % c.render_values()
return HttpResponse(
response,
content_type="text/plain",
)
def post(self, request, *args, **kwargs):
response = HttpResponse(status=501)
return response
@method_decorator(csrf_exempt) # decorator on post method doesn't work
def dispatch(self, *args, **kwargs):
return super(QueryInterface, self).dispatch(*args, **kwargs)
class ComputeInterface(View):
def get(self, request, *args, **kwargs):
response = "\n".join([Compute(instance=i).render_location()
for i in Instance.active.all()])
return HttpResponse(
response,
content_type="text/plain",
)
def post(self, request, *args, **kwargs):
occi_attrs = None
category = None
for k, v in request.META.iteritems():
if k.startswith("HTTP_X_OCCI_ATTRIBUTE"):
occi_attrs = v.split(",")
elif k.startswith("HTTP_CATEGORY") and category is None:
category = v
c = Compute(attrs=occi_attrs)
response = HttpResponse()
response['Location'] = c.location
return response
@method_decorator(csrf_exempt) # decorator on post method doesn't work
def dispatch(self, *args, **kwargs):
return super(ComputeInterface, self).dispatch(*args, **kwargs)
class VmInterface(DetailView):
model = Instance
def get(self, request, *args, **kwargs):
vm = self.get_object()
c = Compute(instance=vm)
return HttpResponse(
c.render_body(),
content_type="text/plain",
)
def post(self, request, *args, **kwargs):
# actions, resource change
pass
@method_decorator(csrf_exempt) # decorator on post method doesn't work
def dispatch(self, *args, **kwargs):
return super(VmInterface, self).dispatch(*args, **kwargs)
"""
test commands:
curl 10.7.0.103:8080/occi/-/ -X GET
curl 10.7.0.103:8080/occi/compute/ -X GET
curl 10.7.0.103:8080/occi/compute/ -X POST
--header "X-OCCI-Attribute: occi.compute.cores=2"
--header "X-OCCI-Attribute: occi.compute.architecture=x86"
--header "X-OCCI-Attribute: occi.compute.speed=1"
--header "X-OCCI-Attribute: occi.compute.memory=1024" -I
"""
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