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
760e8dc0
authored
9 years ago
by
Fukász Rómeó Ervin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
occi query imterface and occi instances
parent
269156f0
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
473 additions
and
72 deletions
+473
-72
circle/occi/occi_client_example.py
+58
-1
circle/occi/occi_core.py
+24
-15
circle/occi/occi_infrastructure.py
+93
-47
circle/occi/occi_instances.py
+213
-0
circle/occi/occi_utils.py
+33
-0
circle/occi/urls.py
+3
-2
circle/occi/views.py
+49
-7
No files found.
circle/occi/occi_client_example.py
View file @
760e8dc0
...
...
@@ -47,6 +47,14 @@ with requests.Session() as session:
print
(
error
)
print
# query interface
req
=
session
.
get
(
server
+
"occi/-/"
,
headers
=
headers
,
verify
=
False
)
print
(
"query-interface"
)
print
(
"---------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
(
req
.
text
)
print
# osszes vm collectionkent
req
=
session
.
get
(
server
+
"occi/compute/"
,
headers
=
headers
,
verify
=
False
)
...
...
@@ -58,7 +66,7 @@ with requests.Session() as session:
# az elso vm a listabol
vmid
=
json
.
loads
(
req
.
text
)[
"resources"
][
0
][
"id"
]
req
=
session
.
get
(
server
+
"occi/compute/"
+
str
(
vmid
),
req
=
session
.
get
(
server
+
"occi/compute/"
+
str
(
vmid
)
+
"/"
,
headers
=
headers
,
verify
=
False
)
print
(
"compute-"
+
str
(
vmid
))
print
(
"------------"
)
...
...
@@ -66,6 +74,55 @@ with requests.Session() as session:
print
(
req
.
text
)
print
# ha nem active, akkor azza tesszuk
state
=
json
.
loads
(
req
.
text
)[
"attributes"
][
"occi.compute.state"
]
action
=
"http://schemas.ogf.org/occi/infrastructure/compute/action#"
if
state
!=
"active"
:
try
:
headers
[
"X-CSRFToken"
]
=
req
.
cookies
[
'csrftoken'
]
except
:
pass
req
=
session
.
post
(
server
+
"occi/compute/"
+
str
(
vmid
)
+
"/"
,
headers
=
headers
,
verify
=
False
,
data
=
json
.
dumps
({
"action"
:
action
+
"start"
}))
print
(
"compute-"
+
str
(
vmid
)
+
"-start"
)
print
(
"---------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
(
req
.
text
)
print
# restart
try
:
headers
[
"X-CSRFToken"
]
=
req
.
cookies
[
'csrftoken'
]
except
:
pass
actionatrs
=
{
"method"
:
"cold"
}
actioninv
=
{
"action"
:
action
+
"restart"
,
"attributes"
:
actionatrs
}
req
=
session
.
post
(
server
+
"occi/compute/"
+
str
(
vmid
)
+
"/"
,
headers
=
headers
,
verify
=
False
,
data
=
json
.
dumps
(
actioninv
))
print
(
"compute-"
+
str
(
vmid
)
+
"-restart"
)
print
(
"-----------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
(
req
.
text
)
print
# suspend
try
:
headers
[
"X-CSRFToken"
]
=
req
.
cookies
[
'csrftoken'
]
except
:
pass
actioninv
[
"action"
]
=
action
+
"suspend"
actioninv
[
"attributes"
][
"method"
]
=
"suspend"
req
=
session
.
post
(
server
+
"occi/compute/"
+
str
(
vmid
)
+
"/"
,
headers
=
headers
,
verify
=
False
,
data
=
json
.
dumps
(
actioninv
))
print
(
"compute-"
+
str
(
vmid
)
+
"-suspend"
)
print
(
"-----------------"
)
print
(
"status_code: "
+
str
(
req
.
status_code
))
print
(
req
.
text
)
print
# Kijelentkezes
req
=
session
.
get
(
server
+
"occi/logout/"
,
headers
=
headers
,
verify
=
False
)
...
...
This diff is collapsed.
Click to expand it.
circle/occi/occi_core.py
View file @
760e8dc0
""" Implementation of the OCCI - Core model classes """
from
occi_utils
import
set_optional_attributes
,
serialize_attributes
from
occi_utils
import
set_optional_attributes
class
Attribute
:
...
...
@@ -45,7 +45,8 @@ class Category(object):
class
Kind
(
Category
):
""" OCCI 1.2 - CORE - Classification - Kind """
kind_optional_attributes
=
(
"parent"
,
"actions"
,
"enitities"
)
kind_optional_attributes
=
(
"parent"
,
"actions"
,
"enitities"
,
"location"
,)
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Kind
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
...
...
@@ -61,9 +62,14 @@ class Kind(Category):
if
hasattr
(
self
,
"location"
):
json
[
"location"
]
=
self
.
location
if
hasattr
(
self
,
"attributes"
):
json
[
"attributes"
]
=
serialize_attributes
(
self
.
attributes
)
json
[
"attributes"
]
=
{}
for
attribute
in
self
.
attributes
:
json
[
"attributes"
][
attribute
.
name
]
=
(
attribute
.
render_as_json
())
if
hasattr
(
self
,
"actions"
):
json
[
"actions"
]
=
serialize_attributes
(
self
.
actions
)
json
[
"actions"
]
=
[]
for
action
in
self
.
actions
:
json
[
"actions"
]
.
append
(
action
.
scheme
+
action
.
term
)
return
json
...
...
@@ -77,7 +83,10 @@ class Action(Category):
if
hasattr
(
self
,
"title"
):
json
[
"title"
]
=
self
.
title
if
hasattr
(
self
,
"attributes"
):
json
[
"attributes"
]
=
serialize_attributes
(
self
.
attributes
)
json
[
"attributes"
]
=
{}
for
attribute
in
self
.
attributes
:
json
[
"attributes"
][
attribute
.
name
]
=
(
attribute
.
render_as_json
())
return
json
...
...
@@ -93,8 +102,7 @@ class Mixin(Category):
kwargs
)
def
render_as_json
(
self
):
json
=
{
"term"
:
self
.
term
,
"scheme"
:
self
.
scheme
,
"attributes"
:
self
.
attributes
,
"actions"
:
self
.
actions
}
json
=
{
"term"
:
self
.
term
,
"scheme"
:
self
.
scheme
}
if
hasattr
(
self
,
"title"
):
json
[
"title"
]
=
self
.
title
if
hasattr
(
self
,
"location"
):
...
...
@@ -103,6 +111,15 @@ class Mixin(Category):
json
[
"depends"
]
=
self
.
depends
if
hasattr
(
self
,
"applies"
):
json
[
"applies"
]
=
self
.
applies
if
hasattr
(
self
,
"attributes"
):
json
[
"attributes"
]
=
{}
for
attribute
in
self
.
attributes
:
json
[
"attributes"
][
attribute
.
name
]
=
(
attribute
.
render_as_json
())
if
hasattr
(
self
,
"actions"
):
json
[
"actions"
]
=
[]
for
action
in
self
.
actions
:
json
[
"actions"
]
.
append
(
action
.
scheme
+
action
.
term
)
return
json
...
...
@@ -169,11 +186,3 @@ class Link(Entity):
if
hasattr
(
self
,
"title"
):
json
[
"title"
]
=
self
.
title
return
json
ENTITY_KIND
=
Kind
(
"http://schemas.ogf.org/occi/core#"
,
"entity"
,
title
=
"Entity"
)
RESOURCE_KIND
=
Kind
(
"http://schemas.ogf.org/occi/core#"
,
"resource"
,
title
=
"Resource"
,
parent
=
"http://schemas.ogf.org/occi/core#entity"
)
This diff is collapsed.
Click to expand it.
circle/occi/occi_infrastructure.py
View file @
760e8dc0
""" Implementation of the OCCI - Infrastructure extension classes """
from
occi_core
import
Action
,
Attribute
,
Resource
from
occi_utils
import
action_list_for_resource
COMPUTE_ATTRIBUTES
=
[
Attribute
(
"occi.compute.architecture"
,
"Object"
,
True
,
False
,
description
=
"CPU Architecture of the instance."
),
Attribute
(
"occi.compute.cores"
,
"Object"
,
True
,
False
,
description
=
"Number of virtual CPU cores assigned to "
+
"the instance."
),
Attribute
(
"occi.compute.hostname"
,
"Object"
,
True
,
False
,
description
=
"Fully Qualified DNS hostname for the "
+
"instance"
),
Attribute
(
"occi.compute.share"
,
"Object"
,
True
,
False
,
description
=
"Relative number of CPU shares for the "
+
"instance."
),
Attribute
(
"occi.compute.memory"
,
"Object"
,
True
,
False
,
description
=
"Maximum RAM in gigabytes allocated to "
+
"the instance."
),
Attribute
(
"occi.compute.state"
,
"Object"
,
False
,
True
,
description
=
"Current state of the instance."
),
Attribute
(
"occi.compute.state.message"
,
"Object"
,
False
,
False
,
description
=
"Human-readable explanation of the current "
+
"instance state"
),
]
COMPUTE_ACTIONS
=
[
Action
(
"http://schemas.ogf.org/occi/infrastructure/compute/action#"
,
"start"
,
title
=
"Start compute instance"
),
Action
(
"http://schemas.ogf.org/occi/infrastructure/compute/action#"
,
"stop"
,
title
=
"Stop compute instance"
,
attributes
=
[
Attribute
(
"method"
,
"Object"
,
True
,
False
),
]),
Action
(
"http://schemas.ogf.org/occi/infrastructure/compute/action#"
,
"restart"
,
title
=
"Restart compute instance"
,
attributes
=
[
Attribute
(
"method"
,
"Object"
,
True
,
False
),
]),
Action
(
"http://schemas.ogf.org/occi/infrastructure/compute/action#"
,
"suspend"
,
title
=
"Suspend compute instance"
,
attributes
=
[
Attribute
(
"method"
,
"Object"
,
True
,
False
),
]),
Action
(
"http://schemas.ogf.org/occi/infrastructure/compute/action#"
,
"save"
,
title
=
"Create a template of compute instance"
,
attributes
=
[
Attribute
(
"method"
,
"Object"
,
True
,
False
),
Attribute
(
"name"
,
"Object"
,
True
,
True
),
]),
]
from
occi_core
import
Resource
from
occi_utils
import
action_list_for_resource
,
OcciActionInvocationError
from
occi_instances
import
COMPUTE_ACTIONS
from
common.models
import
HumanReadableException
COMPUTE_STATES
=
{
"NOSTATE"
:
"inactive"
,
...
...
@@ -82,7 +41,6 @@ class Compute(Resource):
"http://schemas.ogf.org/occi/infrastructure#compute"
,
vm
.
pk
)
self
.
vm
=
vm
self
.
attributes
=
self
.
set_attributes
()
self
.
actions
=
action_list_for_resource
(
COMPUTE_ACTIONS
)
def
set_attributes
(
self
):
...
...
@@ -99,3 +57,91 @@ class Compute(Resource):
attributes
[
"occi.compute.state.message"
]
=
(
COMPUTE_STATE_MESSAGES
.
get
(
self
.
vm
.
state
))
return
attributes
def
invoke_action
(
self
,
user
,
action
,
attributes
):
base
=
"http://schemas.ogf.org/occi/infrastructure/compute/action#"
if
action
==
(
base
+
"start"
):
self
.
start
(
user
)
elif
action
==
(
base
+
"stop"
):
self
.
stop
(
user
,
attributes
)
elif
action
==
(
base
+
"restart"
):
self
.
restart
(
user
,
attributes
)
elif
action
==
(
base
+
"suspend"
):
self
.
suspend
(
user
,
attributes
)
elif
action
==
(
base
+
"save"
):
self
.
save
(
user
,
attributes
)
else
:
raise
OcciActionInvocationError
(
message
=
"Undefined action."
)
self
.
__init__
(
self
.
vm
)
def
start
(
self
,
user
):
""" Start action on a compute instance """
try
:
if
self
.
vm
.
status
==
"SUSPENDED"
:
self
.
vm
.
wake_up
(
user
=
user
)
else
:
self
.
vm
.
deploy
(
user
=
user
)
except
HumanReadableException
as
e
:
raise
OcciActionInvocationError
(
message
=
e
.
get_user_text
())
def
stop
(
self
,
user
,
attributes
):
""" Stop action on a compute instance """
if
"method"
not
in
attributes
:
raise
OcciActionInvocationError
(
message
=
"No method given."
)
if
attributes
[
"method"
]
in
(
"graceful"
,
"acpioff"
,):
try
:
# TODO: call shutdown properly
self
.
vm
.
shutdown
(
user
=
user
)
except
HumanReadableException
as
e
:
raise
OcciActionInvocationError
(
message
=
e
.
get_user_text
())
elif
attributes
[
"method"
]
in
(
"poweroff"
,):
try
:
self
.
vm
.
shut_off
(
user
=
user
)
except
HumanReadableException
as
e
:
raise
OcciActionInvocationError
(
message
=
e
.
get_user_text
())
else
:
raise
OcciActionInvocationError
(
message
=
"Given method is not valid"
)
def
restart
(
self
,
user
,
attributes
):
""" Restart action on a compute instance """
if
"method"
not
in
attributes
:
raise
OcciActionInvocationError
(
message
=
"No method given."
)
if
attributes
[
"method"
]
in
(
"graceful"
,
"warm"
,):
try
:
# TODO: not working for some reason
self
.
vm
.
restart
(
user
=
user
)
except
HumanReadableException
as
e
:
raise
OcciActionInvocationError
(
message
=
e
.
get_user_text
())
elif
attributes
[
"method"
]
in
(
"cold"
,):
try
:
self
.
vm
.
reset
(
user
=
user
)
except
HumanReadableException
as
e
:
raise
OcciActionInvocationError
(
message
=
e
.
get_user_text
())
else
:
raise
OcciActionInvocationError
(
message
=
"Given method is not valid"
)
def
suspend
(
self
,
user
,
attributes
):
""" Suspend action on a compute instance """
if
"method"
not
in
attributes
:
raise
OcciActionInvocationError
(
message
=
"No method given."
)
if
attributes
[
"method"
]
in
(
"hibernate"
,
"suspend"
,):
try
:
self
.
vm
.
sleep
(
user
=
user
)
except
HumanReadableException
as
e
:
raise
OcciActionInvocationError
(
message
=
e
.
get_user_text
())
else
:
raise
OcciActionInvocationError
(
message
=
"Given method is not valid"
)
def
save
(
self
,
user
,
attributes
):
""" Save action on a compute instance """
# TODO: save template
raise
OcciActionInvocationError
(
message
=
"Save action not implemented"
)
class
Network
(
Resource
):
# TODO: network
pass
This diff is collapsed.
Click to expand it.
circle/occi/occi_instances.py
0 → 100644
View file @
760e8dc0
""" Required instances of the OCCI classes """
from
occi_core
import
Kind
,
Mixin
,
Attribute
,
Action
ENTITY_KIND
=
Kind
(
"http://schemas.ogf.org/occi/core#"
,
"entity"
,
title
=
"Entity"
)
RESOURCE_KIND
=
Kind
(
"http://schemas.ogf.org/occi/core#"
,
"resource"
,
title
=
"Resource"
,
parent
=
"http://schemas.ogf.org/occi/core#entity"
)
LINK_KIND
=
Kind
(
"http://schemas.ogf.org/occi/core#"
,
"link"
,
title
=
"Link"
,
parent
=
"http://schemas.ogf.org/occi/ocre#entity"
)
COMPUTE_ATTRIBUTES
=
[
Attribute
(
"occi.compute.architecture"
,
"Enum {x86, x64}"
,
True
,
False
,
description
=
"CPU Architecture of the instance."
),
Attribute
(
"occi.compute.cores"
,
"Integer"
,
True
,
False
,
description
=
"Number of virtual CPU cores assigned to "
+
"the instance."
),
Attribute
(
"occi.compute.hostname"
,
"String"
,
True
,
False
,
description
=
"Fully Qualified DNS hostname for the "
+
"instance"
),
Attribute
(
"occi.compute.share"
,
"Integer"
,
True
,
False
,
description
=
"Relative number of CPU shares for the "
+
"instance."
),
Attribute
(
"occi.compute.memory"
,
"Float, 10^9 (GiB)"
,
True
,
False
,
description
=
"Maximum RAM in gigabytes allocated to "
+
"the instance."
),
Attribute
(
"occi.compute.state"
,
"Enum {active, inactive, suspended, "
+
"error}"
,
False
,
True
,
description
=
"Current state of the instance."
),
Attribute
(
"occi.compute.state.message"
,
"String"
,
False
,
False
,
description
=
"Human-readable explanation of the current "
+
"instance state"
),
]
COMPUTE_ACTIONS
=
[
Action
(
"http://schemas.ogf.org/occi/infrastructure/compute/action#"
,
"start"
,
title
=
"Start compute instance"
),
Action
(
"http://schemas.ogf.org/occi/infrastructure/compute/action#"
,
"stop"
,
title
=
"Stop compute instance"
,
attributes
=
[
Attribute
(
"method"
,
"Enum {graceful, acpioff, "
+
"poweroff}"
,
True
,
False
),
]),
Action
(
"http://schemas.ogf.org/occi/infrastructure/compute/action#"
,
"restart"
,
title
=
"Restart compute instance"
,
attributes
=
[
Attribute
(
"method"
,
"Enum {graceful, warm, cold}"
,
True
,
False
),
]),
Action
(
"http://schemas.ogf.org/occi/infrastructure/compute/action#"
,
"suspend"
,
title
=
"Suspend compute instance"
,
attributes
=
[
Attribute
(
"method"
,
"Enum {hibernate, suspend}"
,
True
,
False
),
]),
Action
(
"http://schemas.ogf.org/occi/infrastructure/compute/action#"
,
"save"
,
title
=
"Create a template of compute instance"
,
attributes
=
[
Attribute
(
"method"
,
"Enum {hot, deferred}"
,
True
,
False
),
Attribute
(
"name"
,
"String"
,
True
,
True
),
]),
]
COMPUTE_KIND
=
Kind
(
"http://schemas.ogf.org/occi/infrastructure#"
,
"compute"
,
title
=
"Compute"
,
location
=
"/compute/"
,
parent
=
"http://schemas.ogf.org/occi/core#resource"
,
actions
=
COMPUTE_ACTIONS
,
attributes
=
COMPUTE_ATTRIBUTES
)
NETWORK_ATTRIBUTES
=
[
Attribute
(
"occi.network.vlan"
,
"Integer: 0-4095"
,
True
,
False
,
description
=
"802.1q VLAN Identifier (e.g., 343)."
),
Attribute
(
"occi.network.label"
,
"Token"
,
True
,
False
,
description
=
"Tag based VLANs (e.g., external-dmz)."
),
Attribute
(
"occi.network.state"
,
"Enum {active, inactive, error}"
,
False
,
True
,
description
=
"Current state of the instance."
),
Attribute
(
"occi.network.state.message"
,
"String"
,
False
,
False
,
description
=
"Human-readable explanation of the current "
+
"instance state."
),
]
NETWORK_ACTIONS
=
[
Action
(
"http://schemas.ogf.org/occi/infrastructure/network/action#"
,
"up"
,
title
=
"Activate the network interface."
),
Action
(
"http://schemas.ogf.org/occi/infrastructure/network/action#"
,
"down"
,
title
=
"Deactivate the network interface."
),
]
NETWORK_KIND
=
Kind
(
"http://schemas.ogf.org/occi/infrastructure#"
,
"network"
,
title
=
"Network Interface"
,
location
=
"/network/"
,
parent
=
"http://schemas.ogf.org/occi/core#resource"
,
actions
=
NETWORK_ACTIONS
,
attributes
=
NETWORK_ATTRIBUTES
)
IPNETWORK_ATTRIBUTES
=
[
Attribute
(
"occi.network.address"
,
"IPv4 or IPv6 Address range, CIDR "
+
"notation"
,
True
,
False
,
description
=
"Internet Protocol (IP) "
+
"network address (e.g., 192.168.0.1/24, fc00::/7)"
),
Attribute
(
"occi.network.gateway"
,
"IPv4 or IPv6 address"
,
True
,
False
,
description
=
"Internet Protocol (IP) network address (e.g., "
+
"192.168.0.1, fc00::)"
),
Attribute
(
"occi.network.allocation"
,
"Enum {dynamic, static}"
,
True
,
False
,
description
=
"Address allocation mechanism: dynamic e.g., uses "
+
"the dynamic host configuration protocol, static e.g., uses "
+
"user supplied static network configurations."
),
]
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"
))
STORAGE_ATTRIBUTES
=
[
Attribute
(
"occi.storage.size"
,
"Float, 10^9 (GiB)"
,
True
,
True
,
description
=
"Storage size of the instance in gigabytes."
),
Attribute
(
"occi.storage.state"
,
"Enum {online, offline, error}"
,
False
,
True
,
description
=
"Current status of the instance."
),
Attribute
(
"occi.storage.state.message"
,
"String"
,
False
,
False
,
description
=
"Human-readable explanation of the current "
+
"instance state"
),
]
STORAGE_ACTIONS
=
[
Action
(
"http://schemas.ogf.org/occi/infrastructure/storage/action#"
,
"online"
,
title
=
"Activate the storage instance"
),
Action
(
"http://schemas.ogf.org/occi/infrastructure/storage/action#"
,
"offline"
,
title
=
"Deactivate the storage instance"
),
]
STORAGE_KIND
=
Kind
(
"http://schemas.ogf.org/occi/infrastructure#"
,
"storage"
,
title
=
"Storage"
,
location
=
"/storage/"
,
parent
=
"http://schemas.ogf.org/occi/core#resource"
,
actions
=
STORAGE_ACTIONS
,
attributes
=
STORAGE_ATTRIBUTES
)
NETWORKINTERFACE_ATTRIBUTES
=
[
Attribute
(
"occi.networkinterface.interface"
,
"String"
,
False
,
True
,
description
=
"Identifier that relates the link to the link's "
+
"decive interface."
),
Attribute
(
"occi.networkinterface.mac"
,
"String"
,
True
,
True
,
description
=
"MAC address associated with the link's device "
+
"interface"
),
Attribute
(
"occi.networkinterface.state"
,
"Enum {active, inactive, error}"
,
False
,
True
,
description
=
"Current status of the interface."
),
Attribute
(
"occi.networkinterface.state.message"
,
"String"
,
False
,
False
,
description
=
"Human-readable explanation of the current "
+
"instance state."
),
]
NETWORKINTERFACE_KIND
=
Kind
(
"http://schemas.ogf.org/occi/infrastructure#"
,
"networkinterface"
,
title
=
"Network Interface"
,
location
=
"/networkinterface/"
,
parent
=
"http://schemas.ogf.org/occi/core#link"
,
attributes
=
NETWORKINTERFACE_ATTRIBUTES
)
IPNETWORKINTERFACE_ATTRIBUTES
=
[
Attribute
(
"occi.networkinterface.address"
,
"IPv4 or IPv6 Address"
,
True
,
True
,
description
=
"Internet Protocol (IP) network address "
+
"(e.g., 192.168.0.1/24, fc00::/7) of the link."
),
Attribute
(
"occi.networkinterface.gateway"
,
"IPv4 or IPv6 Address"
,
True
,
False
,
description
=
"Internet Protocol (IP) network address "
+
"(e.g., 192.168.0.1/24, fc00::/7)"
),
Attribute
(
"occi.networkinterface.allocation"
,
"Enum {dynamic, static}"
,
True
,
True
,
description
=
"Address mechanism: dynamic e.g., uses"
+
" the dynamic host configuration protocol, static e.g., uses "
+
"user supplied network configurations."
),
]
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"
)
STORAGELINK_ATTRIBUTES
=
[
Attribute
(
"occi.storagelink.deviceid"
,
"String"
,
True
,
True
,
description
=
"Device identifier as defined by the OCCI service "
+
"provider."
),
Attribute
(
"occi.storagelink.mountpoint"
,
"String"
,
True
,
False
,
description
=
"Point to where the storage is mounted in the "
+
"guest OS."
),
Attribute
(
"occi.storagelink.state"
,
"Enum {active, inactive, error}"
,
False
,
True
,
description
=
"Current status of the instance."
),
Attribute
(
"occi.storagelink.state.message"
,
"String"
,
False
,
False
,
description
=
"Human-readable explanation of the current "
+
"instance state."
),
]
STORAGELINK_KIND
=
Kind
(
"http://schemas.ogf.org/occi/infrastructure#"
,
"storagelink"
,
title
=
"Storage Link"
,
location
=
"/storagelink/"
,
parent
=
"http://schemas.ogf.org/occi/core#link"
,
atrributes
=
STORAGELINK_ATTRIBUTES
)
# TODO: OS Templates and Credentials
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
]
def
ALL_MIXINS
():
return
[
IPNETWORK_MIXIN
,
IPNETWORKINTERFACE_MIXIN
]
def
ALL_ACTIONS
():
result
=
[]
for
actions
in
ACTION_ARRAYS
:
for
action
in
actions
:
result
.
append
(
action
)
return
result
This diff is collapsed.
Click to expand it.
circle/occi/occi_utils.py
View file @
760e8dc0
"""" Utilities for the OCCI implementation of CIRCLE """
from
django.http
import
JsonResponse
,
HttpResponse
import
json
class
OcciResourceInstanceNotExist
(
Exception
):
def
__init__
(
self
):
message
=
"The resource instance does not exist."
super
(
OcciResourceInstanceNotExist
,
self
)
.
__init__
(
message
)
self
.
response
=
JsonResponse
({
"error"
:
message
},
status
=
404
,
charset
=
"utf-8"
)
class
OcciActionInvocationError
(
Exception
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
message
=
kwargs
.
get
(
"message"
,
"Could not invoke action."
)
super
(
OcciActionInvocationError
,
self
)
.
__init__
(
message
)
self
.
response
=
JsonResponse
({
"error"
:
message
},
status
=
400
,
charset
=
"utf-8"
)
class
OcciResponse
(
HttpResponse
):
""" A response class with its occi headers set """
# TODO: setting occi specific headers
def
init
(
self
,
data
,
response_type
,
*
args
,
**
kwargs
):
if
response_type
==
"json"
:
data
=
json
.
dumps
(
data
)
super
(
OcciResponse
,
self
)
.
__init__
(
data
,
status
=
418
)
if
response_type
==
"json"
:
self
[
"Content-Type"
]
=
"application/json"
else
:
self
[
"Content-Type"
]
=
"text/plain"
self
[
"Server"
]
=
"OCCI/1.2"
def
set_optional_attributes
(
self
,
optional_attributes
,
kwargs
):
""" Sets the optional arguments of an instance.
...
...
This diff is collapsed.
Click to expand it.
circle/occi/urls.py
View file @
760e8dc0
from
django.conf.urls
import
url
from
views
import
(
OcciLoginView
,
OcciLogoutView
,
Occi
Comput
eView
,
OcciComputeCollectionView
)
from
views
import
(
OcciLoginView
,
OcciLogoutView
,
Occi
QueryInterfac
eView
,
OcciCompute
View
,
OcciCompute
CollectionView
)
urlpatterns
=
[
url
(
r'^login/$'
,
OcciLoginView
.
as_view
()),
url
(
r'^logout/$'
,
OcciLogoutView
.
as_view
()),
url
(
r'^-/$'
,
OcciQueryInterfaceView
.
as_view
()),
url
(
r'^compute/$'
,
OcciComputeCollectionView
.
as_view
()),
url
(
r'^compute/(?P<id>\d+)/$'
,
OcciComputeView
.
as_view
()),
]
This diff is collapsed.
Click to expand it.
circle/occi/views.py
View file @
760e8dc0
...
...
@@ -12,6 +12,9 @@ from django.utils.decorators import method_decorator
from
vm.models.instance
import
Instance
from
forms
import
OcciAuthForm
from
occi_infrastructure
import
Compute
from
occi_utils
import
(
OcciResourceInstanceNotExist
,
OcciActionInvocationError
)
from
occi_instances
import
ALL_KINDS
,
ALL_MIXINS
,
ALL_ACTIONS
class
OcciLoginView
(
View
):
...
...
@@ -27,9 +30,9 @@ class OcciLoginView(View):
return
JsonResponse
(
result
,
charset
=
"utf-8"
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
data
=
json
.
loads
(
request
.
body
.
decode
(
"utf-8"
))
""" Returns a response with a cookie to be used for the OCCI api
requests. """
data
=
json
.
loads
(
request
.
body
.
decode
(
"utf-8"
))
form
=
OcciAuthForm
(
data
=
data
,
request
=
request
)
if
form
.
is_valid
():
result
=
{
"result"
:
"OK"
}
...
...
@@ -49,7 +52,22 @@ class OcciLogoutView(View):
return
JsonResponse
(
result
,
charset
=
"utf-8"
)
class
OcciQueryInterfaceView
(
View
):
""" The view of the OCCI query interface """
@method_decorator
(
ensure_csrf_cookie
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
result
=
{
"kinds"
:
[],
"mixins"
:
[],
"actions"
:
[]}
for
kind
in
ALL_KINDS
():
result
[
"kinds"
]
.
append
(
kind
.
render_as_json
())
for
mixin
in
ALL_MIXINS
():
result
[
"mixins"
]
.
append
(
mixin
.
render_as_json
())
for
action
in
ALL_ACTIONS
():
result
[
"actions"
]
.
append
(
action
.
render_as_json
())
return
JsonResponse
(
result
,
charset
=
"utf-8"
)
class
OcciComputeCollectionView
(
View
):
@method_decorator
(
ensure_csrf_cookie
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
request
.
user
.
is_authenticated
():
return
HttpResponse
(
status
=
403
)
...
...
@@ -63,14 +81,38 @@ class OcciComputeCollectionView(View):
class
OcciComputeView
(
View
):
""" View of a compute instance """
def
get_vm_object
(
self
,
request
,
vmid
):
try
:
vm
=
get_object_or_404
(
Instance
.
get_objects_with_level
(
"user"
,
request
.
user
),
pk
=
vmid
)
except
Http404
:
raise
OcciResourceInstanceNotExist
()
return
Compute
(
vm
)
@method_decorator
(
ensure_csrf_cookie
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
request
.
user
.
is_authenticated
():
return
HttpResponse
(
status
=
403
)
try
:
vm
=
get_object_or_404
(
Instance
.
get_objects_with_level
(
"user"
,
request
.
user
),
pk
=
kwargs
[
'id'
])
except
Http404
:
return
JsonResponse
({
"error"
:
"There is no instance with the"
+
" id "
+
kwargs
[
'id'
]
+
"."
},
status
=
400
)
compute
=
Compute
(
vm
)
compute
=
self
.
get_vm_object
(
request
,
kwargs
[
"id"
])
except
OcciResourceInstanceNotExist
as
e
:
return
e
.
json_response
return
JsonResponse
(
compute
.
render_as_json
(),
charset
=
"utf-8"
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
requestData
=
json
.
loads
(
request
.
body
.
decode
(
"utf-8"
))
# TODO post request w/o action, compute creation
if
not
requestData
[
"action"
]:
return
HttpResponse
(
status
=
404
)
try
:
compute
=
self
.
get_vm_object
(
request
,
kwargs
[
"id"
])
except
OcciResourceInstanceNotExist
as
e
:
return
e
.
response
try
:
compute
.
invoke_action
(
request
.
user
,
requestData
.
get
(
"action"
,
None
),
requestData
.
get
(
"attributes"
,
None
))
except
OcciActionInvocationError
as
e
:
return
e
.
response
# TODO: proper return value
return
JsonResponse
(
compute
.
render_as_json
(),
status
=
200
)
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