Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gyuricska Milán
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
a9d62221
authored
8 years ago
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
)
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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
():
...
...
This diff is collapsed.
Click to expand it.
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
=
[]
...
...
This diff is collapsed.
Click to expand it.
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."
})
This diff is collapsed.
Click to expand it.
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