#!/usr/bin/env python
+import re
+import string
from snfOCCI.registry import snfRegistry
from snfOCCI.compute import ComputeBackend
-from snfOCCI.config import SERVER_CONFIG
+from snfOCCI.config import SERVER_CONFIG, KAMAKI_CONFIG
from kamaki.clients.compute import ComputeClient
from kamaki.clients.cyclades import CycladesClient
from occi.backend import MixinBackend
from occi.extensions.infrastructure import COMPUTE, START, STOP, SUSPEND, RESTART, RESOURCE_TEMPLATE, OS_TEMPLATE
from occi.wsgi import Application
+from occi.exceptions import HTTPError
from wsgiref.simple_server import make_server
from wsgiref.validate import validator
-
+import voms
class MyAPP(Application):
def refresh_compute_instances(self, snf):
-
+ '''Syncing registry with cyclades resources'''
+
servers = snf.list_servers()
snf_keys = []
for server in servers:
resources = self.registry.resources
occi_keys = resources.keys()
+ #Compute instances in synnefo not available in registry
diff = [x for x in snf_keys if '/compute/'+x not in occi_keys]
-
for key in diff:
details = snf.get_server_details(int(key))
flavor = snf.get_flavor_details(details['flavorRef'])
+ image = snf.get_image_details(details['imageRef'])
- resource = Resource(key, COMPUTE, [])
+ for i in self.registry.backends:
+ if i.term == str(image['name']):
+ rel_image = i
+ if i.term == str(flavor['name']):
+ rel_flavor = i
+ resource = Resource(key, COMPUTE, [rel_flavor, rel_image])
resource.actions = [START]
- resource.attribute = {}
resource.attributes['occi.core.id'] = key
resource.attributes['occi.compute.state'] = 'inactive'
resource.attributes['occi.compute.architecture'] = SERVER_CONFIG['compute_arch']
resource.attributes['occi.compute.cores'] = flavor['cpu']
resource.attributes['occi.compute.memory'] = flavor['ram']
resource.attributes['occi.compute.hostname'] = SERVER_CONFIG['hostname'] % {'id':int(key)}
-
+
self.registry.add_resource(key, resource, None)
+ #Compute instances in registry not available in synnefo
+ diff = [x for x in occi_keys if x[9:] not in snf_keys]
+ for key in diff:
+ self.registry.delete_resource(key, None)
+
+
def __call__(self, environ, response):
- conf = Config()
- conf.set('compute_token',environ['HTTP_AUTH_TOKEN'])
- compClient = ComputeClient(conf)
- cyclClient = CycladesClient(conf)
+ compClient = ComputeClient(KAMAKI_CONFIG['compute_url'], environ['HTTP_AUTH_TOKEN'])
+ cyclClient = CycladesClient(KAMAKI_CONFIG['compute_url'], environ['HTTP_AUTH_TOKEN'])
#Up-to-date flavors and images
+ self.refresh_images(compClient,cyclClient)
+ self.refresh_flavors(compClient,cyclClient)
self.refresh_compute_instances(compClient)
- self.refresh_images(compClient, cyclClient)
- self.refresh_flavors(compClient, cyclClient)
- # token will be represented in self.extras
- return self._call_occi(environ, response, security = None, token = environ['HTTP_AUTH_TOKEN'], snf = compClient, client = cyclClient)
+ ssl_dict = dict()
+
+ #Regular expression in HTTP headers
+ #environ[HTTP_SSL] contains PEM certificates in wrong format
+
+ pem_re = r'^(-----BEGIN CERTIFICATE----- )(.*|\s]*)( -----END CERTIFICATE-----)'
+
+ client_cert = re.search(pem_re, environ["HTTP_SSL_CLIENT_CERT"])
+ client_chain = re.search(pem_re, environ["HTTP_SSL_CLIENT_CERT_CHAIN_0"])
+
+ client_cert_list=[]
+ client_chain_list=[]
+
+ for i in range(1,4):
+ client_cert_list.append(string.strip(client_cert.group(i)))
+
+ for i in range(1,4):
+ client_chain_list.append(string.strip(client_chain.group(i)))
+
+
+ cert = client_cert_list[0]+"\n"+client_cert_list[1].replace(" "," \n")+"\n"+client_cert_list[2]
+ chain = client_chain_list[0]+"\n"+client_chain_list[1].replace(" "," \n")+"\n"+client_chain_list[2]
+
+ ssl_dict["SSL_CLIENT_S_DN"] = environ["HTTP_SSL_CLIENT_S_DN"]
+ ssl_dict["SSL_CLIENT_CERT"] = cert
+ ssl_dict["SSL_CLIENT_CERT_CHAIN_0"] = chain
+
+ (user_dn, user_vo, user_fqans) = voms.authenticate(ssl_dict)
+ print (user_dn, user_vo, user_fqans)
+
+
+ #Authenticate only VOs in list
+ VOs = ['see','fedcloud.egi.eu']
+ #Always authenticated, only for testing purposes
+
+ authenticated = False
+
+ if user_vo in VOs:
+ authenticated = True
+
+ if authenticated:
+ # token will be represented in self.extras
+ return self._call_occi(environ, response, security = None, token = environ['HTTP_AUTH_TOKEN'], snf = compClient, client = cyclClient)
+ else:
+ raise HTTPError(404, "Unauthorized access")
def main():