2810594a928f3d8edbc6753e7cb3355474cd2f09
[snf-occi] / snfOCCI / compute.py
1 from snfOCCI.config import SERVER_CONFIG
2
3 from kamaki.clients.compute import ComputeClient
4 from kamaki.clients.cyclades import CycladesClient
5 from kamaki.config  import Config
6
7 from occi.backend import ActionBackend, KindBackend
8 from occi.extensions.infrastructure import COMPUTE, START, STOP, SUSPEND, RESTART
9 from occi.exceptions import HTTPError
10
11
12 #Compute Backend for snf-occi-server
13
14 class MyBackend(KindBackend, ActionBackend):
15
16     # Updating and Replacing compute instances not supported by Cyclades
17
18     def update(self, old, new, extras):
19         raise AttributeError("This action is currently no applicable.")
20
21     def replace(self, old, new, extras):
22         raise AttributeError("This action is currently no applicable.")
23
24
25 class ComputeBackend(MyBackend):
26     '''
27     Backend for Cyclades/Openstack compute instances
28     '''
29
30     def create(self, entity, extras):
31
32         #Creating new compute instance
33         
34         try:
35
36             snf = extras['snf']
37
38             for mixin in entity.mixins:
39                 if mixin.related[0].term == 'os_tpl':
40                     image = mixin
41                     image_id = mixin.attributes['occi.core.id']
42                 if mixin.related[0].term == 'resource_tpl':
43                     flavor = mixin
44                     flavor_id = mixin.attributes['occi.core.id']
45
46             vm_name = entity.attributes['occi.core.title']
47             info = snf.create_server(vm_name, flavor_id, image_id)
48
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']}
56
57         except (UnboundLocalError, KeyError) as e:
58             raise HTTPError(406, 'Missing details about compute instance')
59             
60
61     def retrieve(self, entity, extras):
62         
63         #Triggering cyclades to retrieve up to date information
64
65         snf = extras['snf']
66
67         vm_id = int(entity.attributes['occi.core.id'])
68         vm_info = snf.get_server_details(vm_id)
69         vm_state = vm_info['status']
70         
71         status_dict = {'ACTIVE' : 'active',
72                        'STOPPED' : 'inactive',
73                        'ERROR' : 'inactive',
74                        'BUILD' : 'inactive',
75                        'DELETED' : 'inactive',
76                        }
77         
78         entity.attributes['occi.compute.state'] = status_dict[vm_state]
79                 
80         if vm_state == 'ERROR':
81             raise HTTPError(500, 'ERROR building the compute instance')
82
83         else:
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]
88
89
90     def delete(self, entity, extras):
91
92         #Deleting compute instance
93
94         snf = extras['snf']
95         vm_id = int(entity.attributes['occi.core.id'])
96         snf.delete_server(vm_id)
97
98
99     def action(self, entity, action, extras):
100
101         #Triggering action to compute instances
102
103         client = extras['client']
104         snf = extras['snf']
105
106         vm_id = int(entity.attributes['occi.core.id'])
107         vm_info = snf.get_server_details(vm_id)
108         vm_state = vm_info['status']
109
110
111         if vm_state == 'ERROR':
112             raise HTTPError(500, 'ERROR building the compute instance')
113
114         else:
115             if action not in entity.actions:
116                 raise AttributeError("This action is currently no applicable.")
117             
118             elif action == START:
119                 print "Starting VM"
120                 client.start_server(vm_id)
121                 
122             elif action == STOP:
123                 print "Stopping VM"
124                 client.shutdown_server(vm_id)
125     
126             elif action == RESTART:
127                 print "Restarting VM"
128                 snf.reboot_server(vm_id)
129
130             elif action == SUSPEND:
131                 raise HTTPError(501, "This actions is currently no applicable")