From d0ea08cc6ac4e507e2265bdbf97fb4b248a17aa5 Mon Sep 17 00:00:00 2001 From: John Giannelos Date: Fri, 20 Apr 2012 16:10:01 +0300 Subject: [PATCH 1/1] API registry still not working --- snf-occi-server.py | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100755 snf-occi-server.py diff --git a/snf-occi-server.py b/snf-occi-server.py new file mode 100755 index 0000000..a46b117 --- /dev/null +++ b/snf-occi-server.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python + +from kamaki.clients.compute import ComputeClient +from kamaki.config import Config + +from occi.core_model import Mixin +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): + ''' + A Backend for compute instances. + ''' + + def create(self, entity, extras): + + for mixin in entity.mixins: + 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 + + 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']) + + def retrieve(self, entity, extras): + # triggering cyclades to retrieve up to date information + + 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] + + def delete(self, entity, extras): + # call the management framework to delete this compute instance... + print('Removing representation of virtual machine with id: ' + + entity.identifier) + + 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'} + + + #Refresh registry entries with current Cyclades state + 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) + 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()) + + #TODO show only current VM instances + + + 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()) + + + VALIDATOR_APP = validator(APP) + HTTPD = make_server('', 8888, VALIDATOR_APP) + HTTPD.serve_forever() + -- 1.7.10.4