3 # PlanetLab SFA implementation
5 # This implements the SFA Registry and Slice Interfaces on PLC.
6 # Depending on command line options, it starts some combination of a
7 # Registry, an Aggregate Manager, and a Slice Manager.
9 # There are several items that need to be done before starting the servers.
11 # NOTE: Many configuration settings, including the PLC maintenance account
12 # credentials, URI of the PLCAPI, and PLC DB URI and admin credentials are initialized
13 # from your MyPLC configuration (/etc/planetlab/plc_config*). Please make sure this information
14 # is up to date and accurate.
16 # 1) Import the existing planetlab database, creating the
17 # appropriate SFA records. This is done by running the "sfa-import.py" tool.
19 # 2) Create a "trusted_roots" directory and place the certificate of the root
20 # authority in that directory. Given the defaults in sfa-import-plc.py, this
21 # certificate would be named "planetlab.gid". For example,
23 # mkdir trusted_roots; cp authorities/planetlab.gid trusted_roots/
25 # TODO: Can all three servers use the same "registry" certificate?
32 from optparse import OptionParser
34 from sfa.util.sfalogging import init_logger, logger
35 from sfa.util.xrn import get_authority, hrn_to_urn
36 from sfa.util.config import Config
38 from sfa.trust.gid import GID
39 from sfa.trust.trustedroots import TrustedRoots
40 from sfa.trust.certificate import Keypair, Certificate
41 from sfa.trust.hierarchy import Hierarchy
42 from sfa.trust.gid import GID
44 from sfa.server.sfaapi import SfaApi
45 from sfa.server.registry import Registries
46 from sfa.server.aggregate import Aggregates
48 from sfa.client.return_value import ReturnValue
53 Daemonize the current process.
54 after http://www.erlenstar.demon.co.uk/unix/faq_2.html
62 devnull = os.open(os.devnull, os.O_RDWR)
64 # xxx fixme - this is just to make sure that nothing gets stupidly lost -
66 logdir = '/var/log/httpd'
67 # when installed in standalone we might not have httpd installed
68 if not os.path.isdir(logdir):
69 os.mkdir('/var/log/httpd')
70 crashlog = os.open('%s/sfa_access_log' % logdir,
71 os.O_RDWR | os.O_APPEND | os.O_CREAT, 0644)
76 def install_peer_certs(server_key_file, server_cert_file):
78 Attempt to install missing trusted gids and db records for
79 our federated interfaces
81 # Attempt to get any missing peer gids
82 # There should be a gid file in /etc/sfa/trusted_roots for every
83 # peer registry found in in the registries.xml config file. If there
84 # are any missing gids, request a new one from the peer registry.
85 api = SfaApi(key_file=server_key_file, cert_file=server_cert_file)
86 registries = Registries()
87 aggregates = Aggregates()
88 interfaces = dict(registries.items() + aggregates.items())
89 gids_current = api.auth.trusted_cert_list
90 hrns_current = [gid.get_hrn() for gid in gids_current]
91 hrns_expected = set([hrn for hrn in interfaces])
92 new_hrns = set(hrns_expected).difference(hrns_current)
93 #gids = self.get_peer_gids(new_hrns) + gids_current
98 trusted_certs_dir = api.config.get_trustedroots_dir()
99 for new_hrn in new_hrns:
102 # the gid for this interface should already be installed
103 if new_hrn == api.config.SFA_INTERFACE_HRN:
106 # get gid from the registry
107 url = interfaces[new_hrn].get_url()
108 interface = interfaces[new_hrn].server_proxy(
109 server_key_file, server_cert_file, timeout=30)
110 # skip non sfa aggregates
111 server_version = api.get_cached_server_version(interface)
112 if 'sfa' not in server_version:
114 "get_trusted_certs: skipping non sfa aggregate: %s" % new_hrn)
117 trusted_gids = ReturnValue.get_value(interface.get_trusted_certs())
119 # the gid we want should be the first one in the list,
121 for trusted_gid in trusted_gids:
123 message = "interface: %s\t" % (api.interface)
124 message += "unable to install trusted gid for %s" % \
126 gid = GID(string=trusted_gid)
127 peer_gids.append(gid)
128 if gid.get_hrn() == new_hrn:
129 gid_filename = os.path.join(
130 trusted_certs_dir, '%s.gid' % new_hrn)
131 gid.save_to_file(gid_filename, save_parents=True)
132 message = "installed trusted cert for %s" % new_hrn
136 message = "interface: %s\tunable to install trusted gid for %s" % \
137 (api.interface, new_hrn)
138 logger.log_exc(message)
139 # doesnt matter witch one
140 update_cert_records(peer_gids)
143 def update_cert_records(gids):
145 Make sure there is a record in the registry for the specified gids.
146 Removes old records from the db.
148 # import db stuff here here so this module can be loaded by PlcComponentApi
149 from sfa.storage.alchemy import global_dbsession
150 from sfa.storage.model import RegRecord
151 dbsession = global_dbsession
154 # get records that actually exist in the db
155 gid_urns = [gid.get_urn() for gid in gids]
156 hrns_expected = [gid.get_hrn() for gid in gids]
157 records_found = dbsession.query(RegRecord).\
158 filter_by(pointer=-1).filter(RegRecord.hrn.in_(hrns_expected)).all()
161 for record in records_found:
162 if record.hrn not in hrns_expected and \
163 record.hrn != self.api.config.SFA_INTERFACE_HRN:
164 dbsession.delete(record)
166 # TODO: store urn in the db so we do this in 1 query
168 hrn, type = gid.get_hrn(), gid.get_type()
169 record = dbsession.query(RegRecord).filter_by(
170 hrn=hrn, type=type, pointer=-1).first()
175 'authority': get_authority(hrn),
176 'gid': gid.save_to_string(save_parents=True),
178 dbsession.add(record)
183 # Generate command line parser
184 parser = OptionParser(usage="sfa-start.py [options]")
185 parser.add_option("-r", "--registry", dest="registry", action="store_true",
186 help="run registry server", default=False)
187 parser.add_option("-a", "--aggregate", dest="am", action="store_true",
188 help="run aggregate manager", default=False)
189 parser.add_option("-t", "--trusted-certs",
190 dest="trusted_certs", action="store_true",
191 help="refresh trusted certs", default=False)
192 parser.add_option("-d", "--daemon", dest="daemon", action="store_true",
193 help="Run as daemon.", default=False)
194 (options, args) = parser.parse_args()
197 init_logger('server')
198 logger.setLevelFromOptVerbose(config.SFA_API_LOGLEVEL)
200 # ge the server's key and cert
201 hierarchy = Hierarchy()
202 auth_info = hierarchy.get_interface_auth_info()
203 server_key_file = auth_info.get_privkey_filename()
204 server_cert_file = auth_info.get_gid_filename()
206 # ensure interface cert is present in trusted roots dir
207 trusted_roots = TrustedRoots(config.get_trustedroots_dir())
208 trusted_roots.add_gid(GID(filename=server_cert_file))
212 if options.trusted_certs:
213 install_peer_certs(server_key_file, server_cert_file)
215 # start registry server
216 if (options.registry):
217 from sfa.server.registry import Registry
218 r = Registry("", config.SFA_REGISTRY_PORT,
219 server_key_file, server_cert_file)
223 from sfa.server.aggregate import Aggregate
224 a = Aggregate("", config.SFA_AGGREGATE_PORT,
225 server_key_file, server_cert_file)
228 if __name__ == "__main__":
232 logger.log_exc("SFA server is exiting")