Commit 89f43b4b by Fukász Rómeó Ervin

refactor occi api views and classes

parent 5a4b3e24
Pipeline #615 failed with stage
in 0 seconds
...@@ -24,8 +24,25 @@ import json ...@@ -24,8 +24,25 @@ import json
# kikapcsoljuk a figyelmezteteseket # kikapcsoljuk a figyelmezteteseket
# urllib3.disable_warnings() # urllib3.disable_warnings()
def dumps(*args, **kwargs):
try:
return json.dumps(*args, **kwargs)
except Exception as e:
print(e)
return {}
def loads(*args, **kwargs):
try:
return json.loads(*args, **kwargs)
except Exception as e:
print(e)
return {}
# A szerver base url-je es a felhasznalo adatai # A szerver base url-je es a felhasznalo adatai
server = "https://vm.ik.bme.hu:15766/" server = "https://localhost/"
username = "admin" username = "admin"
password = "retekretek" password = "retekretek"
loginData = {"username": username, "password": password} loginData = {"username": username, "password": password}
...@@ -42,8 +59,8 @@ with requests.Session() as session: ...@@ -42,8 +59,8 @@ with requests.Session() as session:
print("----------") print("----------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True, print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) indent=4, separators=(",", ": ")))
print print
# Bejelentkezes # Bejelentkezes
...@@ -52,13 +69,58 @@ with requests.Session() as session: ...@@ -52,13 +69,58 @@ with requests.Session() as session:
# a cookie-ban # a cookie-ban
headers["X-CSRFToken"] = req.cookies['csrftoken'] headers["X-CSRFToken"] = req.cookies['csrftoken']
req = session.post(server + "occi/login/", verify=False, req = session.post(server + "occi/login/", verify=False,
data=json.dumps(loginData), headers=headers) data=dumps(loginData), headers=headers)
print("login") print("login")
print("-----") print("-----")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True, print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) indent=4, separators=(",", ": ")))
print
headers["X-CSRFToken"] = req.cookies['csrftoken']
req = session.get(server + "occi/token/", verify=False,
headers=headers)
print("token")
print("-----")
print("status_code: " + str(req.status_code))
print
print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": ")))
token = req.json()["token"]
req = session.get(server + "occi/test/?token=" + token, verify=False,
headers=headers)
print("token-use")
print("---------")
print(server + "occi/test/?token=" + token)
print("status_code: " + str(req.status_code))
print
print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": ")))
req = session.get(server + "occi/test/?token=asdasdasd" + token, verify=False,
headers=headers)
print("token-use")
print("---------")
print(server + "occi/test/?token=" + token)
print("status_code: " + str(req.status_code))
print
print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": ")))
exit()
# storage creation wrong
headers["X-CSRFToken"] = req.cookies['csrftoken']
req = session.put(server + "occi/storage/100", verify=False,
data=dumps({}), headers=headers)
print("storage_creation_wrong")
print("---------------")
print("status_code: " + str(req.status_code))
print
print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": ")))
print print
# query interface # query interface
...@@ -67,8 +129,8 @@ with requests.Session() as session: ...@@ -67,8 +129,8 @@ with requests.Session() as session:
print("---------------") print("---------------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True, print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) indent=4, separators=(",", ": ")))
print print
# osszes vm collectionkent # osszes vm collectionkent
...@@ -78,24 +140,24 @@ with requests.Session() as session: ...@@ -78,24 +140,24 @@ with requests.Session() as session:
print("------------------") print("------------------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True, print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) indent=4, separators=(",", ": ")))
print print
# az elso vm a listabol # az elso vm a listabol
vmid = json.loads(req.text)["resources"][0]["id"] vmid = loads(req.text)["resources"][0]["id"]
req = session.get(server + "occi/compute/" + vmid + "/", req = session.get(server + "occi/compute/" + vmid + "/",
headers=headers, verify=False) headers=headers, verify=False)
print("compute-" + str(vmid)) print("compute-" + str(vmid))
print("------------") print("------------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True, print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) indent=4, separators=(",", ": ")))
print print
# ha nem active, akkor azza tesszuk # ha nem active, akkor azza tesszuk
state = json.loads(req.text)["attributes"]["occi.compute.state"] state = loads(req.text)["attributes"]["occi.compute.state"]
action = "http://schemas.ogf.org/occi/infrastructure/compute/action#" action = "http://schemas.ogf.org/occi/infrastructure/compute/action#"
if state != "active": if state != "active":
try: try:
...@@ -104,52 +166,52 @@ with requests.Session() as session: ...@@ -104,52 +166,52 @@ with requests.Session() as session:
pass pass
req = session.post(server + "occi/compute/" + vmid + "/", req = session.post(server + "occi/compute/" + vmid + "/",
headers=headers, verify=False, headers=headers, verify=False,
data=json.dumps({"action": action + "start"})) data=dumps({"action": action + "start"}))
print("compute-" + str(vmid) + "-start") print("compute-" + str(vmid) + "-start")
print("---------------") print("---------------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True, print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) indent=4, separators=(",", ": ")))
print print
# restart # # restart
try: # try:
headers["X-CSRFToken"] = req.cookies['csrftoken'] # headers["X-CSRFToken"] = req.cookies['csrftoken']
except: # except:
pass # pass
actionatrs = {"method": "warm"} actionatrs = {"method": "cold"}
actioninv = {"action": action + "restart", "attributes": actionatrs} actioninv = {"action": action + "restart", "attributes": actionatrs}
req = session.post(server + "occi/compute/" + vmid + "/", # req = session.post(server + "occi/compute/" + vmid + "/",
headers=headers, verify=False, # headers=headers, verify=False,
data=json.dumps(actioninv)) # data=dumps(actioninv))
print("compute-" + str(vmid) + "-restart") # print("compute-" + str(vmid) + "-restart")
print("-----------------") # print("-----------------")
print("status_code: " + str(req.status_code)) # print("status_code: " + str(req.status_code))
print # print
print(json.dumps(json.loads(req.text), sort_keys=True, # print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) # indent=4, separators=(",", ": ")))
print # print
# suspend # stop
try: try:
headers["X-CSRFToken"] = req.cookies['csrftoken'] headers["X-CSRFToken"] = req.cookies['csrftoken']
except: except:
pass pass
actioninv["action"] = action + "stop" actioninv["action"] = action + "stop"
actioninv["attributes"]["method"] = "graceful" actioninv["attributes"]["method"] = "poweroff"
req = session.post(server + "occi/compute/" + vmid + "/", req = session.post(server + "occi/compute/" + vmid + "/",
headers=headers, verify=False, headers=headers, verify=False,
data=json.dumps(actioninv)) data=dumps(actioninv))
print("compute-" + str(vmid) + "-stop") print("compute-" + str(vmid) + "-stop")
print("-----------------") print("-----------------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True, print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) indent=4, separators=(",", ": ")))
print print
# nem letezo action # renew action
try: try:
headers["X-CSRFToken"] = req.cookies["csrftoken"] headers["X-CSRFToken"] = req.cookies["csrftoken"]
except: except:
...@@ -157,103 +219,172 @@ with requests.Session() as session: ...@@ -157,103 +219,172 @@ with requests.Session() as session:
actioninv["action"] = action + "renew" actioninv["action"] = action + "renew"
req = session.post(server + "occi/compute/" + vmid + "/", req = session.post(server + "occi/compute/" + vmid + "/",
headers=headers, verify=False, headers=headers, verify=False,
data=json.dumps(actioninv)) data=dumps(actioninv))
print("compute-" + str(vmid) + "-renew") print("compute-" + str(vmid) + "-renew")
print("-------------------") print("-------------------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True, print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) indent=4, separators=(",", ": ")))
print print
# vm krealas
# networkinterface add interface
try: try:
headers["X-CSRFToken"] = req.cookies["csrftoken"] headers["X-CSRFToken"] = req.cookies["csrftoken"]
except: except:
pass pass
# a template mixinje benne kell legyen az adatokban req = session.put(server + "occi/networkinterface/compute" + vmid + "-network3/",
# az osszes template a query interfacen megjelenik mint mixin
# azok a mixinek templatek amik az os_tpl mixintol fuggnek
putdata = {"mixins": [
"http://circlecloud.org/occi/templates/os#os_template_1"],
"other_occi_compute_data": "may be provided"}
req = session.put(server + "occi/compute/1/",
headers=headers, verify=False, headers=headers, verify=False,
data=json.dumps(putdata)) data=dumps({}))
print("create_compute") print("nif-creation")
print("--------------") print("-------------------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True, print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) indent=4, separators=(",", ": ")))
print print
# vm torles # networkinterface addport
actionatrs = {"protocol": "tcp", "port": 1111}
actioninv = {"action": "addport", "attributes": actionatrs}
try: try:
headers["X-CSRFToken"] = req.cookies["csrftoken"] headers["X-CSRFToken"] = req.cookies["csrftoken"]
except: except:
pass pass
vmid = json.loads(req.text)["id"] req = session.post(server + "occi/networkinterface/compute" + vmid + "-network3/",
req = session.delete(server + "occi/compute/" + vmid + "/", headers=headers, verify=False,
headers=headers, verify=False, data=dumps(actioninv))
data=json.dumps(putdata)) print("networkinterface-addport")
print("delete_compute") print("-------------------")
print("--------------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True, print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) indent=4, separators=(",", ": ")))
print print
# networkinterface removeport
actionatrs = {"protocol": "tcp", "port": 1111}
actioninv = {"action": "removeport", "attributes": actionatrs}
try: try:
headers["X-CSRFToken"] = req.cookies["csrftoken"] headers["X-CSRFToken"] = req.cookies["csrftoken"]
except: except:
pass pass
req = session.get(server + "occi/network/1/", headers=headers, req = session.post(server + "occi/networkinterface/compute" + vmid + "-network3/",
verify=False) headers=headers, verify=False,
print("storage") data=dumps(actioninv))
print("-------") print("networkinterface-addport")
print("status_code " + str(req.status_code)) print("-------------------")
print("status_code: " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True, print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) indent=4, separators=(",", ": ")))
try:
headers["X-CSRFToken"] = req.cookies["csrftoken"]
except:
pass
req = session.post(server + "occi/network/1/", headers=headers,
verify=False, data=json.dumps({"action": "online"}))
print("storage")
print("-------")
print("status_code " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True,
indent=4, separators=(",", ": ")))
# networkinterface remove interface
try: try:
headers["X-CSRFToken"] = req.cookies["csrftoken"] headers["X-CSRFToken"] = req.cookies["csrftoken"]
except: except:
pass pass
req = session.post(server + "occi/compute/96/", headers=headers, req = session.delete(server + "occi/networkinterface/compute" + vmid + "-network3/",
verify=False, data=json.dumps( headers=headers, verify=False)
{ print("nif-creation")
"attributes": { print("-------------------")
"occi.compute.memory": 0.250
}
}))
print("computerehelelel")
print("-------")
print("status_code " + str(req.status_code))
print
print(json.dumps(json.loads(req.text), sort_keys=True,
indent=4, separators=(",", ": ")))
# Kijelentkezes
req = session.get(server + "occi/logout/", headers=headers,
verify=False)
print("logout")
print("------")
print("status_code: " + str(req.status_code)) print("status_code: " + str(req.status_code))
print print
print(json.dumps(json.loads(req.text), sort_keys=True, print(dumps(loads(req.text), sort_keys=True,
indent=4, separators=(",", ": "))) indent=4, separators=(",", ": ")))
print
#
# # vm krealas
# try:
# headers["X-CSRFToken"] = req.cookies["csrftoken"]
# except:
# pass
# # a template mixinje benne kell legyen az adatokban
# # az osszes template a query interfacen megjelenik mint mixin
# # azok a mixinek templatek amik az os_tpl mixintol fuggnek
# putdata = {"mixins": [
# "http://circlecloud.org/occi/templates/os#os_template_1"],
# "other_occi_compute_data": "may be provided"}
# req = session.put(server + "occi/compute/1/",
# headers=headers, verify=False,
# data=dumps(putdata))
# print("create_compute")
# print("--------------")
# print("status_code: " + str(req.status_code))
# print
# print(dumps(loads(req.text), sort_keys=True,
# indent=4, separators=(",", ": ")))
# print
#
# # vm torles
# try:
# headers["X-CSRFToken"] = req.cookies["csrftoken"]
# except:
# pass
# vmid = loads(req.text)["id"]
# req = session.delete(server + "occi/compute/" + vmid + "/",
# headers=headers, verify=False,
# data=dumps(putdata))
# print("delete_compute")
# print("--------------")
# print("status_code: " + str(req.status_code))
# print
# print(dumps(loads(req.text), sort_keys=True,
# indent=4, separators=(",", ": ")))
# print
#
# try:
# headers["X-CSRFToken"] = req.cookies["csrftoken"]
# except:
# pass
# req = session.get(server + "occi/network/1/", headers=headers,
# verify=False)
# print("storage")
# print("-------")
# print("status_code " + str(req.status_code))
# print
# print(dumps(loads(req.text), sort_keys=True,
# indent=4, separators=(",", ": ")))
#
# try:
# headers["X-CSRFToken"] = req.cookies["csrftoken"]
# except:
# pass
# req = session.post(server + "occi/network/1/", headers=headers,
# verify=False, data=dumps({"action": "online"}))
# print("storage")
# print("-------")
# print("status_code " + str(req.status_code))
# print
# print(dumps(loads(req.text), sort_keys=True,
# indent=4, separators=(",", ": ")))
#
# try:
# headers["X-CSRFToken"] = req.cookies["csrftoken"]
# except:
# pass
# req = session.post(server + "occi/compute/96/", headers=headers,
# verify=False, data=dumps(
# {
# "attributes": {
# "occi.compute.memory": 0.250
# }
# }))
# print("computerehelelel")
# print("-------")
# print("status_code " + str(req.status_code))
# print
# print(dumps(loads(req.text), sort_keys=True,
# indent=4, separators=(",", ": ")))
#
# # Kijelentkezes
# req = session.get(server + "occi/logout/", headers=headers,
# verify=False)
# print("logout")
# print("------")
# print("status_code: " + str(req.status_code))
# print
# print(dumps(loads(req.text), sort_keys=True,
# indent=4, separators=(",", ": ")))
...@@ -19,10 +19,10 @@ ...@@ -19,10 +19,10 @@
""" 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
class Attribute: class Attribute(object):
""" OCCI 1.2 - CORE - Classification - Attribute """ """ OCCI 1.2 - CORE - Classification - Attribute """
TYPES = ("Object", "List", "Hash") TYPES = ("Object", "List", "Hash")
...@@ -36,16 +36,16 @@ class Attribute: ...@@ -36,16 +36,16 @@ class Attribute:
self.required = required self.required = required
set_optional_attributes(self, self.optional_attributes, kwargs) set_optional_attributes(self, self.optional_attributes, kwargs)
def render_as_json(self): def as_dict(self):
json = {"mutable": self.mutable, "required": self.required, res = {"mutable": self.mutable, "required": self.required,
"type": self.type} "type": self.type}
if hasattr(self, "pattern"): if hasattr(self, "pattern"):
json["pattern"] = self.pattern res["pattern"] = self.pattern
if hasattr(self, "default"): if hasattr(self, "default"):
json["default"] = self.default res["default"] = self.default
if hasattr(self, "description"): if hasattr(self, "description"):
json["description"] = self.description res["description"] = self.description
return json return res
class Category(object): class Category(object):
...@@ -71,24 +71,23 @@ class Kind(Category): ...@@ -71,24 +71,23 @@ class Kind(Category):
set_optional_attributes(self, self.kind_optional_attributes, set_optional_attributes(self, self.kind_optional_attributes,
kwargs) kwargs)
def render_as_json(self): def as_dict(self):
json = {"term": self.term, "scheme": self.scheme} res = {"term": self.term, "scheme": self.scheme}
if hasattr(self, "title"): if hasattr(self, "title"):
json["title"] = self.title res["title"] = self.title
if hasattr(self, "parent"): if hasattr(self, "parent"):
json["parent"] = self.parent res["parent"] = self.parent
if hasattr(self, "location"): if hasattr(self, "location"):
json["location"] = self.location res["location"] = self.location
if hasattr(self, "attributes"): if hasattr(self, "attributes"):
json["attributes"] = {} res["attributes"] = {}
for attribute in self.attributes: for attribute in self.attributes:
json["attributes"][attribute.name] = (attribute res["attributes"][attribute.name] = (attribute.as_dict())
.render_as_json())
if hasattr(self, "actions"): if hasattr(self, "actions"):
json["actions"] = [] res["actions"] = []
for action in self.actions: for action in self.actions:
json["actions"].append(action.scheme + action.term) res["actions"].append(action.scheme + action.term)
return json return res
class Action(Category): class Action(Category):
...@@ -97,16 +96,15 @@ class Action(Category): ...@@ -97,16 +96,15 @@ class Action(Category):
def __init(self, *args, **kwargs): def __init(self, *args, **kwargs):
super(Action, self).__init__(*args, **kwargs) super(Action, self).__init__(*args, **kwargs)
def render_as_json(self): def as_dict(self):
json = {"term": self.term, "scheme": self.scheme} res = {"term": self.term, "scheme": self.scheme}
if hasattr(self, "title"): if hasattr(self, "title"):
json["title"] = self.title res["title"] = self.title
if hasattr(self, "attributes"): if hasattr(self, "attributes"):
json["attributes"] = {} res["attributes"] = {}
for attribute in self.attributes: for attribute in self.attributes:
json["attributes"][attribute.name] = (attribute res["attributes"][attribute.name] = (attribute.as_dict())
.render_as_json()) return res
return json
class Mixin(Category): class Mixin(Category):
...@@ -120,26 +118,25 @@ class Mixin(Category): ...@@ -120,26 +118,25 @@ class Mixin(Category):
set_optional_attributes(self, self.mixin_optional_attributes, set_optional_attributes(self, self.mixin_optional_attributes,
kwargs) kwargs)
def render_as_json(self): def as_dict(self):
json = {"term": self.term, "scheme": self.scheme} res = {"term": self.term, "scheme": self.scheme}
if hasattr(self, "title"): if hasattr(self, "title"):
json["title"] = self.title res["title"] = self.title
if hasattr(self, "location"): if hasattr(self, "location"):
json["location"] = self.location res["location"] = self.location
if hasattr(self, "depends"): if hasattr(self, "depends"):
json["depends"] = self.depends res["depends"] = self.depends
if hasattr(self, "applies"): if hasattr(self, "applies"):
json["applies"] = self.applies res["applies"] = self.applies
if hasattr(self, "attributes"): if hasattr(self, "attributes"):
json["attributes"] = {} res["attributes"] = {}
for attribute in self.attributes: for attribute in self.attributes:
json["attributes"][attribute.name] = (attribute res["attributes"][attribute.name] = (attribute.as_dict())
.render_as_json())
if hasattr(self, "actions"): if hasattr(self, "actions"):
json["actions"] = [] res["actions"] = []
for action in self.actions: for action in self.actions:
json["actions"].append(action.scheme + action.term) res["actions"].append(action.scheme + action.term)
return json return res
class Entity(object): class Entity(object):
...@@ -161,24 +158,24 @@ class Resource(Entity): ...@@ -161,24 +158,24 @@ class Resource(Entity):
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(
kwargs) self, self.resource_optional_attributes, kwargs)
def render_as_json(self): def as_dict(self):
json = {"kind": self.kind, "id": self.id} res = {"kind": self.kind, "id": self.id}
if hasattr(self, "title"): if hasattr(self, "title"):
json["title"] = self.title res["title"] = self.title
if hasattr(self, "summary"): if hasattr(self, "summary"):
json["summary"] = self.summary res["summary"] = self.summary
if hasattr(self, "attributes"): if hasattr(self, "attributes"):
json["attributes"] = self.attributes res["attributes"] = self.attributes
if hasattr(self, "actions"): if hasattr(self, "actions"):
json["actions"] = self.actions res["actions"] = self.actions
if hasattr(self, "links"): if hasattr(self, "links"):
json["links"] = self.links res["links"] = self.links
if hasattr(self, "mixins"): if hasattr(self, "mixins"):
json["mixins"] = self.mixins res["mixins"] = self.mixins
return json return res
class Link(Entity): class Link(Entity):
...@@ -190,18 +187,17 @@ class Link(Entity): ...@@ -190,18 +187,17 @@ class Link(Entity):
super(Link, self).__init__(*args, **kwargs) super(Link, self).__init__(*args, **kwargs)
self.source = source self.source = source
self.target = target self.target = target
set_optional_attributes(self, self.link_optional_attributes, set_optional_attributes(self, self.link_optional_attributes, kwargs)
kwargs)
def render_as_json(self): def as_dict(self):
json = {"kind": self.kind, "id": self.id, "source": self.source, res = {"kind": self.kind, "id": self.id, "source": self.source,
"target": self.target} "target": self.target}
if hasattr(self, "mixins"): if hasattr(self, "mixins"):
json["mixins"] = self.mixins res["mixins"] = self.mixins
if hasattr(self, "attributes"): if hasattr(self, "attributes"):
json["attributes"] = self.attributes res["attributes"] = self.attributes
if hasattr(self, "actions"): if hasattr(self, "actions"):
json["actions"] = self.actions res["actions"] = self.actions
if hasattr(self, "title"): if hasattr(self, "title"):
json["title"] = self.title res["title"] = self.title
return json return res
...@@ -19,12 +19,13 @@ ...@@ -19,12 +19,13 @@
""" Implementation of the OCCI - Infrastructure extension classes """ """ Implementation of the OCCI - Infrastructure extension classes """
from occi_core import Resource, Link from occi.core import Resource, Link
from occi_utils import action_list_for_resource, OcciActionInvocationError from occi.utils import action_list_for_resource, OcciActionInvocationError
from occi_instances import (COMPUTE_ACTIONS, LEASETIME_ACTIONS, from occi.instances import (COMPUTE_ACTIONS, LEASETIME_ACTIONS,
STORAGE_ACTIONS, NETWORK_ACTIONS) STORAGE_ACTIONS, NETWORK_ACTIONS)
from common.models import HumanReadableException from common.models import HumanReadableException
from celery.exceptions import TimeoutError from celery.exceptions import TimeoutError
from firewall.models import Rule
import logging import logging
...@@ -117,11 +118,11 @@ class Compute(Resource): ...@@ -117,11 +118,11 @@ class Compute(Resource):
for disk in disks: for disk in disks:
storages.append(Storage(disk)) storages.append(Storage(disk))
for storage in storages: for storage in storages:
links.append(StorageLink(self, storage).render_as_json()) links.append(StorageLink(self, storage).as_dict())
nics = [NetworkInterface(self, Network(nic.vlan)) nics = [NetworkInterface(self, Network(nic.vlan))
for nic in self.vm.interface_set.all()] for nic in self.vm.interface_set.all()]
for networkinterface in nics: for networkinterface in nics:
links.append(networkinterface.render_as_json()) links.append(networkinterface.as_dict())
return links return links
def invoke_action(self, user, action, attributes): def invoke_action(self, user, action, attributes):
...@@ -137,6 +138,10 @@ class Compute(Resource): ...@@ -137,6 +138,10 @@ class Compute(Resource):
self.save(user, attributes) self.save(user, attributes)
elif action.endswith("renew"): elif action.endswith("renew"):
self.renew(user) self.renew(user)
elif action.endswith("createstorage"):
self.create_disk(user, attributes)
elif action.endswith("downloadstorage"):
self.download_disk(user, attributes)
else: else:
raise OcciActionInvocationError(message="Undefined action.") raise OcciActionInvocationError(message="Undefined action.")
self.__init__(self.vm) self.__init__(self.vm)
...@@ -147,6 +152,28 @@ class Compute(Resource): ...@@ -147,6 +152,28 @@ class Compute(Resource):
except HumanReadableException as e: except HumanReadableException as e:
raise OcciActionInvocationError(message=e.get_user_text()) raise OcciActionInvocationError(message=e.get_user_text())
def create_disk(self, user, attributes):
if "size" not in attributes:
raise OcciActionInvocationError(
message="Storage size is missing from action attributes!"
)
try:
self.vm.create_disk(user=user, size=attributes["size"],
name=attributes.get("name"))
except HumanReadableException as e:
raise OcciActionInvocationError(message=e.get_user_text())
def download_disk(self, user, attributes):
if "url" not in attributes:
raise OcciActionInvocationError(
message="Storage image url is missing from action attributes!"
)
try:
self.vm.download_disk(user=user, url=attributes["url"],
name=attributes.get("name"))
except HumanReadableException as e:
raise OcciActionInvocationError(message=e.get_user_text())
def start(self, user): def start(self, user):
""" Start action on a compute instance """ """ Start action on a compute instance """
try: try:
...@@ -371,9 +398,50 @@ class NetworkInterface(Link): ...@@ -371,9 +398,50 @@ class NetworkInterface(Link):
self.mixins = [ self.mixins = [
("http://schemas.ogf.org/occi/infrastructure/networkinterface#" + ("http://schemas.ogf.org/occi/infrastructure/networkinterface#" +
"ipnetworkinterface"), "ipnetworkinterface"),
("http://circlecloud.org/occi/infrastructure/networkinterface#" +
"ports"),
] ]
self.attributes = self.set_attributes() self.attributes = self.set_attributes()
def invoke_action(self, user, action, attributes):
if action.endswith("addport"):
self.addport(user, attributes)
elif action.endswith("removeport"):
self.removeport(user, attributes)
else:
raise OcciActionInvocationError(message="Undefined action.")
self.__init__(Compute(self.compute.vm), Network(self.network.vlan))
def addport(self, user, attributes):
if "port" not in attributes or "protocol" not in attributes:
raise OcciActionInvocationError(
message="Please supply the protocol and the port!")
try:
self.compute.vm.add_port(user=user, host=self.interface.host,
proto=attributes["protocol"],
port=int(attributes["port"]))
except HumanReadableException as e:
raise OcciActionInvocationError(message=e.get_user_text())
except AttributeError:
raise OcciActionInvocationError(
message="Unmanaged interfaces cant add ports."
)
def removeport(self, user, attributes):
if "port" not in attributes or "protocol" not in attributes:
raise OcciActionInvocationError(
message="Please supply the protocol and the port!")
try:
rule = Rule.objects.filter(host=self.interface.host).filter(
dport=attributes["port"]).get(
proto=attributes["protocol"])
except Rule.DoesNotExist:
raise OcciActionInvocationError(message="Port does not exist!")
try:
self.compute.vm.remove_port(user=user, rule=rule)
except HumanReadableException as e:
raise OcciActionInvocationError(message=e.get_user_text())
def set_attributes(self): def set_attributes(self):
attributes = {} attributes = {}
attributes["occi.networkinterface.interface"] = ( attributes["occi.networkinterface.interface"] = (
...@@ -382,10 +450,17 @@ class NetworkInterface(Link): ...@@ -382,10 +450,17 @@ class NetworkInterface(Link):
attributes["occi.networkinterface.state"] = "active" attributes["occi.networkinterface.state"] = "active"
attributes["occi.networkinterface.state.message"] = ( attributes["occi.networkinterface.state.message"] = (
"The networkinterface is active.") "The networkinterface is active.")
attributes["occi.networkinterface.address"] = ( if self.interface.host:
unicode(self.interface.host.ipv4)) attributes["occi.networkinterface.address"] = (
unicode(self.interface.host.ipv4))
attributes["occi.networkinterface.gateway"] = ( attributes["occi.networkinterface.gateway"] = (
unicode(self.interface.vlan.network4.ip)) unicode(self.interface.vlan.network4.ip))
attributes["occi.networkinterface.allocation"] = ( attributes["occi.networkinterface.allocation"] = (
self.network.attributes["occi.network.allocation"]) self.network.attributes["occi.network.allocation"])
attributes["org.circlecloud.occi.networkinterface.ports"] = (
self.get_open_ports())
return attributes return attributes
def get_open_ports(self):
return [{"port": rule.dport, "protocol": rule.proto}
for rule in Rule.objects.filter(host=self.interface.host)]
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
""" Required instances of the OCCI classes """ """ Required instances of the OCCI classes """
from vm.models.instance import InstanceTemplate from vm.models.instance import InstanceTemplate
from occi_core import Kind, Mixin, Attribute, Action from occi.core import Kind, Mixin, Attribute, Action
ENTITY_KIND = Kind("http://schemas.ogf.org/occi/core#", "entity", ENTITY_KIND = Kind("http://schemas.ogf.org/occi/core#", "entity",
...@@ -237,6 +237,42 @@ CREDENTIALS_MIXIN = Mixin("http://circlecloud.org/occi/infrastructure/" + ...@@ -237,6 +237,42 @@ CREDENTIALS_MIXIN = Mixin("http://circlecloud.org/occi/infrastructure/" +
applies="http://schemas.ogf.org/occi/" + applies="http://schemas.ogf.org/occi/" +
"infrastructure#compute") "infrastructure#compute")
NETWORKINTERFACE_PORTS_ATTRIBUTES = [
Attribute("org.circlecloud.occi.networkinterface.ports", "List", False,
False, description="A list of open ports on the interface."),
]
NETWORKINTERFACE_PORTS_ACTIONS = [
Action(
"http://schemas.ogf.org/occi/infrastructure/networkinterface/action#",
"addport",
title="Open a port on a network interface.",
attributes=[
Attribute("protocol", "Enum {tcp, udp, icmp}", True, False),
Attribute("port", "Integer", False, True),
],
),
Action(
"http://schemas.ogf.org/occi/infrastructure/networkinterface/action#",
"removeport",
title="Closes a port on a network interface.",
attributes=[
Attribute("protocol", "Enum {tcp, udp, icmp}", True, False),
Attribute("port", "Integer", False, True),
],
),
]
NETWORKINTERFACE_PORTS_MIXIN = Mixin(
"http://circlecloud.org/occi/infrastructure/networkinterface#",
"ports",
title="Network interface ports mixin",
attributes=NETWORKINTERFACE_PORTS_ATTRIBUTES,
actions=NETWORKINTERFACE_PORTS_ACTIONS,
applies="http://schemas.ogf.org/occi/infrastructure#networkinterface",
)
LEASETIME_ATTRIBUTES = [ LEASETIME_ATTRIBUTES = [
Attribute("org.circlecloud.occi.leasetime.suspend", "String", False, Attribute("org.circlecloud.occi.leasetime.suspend", "String", False,
False, description="The time remaining until the compute " + False, description="The time remaining until the compute " +
...@@ -264,11 +300,13 @@ OS_TPL_MIXIN = Mixin("http://schemas.ogf.org/occi/infrastructure#", ...@@ -264,11 +300,13 @@ OS_TPL_MIXIN = Mixin("http://schemas.ogf.org/occi/infrastructure#",
"os_tpl", "os_tpl",
title="OS Template") title="OS Template")
ACTION_ARRAYS = [ ACTION_ARRAYS = [
COMPUTE_ACTIONS, COMPUTE_ACTIONS,
NETWORK_ACTIONS, NETWORK_ACTIONS,
STORAGE_ACTIONS, STORAGE_ACTIONS,
LEASETIME_ACTIONS, LEASETIME_ACTIONS,
NETWORKINTERFACE_PORTS_ACTIONS,
] ]
...@@ -290,10 +328,38 @@ def os_tpl_mixins(user): ...@@ -290,10 +328,38 @@ def os_tpl_mixins(user):
templates = InstanceTemplate.get_objects_with_level("user", user) templates = InstanceTemplate.get_objects_with_level("user", user)
result = [] result = []
for template in templates: for template in templates:
result.append(Mixin("http://circlecloud.org/occi/templates/os#", template_attrs = [
"os_template_" + str(template.pk), Attribute("occi.compute.architecture", "Enum {x86, x64}",
title=template.name, True, False,
depends=(OS_TPL_MIXIN.scheme + OS_TPL_MIXIN.term))) default={
"x86_64": "x64",
"x86-64 (64 bit)": "x64",
"i686": "x86",
"x86 (32 bit)": "x86"
}[template.arch],
description="CPU Architecture of the instance."),
Attribute("occi.compute.cores", "Integer", True, False,
default=template.num_cores,
description="Number of virtual CPU cores assigned to " +
"the instance."),
Attribute("occi.compute.share", "Integer", True, False,
default=template.priority,
description="Relative number of CPU shares for the " +
"instance."),
Attribute("occi.compute.memory", "Float, 10^9 (GiB)", True, False,
default=template.ram_size,
description="Maximum RAM in gigabytes allocated to " +
"the instance."),
]
result.append(
Mixin(
"http://circlecloud.org/occi/templates/os#",
"os_template_" + str(template.pk),
title=template.name,
depends=(OS_TPL_MIXIN.scheme + OS_TPL_MIXIN.term),
attributes=template_attrs,
)
)
return result return result
...@@ -304,6 +370,7 @@ def ALL_MIXINS(user): ...@@ -304,6 +370,7 @@ def ALL_MIXINS(user):
CREDENTIALS_MIXIN, CREDENTIALS_MIXIN,
OS_TPL_MIXIN, OS_TPL_MIXIN,
LEASETIME_MIXIN, LEASETIME_MIXIN,
NETWORKINTERFACE_PORTS_MIXIN,
] ]
template_mixins = os_tpl_mixins(user) template_mixins = os_tpl_mixins(user)
for template in template_mixins: for template in template_mixins:
......
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import ensure_csrf_cookie
from occi.utils import OcciRequestNotValid
class EnsureCsrfTokenMixin(object):
@method_decorator(ensure_csrf_cookie)
def dispatch(self, *args, **kwargs):
return super(EnsureCsrfTokenMixin, self).dispatch(*args, **kwargs)
class OcciViewMixin(EnsureCsrfTokenMixin):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated():
return OcciRequestNotValid(message="Authentication required.",
status=403).response
return super(OcciViewMixin, self).dispatch(request, *args, **kwargs)
...@@ -17,13 +17,18 @@ ...@@ -17,13 +17,18 @@
from django.conf.urls import url from django.conf.urls import url
from views import (OcciLoginView, OcciLogoutView, OcciQueryInterfaceView, from occi.views import (OcciLoginView, OcciLogoutView, OcciQueryInterfaceView,
OcciComputeView, OcciComputeCollectionView, OcciComputeView, OcciComputeCollectionView,
OcciStorageView, OcciStorageCollectionView, OcciStorageView, OcciStorageCollectionView,
OcciNetworkView, OcciNetworkCollectionView) OcciNetworkView, OcciNetworkCollectionView,
OcciStoragelinkView, OcciStoragelinkCollectionView,
OcciNetworkInterfaceView,
OcciNetworkInterfaceCollectionView,)
from common.views import GenerateTokenView
urlpatterns = [ urlpatterns = [
url(r'^login/token/$', GenerateTokenView.as_view()),
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'^-/$', OcciQueryInterfaceView.as_view()), url(r'^-/$', OcciQueryInterfaceView.as_view()),
...@@ -33,4 +38,11 @@ urlpatterns = [ ...@@ -33,4 +38,11 @@ urlpatterns = [
url(r'^storage/(?P<id>\d+)/$', OcciStorageView.as_view()), url(r'^storage/(?P<id>\d+)/$', OcciStorageView.as_view()),
url(r'^network/$', OcciNetworkCollectionView.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()),
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()),
] ]
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
"""" Utilities for the OCCI implementation of CIRCLE """ """" Utilities for the OCCI implementation of CIRCLE """
from django.http import HttpResponse from django.http import JsonResponse
import json import json
...@@ -89,44 +89,33 @@ def occi_response(data, *args, **kwargs): ...@@ -89,44 +89,33 @@ def occi_response(data, *args, **kwargs):
by default. """ by default. """
status = kwargs.get("status", 200) status = kwargs.get("status", 200)
# TODO: support for renderings other than json (e.g., text/plain) # TODO: support for renderings other than json (e.g., text/plain)
data = json.dumps(data) response = JsonResponse(data, status=status)
response = HttpResponse(data, charset="utf-8", status=status,
content_type="application/json; charset=utf-8")
# TODO: use Server header instead of OCCI-Server # TODO: use Server header instead of OCCI-Server
response["OCCI-Server"] = "OCCI/1.2" response["OCCI-Server"] = "OCCI/1.2"
response["Accept"] = "application/json" response["Accept"] = "application/json"
return response return response
def validate_request(request, authentication_required=True, def validate_request_data(request, data_keys):
has_data=False, **kwargs): """ This function checks if all the required data keys are set and if the
""" This function checks if the request's content type is input is a valid json object. """
application/json and if the data is a valid json object. If the # checking content type
authentication_required parameter is 'True', it will also check if if request.META.get("CONTENT_TYPE") != "application/json":
the user is authenticated. """ raise OcciRequestNotValid("Only application/json content type" +
# checking if the user is authenticated " is allowed.")
if authentication_required: # checking if the data is a valid json
if not request.user.is_authenticated(): try:
raise OcciRequestNotValid("Authentication required.", status=403) data = json.loads(request.body.decode("utf-8"))
if has_data: except KeyError:
# checking content type raise OcciRequestNotValid("The json provided in the request is " +
if request.META.get("CONTENT_TYPE") != "application/json": "not valid.")
raise OcciRequestNotValid("Only application/json content type" + # checking if provided keys are in the json
" is allowed.") for key in data_keys:
# checking if the data is a valid json if key not in data:
try: raise OcciRequestNotValid(key + " key is required.")
data = json.loads(request.body.decode("utf-8")) # if validation was successful, the function returns the parsed
except KeyError: # json data
raise OcciRequestNotValid("The json provided in the request is " + return data
"not valid.")
# checking if provided keys are in the json
if "data_keys" in kwargs:
for key in kwargs["data_keys"]:
if key not in data:
raise OcciRequestNotValid(key + " key is required.")
# if validation was successful, the function returns the parsed
# json data
return data
def set_optional_attributes(self, optional_attributes, kwargs): def set_optional_attributes(self, optional_attributes, kwargs):
......
...@@ -25,33 +25,33 @@ from django.views.generic import View ...@@ -25,33 +25,33 @@ from django.views.generic import View
from django.contrib.auth import logout from django.contrib.auth import logout
from django.http import Http404 from django.http import Http404
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.views.decorators.csrf import ensure_csrf_cookie
from django.utils.decorators import method_decorator
from vm.models.instance import Instance, InstanceTemplate from vm.models.instance import Instance, InstanceTemplate
from storage.models import Disk from storage.models import Disk
from firewall.models import Vlan from firewall.models import Vlan
from forms import OcciAuthForm from occi.forms import OcciAuthForm
from occi_infrastructure import Compute, Storage, Network from occi.infrastructure import (Compute, Storage, Network, StorageLink,
from occi_utils import (OcciResourceInstanceNotExist, NetworkInterface,)
from occi.utils import (OcciResourceInstanceNotExist,
OcciActionInvocationError, OcciActionInvocationError,
OcciRequestNotValid, OcciRequestNotValid,
OcciResourceCreationError, OcciResourceCreationError,
OcciResourceDeletionError, OcciResourceDeletionError,
occi_response, occi_response,
validate_request) validate_request_data)
from occi_instances import ALL_KINDS, ALL_MIXINS, ALL_ACTIONS from occi.instances import ALL_KINDS, ALL_MIXINS, ALL_ACTIONS
from common.models import HumanReadableException from common.models import HumanReadableException
from occi.mixins import OcciViewMixin, EnsureCsrfTokenMixin
import logging import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class OcciLoginView(View): class OcciLoginView(EnsureCsrfTokenMixin, View):
""" Authentication for the usage of the OCCI api. """ Authentication for the usage of the OCCI api.
This view responds with 200 and the access token in a Cookie if the This view responds with 200 and the access token in a Cookie if the
authentication succeeded, and with 400 if the provided username and authentication succeeded, and with 400 if the provided username and
password is not valid. """ password is not valid. """
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
""" 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. """
...@@ -62,8 +62,6 @@ class OcciLoginView(View): ...@@ -62,8 +62,6 @@ class OcciLoginView(View):
""" Returns a response with a cookie to be used for the OCCI api """ Returns a response with a cookie to be used for the OCCI api
requests. """ requests. """
data = json.loads(request.body.decode("utf-8")) data = json.loads(request.body.decode("utf-8"))
log.error(data)
print(data)
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"}
...@@ -75,7 +73,7 @@ class OcciLoginView(View): ...@@ -75,7 +73,7 @@ class OcciLoginView(View):
return occi_response(result, status=400) return occi_response(result, status=400)
class OcciLogoutView(View): class OcciLogoutView(EnsureCsrfTokenMixin, View):
""" Logout """ """ Logout """
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
...@@ -84,21 +82,17 @@ class OcciLogoutView(View): ...@@ -84,21 +82,17 @@ class OcciLogoutView(View):
return occi_response(result) return occi_response(result)
class OcciQueryInterfaceView(View): class OcciQueryInterfaceView(OcciViewMixin, View):
""" The view of the OCCI query interface """ """ The view of the OCCI query interface """
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
try:
validate_request(request)
except OcciRequestNotValid as e:
return e.response
result = {"kinds": [], "mixins": [], "actions": []} result = {"kinds": [], "mixins": [], "actions": []}
for kind in ALL_KINDS(): for kind in ALL_KINDS():
result["kinds"].append(kind.render_as_json()) result["kinds"].append(kind.as_dict())
for mixin in ALL_MIXINS(request.user): result["mixins"] = [mixin.as_dict() for mixin in
result["mixins"].append(mixin.render_as_json()) ALL_MIXINS(request.user)]
for action in ALL_ACTIONS(): result["actions"] = [action.as_dict()
result["actions"].append(action.render_as_json()) for action in ALL_ACTIONS()]
return occi_response(result) return occi_response(result)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
...@@ -114,32 +108,20 @@ class OcciQueryInterfaceView(View): ...@@ -114,32 +108,20 @@ class OcciQueryInterfaceView(View):
"query interface."}, status=400) "query interface."}, status=400)
class OcciComputeCollectionView(View): class OcciComputeCollectionView(OcciViewMixin, View):
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
try: resources = [Compute(vm).as_dict()
validate_request(request) for vm in Instance.get_objects_with_level(
except OcciRequestNotValid as e: "owner", request.user).filter(destroyed_at=None)]
return e.response return occi_response({"resources": resources})
vms = (Instance.get_objects_with_level("owner", request.user)
.filter(destroyed_at=None))
json = {"resources": []}
for vm in vms:
json["resources"].append(Compute(vm).render_as_json())
return occi_response(json)
def put(self, request, *args, **kwargs): def put(self, request, *args, **kwargs):
# TODO: vm creation # TODO: vm creation
return occi_response({"message": "TODO"}) return occi_response({"message": "TODO"})
try:
Instance.create_from_template(
InstanceTemplate.objects.get(pk=1), request.user)
except Exception:
return occi_response({"test": "tset"})
return occi_response({})
class OcciComputeView(View): class OcciComputeView(OcciViewMixin, View):
""" View of a compute instance """ """ View of a compute instance """
def get_vm_object(self, user, vmid): def get_vm_object(self, user, vmid):
...@@ -150,16 +132,12 @@ class OcciComputeView(View): ...@@ -150,16 +132,12 @@ class OcciComputeView(View):
raise OcciResourceInstanceNotExist() raise OcciResourceInstanceNotExist()
return Compute(vm) return Compute(vm)
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if not request.user.is_authenticated():
return occi_response({"error": "Authentication required."},
status=403)
try: try:
compute = self.get_vm_object(request.user, kwargs["id"]) compute = self.get_vm_object(request.user, kwargs["id"])
except OcciResourceInstanceNotExist as e: except OcciResourceInstanceNotExist as e:
return e.response return e.response
return occi_response(compute.render_as_json(), charset="utf-8") return occi_response(compute.as_dict(), charset="utf-8")
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
requestData = json.loads(request.body.decode("utf-8")) requestData = json.loads(request.body.decode("utf-8"))
...@@ -174,7 +152,7 @@ class OcciComputeView(View): ...@@ -174,7 +152,7 @@ class OcciComputeView(View):
requestData.get("attributes", None)) requestData.get("attributes", None))
except OcciActionInvocationError as e: except OcciActionInvocationError as e:
return e.response return e.response
return occi_response(compute.render_as_json(), status=200) return occi_response(compute.as_dict(), status=200)
elif "attributes" in requestData: elif "attributes" in requestData:
attrs = requestData["attributes"] attrs = requestData["attributes"]
try: try:
...@@ -197,7 +175,7 @@ class OcciComputeView(View): ...@@ -197,7 +175,7 @@ class OcciComputeView(View):
) )
except HumanReadableException as e: except HumanReadableException as e:
log.warning(e.get_user_text()) log.warning(e.get_user_text())
return occi_response(Compute(vm).render_as_json(), status=200) return occi_response(Compute(vm).as_dict(), status=200)
return occi_response({"error": "Bad request"}, status=400) return occi_response({"error": "Bad request"}, status=400)
def put(self, request, *args, **kwargs): def put(self, request, *args, **kwargs):
...@@ -208,8 +186,8 @@ class OcciComputeView(View): ...@@ -208,8 +186,8 @@ class OcciComputeView(View):
# there has to be a mixins array in the provided rendering # there has to be a mixins array in the provided rendering
data_keys = ["mixins"] data_keys = ["mixins"]
try: try:
requestData = validate_request(request, True, True, requestData = validate_request_data(request,
data_keys=data_keys) data_keys=data_keys)
except OcciRequestNotValid as e: except OcciRequestNotValid as e:
return e.response return e.response
ostpl = "http://circlecloud.org/occi/templates/os#os_template_" ostpl = "http://circlecloud.org/occi/templates/os#os_template_"
...@@ -229,7 +207,7 @@ class OcciComputeView(View): ...@@ -229,7 +207,7 @@ class OcciComputeView(View):
except: except:
return OcciResourceCreationError().response return OcciResourceCreationError().response
compute = Compute(vm) compute = Compute(vm)
return occi_response(compute.render_as_json()) return occi_response(compute.as_dict())
# TODO: update compute instance # TODO: update compute instance
return occi_response({"error": "Update of compute instances is " + return occi_response({"error": "Update of compute instances is " +
"not implemented."}, status=501) "not implemented."}, status=501)
...@@ -246,28 +224,23 @@ class OcciComputeView(View): ...@@ -246,28 +224,23 @@ class OcciComputeView(View):
return occi_response({"result": "Compute instance deleted."}) return occi_response({"result": "Compute instance deleted."})
class OcciStorageCollectionView(View): class OcciStorageCollectionView(OcciViewMixin, View):
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
try:
validate_request(request)
except OcciRequestNotValid as e:
return e.response
vms = (Instance.get_objects_with_level("owner", request.user) vms = (Instance.get_objects_with_level("owner", request.user)
.filter(destroyed_at=None)) .filter(destroyed_at=None))
json = {"resources": []} json = {"resources": []}
for vm in vms: for vm in vms:
disks = vm.disks.all() disks = vm.disks.all()
for disk in disks: for disk in disks:
json["resources"].append(Storage(disk).render_as_json()) json["resources"].append(Storage(disk).as_dict())
return occi_response(json) return occi_response(json)
def put(self, request, *args, **kwargs): def put(self, request, *args, **kwargs):
return occi_response({"message": "Not supported."}, status=501) return occi_response({"message": "Not supported."}, status=501)
class OcciStorageView(View): class OcciStorageView(OcciViewMixin, View):
""" View of a storage instance """ """ View of a storage instance """
def get_disk_object(self, user, diskid): def get_disk_object(self, user, diskid):
...@@ -283,17 +256,12 @@ class OcciStorageView(View): ...@@ -283,17 +256,12 @@ class OcciStorageView(View):
return Storage(disk) return Storage(disk)
raise OcciResourceInstanceNotExist() raise OcciResourceInstanceNotExist()
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
try: try:
validate_request(request)
except OcciRequestNotValid as e:
return e.response
try:
disk = self.get_disk_object(request.user, kwargs["id"]) disk = self.get_disk_object(request.user, kwargs["id"])
except OcciResourceInstanceNotExist as e: except OcciResourceInstanceNotExist as e:
return e.response return e.response
return occi_response(disk.render_as_json(), charset="utf-8") return occi_response(disk.as_dict(), charset="utf-8")
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
requestData = json.loads(request.body.decode("utf-8")) requestData = json.loads(request.body.decode("utf-8"))
...@@ -315,24 +283,26 @@ class OcciStorageView(View): ...@@ -315,24 +283,26 @@ class OcciStorageView(View):
requestData.get("attributes", None)) requestData.get("attributes", None))
except OcciActionInvocationError as e: except OcciActionInvocationError as e:
return e.response return e.response
return occi_response(storage.render_as_json(), status=200) return occi_response(storage.as_dict(), status=200)
def put(self, request, *args, **kwargs):
return OcciResourceCreationError(
message="Storage creation is not supported at this uri. " +
"Please use the compute instances' actions!"
).response
class OcciNetworkCollectionView(OcciViewMixin, View):
class OcciNetworkCollectionView(View):
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
try:
validate_request(request)
except OcciRequestNotValid as e:
return e.response
vlans = (Vlan.get_objects_with_level("owner", request.user)) vlans = (Vlan.get_objects_with_level("owner", request.user))
json = {"resources": []} json = {"resources": []}
for vlan in vlans: for vlan in vlans:
json["resources"].append(Network(vlan).render_as_json()) json["resources"].append(Network(vlan).as_dict())
return occi_response(json) return occi_response(json)
class OcciNetworkView(View): class OcciNetworkView(OcciViewMixin, View):
""" View of a compute instance """ """ View of a compute instance """
def get_vlan_object(self, user, vlanid): def get_vlan_object(self, user, vlanid):
...@@ -343,17 +313,12 @@ class OcciNetworkView(View): ...@@ -343,17 +313,12 @@ class OcciNetworkView(View):
raise OcciResourceInstanceNotExist() raise OcciResourceInstanceNotExist()
return Network(vlan) return Network(vlan)
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
try: try:
validate_request(request)
except OcciRequestNotValid as e:
return e.response
try:
network = self.get_vlan_object(request.user, kwargs["id"]) network = self.get_vlan_object(request.user, kwargs["id"])
except OcciResourceInstanceNotExist as e: except OcciResourceInstanceNotExist as e:
return e.response return e.response
return occi_response(network.render_as_json(), charset="utf-8") return occi_response(network.as_dict(), charset="utf-8")
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
requestData = json.loads(request.body.decode("utf-8")) requestData = json.loads(request.body.decode("utf-8"))
...@@ -375,4 +340,135 @@ class OcciNetworkView(View): ...@@ -375,4 +340,135 @@ class OcciNetworkView(View):
requestData.get("attributes", None)) requestData.get("attributes", None))
except OcciActionInvocationError as e: except OcciActionInvocationError as e:
return e.response return e.response
return occi_response(network.render_as_json(), status=200) return occi_response(network.as_dict(), status=200)
class OcciStoragelinkCollectionView(OcciViewMixin, View):
""" View of all storage link instances of the user """
def get(self, request, *args, **kwargs):
vms = (Instance.get_objects_with_level("owner", request.user)
.filter(destroyed_at=None))
links = [StorageLink(Compute(vm), Storage(disk)).as_dict()
for vm in vms for disk in vm.disks.all()]
return occi_response({"links": links})
class OcciStoragelinkView(OcciViewMixin, View):
""" VIew of a storage link instance """
def get(self, request, *args, **kwargs):
try:
vm = get_object_or_404(Instance.get_objects_with_level(
"owner", request.user).filter(destroyed_at=None),
pk=kwargs["computeid"])
except Http404:
return OcciResourceInstanceNotExist().response
try:
disk = vm.disks.get(pk=kwargs["storageid"])
except Disk.DoesNotExist:
return OcciResourceInstanceNotExist().response
return occi_response(
StorageLink(Compute(vm), Storage(disk)).as_dict())
class OcciNetworkInterfaceCollectionView(OcciViewMixin, View):
""" View of network interface instances of a user """
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()]
return occi_response({"links": links})
class OcciNetworkInterfaceView(OcciViewMixin, View):
""" View of a network interface instance """
def get_compute_object(self, user, vmid):
try:
vm = get_object_or_404(Instance.get_objects_with_level(
"owner", user).filter(destroyed_at=None), pk=vmid)
except Http404:
raise OcciResourceInstanceNotExist()
return Compute(vm)
def get_network_object(self, user, vlanid):
try:
vlan = get_object_or_404(Vlan.get_objects_with_level(
"user", user), pk=vlanid)
except Http404:
raise OcciResourceInstanceNotExist()
return Network(vlan)
def get_networkinterface_object(self, user, vmid, vlanid):
compute = self.get_compute_object(user, vmid)
try:
interface = compute.vm.interface_set.get(vlan__pk=vlanid)
except:
raise OcciResourceInstanceNotExist()
return NetworkInterface(compute, Network(interface.vlan))
def get(self, request, *args, **kwargs):
try:
nic = self.get_networkinterface_object(
request.user, kwargs["computeid"], kwargs["networkid"])
except OcciResourceInstanceNotExist as e:
return e.response
return occi_response(nic.as_dict())
def post(self, request, *args, **kwargs):
requestData = json.loads(request.body.decode("utf-8"))
if "action" in requestData:
try:
nif = self.get_networkinterface_object(
request.user, kwargs["computeid"], kwargs["networkid"])
except OcciResourceInstanceNotExist as e:
return e.response
try:
nif.invoke_action(request.user,
requestData.get("action", None),
requestData.get("attributes", None))
except OcciActionInvocationError as e:
return e.response
return occi_response(nif.as_dict(), status=200)
return OcciActionInvocationError().response
def put(self, request, *args, **kwargs):
compute = self.get_compute_object(request.user, kwargs["computeid"])
network = self.get_network_object(request.user, kwargs["networkid"])
try:
compute.vm.add_interface(user=request.user, vlan=network.vlan)
except HumanReadableException as e:
return OcciResourceCreationError(
message=e.get_user_text()).response
except Exception as e:
return OcciResourceCreationError(message=unicode(e)).response
nif = NetworkInterface(compute, network)
return occi_response(nif.as_dict())
def delete(self, request, *args, **kwargs):
compute = self.get_compute_object(request.user, kwargs["computeid"])
network = self.get_network_object(request.user, kwargs["networkid"])
try:
interface = compute.vm.interface_set.get(vlan=network.vlan)
except:
return OcciResourceInstanceNotExist().response
try:
from firewall.models import Host
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)
except HumanReadableException as e:
return OcciResourceDeletionError(
message=e.get_user_text()).response
except Exception:
from firewall.models import Host
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()
return occi_response({"host": hc, "interface": ic})
return occi_response({"status": "ok"})
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