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