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
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
381 additions
and
96 deletions
+381
-96
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
+97
-35
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:
...
@@ -25,7 +25,9 @@ with requests.Session() as session:
print
(
"csrf-token"
)
print
(
"csrf-token"
)
print
(
"----------"
)
print
(
"----------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
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
print
# Bejelentkezes
# Bejelentkezes
...
@@ -38,13 +40,9 @@ with requests.Session() as session:
...
@@ -38,13 +40,9 @@ with requests.Session() as session:
print
(
"login"
)
print
(
"login"
)
print
(
"-----"
)
print
(
"-----"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
(
"status_code: "
+
str
(
req
.
status_code
))
if
req
.
status_code
==
200
:
print
print
(
json
.
loads
(
req
.
text
)[
"result"
])
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
else
:
indent
=
4
,
separators
=
(
","
,
": "
)))
print
(
json
.
loads
(
req
.
text
)[
"result"
])
errors
=
json
.
loads
(
req
.
text
)[
"errors"
]
for
error
in
errors
:
print
(
error
)
print
print
# query interface
# query interface
...
@@ -52,7 +50,9 @@ with requests.Session() as session:
...
@@ -52,7 +50,9 @@ with requests.Session() as session:
print
(
"query-interface"
)
print
(
"query-interface"
)
print
(
"---------------"
)
print
(
"---------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
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
print
# osszes vm collectionkent
# osszes vm collectionkent
...
@@ -61,17 +61,21 @@ with requests.Session() as session:
...
@@ -61,17 +61,21 @@ with requests.Session() as session:
print
(
"compute-collection"
)
print
(
"compute-collection"
)
print
(
"------------------"
)
print
(
"------------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
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
print
# az elso vm a listabol
# az elso vm a listabol
vmid
=
json
.
loads
(
req
.
text
)[
"resources"
][
0
][
"id"
]
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
)
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
(
req
.
text
)
print
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
print
# ha nem active, akkor azza tesszuk
# ha nem active, akkor azza tesszuk
...
@@ -82,13 +86,15 @@ with requests.Session() as session:
...
@@ -82,13 +86,15 @@ with requests.Session() as session:
headers
[
"X-CSRFToken"
]
=
req
.
cookies
[
'csrftoken'
]
headers
[
"X-CSRFToken"
]
=
req
.
cookies
[
'csrftoken'
]
except
:
except
:
pass
pass
req
=
session
.
post
(
server
+
"occi/compute/"
+
str
(
vmid
)
+
"/"
,
req
=
session
.
post
(
server
+
"occi/compute/"
+
vmid
+
"/"
,
headers
=
headers
,
verify
=
False
,
headers
=
headers
,
verify
=
False
,
data
=
json
.
dumps
({
"action"
:
action
+
"start"
}))
data
=
json
.
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
(
req
.
text
)
print
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
print
# restart
# restart
...
@@ -98,13 +104,15 @@ with requests.Session() as session:
...
@@ -98,13 +104,15 @@ with requests.Session() as session:
pass
pass
actionatrs
=
{
"method"
:
"cold"
}
actionatrs
=
{
"method"
:
"cold"
}
actioninv
=
{
"action"
:
action
+
"restart"
,
"attributes"
:
actionatrs
}
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
,
headers
=
headers
,
verify
=
False
,
data
=
json
.
dumps
(
actioninv
))
data
=
json
.
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
(
req
.
text
)
print
print
(
json
.
dumps
(
json
.
loads
(
req
.
text
),
sort_keys
=
True
,
indent
=
4
,
separators
=
(
","
,
": "
)))
print
print
# suspend
# suspend
...
@@ -114,21 +122,82 @@ with requests.Session() as session:
...
@@ -114,21 +122,82 @@ with requests.Session() as session:
pass
pass
actioninv
[
"action"
]
=
action
+
"suspend"
actioninv
[
"action"
]
=
action
+
"suspend"
actioninv
[
"attributes"
][
"method"
]
=
"suspend"
actioninv
[
"attributes"
][
"method"
]
=
"suspend"
req
=
session
.
post
(
server
+
"occi/compute/"
+
str
(
vmid
)
+
"/"
,
req
=
session
.
post
(
server
+
"occi/compute/"
+
vmid
+
"/"
,
headers
=
headers
,
verify
=
False
,
headers
=
headers
,
verify
=
False
,
data
=
json
.
dumps
(
actioninv
))
data
=
json
.
dumps
(
actioninv
))
print
(
"compute-"
+
str
(
vmid
)
+
"-suspend"
)
print
(
"compute-"
+
str
(
vmid
)
+
"-suspend"
)
print
(
"-----------------"
)
print
(
"-----------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
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
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
# Kijelentkezes
req
=
session
.
get
(
server
+
"occi/logout/"
,
headers
=
headers
,
req
=
session
.
get
(
server
+
"occi/logout/"
,
headers
=
headers
,
verify
=
False
)
verify
=
False
)
print
(
"logout"
)
print
(
"logout"
)
print
(
"------"
)
print
(
"------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
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
:
except
ConnectionError
as
e
:
print
(
e
)
print
(
e
)
circle/occi/occi_infrastructure.py
View file @
a9d62221
...
@@ -38,24 +38,43 @@ class Compute(Resource):
...
@@ -38,24 +38,43 @@ class Compute(Resource):
def
__init__
(
self
,
vm
):
def
__init__
(
self
,
vm
):
""" Creates a Compute instance of a VM instance object """
""" Creates a Compute instance of a VM instance object """
super
(
Compute
,
self
)
.
__init__
(
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
.
vm
=
vm
self
.
attributes
=
self
.
set_attributes
()
self
.
attributes
=
self
.
set_attributes
()
self
.
actions
=
action_list_for_resource
(
COMPUTE_ACTIONS
)
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
):
def
set_attributes
(
self
):
""" Sets the attributes of the Compute object based on the VM
""" Sets the attributes of the Compute object based on the VM
instance. """
instance. """
attributes
=
{}
attributes
=
{}
attributes
[
"occi.compute.architecture"
]
=
(
COMPUTE_ARCHITECTURES
attributes
[
"occi.compute.architecture"
]
=
(
.
get
(
self
.
vm
.
arch
))
COMPUTE_ARCHITECTURES
.
get
(
self
.
vm
.
arch
))
attributes
[
"occi.compute.cores"
]
=
self
.
vm
.
num_cores
attributes
[
"occi.compute.cores"
]
=
self
.
vm
.
num_cores
attributes
[
"occi.compute.hostname"
]
=
self
.
vm
.
short_hostname
attributes
[
"occi.compute.hostname"
]
=
self
.
vm
.
short_hostname
attributes
[
"occi.compute.share"
]
=
self
.
vm
.
priority
attributes
[
"occi.compute.share"
]
=
self
.
vm
.
priority
attributes
[
"occi.compute.memory"
]
=
self
.
vm
.
ram_size
/
1024.0
attributes
[
"occi.compute.memory"
]
=
self
.
vm
.
ram_size
/
1024.0
attributes
[
"occi.compute.state"
]
=
COMPUTE_STATES
.
get
(
self
.
vm
.
state
)
attributes
[
"occi.compute.state"
]
=
COMPUTE_STATES
.
get
(
self
.
vm
.
state
)
attributes
[
"occi.compute.state.message"
]
=
(
COMPUTE_STATE_MESSAGES
attributes
[
"occi.compute.state.message"
]
=
(
.
get
(
self
.
vm
.
state
))
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
return
attributes
def
invoke_action
(
self
,
user
,
action
,
attributes
):
def
invoke_action
(
self
,
user
,
action
,
attributes
):
...
@@ -140,8 +159,3 @@ class Compute(Resource):
...
@@ -140,8 +159,3 @@ class Compute(Resource):
# TODO: save template
# TODO: save template
raise
OcciActionInvocationError
(
raise
OcciActionInvocationError
(
message
=
"Save action not implemented"
)
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 """
""" Required instances of the OCCI classes """
from
vm.models.instance
import
InstanceTemplate
from
occi_core
import
Kind
,
Mixin
,
Attribute
,
Action
from
occi_core
import
Kind
,
Mixin
,
Attribute
,
Action
...
@@ -103,7 +104,6 @@ IPNETWORK_ATTRIBUTES = [
...
@@ -103,7 +104,6 @@ IPNETWORK_ATTRIBUTES = [
IPNETWORK_MIXIN
=
Mixin
(
"http://schemas.ogf.org/occi/infrastructure/network#"
,
IPNETWORK_MIXIN
=
Mixin
(
"http://schemas.ogf.org/occi/infrastructure/network#"
,
"ipnetwork"
,
title
=
"IP Network Mixin"
,
"ipnetwork"
,
title
=
"IP Network Mixin"
,
location
=
"/network/ipnetwork"
,
applies
=
(
"http://shemas.ogf.org/occi/infrastructure"
+
applies
=
(
"http://shemas.ogf.org/occi/infrastructure"
+
"#network"
))
"#network"
))
...
@@ -166,8 +166,6 @@ IPNETWORKINTERFACE_MIXIN = Mixin("http://schemas.ogf.org/occi/" +
...
@@ -166,8 +166,6 @@ IPNETWORKINTERFACE_MIXIN = Mixin("http://schemas.ogf.org/occi/" +
"infrastructure/networkinterface#"
,
"infrastructure/networkinterface#"
,
"ipnetworkinterface"
,
"ipnetworkinterface"
,
title
=
"IP Network Interface Mixin"
,
title
=
"IP Network Interface Mixin"
,
location
=
"/networkinterface"
+
"/ipnetworkinterface/"
,
applies
=
"http://schemas.ogf.org/occi/"
+
applies
=
"http://schemas.ogf.org/occi/"
+
"infrastructure#networkinterface"
)
"infrastructure#networkinterface"
)
...
@@ -191,18 +189,81 @@ STORAGELINK_KIND = Kind("http://schemas.ogf.org/occi/infrastructure#",
...
@@ -191,18 +189,81 @@ STORAGELINK_KIND = Kind("http://schemas.ogf.org/occi/infrastructure#",
parent
=
"http://schemas.ogf.org/occi/core#link"
,
parent
=
"http://schemas.ogf.org/occi/core#link"
,
atrributes
=
STORAGELINK_ATTRIBUTES
)
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
():
def
ALL_KINDS
():
return
[
ENTITY_KIND
,
RESOURCE_KIND
,
LINK_KIND
,
COMPUTE_KIND
,
NETWORK_KIND
,
return
[
STORAGE_KIND
,
NETWORKINTERFACE_KIND
]
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
():
def
ALL_MIXINS
(
user
):
return
[
IPNETWORK_MIXIN
,
IPNETWORKINTERFACE_MIXIN
]
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
():
def
ALL_ACTIONS
():
...
...
circle/occi/occi_utils.py
View file @
a9d62221
"""" Utilities for the OCCI implementation of CIRCLE """
"""" Utilities for the OCCI implementation of CIRCLE """
from
django.http
import
JsonResponse
,
HttpResponse
from
django.http
import
HttpResponse
import
json
import
json
class
OcciResourceInstanceNotExist
(
Exception
):
class
OcciException
(
Exception
):
def
__init__
(
self
):
""" The superclass for OCCI exceptions. It creates a response to be
message
=
"The resource instance does not exist."
returned when an error occures. """
super
(
OcciResourceInstanceNotExist
,
self
)
.
__init__
(
message
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
response
=
JsonResponse
({
"error"
:
message
},
status
=
404
,
message
=
kwargs
.
get
(
"message"
,
"An error occured."
)
charset
=
"utf-8"
)
status
=
kwargs
.
get
(
"status"
,
400
)
super
(
OcciException
,
self
)
.
__init__
(
message
)
self
.
response
=
occi_response
({
"error"
:
message
},
status
=
status
)
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
):
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
OcciActionInvocationError
(
Exception
):
class
OcciResourceDeletionError
(
OcciException
):
""" An exception to be raised when a resource instance could not be
deleted for some reason. """
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
message
=
kwargs
.
get
(
"message"
,
"Could not invoke action."
)
if
"message"
not
in
kwargs
:
super
(
OcciActionInvocationError
,
self
)
.
__init__
(
message
)
kwargs
[
"message"
]
=
"Could not delete resource instance."
self
.
response
=
JsonResponse
({
"error"
:
message
},
status
=
400
,
super
(
OcciResourceDeletionError
,
self
)
.
__init__
(
self
,
**
kwargs
)
charset
=
"utf-8"
)
class
OcciRequestNotValid
(
OcciException
):
class
OcciResponse
(
HttpResponse
):
""" An exception to be raised when the request sent by the client is
""" A response class with its occi headers set """
not valid for a reason. (e.g, wrong content type, etc.) """
# TODO: setting occi specific headers
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
init
(
self
,
data
,
response_type
,
*
args
,
**
kwargs
):
if
"message"
not
in
kwargs
:
if
response_type
==
"json"
:
kwargs
[
"message"
]
=
"The request is not valid."
data
=
json
.
dumps
(
data
)
super
(
OcciRequestNotValid
,
self
)
.
__init__
(
self
,
**
kwargs
)
super
(
OcciResponse
,
self
)
.
__init__
(
data
,
status
=
418
)
if
response_type
==
"json"
:
self
[
"Content-Type"
]
=
"application/json"
def
occi_response
(
data
,
*
args
,
**
kwargs
):
else
:
""" This function returns a response with its headers set, like occi
self
[
"Content-Type"
]
=
"text/plain"
server. The content_type of the response is application/json
self
[
"Server"
]
=
"OCCI/1.2"
by default. """
status
=
kwargs
.
get
(
"status"
,
200
)
# TODO: support for renderings other than json (e.g., text/plain)
data
=
json
.
dumps
(
data
)
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
):
def
set_optional_attributes
(
self
,
optional_attributes
,
kwargs
):
...
@@ -43,15 +114,6 @@ def set_optional_attributes(self, optional_attributes, kwargs):
...
@@ -43,15 +114,6 @@ def set_optional_attributes(self, optional_attributes, kwargs):
setattr
(
self
,
k
,
v
)
setattr
(
self
,
k
,
v
)
def
serialize_attributes
(
attributes
):
""" Creates a list of attributes, that are serializable to json from
a list of Attribute class objects. """
atrs
=
[]
for
attribute
in
attributes
:
atrs
.
append
(
attribute
.
render_as_json
())
return
atrs
def
action_list_for_resource
(
actions
):
def
action_list_for_resource
(
actions
):
""" Creates a list of actions for Resource object rendering """
""" Creates a list of actions for Resource object rendering """
acts
=
[]
acts
=
[]
...
...
circle/occi/views.py
View file @
a9d62221
...
@@ -5,15 +5,20 @@
...
@@ -5,15 +5,20 @@
import
json
import
json
from
django.views.generic
import
View
from
django.views.generic
import
View
from
django.contrib.auth
import
logout
from
django.contrib.auth
import
logout
from
django.http
import
Http
Response
,
JsonResponse
,
Http
404
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.views.decorators.csrf
import
ensure_csrf_cookie
from
django.utils.decorators
import
method_decorator
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
forms
import
OcciAuthForm
from
occi_infrastructure
import
Compute
from
occi_infrastructure
import
Compute
from
occi_utils
import
(
OcciResourceInstanceNotExist
,
from
occi_utils
import
(
OcciResourceInstanceNotExist
,
OcciActionInvocationError
)
OcciActionInvocationError
,
OcciRequestNotValid
,
OcciResourceCreationError
,
OcciResourceDeletionError
,
occi_response
,
validate_request
)
from
occi_instances
import
ALL_KINDS
,
ALL_MIXINS
,
ALL_ACTIONS
from
occi_instances
import
ALL_KINDS
,
ALL_MIXINS
,
ALL_ACTIONS
...
@@ -27,7 +32,7 @@ class OcciLoginView(View):
...
@@ -27,7 +32,7 @@ class OcciLoginView(View):
""" Returns a response with a cookie to be used for requests other
""" Returns a response with a cookie to be used for requests other
than get. """
than get. """
result
=
{
"result"
:
"OK"
}
result
=
{
"result"
:
"OK"
}
return
JsonResponse
(
result
,
charset
=
"utf-8"
)
return
occi_response
(
result
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
""" 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
...
@@ -36,12 +41,12 @@ class OcciLoginView(View):
...
@@ -36,12 +41,12 @@ class OcciLoginView(View):
form
=
OcciAuthForm
(
data
=
data
,
request
=
request
)
form
=
OcciAuthForm
(
data
=
data
,
request
=
request
)
if
form
.
is_valid
():
if
form
.
is_valid
():
result
=
{
"result"
:
"OK"
}
result
=
{
"result"
:
"OK"
}
return
JsonResponse
(
result
,
charset
=
"utf-8"
)
return
occi_response
(
result
)
else
:
else
:
errors
=
dict
([(
k
,
[
unicode
(
e
)
for
e
in
v
])
errors
=
dict
([(
k
,
[
unicode
(
e
)
for
e
in
v
])
for
k
,
v
in
form
.
errors
.
items
()])
for
k
,
v
in
form
.
errors
.
items
()])
result
=
{
"result"
:
"ERROR"
,
"errors"
:
errors
[
"__all__"
]}
result
=
{
"result"
:
"ERROR"
,
"errors"
:
errors
[
"__all__"
]}
return
JsonResponse
(
result
,
status
=
400
,
charset
=
"utf-8"
)
return
occi_response
(
result
,
status
=
400
)
class
OcciLogoutView
(
View
):
class
OcciLogoutView
(
View
):
...
@@ -49,42 +54,70 @@ class OcciLogoutView(View):
...
@@ -49,42 +54,70 @@ class OcciLogoutView(View):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
logout
(
request
)
logout
(
request
)
result
=
{
"result"
:
"OK"
}
result
=
{
"result"
:
"OK"
}
return
JsonResponse
(
result
,
charset
=
"utf-8"
)
return
occi_response
(
result
)
class
OcciQueryInterfaceView
(
View
):
class
OcciQueryInterfaceView
(
View
):
""" The view of the OCCI query interface """
""" The view of the OCCI query interface """
@method_decorator
(
ensure_csrf_cookie
)
@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
.
render_as_json
())
for
mixin
in
ALL_MIXINS
():
for
mixin
in
ALL_MIXINS
(
request
.
user
):
result
[
"mixins"
]
.
append
(
mixin
.
render_as_json
())
result
[
"mixins"
]
.
append
(
mixin
.
render_as_json
())
for
action
in
ALL_ACTIONS
():
for
action
in
ALL_ACTIONS
():
result
[
"actions"
]
.
append
(
action
.
render_as_json
())
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
):
class
OcciComputeCollectionView
(
View
):
@method_decorator
(
ensure_csrf_cookie
)
@method_decorator
(
ensure_csrf_cookie
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
request
.
user
.
is_authenticated
():
try
:
return
HttpResponse
(
status
=
403
)
validate_request
(
request
)
except
OcciRequestNotValid
as
e
:
return
e
.
response
vms
=
(
Instance
.
get_objects_with_level
(
"user"
,
request
.
user
)
vms
=
(
Instance
.
get_objects_with_level
(
"user"
,
request
.
user
)
.
filter
(
destroyed_at
=
None
))
.
filter
(
destroyed_at
=
None
))
json
=
{
"resources"
:
[]}
json
=
{
"resources"
:
[]}
for
vm
in
vms
:
for
vm
in
vms
:
json
[
"resources"
]
.
append
(
Compute
(
vm
)
.
render_as_json
())
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
):
class
OcciComputeView
(
View
):
""" View of a compute instance """
""" View of a compute instance """
def
get_vm_object
(
self
,
request
,
vmid
):
def
get_vm_object
(
self
,
user
,
vmid
):
try
:
try
:
vm
=
get_object_or_404
(
Instance
.
get_objects_with_level
(
"user"
,
vm
=
get_object_or_404
(
Instance
.
get_objects_with_level
(
"user"
,
request
.
user
),
pk
=
vmid
)
user
)
.
filter
(
destroyed_at
=
None
),
pk
=
vmid
)
except
Http404
:
except
Http404
:
raise
OcciResourceInstanceNotExist
()
raise
OcciResourceInstanceNotExist
()
return
Compute
(
vm
)
return
Compute
(
vm
)
...
@@ -92,20 +125,22 @@ class OcciComputeView(View):
...
@@ -92,20 +125,22 @@ class OcciComputeView(View):
@method_decorator
(
ensure_csrf_cookie
)
@method_decorator
(
ensure_csrf_cookie
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
request
.
user
.
is_authenticated
():
if
not
request
.
user
.
is_authenticated
():
return
HttpResponse
(
status
=
403
)
return
occi_response
({
"error"
:
"Authentication required."
},
status
=
403
)
try
:
try
:
compute
=
self
.
get_vm_object
(
request
,
kwargs
[
"id"
])
compute
=
self
.
get_vm_object
(
request
.
user
,
kwargs
[
"id"
])
except
OcciResourceInstanceNotExist
as
e
:
except
OcciResourceInstanceNotExist
as
e
:
return
e
.
json_
response
return
e
.
response
return
JsonR
esponse
(
compute
.
render_as_json
(),
charset
=
"utf-8"
)
return
occi_r
esponse
(
compute
.
render_as_json
(),
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"
))
# TODO post request w/o action, compute creation
if
not
requestData
[
"action"
]:
if
not
requestData
[
"action"
]:
return
HttpResponse
(
status
=
404
)
return
occi_response
({
"error"
:
"Action invocation rendering "
+
"is not supplied."
},
status
=
400
)
try
:
try
:
compute
=
self
.
get_vm_object
(
request
,
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
try
:
try
:
...
@@ -114,5 +149,49 @@ class OcciComputeView(View):
...
@@ -114,5 +149,49 @@ 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
# TODO: proper return value
return
occi_response
(
compute
.
render_as_json
(),
status
=
200
)
return
JsonResponse
(
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