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/"
24 def handle_gid_mismatch_exception(f):
25 def wrapper(*args, **kwds):
26 try: return f(*args, **kwds)
27 except ConnectionKeyGIDMismatch:
28 # clean regen server keypair and try again
29 print("cleaning keys and trying again")
35 def server_proxy(url=None, port=None, keyfile=None, certfile=None,verbose=False):
37 returns an xmlrpc connection to the service a the specified
41 url_parts = url.split(":")
45 url = "http://%(url)s:%(port)s" % locals()
47 # connect to registry by default
49 addr, port = config.SFA_REGISTRY_HOST, config.SFA_REGISTRY_PORT
50 url = "http://%(addr)s:%(port)s" % locals()
53 print("Contacting registry at: %(url)s" % locals())
55 server = SfaServerProxy(url, keyfile, certfile)
59 def create_default_dirs():
61 hierarchy = Hierarchy()
62 config_dir = config.config_path
63 trusted_certs_dir = config.get_trustedroots_dir()
64 authorities_dir = hierarchy.basedir
65 all_dirs = [config_dir, trusted_certs_dir, authorities_dir]
67 if not os.path.exists(dir):
71 key_file = KEYDIR + os.sep + 'server.key'
72 return os.path.exists(key_file)
76 remove the existing keypair and cred and generate new ones
78 files = ["server.key", "server.cert", "node.cred"]
80 filepath = KEYDIR + os.sep + f
81 if os.path.isfile(filepath):
84 # install the new key pair
85 # GetCredential will take care of generating the new keypair
90 def get_node_key(registry=None, verbose=False):
91 # this call requires no authentication,
92 # so we can generate a random keypair here
94 (kfd, keyfile) = tempfile.mkstemp()
95 (cfd, certfile) = tempfile.mkstemp()
96 key = Keypair(create=True)
97 key.save_to_file(keyfile)
98 cert = Certificate(subject=subject)
99 cert.set_issuer(key=key, subject=subject)
102 cert.save_to_file(certfile)
104 registry = server_proxy(url = registry, keyfile=keyfile, certfile=certfile)
105 registry.get_key_from_incoming_ip()
107 def create_server_keypair(keyfile=None, certfile=None, hrn="component", verbose=False):
109 create the server key/cert pair in the right place
111 key = Keypair(filename=keyfile)
112 key.save_to_file(keyfile)
113 cert = Certificate(subject=hrn)
114 cert.set_issuer(key=key, subject=hrn)
117 cert.save_to_file(certfile, save_parents=True)
119 @handle_gid_mismatch_exception
120 def GetCredential(registry=None, force=False, verbose=False):
122 hierarchy = Hierarchy()
123 key_dir= hierarchy.basedir
124 data_dir = config.data_path
125 config_dir = config.config_path
126 credfile = data_dir + os.sep + 'node.cred'
127 # check for existing credential
128 if not force and os.path.exists(credfile):
130 print("Loading Credential from %(credfile)s " % locals())
131 cred = Credential(filename=credfile).save_to_string(save_parents=True)
134 print("Getting credential from registry")
135 # make sure node private key exists
136 node_pkey_file = config_dir + os.sep + "node.key"
137 node_gid_file = config_dir + os.sep + "node.gid"
138 if not os.path.exists(node_pkey_file) or \
139 not os.path.exists(node_gid_file):
140 get_node_key(registry=registry, verbose=verbose)
142 gid = GID(filename=node_gid_file)
144 # create server key and certificate
145 keyfile =data_dir + os.sep + "server.key"
146 certfile = data_dir + os.sep + "server.cert"
147 key = Keypair(filename=node_pkey_file)
148 key.save_to_file(keyfile)
149 create_server_keypair(keyfile, certfile, hrn, verbose)
151 # get credential from registry
152 registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
153 cert = Certificate(filename=certfile)
154 cert_str = cert.save_to_string(save_parents=True)
155 cred = registry.GetSelfCredential(cert_str, 'node', hrn)
156 Credential(string=cred).save_to_file(credfile, save_parents=True)
160 @handle_gid_mismatch_exception
161 def get_trusted_certs(registry=None, verbose=False):
163 refresh our list of trusted certs.
165 # define useful variables
167 data_dir = config.SFA_DATA_DIR
168 config_dir = config.SFA_CONFIG_DIR
169 trusted_certs_dir = config.get_trustedroots_dir()
170 keyfile = data_dir + os.sep + "server.key"
171 certfile = data_dir + os.sep + "server.cert"
172 node_gid_file = config_dir + os.sep + "node.gid"
173 node_gid = GID(filename=node_gid_file)
174 hrn = node_gid.get_hrn()
176 cred = GetCredential(registry=registry, verbose=verbose)
177 # make sure server key cert pair exists
178 create_server_keypair(keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
179 registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
180 # get the trusted certs and save them in the right place
182 print("Getting trusted certs from registry")
183 trusted_certs = registry.get_trusted_certs(cred)
184 trusted_gid_names = []
185 for gid_str in trusted_certs:
186 gid = GID(string=gid_str)
188 relative_filename = gid.get_hrn() + ".gid"
189 trusted_gid_names.append(relative_filename)
190 gid_filename = trusted_certs_dir + os.sep + relative_filename
192 print("Writing GID for %s as %s" % (gid.get_hrn(), gid_filename))
193 gid.save_to_file(gid_filename, save_parents=True)
196 all_gids_names = os.listdir(trusted_certs_dir)
197 for gid_name in all_gids_names:
198 if gid_name not in trusted_gid_names:
200 print("Removing old gid ", gid_name)
201 os.unlink(trusted_certs_dir + os.sep + gid_name)
203 @handle_gid_mismatch_exception
204 def get_gids(registry=None, verbose=False):
206 Get the gid for all instantiated slices on this node and store it
207 in /etc/sfa/slice.gid in the slice's filesystem
209 # define useful variables
211 data_dir = config.data_path
212 config_dir = config.SFA_CONFIG_DIR
213 trusted_certs_dir = config.get_trustedroots_dir()
214 keyfile = data_dir + os.sep + "server.key"
215 certfile = data_dir + os.sep + "server.cert"
216 node_gid_file = config_dir + os.sep + "node.gid"
217 node_gid = GID(filename=node_gid_file)
218 hrn = node_gid.get_hrn()
219 interface_hrn = config.SFA_INTERFACE_HRN
221 cred = GetCredential(registry=registry, verbose=verbose)
222 # make sure server key cert pair exists
223 create_server_keypair(keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
224 registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
227 print("Getting current slices on this node")
228 # get a list of slices on this node
229 from sfa.generic import Generic
230 generic=Generic.the_flavour()
231 api = generic.make_api(interface='component')
232 xids_tuple = api.driver.nodemanager.GetXIDs()
233 slices = eval(xids_tuple[1])
234 slicenames = slices.keys()
236 # generate a list of slices that dont have gids installed
237 slices_without_gids = []
238 for slicename in slicenames:
239 if not os.path.isfile("/vservers/%s/etc/slice.gid" % slicename) \
240 or not os.path.isfile("/vservers/%s/etc/node.gid" % slicename):
241 slices_without_gids.append(slicename)
243 # convert slicenames to hrns
244 hrns = [slicename_to_hrn(interface_hrn, slicename) \
245 for slicename in slices_without_gids]
247 # exit if there are no gids to install
252 print("Getting gids for slices on this node from registry")
254 # and save them in the right palce
255 records = registry.GetGids(hrns, cred)
256 for record in records:
257 # if this isnt a slice record skip it
258 if not record['type'] == 'slice':
260 slicename = hrn_to_pl_slicename(record['hrn'])
261 # if this slice isnt really instatiated skip it
262 if not os.path.exists("/vservers/%(slicename)s" % locals()):
265 # save the slice gid in /etc/sfa/ in the vservers filesystem
266 vserver_path = "/vservers/%(slicename)s" % locals()
268 slice_gid_filename = os.sep.join([vserver_path, "etc", "slice.gid"])
270 print("Saving GID for %(slicename)s as %(slice_gid_filename)s" % locals())
271 GID(string=gid).save_to_file(slice_gid_filename, save_parents=True)
272 # save the node gid in /etc/sfa
273 node_gid_filename = os.sep.join([vserver_path, "etc", "node.gid"])
275 print("Saving node GID for %(slicename)s as %(node_gid_filename)s" % locals())
276 node_gid.save_to_file(node_gid_filename, save_parents=True)
279 def dispatch(options, args):
281 create_default_dirs()
284 print("Getting the component's pkey")
285 get_node_key(registry=options.registry, verbose=options.verbose)
288 print("Getting the component's trusted certs")
289 get_trusted_certs(verbose=options.verbose)
292 print("Geting the component's GIDs")
293 get_gids(verbose=options.verbose)
298 parser = OptionParser(usage="%(prog_name)s [options]" % locals())
299 parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
300 default=False, help="Be verbose")
301 parser.add_option("-r", "--registry", dest="registry", default=None,
302 help="Url of registry to contact")
303 parser.add_option("-k", "--key", dest="key", action="store_true",
305 help="Get the node's pkey from the registry")
306 parser.add_option("-c", "--certs", dest="certs", action="store_true",
308 help="Get the trusted certs from the registry")
309 parser.add_option("-g", "--gids", dest="gids", action="store_true",
311 help="Get gids for all the slices on the component")
313 (options, args) = parser.parse_args()
315 dispatch(options, args)
317 if __name__ == '__main__':