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
760e8dc0
authored
Apr 20, 2016
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:
...
@@ -47,6 +47,14 @@ with requests.Session() as session:
print
(
error
)
print
(
error
)
print
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
# osszes vm collectionkent
req
=
session
.
get
(
server
+
"occi/compute/"
,
headers
=
headers
,
req
=
session
.
get
(
server
+
"occi/compute/"
,
headers
=
headers
,
verify
=
False
)
verify
=
False
)
...
@@ -58,7 +66,7 @@ with requests.Session() as session:
...
@@ -58,7 +66,7 @@ with requests.Session() as session:
# 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/"
+
str
(
vmid
)
+
"/"
,
headers
=
headers
,
verify
=
False
)
headers
=
headers
,
verify
=
False
)
print
(
"compute-"
+
str
(
vmid
))
print
(
"compute-"
+
str
(
vmid
))
print
(
"------------"
)
print
(
"------------"
)
...
@@ -66,6 +74,55 @@ with requests.Session() as session:
...
@@ -66,6 +74,55 @@ with requests.Session() as session:
print
(
req
.
text
)
print
(
req
.
text
)
print
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
# Kijelentkezes
req
=
session
.
get
(
server
+
"occi/logout/"
,
headers
=
headers
,
req
=
session
.
get
(
server
+
"occi/logout/"
,
headers
=
headers
,
verify
=
False
)
verify
=
False
)
...
...
circle/occi/occi_core.py
View file @
760e8dc0
""" Implementation of the OCCI - Core model classes """
""" 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
:
class
Attribute
:
...
@@ -45,7 +45,8 @@ class Category(object):
...
@@ -45,7 +45,8 @@ class Category(object):
class
Kind
(
Category
):
class
Kind
(
Category
):
""" OCCI 1.2 - CORE - Classification - Kind """
""" OCCI 1.2 - CORE - Classification - Kind """
kind_optional_attributes
=
(
"parent"
,
"actions"
,
"enitities"
)
kind_optional_attributes
=
(
"parent"
,
"actions"
,
"enitities"
,
"location"
,)
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Kind
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
super
(
Kind
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
...
@@ -61,9 +62,14 @@ class Kind(Category):
...
@@ -61,9 +62,14 @@ class Kind(Category):
if
hasattr
(
self
,
"location"
):
if
hasattr
(
self
,
"location"
):
json
[
"location"
]
=
self
.
location
json
[
"location"
]
=
self
.
location
if
hasattr
(
self
,
"attributes"
):
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"
):
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
return
json
...
@@ -77,7 +83,10 @@ class Action(Category):
...
@@ -77,7 +83,10 @@ class Action(Category):
if
hasattr
(
self
,
"title"
):
if
hasattr
(
self
,
"title"
):
json
[
"title"
]
=
self
.
title
json
[
"title"
]
=
self
.
title
if
hasattr
(
self
,
"attributes"
):
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
return
json
...
@@ -93,8 +102,7 @@ class Mixin(Category):
...
@@ -93,8 +102,7 @@ class Mixin(Category):
kwargs
)
kwargs
)
def
render_as_json
(
self
):
def
render_as_json
(
self
):
json
=
{
"term"
:
self
.
term
,
"scheme"
:
self
.
scheme
,
json
=
{
"term"
:
self
.
term
,
"scheme"
:
self
.
scheme
}
"attributes"
:
self
.
attributes
,
"actions"
:
self
.
actions
}
if
hasattr
(
self
,
"title"
):
if
hasattr
(
self
,
"title"
):
json
[
"title"
]
=
self
.
title
json
[
"title"
]
=
self
.
title
if
hasattr
(
self
,
"location"
):
if
hasattr
(
self
,
"location"
):
...
@@ -103,6 +111,15 @@ class Mixin(Category):
...
@@ -103,6 +111,15 @@ class Mixin(Category):
json
[
"depends"
]
=
self
.
depends
json
[
"depends"
]
=
self
.
depends
if
hasattr
(
self
,
"applies"
):
if
hasattr
(
self
,
"applies"
):
json
[
"applies"
]
=
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
return
json
...
@@ -169,11 +186,3 @@ class Link(Entity):
...
@@ -169,11 +186,3 @@ class Link(Entity):
if
hasattr
(
self
,
"title"
):
if
hasattr
(
self
,
"title"
):
json
[
"title"
]
=
self
.
title
json
[
"title"
]
=
self
.
title
return
json
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"
)
circle/occi/occi_infrastructure.py
View file @
760e8dc0
""" Implementation of the OCCI - Infrastructure extension classes """
""" Implementation of the OCCI - Infrastructure extension classes """
from
occi_core
import
Action
,
Attribute
,
Resource
from
occi_core
import
Resource
from
occi_utils
import
action_list_for_resource
from
occi_utils
import
action_list_for_resource
,
OcciActionInvocationError
from
occi_instances
import
COMPUTE_ACTIONS
from
common.models
import
HumanReadableException
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
),
]),
]
COMPUTE_STATES
=
{
COMPUTE_STATES
=
{
"NOSTATE"
:
"inactive"
,
"NOSTATE"
:
"inactive"
,
...
@@ -82,7 +41,6 @@ class Compute(Resource):
...
@@ -82,7 +41,6 @@ class Compute(Resource):
"http://schemas.ogf.org/occi/infrastructure#compute"
,
vm
.
pk
)
"http://schemas.ogf.org/occi/infrastructure#compute"
,
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
)
def
set_attributes
(
self
):
def
set_attributes
(
self
):
...
@@ -99,3 +57,91 @@ class Compute(Resource):
...
@@ -99,3 +57,91 @@ class Compute(Resource):
attributes
[
"occi.compute.state.message"
]
=
(
COMPUTE_STATE_MESSAGES
attributes
[
"occi.compute.state.message"
]
=
(
COMPUTE_STATE_MESSAGES
.
get
(
self
.
vm
.
state
))
.
get
(
self
.
vm
.
state
))
return
attributes
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
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
circle/occi/occi_utils.py
View file @
760e8dc0
"""" Utilities for the OCCI implementation of CIRCLE """
"""" 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
):
def
set_optional_attributes
(
self
,
optional_attributes
,
kwargs
):
""" Sets the optional arguments of an instance.
""" Sets the optional arguments of an instance.
...
...
circle/occi/urls.py
View file @
760e8dc0
from
django.conf.urls
import
url
from
django.conf.urls
import
url
from
views
import
(
OcciLoginView
,
OcciLogoutView
,
Occi
Comput
eView
,
from
views
import
(
OcciLoginView
,
OcciLogoutView
,
Occi
QueryInterfac
eView
,
OcciComputeCollectionView
)
OcciCompute
View
,
OcciCompute
CollectionView
)
urlpatterns
=
[
urlpatterns
=
[
url
(
r'^login/$'
,
OcciLoginView
.
as_view
()),
url
(
r'^login/$'
,
OcciLoginView
.
as_view
()),
url
(
r'^logout/$'
,
OcciLogoutView
.
as_view
()),
url
(
r'^logout/$'
,
OcciLogoutView
.
as_view
()),
url
(
r'^-/$'
,
OcciQueryInterfaceView
.
as_view
()),
url
(
r'^compute/$'
,
OcciComputeCollectionView
.
as_view
()),
url
(
r'^compute/$'
,
OcciComputeCollectionView
.
as_view
()),
url
(
r'^compute/(?P<id>\d+)/$'
,
OcciComputeView
.
as_view
()),
url
(
r'^compute/(?P<id>\d+)/$'
,
OcciComputeView
.
as_view
()),
]
]
circle/occi/views.py
View file @
760e8dc0
...
@@ -12,6 +12,9 @@ from django.utils.decorators import method_decorator
...
@@ -12,6 +12,9 @@ from django.utils.decorators import method_decorator
from
vm.models.instance
import
Instance
from
vm.models.instance
import
Instance
from
forms
import
OcciAuthForm
from
forms
import
OcciAuthForm
from
occi_infrastructure
import
Compute
from
occi_infrastructure
import
Compute
from
occi_utils
import
(
OcciResourceInstanceNotExist
,
OcciActionInvocationError
)
from
occi_instances
import
ALL_KINDS
,
ALL_MIXINS
,
ALL_ACTIONS
class
OcciLoginView
(
View
):
class
OcciLoginView
(
View
):
...
@@ -27,9 +30,9 @@ class OcciLoginView(View):
...
@@ -27,9 +30,9 @@ class OcciLoginView(View):
return
JsonResponse
(
result
,
charset
=
"utf-8"
)
return
JsonResponse
(
result
,
charset
=
"utf-8"
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
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
""" Returns a response with a cookie to be used for the OCCI api
requests. """
requests. """
data
=
json
.
loads
(
request
.
body
.
decode
(
"utf-8"
))
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"
}
...
@@ -49,7 +52,22 @@ class OcciLogoutView(View):
...
@@ -49,7 +52,22 @@ class OcciLogoutView(View):
return
JsonResponse
(
result
,
charset
=
"utf-8"
)
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
):
class
OcciComputeCollectionView
(
View
):
@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
HttpResponse
(
status
=
403
)
...
@@ -63,14 +81,38 @@ class OcciComputeCollectionView(View):
...
@@ -63,14 +81,38 @@ class OcciComputeCollectionView(View):
class
OcciComputeView
(
View
):
class
OcciComputeView
(
View
):
""" View of a compute instance """
""" 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
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
request
.
user
.
is_authenticated
():
if
not
request
.
user
.
is_authenticated
():
return
HttpResponse
(
status
=
403
)
return
HttpResponse
(
status
=
403
)
try
:
try
:
vm
=
get_object_or_404
(
Instance
.
get_objects_with_level
(
"user"
,
compute
=
self
.
get_vm_object
(
request
,
kwargs
[
"id"
])
request
.
user
),
pk
=
kwargs
[
'id'
])
except
OcciResourceInstanceNotExist
as
e
:
except
Http404
:
return
e
.
json_response
return
JsonResponse
({
"error"
:
"There is no instance with the"
+
" id "
+
kwargs
[
'id'
]
+
"."
},
status
=
400
)
compute
=
Compute
(
vm
)
return
JsonResponse
(
compute
.
render_as_json
(),
charset
=
"utf-8"
)
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
)
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