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
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
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
260 additions
and
72 deletions
+260
-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
+0
-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
)
...
...
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"
)
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
circle/occi/occi_instances.py
0 → 100644
View file @
760e8dc0
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.
...
...
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
()),
]
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
)
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