root / snf-occi-server.py @ f882a314
History | View | Annotate | Download (5.3 kB)
1 |
#!/usr/bin/env python
|
---|---|
2 |
|
3 |
from kamaki.clients.compute import ComputeClient |
4 |
from kamaki.config import Config |
5 |
|
6 |
from occi.core_model import Mixin, Resource, Link, Entity |
7 |
from occi.backend import ActionBackend, KindBackend, MixinBackend |
8 |
from occi.extensions.infrastructure import COMPUTE, START, STOP, SUSPEND, RESTART, RESOURCE_TEMPLATE, OS_TEMPLATE |
9 |
|
10 |
from occi.wsgi import Application |
11 |
|
12 |
from wsgiref.simple_server import make_server |
13 |
from wsgiref.validate import validator |
14 |
|
15 |
|
16 |
class MyBackend(KindBackend, ActionBackend): |
17 |
'''
|
18 |
An very simple abstract backend which handles update and replace for
|
19 |
attributes. Support for links and mixins would need to added.
|
20 |
'''
|
21 |
|
22 |
def update(self, old, new, extras): |
23 |
# here you can check what information from new_entity you wanna bring
|
24 |
# into old_entity
|
25 |
|
26 |
# trigger your hypervisor and push most recent information
|
27 |
print('Updating a resource with id: ' + old.identifier)
|
28 |
for item in new.attributes.keys(): |
29 |
old.attributes[item] = new.attributes[item] |
30 |
|
31 |
def replace(self, old, new, extras): |
32 |
print('Replacing a resource with id: ' + old.identifier)
|
33 |
old.attributes = {} |
34 |
for item in new.attributes.keys(): |
35 |
old.attributes[item] = new.attributes[item] |
36 |
old.attributes['occi.compute.state'] = 'inactive' |
37 |
|
38 |
|
39 |
class ComputeBackend(MyBackend): |
40 |
'''
|
41 |
A Backend for compute instances.
|
42 |
'''
|
43 |
|
44 |
def create(self, entity, extras): |
45 |
entity.attributes['occi.compute.state'] = 'active' |
46 |
entity.actions = [STOP, SUSPEND, RESTART] |
47 |
|
48 |
for mixin in entity.mixins: |
49 |
print mixin.term
|
50 |
print mixin.attributes
|
51 |
|
52 |
print('Creating the virtual machine with id: ' + entity.identifier)
|
53 |
|
54 |
|
55 |
def retrieve(self, entity, extras): |
56 |
# triggering cyclades to retrieve up to date information
|
57 |
|
58 |
if entity.attributes['occi.compute.state'] == 'inactive': |
59 |
entity.actions = [START] |
60 |
if entity.attributes['occi.compute.state'] == 'active': |
61 |
entity.actions = [STOP, SUSPEND, RESTART] |
62 |
if entity.attributes['occi.compute.state'] == 'suspended': |
63 |
entity.actions = [START] |
64 |
|
65 |
def delete(self, entity, extras): |
66 |
# call the management framework to delete this compute instance...
|
67 |
print('Removing representation of virtual machine with id: '
|
68 |
+ entity.identifier) |
69 |
|
70 |
def action(self, entity, action, extras): |
71 |
if action not in entity.actions: |
72 |
raise AttributeError("This action is currently no applicable.") |
73 |
elif action == START:
|
74 |
entity.attributes['occi.compute.state'] = 'active' |
75 |
entity.actions = [STOP, SUSPEND, RESTART] |
76 |
# read attributes from action and do something with it :-)
|
77 |
print('Starting virtual machine with id' + entity.identifier)
|
78 |
elif action == STOP:
|
79 |
entity.attributes['occi.compute.state'] = 'inactive' |
80 |
entity.actions = [START] |
81 |
# read attributes from action and do something with it :-)
|
82 |
print('Stopping virtual machine with id' + entity.identifier)
|
83 |
elif action == RESTART:
|
84 |
entity.actions = [STOP, SUSPEND, RESTART] |
85 |
entity.attributes['occi.compute.state'] = 'active' |
86 |
# read attributes from action and do something with it :-)
|
87 |
print('Restarting virtual machine with id' + entity.identifier)
|
88 |
elif action == SUSPEND:
|
89 |
entity.attributes['occi.compute.state'] = 'suspended' |
90 |
entity.actions = [START] |
91 |
# read attributes from action and do something with it :-)
|
92 |
print('Suspending virtual machine with id' + entity.identifier)
|
93 |
|
94 |
|
95 |
class MyAPP(Application): |
96 |
'''
|
97 |
An OCCI WSGI application.
|
98 |
'''
|
99 |
|
100 |
def __call__(self, environ, response): |
101 |
sec_obj = {'username': 'password'} |
102 |
|
103 |
snf = ComputeClient(Config()) |
104 |
|
105 |
images = snf.list_images() |
106 |
for image in images: |
107 |
IMAGE = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(image['name']), [OS_TEMPLATE]) |
108 |
self.register_backend(IMAGE, MixinBackend())
|
109 |
|
110 |
flavors = snf.list_flavors() |
111 |
for flavor in flavors: |
112 |
FLAVOR_ATTRIBUTES = {'occi.compute.cores': snf.get_flavor_details(flavor['id'])['cpu'], |
113 |
'occi.compute.memory': snf.get_flavor_details(flavor['id'])['ram'], |
114 |
'occi.storage.size': snf.get_flavor_details(flavor['id'])['disk'], |
115 |
} |
116 |
FLAVOR = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(flavor['name']), [RESOURCE_TEMPLATE], attributes = FLAVOR_ATTRIBUTES) |
117 |
self.register_backend(FLAVOR, MixinBackend())
|
118 |
|
119 |
|
120 |
|
121 |
return self._call_occi(environ, response, security=sec_obj, foo=None) |
122 |
|
123 |
if __name__ == '__main__': |
124 |
|
125 |
APP = MyAPP() |
126 |
|
127 |
COMPUTE_BACKEND = ComputeBackend() |
128 |
|
129 |
APP.register_backend(COMPUTE, COMPUTE_BACKEND) |
130 |
APP.register_backend(START, COMPUTE_BACKEND) |
131 |
APP.register_backend(STOP, COMPUTE_BACKEND) |
132 |
APP.register_backend(RESTART, COMPUTE_BACKEND) |
133 |
APP.register_backend(SUSPEND, COMPUTE_BACKEND) |
134 |
APP.register_backend(RESOURCE_TEMPLATE, MixinBackend()) |
135 |
APP.register_backend(OS_TEMPLATE, MixinBackend()) |
136 |
|
137 |
|
138 |
VALIDATOR_APP = validator(APP) |
139 |
HTTPD = make_server('', 8888, VALIDATOR_APP) |
140 |
HTTPD.serve_forever() |
141 |
|