Commit 760e8dc0 by Fukász Rómeó Ervin

occi query imterface and occi instances

parent 269156f0
......@@ -47,6 +47,14 @@ with requests.Session() as session:
print(error)
print
# query interface
req = session.get(server + "occi/-/", headers=headers, verify=False)
print("query-interface")
print("---------------")
print("status_code: " + str(req.status_code))
print(req.text)
print
# osszes vm collectionkent
req = session.get(server + "occi/compute/", headers=headers,
verify=False)
......@@ -58,7 +66,7 @@ with requests.Session() as session:
# az elso vm a listabol
vmid = json.loads(req.text)["resources"][0]["id"]
req = session.get(server + "occi/compute/" + str(vmid),
req = session.get(server + "occi/compute/" + str(vmid) + "/",
headers=headers, verify=False)
print("compute-"+str(vmid))
print("------------")
......@@ -66,6 +74,55 @@ with requests.Session() as session:
print(req.text)
print
# ha nem active, akkor azza tesszuk
state = json.loads(req.text)["attributes"]["occi.compute.state"]
action = "http://schemas.ogf.org/occi/infrastructure/compute/action#"
if state != "active":
try:
headers["X-CSRFToken"] = req.cookies['csrftoken']
except:
pass
req = session.post(server + "occi/compute/" + str(vmid) + "/",
headers=headers, verify=False,
data=json.dumps({"action": action + "start"}))
print("compute-" + str(vmid) + "-start")
print("---------------")
print("status_code: " + str(req.status_code))
print(req.text)
print
# restart
try:
headers["X-CSRFToken"] = req.cookies['csrftoken']
except:
pass
actionatrs = {"method": "cold"}
actioninv = {"action": action + "restart", "attributes": actionatrs}
req = session.post(server + "occi/compute/" + str(vmid) + "/",
headers=headers, verify=False,
data=json.dumps(actioninv))
print("compute-"+str(vmid) + "-restart")
print("-----------------")
print("status_code: " + str(req.status_code))
print(req.text)
print
# suspend
try:
headers["X-CSRFToken"] = req.cookies['csrftoken']
except:
pass
actioninv["action"] = action + "suspend"
actioninv["attributes"]["method"] = "suspend"
req = session.post(server + "occi/compute/" + str(vmid) + "/",
headers=headers, verify=False,
data=json.dumps(actioninv))
print("compute-" + str(vmid) + "-suspend")
print("-----------------")
print("status_code: " + str(req.status_code))
print(req.text)
print
# Kijelentkezes
req = session.get(server + "occi/logout/", headers=headers,
verify=False)
......
""" Implementation of the OCCI - Core model classes """
from occi_utils import set_optional_attributes, serialize_attributes
from occi_utils import set_optional_attributes
class Attribute:
......@@ -45,7 +45,8 @@ class Category(object):
class Kind(Category):
""" OCCI 1.2 - CORE - Classification - Kind """
kind_optional_attributes = ("parent", "actions", "enitities")
kind_optional_attributes = ("parent", "actions", "enitities",
"location",)
def __init__(self, *args, **kwargs):
super(Kind, self).__init__(*args, **kwargs)
......@@ -61,9 +62,14 @@ class Kind(Category):
if hasattr(self, "location"):
json["location"] = self.location
if hasattr(self, "attributes"):
json["attributes"] = serialize_attributes(self.attributes)
json["attributes"] = {}
for attribute in self.attributes:
json["attributes"][attribute.name] = (attribute
.render_as_json())
if hasattr(self, "actions"):
json["actions"] = serialize_attributes(self.actions)
json["actions"] = []
for action in self.actions:
json["actions"].append(action.scheme + action.term)
return json
......@@ -77,7 +83,10 @@ class Action(Category):
if hasattr(self, "title"):
json["title"] = self.title
if hasattr(self, "attributes"):
json["attributes"] = serialize_attributes(self.attributes)
json["attributes"] = {}
for attribute in self.attributes:
json["attributes"][attribute.name] = (attribute
.render_as_json())
return json
......@@ -93,8 +102,7 @@ class Mixin(Category):
kwargs)
def render_as_json(self):
json = {"term": self.term, "scheme": self.scheme,
"attributes": self.attributes, "actions": self.actions}
json = {"term": self.term, "scheme": self.scheme}
if hasattr(self, "title"):
json["title"] = self.title
if hasattr(self, "location"):
......@@ -103,6 +111,15 @@ class Mixin(Category):
json["depends"] = self.depends
if hasattr(self, "applies"):
json["applies"] = self.applies
if hasattr(self, "attributes"):
json["attributes"] = {}
for attribute in self.attributes:
json["attributes"][attribute.name] = (attribute
.render_as_json())
if hasattr(self, "actions"):
json["actions"] = []
for action in self.actions:
json["actions"].append(action.scheme + action.term)
return json
......@@ -169,11 +186,3 @@ class Link(Entity):
if hasattr(self, "title"):
json["title"] = self.title
return json
ENTITY_KIND = Kind("http://schemas.ogf.org/occi/core#", "entity",
title="Entity")
RESOURCE_KIND = Kind("http://schemas.ogf.org/occi/core#", "resource",
title="Resource",
parent="http://schemas.ogf.org/occi/core#entity")
""" Implementation of the OCCI - Infrastructure extension classes """
from occi_core import Action, Attribute, Resource
from occi_utils import action_list_for_resource
COMPUTE_ATTRIBUTES = [
Attribute("occi.compute.architecture", "Object", True, False,
description="CPU Architecture of the instance."),
Attribute("occi.compute.cores", "Object", True, False,
description="Number of virtual CPU cores assigned to " +
"the instance."),
Attribute("occi.compute.hostname", "Object", True, False,
description="Fully Qualified DNS hostname for the " +
"instance"),
Attribute("occi.compute.share", "Object", True, False,
description="Relative number of CPU shares for the " +
"instance."),
Attribute("occi.compute.memory", "Object", True, False,
description="Maximum RAM in gigabytes allocated to " +
"the instance."),
Attribute("occi.compute.state", "Object", False, True,
description="Current state of the instance."),
Attribute("occi.compute.state.message", "Object", False, False,
description="Human-readable explanation of the current " +
"instance state"),
]
COMPUTE_ACTIONS = [
Action("http://schemas.ogf.org/occi/infrastructure/compute/action#",
"start", title="Start compute instance"),
Action("http://schemas.ogf.org/occi/infrastructure/compute/action#",
"stop", title="Stop compute instance",
attributes=[Attribute("method", "Object", True, False), ]),
Action("http://schemas.ogf.org/occi/infrastructure/compute/action#",
"restart", title="Restart compute instance",
attributes=[Attribute("method", "Object",
True, False), ]),
Action("http://schemas.ogf.org/occi/infrastructure/compute/action#",
"suspend", title="Suspend compute instance",
attributes=[Attribute("method", "Object",
True, False), ]),
Action("http://schemas.ogf.org/occi/infrastructure/compute/action#",
"save", title="Create a template of compute instance",
attributes=[Attribute("method", "Object", True,
False),
Attribute("name", "Object", True, True), ]),
]
from occi_core import Resource
from occi_utils import action_list_for_resource, OcciActionInvocationError
from occi_instances import COMPUTE_ACTIONS
from common.models import HumanReadableException
COMPUTE_STATES = {
"NOSTATE": "inactive",
......@@ -82,7 +41,6 @@ class Compute(Resource):
"http://schemas.ogf.org/occi/infrastructure#compute", vm.pk)
self.vm = vm
self.attributes = self.set_attributes()
self.actions = action_list_for_resource(COMPUTE_ACTIONS)
def set_attributes(self):
......@@ -99,3 +57,91 @@ class Compute(Resource):
attributes["occi.compute.state.message"] = (COMPUTE_STATE_MESSAGES
.get(self.vm.state))
return attributes
def invoke_action(self, user, action, attributes):
base = "http://schemas.ogf.org/occi/infrastructure/compute/action#"
if action == (base + "start"):
self.start(user)
elif action == (base + "stop"):
self.stop(user, attributes)
elif action == (base + "restart"):
self.restart(user, attributes)
elif action == (base + "suspend"):
self.suspend(user, attributes)
elif action == (base + "save"):
self.save(user, attributes)
else:
raise OcciActionInvocationError(message="Undefined action.")
self.__init__(self.vm)
def start(self, user):
""" Start action on a compute instance """
try:
if self.vm.status == "SUSPENDED":
self.vm.wake_up(user=user)
else:
self.vm.deploy(user=user)
except HumanReadableException as e:
raise OcciActionInvocationError(message=e.get_user_text())
def stop(self, user, attributes):
""" Stop action on a compute instance """
if "method" not in attributes:
raise OcciActionInvocationError(message="No method given.")
if attributes["method"] in ("graceful", "acpioff",):
try:
# TODO: call shutdown properly
self.vm.shutdown(user=user)
except HumanReadableException as e:
raise OcciActionInvocationError(message=e.get_user_text())
elif attributes["method"] in ("poweroff",):
try:
self.vm.shut_off(user=user)
except HumanReadableException as e:
raise OcciActionInvocationError(message=e.get_user_text())
else:
raise OcciActionInvocationError(
message="Given method is not valid")
def restart(self, user, attributes):
""" Restart action on a compute instance """
if "method" not in attributes:
raise OcciActionInvocationError(message="No method given.")
if attributes["method"] in ("graceful", "warm",):
try:
# TODO: not working for some reason
self.vm.restart(user=user)
except HumanReadableException as e:
raise OcciActionInvocationError(message=e.get_user_text())
elif attributes["method"] in ("cold",):
try:
self.vm.reset(user=user)
except HumanReadableException as e:
raise OcciActionInvocationError(message=e.get_user_text())
else:
raise OcciActionInvocationError(
message="Given method is not valid")
def suspend(self, user, attributes):
""" Suspend action on a compute instance """
if "method" not in attributes:
raise OcciActionInvocationError(message="No method given.")
if attributes["method"] in ("hibernate", "suspend",):
try:
self.vm.sleep(user=user)
except HumanReadableException as e:
raise OcciActionInvocationError(message=e.get_user_text())
else:
raise OcciActionInvocationError(
message="Given method is not valid")
def save(self, user, attributes):
""" Save action on a compute instance """
# TODO: save template
raise OcciActionInvocationError(
message="Save action not implemented")
class Network(Resource):
# TODO: network
pass
"""" Utilities for the OCCI implementation of CIRCLE """
from django.http import JsonResponse, HttpResponse
import json
class OcciResourceInstanceNotExist(Exception):
def __init__(self):
message = "The resource instance does not exist."
super(OcciResourceInstanceNotExist, self).__init__(message)
self.response = JsonResponse({"error": message}, status=404,
charset="utf-8")
class OcciActionInvocationError(Exception):
def __init__(self, *args, **kwargs):
message = kwargs.get("message", "Could not invoke action.")
super(OcciActionInvocationError, self).__init__(message)
self.response = JsonResponse({"error": message}, status=400,
charset="utf-8")
class OcciResponse(HttpResponse):
""" A response class with its occi headers set """
# TODO: setting occi specific headers
def init(self, data, response_type, *args, **kwargs):
if response_type == "json":
data = json.dumps(data)
super(OcciResponse, self).__init__(data, status=418)
if response_type == "json":
self["Content-Type"] = "application/json"
else:
self["Content-Type"] = "text/plain"
self["Server"] = "OCCI/1.2"
def set_optional_attributes(self, optional_attributes, kwargs):
""" Sets the optional arguments of an instance.
......
from django.conf.urls import url
from views import (OcciLoginView, OcciLogoutView, OcciComputeView,
OcciComputeCollectionView)
from views import (OcciLoginView, OcciLogoutView, OcciQueryInterfaceView,
OcciComputeView, OcciComputeCollectionView)
urlpatterns = [
url(r'^login/$', OcciLoginView.as_view()),
url(r'^logout/$', OcciLogoutView.as_view()),
url(r'^-/$', OcciQueryInterfaceView.as_view()),
url(r'^compute/$', OcciComputeCollectionView.as_view()),
url(r'^compute/(?P<id>\d+)/$', OcciComputeView.as_view()),
]
......@@ -12,6 +12,9 @@ from django.utils.decorators import method_decorator
from vm.models.instance import Instance
from forms import OcciAuthForm
from occi_infrastructure import Compute
from occi_utils import (OcciResourceInstanceNotExist,
OcciActionInvocationError)
from occi_instances import ALL_KINDS, ALL_MIXINS, ALL_ACTIONS
class OcciLoginView(View):
......@@ -27,9 +30,9 @@ class OcciLoginView(View):
return JsonResponse(result, charset="utf-8")
def post(self, request, *args, **kwargs):
data = json.loads(request.body.decode("utf-8"))
""" Returns a response with a cookie to be used for the OCCI api
requests. """
data = json.loads(request.body.decode("utf-8"))
form = OcciAuthForm(data=data, request=request)
if form.is_valid():
result = {"result": "OK"}
......@@ -49,7 +52,22 @@ class OcciLogoutView(View):
return JsonResponse(result, charset="utf-8")
class OcciQueryInterfaceView(View):
""" The view of the OCCI query interface """
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs):
result = {"kinds": [], "mixins": [], "actions": []}
for kind in ALL_KINDS():
result["kinds"].append(kind.render_as_json())
for mixin in ALL_MIXINS():
result["mixins"].append(mixin.render_as_json())
for action in ALL_ACTIONS():
result["actions"].append(action.render_as_json())
return JsonResponse(result, charset="utf-8")
class OcciComputeCollectionView(View):
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs):
if not request.user.is_authenticated():
return HttpResponse(status=403)
......@@ -63,14 +81,38 @@ class OcciComputeCollectionView(View):
class OcciComputeView(View):
""" View of a compute instance """
def get_vm_object(self, request, vmid):
try:
vm = get_object_or_404(Instance.get_objects_with_level("user",
request.user), pk=vmid)
except Http404:
raise OcciResourceInstanceNotExist()
return Compute(vm)
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs):
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)
compute = self.get_vm_object(request, kwargs["id"])
except OcciResourceInstanceNotExist as e:
return e.json_response
return JsonResponse(compute.render_as_json(), charset="utf-8")
def post(self, request, *args, **kwargs):
requestData = json.loads(request.body.decode("utf-8"))
# TODO post request w/o action, compute creation
if not requestData["action"]:
return HttpResponse(status=404)
try:
compute = self.get_vm_object(request, kwargs["id"])
except OcciResourceInstanceNotExist as e:
return e.response
try:
compute.invoke_action(request.user,
requestData.get("action", None),
requestData.get("attributes", None))
except OcciActionInvocationError as e:
return e.response
# TODO: proper return value
return JsonResponse(compute.render_as_json(), status=200)
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