2 # now that logs are managed through stdout and journalctl,
3 # it is important to run with -u so that they show up quickly
4 # and don't get buffered
6 # PlanetLab SFA implementation
8 # This implements the SFA Registry and Slice Interfaces on PLC.
9 # Depending on command line options, it starts some combination of a
10 # Registry, an Aggregate Manager, and a Slice Manager.
12 # There are several items that need to be done before starting the servers.
14 # NOTE: Many configuration settings, including the PLC maintenance account
15 # credentials, URI of the PLCAPI, and PLC DB URI and admin credentials are initialized
16 # from your MyPLC configuration (/etc/planetlab/plc_config*). Please make sure this information
17 # is up to date and accurate.
19 # 1) Import the existing planetlab database, creating the
20 # appropriate SFA records. This is done by running the "sfa-import.py" tool.
22 # 2) Create a "trusted_roots" directory and place the certificate of the root
23 # authority in that directory. Given the defaults in sfa-import-plc.py, this
24 # certificate would be named "planetlab.gid". For example,
26 # mkdir trusted_roots; cp authorities/planetlab.gid trusted_roots/
28 # TODO: Can all three servers use the same "registry" certificate?
35 from optparse import OptionParser
37 from sfa.util.sfalogging import init_logger, logger
38 from sfa.util.xrn import get_authority, hrn_to_urn
39 from sfa.util.config import Config
41 from sfa.trust.gid import GID
42 from sfa.trust.trustedroots import TrustedRoots
43 from sfa.trust.certificate import Keypair, Certificate
44 from sfa.trust.hierarchy import Hierarchy
45 from sfa.trust.gid import GID
47 from sfa.server.sfaapi import SfaApi
48 from sfa.server.registry import Registries
49 from sfa.server.aggregate import Aggregates
51 from sfa.client.return_value import ReturnValue
54 def install_peer_certs(server_key_file, server_cert_file):
56 Attempt to install missing trusted gids and db records for
57 our federated interfaces
59 # Attempt to get any missing peer gids
60 # There should be a gid file in /etc/sfa/trusted_roots for every
61 # peer registry found in in the registries.xml config file. If there
62 # are any missing gids, request a new one from the peer registry.
63 api = SfaApi(key_file=server_key_file, cert_file=server_cert_file)
64 registries = Registries()
65 aggregates = Aggregates()
66 interfaces = dict(list(registries.items()) + list(aggregates.items()))
67 gids_current = api.auth.trusted_cert_list
68 hrns_current = [gid.get_hrn() for gid in gids_current]
69 hrns_expected = set([hrn for hrn in interfaces])
70 new_hrns = set(hrns_expected).difference(hrns_current)
71 #gids = self.get_peer_gids(new_hrns) + gids_current
76 trusted_certs_dir = api.config.get_trustedroots_dir()
77 for new_hrn in new_hrns:
80 # the gid for this interface should already be installed
81 if new_hrn == api.config.SFA_INTERFACE_HRN:
84 # get gid from the registry
85 url = interfaces[new_hrn].get_url()
86 interface = interfaces[new_hrn].server_proxy(
87 server_key_file, server_cert_file, timeout=30)
88 # skip non sfa aggregates
89 server_version = api.get_cached_server_version(interface)
90 if 'sfa' not in server_version:
92 "get_trusted_certs: skipping non sfa aggregate: %s" % new_hrn)
95 trusted_gids = ReturnValue.get_value(interface.get_trusted_certs())
97 # the gid we want should be the first one in the list,
99 for trusted_gid in trusted_gids:
101 message = "interface: %s\t" % (api.interface)
102 message += "unable to install trusted gid for %s" % \
104 gid = GID(string=trusted_gid)
105 peer_gids.append(gid)
106 if gid.get_hrn() == new_hrn:
107 gid_filename = os.path.join(
108 trusted_certs_dir, '%s.gid' % new_hrn)
109 gid.save_to_file(gid_filename, save_parents=True)
110 message = "installed trusted cert for %s" % new_hrn
114 message = "interface: %s\tunable to install trusted gid for %s" % \
115 (api.interface, new_hrn)
116 logger.log_exc(message)
117 # doesnt matter witch one
118 update_cert_records(peer_gids)
121 def update_cert_records(gids):
123 Make sure there is a record in the registry for the specified gids.
124 Removes old records from the db.
126 # import db stuff here here so this module can be loaded by PlcComponentApi
127 from sfa.storage.alchemy import global_dbsession
128 from sfa.storage.model import RegRecord
129 dbsession = global_dbsession
132 # get records that actually exist in the db
133 gid_urns = [gid.get_urn() for gid in gids]
134 hrns_expected = [gid.get_hrn() for gid in gids]
135 records_found = dbsession.query(RegRecord).\
136 filter_by(pointer=-1).filter(RegRecord.hrn.in_(hrns_expected)).all()
139 for record in records_found:
140 if record.hrn not in hrns_expected and \
141 record.hrn != self.api.config.SFA_INTERFACE_HRN:
142 dbsession.delete(record)
144 # TODO: store urn in the db so we do this in 1 query
146 hrn, type = gid.get_hrn(), gid.get_type()
147 record = dbsession.query(RegRecord).filter_by(
148 hrn=hrn, type=type, pointer=-1).first()
153 'authority': get_authority(hrn),
154 'gid': gid.save_to_string(save_parents=True),
156 dbsession.add(record)
161 # Generate command line parser
162 parser = OptionParser(usage="sfa-start.py [options]")
163 parser.add_option("-r", "--registry", dest="registry", action="store_true",
164 help="run registry server", default=False)
165 parser.add_option("-a", "--aggregate", dest="am", action="store_true",
166 help="run aggregate manager", default=False)
167 parser.add_option("-t", "--trusted-certs",
168 dest="trusted_certs", action="store_true",
169 help="refresh trusted certs", default=False)
170 (options, args) = parser.parse_args()
173 init_logger('server')
174 logger.setLevelFromOptVerbose(config.SFA_API_LOGLEVEL)
176 # ge the server's key and cert
177 hierarchy = Hierarchy()
178 auth_info = hierarchy.get_interface_auth_info()
179 server_key_file = auth_info.get_privkey_filename()
180 server_cert_file = auth_info.get_gid_filename()
182 # ensure interface cert is present in trusted roots dir
183 trusted_roots = TrustedRoots(config.get_trustedroots_dir())
184 trusted_roots.add_gid(GID(filename=server_cert_file))
186 if options.trusted_certs:
187 install_peer_certs(server_key_file, server_cert_file)
189 # start registry server
190 if (options.registry):
191 from sfa.server.registry import Registry
192 r = Registry("", config.SFA_REGISTRY_PORT,
193 server_key_file, server_cert_file)
197 from sfa.server.aggregate import Aggregate
198 a = Aggregate("", config.SFA_AGGREGATE_PORT,
199 server_key_file, server_cert_file)
202 if __name__ == "__main__":
206 logger.log_exc("SFA server is exiting")