5 from optparse import OptionParser
7 from sfa.util.faults import ConnectionKeyGIDMismatch
8 from sfa.util.config import Config
9 from sfa.client.sfaserverproxy import SfaServerProxy
10 from sfa.util.plxrn import hrn_to_pl_slicename, slicename_to_hrn
12 from sfa.trust.certificate import Keypair, Certificate
13 from sfa.trust.credential import Credential
14 from sfa.trust.gid import GID
15 from sfa.trust.hierarchy import Hierarchy
17 KEYDIR = "/var/lib/sfa/"
20 def handle_gid_mismatch_exception(f):
21 def wrapper(*args, **kwds):
22 try: return f(*args, **kwds)
23 except ConnectionKeyGIDMismatch:
24 # clean regen server keypair and try again
25 print "cleaning keys and trying again"
31 def server_proxy(url=None, port=None, keyfile=None, certfile=None,verbose=False):
33 returns an xmlrpc connection to the service a the specified
37 url_parts = url.split(":")
41 url = "http://%(url)s:%(port)s" % locals()
43 # connect to registry by default
45 addr, port = config.SFA_REGISTRY_HOST, config.SFA_REGISTRY_PORT
46 url = "http://%(addr)s:%(port)s" % locals()
49 print "Contacting registry at: %(url)s" % locals()
51 server = SfaServerProxy(url, keyfile, certfile)
55 def create_default_dirs():
57 hierarchy = Hierarchy()
58 config_dir = config.config_path
59 trusted_certs_dir = config.get_trustedroots_dir()
60 authorities_dir = hierarchy.basedir
61 all_dirs = [config_dir, trusted_certs_dir, authorities_dir]
63 if not os.path.exists(dir):
67 key_file = KEYDIR + os.sep + 'server.key'
68 return os.path.exists(key_file)
72 remove the existing keypair and cred and generate new ones
74 files = ["server.key", "server.cert", "node.cred"]
76 filepath = KEYDIR + os.sep + f
77 if os.path.isfile(filepath):
80 # install the new key pair
81 # GetCredential will take care of generating the new keypair
86 def get_node_key(registry=None, verbose=False):
87 # this call requires no authentication,
88 # so we can generate a random keypair here
90 (kfd, keyfile) = tempfile.mkstemp()
91 (cfd, certfile) = tempfile.mkstemp()
92 key = Keypair(create=True)
93 key.save_to_file(keyfile)
94 cert = Certificate(subject=subject)
95 cert.set_issuer(key=key, subject=subject)
98 cert.save_to_file(certfile)
100 registry = server_proxy(url = registry, keyfile=keyfile, certfile=certfile)
101 registry.get_key_from_incoming_ip()
103 def create_server_keypair(keyfile=None, certfile=None, hrn="component", verbose=False):
105 create the server key/cert pair in the right place
107 key = Keypair(filename=keyfile)
108 key.save_to_file(keyfile)
109 cert = Certificate(subject=hrn)
110 cert.set_issuer(key=key, subject=hrn)
113 cert.save_to_file(certfile, save_parents=True)
115 @handle_gid_mismatch_exception
116 def GetCredential(registry=None, force=False, verbose=False):
118 hierarchy = Hierarchy()
119 key_dir= hierarchy.basedir
120 data_dir = config.data_path
121 config_dir = config.config_path
122 credfile = data_dir + os.sep + 'node.cred'
123 # check for existing credential
124 if not force and os.path.exists(credfile):
126 print "Loading Credential from %(credfile)s " % locals()
127 cred = Credential(filename=credfile).save_to_string(save_parents=True)
130 print "Getting credential from registry"
131 # make sure node private key exists
132 node_pkey_file = config_dir + os.sep + "node.key"
133 node_gid_file = config_dir + os.sep + "node.gid"
134 if not os.path.exists(node_pkey_file) or \
135 not os.path.exists(node_gid_file):
136 get_node_key(registry=registry, verbose=verbose)
138 gid = GID(filename=node_gid_file)
140 # create server key and certificate
141 keyfile =data_dir + os.sep + "server.key"
142 certfile = data_dir + os.sep + "server.cert"
143 key = Keypair(filename=node_pkey_file)
144 key.save_to_file(keyfile)
145 create_server_keypair(keyfile, certfile, hrn, verbose)
147 # get credential from registry
148 registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
149 cert = Certificate(filename=certfile)
150 cert_str = cert.save_to_string(save_parents=True)
151 cred = registry.GetSelfCredential(cert_str, 'node', hrn)
152 Credential(string=cred).save_to_file(credfile, save_parents=True)
156 @handle_gid_mismatch_exception
157 def get_trusted_certs(registry=None, verbose=False):
159 refresh our list of trusted certs.
161 # define useful variables
163 data_dir = config.SFA_DATA_DIR
164 config_dir = config.SFA_CONFIG_DIR
165 trusted_certs_dir = config.get_trustedroots_dir()
166 keyfile = data_dir + os.sep + "server.key"
167 certfile = data_dir + os.sep + "server.cert"
168 node_gid_file = config_dir + os.sep + "node.gid"
169 node_gid = GID(filename=node_gid_file)
170 hrn = node_gid.get_hrn()
172 cred = GetCredential(registry=registry, verbose=verbose)
173 # make sure server key cert pair exists
174 create_server_keypair(keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
175 registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
176 # get the trusted certs and save them in the right place
178 print "Getting trusted certs from registry"
179 trusted_certs = registry.get_trusted_certs(cred)
180 trusted_gid_names = []
181 for gid_str in trusted_certs:
182 gid = GID(string=gid_str)
184 relative_filename = gid.get_hrn() + ".gid"
185 trusted_gid_names.append(relative_filename)
186 gid_filename = trusted_certs_dir + os.sep + relative_filename
188 print "Writing GID for %s as %s" % (gid.get_hrn(), gid_filename)
189 gid.save_to_file(gid_filename, save_parents=True)
192 all_gids_names = os.listdir(trusted_certs_dir)
193 for gid_name in all_gids_names:
194 if gid_name not in trusted_gid_names:
196 print "Removing old gid ", gid_name
197 os.unlink(trusted_certs_dir + os.sep + gid_name)
199 @handle_gid_mismatch_exception
200 def get_gids(registry=None, verbose=False):
202 Get the gid for all instantiated slices on this node and store it
203 in /etc/sfa/slice.gid in the slice's filesystem
205 # define useful variables
207 data_dir = config.data_path
208 config_dir = config.SFA_CONFIG_DIR
209 trusted_certs_dir = config.get_trustedroots_dir()
210 keyfile = data_dir + os.sep + "server.key"
211 certfile = data_dir + os.sep + "server.cert"
212 node_gid_file = config_dir + os.sep + "node.gid"
213 node_gid = GID(filename=node_gid_file)
214 hrn = node_gid.get_hrn()
215 interface_hrn = config.SFA_INTERFACE_HRN
217 cred = GetCredential(registry=registry, verbose=verbose)
218 # make sure server key cert pair exists
219 create_server_keypair(keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
220 registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
223 print "Getting current slices on this node"
224 # get a list of slices on this node
225 from sfa.generic import Generic
226 generic=Generic.the_flavour()
227 api = generic.make_api(interface='component')
228 xids_tuple = api.driver.nodemanager.GetXIDs()
229 slices = eval(xids_tuple[1])
230 slicenames = slices.keys()
232 # generate a list of slices that dont have gids installed
233 slices_without_gids = []
234 for slicename in slicenames:
235 if not os.path.isfile("/vservers/%s/etc/slice.gid" % slicename) \
236 or not os.path.isfile("/vservers/%s/etc/node.gid" % slicename):
237 slices_without_gids.append(slicename)
239 # convert slicenames to hrns
240 hrns = [slicename_to_hrn(interface_hrn, slicename) \
241 for slicename in slices_without_gids]
243 # exit if there are no gids to install
248 print "Getting gids for slices on this node from registry"
250 # and save them in the right palce
251 records = registry.GetGids(hrns, cred)
252 for record in records:
253 # if this isnt a slice record skip it
254 if not record['type'] == 'slice':
256 slicename = hrn_to_pl_slicename(record['hrn'])
257 # if this slice isnt really instatiated skip it
258 if not os.path.exists("/vservers/%(slicename)s" % locals()):
261 # save the slice gid in /etc/sfa/ in the vservers filesystem
262 vserver_path = "/vservers/%(slicename)s" % locals()
264 slice_gid_filename = os.sep.join([vserver_path, "etc", "slice.gid"])
266 print "Saving GID for %(slicename)s as %(slice_gid_filename)s" % locals()
267 GID(string=gid).save_to_file(slice_gid_filename, save_parents=True)
268 # save the node gid in /etc/sfa
269 node_gid_filename = os.sep.join([vserver_path, "etc", "node.gid"])
271 print "Saving node GID for %(slicename)s as %(node_gid_filename)s" % locals()
272 node_gid.save_to_file(node_gid_filename, save_parents=True)
275 def dispatch(options, args):
277 create_default_dirs()
280 print "Getting the component's pkey"
281 get_node_key(registry=options.registry, verbose=options.verbose)
284 print "Getting the component's trusted certs"
285 get_trusted_certs(verbose=options.verbose)
288 print "Geting the component's GIDs"
289 get_gids(verbose=options.verbose)
294 parser = OptionParser(usage="%(prog_name)s [options]" % locals())
295 parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
296 default=False, help="Be verbose")
297 parser.add_option("-r", "--registry", dest="registry", default=None,
298 help="Url of registry to contact")
299 parser.add_option("-k", "--key", dest="key", action="store_true",
301 help="Get the node's pkey from the registry")
302 parser.add_option("-c", "--certs", dest="certs", action="store_true",
304 help="Get the trusted certs from the registry")
305 parser.add_option("-g", "--gids", dest="gids", action="store_true",
307 help="Get gids for all the slices on the component")
309 (options, args) = parser.parse_args()
311 dispatch(options, args)
313 if __name__ == '__main__':