root / snfOCCI / APIserver.py @ 088e4262
History | View | Annotate | Download (4.6 kB)
1 |
#!/usr/bin/env python
|
---|---|
2 |
|
3 |
from snfOCCI.registry import snfRegistry |
4 |
from snfOCCI.compute import ComputeBackend |
5 |
from snfOCCI.config import SERVER_CONFIG, KAMAKI_CONFIG |
6 |
|
7 |
from kamaki.clients.compute import ComputeClient |
8 |
from kamaki.clients.cyclades import CycladesClient |
9 |
from kamaki.config import Config |
10 |
|
11 |
from occi.core_model import Mixin, Resource |
12 |
from occi.backend import MixinBackend |
13 |
from occi.extensions.infrastructure import COMPUTE, START, STOP, SUSPEND, RESTART, RESOURCE_TEMPLATE, OS_TEMPLATE |
14 |
from occi.wsgi import Application |
15 |
|
16 |
from wsgiref.simple_server import make_server |
17 |
from wsgiref.validate import validator |
18 |
|
19 |
|
20 |
|
21 |
|
22 |
class MyAPP(Application): |
23 |
'''
|
24 |
An OCCI WSGI application.
|
25 |
'''
|
26 |
|
27 |
def refresh_images(self, snf, client): |
28 |
|
29 |
images = snf.list_images() |
30 |
for image in images: |
31 |
IMAGE_ATTRIBUTES = {'occi.core.id': str(image['id'])} |
32 |
IMAGE = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(image['name']), [OS_TEMPLATE], attributes = IMAGE_ATTRIBUTES) |
33 |
self.register_backend(IMAGE, MixinBackend())
|
34 |
|
35 |
def refresh_flavors(self, snf, client): |
36 |
|
37 |
flavors = snf.list_flavors() |
38 |
for flavor in flavors: |
39 |
details = snf.get_flavor_details(flavor['id'])
|
40 |
FLAVOR_ATTRIBUTES = {'occi.core.id': flavor['id'], |
41 |
'occi.compute.cores': details['cpu'], |
42 |
'occi.compute.memory': details['ram'], |
43 |
'occi.storage.size': details['disk'], |
44 |
} |
45 |
FLAVOR = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(flavor['name']), [RESOURCE_TEMPLATE], attributes = FLAVOR_ATTRIBUTES) |
46 |
self.register_backend(FLAVOR, MixinBackend())
|
47 |
|
48 |
|
49 |
def refresh_compute_instances(self, snf): |
50 |
'''Syncing registry with cyclades resources'''
|
51 |
|
52 |
servers = snf.list_servers() |
53 |
snf_keys = [] |
54 |
for server in servers: |
55 |
snf_keys.append(str(server['id'])) |
56 |
|
57 |
resources = self.registry.resources
|
58 |
occi_keys = resources.keys() |
59 |
|
60 |
#Compute instances in synnefo not available in registry
|
61 |
diff = [x for x in snf_keys if '/compute/'+x not in occi_keys] |
62 |
for key in diff: |
63 |
|
64 |
details = snf.get_server_details(int(key))
|
65 |
flavor = snf.get_flavor_details(details['flavorRef'])
|
66 |
image = snf.get_image_details(details['imageRef'])
|
67 |
|
68 |
for i in self.registry.backends: |
69 |
if i.term == str(image['name']): |
70 |
rel_image = i |
71 |
if i.term == str(flavor['name']): |
72 |
rel_flavor = i |
73 |
|
74 |
resource = Resource(key, COMPUTE, [rel_flavor, rel_image]) |
75 |
resource.actions = [START] |
76 |
resource.attributes['occi.core.id'] = key
|
77 |
resource.attributes['occi.compute.state'] = 'inactive' |
78 |
resource.attributes['occi.compute.architecture'] = SERVER_CONFIG['compute_arch'] |
79 |
resource.attributes['occi.compute.cores'] = flavor['cpu'] |
80 |
resource.attributes['occi.compute.memory'] = flavor['ram'] |
81 |
resource.attributes['occi.compute.hostname'] = SERVER_CONFIG['hostname'] % {'id':int(key)} |
82 |
|
83 |
self.registry.add_resource(key, resource, None) |
84 |
|
85 |
#Compute instances in registry not available in synnefo
|
86 |
diff = [x for x in occi_keys if x[9:] not in snf_keys] |
87 |
for key in diff: |
88 |
self.registry.delete_resource(key, None) |
89 |
|
90 |
|
91 |
def __call__(self, environ, response): |
92 |
|
93 |
compClient = ComputeClient(KAMAKI_CONFIG['compute_url'], environ['HTTP_AUTH_TOKEN']) |
94 |
cyclClient = CycladesClient(KAMAKI_CONFIG['compute_url'], environ['HTTP_AUTH_TOKEN']) |
95 |
|
96 |
#Up-to-date flavors and images
|
97 |
self.refresh_images(compClient,cyclClient)
|
98 |
self.refresh_flavors(compClient,cyclClient)
|
99 |
self.refresh_compute_instances(compClient)
|
100 |
|
101 |
# token will be represented in self.extras
|
102 |
return self._call_occi(environ, response, security = None, token = environ['HTTP_AUTH_TOKEN'], snf = compClient, client = cyclClient) |
103 |
|
104 |
|
105 |
def main(): |
106 |
|
107 |
APP = MyAPP(registry = snfRegistry()) |
108 |
COMPUTE_BACKEND = ComputeBackend() |
109 |
|
110 |
APP.register_backend(COMPUTE, COMPUTE_BACKEND) |
111 |
APP.register_backend(START, COMPUTE_BACKEND) |
112 |
APP.register_backend(STOP, COMPUTE_BACKEND) |
113 |
APP.register_backend(RESTART, COMPUTE_BACKEND) |
114 |
APP.register_backend(SUSPEND, COMPUTE_BACKEND) |
115 |
APP.register_backend(RESOURCE_TEMPLATE, MixinBackend()) |
116 |
APP.register_backend(OS_TEMPLATE, MixinBackend()) |
117 |
|
118 |
VALIDATOR_APP = validator(APP) |
119 |
HTTPD = make_server('', SERVER_CONFIG['port'], VALIDATOR_APP) |
120 |
HTTPD.serve_forever() |
121 |
|