728c4337910f7a84aaa7110e996e2bc14e2667fa
[sfa.git] / sfa / server / sfa_component_setup.py
1 #!/usr/bin/python
2 import sys
3 import os
4 import tempfile
5 from optparse import OptionParser
6 from sfa.util.config import Config
7 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
8 from sfa.util.namepace import *
9 from sfa.trust.certificate import Keypair, Certificate
10 from sfa.trust.credential import Credential
11 from sfa.trust.gid import GID
12 from sfa.trust.hierarchy import Hierarchy
13
14 def get_server(url=None, port=None, keyfile=None, certfile=None,verbose=False):
15     """
16     returns an xmlrpc connection to the service a the specified 
17     address
18     """
19     if url:
20         url_parts = url.split(":")
21         if len(url_parts) >1:
22             pass
23         else:
24             url = "http://%(url)s:%(port)s" % locals()
25     else:
26         # connect to registry by default
27         config = Config()
28         addr, port = config.SFA_REGISTRY_HOST, config.SFA_REGISTRY_PORT
29         url = "http://%(addr)s:%(port)s" % locals()
30
31     if verbose:
32         print "Contacting registry at: %(url)s" % locals()
33
34     server = xmlrpcprotocol.get_server(url, keyfile, certfile)
35     return server    
36     
37
38 def create_default_dirs():
39     config = Config()
40     hierarchy = Hierarchy()
41     config_dir = config.config_path
42     trusted_certs_dir = config.get_trustedroots_dir()
43     authorities_dir = hierarchy.basedir
44     all_dirs = [config_dir, trusted_certs_dir, authorities_dir]
45     for dir in all_dirs:
46         if not os.path.exists(dir):
47             os.makedirs(dir)
48              
49 def get_node_key(registry=None, verbose=False):
50     # this call requires no authentication, 
51     # so we can generate a random keypair here
52     subject="component"
53     (kfd, keyfile) = tempfile.mkstemp()
54     (cfd, certfile) = tempfile.mkstemp()
55     key = Keypair(create=True)
56     key.save_to_file(keyfile)
57     cert = Certificate(subject=subject)
58     cert.set_issuer(key=key, subject=subject)
59     cert.set_pubkey(key)
60     cert.sign()
61     cert.save_to_file(certfile)
62     
63     registry = get_server(url = registry, keyfile=keyfile, certfile=certfile)    
64     registry.get_key()
65
66 def create_server_keypair(keyfile=None, certfile=None, hrn="component", verbose=False):
67     """
68     create the server key/cert pair in the right place
69     """
70     key = Keypair(filename=keyfile)
71     key.save_to_file(keyfile)
72     cert = Certificate(subject=hrn)
73     cert.set_issuer(key=key, subject=hrn)
74     cert.set_pubkey(key)
75     cert.sign()
76     cert.save_to_file(certfile, save_parents=True)       
77         
78 def get_credential(registry=None, force=False, verbose=False):
79     config = Config()
80     hierarchy = Hierarchy()
81     key_dir= hierarchy.basedir
82     data_dir = config.data_path
83     config_dir = config.config_path
84     credfile = data_dir + os.sep + 'node.cred'
85     # check for existing credential
86     if not force and os.path.exists(credfile):
87         if verbose:
88             print "Loading Credential from %(credfile)s " % locals()  
89         cred = Credential(filename=credfile).save_to_string(save_parents=True)
90     else:
91         if verbose:
92             print "Getting credential from registry" 
93         # make sure node private key exists
94         node_pkey_file = config_dir + os.sep + "node.key"
95         node_gid_file = config_dir + os.sep + "node.gid"
96         if not os.path.exists(node_pkey_file) or \
97            not os.path.exists(node_gid_file):
98             get_node_key(registry=registry, verbose=verbose)
99         
100         gid = GID(filename=node_gid_file)
101         hrn = gid.get_hrn()
102         # create server key and certificate
103         keyfile =data_dir + os.sep + "server.key"
104         certfile = data_dir + os.sep + "server.cert"
105         key = Keypair(filename=node_pkey_file)
106         key.save_to_file(keyfile)
107         create_server_keypair(keyfile, certfile, hrn, verbose)
108
109         # get credential from registry 
110         registry = get_server(url=registry, keyfile=keyfile, certfile=certfile)
111         cert = Certificate(filename=certfile)
112         cert_str = cert.save_to_string(save_parents=True)
113         cred = registry.get_self_credential(cert_str, 'node', hrn)    
114         Credential(string=cred).save_to_file(credfile, save_parents=True)
115     
116     return cred
117
118 def get_trusted_certs(registry=None, verbose=False):
119     """
120     refresh our list of trusted certs.
121     """
122     # define useful variables
123     config = Config()
124     data_dir = config.SFA_DATA_DIR
125     config_dir = config.SFA_CONFIG_DIR
126     trusted_certs_dir = config.get_trustedroots_dir()
127     keyfile = data_dir + os.sep + "server.key"
128     certfile = data_dir + os.sep + "server.cert"
129     node_gid_file = config_dir + os.sep + "node.gid"
130     node_gid = GID(filename=node_gid_file)
131     hrn = node_gid.get_hrn()
132     # get credential
133     cred = get_credential(registry=registry, verbose=verbose)
134     # make sure server key cert pair exists
135     create_server_keypair(keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
136     registry = get_server(url=registry, keyfile=keyfile, certfile=certfile)
137     # get the trusted certs and save them in the right place
138     if verbose:
139         print "Getting trusted certs from registry"
140     trusted_certs = registry.get_trusted_certs(cred)
141     trusted_gid_names = [] 
142     for gid_str in trusted_certs:
143         gid = GID(string=gid_str)
144         gid.decode()
145         relative_filename = gid.get_hrn() + ".gid"
146         trusted_gid_names.append(relative_filename)
147         gid_filename = trusted_certs_dir + os.sep + relative_filename
148         if verbose:
149             print "Writing GID for %s as %s" % (gid.get_hrn(), gid_filename) 
150         gid.save_to_file(gid_filename, save_parents=True)
151
152     # remove old certs
153     all_gids_names = os.listdir(trusted_certs_dir)
154     for gid_name in all_gids_names:
155         if gid_name not in trusted_gid_names:
156             if verbose:
157                 print "Removing old gid ", gid_name
158             os.unlink(trusted_certs_dir + os.sep + gid_name)                     
159
160 def get_gids(registry=None, verbose=False):
161     """
162     Get the gid for all instantiated slices on this node and store it
163     in /etc/sfa/slice.gid in the slice's filesystem
164     """
165     # define useful variables
166     config = Config()
167     data_dir = config.data_path
168     config_dir = config.SFA_CONFIG_DIR
169     trusted_certs_dir = config.get_trustedroots_dir()
170     keyfile = data_dir + os.sep + "server.key"
171     certfile = data_dir + os.sep + "server.cert"
172     node_gid_file = config_dir + os.sep + "node.gid"
173     node_gid = GID(filename=node_gid_file)
174     hrn = node_gid.get_hrn()
175     interface_hrn = config.SFA_INTERFACE_HRN
176     # get credential
177     cred = get_credential(registry=registry, verbose=verbose)
178     # make sure server key cert pair exists
179     create_server_keypair(keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
180     registry = get_server(url=registry, keyfile=keyfile, certfile=certfile)
181             
182     if verbose:
183         print "Getting current slices on this node"
184     # get a list of slices on this node
185     from sfa.plc.api import ComponentAPI
186     api = ComponentAPI()
187     slicenames = api.nodemanager.GetXIDs().keys()   
188     hrns = [slicename_to_hrn(interface_hrn, slicename) for slicename in slicenames]
189         
190
191     if verbose:
192         print "Getting gids for slices on this node from registry"  
193     # get the gids
194     # and save them in the right palce
195     records = registry.get_gids(cred, hrns)
196     for record in records:
197         # if this isnt a slice record skip it
198         if not record['type'] == 'slice':
199             continue
200         slicename = hrn_to_pl_slicename(record['hrn'])
201         # if this slice isnt really instatiated skip it
202         if not os.path.exists("/vservers/%(slicename)s" % locals()):
203             continue
204        
205         # save the slice gid in /etc/sfa/ in the vservers filesystem
206         vserver_path = "/vservers/%(slicename)s" % locals()
207         gid = record['gid']
208         slice_gid_filename = os.sep.join([vserver_path, "etc", "slice.gid"])
209         if verbose:
210             print "Saving GID for %(slicename)s as %(slice_gid_filename)s" % locals()
211         GID(string=gid).save_to_file(slice_gid_filename, save_parents=True)
212         # save the node gid in /etc/sfa
213         node_gid_filename = os.sep.join([vserver_path, "etc", "node.gid"])
214         if verbose:
215             print "Saving node GID for %(slicename)s as %(node_gid_filename)s" % locals()
216         node_gid.save_to_file(node_gid_filename, save_parents=True) 
217                 
218
219 def dispatch(options, args):
220
221     create_default_dirs()
222     if options.key:
223         if options.verbose:
224             print "Getting the component's pkey"
225         get_node_key(registry=options.registry, verbose=options.verbose)
226     if options.certs:
227         if options.verbose:
228             print "Getting the component's trusted certs"
229         get_trusted_certs(verbose=options.verbose)
230     if options.gids:        
231         if options.verbose:
232             print "Geting the component's GIDs"
233         get_gids(verbose=options.verbose)
234
235 def main():
236     args = sys.argv
237     prog_name = args[0]
238     parser = OptionParser(usage="%(prog_name)s [options]" % locals())
239     parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
240                       default=False, help="Be verbose") 
241     parser.add_option("-r", "--registry", dest="registry", default=None,
242                       help="Url of registry to contact")  
243     parser.add_option("-k", "--key", dest="key", action="store_true", 
244                      default=False,  
245                      help="Get the node's pkey from the registry")
246     parser.add_option("-c", "--certs", dest="certs", action="store_true",
247                       default=False,
248                       help="Get the trusted certs from the registry")
249     parser.add_option("-g", "--gids", dest="gids", action="store_true",       
250                       default=False,
251                       help="Get gids for all the slices on the component")
252
253     (options, args) = parser.parse_args()
254
255     dispatch(options, args)
256
257 if __name__ == '__main__':
258     main()