5 from optparse import OptionParser
7 from sfa.util.faults import ConnectionKeyGIDMismatch
8 from sfa.util.config import Config
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 from sfa.client.sfaserverproxy import SfaServerProxy
17 from sfa.planetlab.plxrn import hrn_to_pl_slicename, slicename_to_hrn
19 KEYDIR = "/var/lib/sfa/"
22 def handle_gid_mismatch_exception(f):
23 def wrapper(*args, **kwds):
24 try: return f(*args, **kwds)
25 except ConnectionKeyGIDMismatch:
26 # clean regen server keypair and try again
27 print "cleaning keys and trying again"
33 def server_proxy(url=None, port=None, keyfile=None, certfile=None,verbose=False):
35 returns an xmlrpc connection to the service a the specified
39 url_parts = url.split(":")
43 url = "http://%(url)s:%(port)s" % locals()
45 # connect to registry by default
47 addr, port = config.SFA_REGISTRY_HOST, config.SFA_REGISTRY_PORT
48 url = "http://%(addr)s:%(port)s" % locals()
51 print "Contacting registry at: %(url)s" % locals()
53 server = SfaServerProxy(url, keyfile, certfile)
57 def create_default_dirs():
59 hierarchy = Hierarchy()
60 config_dir = config.config_path
61 trusted_certs_dir = config.get_trustedroots_dir()
62 authorities_dir = hierarchy.basedir
63 all_dirs = [config_dir, trusted_certs_dir, authorities_dir]
65 if not os.path.exists(dir):
69 key_file = KEYDIR + os.sep + 'server.key'
70 return os.path.exists(key_file)
74 remove the existing keypair and cred and generate new ones
76 files = ["server.key", "server.cert", "node.cred"]
78 filepath = KEYDIR + os.sep + f
79 if os.path.isfile(filepath):
82 # install the new key pair
83 # GetCredential will take care of generating the new keypair
88 def get_node_key(registry=None, verbose=False):
89 # this call requires no authentication,
90 # so we can generate a random keypair here
92 (kfd, keyfile) = tempfile.mkstemp()
93 (cfd, certfile) = tempfile.mkstemp()
94 key = Keypair(create=True)
95 key.save_to_file(keyfile)
96 cert = Certificate(subject=subject)
97 cert.set_issuer(key=key, subject=subject)
100 cert.save_to_file(certfile)
102 registry = server_proxy(url = registry, keyfile=keyfile, certfile=certfile)
103 registry.get_key_from_incoming_ip()
105 def create_server_keypair(keyfile=None, certfile=None, hrn="component", verbose=False):
107 create the server key/cert pair in the right place
109 key = Keypair(filename=keyfile)
110 key.save_to_file(keyfile)
111 cert = Certificate(subject=hrn)
112 cert.set_issuer(key=key, subject=hrn)
115 cert.save_to_file(certfile, save_parents=True)
117 @handle_gid_mismatch_exception
118 def GetCredential(registry=None, force=False, verbose=False):
120 hierarchy = Hierarchy()
121 key_dir= hierarchy.basedir
122 data_dir = config.data_path
123 config_dir = config.config_path
124 credfile = data_dir + os.sep + 'node.cred'
125 # check for existing credential
126 if not force and os.path.exists(credfile):
128 print "Loading Credential from %(credfile)s " % locals()
129 cred = Credential(filename=credfile).save_to_string(save_parents=True)
132 print "Getting credential from registry"
133 # make sure node private key exists
134 node_pkey_file = config_dir + os.sep + "node.key"
135 node_gid_file = config_dir + os.sep + "node.gid"
136 if not os.path.exists(node_pkey_file) or \
137 not os.path.exists(node_gid_file):
138 get_node_key(registry=registry, verbose=verbose)
140 gid = GID(filename=node_gid_file)
142 # create server key and certificate
143 keyfile =data_dir + os.sep + "server.key"
144 certfile = data_dir + os.sep + "server.cert"
145 key = Keypair(filename=node_pkey_file)
146 key.save_to_file(keyfile)
147 create_server_keypair(keyfile, certfile, hrn, verbose)
149 # get credential from registry
150 registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
151 cert = Certificate(filename=certfile)
152 cert_str = cert.save_to_string(save_parents=True)
153 cred = registry.GetSelfCredential(cert_str, 'node', hrn)
154 Credential(string=cred).save_to_file(credfile, save_parents=True)
158 @handle_gid_mismatch_exception
159 def get_trusted_certs(registry=None, verbose=False):
161 refresh our list of trusted certs.
163 # define useful variables
165 data_dir = config.SFA_DATA_DIR
166 config_dir = config.SFA_CONFIG_DIR
167 trusted_certs_dir = config.get_trustedroots_dir()
168 keyfile = data_dir + os.sep + "server.key"
169 certfile = data_dir + os.sep + "server.cert"
170 node_gid_file = config_dir + os.sep + "node.gid"
171 node_gid = GID(filename=node_gid_file)
172 hrn = node_gid.get_hrn()
174 cred = GetCredential(registry=registry, verbose=verbose)
175 # make sure server key cert pair exists
176 create_server_keypair(keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
177 registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
178 # get the trusted certs and save them in the right place
180 print "Getting trusted certs from registry"
181 trusted_certs = registry.get_trusted_certs(cred)
182 trusted_gid_names = []
183 for gid_str in trusted_certs:
184 gid = GID(string=gid_str)
186 relative_filename = gid.get_hrn() + ".gid"
187 trusted_gid_names.append(relative_filename)
188 gid_filename = trusted_certs_dir + os.sep + relative_filename
190 print "Writing GID for %s as %s" % (gid.get_hrn(), gid_filename)
191 gid.save_to_file(gid_filename, save_parents=True)
194 all_gids_names = os.listdir(trusted_certs_dir)
195 for gid_name in all_gids_names:
196 if gid_name not in trusted_gid_names:
198 print "Removing old gid ", gid_name
199 os.unlink(trusted_certs_dir + os.sep + gid_name)
201 @handle_gid_mismatch_exception
202 def get_gids(registry=None, verbose=False):
204 Get the gid for all instantiated slices on this node and store it
205 in /etc/sfa/slice.gid in the slice's filesystem
207 # define useful variables
209 data_dir = config.data_path
210 config_dir = config.SFA_CONFIG_DIR
211 trusted_certs_dir = config.get_trustedroots_dir()
212 keyfile = data_dir + os.sep + "server.key"
213 certfile = data_dir + os.sep + "server.cert"
214 node_gid_file = config_dir + os.sep + "node.gid"
215 node_gid = GID(filename=node_gid_file)
216 hrn = node_gid.get_hrn()
217 interface_hrn = config.SFA_INTERFACE_HRN
219 cred = GetCredential(registry=registry, verbose=verbose)
220 # make sure server key cert pair exists
221 create_server_keypair(keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
222 registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
225 print "Getting current slices on this node"
226 # get a list of slices on this node
227 from sfa.generic import Generic
228 generic=Generic.the_flavour()
229 api = generic.make_api(interface='component')
230 xids_tuple = api.driver.nodemanager.GetXIDs()
231 slices = eval(xids_tuple[1])
232 slicenames = slices.keys()
234 # generate a list of slices that dont have gids installed
235 slices_without_gids = []
236 for slicename in slicenames:
237 if not os.path.isfile("/vservers/%s/etc/slice.gid" % slicename) \
238 or not os.path.isfile("/vservers/%s/etc/node.gid" % slicename):
239 slices_without_gids.append(slicename)
241 # convert slicenames to hrns
242 hrns = [slicename_to_hrn(interface_hrn, slicename) \
243 for slicename in slices_without_gids]
245 # exit if there are no gids to install
250 print "Getting gids for slices on this node from registry"
252 # and save them in the right palce
253 records = registry.GetGids(hrns, cred)
254 for record in records:
255 # if this isnt a slice record skip it
256 if not record['type'] == 'slice':
258 slicename = hrn_to_pl_slicename(record['hrn'])
259 # if this slice isnt really instatiated skip it
260 if not os.path.exists("/vservers/%(slicename)s" % locals()):
263 # save the slice gid in /etc/sfa/ in the vservers filesystem
264 vserver_path = "/vservers/%(slicename)s" % locals()
266 slice_gid_filename = os.sep.join([vserver_path, "etc", "slice.gid"])
268 print "Saving GID for %(slicename)s as %(slice_gid_filename)s" % locals()
269 GID(string=gid).save_to_file(slice_gid_filename, save_parents=True)
270 # save the node gid in /etc/sfa
271 node_gid_filename = os.sep.join([vserver_path, "etc", "node.gid"])
273 print "Saving node GID for %(slicename)s as %(node_gid_filename)s" % locals()
274 node_gid.save_to_file(node_gid_filename, save_parents=True)
277 def dispatch(options, args):
279 create_default_dirs()
282 print "Getting the component's pkey"
283 get_node_key(registry=options.registry, verbose=options.verbose)
286 print "Getting the component's trusted certs"
287 get_trusted_certs(verbose=options.verbose)
290 print "Geting the component's GIDs"
291 get_gids(verbose=options.verbose)
296 parser = OptionParser(usage="%(prog_name)s [options]" % locals())
297 parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
298 default=False, help="Be verbose")
299 parser.add_option("-r", "--registry", dest="registry", default=None,
300 help="Url of registry to contact")
301 parser.add_option("-k", "--key", dest="key", action="store_true",
303 help="Get the node's pkey from the registry")
304 parser.add_option("-c", "--certs", dest="certs", action="store_true",
306 help="Get the trusted certs from the registry")
307 parser.add_option("-g", "--gids", dest="gids", action="store_true",
309 help="Get gids for all the slices on the component")
311 (options, args) = parser.parse_args()
313 dispatch(options, args)
315 if __name__ == '__main__':