3 from snfOCCI.registry import snfRegistry
4 from snfOCCI.compute import ComputeBackend
5 from snfOCCI.network import NetworkBackend, IpNetworkBackend, IpNetworkInterfaceBackend, NetworkInterfaceBackend
7 from snfOCCI.config import SERVER_CONFIG, KAMAKI_CONFIG
9 from kamaki.clients.compute import ComputeClient
10 from kamaki.clients.cyclades import CycladesClient
11 from kamaki.clients import ClientError
13 from occi.core_model import Mixin, Resource
14 from occi.backend import MixinBackend, KindBackend
15 from occi.extensions.infrastructure import COMPUTE, START, STOP, SUSPEND, RESTART, RESOURCE_TEMPLATE, OS_TEMPLATE, NETWORK, IPNETWORK, NETWORKINTERFACE,IPNETWORKINTERFACE
16 from occi.wsgi import Application
17 from occi.exceptions import HTTPError
18 from occi import core_model
20 from wsgiref.simple_server import make_server
21 from wsgiref.validate import validator
24 class MyAPP(Application):
26 An OCCI WSGI application.
29 def refresh_images(self, snf, client):
31 images = snf.list_images()
33 IMAGE_ATTRIBUTES = {'occi.core.id': str(image['id'])}
34 IMAGE = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(image['name']), [OS_TEMPLATE], attributes = IMAGE_ATTRIBUTES)
35 self.register_backend(IMAGE, MixinBackend())
37 def refresh_flavors(self, snf, client):
39 flavors = snf.list_flavors()
40 print "Retrieving details for each image id"
41 for flavor in flavors:
42 details = snf.get_flavor_details(flavor['id'])
43 FLAVOR_ATTRIBUTES = {'occi.core.id': flavor['id'],
44 'occi.compute.cores': str(details['vcpus']),
45 'occi.compute.memory': str(details['ram']),
46 'occi.storage.size': str(details['disk']),
48 FLAVOR = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(flavor['name']), [RESOURCE_TEMPLATE], attributes = FLAVOR_ATTRIBUTES)
49 self.register_backend(FLAVOR, MixinBackend())
51 def refresh_flavors_norecursive(self, snf, client):
52 flavors = snf.list_flavors(True)
53 print "Retrieving details for each image id"
54 for flavor in flavors:
55 # details = snf.get_flavor_details(flavor['id'])
56 FLAVOR_ATTRIBUTES = {'occi.core.id': flavor['id'],
57 'occi.compute.cores': str(flavor['vcpus']),
58 'occi.compute.memory': str(flavor['ram']),
59 'occi.storage.size': str(flavor['disk']),
62 FLAVOR = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(flavor['name']), [RESOURCE_TEMPLATE], attributes = FLAVOR_ATTRIBUTES)
63 self.register_backend(FLAVOR, MixinBackend())
66 def refresh_network_instances(self,client):
67 networks =client.networks_get(command = 'detail')
68 network_details = networks.json['networks']
69 resources = self.registry.resources
70 occi_keys = resources.keys()
72 for network in network_details:
73 if '/network/'+str(network['id']) not in occi_keys:
74 netID = '/network/'+str(network['id'])
75 snf_net = core_model.Resource(netID,
79 snf_net.attributes['occi.core.id'] = str(network['id'])
81 #This info comes from the network details
82 snf_net.attributes['occi.network.state'] = str(network['status'])
83 snf_net.attributes['occi.network.gateway'] = str(network['gateway'])
85 if network['public'] == True:
86 snf_net.attributes['occi.network.type'] = "Public = True"
88 snf_net.attributes['occi.network.type'] = "Public = False"
90 self.registry.add_resource(netID, snf_net, None)
94 def refresh_compute_instances(self, snf, client):
95 '''Syncing registry with cyclades resources'''
97 servers = snf.list_servers()
99 for server in servers:
100 snf_keys.append(str(server['id']))
102 resources = self.registry.resources
103 occi_keys = resources.keys()
105 print resources.keys()
107 for serverID in occi_keys:
108 if '/compute/' in serverID and resources[serverID].attributes['occi.compute.hostname'] == "":
109 self.registry.delete_resource(serverID, None)
111 occi_keys = resources.keys()
114 #Compute instances in synnefo not available in registry
115 diff = [x for x in snf_keys if '/compute/'+x not in occi_keys]
118 details = snf.get_server_details(int(key))
119 flavor = snf.get_flavor_details(details['flavor']['id'])
122 print "line 65:Finished getting image details for VM with ID" + str(details['flavor']['id'])
123 image = snf.get_image_details(details['image']['id'])
125 for i in self.registry.backends:
126 if i.term == str(image['name']):
128 if i.term == str(flavor['name']):
131 resource = Resource(key, COMPUTE, [rel_flavor, rel_image])
132 resource.actions = [START]
133 resource.attributes['occi.core.id'] = key
134 resource.attributes['occi.compute.state'] = 'inactive'
135 resource.attributes['occi.compute.architecture'] = SERVER_CONFIG['compute_arch']
136 resource.attributes['occi.compute.cores'] = str(flavor['vcpus'])
137 resource.attributes['occi.compute.memory'] = str(flavor['ram'])
138 resource.attributes['occi.core.title'] = str(details['name'])
139 networkIDs = details['addresses'].keys()
140 if len(networkIDs)>0:
141 #resource.attributes['occi.compute.hostname'] = SERVER_CONFIG['hostname'] % {'id':int(key)}
142 resource.attributes['occi.compute.hostname'] = str(details['addresses'][networkIDs[0]][0]['addr'])
143 #resource.attributes['occi.networkinterface.address'] = str(details['addresses'][networkIDs[0]][0]['addr'])
145 resource.attributes['occi.compute.hostname'] = ""
147 self.registry.add_resource(key, resource, None)
149 for netKey in networkIDs:
150 link_id = str(uuid.uuid4())
151 NET_LINK = core_model.Link("http://schemas.ogf.org/occi/infrastructure#networkinterface" + link_id,
153 [IPNETWORKINTERFACE], resource,
154 self.registry.resources['/network/'+str(netKey)])
156 for version in details['addresses'][netKey]:
157 if version['version']==4:
158 ip4address = str(version['addr'])
159 allocheme = str(version['OS-EXT-IPS:type'])
160 elif version['version']==6:
161 ip6address = str(version['addr'])
163 if 'attachments' in details.keys():
164 for item in details['attachments']:
165 NET_LINK.attributes ={'occi.core.id':link_id,
166 'occi.networkinterface.allocation' : allocheme,
167 'occi.networking.interface': str(item['id']),
168 'occi.networkinterface.mac' : str(item['mac_address']),
169 'occi.networkinterface.ip4' : ip4address,
170 'occi.networkinterface.ip6' : ip6address
172 elif len(details['addresses'][netKey])>0:
173 NET_LINK.attributes ={'occi.core.id':link_id,
174 'occi.networkinterface.allocation' : allocheme,
175 'occi.networking.interface': '',
176 'occi.networkinterface.mac' : '',
177 'occi.networkinterface.ip4' : ip4address,
178 'occi.networkinterface.ip6' : ip6address
182 NET_LINK.attributes ={'occi.core.id':link_id,
183 'occi.networkinterface.allocation' : '',
184 'occi.networking.interface': '',
185 'occi.networkinterface.mac' : '',
186 'occi.networkinterface.ip4' :'',
187 'occi.networkinterface.ip6' : '' }
189 resource.links.append(NET_LINK)
190 self.registry.add_resource(link_id, NET_LINK, None)
193 except ClientError as ce:
195 print('Image not found, sorry!!!')
200 #Compute instances in registry not available in synnefo
201 diff = [x for x in occi_keys if x[9:] not in snf_keys]
203 if '/network/' not in key:
204 self.registry.delete_resource(key, None)
207 def __call__(self, environ, response):
209 compClient = ComputeClient(KAMAKI_CONFIG['compute_url'], environ['HTTP_AUTH_TOKEN'])
210 cyclClient = CycladesClient(KAMAKI_CONFIG['compute_url'], environ['HTTP_AUTH_TOKEN'])
212 #Up-to-date flavors and images
213 print "@refresh_images"
214 self.refresh_images(compClient,cyclClient)
215 print "@refresh_flavors"
216 self.refresh_flavors_norecursive(compClient,cyclClient)
217 self.refresh_network_instances(cyclClient)
218 print "@refresh_compute_instances"
219 self.refresh_compute_instances(compClient,cyclClient)
221 # token will be represented in self.extras
222 return self._call_occi(environ, response, security = None, token = environ['HTTP_AUTH_TOKEN'], snf = compClient, client = cyclClient)
227 APP = MyAPP(registry = snfRegistry())
228 COMPUTE_BACKEND = ComputeBackend()
229 NETWORK_BACKEND = NetworkBackend()
230 NETWORKINTERFACE_BACKEND = NetworkInterfaceBackend()
231 IPNETWORK_BACKEND = IpNetworkBackend()
232 IPNETWORKINTERFACE_BACKEND = IpNetworkInterfaceBackend()
234 APP.register_backend(COMPUTE, COMPUTE_BACKEND)
235 APP.register_backend(START, COMPUTE_BACKEND)
236 APP.register_backend(STOP, COMPUTE_BACKEND)
237 APP.register_backend(RESTART, COMPUTE_BACKEND)
238 APP.register_backend(SUSPEND, COMPUTE_BACKEND)
239 APP.register_backend(RESOURCE_TEMPLATE, MixinBackend())
240 APP.register_backend(OS_TEMPLATE, MixinBackend())
242 # Network related backends
243 APP.register_backend(NETWORK, NETWORK_BACKEND)
244 APP.register_backend(IPNETWORK, IPNETWORK_BACKEND)
245 APP.register_backend(NETWORKINTERFACE,NETWORKINTERFACE_BACKEND)
246 APP.register_backend(IPNETWORKINTERFACE, IPNETWORKINTERFACE_BACKEND)
248 VALIDATOR_APP = validator(APP)
250 HTTPD = make_server('', SERVER_CONFIG['port'], VALIDATOR_APP)
251 HTTPD.serve_forever()