X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fserver%2Finterface.py;h=0804fc1d8535abad1c3541e7dd1acb9b0bb03df7;hb=06b330f0ee047bdb107e43e82b1d7356c876bc15;hp=6ba74fbcef0732edaf30473e78cdf23837d35f8d;hpb=5f78ea7c4804aa5baca5c77afa8c7e52ca2fb072;p=sfa.git diff --git a/sfa/server/interface.py b/sfa/server/interface.py index 6ba74fbc..0804fc1d 100644 --- a/sfa/server/interface.py +++ b/sfa/server/interface.py @@ -3,14 +3,15 @@ ### $URL: https://svn.planet-lab.org/svn/sfa/trunk/sfa/server/interface.py $ # - from sfa.util.faults import * from sfa.util.storage import * +from sfa.util.xrn import get_authority, hrn_to_urn from sfa.trust.gid import GID -from sfa.util.table import SfaTable +from sfa.util.record import SfaRecord +import traceback import sfa.util.xmlrpcprotocol as xmlrpcprotocol import sfa.util.soapprotocol as soapprotocol - + # GeniLight client support is optional try: from egeni.geniLight_client import * @@ -43,119 +44,153 @@ class Interfaces(dict): # defined by the class default_dict = {} - # allowed types - types = ['sa', 'ma'] + types = ['authority'] - def __init__(self, api, conf_file, type): - if type not in self.allowed_types: + def __init__(self, api, conf_file, type='authority'): + if type not in self.types: raise SfaInfaildArgument('Invalid type %s: must be in %s' % (type, self.types)) dict.__init__(self, {}) self.api = api - + self.type = type # load config file - self.interface_info = XmlStorage(conf_file, default_dict) + self.interface_info = XmlStorage(conf_file, self.default_dict) self.interface_info.load() - self.interfaces = self.interface_info.values()[0].values()[0] - if not isinstance(self.interfaces, list): - self.interfaces = [self.interfaces] - + interfaces = self.interface_info.values()[0].values()[0] + if not isinstance(interfaces, list): + interfaces = [self.interfaces] + # set the url and urn + for interface in interfaces: + hrn, address, port = interface['hrn'], interface['addr'], interface['port'] + url = 'http://%(address)s:%(port)s' % locals() + interface['url'] = url + interface['urn'] = hrn_to_urn(hrn, 'authority') + + self.interfaces = {} + required_fields = self.default_fields.keys() + for interface in interfaces: + valid = True + # skp any interface definition that has a null hrn, + # address or port + for field in required_fields: + if field not in interface or not interface[field]: + valid = False + break + if valid: + self.interfaces[interface['hrn']] = interface + + + def sync_interfaces(self): + """ + Install missing trusted gids and db records for our federated + interfaces + """ # Attempt to get any missing peer gids # There should be a gid file in /etc/sfa/trusted_roots for every # peer registry found in in the registries.xml config file. If there # are any missing gids, request a new one from the peer registry. - gids_current = self.api.auth.trusted_cert_list.get_list() - hrns_current = [gid.get_hrn() for gid in gids_found] - hrns_expected = [interface['hrn'] for interfaces in self.interfaces] - new_hrns = set(hrns_current).difference(hrns_expected) + gids_current = self.api.auth.trusted_cert_list + hrns_current = [gid.get_hrn() for gid in gids_current] + hrns_expected = self.interfaces.keys() + new_hrns = set(hrns_expected).difference(hrns_current) + gids = self.get_peer_gids(new_hrns) + gids_current + # make sure there is a record for every gid + self.update_db_records(self.type, gids) - self.get_peer_gids(new_hrns) - - # update the local db records for these registries - self.update_db_records(type) - - # create connections to the registries - self.update(self.get_connections(interfaces)) - def get_peer_gids(self, new_hrns): """ Install trusted gids from the specified interfaces. """ + peer_gids = [] if not new_hrns: - return + return peer_gids trusted_certs_dir = self.api.config.get_trustedroots_dir() for new_hrn in new_hrns: + if not new_hrn: + continue + # the gid for this interface should already be installed + if new_hrn == self.api.config.SFA_INTERFACE_HRN: + continue try: # get gid from the registry - interface = self.get_connections(self.interfaces[new_hrn])[new_hrn] + interface_info = self.interfaces[new_hrn] + interface = self[new_hrn] trusted_gids = interface.get_trusted_certs() - # default message - message = "interface: %s\tunable to install trusted gid for %s" % \ - (self.api.interface, new_hrn) if trusted_gids: # the gid we want shoudl be the first one in the list, # but lets make sure for trusted_gid in trusted_gids: + # default message + message = "interface: %s\t" % (self.api.interface) + message += "unable to install trusted gid for %s" % \ + (new_hrn) gid = GID(string=trusted_gids[0]) + peer_gids.append(gid) if gid.get_hrn() == new_hrn: gid_filename = os.path.join(trusted_certs_dir, '%s.gid' % new_hrn) gid.save_to_file(gid_filename, save_parents=True) message = "interface: %s\tinstalled trusted gid for %s" % \ (self.api.interface, new_hrn) - # log the message - self.api.logger.info(message) + # log the message + self.api.logger.info(message) except: message = "interface: %s\tunable to install trusted gid for %s" % \ (self.api.interface, new_hrn) - self.api.logger.info(message) + self.api.logger.log_exc(message) # reload the trusted certs list self.api.auth.load_trusted_certs() + return peer_gids - def update_db_records(self, type): + def update_db_records(self, type, gids): """ Make sure there is a record in the local db for allowed registries defined in the config file (registries.xml). Removes old records from the db. """ - # get hrns we expect to find - hrns_expected = self.interfaces.keys() + # import SfaTable here so this module can be loaded by ComponentAPI + from sfa.util.table import SfaTable + if not gids: + return + + # hrns that should have a record + hrns_expected = [gid.get_hrn() for gid in gids] # get hrns that actually exist in the db table = SfaTable() - records = table.find({'type': type}) + records = table.find({'type': type, 'pointer': -1}) hrns_found = [record['hrn'] for record in records] - + # remove old records for record in records: - if record['hrn'] not in hrns_expected: + if record['hrn'] not in hrns_expected and \ + record['hrn'] != self.api.config.SFA_INTERFACE_HRN: table.remove(record) # add new records - for hrn in hrns_expected: + for gid in gids: + hrn = gid.get_hrn() if hrn not in hrns_found: record = { 'hrn': hrn, 'type': type, + 'pointer': -1, + 'authority': get_authority(hrn), + 'gid': gid.save_to_string(save_parents=True), } - table.insert(record) + record = SfaRecord(dict=record) + table.insert(record) - - def get_connections(self, interfaces): + def get_connections(self): """ read connection details for the trusted peer registries from file return a dictionary of connections keyed on interface hrn. """ connections = {} required_fields = self.default_fields.keys() - if not isinstance(interfaces, []): - interfaces = [interfaces] - for interface in interfaces: + for interface in self.interfaces.values(): # make sure the required fields are present and not null - for key in required_fields: - if not interface.get(key): - continue - hrn, address, port = interface['hrn'], interface['addr'], interface['port'] - url = 'http://%(address)s:%(port)s' % locals() + + url = interface['url'] # check which client we should use # sfa.util.xmlrpcprotocol is default client_type = 'xmlrpcprotocol' @@ -165,6 +200,6 @@ class Interfaces(dict): client_type = 'geniclientlight' connections[hrn] = GeniClientLight(url, self.api.key_file, self.api.cert_file) else: - connections[hrn] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file) + connections[interface['hrn']] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file) return connections