Minor fixes to config.py
[snf-occi] / snfOCCI / APIserver.py
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