3 # sfi -- slice-based facility interface
11 from types import StringTypes, ListType
12 from optparse import OptionParser
13 from sfa.trust.certificate import Keypair, Certificate
14 from sfa.trust.credential import Credential
15 from sfa.util.geniclient import GeniClient
16 from sfa.util.sfaticket import SfaTicket
17 from sfa.util.record import *
18 from sfa.util.misc import *
19 from sfa.util.rspec import RSpec
20 from sfa.util.xmlrpcprotocol import ServerException
21 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
22 from sfa.util.config import Config
24 # utility methods here
26 def display_rspec(rspec, format = 'rspec'):
29 spec.parseString(rspec)
31 nodespecs = spec.getDictsByTagName('NodeSpec')
32 for nodespec in nodespecs:
33 if nodespec.has_key('name') and nodespec['name']:
34 if isinstance(nodespec['name'], ListType):
35 hostnames.extend(nodespec['name'])
36 elif isinstance(nodespec['name'], StringTypes):
37 hostnames.append(nodespec['name'])
39 elif format in ['ip']:
41 spec.parseString(rspec)
43 ifspecs = spec.getDictsByTagName('IfSpec')
44 for ifspec in ifspecs:
45 if ifspec.has_key('addr') and ifspec['addr']:
46 ips.append(ifspec['addr'])
54 def display_list(results):
55 for result in results:
59 def display_records(recordList, dump = False):
60 ''' Print all fields in the record'''
61 for record in recordList:
62 display_record(record, dump)
64 def display_record(record, dump = False):
68 info = record.getdict()
69 print "%s (%s)" % (info['hrn'], info['type'])
73 def filter_records(type, records):
75 for record in records:
76 if (record['type'] == type) or (type == "all"):
77 filtered_records.append(record)
78 return filtered_records
82 def save_rspec_to_file(rspec, filename):
83 if not filename.endswith(".rspec"):
84 filename = filename + ".rspec"
86 f = open(filename, 'w')
91 def save_records_to_file(filename, recordList):
93 for record in recordList:
95 save_record_to_file(filename + "." + str(index), record)
97 save_record_to_file(filename, record)
100 def save_record_to_file(filename, record):
101 if record['type'] in ['user']:
102 record = UserRecord(dict = record)
103 elif record['type'] in ['slice']:
104 record = SliceRecord(dict = record)
105 elif record['type'] in ['node']:
106 record = NodeRecord(dict = record)
107 elif record['type'] in ['authority', 'ma', 'sa']:
108 record = AuthorityRecord(dict = record)
110 record = GeniRecord(dict = record)
111 str = record.save_to_string()
112 file(filename, "w").write(str)
117 def load_record_from_file(filename):
118 str = file(filename, "r").read()
119 record = GeniRecord(string=str)
133 def create_cmd_parser(self,command, additional_cmdargs = None):
134 cmdargs = {"gid": "",
140 "aggregates": "[name]",
141 "registries": "[name]",
143 "resources": "[name]",
144 "create": "name rspec",
145 "get_trusted_certs": "cred",
146 "get_ticket": "name rspec",
147 "redeem_ticket": "ticket",
155 if additional_cmdargs:
156 cmdargs.update(additional_cmdargs)
158 if command not in cmdargs:
159 print "Invalid command\n"
161 for key in cmdargs.keys():
166 parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \
167 % (command, cmdargs[command]))
169 if command in ("resources"):
170 parser.add_option("-f", "--format", dest="format",type="choice",
171 help="display format ([xml]|dns|ip)",default="xml",
172 choices=("xml","dns","ip"))
173 parser.add_option("-a", "--aggregate", dest="aggregate",
174 default=None, help="aggregate hrn")
176 if command in ("create", "get_ticket"):
177 parser.add_option("-a", "--aggregate", dest="aggregate",default=None,
178 help="aggregate hrn")
180 if command in ("start", "stop", "reset", "delete", "slices"):
181 parser.add_option("-c", "--component", dest="component",default=None,
182 help="component hrn")
184 if command in ("list", "show", "remove"):
185 parser.add_option("-t", "--type", dest="type",type="choice",
186 help="type filter ([all]|user|slice|sa|ma|node|aggregate)",
187 choices=("all","user","slice","sa","ma","node","aggregate"),
190 if command in ("resources", "show", "list"):
191 parser.add_option("-o", "--output", dest="file",
192 help="output XML to file", metavar="FILE", default=None)
194 if command in ("show", "list"):
195 parser.add_option("-f", "--format", dest="format", type="choice",
196 help="display format ([text]|xml)",default="text",
197 choices=("text","xml"))
199 if command in ("delegate"):
200 parser.add_option("-u", "--user",
201 action="store_true", dest="delegate_user", default=False,
202 help="delegate user credential")
203 parser.add_option("-s", "--slice", dest="delegate_slice",
204 help="delegate slice credential", metavar="HRN", default=None)
208 def create_parser(self):
210 # Generate command line parser
211 parser = OptionParser(usage="sfi [options] command [command_options] [command_args]",
212 description="Commands: gid,list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset")
213 parser.add_option("-r", "--registry", dest="registry",
214 help="root registry", metavar="URL", default=None)
215 parser.add_option("-s", "--slicemgr", dest="sm",
216 help="slice manager", metavar="URL", default=None)
217 default_sfi_dir=os.path.expanduser("~/.sfi/")
218 parser.add_option("-d", "--dir", dest="sfi_dir",
219 help="config & working directory - default is " + default_sfi_dir,
220 metavar="PATH", default = default_sfi_dir)
221 parser.add_option("-u", "--user", dest="user",
222 help="user name", metavar="HRN", default=None)
223 parser.add_option("-a", "--auth", dest="auth",
224 help="authority name", metavar="HRN", default=None)
225 parser.add_option("-v", "--verbose",
226 action="store_true", dest="verbose", default=False,
228 parser.add_option("-p", "--protocol",
229 dest="protocol", default="xmlrpc",
230 help="RPC protocol (xmlrpc or soap)")
231 parser.add_option("-k", "--hashrequest",
232 action="store_true", dest="hashrequest", default=False,
233 help="Create a hash of the request that will be authenticated on the server")
234 parser.disable_interspersed_args()
240 # Establish Connection to SliceMgr and Registry Servers
242 def set_servers(self):
243 config_file = self.options.sfi_dir + os.sep + "sfi_config"
245 config = Config (config_file)
247 print "Failed to read configuration file",config_file
248 print "Make sure to remove the export clauses and to add quotes"
249 if not self.options.verbose:
250 print "Re-run with -v for more details"
252 traceback.print_exc()
257 if (self.options.sm is not None):
258 sm_url = self.options.sm
259 elif hasattr(config,"SFI_SM"):
260 sm_url = config.SFI_SM
262 print "You need to set e.g. SFI_SM='http://your.slicemanager.url:12347/' in %s"%config_file
266 if (self.options.registry is not None):
267 reg_url = self.options.registry
268 elif hasattr(config,"SFI_REGISTRY"):
269 reg_url = config.SFI_REGISTRY
271 print "You need to set e.g. SFI_REGISTRY='http://your.registry.url:12345/' in %s"%config_file
275 if (self.options.user is not None):
276 self.user = self.options.user
277 elif hasattr(config,"SFI_USER"):
278 self.user = config.SFI_USER
280 print "You need to set e.g. SFI_USER='plc.princeton.username' in %s"%config_file
284 if (self.options.auth is not None):
285 self.authority = self.options.auth
286 elif hasattr(config,"SFI_AUTH"):
287 self.authority = config.SFI_AUTH
289 print "You need to set e.g. SFI_AUTH='plc.princeton' in %s"%config_file
295 if self.options.verbose :
296 print "Contacting Slice Manager at:", sm_url
297 print "Contacting Registry at:", reg_url
299 # Get key and certificate
300 key_file = self.get_key_file()
301 cert_file = self.get_cert_file(key_file)
302 self.key = Keypair(filename=key_file)
303 self.key_file = key_file
304 self.cert_file = cert_file
305 self.cert = Certificate(filename=cert_file)
306 # Establish connection to server(s)
307 #self.slicemgr = GeniClient(sm_url, key_file, cert_file, self.options.protocol)
308 #self.registry = GeniClient(reg_url, key_file, cert_file, self.options.protocol)
309 self.registry = xmlrpcprotocol.get_server(reg_url, key_file, cert_file)
310 self.slicemgr = xmlrpcprotocol.get_server(sm_url, key_file, cert_file)
314 # Get various credential and spec files
316 # Establishes limiting conventions
317 # - conflates MAs and SAs
318 # - assumes last token in slice name is unique
320 # Bootstraps credentials
321 # - bootstrap user credential from self-signed certificate
322 # - bootstrap authority credential from user credential
323 # - bootstrap slice credential from user credential
327 def get_key_file(self):
328 file=os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".pkey")
329 #file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".pkey")
330 if (os.path.isfile(file)):
333 print "Key file", file, "does not exist"
337 def get_cert_file(self,key_file):
339 #file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".cert")
340 file=os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert")
341 if (os.path.isfile(file)):
344 k = Keypair(filename = key_file)
345 cert = Certificate(subject=self.user)
347 cert.set_issuer(k, self.user)
349 if self.options.verbose :
350 print "Writing self-signed certificate to", file
351 cert.save_to_file(file)
355 #file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".gid")
356 file=os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".gid")
357 if (os.path.isfile(file)):
358 gid = GID(filename=file)
361 cert_str = self.cert.save_to_string(save_parents=True)
364 request_hash = self.key.compute_hash([cert_str, self.user, "user"])
365 gid_str = self.registry.get_gid(cert_str, self.user, "user", request_hash)
366 gid = GID(string=gid_str)
367 if self.options.verbose:
368 print "Writing user gid to", file
369 gid.save_to_file(file, save_parents=True)
372 def get_user_cred(self):
373 #file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".cred")
374 file=os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cred")
375 if (os.path.isfile(file)):
376 user_cred = Credential(filename=file)
379 # bootstrap user credential
380 cert_string = self.cert.save_to_string(save_parents=True)
383 request_hash = self.key.compute_hash([cert_string, "user", self.user])
384 user_name=self.user.replace(self.authority+".", '')
385 if user_name.count(".") > 0:
386 user_name = user_name.replace(".", '_')
387 self.user=self.authority + "." + user_name
388 user_cred = self.registry.get_self_credential(cert_string, "user", self.user, request_hash)
390 cred = Credential(string=user_cred)
391 cred.save_to_file(file, save_parents=True)
392 if self.options.verbose:
393 print "Writing user credential to", file
396 print "Failed to get user credential"
399 def get_auth_cred(self):
400 if not self.authority:
401 print "no authority specified. Use -a or set SF_AUTH"
404 file = os.path.join(self.options.sfi_dir, get_leaf("authority") +".cred")
405 if (os.path.isfile(file)):
406 auth_cred = Credential(filename=file)
409 # bootstrap authority credential from user credential
410 user_cred = self.get_user_cred().save_to_string(save_parents=True)
413 request_hash = self.key.compute_hash([user_cred, "authority", self.authority])
414 auth_cred = self.registry.get_credential(user_cred, "authority", self.authority, request_hash)
416 cred = Credential(string=auth_cred)
417 cred.save_to_file(file, save_parents=True)
418 if self.options.verbose:
419 print "Writing authority credential to", file
422 print "Failed to get authority credential"
425 def get_slice_cred(self,name):
426 file = os.path.join(self.options.sfi_dir, "slice_" + get_leaf(name) + ".cred")
427 if (os.path.isfile(file)):
428 slice_cred = Credential(filename=file)
431 # bootstrap slice credential from user credential
432 user_cred = self.get_user_cred().save_to_string(save_parents=True)
433 arg_list = [user_cred, "slice", name]
436 request_hash = self.key.compute_hash(arg_list)
437 slice_cred_str = self.registry.get_credential(user_cred, "slice", name, request_hash)
439 slice_cred = Credential(string=slice_cred_str)
440 slice_cred.save_to_file(file, save_parents=True)
441 if self.options.verbose:
442 print "Writing slice credential to", file
445 print "Failed to get slice credential"
448 def delegate_cred(self,cred, hrn, type = 'authority'):
449 # the gid and hrn of the object we are delegating
450 user_cred = Credential(string=cred)
451 object_gid = user_cred.get_gid_object()
452 object_hrn = object_gid.get_hrn()
453 #cred.set_delegate(True)
454 #if not cred.get_delegate():
455 # raise Exception, "Error: Object credential %(object_hrn)s does not have delegate bit set" % locals()
458 records = self.registry.resolve(cred, hrn)
459 records = filter_records(type, records)
462 raise Exception, "Error: Didn't find a %(type)s record for %(hrn)s" % locals()
464 # the gid of the user who will be delegated too
465 record = GeniRecord(dict=records[0])
466 delegee_gid = record.get_gid_object()
467 delegee_hrn = delegee_gid.get_hrn()
469 # the key and hrn of the user who will be delegating
470 user_key = Keypair(filename = self.get_key_file())
471 user_hrn = user_cred.get_gid_caller().get_hrn()
473 dcred = Credential(subject=object_hrn + " delegated to " + delegee_hrn)
474 dcred.set_gid_caller(delegee_gid)
475 dcred.set_gid_object(object_gid)
476 dcred.set_privileges(user_cred.get_privileges())
477 dcred.set_delegate(True)
478 dcred.set_pubkey(object_gid.get_pubkey())
479 dcred.set_issuer(user_key, user_hrn)
480 dcred.set_parent(user_cred)
484 return dcred.save_to_string(save_parents=True)
486 def get_rspec_file(self,rspec):
487 if (os.path.isabs(rspec)):
490 file = os.path.join(self.options.sfi_dir, rspec)
491 if (os.path.isfile(file)):
494 print "No such rspec file", rspec
497 def get_record_file(self,record):
498 if (os.path.isabs(record)):
501 file = os.path.join(self.options.sfi_dir, record)
502 if (os.path.isfile(file)):
505 print "No such registry record file", record
508 def load_publickey_string(self,fn):
510 key_string = f.read()
512 # if the filename is a private key file, then extract the public key
513 if "PRIVATE KEY" in key_string:
514 outfn = tempfile.mktemp()
515 cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
518 key_string = f.read()
523 def get_component_server_from_hrn(self, hrn):
524 # direct connection to the nodes component manager interface
525 user_cred = self.get_user_cred().save_to_string(save_parents=True)
526 request_hash = self.key.compute_hash([user_cred, hrn])
527 records = self.registry.resolve(user_cred, hrn, request_hash)
528 records = filter_records('node', records)
530 print "No such component:", opts.component
533 url = "https://%s:%s" % (record['hostname'], cm_port)
534 return xmlrpcprotocol.get_server(url, self.key_file, self.cert_file)
537 # Following functions implement the commands
539 # Registry-related commands
542 def dispatch(self,command, cmd_opts, cmd_args):
543 getattr(self,command)(cmd_opts, cmd_args)
545 def gid(self, opts, args):
547 print "GID: %s" % (gid.save_to_string(save_parents=True))
550 # list entires in named authority registry
551 def list(self,opts, args):
552 user_cred = self.get_user_cred().save_to_string(save_parents=True)
556 request_hash = self.key.compute_hash([user_cred, hrn])
558 list = self.registry.list(user_cred, hrn, request_hash)
560 raise Exception, "Not enough parameters for the 'list' command"
562 # filter on person, slice, site, node, etc.
563 # THis really should be in the self.filter_records funct def comment...
564 list = filter_records(opts.type, list)
566 print "%s (%s)" % (record['hrn'], record['type'])
569 if not file.startswith(os.sep):
570 file = os.path.join(self.options.sfi_dir, file)
571 save_records_to_file(file, list)
574 # show named registry record
575 def show(self,opts, args):
576 user_cred = self.get_user_cred().save_to_string(save_parents=True)
580 request_hash = self.key.compute_hash([user_cred, hrn])
581 records = self.registry.resolve(user_cred, hrn, request_hash)
582 records = filter_records(opts.type, records)
584 print "No record of type", opts.type
585 for record in records:
586 if record['type'] in ['user']:
587 record = UserRecord(dict = record)
588 elif record['type'] in ['slice']:
589 record = SliceRecord(dict = record)
590 elif record['type'] in ['node']:
591 record = NodeRecord(dict = record)
592 elif record['type'] in ['authority', 'ma', 'sa']:
593 record = AuthorityRecord(dict = record)
595 record = GeniRecord(dict = record)
596 if (opts.format=="text"):
599 print record.save_to_string()
603 if not file.startswith(os.sep):
604 file = os.path.join(self.options.sfi_dir, file)
605 save_records_to_file(file, records)
608 def delegate(self,opts, args):
609 user_cred = self.get_user_cred()
610 if opts.delegate_user:
611 object_cred = user_cred
612 elif opts.delegate_slice:
613 object_cred = self.get_slice_cred(opts.delegate_slice)
615 print "Must specify either --user or --slice <hrn>"
618 # the gid and hrn of the object we are delegating
619 object_gid = object_cred.get_gid_object()
620 object_hrn = object_gid.get_hrn()
622 if not object_cred.get_delegate():
623 print "Error: Object credential", object_hrn, "does not have delegate bit set"
626 records = self.registry.resolve(user_cred, args[0])
627 records = filter_records("user", records)
630 print "Error: Didn't find a user record for", args[0]
633 # the gid of the user who will be delegated too
634 delegee_gid = records[0].get_gid_object()
635 delegee_hrn = delegee_gid.get_hrn()
637 # the key and hrn of the user who will be delegating
638 user_key = Keypair(filename = self.get_key_file())
639 user_hrn = user_cred.get_gid_caller().get_hrn()
641 dcred = Credential(subject=object_hrn + " delegated to " + delegee_hrn)
642 dcred.set_gid_caller(delegee_gid)
643 dcred.set_gid_object(object_gid)
644 dcred.set_privileges(object_cred.get_privileges())
645 dcred.set_delegate(True)
646 dcred.set_pubkey(object_gid.get_pubkey())
647 dcred.set_issuer(user_key, user_hrn)
648 dcred.set_parent(object_cred)
652 if opts.delegate_user:
653 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_"
654 + get_leaf(object_hrn) + ".cred")
655 elif opts.delegate_slice:
656 dest_fn = os.path_join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_"
657 + get_leaf(object_hrn) + ".cred")
659 dcred.save_to_file(dest_fn, save_parents = True)
661 print "delegated credential for", object_hrn, "to", delegee_hrn, "and wrote to", dest_fn
663 # removed named registry record
664 # - have to first retrieve the record to be removed
665 def remove(self,opts, args):
666 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
673 arg_list = [auth_cred, type, hrn]
674 request_hash = self.key.compute_hash(arg_list)
675 return self.registry.remove(auth_cred, type, hrn, request_hash)
677 # add named registry record
678 def add(self,opts, args):
679 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
680 record_filepath = args[0]
681 rec_file = self.get_record_file(record_filepath)
682 record = load_record_from_file(rec_file).as_dict()
685 arg_list = [auth_cred]
686 request_hash = self.key.compute_hash(arg_list)
687 return self.registry.register(auth_cred, record, request_hash)
689 # update named registry entry
690 def update(self,opts, args):
691 user_cred = self.get_user_cred()
692 rec_file = self.get_record_file(args[0])
693 record = load_record_from_file(rec_file)
694 if record['type'] == "user":
695 if record.get_name() == user_cred.get_gid_object().get_hrn():
696 cred = user_cred.save_to_string(save_parents=True)
698 cred = self.get_auth_cred().save_to_string(save_parents=True)
699 elif record['type'] in ["slice"]:
701 cred = self.get_slice_cred(record.get_name()).save_to_string(save_parents=True)
702 except ServerException, e:
703 # XXX smbaker -- once we have better error return codes, update this
704 # to do something better than a string compare
705 if "Permission error" in e.args[0]:
706 cred = self.get_auth_cred().save_to_string(save_parents=True)
709 elif record.get_type() in ["authority"]:
710 cred = self.get_auth_cred().save_to_string(save_parents=True)
711 elif record.get_type() == 'node':
712 cred = self.get_auth_cred().save_to_string(save_parents=True)
714 raise "unknown record type" + record.get_type()
715 record = record.as_dict()
719 request_hash = self.key.compute_hash(arg_list)
720 return self.registry.update(cred, record, request_hash)
722 def get_trusted_certs(self, opts, args):
724 return the trusted certs at this interface
726 trusted_certs = self.registry.get_trusted_certs()
727 for trusted_cert in trusted_certs:
728 cert = Certificate(string=trusted_cert)
729 print cert.get_subject()
732 def aggregates(self, opts, args):
734 return a list of details about known aggregates
736 user_cred = self.get_user_cred().save_to_string(save_parents=True)
742 arg_list = [user_cred, hrn]
743 request_hash = self.key.compute_hash(arg_list)
744 result = self.registry.get_aggregates(user_cred, hrn, request_hash)
748 def registries(self, opts, args):
750 return a list of details about known registries
752 user_cred = self.get_user_cred().save_to_string(save_parents=True)
758 arg_list = [user_cred, hrn]
759 request_hash = self.key.compute_hash(arg_list)
760 result = self.registry.get_registries(user_cred, hrn, request_hash)
766 # Slice-related commands
769 # list available nodes -- use 'resources' w/ no argument instead
771 # list instantiated slices
772 def slices(self,opts, args):
773 user_cred = self.get_user_cred().save_to_string(save_parents=True)
776 arg_list = [user_cred]
777 request_hash = self.key.compute_hash(arg_list)
779 server = self.slicemgr
780 # direct connection to the nodes component manager interface
782 server = self.get_component_server_from_hrn(opts.component)
783 results = server.get_slices(user_cred, request_hash)
784 display_list(results)
787 # show rspec for named slice
788 def resources(self,opts, args):
789 user_cred = self.get_user_cred().save_to_string(save_parents=True)
790 server = self.slicemgr
792 agg_hrn = opts.aggregate
793 arg_list = [user_cred, agg_hrn]
794 request_hash = self.key.compute_hash(arg_list)
795 aggregates = self.registry.get_aggregates(user_cred, agg_hrn, request_hash)
797 raise Exception, "No such aggregate %s" % agg_hrn
798 aggregate = aggregates[0]
799 url = "http://%s:%s" % (aggregate['addr'], aggregate['port'])
800 server = xmlrpcprotocol.get_server(url, self.key_file, self.cert_file)
802 cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
810 arg_list = [cred, hrn]
811 request_hash = self.key.compute_hash(arg_list)
812 result = server.get_resources(cred, hrn, request_hash)
815 display_rspec(result, format)
816 if (opts.file is not None):
818 if not file.startswith(os.sep):
819 file = os.path.join(self.options.sfi_dir, file)
820 save_rspec_to_file(result, file)
823 # created named slice with given rspec
824 def create(self,opts, args):
826 user_cred = self.get_user_cred()
827 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
828 rspec_file = self.get_rspec_file(args[1])
829 rspec=open(rspec_file).read()
830 server = self.slicemgr
832 aggregates = self.registry.get_aggregates(user_cred, opts.aggregate)
834 raise Exception, "No such aggregate %s" % opts.aggregate
835 aggregate = aggregates[0]
836 url = "http://%s:%s" % (aggregate['addr'], aggregate['port'])
837 server = GeniClient(url, self.key_file, self.cert_file, self.options.protocol)
840 arg_list = [slice_cred, slice_hrn, rspec]
841 request_hash = self.key.compute_hash(arg_list)
842 return server.create_slice(slice_cred, slice_hrn, rspec, request_hash)
844 # get a ticket for the specified slice
845 def get_ticket(self, opts, args):
846 slice_hrn, rspec_path = args[0], args[1]
847 user_cred = self.get_user_cred()
848 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
849 rspec_file = self.get_rspec_file(rspec_path)
850 rspec=open(rspec_file).read()
851 server = self.slicemgr
853 aggregates = self.registry.get_aggregates(user_cred, opts.aggregate)
855 raise Exception, "No such aggregate %s" % opts.aggregate
856 aggregate = aggregates[0]
857 url = "http://%s:%s" % (aggregate['addr'], aggregate['port'])
858 server = GeniClient(url, self.key_file, self.cert_file, self.options.protocol)
861 arg_list = [slice_cred, slice_hrn, rspec]
862 request_hash = self.key.compute_hash(arg_list)
863 ticket_string = server.get_ticket(slice_cred, slice_hrn, rspec, request_hash)
864 file = os.path.join(self.options.sfi_dir, get_leaf(slice_hrn) + ".ticket")
865 print "writing ticket to ", file
866 ticket = SfaTicket(string=ticket_string)
867 ticket.save_to_file(filename=file, save_parents=True)
869 def redeem_ticket(self, opts, args):
870 ticket_file = args[0]
872 # get slice hrn from the ticket
873 # use this to get the right slice credential
874 ticket = SfaTicket(filename=ticket_file)
876 slice_hrn = ticket.attributes['slivers'][0]['hrn']
877 user_cred = self.get_user_cred()
878 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
880 # get a list node hostnames from the nodespecs in the rspec
882 rspec.parseString(ticket.rspec)
883 nodespecs = rspec.getDictsByTagName('NodeSpec')
884 hostnames = [nodespec['name'] for nodespec in nodespecs]
886 # create an xmlrpc connection to the component manager at each of these
887 # components and gall redeem_ticket
889 for hostname in hostnames:
892 url = "https://%(hostname)s:%(cm_port)s" % locals()
893 print "Calling get_ticket at %(url)s " % locals(),
894 cm = xmlrpcprotocol.get_server(url, self.key_file, self.cert_file)
895 cm.redeem_ticket(slice_cred, ticket.save_to_string(save_parents=True))
897 except socket.gaierror:
899 print "Componet Manager not accepting requests"
901 print "Failed:", e.message
906 def delete(self,opts, args):
908 server = self.slicemgr
909 # direct connection to the nodes component manager interface
911 server = self.get_component_server_from_hrn(opts.component)
913 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
916 arg_list = [slice_cred, slice_hrn]
917 request_hash = self.key.compute_hash(arg_list)
918 return server.delete_slice(slice_cred, slice_hrn, request_hash)
921 def start(self,opts, args):
923 server = self.slicemgr
924 # direct connection to the nodes component manager interface
926 server = self.get_component_server_from_hrn(opts.component)
928 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
931 arg_list = [slice_cred, slice_hrn]
932 request_hash = self.key.compute_hash(arg_list)
933 return server.start_slice(slice_cred, slice_hrn, request_hash)
936 def stop(self,opts, args):
938 server = self.slicemgr
939 # direct connection to the nodes component manager interface
941 server = self.get_component_server_from_hrn(opts.component)
943 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
946 arg_list = [slice_cred, slice_hrn]
947 request_hash = self.key.compute_hash(arg_list)
948 return server.stop_slice(slice_cred, slice_hrn, request_hash)
951 def reset(self,opts, args):
953 server = self.slicemgr
954 # direct connection to the nodes component manager interface
956 server = self.get_component_server_from_hrn(opts.component)
957 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
960 arg_list = [slice_cred, slice_hrn]
961 request_hash = self.key.compute_hash(arg_list)
962 return server.reset_slice(slice_cred, slice_hrn, request_hash)
965 # Main: parse arguments and dispatch to command
968 parser = self.create_parser()
969 (options, args) = parser.parse_args()
970 self.options = options
972 if options.hashrequest:
973 self.hashrequest=True
976 print "No command given. Use -h for help."
980 (cmd_opts, cmd_args) = self.create_cmd_parser(command).parse_args(args[1:])
981 if self.options.verbose :
982 print "Registry %s, sm %s, dir %s, user %s, auth %s" % (options.registry, options.sm,
983 options.sfi_dir, options.user,
985 print "Command %s" %command
986 if command in ("resources"):
987 print "resources cmd_opts %s" %cmd_opts.format
988 elif command in ("list","show","remove"):
989 print "cmd_opts.type %s" %cmd_opts.type
990 print "cmd_args %s" %cmd_args
995 self.dispatch(command, cmd_opts, cmd_args)
998 print "Command not found:", command
1003 if __name__=="__main__":