5 from optparse import OptionParser
6 from sfa.util.config import Config
7 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
8 from sfa.util.namespace import *
9 from sfa.util.faults import *
10 from sfa.trust.certificate import Keypair, Certificate
11 from sfa.trust.credential import Credential
12 from sfa.trust.gid import GID
13 from sfa.trust.hierarchy import Hierarchy
15 KEYDIR = "/var/lib/sfa/"
18 def handle_gid_mismatch_exception(f):
19 def wrapper(*args, **kwds):
20 try: return f(*args, **kwds)
21 except ConnectionKeyGIDMismatch:
22 # clean regen server keypair and try again
23 print "cleaning keys and trying again"
29 def get_server(url=None, port=None, keyfile=None, certfile=None,verbose=False):
31 returns an xmlrpc connection to the service a the specified
35 url_parts = url.split(":")
39 url = "http://%(url)s:%(port)s" % locals()
41 # connect to registry by default
43 addr, port = config.SFA_REGISTRY_HOST, config.SFA_REGISTRY_PORT
44 url = "http://%(addr)s:%(port)s" % locals()
47 print "Contacting registry at: %(url)s" % locals()
49 server = xmlrpcprotocol.get_server(url, keyfile, certfile)
53 def create_default_dirs():
55 hierarchy = Hierarchy()
56 config_dir = config.config_path
57 trusted_certs_dir = config.get_trustedroots_dir()
58 authorities_dir = hierarchy.basedir
59 all_dirs = [config_dir, trusted_certs_dir, authorities_dir]
61 if not os.path.exists(dir):
65 key_file = KEYDIR + os.sep + 'server.key'
66 return os.path.exists(key_file)
70 remove the existing keypair and cred and generate new ones
72 files = ["server.key", "server.cert", "node.cred"]
74 filepath = KEYDIR + os.sep + f
75 if os.path.isfile(filepath):
78 # install the new key pair
79 # get_credential will take care of generating the new keypair
84 def get_node_key(registry=None, verbose=False):
85 # this call requires no authentication,
86 # so we can generate a random keypair here
88 (kfd, keyfile) = tempfile.mkstemp()
89 (cfd, certfile) = tempfile.mkstemp()
90 key = Keypair(create=True)
91 key.save_to_file(keyfile)
92 cert = Certificate(subject=subject)
93 cert.set_issuer(key=key, subject=subject)
96 cert.save_to_file(certfile)
98 registry = get_server(url = registry, keyfile=keyfile, certfile=certfile)
101 def create_server_keypair(keyfile=None, certfile=None, hrn="component", verbose=False):
103 create the server key/cert pair in the right place
105 key = Keypair(filename=keyfile)
106 key.save_to_file(keyfile)
107 cert = Certificate(subject=hrn)
108 cert.set_issuer(key=key, subject=hrn)
111 cert.save_to_file(certfile, save_parents=True)
113 @handle_gid_mismatch_exception
114 def get_credential(registry=None, force=False, verbose=False):
116 hierarchy = Hierarchy()
117 key_dir= hierarchy.basedir
118 data_dir = config.data_path
119 config_dir = config.config_path
120 credfile = data_dir + os.sep + 'node.cred'
121 # check for existing credential
122 if not force and os.path.exists(credfile):
124 print "Loading Credential from %(credfile)s " % locals()
125 cred = Credential(filename=credfile).save_to_string(save_parents=True)
128 print "Getting credential from registry"
129 # make sure node private key exists
130 node_pkey_file = config_dir + os.sep + "node.key"
131 node_gid_file = config_dir + os.sep + "node.gid"
132 if not os.path.exists(node_pkey_file) or \
133 not os.path.exists(node_gid_file):
134 get_node_key(registry=registry, verbose=verbose)
136 gid = GID(filename=node_gid_file)
138 # create server key and certificate
139 keyfile =data_dir + os.sep + "server.key"
140 certfile = data_dir + os.sep + "server.cert"
141 key = Keypair(filename=node_pkey_file)
142 key.save_to_file(keyfile)
143 create_server_keypair(keyfile, certfile, hrn, verbose)
145 # get credential from registry
146 registry = get_server(url=registry, keyfile=keyfile, certfile=certfile)
147 cert = Certificate(filename=certfile)
148 cert_str = cert.save_to_string(save_parents=True)
149 cred = registry.GetSelfCredential(cert_str, hrn, 'node')
150 Credential(string=cred).save_to_file(credfile, save_parents=True)
154 @handle_gid_mismatch_exception
155 def get_trusted_certs(registry=None, verbose=False):
157 refresh our list of trusted certs.
159 # define useful variables
161 data_dir = config.SFA_DATA_DIR
162 config_dir = config.SFA_CONFIG_DIR
163 trusted_certs_dir = config.get_trustedroots_dir()
164 keyfile = data_dir + os.sep + "server.key"
165 certfile = data_dir + os.sep + "server.cert"
166 node_gid_file = config_dir + os.sep + "node.gid"
167 node_gid = GID(filename=node_gid_file)
168 hrn = node_gid.get_hrn()
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 # get the trusted certs and save them in the right place
176 print "Getting trusted certs from registry"
177 trusted_certs = registry.get_trusted_certs(cred)
178 trusted_gid_names = []
179 for gid_str in trusted_certs:
180 gid = GID(string=gid_str)
182 relative_filename = gid.get_hrn() + ".gid"
183 trusted_gid_names.append(relative_filename)
184 gid_filename = trusted_certs_dir + os.sep + relative_filename
186 print "Writing GID for %s as %s" % (gid.get_hrn(), gid_filename)
187 gid.save_to_file(gid_filename, save_parents=True)
190 all_gids_names = os.listdir(trusted_certs_dir)
191 for gid_name in all_gids_names:
192 if gid_name not in trusted_gid_names:
194 print "Removing old gid ", gid_name
195 os.unlink(trusted_certs_dir + os.sep + gid_name)
197 @handle_gid_mismatch_exception
198 def get_gids(registry=None, verbose=False):
200 Get the gid for all instantiated slices on this node and store it
201 in /etc/sfa/slice.gid in the slice's filesystem
203 # define useful variables
205 data_dir = config.data_path
206 config_dir = config.SFA_CONFIG_DIR
207 trusted_certs_dir = config.get_trustedroots_dir()
208 keyfile = data_dir + os.sep + "server.key"
209 certfile = data_dir + os.sep + "server.cert"
210 node_gid_file = config_dir + os.sep + "node.gid"
211 node_gid = GID(filename=node_gid_file)
212 hrn = node_gid.get_hrn()
213 interface_hrn = config.SFA_INTERFACE_HRN
215 cred = get_credential(registry=registry, verbose=verbose)
216 # make sure server key cert pair exists
217 create_server_keypair(keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
218 registry = get_server(url=registry, keyfile=keyfile, certfile=certfile)
221 print "Getting current slices on this node"
222 # get a list of slices on this node
223 from sfa.plc.api import ComponentAPI
225 xids_tuple = api.nodemanager.GetXIDs()
226 slices = eval(xids_tuple[1])
227 slicenames = slices.keys()
229 # generate a list of slices that dont have gids installed
230 slices_without_gids = []
231 for slicename in slicenames:
232 if not os.path.isfile("/vservers/%s/etc/slice.gid" % slicename) \
233 or not os.path.isfile("/vservers/%s/etc/node.gid" % slicename):
234 slices_without_gids.append(slicename)
236 # convert slicenames to hrns
237 hrns = [slicename_to_hrn(interface_hrn, slicename) \
238 for slicename in slices_without_gids]
240 # exit if there are no gids to install
245 print "Getting gids for slices on this node from registry"
247 # and save them in the right palce
248 records = registry.GetGids(hrns, cred)
249 for record in records:
250 # if this isnt a slice record skip it
251 if not record['type'] == 'slice':
253 slicename = hrn_to_pl_slicename(record['hrn'])
254 # if this slice isnt really instatiated skip it
255 if not os.path.exists("/vservers/%(slicename)s" % locals()):
258 # save the slice gid in /etc/sfa/ in the vservers filesystem
259 vserver_path = "/vservers/%(slicename)s" % locals()
261 slice_gid_filename = os.sep.join([vserver_path, "etc", "slice.gid"])
263 print "Saving GID for %(slicename)s as %(slice_gid_filename)s" % locals()
264 GID(string=gid).save_to_file(slice_gid_filename, save_parents=True)
265 # save the node gid in /etc/sfa
266 node_gid_filename = os.sep.join([vserver_path, "etc", "node.gid"])
268 print "Saving node GID for %(slicename)s as %(node_gid_filename)s" % locals()
269 node_gid.save_to_file(node_gid_filename, save_parents=True)
272 def dispatch(options, args):
274 create_default_dirs()
277 print "Getting the component's pkey"
278 get_node_key(registry=options.registry, verbose=options.verbose)
281 print "Getting the component's trusted certs"
282 get_trusted_certs(verbose=options.verbose)
285 print "Geting the component's GIDs"
286 get_gids(verbose=options.verbose)
291 parser = OptionParser(usage="%(prog_name)s [options]" % locals())
292 parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
293 default=False, help="Be verbose")
294 parser.add_option("-r", "--registry", dest="registry", default=None,
295 help="Url of registry to contact")
296 parser.add_option("-k", "--key", dest="key", action="store_true",
298 help="Get the node's pkey from the registry")
299 parser.add_option("-c", "--certs", dest="certs", action="store_true",
301 help="Get the trusted certs from the registry")
302 parser.add_option("-g", "--gids", dest="gids", action="store_true",
304 help="Get gids for all the slices on the component")
306 (options, args) = parser.parse_args()
308 dispatch(options, args)
310 if __name__ == '__main__':