6e33a1754737ab3074d509f0c986248d4e922a08
[snf-occi] / snf-occi-server.py
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             # read attributes from action and do something with it :-)
76             print('Starting virtual machine with id' + entity.identifier)
77         elif action == STOP:
78             entity.attributes['occi.compute.state'] = 'inactive'
79             # read attributes from action and do something with it :-)
80             print('Stopping virtual machine with id' + entity.identifier)
81         elif action == RESTART:
82             entity.attributes['occi.compute.state'] = 'active'
83             # read attributes from action and do something with it :-)
84             print('Restarting virtual machine with id' + entity.identifier)
85         elif action == SUSPEND:
86             entity.attributes['occi.compute.state'] = 'suspended'
87             # read attributes from action and do something with it :-)
88             print('Suspending virtual machine with id' + entity.identifier)
89
90
91 class MyAPP(Application):
92     '''
93     An OCCI WSGI application.
94     '''
95
96     def __call__(self, environ, response):
97         sec_obj = {'username': 'password'}
98
99         snf = ComputeClient(Config())
100         images = snf.list_images()
101         for image in images:
102             IMAGE = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(image['name']), [OS_TEMPLATE])
103             self.register_backend(IMAGE, MixinBackend())
104
105         flavors = snf.list_flavors()
106         for flavor in flavors:
107             FLAVOR_ATTRIBUTES = {'occi.compute.cores': snf.get_flavor_details(flavor['id'])['cpu'],
108                                  'occi.compute.memory': snf.get_flavor_details(flavor['id'])['ram'],
109                                  'occi.storage.size': snf.get_flavor_details(flavor['id'])['disk'],
110                                  }
111             FLAVOR = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(flavor['name']), [RESOURCE_TEMPLATE], attributes = FLAVOR_ATTRIBUTES)
112             self.register_backend(FLAVOR, MixinBackend())
113    
114         
115         
116         return self._call_occi(environ, response, security=sec_obj, foo=None)
117
118 if __name__ == '__main__':
119
120     APP = MyAPP()
121
122     COMPUTE_BACKEND = ComputeBackend()
123
124     APP.register_backend(COMPUTE, COMPUTE_BACKEND)
125     APP.register_backend(START, COMPUTE_BACKEND)
126     APP.register_backend(STOP, COMPUTE_BACKEND)
127     APP.register_backend(RESTART, COMPUTE_BACKEND)
128     APP.register_backend(SUSPEND, COMPUTE_BACKEND)
129     APP.register_backend(RESOURCE_TEMPLATE, MixinBackend())
130     APP.register_backend(OS_TEMPLATE, MixinBackend())
131     
132  
133     VALIDATOR_APP = validator(APP)
134     HTTPD = make_server('', 8888, VALIDATOR_APP)
135     HTTPD.serve_forever()
136