Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gelencsér Szabolcs
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
a9d62221
authored
May 07, 2016
by
Fukász Rómeó Ervin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
os templates, credentials, compute creation, compute delete
parent
760e8dc0
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
378 additions
and
93 deletions
+378
-93
circle/occi/occi_client_example.py
+88
-19
circle/occi/occi_infrastructure.py
+24
-10
circle/occi/occi_instances.py
+70
-9
circle/occi/occi_utils.py
+94
-32
circle/occi/views.py
+102
-23
No files found.
circle/occi/occi_client_example.py
View file @
a9d62221
...
...
@@ -25,7 +25,9 @@ with requests.Session() as session:
print
(
"csrf-token"
)
print
(
"----------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
(
json
.
loads
(
req
.
text
)[
"result"
])
print
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
# Bejelentkezes
...
...
@@ -38,13 +40,9 @@ with requests.Session() as session:
print
(
"login"
)
print
(
"-----"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
if
req
.
status_code
==
200
:
print
(
json
.
loads
(
req
.
text
)[
"result"
])
else
:
print
(
json
.
loads
(
req
.
text
)[
"result"
])
errors
=
json
.
loads
(
req
.
text
)[
"errors"
]
for
error
in
errors
:
print
(
error
)
print
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
# query interface
...
...
@@ -52,7 +50,9 @@ with requests.Session() as session:
print
(
"query-interface"
)
print
(
"---------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
(
req
.
text
)
print
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
# osszes vm collectionkent
...
...
@@ -61,17 +61,21 @@ with requests.Session() as session:
print
(
"compute-collection"
)
print
(
"------------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
(
req
.
text
)
print
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
# 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/"
+
vmid
+
"/"
,
headers
=
headers
,
verify
=
False
)
print
(
"compute-"
+
str
(
vmid
))
print
(
"------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
(
req
.
text
)
print
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
# ha nem active, akkor azza tesszuk
...
...
@@ -82,13 +86,15 @@ with requests.Session() as session:
headers
[
"X-CSRFToken"
]
=
req
.
cookies
[
'csrftoken'
]
except
:
pass
req
=
session
.
post
(
server
+
"occi/compute/"
+
str
(
vmid
)
+
"/"
,
req
=
session
.
post
(
server
+
"occi/compute/"
+
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
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
# restart
...
...
@@ -98,13 +104,15 @@ with requests.Session() as session:
pass
actionatrs
=
{
"method"
:
"cold"
}
actioninv
=
{
"action"
:
action
+
"restart"
,
"attributes"
:
actionatrs
}
req
=
session
.
post
(
server
+
"occi/compute/"
+
str
(
vmid
)
+
"/"
,
req
=
session
.
post
(
server
+
"occi/compute/"
+
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
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
# suspend
...
...
@@ -114,21 +122,82 @@ with requests.Session() as session:
pass
actioninv
[
"action"
]
=
action
+
"suspend"
actioninv
[
"attributes"
][
"method"
]
=
"suspend"
req
=
session
.
post
(
server
+
"occi/compute/"
+
str
(
vmid
)
+
"/"
,
req
=
session
.
post
(
server
+
"occi/compute/"
+
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
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
# nem letezo action
try
:
headers
[
"X-CSRFToken"
]
=
req
.
cookies
[
"csrftoken"
]
except
:
pass
actioninv
[
"action"
]
=
action
+
"noaction"
req
=
session
.
post
(
server
+
"occi/compute/"
+
vmid
+
"/"
,
headers
=
headers
,
verify
=
False
,
data
=
json
.
dumps
(
actioninv
))
print
(
"compute-"
+
str
(
vmid
)
+
"-noaction"
)
print
(
"-------------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
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
=
json
.
dumps
(
putdata
))
print
(
"create_compute"
)
print
(
"--------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
# vm torles
try
:
headers
[
"X-CSRFToken"
]
=
req
.
cookies
[
"csrftoken"
]
except
:
pass
vmid
=
json
.
loads
(
req
.
text
)[
"id"
]
req
=
session
.
delete
(
server
+
"occi/compute/"
+
vmid
+
"/"
,
headers
=
headers
,
verify
=
False
,
data
=
json
.
dumps
(
putdata
))
print
(
"delete_compute"
)
print
(
"--------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
# Kijelentkezes
req
=
session
.
get
(
server
+
"occi/logout/"
,
headers
=
headers
,
verify
=
False
)
print
(
"logout"
)
print
(
"------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
(
json
.
loads
(
req
.
text
)[
"result"
])
print
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
except
ConnectionError
as
e
:
print
(
e
)
circle/occi/occi_infrastructure.py
View file @
a9d62221
...
...
@@ -38,24 +38,43 @@ class Compute(Resource):
def
__init__
(
self
,
vm
):
""" Creates a Compute instance of a VM instance object """
super
(
Compute
,
self
)
.
__init__
(
"http://schemas.ogf.org/occi/infrastructure#compute"
,
vm
.
pk
)
"http://schemas.ogf.org/occi/infrastructure#compute"
,
str
(
vm
.
pk
))
self
.
vm
=
vm
self
.
attributes
=
self
.
set_attributes
()
self
.
actions
=
action_list_for_resource
(
COMPUTE_ACTIONS
)
self
.
mixins
=
[
"http://circlecloud.org/occi/infrastructure#credentials"
,
]
if
vm
.
template
:
self
.
mixins
.
append
(
"http://circlecloud.org/occi/templates/os#os_template_"
+
str
(
vm
.
template
.
pk
))
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.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
))
attributes
[
"occi.compute.state.message"
]
=
(
COMPUTE_STATE_MESSAGES
.
get
(
self
.
vm
.
state
))
attributes
[
"org.circlecloud.occi.credentials.protocol"
]
=
(
self
.
vm
.
access_method
)
attributes
[
"org.circlecloud.occi.credentials.host"
]
=
(
self
.
vm
.
get_connect_host
())
attributes
[
"org.circlecloud.occi.credentials.port"
]
=
(
self
.
vm
.
get_connect_port
())
attributes
[
"org.circlecloud.occi.credentials.username"
]
=
"cloud"
attributes
[
"org.circlecloud.occi.credentials.password"
]
=
(
self
.
vm
.
pw
)
attributes
[
"org.circlecloud.occi.credentials.command"
]
=
(
self
.
vm
.
get_connect_command
())
return
attributes
def
invoke_action
(
self
,
user
,
action
,
attributes
):
...
...
@@ -140,8 +159,3 @@ class Compute(Resource):
# TODO: save template
raise
OcciActionInvocationError
(
message
=
"Save action not implemented"
)
class
Network
(
Resource
):
# TODO: network
pass
circle/occi/occi_instances.py
View file @
a9d62221
""" Required instances of the OCCI classes """
from
vm.models.instance
import
InstanceTemplate
from
occi_core
import
Kind
,
Mixin
,
Attribute
,
Action
...
...
@@ -103,7 +104,6 @@ IPNETWORK_ATTRIBUTES = [
IPNETWORK_MIXIN
=
Mixin
(
"http://schemas.ogf.org/occi/infrastructure/network#"
,
"ipnetwork"
,
title
=
"IP Network Mixin"
,
location
=
"/network/ipnetwork"
,
applies
=
(
"http://shemas.ogf.org/occi/infrastructure"
+
"#network"
))
...
...
@@ -166,8 +166,6 @@ IPNETWORKINTERFACE_MIXIN = Mixin("http://schemas.ogf.org/occi/" +
"infrastructure/networkinterface#"
,
"ipnetworkinterface"
,
title
=
"IP Network Interface Mixin"
,
location
=
"/networkinterface"
+
"/ipnetworkinterface/"
,
applies
=
"http://schemas.ogf.org/occi/"
+
"infrastructure#networkinterface"
)
...
...
@@ -191,18 +189,81 @@ STORAGELINK_KIND = Kind("http://schemas.ogf.org/occi/infrastructure#",
parent
=
"http://schemas.ogf.org/occi/core#link"
,
atrributes
=
STORAGELINK_ATTRIBUTES
)
# TODO: OS Templates and Credentials
ACTION_ARRAYS
=
[
COMPUTE_ACTIONS
,
NETWORK_ACTIONS
,
STORAGE_ACTIONS
]
CREDENTIALS_ATTRIBUTES
=
[
Attribute
(
"org.circlecloud.occi.credentials.protocol"
,
"String"
,
False
,
False
,
description
=
"The protocol to be used to access the "
"compute instance."
),
Attribute
(
"org.circlecloud.occi.credentials.host"
,
"String"
,
False
,
False
,
description
=
"The host to be used to access the compute "
+
"instance."
),
Attribute
(
"org.circlecloud.occi.credentials.port"
,
"Integer"
,
False
,
False
,
description
=
"The port to be used to access the compute "
+
"instance."
),
Attribute
(
"org.circlecloud.occi.credentials.username"
,
"String"
,
False
,
False
,
description
=
"The username to be used to access the "
+
"compute instance."
),
Attribute
(
"org.circlecloud.occi.credentials.password"
,
"String"
,
False
,
False
,
description
=
"The password to be used to acces the "
+
"compute instance."
),
Attribute
(
"org.circlecloud.occi.credentials.command"
,
"String"
,
False
,
False
,
description
=
"The full command that may be used to "
+
"connect to the compute instance."
),
]
CREDENTIALS_MIXIN
=
Mixin
(
"http://circlecloud.org/occi/infrastructure#"
,
"credentials"
,
title
=
"Credentials Mixin"
,
attributes
=
CREDENTIALS_ATTRIBUTES
,
applies
=
"http://schemas.ogf.org/occi/infrastructure"
+
"#compute"
)
OS_TPL_MIXIN
=
Mixin
(
"http://schemas.ogf.org/occi/infrastructure#"
,
"os_tpl"
,
title
=
"OS Template"
)
ACTION_ARRAYS
=
[
COMPUTE_ACTIONS
,
# NETWORK_ACTIONS,
# STORAGE_ACTIONS,
]
def
ALL_KINDS
():
return
[
ENTITY_KIND
,
RESOURCE_KIND
,
LINK_KIND
,
COMPUTE_KIND
,
NETWORK_KIND
,
STORAGE_KIND
,
NETWORKINTERFACE_KIND
]
return
[
ENTITY_KIND
,
RESOURCE_KIND
,
LINK_KIND
,
COMPUTE_KIND
,
# NETWORK_KIND,
# STORAGE_KIND,
# NETWORKINTERFACE_KIND
]
def
os_tpl_mixins
(
user
):
""" Returns an array of all the templates the user has access to. """
templates
=
InstanceTemplate
.
get_objects_with_level
(
"user"
,
user
)
result
=
[]
for
template
in
templates
:
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
)))
return
result
def
ALL_MIXINS
():
return
[
IPNETWORK_MIXIN
,
IPNETWORKINTERFACE_MIXIN
]
def
ALL_MIXINS
(
user
):
mixins
=
[
# IPNETWORK_MIXIN,
# IPNETWORKINTERFACE_MIXIN,
CREDENTIALS_MIXIN
,
OS_TPL_MIXIN
,
]
template_mixins
=
os_tpl_mixins
(
user
)
for
template
in
template_mixins
:
mixins
.
append
(
template
)
return
mixins
def
ALL_ACTIONS
():
...
...
circle/occi/occi_utils.py
View file @
a9d62221
"""" Utilities for the OCCI implementation of CIRCLE """
from
django.http
import
JsonResponse
,
HttpResponse
from
django.http
import
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
OcciException
(
Exception
):
""" The superclass for OCCI exceptions. It creates a response to be
returned when an error occures. """
def
__init__
(
self
,
*
args
,
**
kwargs
):
message
=
kwargs
.
get
(
"message"
,
"An error occured."
)
status
=
kwargs
.
get
(
"status"
,
400
)
super
(
OcciException
,
self
)
.
__init__
(
message
)
self
.
response
=
occi_response
({
"error"
:
message
},
status
=
status
)
class
OcciActionInvocationError
(
Exception
):
class
OcciResourceInstanceNotExist
(
OcciException
):
""" An exception to be raised when a resource instance which has been
asked for does not exist. """
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"
)
if
"message"
not
in
kwargs
:
kwargs
[
"message"
]
=
"The resource instance does not exist."
super
(
OcciResourceInstanceNotExist
,
self
)
.
__init__
(
self
,
**
kwargs
)
class
OcciActionInvocationError
(
OcciException
):
""" An exception to be raised when an action could not be invoked on
an entity instance for some reason """
def
__init__
(
self
,
*
args
,
**
kwargs
):
if
"message"
not
in
kwargs
:
kwargs
[
"message"
]
=
"Could not invoke action."
super
(
OcciActionInvocationError
,
self
)
.
__init__
(
self
,
**
kwargs
)
class
OcciResourceCreationError
(
OcciException
):
""" An exception to be raised when a resource instance could not be
created for a reason. """
def
__init__
(
self
,
*
args
,
**
kwargs
):
if
"message"
not
in
kwargs
:
kwargs
[
"message"
]
=
"Could not create resource instance."
super
(
OcciResourceCreationError
,
self
)
.
__init__
(
self
,
**
kwargs
)
class
OcciResourceDeletionError
(
OcciException
):
""" An exception to be raised when a resource instance could not be
deleted for some reason. """
def
__init__
(
self
,
*
args
,
**
kwargs
):
if
"message"
not
in
kwargs
:
kwargs
[
"message"
]
=
"Could not delete resource instance."
super
(
OcciResourceDeletionError
,
self
)
.
__init__
(
self
,
**
kwargs
)
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"
:
class
OcciRequestNotValid
(
OcciException
):
""" An exception to be raised when the request sent by the client is
not valid for a reason. (e.g, wrong content type, etc.) """
def
__init__
(
self
,
*
args
,
**
kwargs
):
if
"message"
not
in
kwargs
:
kwargs
[
"message"
]
=
"The request is not valid."
super
(
OcciRequestNotValid
,
self
)
.
__init__
(
self
,
**
kwargs
)
def
occi_response
(
data
,
*
args
,
**
kwargs
):
""" This function returns a response with its headers set, like occi
server. The content_type of the response is application/json
by default. """
status
=
kwargs
.
get
(
"status"
,
200
)
# TODO: support for renderings other than json (e.g., text/plain)
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"
response
=
HttpResponse
(
data
,
charset
=
"utf-8"
,
status
=
status
,
content_type
=
"application/json; charset=utf-8"
)
# TODO: use Server header instead of OCCI-Server
response
[
"OCCI-Server"
]
=
"OCCI/1.2"
response
[
"Accept"
]
=
"application/json"
return
response
def
validate_request
(
request
,
authentication_required
=
True
,
has_data
=
False
,
**
kwargs
):
""" This function checks if the request's content type is
application/json and if the data is a valid json object. If the
authentication_required parameter is True, it will also check if
the user is authenticated. """
# checking if the user is authenticated
if
authentication_required
:
if
not
request
.
user
.
is_authenticated
():
raise
OcciRequestNotValid
(
"Authentication required."
,
status
=
403
)
if
has_data
:
# checking content type
if
request
.
META
.
get
(
"CONTENT_TYPE"
)
!=
"application/json"
:
raise
OcciRequestNotValid
(
"Only application/json content type is "
+
"allowed."
)
# checking if the data is a valid json
try
:
data
=
json
.
loads
(
request
.
body
.
decode
(
"utf-8"
))
except
KeyError
:
raise
OcciRequestNotValid
(
"The json provided in the request is "
+
"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
):
...
...
@@ -43,15 +114,6 @@ def set_optional_attributes(self, optional_attributes, kwargs):
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
=
[]
...
...
circle/occi/views.py
View file @
a9d62221
...
...
@@ -5,15 +5,20 @@
import
json
from
django.views.generic
import
View
from
django.contrib.auth
import
logout
from
django.http
import
Http
Response
,
JsonResponse
,
Http
404
from
django.http
import
Http404
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
from
vm.models.instance
import
Instance
,
InstanceTemplate
from
forms
import
OcciAuthForm
from
occi_infrastructure
import
Compute
from
occi_utils
import
(
OcciResourceInstanceNotExist
,
OcciActionInvocationError
)
OcciActionInvocationError
,
OcciRequestNotValid
,
OcciResourceCreationError
,
OcciResourceDeletionError
,
occi_response
,
validate_request
)
from
occi_instances
import
ALL_KINDS
,
ALL_MIXINS
,
ALL_ACTIONS
...
...
@@ -27,7 +32,7 @@ class OcciLoginView(View):
""" Returns a response with a cookie to be used for requests other
than get. """
result
=
{
"result"
:
"OK"
}
return
JsonResponse
(
result
,
charset
=
"utf-8"
)
return
occi_response
(
result
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
""" Returns a response with a cookie to be used for the OCCI api
...
...
@@ -36,12 +41,12 @@ class OcciLoginView(View):
form
=
OcciAuthForm
(
data
=
data
,
request
=
request
)
if
form
.
is_valid
():
result
=
{
"result"
:
"OK"
}
return
JsonResponse
(
result
,
charset
=
"utf-8"
)
return
occi_response
(
result
)
else
:
errors
=
dict
([(
k
,
[
unicode
(
e
)
for
e
in
v
])
for
k
,
v
in
form
.
errors
.
items
()])
result
=
{
"result"
:
"ERROR"
,
"errors"
:
errors
[
"__all__"
]}
return
JsonResponse
(
result
,
status
=
400
,
charset
=
"utf-8"
)
return
occi_response
(
result
,
status
=
400
)
class
OcciLogoutView
(
View
):
...
...
@@ -49,42 +54,70 @@ class OcciLogoutView(View):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
logout
(
request
)
result
=
{
"result"
:
"OK"
}
return
JsonResponse
(
result
,
charset
=
"utf-8"
)
return
occi_response
(
result
)
class
OcciQueryInterfaceView
(
View
):
""" The view of the OCCI query interface """
@method_decorator
(
ensure_csrf_cookie
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
try
:
validate_request
(
request
)
except
OcciRequestNotValid
as
e
:
return
e
.
response
result
=
{
"kinds"
:
[],
"mixins"
:
[],
"actions"
:
[]}
for
kind
in
ALL_KINDS
():
result
[
"kinds"
]
.
append
(
kind
.
render_as_json
())
for
mixin
in
ALL_MIXINS
():
for
mixin
in
ALL_MIXINS
(
request
.
user
):
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"
)
return
occi_response
(
result
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
return
occi_response
({
"error"
:
"User defined mixins are not "
+
"supported."
},
status
=
405
)
def
delete
(
self
,
request
,
*
args
,
**
kwargs
):
return
occi_response
({
"error"
:
"User defined mixins are not "
+
"supported."
},
status
=
405
)
def
put
(
self
,
request
,
*
args
,
**
kwargs
):
return
occi_response
({
"error"
:
"Put method is not defined on the "
+
"query interface."
},
status
=
400
)
class
OcciComputeCollectionView
(
View
):
@method_decorator
(
ensure_csrf_cookie
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
request
.
user
.
is_authenticated
():
return
HttpResponse
(
status
=
403
)
try
:
validate_request
(
request
)
except
OcciRequestNotValid
as
e
:
return
e
.
response
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"
)
return
occi_response
(
json
)
def
put
(
self
,
request
,
*
args
,
**
kwargs
):
# TODO: vm creation
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
):
""" View of a compute instance """
def
get_vm_object
(
self
,
request
,
vmid
):
def
get_vm_object
(
self
,
user
,
vmid
):
try
:
vm
=
get_object_or_404
(
Instance
.
get_objects_with_level
(
"user"
,
request
.
user
),
pk
=
vmid
)
user
)
.
filter
(
destroyed_at
=
None
),
pk
=
vmid
)
except
Http404
:
raise
OcciResourceInstanceNotExist
()
return
Compute
(
vm
)
...
...
@@ -92,20 +125,22 @@ class OcciComputeView(View):
@method_decorator
(
ensure_csrf_cookie
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
request
.
user
.
is_authenticated
():
return
HttpResponse
(
status
=
403
)
return
occi_response
({
"error"
:
"Authentication required."
},
status
=
403
)
try
:
compute
=
self
.
get_vm_object
(
request
,
kwargs
[
"id"
])
compute
=
self
.
get_vm_object
(
request
.
user
,
kwargs
[
"id"
])
except
OcciResourceInstanceNotExist
as
e
:
return
e
.
json_
response
return
JsonR
esponse
(
compute
.
render_as_json
(),
charset
=
"utf-8"
)
return
e
.
response
return
occi_r
esponse
(
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
)
return
occi_response
({
"error"
:
"Action invocation rendering "
+
"is not supplied."
},
status
=
400
)
try
:
compute
=
self
.
get_vm_object
(
request
,
kwargs
[
"id"
])
compute
=
self
.
get_vm_object
(
request
.
user
,
kwargs
[
"id"
])
except
OcciResourceInstanceNotExist
as
e
:
return
e
.
response
try
:
...
...
@@ -114,5 +149,49 @@ class OcciComputeView(View):
requestData
.
get
(
"attributes"
,
None
))
except
OcciActionInvocationError
as
e
:
return
e
.
response
# TODO: proper return value
return
JsonResponse
(
compute
.
render_as_json
(),
status
=
200
)
return
occi_response
(
compute
.
render_as_json
(),
status
=
200
)
def
put
(
self
,
request
,
*
args
,
**
kwargs
):
# checking if the requested resource exists
try
:
self
.
get_vm_object
(
request
.
user
,
kwargs
[
"id"
])
except
OcciResourceInstanceNotExist
:
# there has to be a mixins array in the provided rendering
data_keys
=
[
"mixins"
]
try
:
requestData
=
validate_request
(
request
,
True
,
True
,
data_keys
=
data_keys
)
except
OcciRequestNotValid
as
e
:
return
e
.
response
ostpl
=
"http://circlecloud.org/occi/templates/os#os_template_"
for
mixin
in
requestData
[
"mixins"
]:
if
ostpl
in
mixin
:
tpl_id
=
int
(
mixin
.
replace
(
ostpl
,
""
))
try
:
template
=
get_object_or_404
(
InstanceTemplate
.
get_objects_with_level
(
"user"
,
request
.
user
),
pk
=
tpl_id
)
except
Http404
:
return
occi_response
({
"error"
:
"Template does not"
+
"exist."
})
try
:
vm
=
Instance
.
create_from_template
(
template
,
request
.
user
)
except
:
return
OcciResourceCreationError
()
.
response
compute
=
Compute
(
vm
)
return
occi_response
(
compute
.
render_as_json
())
# TODO: update compute instance
return
occi_response
({
"error"
:
"Update of compute instances is "
+
"not implemented."
},
status
=
501
)
def
delete
(
self
,
request
,
*
args
,
**
kwargs
):
try
:
compute
=
self
.
get_vm_object
(
request
.
user
,
kwargs
[
"id"
])
except
OcciResourceInstanceNotExist
as
e
:
return
e
.
response
try
:
compute
.
vm
.
destroy
(
user
=
request
.
user
)
except
:
return
OcciResourceDeletionError
()
.
response
return
occi_response
({
"result"
:
"Compute instance deleted."
})
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment