7 from snfOCCI.registry import snfRegistry
8 from snfOCCI.compute import ComputeBackend
9 from snfOCCI.config import SERVER_CONFIG, KAMAKI_CONFIG
11 from kamaki.clients.compute import ComputeClient
12 from kamaki.clients.cyclades import CycladesClient
13 from kamaki.config import Config
15 from occi.core_model import Mixin, Resource
16 from occi.backend import MixinBackend
17 from occi.extensions.infrastructure import COMPUTE, START, STOP, SUSPEND, RESTART, RESOURCE_TEMPLATE, OS_TEMPLATE
18 from occi.wsgi import Application
19 from occi.exceptions import HTTPError
21 from wsgiref.simple_server import make_server
22 from wsgiref.validate import validator
27 conn = sqlite3.connect('/home/nemo/myWorkspace/snf-occi/snfOCCI/voms.db')
29 class MyAPP(Application):
31 An OCCI WSGI application.
34 def refresh_images(self, snf, client):
36 images = snf.list_images()
38 IMAGE_ATTRIBUTES = {'occi.core.id': str(image['id'])}
39 IMAGE = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(image['name']), [OS_TEMPLATE], attributes = IMAGE_ATTRIBUTES)
40 self.register_backend(IMAGE, MixinBackend())
42 def refresh_flavors(self, snf, client):
44 flavors = snf.list_flavors()
45 for flavor in flavors:
46 details = snf.get_flavor_details(flavor['id'])
47 FLAVOR_ATTRIBUTES = {'occi.core.id': flavor['id'],
48 'occi.compute.cores': details['cpu'],
49 'occi.compute.memory': details['ram'],
50 'occi.storage.size': details['disk'],
52 FLAVOR = Mixin("http://schemas.ogf.org/occi/infrastructure#", str(flavor['name']), [RESOURCE_TEMPLATE], attributes = FLAVOR_ATTRIBUTES)
53 self.register_backend(FLAVOR, MixinBackend())
56 def refresh_compute_instances(self, snf):
57 '''Syncing registry with cyclades resources'''
59 servers = snf.list_servers()
61 for server in servers:
62 snf_keys.append(str(server['id']))
64 resources = self.registry.resources
65 occi_keys = resources.keys()
67 #Compute instances in synnefo not available in registry
68 diff = [x for x in snf_keys if '/compute/'+x not in occi_keys]
71 details = snf.get_server_details(int(key))
72 flavor = snf.get_flavor_details(details['flavorRef'])
73 image = snf.get_image_details(details['imageRef'])
75 for i in self.registry.backends:
76 if i.term == str(image['name']):
78 if i.term == str(flavor['name']):
81 resource = Resource(key, COMPUTE, [rel_flavor, rel_image])
82 resource.actions = [START]
83 resource.attributes['occi.core.id'] = key
84 resource.attributes['occi.compute.state'] = 'inactive'
85 resource.attributes['occi.compute.architecture'] = SERVER_CONFIG['compute_arch']
86 resource.attributes['occi.compute.cores'] = flavor['cpu']
87 resource.attributes['occi.compute.memory'] = flavor['ram']
88 resource.attributes['occi.compute.hostname'] = SERVER_CONFIG['hostname'] % {'id':int(key)}
90 self.registry.add_resource(key, resource, None)
92 #Compute instances in registry not available in synnefo
93 diff = [x for x in occi_keys if x[9:] not in snf_keys]
95 self.registry.delete_resource(key, None)
98 def __call__(self, environ, response):
104 #Regular expression in HTTP headers
105 #raw environ[HTTP_SSL] contains PEM certificates in wrong format
107 pem_re = r'^(-----BEGIN CERTIFICATE----- )(.*|\s]*)( -----END CERTIFICATE-----)'
109 client_cert = re.search(pem_re, environ["HTTP_SSL_CLIENT_CERT"])
110 client_chain = re.search(pem_re, environ["HTTP_SSL_CLIENT_CERT_CHAIN_0"])
116 client_cert_list.append(string.strip(client_cert.group(i)))
119 client_chain_list.append(string.strip(client_chain.group(i)))
122 cert = client_cert_list[0]+"\n"+client_cert_list[1].replace(" "," \n")+"\n"+client_cert_list[2]
123 chain = client_chain_list[0]+"\n"+client_chain_list[1].replace(" "," \n")+"\n"+client_chain_list[2]
125 ssl_dict["SSL_CLIENT_S_DN"] = environ["HTTP_SSL_CLIENT_S_DN"]
126 ssl_dict["SSL_CLIENT_CERT"] = cert
127 ssl_dict["SSL_CLIENT_CERT_CHAIN_0"] = chain
129 (user_dn, user_vo, user_fqans) = voms.authenticate(ssl_dict)
130 print (user_dn, user_vo, user_fqans)
133 cursor = conn.cursor()
134 query = "SELECT token FROM vo_map WHERE vo_name=?"
135 cursor.execute(query,[(user_vo)])
137 (token,) = cursor.fetchone()
140 compClient = ComputeClient(KAMAKI_CONFIG['compute_url'], token)
141 cyclClient = CycladesClient(KAMAKI_CONFIG['compute_url'], token)
143 self.refresh_images(compClient,cyclClient)
144 self.refresh_flavors(compClient,cyclClient)
145 self.refresh_compute_instances(compClient)
148 return self._call_occi(environ, response, security = None, token = token, snf = compClient, client = cyclClient)
150 raise HTTPError(404, "Unauthorized access")
156 APP = MyAPP(registry = snfRegistry())
157 COMPUTE_BACKEND = ComputeBackend()
159 APP.register_backend(COMPUTE, COMPUTE_BACKEND)
160 APP.register_backend(START, COMPUTE_BACKEND)
161 APP.register_backend(STOP, COMPUTE_BACKEND)
162 APP.register_backend(RESTART, COMPUTE_BACKEND)
163 APP.register_backend(SUSPEND, COMPUTE_BACKEND)
164 APP.register_backend(RESOURCE_TEMPLATE, MixinBackend())
165 APP.register_backend(OS_TEMPLATE, MixinBackend())
167 VALIDATOR_APP = validator(APP)
168 HTTPD = make_server('', SERVER_CONFIG['port'], VALIDATOR_APP)
169 HTTPD.serve_forever()