From: Tony Mack Date: Thu, 30 Jun 2011 04:53:46 +0000 (-0400) Subject: only call get_trusted_certs at sfa aggregates. X-Git-Tag: sfa-1.0-27~52 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=2766cff70df938dc100894220209f8a46acc2a2d;p=sfa.git only call get_trusted_certs at sfa aggregates. --- diff --git a/sfa/init.d/sfa b/sfa/init.d/sfa index b039c242..e2fdb108 100755 --- a/sfa/init.d/sfa +++ b/sfa/init.d/sfa @@ -61,6 +61,9 @@ start() { reload + # install peer certs + action $"SFA installing peer certs" daemon /usr/bin/sfa-server.py -t -d $OPTIONS + if [ "$SFA_REGISTRY_ENABLED" -eq 1 ]; then action $"SFA Registry" daemon /usr/bin/sfa-server.py -r -d $OPTIONS fi diff --git a/sfa/managers/slice_manager_pl.py b/sfa/managers/slice_manager_pl.py index 57d888a4..4ac41a43 100644 --- a/sfa/managers/slice_manager_pl.py +++ b/sfa/managers/slice_manager_pl.py @@ -33,20 +33,11 @@ from sfa.util.version import version_core from sfa.util.callids import Callids -def _get_cached_server_version(api, server): - cache_key = server.url + "-version" - server_version = api.cache.get(cache_key) - if not server_version: - server_version = server.GetVersion() - # cache version for 24 hours - api.cache.add(cache_key, server_version, ttl= 60*60*24) - return server_version - def _call_id_supported(api, server): """ Returns true if server support the optional call_id arg, false otherwise. """ - server_version = _get_cached_server_version(api, server) + server_version = api.get_cached_server_version(server) if 'sfa' in server_version: code_tag = server_version['code_tag'] diff --git a/sfa/server/interface.py b/sfa/server/interface.py index 12a0e4fe..f37331a3 100644 --- a/sfa/server/interface.py +++ b/sfa/server/interface.py @@ -80,107 +80,6 @@ class Interfaces(dict): 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 - 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) - - def get_peer_gids(self, new_hrns): - """ - Install trusted gids from the specified interfaces. - """ - peer_gids = [] - if not new_hrns: - 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_info = self.interfaces[new_hrn] - interface = self[new_hrn] - trusted_gids = interface.get_trusted_certs() - 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) - except: - message = "interface: %s\tunable to install trusted gid for %s" % \ - (self.api.interface, new_hrn) - 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, 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. - """ - # 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, 'pointer': -1}) - hrns_found = [record['hrn'] for record in records] - - # remove old records - for record in records: - if record['hrn'] not in hrns_expected and \ - record['hrn'] != self.api.config.SFA_INTERFACE_HRN: - table.remove(record) - - # add new records - 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), - } - record = SfaRecord(dict=record) - table.insert(record) - def get_connections(self): """ read connection details for the trusted peer registries from file return diff --git a/sfa/server/registry.py b/sfa/server/registry.py index b7bfdd87..da25b2a4 100644 --- a/sfa/server/registry.py +++ b/sfa/server/registry.py @@ -9,8 +9,6 @@ from sfa.util.server import SfaServer from sfa.util.faults import * from sfa.util.xrn import hrn_to_urn from sfa.server.interface import Interfaces -import sfa.util.xmlrpcprotocol as xmlrpcprotocol -import sfa.util.soapprotocol as soapprotocol ## diff --git a/sfa/server/sfa-server.py b/sfa/server/sfa-server.py index c981158b..28a5a612 100755 --- a/sfa/server/sfa-server.py +++ b/sfa/server/sfa-server.py @@ -35,6 +35,7 @@ component_port=12346 import os, os.path import traceback import sys +import sfa.util.xmlrpcprotocol as xmlrpcprotocol from optparse import OptionParser from sfa.util.sfalogging import logger @@ -46,7 +47,8 @@ from sfa.util.config import Config from sfa.plc.api import SfaAPI from sfa.server.registry import Registries from sfa.server.aggregate import Aggregates - +from sfa.util.xrn import get_authority, hrn_to_urn +from sfa.util.sfalogging import logger # after http://www.erlenstar.demon.co.uk/unix/faq_2.html def daemon(): @@ -162,17 +164,101 @@ def init_server(options, config): manager_module = manager_base + ".component_manager_%s" % mgr_type init_manager(manager_module, manager_base) -def sync_interfaces(server_key_file, server_cert_file): +def install_peer_certs(server_key_file, server_cert_file): """ Attempt to 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. api = SfaAPI(key_file = server_key_file, cert_file = server_cert_file) registries = Registries(api) aggregates = Aggregates(api) - registries.sync_interfaces() - aggregates.sync_interfaces() + interfaces = dict(registries.interfaces.items() + aggregates.interfaces.items()) + gids_current = api.auth.trusted_cert_list + hrns_current = [gid.get_hrn() for gid in gids_current] + hrns_expected = interfaces.keys() + new_hrns = set(hrns_expected).difference(hrns_current) + #gids = self.get_peer_gids(new_hrns) + gids_current + peer_gids = [] + if not new_hrns: + return + + trusted_certs_dir = 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 == api.config.SFA_INTERFACE_HRN: continue + try: + # get gid from the registry + url = interfaces[new_hrn]['url'] + interface = xmlrpcprotocol.get_server(url, server_key_file, server_cert_file) + # skip non sfa aggregates + server_version = api.get_cached_server_version(interface) + if 'sfa' not in server_version: + logger.info("get_trusted_certs: skipping non sfa aggregate: %s" % new_hrn) + continue + + trusted_gids = interface.get_trusted_certs() + if trusted_gids: + # the gid we want should be the first one in the list, + # but lets make sure + for trusted_gid in trusted_gids: + # default message + message = "interface: %s\t" % (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 = "installed trusted cert for %s" % new_hrn + # log the message + api.logger.info(message) + except: + message = "interface: %s\tunable to install trusted gid for %s" % \ + (api.interface, new_hrn) + api.logger.log_exc(message) + # doesnt matter witch one + update_cert_records(peer_gids) + +def update_cert_records(gids): + """ + Make sure there is a record in the registry for the specified gids. + Removes old records from the db. + """ + # import SfaTable here so this module can be loaded by ComponentAPI + from sfa.util.table import SfaTable + if not gids: + return + table = SfaTable() + # get records that actually exist in the db + gid_urns = [gid.get_urn() for gid in gids] + hrns_expected = [gid.get_hrn() for gid in gids] + records_found = table.find({'hrn': hrns_expected, 'pointer': -1}) + + # remove old records + for record in records_found: + if record['hrn'] not in hrns_expected and \ + record['hrn'] != self.api.config.SFA_INTERFACE_HRN: + table.remove(record) + # TODO: store urn in the db so we do this in 1 query + for gid in gids: + hrn, type = gid.get_hrn(), gid.get_type() + record = table.find({'hrn': hrn, 'type': type, 'pointer': -1}) + if not record: + record = { + 'hrn': hrn, 'type': type, 'pointer': -1, + 'authority': get_authority(hrn), + 'gid': gid.save_to_string(save_parents=True), + } + record = SfaRecord(dict=record) + table.insert(record) + def main(): # Generate command line parser parser = OptionParser(usage="sfa-server [options]") @@ -184,12 +270,14 @@ def main(): help="run aggregate manager", default=False) parser.add_option("-c", "--component", dest="cm", action="store_true", help="run component server", default=False) + parser.add_option("-t", "--trusted-certs", dest="trusted_certs", action="store_true", + help="refresh trusted certs", default=False) parser.add_option("-v", "--verbose", action="count", dest="verbose", default=0, help="verbose mode - cumulative") parser.add_option("-d", "--daemon", dest="daemon", action="store_true", help="Run as daemon.", default=False) (options, args) = parser.parse_args() - + config = Config() if config.SFA_API_DEBUG: pass hierarchy = Hierarchy() @@ -198,9 +286,12 @@ def main(): init_server_key(server_key_file, server_cert_file, config, hierarchy) init_server(options, config) - sync_interfaces(server_key_file, server_cert_file) if (options.daemon): daemon() + + if options.trusted_certs: + install_peer_certs(server_key_file, server_cert_file) + # start registry server if (options.registry): from sfa.server.registry import Registry diff --git a/sfa/util/api.py b/sfa/util/api.py index 67d155e7..a7333086 100644 --- a/sfa/util/api.py +++ b/sfa/util/api.py @@ -7,11 +7,13 @@ import os import traceback import string import xmlrpclib +import sfa.util.xmlrpcprotocol as xmlrpcprotocol from sfa.util.sfalogging import logger from sfa.trust.auth import Auth from sfa.util.config import * from sfa.util.faults import * +from sfa.util.cache import Cache from sfa.trust.credential import * from sfa.trust.certificate import * @@ -113,12 +115,11 @@ class ManagerWrapper: class BaseAPI: - cache = None protocol = None def __init__(self, config = "/etc/sfa/sfa_config.py", encoding = "utf-8", methods='sfa.methods', peer_cert = None, interface = None, - key_file = None, cert_file = None, cache = cache): + key_file = None, cert_file = None, cache = None): self.encoding = encoding @@ -129,7 +130,6 @@ class BaseAPI: # Better just be documenting the API if config is None: return - # Load configuration self.config = Config(config) self.auth = Auth(peer_cert) @@ -140,6 +140,8 @@ class BaseAPI: self.cert_file = cert_file self.cert = Certificate(filename=self.cert_file) self.cache = cache + if self.cache is None: + self.cache = Cache() self.credential = None self.source = None self.time_format = "%Y-%m-%d %H:%M:%S" @@ -266,3 +268,14 @@ class BaseAPI: raise result return response + + def get_cached_server_version(self, server): + cache_key = server.url + "-version" + server_version = None + if self.cache: + server_version = self.cache.get(cache_key) + if not server_version: + server_version = server.GetVersion() + # cache version for 24 hours + self.cache.add(cache_key, server_version, ttl= 60*60*24) + return server_version