7d2dc977beed7ad3dd32396eb8f922214b65104d
[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     An very simple abstract backend which handles update and replace for
17     attributes. Support for links and mixins would need to added.
18     '''
19
20     # Updating and Replacing compute instances not supported by Cyclades
21
22     def update(self, old, new, extras):
23         raise AttributeError("This action is currently no applicable.")
24
25     def replace(self, old, new, extras):
26         raise AttributeError("This action is currently no applicable.")
27
28
29 class ComputeBackend(MyBackend):
30     '''
31     Backend for Cyclades/Openstack compute instances
32     '''
33
34     def create(self, entity, extras):
35
36         #Creating new compute instance
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         entity.attributes['occi.compute.state'] = 'inactive'
47         entity.actions = [START]
48
49         conf = Config()
50         conf.set('token',extras['token'])
51         snf = ComputeClient(conf)
52
53         vm_name = entity.attributes['occi.compute.hostname']
54         info = snf.create_server(vm_name, flavor_id, image_id)
55         entity.attributes['occi.core.id'] = str(info['id'])
56         entity.attributes['occi.compute.architecture'] = SERVER_CONFIG['compute_arch']
57         entity.attributes['occi.compute.cores'] = flavor.attributes['occi.compute.cores']
58         entity.attributes['occi.compute.memory'] = flavor.attributes['occi.compute.memory']
59         entity.attributes['occi.compute.hostname'] = SERVER_CONFIG['hostname'] % {'id':info['id']}
60
61     def retrieve(self, entity, extras):
62         
63         #Triggering cyclades to retrieve up to date information
64
65         conf = Config()
66         conf.set('token',extras['token'])
67         snf = ComputeClient(conf)
68
69         vm_id = int(entity.attributes['occi.core.id'])
70         vm_info = snf.get_server_details(vm_id)
71         vm_state = vm_info['status']
72         
73         status_dict = {'ACTIVE' : 'active',
74                        'STOPPED' : 'inactive',
75                        'ERROR' : 'inactive',
76                        'BUILD' : 'inactive',
77                        'DELETED' : 'inactive',
78                        }
79         
80         entity.attributes['occi.compute.state'] = status_dict[vm_state]
81                 
82         if vm_state == 'ERROR':
83             raise HTTPError(500, 'ERROR building the compute instance')
84
85         else:
86             if entity.attributes['occi.compute.state'] == 'inactive':
87                 entity.actions = [START]
88             if entity.attributes['occi.compute.state'] == 'active': 
89                 entity.actions = [STOP, SUSPEND, RESTART]
90             if entity.attributes['occi.compute.state'] == 'suspended':
91                 entity.actions = [START]
92
93
94     def delete(self, entity, extras):
95
96         #Deleting compute instance
97
98         conf = Config()
99         conf.set('token',extras['token'])
100         snf = ComputeClient(conf)
101
102         vm_id = int(entity.attributes['occi.core.id'])
103         snf.delete_server(vm_id)
104
105
106     def action(self, entity, action, extras):
107
108         #Triggering action to compute instances
109
110         conf = Config()
111         conf.set('token',extras['token'])
112         client = CycladesClient(conf)
113         snf = ComputeClient(conf)
114
115         vm_id = int(entity.attributes['occi.core.id'])
116         vm_info = snf.get_server_details(vm_id)
117         vm_state = vm_info['status']
118
119
120         if vm_state == 'ERROR':
121             raise HTTPError(500, 'ERROR building the compute instance')
122
123         else:
124             if action not in entity.actions:
125                 raise AttributeError("This action is currently no applicable.")
126             
127             elif action == START:
128                 print "Starting VM"
129                 client.start_server(vm_id)
130                 
131             elif action == STOP:
132                 print "Stopping VM"
133                 client.shutdown_server(vm_id)
134     
135             elif action == RESTART:
136                 print "Restarting VM"
137                 snf.reboot_server(vm_id)
138
139             elif action == SUSPEND:
140                 raise AttributeError("This actions is currently no applicable")