-import os, os.path
+import os
+import os.path
import datetime
from sfa.util.faults import SfaFault, SfaAPIError, RecordNotFound
from sfa.trust.certificate import Keypair, Certificate
from sfa.trust.credential import Credential
from sfa.trust.rights import determine_rights
-
+from sfa.util.version import version_core
from sfa.server.xmlrpcapi import XmlrpcApi
-
from sfa.client.return_value import ReturnValue
+from sfa.storage.alchemy import alchemy
####################
-class SfaApi (XmlrpcApi):
-
+
+
+class SfaApi (XmlrpcApi):
"""
- An SfaApi instance is a basic xmlrcp service
+ An SfaApi instance is a basic xmlrpc service
augmented with the local cryptographic material and hrn
It also has the notion of its own interface (a string describing
It gets augmented by the generic layer with
(*) an instance of manager (actually a manager module for now)
- (*) which in turn holds an instance of a testbed driver
- For convenience api.manager.driver == api.driver
+ beware that this is shared among all instances of api
+ (*) an instance of a testbed driver
"""
- def __init__ (self, encoding="utf-8", methods='sfa.methods',
- config = "/etc/sfa/sfa_config.py",
- peer_cert = None, interface = None,
- key_file = None, cert_file = None, cache = None):
-
- XmlrpcApi.__init__ (self, encoding)
-
+ def __init__(self, encoding="utf-8", methods='sfa.methods',
+ config="/etc/sfa/sfa_config",
+ peer_cert=None, interface=None,
+ key_file=None, cert_file=None, cache=None):
+
+ XmlrpcApi.__init__(self, encoding)
+
# we may be just be documenting the API
if config is None:
return
# load registries
from sfa.server.registry import Registries
- self.registries = Registries()
+ self.registries = Registries()
# load aggregates
from sfa.server.aggregate import Aggregates
self.aggregates = Aggregates()
-
+
# filled later on by generic/Generic
- self.manager=None
+ self.manager = None
+ self._dbsession = None
def server_proxy(self, interface, cred, timeout=30):
"""
Returns a connection to the specified interface. Use the specified
credential to determine the caller and look for the caller's key/cert
in the registry hierarchy cache.
- """
+ """
from sfa.trust.hierarchy import Hierarchy
if not isinstance(cred, Credential):
cred_obj = Credential(string=cred)
cert_file = auth_info.get_gid_filename()
server = interface.server_proxy(key_file, cert_file, timeout)
return server
-
-
+
+ def dbsession(self):
+ if self._dbsession is None:
+ self._dbsession = alchemy.session()
+ return self._dbsession
+
+ def close_dbsession(self):
+ if self._dbsession is None:
+ return
+ alchemy.close_session(self._dbsession)
+ self._dbsession = None
+
def getCredential(self, minimumExpiration=0):
"""
Return a valid credential for this interface.
type = 'authority'
path = self.config.SFA_DATA_DIR
filename = ".".join([self.interface, self.hrn, type, "cred"])
- cred_filename = os.path.join(path,filename)
+ cred_filename = os.path.join(path, filename)
cred = None
if os.path.isfile(cred_filename):
- cred = Credential(filename = cred_filename)
+ cred = Credential(filename=cred_filename)
# make sure cred isnt expired
if not cred.get_expiration or \
datetime.datetime.utcnow() + datetime.timedelta(seconds=minimumExpiration) < cred.get_expiration():
# get a new credential
if self.interface in ['registry']:
- cred = self._getCredentialRaw()
+ cred = self._getCredentialRaw()
else:
- cred = self._getCredential()
+ cred = self._getCredential()
cred.save_to_file(cred_filename, save_parents=True)
return cred.save_to_string(save_parents=True)
-
def getDelegatedCredential(self, creds):
"""
Attempt to find a credential delegated to us in
the specified list of creds.
"""
from sfa.trust.hierarchy import Hierarchy
- if creds and not isinstance(creds, list):
+ if creds and not isinstance(creds, list):
creds = [creds]
hierarchy = Hierarchy()
-
+
delegated_cred = None
for cred in creds:
- if hierarchy.auth_exists(Credential(string=cred).get_gid_caller().get_hrn()):
+ if hierarchy.auth_exists(Credential(cred=cred).get_gid_caller().get_hrn()):
delegated_cred = cred
break
return delegated_cred
-
+
def _getCredential(self):
"""
Get our credential from a remote registry
"""
from sfa.server.registry import Registries
registries = Registries()
- registry = registries.server_proxy(self.hrn, self.key_file, self.cert_file)
- cert_string=self.cert.save_to_string(save_parents=True)
+ registry = registries.server_proxy(
+ self.hrn, self.key_file, self.cert_file)
+ cert_string = self.cert.save_to_string(save_parents=True)
# get self credential
- self_cred = registry.GetSelfCredential(cert_string, self.hrn, 'authority')
+ self_cred = registry.GetSelfCredential(
+ cert_string, self.hrn, 'authority')
# get credential
cred = registry.GetCredential(self_cred, self.hrn, 'authority')
return Credential(string=cred)
hrn = self.hrn
auth_hrn = self.auth.get_authority(hrn)
-
+
# is this a root or sub authority
if not auth_hrn or hrn == self.config.SFA_INTERFACE_HRN:
auth_hrn = hrn
auth_info = self.auth.get_auth_info(auth_hrn)
- from sfa.storage.alchemy import dbsession
+ # xxx although unlikely we might want to check for a potential leak
+ dbsession = self.dbsession()
from sfa.storage.model import RegRecord
- record = dbsession.query(RegRecord).filter_by(type='authority+sa', hrn=hrn).first()
+ record = dbsession.query(RegRecord).filter_by(
+ type='authority+sa', hrn=hrn).first()
if not record:
raise RecordNotFound(hrn)
type = record.type
object_gid = record.get_gid_object()
- new_cred = Credential(subject = object_gid.get_subject())
+ new_cred = Credential(subject=object_gid.get_subject())
new_cred.set_gid_caller(object_gid)
new_cred.set_gid_object(object_gid)
- new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
-
+ new_cred.set_issuer_keys(
+ auth_info.get_privkey_filename(), auth_info.get_gid_filename())
+
r1 = determine_rights(type, hrn)
new_cred.set_privileges(r1)
new_cred.encode()
new_cred.sign()
return new_cred
-
- def loadCredential (self):
+
+ def loadCredential(self):
"""
Attempt to load credential from file if it exists. If it doesnt get
credential from registry.
# XX This is really the aggregate's credential. Using this is easier than getting
# the registry's credential from iteslf (ssl errors).
filename = self.interface + self.hrn + ".ma.cred"
- ma_cred_path = os.path.join(self.config.SFA_DATA_DIR,filename)
+ ma_cred_path = os.path.join(self.config.SFA_DATA_DIR, filename)
try:
- self.credential = Credential(filename = ma_cred_path)
+ self.credential = Credential(filename=ma_cred_path)
except IOError:
self.credential = self.getCredentialFromRegistry()
result = server.GetVersion()
server_version = ReturnValue.get_value(result)
# cache version for 24 hours
- self.cache.add(cache_key, server_version, ttl= 60*60*24)
+ self.cache.add(cache_key, server_version, ttl=60 * 60 * 24)
return server_version
-
def get_geni_code(self, result):
code = {
- 'geni_code': GENICODE.SUCCESS,
+ 'geni_code': GENICODE.SUCCESS,
'am_type': 'sfa',
'am_code': None,
}
if isinstance(result, SfaFault):
code['geni_code'] = result.faultCode
- code['am_code'] = result.faultCode
-
+ code['am_code'] = result.faultCode
+
return code
def get_geni_value(self, result):
def get_geni_output(self, result):
output = ""
if isinstance(result, SfaFault):
- output = result.faultString
+ output = result.faultString
return output
- def prepare_response_v2_am(self, result):
+ def prepare_response_am(self, result):
+ version = version_core()
response = {
- 'geni_api': 2,
+ 'geni_api': 3,
'code': self.get_geni_code(result),
'value': self.get_geni_value(result),
'output': self.get_geni_output(result),
}
return response
-
+
def prepare_response(self, result, method=""):
"""
Converts the specified result into a standard GENI compliant
response
"""
# as of dec 13 2011 we only support API v2
- if self.interface.lower() in ['aggregate', 'slicemgr']:
- result = self.prepare_response_v2_am(result)
+ if self.interface.lower() in ['aggregate', 'slicemgr']:
+ result = self.prepare_response_am(result)
return XmlrpcApi.prepare_response(self, result, method)
-