3 # sfi -- slice-based facility interface
13 from lxml import etree
14 from StringIO import StringIO
15 from types import StringTypes, ListType
16 from optparse import OptionParser
19 from sfa.util.sfalogging import sfa_logger,sfa_logger_goes_to_console
20 from sfa.trust.certificate import Keypair, Certificate
21 from sfa.trust.gid import GID
22 from sfa.trust.credential import Credential
23 from sfa.util.sfaticket import SfaTicket
24 from sfa.util.record import SfaRecord, UserRecord, SliceRecord, NodeRecord, AuthorityRecord
25 from sfa.util.xrn import Xrn, get_leaf, get_authority, hrn_to_urn
26 from sfa.util.xmlrpcprotocol import ServerException
27 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
28 from sfa.util.config import Config
29 from sfa.util.version import version_core
34 # utility methods here
36 def display_rspec(rspec, format='rspec'):
38 tree = etree.parse(StringIO(rspec))
40 result = root.xpath("./network/site/node/hostname/text()")
41 elif format in ['ip']:
42 # The IP address is not yet part of the new RSpec
43 # so this doesn't do anything yet.
44 tree = etree.parse(StringIO(rspec))
46 result = root.xpath("./network/site/node/ipv4/text()")
53 def display_list(results):
54 for result in results:
57 def display_records(recordList, dump=False):
58 ''' Print all fields in the record'''
59 for record in recordList:
60 display_record(record, dump)
62 def display_record(record, dump=False):
66 info = record.getdict()
67 print "%s (%s)" % (info['hrn'], info['type'])
71 def filter_records(type, records):
73 for record in records:
74 if (record['type'] == type) or (type == "all"):
75 filtered_records.append(record)
76 return filtered_records
80 def save_rspec_to_file(rspec, filename):
81 if not filename.endswith(".rspec"):
82 filename = filename + ".rspec"
84 f = open(filename, 'w')
89 def save_records_to_file(filename, recordList):
91 for record in recordList:
93 save_record_to_file(filename + "." + str(index), record)
95 save_record_to_file(filename, record)
98 def save_record_to_file(filename, record):
99 if record['type'] in ['user']:
100 record = UserRecord(dict=record)
101 elif record['type'] in ['slice']:
102 record = SliceRecord(dict=record)
103 elif record['type'] in ['node']:
104 record = NodeRecord(dict=record)
105 elif record['type'] in ['authority', 'ma', 'sa']:
106 record = AuthorityRecord(dict=record)
108 record = SfaRecord(dict=record)
109 str = record.save_to_string()
110 file(filename, "w").write(str)
115 def load_record_from_file(filename):
116 str = file(filename, "r").read()
117 record = SfaRecord(string=str)
124 required_options=['verbose', 'debug', 'registry', 'sm', 'auth', 'user']
126 def __init__ (self,options=None):
127 for opt in Sfi.required_options:
128 if not hasattr(options,opt): setattr(options,opt,None)
129 if not hasattr(options,'sfi_dir'): options.sfi_dir=os.path.expanduser("~/.sfi/")
130 self.options = options
134 self.authority = None
135 self.hashrequest = False
136 sfa_logger_goes_to_console()
137 self.logger=sfa_logger()
139 def create_cmd_parser(self, command, additional_cmdargs=None):
140 cmdargs = {"list": "authority",
145 "aggregates": "[name]",
146 "registries": "[name]",
148 "get_trusted_certs": "cred",
150 "resources": "[name]",
151 "create": "name rspec",
152 "get_ticket": "name rspec",
153 "redeem_ticket": "ticket",
165 if additional_cmdargs:
166 cmdargs.update(additional_cmdargs)
168 if command not in cmdargs:
169 msg="Invalid command\n"
171 msg += ','.join(cmdargs.keys())
172 self.logger.critical(msg)
175 parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \
176 % (command, cmdargs[command]))
178 # user specifies remote aggregate/sm/component
179 if command in ("resources", "slices", "create", "delete", "start", "stop",
180 "restart", "shutdown", "get_ticket", "renew", "status"):
181 parser.add_option("-a", "--aggregate", dest="aggregate",
182 default=None, help="aggregate host")
183 parser.add_option("-p", "--port", dest="port",
184 default=AGGREGATE_PORT, help="aggregate port")
185 parser.add_option("-c", "--component", dest="component", default=None,
186 help="component hrn")
187 parser.add_option("-d", "--delegate", dest="delegate", default=None,
189 help="Include a credential delegated to the user's root"+\
190 "authority in set of credentials for this call")
192 # registy filter option
193 if command in ("list", "show", "remove"):
194 parser.add_option("-t", "--type", dest="type", type="choice",
195 help="type filter ([all]|user|slice|authority|node|aggregate)",
196 choices=("all", "user", "slice", "authority", "node", "aggregate"),
199 if command in ("resources"):
200 parser.add_option("-f", "--format", dest="format", type="choice",
201 help="display format ([xml]|dns|ip)", default="xml",
202 choices=("xml", "dns", "ip"))
204 if command in ("resources", "show", "list"):
205 parser.add_option("-o", "--output", dest="file",
206 help="output XML to file", metavar="FILE", default=None)
208 if command in ("show", "list"):
209 parser.add_option("-f", "--format", dest="format", type="choice",
210 help="display format ([text]|xml)", default="text",
211 choices=("text", "xml"))
213 if command in ("delegate"):
214 parser.add_option("-u", "--user",
215 action="store_true", dest="delegate_user", default=False,
216 help="delegate user credential")
217 parser.add_option("-s", "--slice", dest="delegate_slice",
218 help="delegate slice credential", metavar="HRN", default=None)
220 if command in ("version"):
221 parser.add_option("-R","--registry-version",
222 action="store_true", dest="version_registry", default=False,
223 help="probe registry version instead of slicemgr")
224 parser.add_option("-l","--local",
225 action="store_true", dest="version_local", default=False,
226 help="display version of the local client")
231 def create_parser(self):
233 # Generate command line parser
234 parser = OptionParser(usage="sfi [options] command [command_options] [command_args]",
235 description="Commands: gid,list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset")
236 parser.add_option("-r", "--registry", dest="registry",
237 help="root registry", metavar="URL", default=None)
238 parser.add_option("-s", "--slicemgr", dest="sm",
239 help="slice manager", metavar="URL", default=None)
240 default_sfi_dir = os.path.expanduser("~/.sfi/")
241 parser.add_option("-d", "--dir", dest="sfi_dir",
242 help="config & working directory - default is " + default_sfi_dir,
243 metavar="PATH", default=default_sfi_dir)
244 parser.add_option("-u", "--user", dest="user",
245 help="user name", metavar="HRN", default=None)
246 parser.add_option("-a", "--auth", dest="auth",
247 help="authority name", metavar="HRN", default=None)
248 parser.add_option("-v", "--verbose", action="count", dest="verbose", default=0,
249 help="verbose mode - cumulative")
250 parser.add_option("-D", "--debug",
251 action="store_true", dest="debug", default=False,
252 help="Debug (xml-rpc) protocol messages")
253 parser.add_option("-p", "--protocol", dest="protocol", default="xmlrpc",
254 help="RPC protocol (xmlrpc or soap)")
255 parser.add_option("-k", "--hashrequest",
256 action="store_true", dest="hashrequest", default=False,
257 help="Create a hash of the request that will be authenticated on the server")
258 parser.disable_interspersed_args()
263 def read_config(self):
264 config_file = self.options.sfi_dir + os.sep + "sfi_config"
266 config = Config (config_file)
268 self.logger.critical("Failed to read configuration file %s"%config_file)
269 self.logger.info("Make sure to remove the export clauses and to add quotes")
270 if self.options.verbose==0:
271 self.logger.info("Re-run with -v for more details")
273 self.logger.log_exc("Could not read config file %s"%config_file)
278 if (self.options.sm is not None):
279 self.sm_url = self.options.sm
280 elif hasattr(config, "SFI_SM"):
281 self.sm_url = config.SFI_SM
283 self.logger.error("You need to set e.g. SFI_SM='http://your.slicemanager.url:12347/' in %s" % config_file)
287 if (self.options.registry is not None):
288 self.reg_url = self.options.registry
289 elif hasattr(config, "SFI_REGISTRY"):
290 self.reg_url = config.SFI_REGISTRY
292 self.logger.errors("You need to set e.g. SFI_REGISTRY='http://your.registry.url:12345/' in %s" % config_file)
297 if (self.options.user is not None):
298 self.user = self.options.user
299 elif hasattr(config, "SFI_USER"):
300 self.user = config.SFI_USER
302 self.logger.errors("You need to set e.g. SFI_USER='plc.princeton.username' in %s" % config_file)
306 if (self.options.auth is not None):
307 self.authority = self.options.auth
308 elif hasattr(config, "SFI_AUTH"):
309 self.authority = config.SFI_AUTH
311 self.logger.error("You need to set e.g. SFI_AUTH='plc.princeton' in %s" % config_file)
319 # Establish Connection to SliceMgr and Registry Servers
321 def set_servers(self):
324 # Get key and certificate
325 key_file = self.get_key_file()
326 cert_file = self.get_cert_file(key_file)
327 self.key = Keypair(filename=key_file)
328 self.key_file = key_file
329 self.cert_file = cert_file
330 self.cert = Certificate(filename=cert_file)
331 # Establish connection to server(s)
332 self.logger.info("Contacting Registry at: %s"%self.reg_url)
333 self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, self.options)
334 self.logger.info("Contacting Slice Manager at: %s"%self.sm_url)
335 self.slicemgr = xmlrpcprotocol.get_server(self.sm_url, key_file, cert_file, self.options)
340 # Get various credential and spec files
342 # Establishes limiting conventions
343 # - conflates MAs and SAs
344 # - assumes last token in slice name is unique
346 # Bootstraps credentials
347 # - bootstrap user credential from self-signed certificate
348 # - bootstrap authority credential from user credential
349 # - bootstrap slice credential from user credential
353 def get_key_file(self):
354 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".pkey")
355 if (os.path.isfile(file)):
358 self.logger.error("Key file %s does not exist"%file)
362 def get_cert_file(self, key_file):
364 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert")
365 if (os.path.isfile(file)):
366 # use existing cert if it exists
370 # attempt to use gid as the cert.
371 gid = self._get_gid()
372 self.logger.info("Writing certificate to %s"%file)
373 gid.save_to_file(file)
375 # generate self signed certificate
376 k = Keypair(filename=key_file)
377 cert = Certificate(subject=self.user)
379 cert.set_issuer(k, self.user)
381 self.logger.info("Writing self-signed certificate to %s"%file)
382 cert.save_to_file(file)
386 def get_cached_gid(self, file):
391 if (os.path.isfile(file)):
392 gid = GID(filename=file)
396 def get_gid(self, opts, args):
398 Get the specify gid and save it to file
403 gid = self._get_gid(hrn)
404 self.logger.debug("Sfi.get_gid-> %s",gid.save_to_string(save_parents=True))
407 def _get_gid(self, hrn=None):
409 git_gid helper. Retrive the gid from the registry and save it to file.
415 gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid")
416 gid = self.get_cached_gid(gidfile)
418 user_cred = self.get_user_cred()
419 records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True))
421 raise RecordNotFound(args[0])
422 gid = GID(string=records[0]['gid'])
423 self.logger.info("Writing gid to %s"%gidfile)
424 gid.save_to_file(filename=gidfile)
428 def get_cached_credential(self, file):
430 Return a cached credential only if it hasn't expired.
432 if (os.path.isfile(file)):
433 credential = Credential(filename=file)
434 # make sure it isnt expired
435 if not credential.get_expiration or \
436 datetime.datetime.today() < credential.get_expiration():
440 def get_user_cred(self):
441 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cred")
442 return self.get_cred(file, 'user', self.user)
444 def get_auth_cred(self):
445 if not self.authority:
446 self.logger.critical("no authority specified. Use -a or set SF_AUTH")
448 file = os.path.join(self.options.sfi_dir, self.authority + ".cred")
449 return self.get_cred(file, 'authority', self.authority)
451 def get_slice_cred(self, name):
452 file = os.path.join(self.options.sfi_dir, "slice_" + get_leaf(name) + ".cred")
453 return self.get_cred(file, 'slice', name)
455 def get_cred(self, file, type, hrn):
456 # attempt to load a cached credential
457 cred = self.get_cached_credential(file)
460 cert_string = self.cert.save_to_string(save_parents=True)
461 user_name = self.user.replace(self.authority + ".", '')
462 if user_name.count(".") > 0:
463 user_name = user_name.replace(".", '_')
464 self.user = self.authority + "." + user_name
465 cred_str = self.registry.GetSelfCredential(cert_string, hrn, "user")
467 # bootstrap slice credential from user credential
468 user_cred = self.get_user_cred().save_to_string(save_parents=True)
469 cred_str = self.registry.GetCredential(user_cred, hrn, type)
472 self.logger.critical("Failed to get %s credential" % type)
475 cred = Credential(string=cred_str)
476 cred.save_to_file(file, save_parents=True)
477 self.logger.info("Writing %s credential to %s" %(type, file))
482 def get_rspec_file(self, rspec):
483 if (os.path.isabs(rspec)):
486 file = os.path.join(self.options.sfi_dir, rspec)
487 if (os.path.isfile(file)):
490 self.logger.critical("No such rspec file"%rspec)
493 def get_record_file(self, record):
494 if (os.path.isabs(record)):
497 file = os.path.join(self.options.sfi_dir, record)
498 if (os.path.isfile(file)):
501 self.logger.critical("No such registry record file %s"%record)
504 def load_publickey_string(self, fn):
506 key_string = f.read()
508 # if the filename is a private key file, then extract the public key
509 if "PRIVATE KEY" in key_string:
510 outfn = tempfile.mktemp()
511 cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
514 key_string = f.read()
520 def get_component_server_from_hrn(self, hrn):
521 # direct connection to the nodes component manager interface
522 user_cred = self.get_user_cred().save_to_string(save_parents=True)
523 records = self.registry.Resolve(hrn, user_cred)
524 records = filter_records('node', records)
526 self.logger.warning("No such component:%r"% opts.component)
529 return self.get_server(record['hostname'], CM_PORT, self.key_file, self.cert_file)
531 def get_server(self, host, port, keyfile, certfile):
533 Return an instance of an xmlrpc server connection
535 # port is appended onto the domain, before the path. Should look like:
536 # http://domain:port/path
537 host_parts = host.split('/')
538 host_parts[0] = host_parts[0] + ":" + str(port)
539 url = "http://%s" % "/".join(host_parts)
540 return xmlrpcprotocol.get_server(url, keyfile, certfile, self.options)
542 # xxx opts could be retrieved in self.options
543 def get_server_from_opts(self, opts):
545 Return instance of an xmlrpc connection to a slice manager, aggregate
546 or component server depending on the specified opts
548 server = self.slicemgr
549 # direct connection to an aggregate
550 if hasattr(opts, 'aggregate') and opts.aggregate:
551 server = self.get_server(opts.aggregate, opts.port, self.key_file, self.cert_file)
552 # direct connection to the nodes component manager interface
553 if hasattr(opts, 'component') and opts.component:
554 server = self.get_component_server_from_hrn(opts.component)
557 #==========================================================================
558 # Following functions implement the commands
560 # Registry-related commands
561 #==========================================================================
563 def dispatch(self, command, cmd_opts, cmd_args):
564 return getattr(self, command)(cmd_opts, cmd_args)
566 # list entires in named authority registry
567 def list(self, opts, args):
572 user_cred = self.get_user_cred().save_to_string(save_parents=True)
574 list = self.registry.List(hrn, user_cred)
576 raise Exception, "Not enough parameters for the 'list' command"
578 # filter on person, slice, site, node, etc.
579 # THis really should be in the self.filter_records funct def comment...
580 list = filter_records(opts.type, list)
582 print "%s (%s)" % (record['hrn'], record['type'])
585 if not file.startswith(os.sep):
586 file = os.path.join(self.options.sfi_dir, file)
587 save_records_to_file(file, list)
590 # show named registry record
591 def show(self, opts, args):
596 user_cred = self.get_user_cred().save_to_string(save_parents=True)
597 records = self.registry.Resolve(hrn, user_cred)
598 records = filter_records(opts.type, records)
600 print "No record of type", opts.type
601 for record in records:
602 if record['type'] in ['user']:
603 record = UserRecord(dict=record)
604 elif record['type'] in ['slice']:
605 record = SliceRecord(dict=record)
606 elif record['type'] in ['node']:
607 record = NodeRecord(dict=record)
608 elif record['type'] in ['authority', 'ma', 'sa']:
609 record = AuthorityRecord(dict=record)
611 record = SfaRecord(dict=record)
612 if (opts.format == "text"):
615 print record.save_to_string()
619 if not file.startswith(os.sep):
620 file = os.path.join(self.options.sfi_dir, file)
621 save_records_to_file(file, records)
624 def delegate(self, opts, args):
626 delegee_hrn = args[0]
627 if opts.delegate_user:
628 user_cred = self.get_user_cred()
629 cred = self.delegate_cred(user_cred, delegee_hrn)
630 elif opts.delegate_slice:
631 slice_cred = self.get_slice_cred(opts.delegate_slice)
632 cred = self.delegate_cred(slice_cred, delegee_hrn)
634 self.logger.warning("Must specify either --user or --slice <hrn>")
636 delegated_cred = Credential(string=cred)
637 object_hrn = delegated_cred.get_gid_object().get_hrn()
638 if opts.delegate_user:
639 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_"
640 + get_leaf(object_hrn) + ".cred")
641 elif opts.delegate_slice:
642 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_"
643 + get_leaf(object_hrn) + ".cred")
645 delegated_cred.save_to_file(dest_fn, save_parents=True)
647 self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
649 def delegate_cred(self, object_cred, hrn):
650 # the gid and hrn of the object we are delegating
651 if isinstance(object_cred, str):
652 object_cred = Credential(string=object_cred)
653 object_gid = object_cred.get_gid_object()
654 object_hrn = object_gid.get_hrn()
656 if not object_cred.get_privileges().get_all_delegate():
657 self.logger.error("Object credential %s does not have delegate bit set"%object_hrn)
660 # the delegating user's gid
661 caller_gid = self._get_gid(self.user)
662 caller_gidfile = os.path.join(self.options.sfi_dir, self.user + ".gid")
664 # the gid of the user who will be delegated to
665 delegee_gid = self._get_gid(hrn)
666 delegee_hrn = delegee_gid.get_hrn()
667 delegee_gidfile = os.path.join(self.options.sfi_dir, delegee_hrn + ".gid")
668 delegee_gid.save_to_file(filename=delegee_gidfile)
669 dcred = object_cred.delegate(delegee_gidfile, self.get_key_file(), caller_gidfile)
670 return dcred.save_to_string(save_parents=True)
672 # removed named registry record
673 # - have to first retrieve the record to be removed
674 def remove(self, opts, args):
675 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
683 return self.registry.Remove(hrn, auth_cred, type)
685 # add named registry record
686 def add(self, opts, args):
687 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
691 record_filepath = args[0]
692 rec_file = self.get_record_file(record_filepath)
693 record = load_record_from_file(rec_file).as_dict()
694 return self.registry.Register(record, auth_cred)
696 # update named registry entry
697 def update(self, opts, args):
698 user_cred = self.get_user_cred()
702 rec_file = self.get_record_file(args[0])
703 record = load_record_from_file(rec_file)
704 if record['type'] == "user":
705 if record.get_name() == user_cred.get_gid_object().get_hrn():
706 cred = user_cred.save_to_string(save_parents=True)
708 cred = self.get_auth_cred().save_to_string(save_parents=True)
709 elif record['type'] in ["slice"]:
711 cred = self.get_slice_cred(record.get_name()).save_to_string(save_parents=True)
712 except ServerException, e:
713 # XXX smbaker -- once we have better error return codes, update this
714 # to do something better than a string compare
715 if "Permission error" in e.args[0]:
716 cred = self.get_auth_cred().save_to_string(save_parents=True)
719 elif record.get_type() in ["authority"]:
720 cred = self.get_auth_cred().save_to_string(save_parents=True)
721 elif record.get_type() == 'node':
722 cred = self.get_auth_cred().save_to_string(save_parents=True)
724 raise "unknown record type" + record.get_type()
725 record = record.as_dict()
726 return self.registry.Update(record, cred)
728 def get_trusted_certs(self, opts, args):
730 return uhe trusted certs at this interface
732 trusted_certs = self.registry.get_trusted_certs()
733 for trusted_cert in trusted_certs:
734 cert = Certificate(string=trusted_cert)
735 self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject())
738 def aggregates(self, opts, args):
740 return a list of details about known aggregates
742 user_cred = self.get_user_cred().save_to_string(save_parents=True)
747 result = self.registry.get_aggregates(user_cred, hrn)
751 def registries(self, opts, args):
753 return a list of details about known registries
755 user_cred = self.get_user_cred().save_to_string(save_parents=True)
759 result = self.registry.get_registries(user_cred, hrn)
764 # ==================================================================
765 # Slice-related commands
766 # ==================================================================
769 def version(self, opts, args):
770 if opts.version_local:
771 version=version_core()
773 if opts.version_registry:
776 server = self.get_server_from_opts(opts)
777 version=server.GetVersion()
778 for (k,v) in version.items():
779 print "%-20s: %s"%(k,v)
781 # list instantiated slices
782 def slices(self, opts, args):
784 list instantiated slices
786 user_cred = self.get_user_cred().save_to_string(save_parents=True)
789 delegated_cred = self.delegate_cred(user_cred, get_authority(self.authority))
790 creds.append(delegated_cred)
791 server = self.get_server_from_opts(opts)
792 results = server.ListSlices(creds)
793 display_list(results)
796 # show rspec for named slice
797 def resources(self, opts, args):
798 user_cred = self.get_user_cred().save_to_string(save_parents=True)
799 server = self.slicemgr
801 server = self.get_server_from_opts(opts)
804 cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
806 call_options = {'geni_slice_urn': hrn_to_urn(hrn, 'slice')}
813 delegated_cred = self.delegate_cred(cred, get_authority(self.authority))
814 creds.append(delegated_cred)
815 result = server.ListResources(creds, call_options)
817 if opts.file is None:
818 display_rspec(result, format)
821 if not file.startswith(os.sep):
822 file = os.path.join(self.options.sfi_dir, file)
823 save_rspec_to_file(result, file)
826 # created named slice with given rspec
827 def create(self, opts, args):
829 slice_urn = hrn_to_urn(slice_hrn, 'slice')
830 user_cred = self.get_user_cred()
831 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
834 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
835 creds.append(delegated_cred)
836 rspec_file = self.get_rspec_file(args[1])
837 rspec = open(rspec_file).read()
838 server = self.get_server_from_opts(opts)
839 result = server.CreateSliver(slice_urn, creds, rspec, [])
843 # get a ticket for the specified slice
844 def get_ticket(self, opts, args):
845 slice_hrn, rspec_path = args[0], args[1]
846 slice_urn = hrn_to_urn(slice_hrn, 'slice')
847 user_cred = self.get_user_cred()
848 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
851 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
852 creds.append(delegated_cred)
853 rspec_file = self.get_rspec_file(rspec_path)
854 rspec = open(rspec_file).read()
855 server = self.get_server_from_opts(opts)
856 ticket_string = server.GetTicket(slice_urn, creds, rspec, [])
857 file = os.path.join(self.options.sfi_dir, get_leaf(slice_hrn) + ".ticket")
858 self.logger.info("writing ticket to %s"%file)
859 ticket = SfaTicket(string=ticket_string)
860 ticket.save_to_file(filename=file, save_parents=True)
862 def redeem_ticket(self, opts, args):
863 ticket_file = args[0]
865 # get slice hrn from the ticket
866 # use this to get the right slice credential
867 ticket = SfaTicket(filename=ticket_file)
869 slice_hrn = ticket.gidObject.get_hrn()
870 slice_urn = hrn_to_urn(slice_hrn, 'slice')
871 #slice_hrn = ticket.attributes['slivers'][0]['hrn']
872 user_cred = self.get_user_cred()
873 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
875 # get a list of node hostnames from the RSpec
876 tree = etree.parse(StringIO(ticket.rspec))
877 root = tree.getroot()
878 hostnames = root.xpath("./network/site/node/hostname/text()")
880 # create an xmlrpc connection to the component manager at each of these
881 # components and gall redeem_ticket
883 for hostname in hostnames:
885 self.logger.info("Calling redeem_ticket at %(hostname)s " % locals())
886 server = self.get_server(hostname, CM_PORT, self.key_file, \
887 self.cert_file, self.options.debug)
888 server.RedeemTicket(ticket.save_to_string(save_parents=True), slice_cred)
889 self.logger.info("Success")
890 except socket.gaierror:
891 self.logger.error("redeem_ticket failed: Component Manager not accepting requests")
893 self.logger.log_exc(e.message)
897 def delete(self, opts, args):
899 slice_urn = hrn_to_urn(slice_hrn, 'slice')
900 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
903 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
904 creds.append(delegated_cred)
905 server = self.get_server_from_opts(opts)
906 return server.DeleteSliver(slice_urn, creds)
909 def start(self, opts, args):
911 slice_urn = hrn_to_urn(slice_hrn, 'slice')
912 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
915 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
916 creds.append(delegated_cred)
917 server = self.get_server_from_opts(opts)
918 return server.Start(slice_urn, creds)
921 def stop(self, opts, args):
923 slice_urn = hrn_to_urn(slice_hrn, 'slice')
924 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
927 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
928 creds.append(delegated_cred)
929 server = self.get_server_from_opts(opts)
930 return server.Stop(slice_urn, creds)
933 def reset(self, opts, args):
935 slice_urn = hrn_to_urn(slice_hrn, 'slice')
936 server = self.get_server_from_opts(opts)
937 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
940 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
941 creds.append(delegated_cred)
942 return server.reset_slice(creds, slice_urn)
944 def renew(self, opts, args):
946 slice_urn = hrn_to_urn(slice_hrn, 'slice')
947 server = self.get_server_from_opts(opts)
948 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
951 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
952 creds.append(delegated_cred)
954 return server.RenewSliver(slice_urn, creds, time)
957 def status(self, opts, args):
959 slice_urn = hrn_to_urn(slice_hrn, 'slice')
960 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
963 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
964 creds.append(delegated_cred)
965 server = self.get_server_from_opts(opts)
966 print server.SliverStatus(slice_urn, creds)
969 def shutdown(self, opts, args):
971 slice_urn = hrn_to_urn(slice_hrn, 'slice')
972 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
975 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
976 creds.append(delegated_cred)
977 server = self.get_server_from_opts(opts)
978 return server.Shutdown(slice_urn, creds)
980 def print_help (self):
981 self.sfi_parser.print_help()
982 self.cmd_parser.print_help()
985 # Main: parse arguments and dispatch to command
988 self.sfi_parser = self.create_parser()
989 (options, args) = self.sfi_parser.parse_args()
990 self.options = options
992 self.logger.setLevelFromOptVerbose(self.options.verbose)
993 if options.hashrequest:
994 self.hashrequest = True
997 self.logger.critical("No command given. Use -h for help.")
1001 self.cmd_parser = self.create_cmd_parser(command)
1002 (cmd_opts, cmd_args) = self.cmd_parser.parse_args(args[1:])
1006 self.logger.info("Command=%s" % command)
1007 if command in ("resources"):
1008 self.logger.debug("resources cmd_opts %s" % cmd_opts.format)
1009 elif command in ("list", "show", "remove"):
1010 self.logger.debug("cmd_opts.type %s" % cmd_opts.type)
1011 self.logger.debug('cmd_args %s',cmd_args)
1014 self.dispatch(command, cmd_opts, cmd_args)
1016 self.logger.critical ("Unknown command %s"%command)
1021 if __name__ == "__main__":