REmoved modifications in auth.py and sfa-start.py.
[sfa.git] / sfa / server / sfa-start.py
1 #!/usr/bin/python
2 #
3 # PlanetLab SFA implementation
4 #
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.
8 #
9 # There are several items that need to be done before starting the servers.
10 #
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.
15 #
16 # 1) Import the existing planetlab database, creating the
17 #    appropriate SFA records. This is done by running the "sfa-import-plc.py" tool.
18 #
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,
22 #
23 #    mkdir trusted_roots; cp authorities/planetlab.gid trusted_roots/
24 #
25 # TODO: Can all three servers use the same "registry" certificate?
26 ##
27
28 ### xxx todo not in the config yet
29 component_port=12346
30 import os, os.path
31 import traceback
32 import sys
33 from optparse import OptionParser
34
35 from sfa.util.sfalogging import logger
36 from sfa.util.xrn import get_authority, hrn_to_urn
37 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
43
44 from sfa.server.sfaapi import SfaApi
45 from sfa.server.registry import Registries
46 from sfa.server.aggregate import Aggregates
47
48 # after http://www.erlenstar.demon.co.uk/unix/faq_2.html
49 def daemon():
50     """Daemonize the current process."""
51     if os.fork() != 0: os._exit(0)
52     os.setsid()
53     if os.fork() != 0: os._exit(0)
54     os.umask(0)
55     devnull = os.open(os.devnull, os.O_RDWR)
56     os.dup2(devnull, 0)
57     # xxx fixme - this is just to make sure that nothing gets stupidly lost - should use devnull
58     logdir='/var/log/httpd'
59     # when installed in standalone we might not have httpd installed
60     if not os.path.isdir(logdir): os.mkdir('/var/log/httpd')
61     crashlog = os.open('%s/sfa_access_log'%logdir, os.O_RDWR | os.O_APPEND | os.O_CREAT, 0644)
62     os.dup2(crashlog, 1)
63     os.dup2(crashlog, 2)
64
65
66 def install_peer_certs(server_key_file, server_cert_file):
67     """
68     Attempt to install missing trusted gids and db records for 
69     our federated interfaces
70     """
71     # Attempt to get any missing peer gids
72     # There should be a gid file in /etc/sfa/trusted_roots for every
73     # peer registry found in in the registries.xml config file. If there
74     # are any missing gids, request a new one from the peer registry.
75     print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs server_key_file  %s  server_cert_file %s"%(server_key_file,server_cert_file)
76     api = SfaApi(key_file = server_key_file, cert_file = server_cert_file)
77     registries = Registries()
78     aggregates = Aggregates()
79     interfaces = dict(registries.items() + aggregates.items())
80     gids_current = api.auth.trusted_cert_list
81     hrns_current = [gid.get_hrn() for gid in gids_current]
82     hrns_expected = set([hrn for hrn in interfaces])
83     new_hrns = set(hrns_expected).difference(hrns_current)
84     #gids = self.get_peer_gids(new_hrns) + gids_current
85     peer_gids = []
86     if not new_hrns:
87         return 
88     print>>sys.stderr," \r\n \r\n \t=============================================== install_peer_certs interfaces %s  api.config.SFA_INTERFACE_HRN %s  new_hrns %s" %( interfaces,api.config.SFA_INTERFACE_HRN,new_hrns)
89     trusted_certs_dir = api.config.get_trustedroots_dir()
90     for new_hrn in new_hrns: 
91         if not new_hrn: continue
92         # the gid for this interface should already be installed
93         if new_hrn == api.config.SFA_INTERFACE_HRN: continue
94         try:
95             # get gid from the registry
96             url = interfaces[new_hrn].get_url()
97             interface = interfaces[new_hrn].server_proxy(server_key_file, server_cert_file, timeout=30)
98             # skip non sfa aggregates
99             print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs IIIinterface  %s url %s" %(interface,url)
100             server_version = api.get_cached_server_version(interface)
101             print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs server_version  %s \r\n \r\rn \t\t =============================================== server_version['sfa'] %s, " %(server_version, server_version['sfa'])
102             if 'sfa' not in server_version:
103                 logger.info("get_trusted_certs: skipping non sfa aggregate: %s" % new_hrn)
104                 continue
105       
106             trusted_gids = interface.get_trusted_certs()
107             print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs  TRUSTED_GIDS %s   " %(trusted_gids)
108             if trusted_gids:
109                  #and not isinstance(trusted_gids,list):
110                 # the gid we want should be the first one in the list,
111                 # but lets make sure
112                 #trusted_gids = [trusted_gids]
113                 print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs  TRUSTED_GIDS %s   " %(trusted_gids)
114                 for trusted_gid in trusted_gids: 
115                     print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs  trusted_gids%s   " %(trusted_gid)
116                     # default message
117                     message = "interface: %s\t" % (api.interface)
118                     message += "unable to install trusted gid for %s" % \
119                                (new_hrn) 
120                     print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs   message %s   " %(message)
121                     gid = GID(string=trusted_gid[0])
122                     #gid = GID(string=trusted_gid['value'][0])
123                     print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs   gid %s   " %(gid)
124                     peer_gids.append(gid)
125                     if gid.get_hrn() == new_hrn:
126                         gid_filename = os.path.join(trusted_certs_dir, '%s.gid' % new_hrn)
127                         gid.save_to_file(gid_filename, save_parents=True)
128                         message = "installed trusted cert for %s" % new_hrn
129                     # log the message
130                     api.logger.info(message)
131         except:
132             message = "interface: %s\tunable to install trusted gid for %s" % \
133                         (api.interface, new_hrn)
134             api.logger.log_exc(message)
135     # doesnt matter witch one
136     update_cert_records(peer_gids)
137
138 def update_cert_records(gids):
139     """
140     Make sure there is a record in the registry for the specified gids. 
141     Removes old records from the db.
142     """
143     # import SfaTable here so this module can be loaded by PlcComponentApi
144     from sfa.storage.table import SfaTable
145     from sfa.storage.record import SfaRecord
146     if not gids:
147         return
148     table = SfaTable()
149     # get records that actually exist in the db
150     gid_urns = [gid.get_urn() for gid in gids]
151     hrns_expected = [gid.get_hrn() for gid in gids]
152     records_found = table.find({'hrn': hrns_expected, 'pointer': -1}) 
153
154     # remove old records
155     for record in records_found:
156         if record['hrn'] not in hrns_expected and \
157             record['hrn'] != self.api.config.SFA_INTERFACE_HRN:
158             table.remove(record)
159
160     # TODO: store urn in the db so we do this in 1 query 
161     for gid in gids:
162         hrn, type = gid.get_hrn(), gid.get_type()
163         print>>sys.stderr, " \r\n \r\n  update_cert_records  hrn,%s type %s"%(hrn, type)       
164         record = table.find({'hrn': hrn, 'type': type, 'pointer': -1})
165         if not record:
166             record = {
167                 'hrn': hrn, 'type': type, 'pointer': -1,
168                 'authority': get_authority(hrn),
169                 'gid': gid.save_to_string(save_parents=True),
170             }
171             record = SfaRecord(dict=record)
172             print>>sys.stderr, " \r\n \r\rn record %s "%(record)
173             table.insert(record)
174         
175 def main():
176     # Generate command line parser
177     parser = OptionParser(usage="sfa-start.py [options]")
178     parser.add_option("-r", "--registry", dest="registry", action="store_true",
179          help="run registry server", default=False)
180     parser.add_option("-s", "--slicemgr", dest="sm", action="store_true",
181          help="run slice manager", default=False)
182     parser.add_option("-a", "--aggregate", dest="am", action="store_true",
183          help="run aggregate manager", default=False)
184     parser.add_option("-c", "--component", dest="cm", action="store_true",
185          help="run component server", default=False)
186     parser.add_option("-t", "--trusted-certs", dest="trusted_certs", action="store_true",
187          help="refresh trusted certs", default=False)
188     parser.add_option("-d", "--daemon", dest="daemon", action="store_true",
189          help="Run as daemon.", default=False)
190     (options, args) = parser.parse_args()
191     
192     config = Config()
193     logger.setLevelFromOptVerbose(config.SFA_API_LOGLEVEL)
194     
195
196     # ge the server's key and cert
197     hierarchy = Hierarchy()
198     auth_info = hierarchy.get_interface_auth_info()
199     server_key_file = auth_info.get_privkey_filename()
200     server_cert_file = auth_info.get_gid_filename() 
201     print>>sys.stderr, " \r\n \t\t\t\t\t SFA-START MAIN auth_info %s server_key_file %s server_cert_file %s "%(auth_info, server_key_file,server_cert_file)
202     # ensure interface cert is present in trusted roots dir
203     trusted_roots = TrustedRoots(config.get_trustedroots_dir())
204     trusted_roots.add_gid(GID(filename=server_cert_file))
205     if (options.daemon):  daemon()
206     
207     if options.trusted_certs:
208         install_peer_certs(server_key_file, server_cert_file)   
209     
210     # start registry server
211     if (options.registry):
212         from sfa.server.registry import Registry
213         r = Registry("", config.SFA_REGISTRY_PORT, server_key_file, server_cert_file)
214         r.start()
215
216     if (options.am):
217         from sfa.server.aggregate import Aggregate
218         a = Aggregate("", config.SFA_AGGREGATE_PORT, server_key_file, server_cert_file)
219         a.start()
220
221     # start slice manager
222     if (options.sm):
223         from sfa.server.slicemgr import SliceMgr
224         s = SliceMgr("", config.SFA_SM_PORT, server_key_file, server_cert_file)
225         s.start()
226
227     if (options.cm):
228         from sfa.server.component import Component
229         c = Component("", config.component_port, server_key_file, server_cert_file)
230 #        c = Component("", config.SFA_COMPONENT_PORT, server_key_file, server_cert_file)
231         c.start()
232
233 if __name__ == "__main__":
234     try:
235         main()
236     except:
237         logger.log_exc_critical("SFA server is exiting")