Statistics
| Branch: | Revision:

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