2 from __future__ import print_function
7 from optparse import OptionParser
9 from sfa.util.faults import ConnectionKeyGIDMismatch
10 from sfa.util.config import Config
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 from sfa.client.sfaserverproxy import SfaServerProxy
19 from sfa.planetlab.plxrn import hrn_to_pl_slicename, slicename_to_hrn
21 KEYDIR = "/var/lib/sfa/"
25 def handle_gid_mismatch_exception(f):
26 def wrapper(*args, **kwds):
28 return f(*args, **kwds)
29 except ConnectionKeyGIDMismatch:
30 # clean regen server keypair and try again
31 print("cleaning keys and trying again")
38 def server_proxy(url=None, port=None, keyfile=None, certfile=None, verbose=False):
40 returns an xmlrpc connection to the service a the specified
44 url_parts = url.split(":")
45 if len(url_parts) > 1:
48 url = "http://%(url)s:%(port)s" % locals()
50 # connect to registry by default
52 addr, port = config.SFA_REGISTRY_HOST, config.SFA_REGISTRY_PORT
53 url = "http://%(addr)s:%(port)s" % locals()
56 print("Contacting registry at: %(url)s" % locals())
58 server = SfaServerProxy(url, keyfile, certfile)
62 def create_default_dirs():
64 hierarchy = Hierarchy()
65 config_dir = config.config_path
66 trusted_certs_dir = config.get_trustedroots_dir()
67 authorities_dir = hierarchy.basedir
68 all_dirs = [config_dir, trusted_certs_dir, authorities_dir]
70 if not os.path.exists(dir):
75 key_file = KEYDIR + os.sep + 'server.key'
76 return os.path.exists(key_file)
81 remove the existing keypair and cred and generate new ones
83 files = ["server.key", "server.cert", "node.cred"]
85 filepath = KEYDIR + os.sep + f
86 if os.path.isfile(filepath):
89 # install the new key pair
90 # GetCredential will take care of generating the new keypair
95 def get_node_key(registry=None, verbose=False):
96 # this call requires no authentication,
97 # so we can generate a random keypair here
99 (kfd, keyfile) = tempfile.mkstemp()
100 (cfd, certfile) = tempfile.mkstemp()
101 key = Keypair(create=True)
102 key.save_to_file(keyfile)
103 cert = Certificate(subject=subject)
104 cert.set_issuer(key=key, subject=subject)
107 cert.save_to_file(certfile)
109 registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
110 registry.get_key_from_incoming_ip()
113 def create_server_keypair(keyfile=None, certfile=None, hrn="component", verbose=False):
115 create the server key/cert pair in the right place
117 key = Keypair(filename=keyfile)
118 key.save_to_file(keyfile)
119 cert = Certificate(subject=hrn)
120 cert.set_issuer(key=key, subject=hrn)
123 cert.save_to_file(certfile, save_parents=True)
126 @handle_gid_mismatch_exception
127 def GetCredential(registry=None, force=False, verbose=False):
129 hierarchy = Hierarchy()
130 key_dir = hierarchy.basedir
131 data_dir = config.data_path
132 config_dir = config.config_path
133 credfile = data_dir + os.sep + 'node.cred'
134 # check for existing credential
135 if not force and os.path.exists(credfile):
137 print("Loading Credential from %(credfile)s " % locals())
138 cred = Credential(filename=credfile).save_to_string(save_parents=True)
141 print("Getting credential from registry")
142 # make sure node private key exists
143 node_pkey_file = config_dir + os.sep + "node.key"
144 node_gid_file = config_dir + os.sep + "node.gid"
145 if not os.path.exists(node_pkey_file) or \
146 not os.path.exists(node_gid_file):
147 get_node_key(registry=registry, verbose=verbose)
149 gid = GID(filename=node_gid_file)
151 # create server key and certificate
152 keyfile = data_dir + os.sep + "server.key"
153 certfile = data_dir + os.sep + "server.cert"
154 key = Keypair(filename=node_pkey_file)
155 key.save_to_file(keyfile)
156 create_server_keypair(keyfile, certfile, hrn, verbose)
158 # get credential from registry
159 registry = server_proxy(
160 url=registry, keyfile=keyfile, certfile=certfile)
161 cert = Certificate(filename=certfile)
162 cert_str = cert.save_to_string(save_parents=True)
163 cred = registry.GetSelfCredential(cert_str, 'node', hrn)
164 Credential(string=cred).save_to_file(credfile, save_parents=True)
169 @handle_gid_mismatch_exception
170 def get_trusted_certs(registry=None, verbose=False):
172 refresh our list of trusted certs.
174 # define useful variables
176 data_dir = config.SFA_DATA_DIR
177 config_dir = config.SFA_CONFIG_DIR
178 trusted_certs_dir = config.get_trustedroots_dir()
179 keyfile = data_dir + os.sep + "server.key"
180 certfile = data_dir + os.sep + "server.cert"
181 node_gid_file = config_dir + os.sep + "node.gid"
182 node_gid = GID(filename=node_gid_file)
183 hrn = node_gid.get_hrn()
185 cred = GetCredential(registry=registry, verbose=verbose)
186 # make sure server key cert pair exists
187 create_server_keypair(
188 keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
189 registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
190 # get the trusted certs and save them in the right place
192 print("Getting trusted certs from registry")
193 trusted_certs = registry.get_trusted_certs(cred)
194 trusted_gid_names = []
195 for gid_str in trusted_certs:
196 gid = GID(string=gid_str)
198 relative_filename = gid.get_hrn() + ".gid"
199 trusted_gid_names.append(relative_filename)
200 gid_filename = trusted_certs_dir + os.sep + relative_filename
202 print("Writing GID for %s as %s" % (gid.get_hrn(), gid_filename))
203 gid.save_to_file(gid_filename, save_parents=True)
206 all_gids_names = os.listdir(trusted_certs_dir)
207 for gid_name in all_gids_names:
208 if gid_name not in trusted_gid_names:
210 print("Removing old gid ", gid_name)
211 os.unlink(trusted_certs_dir + os.sep + gid_name)
214 @handle_gid_mismatch_exception
215 def get_gids(registry=None, verbose=False):
217 Get the gid for all instantiated slices on this node and store it
218 in /etc/sfa/slice.gid in the slice's filesystem
220 # define useful variables
222 data_dir = config.data_path
223 config_dir = config.SFA_CONFIG_DIR
224 trusted_certs_dir = config.get_trustedroots_dir()
225 keyfile = data_dir + os.sep + "server.key"
226 certfile = data_dir + os.sep + "server.cert"
227 node_gid_file = config_dir + os.sep + "node.gid"
228 node_gid = GID(filename=node_gid_file)
229 hrn = node_gid.get_hrn()
230 interface_hrn = config.SFA_INTERFACE_HRN
232 cred = GetCredential(registry=registry, verbose=verbose)
233 # make sure server key cert pair exists
234 create_server_keypair(
235 keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
236 registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
239 print("Getting current slices on this node")
240 # get a list of slices on this node
241 from sfa.generic import Generic
242 generic = Generic.the_flavour()
243 api = generic.make_api(interface='component')
244 xids_tuple = api.driver.nodemanager.GetXIDs()
245 slices = eval(xids_tuple[1])
246 slicenames = slices.keys()
248 # generate a list of slices that dont have gids installed
249 slices_without_gids = []
250 for slicename in slicenames:
251 if not os.path.isfile("/vservers/%s/etc/slice.gid" % slicename) \
252 or not os.path.isfile("/vservers/%s/etc/node.gid" % slicename):
253 slices_without_gids.append(slicename)
255 # convert slicenames to hrns
256 hrns = [slicename_to_hrn(interface_hrn, slicename)
257 for slicename in slices_without_gids]
259 # exit if there are no gids to install
264 print("Getting gids for slices on this node from registry")
266 # and save them in the right palce
267 records = registry.GetGids(hrns, cred)
268 for record in records:
269 # if this isnt a slice record skip it
270 if not record['type'] == 'slice':
272 slicename = hrn_to_pl_slicename(record['hrn'])
273 # if this slice isnt really instatiated skip it
274 if not os.path.exists("/vservers/%(slicename)s" % locals()):
277 # save the slice gid in /etc/sfa/ in the vservers filesystem
278 vserver_path = "/vservers/%(slicename)s" % locals()
280 slice_gid_filename = os.sep.join([vserver_path, "etc", "slice.gid"])
282 print("Saving GID for %(slicename)s as %(slice_gid_filename)s" % locals())
283 GID(string=gid).save_to_file(slice_gid_filename, save_parents=True)
284 # save the node gid in /etc/sfa
285 node_gid_filename = os.sep.join([vserver_path, "etc", "node.gid"])
287 print("Saving node GID for %(slicename)s as %(node_gid_filename)s" % locals())
288 node_gid.save_to_file(node_gid_filename, save_parents=True)
291 def dispatch(options, args):
293 create_default_dirs()
296 print("Getting the component's pkey")
297 get_node_key(registry=options.registry, verbose=options.verbose)
300 print("Getting the component's trusted certs")
301 get_trusted_certs(verbose=options.verbose)
304 print("Geting the component's GIDs")
305 get_gids(verbose=options.verbose)
311 parser = OptionParser(usage="%(prog_name)s [options]" % locals())
312 parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
313 default=False, help="Be verbose")
314 parser.add_option("-r", "--registry", dest="registry", default=None,
315 help="Url of registry to contact")
316 parser.add_option("-k", "--key", dest="key", action="store_true",
318 help="Get the node's pkey from the registry")
319 parser.add_option("-c", "--certs", dest="certs", action="store_true",
321 help="Get the trusted certs from the registry")
322 parser.add_option("-g", "--gids", dest="gids", action="store_true",
324 help="Get gids for all the slices on the component")
326 (options, args) = parser.parse_args()
328 dispatch(options, args)
330 if __name__ == '__main__':