1 from snfOCCI.config import SERVER_CONFIG
3 from kamaki.clients.compute import ComputeClient
4 from kamaki.clients.cyclades import CycladesClient
5 from kamaki.config import Config
7 from occi.backend import ActionBackend, KindBackend
8 from occi.extensions.infrastructure import COMPUTE, START, STOP, SUSPEND, RESTART
9 from occi.exceptions import HTTPError
12 #Compute Backend for snf-occi-server
14 class MyBackend(KindBackend, ActionBackend):
16 # Updating and Replacing compute instances not supported by Cyclades
18 def update(self, old, new, extras):
19 raise AttributeError("This action is currently no applicable.")
21 def replace(self, old, new, extras):
22 raise AttributeError("This action is currently no applicable.")
25 class ComputeBackend(MyBackend):
27 Backend for Cyclades/Openstack compute instances
30 def create(self, entity, extras):
32 #Creating new compute instance
38 for mixin in entity.mixins:
39 if mixin.related[0].term == 'os_tpl':
41 image_id = mixin.attributes['occi.core.id']
42 if mixin.related[0].term == 'resource_tpl':
44 flavor_id = mixin.attributes['occi.core.id']
46 vm_name = entity.attributes['occi.core.title']
47 info = snf.create_server(vm_name, flavor_id, image_id)
49 entity.actions = [START]
50 entity.attributes['occi.compute.state'] = 'inactive'
51 entity.attributes['occi.core.id'] = str(info['id'])
52 entity.attributes['occi.compute.architecture'] = SERVER_CONFIG['compute_arch']
53 entity.attributes['occi.compute.cores'] = flavor.attributes['occi.compute.cores']
54 entity.attributes['occi.compute.memory'] = flavor.attributes['occi.compute.memory']
55 entity.attributes['occi.compute.hostname'] = SERVER_CONFIG['hostname'] % {'id':info['id']}
57 except (UnboundLocalError, KeyError) as e:
58 raise HTTPError(406, 'Missing details about compute instance')
61 def retrieve(self, entity, extras):
63 #Triggering cyclades to retrieve up to date information
67 vm_id = int(entity.attributes['occi.core.id'])
68 vm_info = snf.get_server_details(vm_id)
69 vm_state = vm_info['status']
71 status_dict = {'ACTIVE' : 'active',
72 'STOPPED' : 'inactive',
75 'DELETED' : 'inactive',
78 entity.attributes['occi.compute.state'] = status_dict[vm_state]
80 if vm_state == 'ERROR':
81 raise HTTPError(500, 'ERROR building the compute instance')
84 if entity.attributes['occi.compute.state'] == 'inactive':
85 entity.actions = [START]
86 if entity.attributes['occi.compute.state'] == 'active':
87 entity.actions = [STOP, SUSPEND, RESTART]
90 def delete(self, entity, extras):
92 #Deleting compute instance
95 vm_id = int(entity.attributes['occi.core.id'])
96 snf.delete_server(vm_id)
99 def action(self, entity, action, extras):
101 #Triggering action to compute instances
103 client = extras['client']
106 vm_id = int(entity.attributes['occi.core.id'])
107 vm_info = snf.get_server_details(vm_id)
108 vm_state = vm_info['status']
111 if vm_state == 'ERROR':
112 raise HTTPError(500, 'ERROR building the compute instance')
115 if action not in entity.actions:
116 raise AttributeError("This action is currently no applicable.")
118 elif action == START:
120 client.start_server(vm_id)
124 client.shutdown_server(vm_id)
126 elif action == RESTART:
127 print "Restarting VM"
128 snf.reboot_server(vm_id)
130 elif action == SUSPEND:
131 raise HTTPError(501, "This actions is currently no applicable")