Commit 269156f0 by Fukász Rómeó Ervin

compute collection and compute instance get requests

parent a0cf9380
...@@ -3,6 +3,7 @@ from django.contrib.auth import login ...@@ -3,6 +3,7 @@ from django.contrib.auth import login
class OcciAuthForm(AuthenticationForm): class OcciAuthForm(AuthenticationForm):
""" An authentication form for the OCCI implementation. """
def __init__(self, request, *args, **kwargs): def __init__(self, request, *args, **kwargs):
super(OcciAuthForm, self).__init__(*args, **kwargs) super(OcciAuthForm, self).__init__(*args, **kwargs)
self.request = request self.request = request
......
import requests import requests
from requests.exceptions import ConnectionError from requests.exceptions import ConnectionError
import json import json
import urllib3 # import urllib3
# Mivel nincs a devenv-nek SSL tanusitvanya, ezert az urllib3 csomag minden keresnel # Mivel nincs a devenv-nek SSL tanusitvanya, ezert az urllib3 csomag minden
# InsecureRequestWarning-ot adna. Ezt elkeruljuk ugy, hogy kikapcsoljuk a # keresnel InsecureRequestWarning-ot adna. Ezt elkeruljuk ugy, hogy
# figyelmezteteseket # kikapcsoljuk a figyelmezteteseket
# urllib3.disable_warnings() # urllib3.disable_warnings()
# A szerver base url-je es a felhasznalo adatai # A szerver base url-je es a felhasznalo adatai
...@@ -14,13 +14,14 @@ username = "admin" ...@@ -14,13 +14,14 @@ username = "admin"
password = "retekretek" password = "retekretek"
loginData = {"username": username, "password": password} loginData = {"username": username, "password": password}
# Csinalunk egy sessiont, hogy a cookie ami az auth-ert felelos automatikusan benne # Csinalunk egy sessiont, hogy a cookie ami az auth-ert felelos
# maradjon az osszes keresunkben # automatikusan benne maradjon az osszes keresunkben
with requests.Session() as session: with requests.Session() as session:
headers = {"Content-Type": "application/json", "Referer" : server} headers = {"Content-Type": "application/json", "Referer": server}
try: try:
# Csrf-Token a bejelentkezeshez # Csrf-Token a bejelentkezeshez
req = session.get(server + "occi/login/", headers=headers, verify=False) req = session.get(server + "occi/login/", headers=headers,
verify=False)
print("csrf-token") print("csrf-token")
print("----------") print("----------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
...@@ -28,11 +29,12 @@ with requests.Session() as session: ...@@ -28,11 +29,12 @@ with requests.Session() as session:
print print
# Bejelentkezes # Bejelentkezes
# POST, DELETE, PUT keresek elott be kell allitani az X-CSRFToken header # POST, DELETE, PUT keresek elott be kell allitani az X-CSRFToken
# erteket az aktualis csrftoken-re, amely mindig benne van a cookie-ban # header erteket az aktualis csrftoken-re, amely mindig benne van
# a cookie-ban
headers["X-CSRFToken"] = req.cookies['csrftoken'] headers["X-CSRFToken"] = req.cookies['csrftoken']
req = session.post(server + "occi/login/", data=json.dumps(loginData), req = session.post(server + "occi/login/", verify=False,
headers=headers, verify=False) data=json.dumps(loginData), headers=headers)
print("login") print("login")
print("-----") print("-----")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
...@@ -45,24 +47,28 @@ with requests.Session() as session: ...@@ -45,24 +47,28 @@ with requests.Session() as session:
print(error) print(error)
print print
# Gep ebresztes teszt (meg nem OCCI) # osszes vm collectionkent
req = session.get(server + "occi/wakeup/", headers=headers, verify=False) req = session.get(server + "occi/compute/", headers=headers,
print("wakeup") verify=False)
print("------") print("compute-collection")
print("------------------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print(req.text) print(req.text)
print print
# Gep altatas teszt (meg nem OCCI) # az elso vm a listabol
req = session.get(server + "occi/sleep/", headers=headers, verify=False) vmid = json.loads(req.text)["resources"][0]["id"]
print("sleep") req = session.get(server + "occi/compute/" + str(vmid),
print("-----") headers=headers, verify=False)
print("compute-"+str(vmid))
print("------------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print(req.text) print(req.text)
print print
# Kijelentkezes # Kijelentkezes
req = session.get(server + "occi/logout/", headers=headers, verify=False) req = session.get(server + "occi/logout/", headers=headers,
verify=False)
print("logout") print("logout")
print("------") print("------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
......
""" Implementation of the OCCI - Core model classes """ """ Implementation of the OCCI - Core model classes """
from occi_utils import set_optional_attributes from occi_utils import set_optional_attributes, serialize_attributes
class Attribute: class Attribute:
...@@ -35,8 +35,6 @@ class Category(object): ...@@ -35,8 +35,6 @@ class Category(object):
category_optional_attributes = ("title", "attributes") category_optional_attributes = ("title", "attributes")
attributes = {}
def __init__(self, scheme, term, **kwargs): def __init__(self, scheme, term, **kwargs):
self.scheme = scheme self.scheme = scheme
self.term = term self.term = term
...@@ -49,23 +47,23 @@ class Kind(Category): ...@@ -49,23 +47,23 @@ class Kind(Category):
kind_optional_attributes = ("parent", "actions", "enitities") kind_optional_attributes = ("parent", "actions", "enitities")
actions = ()
entities = ()
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Kind, self).__init__(*args, **kwargs) super(Kind, self).__init__(*args, **kwargs)
set_optional_attributes(self, self.kind_optional_attributes, set_optional_attributes(self, self.kind_optional_attributes,
kwargs) kwargs)
def render_as_json(self): def render_as_json(self):
json = {"term": self.term, "scheme": self.scheme, json = {"term": self.term, "scheme": self.scheme}
"attributes": self.attributes, "actions": self.actions}
if hasattr(self, "title"): if hasattr(self, "title"):
json["title"] = self.title json["title"] = self.title
if hasattr(self, "parent"): if hasattr(self, "parent"):
json["parent"] = self.parent json["parent"] = self.parent
if hasattr(self, "location"): if hasattr(self, "location"):
json["location"] = self.location json["location"] = self.location
if hasattr(self, "attributes"):
json["attributes"] = serialize_attributes(self.attributes)
if hasattr(self, "actions"):
json["actions"] = serialize_attributes(self.actions)
return json return json
...@@ -79,7 +77,7 @@ class Action(Category): ...@@ -79,7 +77,7 @@ class Action(Category):
if hasattr(self, "title"): if hasattr(self, "title"):
json["title"] = self.title json["title"] = self.title
if hasattr(self, "attributes"): if hasattr(self, "attributes"):
json["attributes"] = self.attributes json["attributes"] = serialize_attributes(self.attributes)
return json return json
...@@ -89,11 +87,6 @@ class Mixin(Category): ...@@ -89,11 +87,6 @@ class Mixin(Category):
mixin_optional_attributes = ("depends", "entities", "applies", mixin_optional_attributes = ("depends", "entities", "applies",
"actions") "actions")
depends = ()
entities = ()
applies = ()
actions = ()
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Mixin, self).__init__(*args, **kwargs) super(Mixin, self).__init__(*args, **kwargs)
set_optional_attributes(self, self.mixin_optional_attributes, set_optional_attributes(self, self.mixin_optional_attributes,
...@@ -118,8 +111,6 @@ class Entity(object): ...@@ -118,8 +111,6 @@ class Entity(object):
entity_optional_attributes = ("mixins", "title") entity_optional_attributes = ("mixins", "title")
mixins = ()
def __init__(self, kind, id, **kwargs): def __init__(self, kind, id, **kwargs):
self.kind = kind self.kind = kind
self.id = id self.id = id
...@@ -132,16 +123,13 @@ class Resource(Entity): ...@@ -132,16 +123,13 @@ class Resource(Entity):
resource_optional_attributes = ("links", "summary") resource_optional_attributes = ("links", "summary")
links = ()
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Resource, self).__init__(*args, **kwargs) super(Resource, self).__init__(*args, **kwargs)
set_optional_attributes(self, self.resource_optional_attributes, set_optional_attributes(self, self.resource_optional_attributes,
kwargs) kwargs)
def render_as_json(self): def render_as_json(self):
json = {"kind": self.kind, "id": self.id, "links": self.links, json = {"kind": self.kind, "id": self.id}
"mixins": self.mixins}
if hasattr(self, "title"): if hasattr(self, "title"):
json["title"] = self.title json["title"] = self.title
if hasattr(self, "summary"): if hasattr(self, "summary"):
...@@ -150,6 +138,10 @@ class Resource(Entity): ...@@ -150,6 +138,10 @@ class Resource(Entity):
json["attributes"] = self.attributes json["attributes"] = self.attributes
if hasattr(self, "actions"): if hasattr(self, "actions"):
json["actions"] = self.actions json["actions"] = self.actions
if hasattr(self, "links"):
json["links"] = self.links
if hasattr(self, "mixins"):
json["mixins"] = self.mixins
return json return json
......
...@@ -2,27 +2,27 @@ ...@@ -2,27 +2,27 @@
from occi_core import Action, Attribute, Resource from occi_core import Action, Attribute, Resource
from occi_utils import action_list_for_resource
COMPUTE_ATTRIBUTES = [ COMPUTE_ATTRIBUTES = [
Attribute("occi.compute.architecture", "Enum {x86, x84}", True, False, Attribute("occi.compute.architecture", "Object", True, False,
description="CPU Architecture of the instance."), description="CPU Architecture of the instance."),
Attribute("occi.compute.cores", "Integer", True, False, Attribute("occi.compute.cores", "Object", True, False,
description="Number of virtual CPU cores assigned to " + description="Number of virtual CPU cores assigned to " +
"the instance."), "the instance."),
Attribute("occi.compute.hostname", "String", True, False, Attribute("occi.compute.hostname", "Object", True, False,
description="Fully Qualified DNS hostname for the " + description="Fully Qualified DNS hostname for the " +
"instance"), "instance"),
Attribute("occi.compute.share", "Integer", True, False, Attribute("occi.compute.share", "Object", True, False,
description="Relative number of CPU shares for the " + description="Relative number of CPU shares for the " +
"instance."), "instance."),
Attribute("occi.compute.memory", "Float, 10^9 (GiB)", True, False, Attribute("occi.compute.memory", "Object", True, False,
description="Maximum RAM in gigabytes allocated to " + description="Maximum RAM in gigabytes allocated to " +
"the instance."), "the instance."),
Attribute("occi.compute.state", "Enum {active, inactive, suspended, " + Attribute("occi.compute.state", "Object", False, True,
"error}", False, True,
description="Current state of the instance."), description="Current state of the instance."),
Attribute("occi.compute.state.message", "String", False, False, Attribute("occi.compute.state.message", "Object", False, False,
description="Human-readable explanation of the current " + description="Human-readable explanation of the current " +
"instance state"), "instance state"),
] ]
...@@ -32,27 +32,70 @@ COMPUTE_ACTIONS = [ ...@@ -32,27 +32,70 @@ COMPUTE_ACTIONS = [
"start", title="Start compute instance"), "start", title="Start compute instance"),
Action("http://schemas.ogf.org/occi/infrastructure/compute/action#", Action("http://schemas.ogf.org/occi/infrastructure/compute/action#",
"stop", title="Stop compute instance", "stop", title="Stop compute instance",
attributes=[Attribute("method", "Enum {graceful, acpioff, " + attributes=[Attribute("method", "Object", True, False), ]),
"poweroff}", True, False), ]),
Action("http://schemas.ogf.org/occi/infrastructure/compute/action#", Action("http://schemas.ogf.org/occi/infrastructure/compute/action#",
"restart", title="Restart compute instance", "restart", title="Restart compute instance",
attributes=[Attribute("method", "Enum {graceful, warm, cold}", attributes=[Attribute("method", "Object",
True, False), ]), True, False), ]),
Action("http://schemas.ogf.org/occi/infrastructure/compute/action#", Action("http://schemas.ogf.org/occi/infrastructure/compute/action#",
"suspend", title="Suspend compute instance", "suspend", title="Suspend compute instance",
attributes=[Attribute("method", "Enum {hibernate, suspend}", attributes=[Attribute("method", "Object",
True, False), ]), True, False), ]),
Action("http://schemas.ogf.org/occi/infrastructure/compute/action#", Action("http://schemas.ogf.org/occi/infrastructure/compute/action#",
"save", title="Create a template of compute instance", "save", title="Create a template of compute instance",
attributes=[Attribute("method", "Enum {hot, deffered}", True, attributes=[Attribute("method", "Object", True,
False), False),
Attribute("name", "String", True, True), ]), Attribute("name", "Object", True, True), ]),
] ]
COMPUTE_STATES = {
"NOSTATE": "inactive",
"RUNNING": "active",
"STOPPED": "inactive",
"SUSPENDED": "suspended",
"ERROR": "error",
"PENDING": "inactive",
"DESTROYED": "inactive",
}
COMPUTE_STATE_MESSAGES = {
"NOSTATE": "The virtual machine is not in a valid state.",
"RUNNING": "The virtual machine is running.",
"STOPPED": "The virtual machine is stopped.",
"SUSPENDED": "The virtual machine is suspended.",
"ERROR": "The virtual machine is in error state.",
"PENDING": "There is an action going on.",
"DESTROYED": "The virtual machine is destroyed",
}
COMPUTE_ARCHITECTURES = {"x86_64": "x64",
"x86-64 (64 bit)": "x64",
"i686": "x86",
"x86 (32 bit)": "x86"}
class Compute(Resource): class Compute(Resource):
""" OCCI 1.2 - Infrastructure extension - Compute """ """ OCCI 1.2 - Infrastructure extension - Compute """
def __init__(self, vm): def __init__(self, vm):
""" Creates a Compute instance of a VM instance object """ """ Creates a Compute instance of a VM instance object """
self.location = "/compute/%d" % (vm.pk) super(Compute, self).__init__(
"http://schemas.ogf.org/occi/infrastructure#compute", vm.pk)
self.vm = vm self.vm = vm
self.attributes = self.set_attributes()
self.actions = action_list_for_resource(COMPUTE_ACTIONS)
def set_attributes(self):
""" Sets the attributes of the Compute object based on the VM
instance. """
attributes = {}
attributes["occi.compute.architecture"] = (COMPUTE_ARCHITECTURES
.get(self.vm.arch))
attributes["occi.compute.cores"] = self.vm.num_cores
attributes["occi.compute.hostname"] = self.vm.short_hostname
attributes["occi.compute.share"] = self.vm.priority
attributes["occi.compute.memory"] = self.vm.ram_size / 1024.0
attributes["occi.compute.state"] = COMPUTE_STATES.get(self.vm.state)
attributes["occi.compute.state.message"] = (COMPUTE_STATE_MESSAGES
.get(self.vm.state))
return attributes
...@@ -8,3 +8,20 @@ def set_optional_attributes(self, optional_attributes, kwargs): ...@@ -8,3 +8,20 @@ def set_optional_attributes(self, optional_attributes, kwargs):
for k, v in kwargs.iteritems(): for k, v in kwargs.iteritems():
if k in optional_attributes: if k in optional_attributes:
setattr(self, k, v) setattr(self, k, v)
def serialize_attributes(attributes):
""" Creates a list of attributes, that are serializable to json from
a list of Attribute class objects. """
atrs = []
for attribute in attributes:
atrs.append(attribute.render_as_json())
return atrs
def action_list_for_resource(actions):
""" Creates a list of actions for Resource object rendering """
acts = []
for action in actions:
acts.append(action.scheme + action.term)
return acts
from django.conf.urls import url from django.conf.urls import url
from views import OcciLoginView, OcciLogoutView, TestView from views import (OcciLoginView, OcciLogoutView, OcciComputeView,
OcciComputeCollectionView)
urlpatterns = [ urlpatterns = [
url(r'^login/$', OcciLoginView.as_view()), url(r'^login/$', OcciLoginView.as_view()),
url(r'^logout/$', OcciLogoutView.as_view()), url(r'^logout/$', OcciLogoutView.as_view()),
url(r'^test/$', TestView.as_view()), url(r'^compute/$', OcciComputeCollectionView.as_view()),
url(r'^compute/(?P<id>\d+)/$', OcciComputeView.as_view()),
] ]
...@@ -2,16 +2,16 @@ ...@@ -2,16 +2,16 @@
These views handle the http requests of the API. """ These views handle the http requests of the API. """
import json
from django.views.generic import View from django.views.generic import View
from django.contrib.auth import logout from django.contrib.auth import logout
from django.http import JsonResponse from django.http import HttpResponse, JsonResponse, Http404
# from vm.models.instance import Instance from django.shortcuts import get_object_or_404
# from common.models import HumanReadableException
from forms import OcciAuthForm
import json
from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.csrf import ensure_csrf_cookie
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from occi_core import ENTITY_KIND from vm.models.instance import Instance
from forms import OcciAuthForm
from occi_infrastructure import Compute
class OcciLoginView(View): class OcciLoginView(View):
...@@ -24,7 +24,7 @@ class OcciLoginView(View): ...@@ -24,7 +24,7 @@ class OcciLoginView(View):
""" Returns a response with a cookie to be used for requests other """ Returns a response with a cookie to be used for requests other
than get. """ than get. """
result = {"result": "OK"} result = {"result": "OK"}
return JsonResponse(result) return JsonResponse(result, charset="utf-8")
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
data = json.loads(request.body.decode("utf-8")) data = json.loads(request.body.decode("utf-8"))
...@@ -33,12 +33,12 @@ class OcciLoginView(View): ...@@ -33,12 +33,12 @@ class OcciLoginView(View):
form = OcciAuthForm(data=data, request=request) form = OcciAuthForm(data=data, request=request)
if form.is_valid(): if form.is_valid():
result = {"result": "OK"} result = {"result": "OK"}
return JsonResponse(result) return JsonResponse(result, charset="utf-8")
else: else:
errors = dict([(k, [unicode(e) for e in v]) errors = dict([(k, [unicode(e) for e in v])
for k, v in form.errors.items()]) for k, v in form.errors.items()])
result = {"result": "ERROR", "errors": errors["__all__"]} result = {"result": "ERROR", "errors": errors["__all__"]}
return JsonResponse(result, status=400) return JsonResponse(result, status=400, charset="utf-8")
class OcciLogoutView(View): class OcciLogoutView(View):
...@@ -46,10 +46,31 @@ class OcciLogoutView(View): ...@@ -46,10 +46,31 @@ class OcciLogoutView(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
logout(request) logout(request)
result = {"result": "OK"} result = {"result": "OK"}
return JsonResponse(result) return JsonResponse(result, charset="utf-8")
class OcciComputeCollectionView(View):
def get(self, request, *args, **kwargs):
if not request.user.is_authenticated():
return HttpResponse(status=403)
vms = (Instance.get_objects_with_level("user", request.user)
.filter(destroyed_at=None))
json = {"resources": []}
for vm in vms:
json["resources"].append(Compute(vm).render_as_json())
return JsonResponse(json, charset="utf-8")
class TestView(View): class OcciComputeView(View):
""" TEST VIEW """ """ View of a compute instance """
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
return JsonResponse(ENTITY_KIND.render_as_json()) if not request.user.is_authenticated():
return HttpResponse(status=403)
try:
vm = get_object_or_404(Instance.get_objects_with_level("user",
request.user), pk=kwargs['id'])
except Http404:
return JsonResponse({"error": "There is no instance with the" +
" id " + kwargs['id'] + "."}, status=400)
compute = Compute(vm)
return JsonResponse(compute.render_as_json(), charset="utf-8")
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