snf-occi-server.py 9.42 KB
Newer Older
1
2
3
4
5
#!/usr/bin/env python

from kamaki.clients.compute import ComputeClient
from kamaki.config  import Config

6
<<<<<<< HEAD
7
from occi.core_model import Mixin
8
=======
9
from occi.core_model import Mixin, Resource, Link, Entity
10
>>>>>>> 592e811729d5f061377c854f645311e560ec4faa
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from occi.backend import ActionBackend, KindBackend, MixinBackend
from occi.extensions.infrastructure import COMPUTE, START, STOP, SUSPEND, RESTART, RESOURCE_TEMPLATE, OS_TEMPLATE

from occi.wsgi import Application

from wsgiref.simple_server import make_server
from wsgiref.validate import validator


class MyBackend(KindBackend, ActionBackend):
    '''
    An very simple abstract backend which handles update and replace for
    attributes. Support for links and mixins would need to added.
    '''

    def update(self, old, new, extras):
        # here you can check what information from new_entity you wanna bring
        # into old_entity

        # trigger your hypervisor and push most recent information
        print('Updating a resource with id: ' + old.identifier)
        for item in new.attributes.keys():
            old.attributes[item] = new.attributes[item]

    def replace(self, old, new, extras):
        print('Replacing a resource with id: ' + old.identifier)
        old.attributes = {}
        for item in new.attributes.keys():
            old.attributes[item] = new.attributes[item]
        old.attributes['occi.compute.state'] = 'inactive'


class ComputeBackend(MyBackend):
    '''
45
<<<<<<< HEAD
46
    A Backend for compute instances.
47
=======
48
    Backend for Cyclades/Openstack compute instances
49
>>>>>>> 592e811729d5f061377c854f645311e560ec4faa
50
51
52
53
54
    '''

    def create(self, entity, extras):
    
        for mixin in entity.mixins:
55
<<<<<<< HEAD
56
57
58
59
60
61
62
63
64
65
66
67
68
69
            print mixin.term
            print mixin.attributes
            if mixin.related[0].term == 'os_tpl':
                image = mixin.related[0]
                image_id = mixin.attributes['occi.core.id']
            if mixin.related[0].term == 'resource_tpl':
                flavor = mixin.related[0]
                flavor_id = mixin.attributes['occi.core.id']
                
        
        entity.attributes['occi.compute.state'] = 'active'
        entity.actions = [STOP, SUSPEND, RESTART]

        #TODO VM identifier
70
=======
71
72
            if mixin.related[0].term == 'os_tpl':
                image = mixin
73
                image_id = mixin.attributes['occi.core.id']
74
75
            if mixin.related[0].term == 'resource_tpl':
                flavor = mixin
76
                flavor_id = mixin.attributes['occi.core.id']
77
78
79
80
81
82
                
        entity.attributes['occi.compute.state'] = 'active'
        entity.actions = [STOP, SUSPEND, RESTART]

        #Registry identifier is the uuid key occi.handler assigns
        #attribute 'occi.core.id' will be the snf-server id
83
>>>>>>> 592e811729d5f061377c854f645311e560ec4faa
84
85
86
87
88

        snf = ComputeClient(Config())
        vm_name = entity.attributes['occi.compute.hostname']
        info = snf.create_server(vm_name, flavor_id, image_id)
        entity.attributes['occi.core.id'] = str(info['id'])
89
<<<<<<< HEAD
90
91
92
93

    def retrieve(self, entity, extras):
        # triggering cyclades to retrieve up to date information

94
=======
95
96
        entity.attributes['occi.compute.cores'] = flavor.attributes['occi.compute.cores']
        entity.attributes['occi.compute.memory'] = flavor.attributes['occi.compute.memory']
John Giannelos's avatar
John Giannelos committed
97
98

    def retrieve(self, entity, extras):
99
        
John Giannelos's avatar
John Giannelos committed
100
101
        # triggering cyclades to retrieve up to date information

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
        snf = ComputeClient(Config())

        vm_id = int(entity.attributes['occi.core.id'])
        vm_info = snf.get_server_details(vm_id)
        vm_state = vm_info['status']
        
        status_dict = {'ACTIVE' : 'active',
                       'STOPPED' : 'inactive',
                       'ERROR' : 'inactive',
                       'BUILD' : 'inactive',
                       'DELETED' : 'inactive',
                       }
        
        entity.attributes['occi.compute.state'] = status_dict[vm_state]

117
>>>>>>> 592e811729d5f061377c854f645311e560ec4faa
118
119
120
121
122
123
124
        if entity.attributes['occi.compute.state'] == 'inactive':
            entity.actions = [START]
        if entity.attributes['occi.compute.state'] == 'active': 
            entity.actions = [STOP, SUSPEND, RESTART]
        if entity.attributes['occi.compute.state'] == 'suspended':
            entity.actions = [START]

125
<<<<<<< HEAD
126
127
128
129
    def delete(self, entity, extras):
        # call the management framework to delete this compute instance...
        print('Removing representation of virtual machine with id: '
              + entity.identifier)
130
=======
131
132
133
        


John Giannelos's avatar
John Giannelos committed
134
    def delete(self, entity, extras):
135
136
137
138
139
        # delete vm with vm_id = entity.attributes['occi.core.id']
        snf = ComputeClient(Config())
        vm_id = int(entity.attributes['occi.core.id'])
        snf.delete_server(vm_id)

140
>>>>>>> 592e811729d5f061377c854f645311e560ec4faa
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

    def action(self, entity, action, extras):
        if action not in entity.actions:
            raise AttributeError("This action is currently no applicable.")
        elif action == START:
            entity.attributes['occi.compute.state'] = 'active'
            entity.actions = [STOP, SUSPEND, RESTART]
            # read attributes from action and do something with it :-)
            print('Starting virtual machine with id' + entity.identifier)
        elif action == STOP:
            entity.attributes['occi.compute.state'] = 'inactive'
            entity.actions = [START]
            # read attributes from action and do something with it :-)
            print('Stopping virtual machine with id' + entity.identifier)
        elif action == RESTART:
            entity.actions = [STOP, SUSPEND, RESTART]
            entity.attributes['occi.compute.state'] = 'active'
            # read attributes from action and do something with it :-)
            print('Restarting virtual machine with id' + entity.identifier)
        elif action == SUSPEND:
            entity.attributes['occi.compute.state'] = 'suspended'
            entity.actions = [START]
            # read attributes from action and do something with it :-)
            print('Suspending virtual machine with id' + entity.identifier)


class MyAPP(Application):
    '''
    An OCCI WSGI application.
    '''

    def __call__(self, environ, response):
        sec_obj = {'username': 'password'}

175
<<<<<<< HEAD
176
177
178
179

        #Refresh registry entries with current Cyclades state
        snf = ComputeClient(Config())

180
=======
181
        
182
        #Refresh registry entries with current Cyclades state
183
        snf = ComputeClient(Config())
184

185
        '''
186
>>>>>>> 592e811729d5f061377c854f645311e560ec4faa
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
        images = snf.list_images()
        for image in images:
            IMAGE_ATTRIBUTES = {'occi.core.id': str(image['id'])}
            IMAGE = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(image['name']), [OS_TEMPLATE], attributes = IMAGE_ATTRIBUTES)
            self.register_backend(IMAGE, MixinBackend())

        flavors = snf.list_flavors()
        for flavor in flavors:
            FLAVOR_ATTRIBUTES = {'occi.core.id': flavor['id'],
                                 'occi.compute.cores': snf.get_flavor_details(flavor['id'])['cpu'],
                                 'occi.compute.memory': snf.get_flavor_details(flavor['id'])['ram'],
                                 'occi.storage.size': snf.get_flavor_details(flavor['id'])['disk'],
                                 }
            FLAVOR = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(flavor['name']), [RESOURCE_TEMPLATE], attributes = FLAVOR_ATTRIBUTES)
            self.register_backend(FLAVOR, MixinBackend())
202
<<<<<<< HEAD
203
204
205
        
        #TODO show only current VM instances
                
206
=======
207
208
            '''       

209
        #TODO show only current VM instances
210
>>>>>>> 592e811729d5f061377c854f645311e560ec4faa
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
        
        return self._call_occi(environ, response, security=sec_obj, foo=None)

if __name__ == '__main__':

    APP = MyAPP()

    COMPUTE_BACKEND = ComputeBackend()

    APP.register_backend(COMPUTE, COMPUTE_BACKEND)
    APP.register_backend(START, COMPUTE_BACKEND)
    APP.register_backend(STOP, COMPUTE_BACKEND)
    APP.register_backend(RESTART, COMPUTE_BACKEND)
    APP.register_backend(SUSPEND, COMPUTE_BACKEND)
    APP.register_backend(RESOURCE_TEMPLATE, MixinBackend())
    APP.register_backend(OS_TEMPLATE, MixinBackend())
    
228
229
<<<<<<< HEAD
=======
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
    snf = ComputeClient(Config())
    
    images = snf.list_images()
    for image in images:
        IMAGE_ATTRIBUTES = {'occi.core.id': str(image['id'])}
        IMAGE = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(image['name']), [OS_TEMPLATE], attributes = IMAGE_ATTRIBUTES)
        APP.register_backend(IMAGE, MixinBackend())

    flavors = snf.list_flavors()
    for flavor in flavors:
        FLAVOR_ATTRIBUTES = {'occi.core.id': flavor['id'],
                             'occi.compute.cores': snf.get_flavor_details(flavor['id'])['cpu'],
                             'occi.compute.memory': snf.get_flavor_details(flavor['id'])['ram'],
                             'occi.storage.size': snf.get_flavor_details(flavor['id'])['disk'],
                             }
        FLAVOR = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(flavor['name']), [RESOURCE_TEMPLATE], attributes = FLAVOR_ATTRIBUTES)
        APP.register_backend(FLAVOR, MixinBackend())

248
>>>>>>> 592e811729d5f061377c854f645311e560ec4faa
249
250
251
252
253
 
    VALIDATOR_APP = validator(APP)
    HTTPD = make_server('', 8888, VALIDATOR_APP)
    HTTPD.serve_forever()