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 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
27 from sfa.util.config import Config
28 from sfa.util.version import version_core
33 # utility methods here
35 def display_rspec(rspec, format='rspec'):
37 tree = etree.parse(StringIO(rspec))
39 result = root.xpath("./network/site/node/hostname/text()")
40 elif format in ['ip']:
41 # The IP address is not yet part of the new RSpec
42 # so this doesn't do anything yet.
43 tree = etree.parse(StringIO(rspec))
45 result = root.xpath("./network/site/node/ipv4/text()")
52 def display_list(results):
53 for result in results:
56 def display_records(recordList, dump=False):
57 ''' Print all fields in the record'''
58 for record in recordList:
59 display_record(record, dump)
61 def display_record(record, dump=False):
65 info = record.getdict()
66 print "%s (%s)" % (info['hrn'], info['type'])
70 def filter_records(type, records):
72 for record in records:
73 if (record['type'] == type) or (type == "all"):
74 filtered_records.append(record)
75 return filtered_records
79 def save_rspec_to_file(rspec, filename):
80 if not filename.endswith(".rspec"):
81 filename = filename + ".rspec"
83 f = open(filename, 'w')
88 def save_records_to_file(filename, recordList):
90 for record in recordList:
92 save_record_to_file(filename + "." + str(index), record)
94 save_record_to_file(filename, record)
97 def save_record_to_file(filename, record):
98 if record['type'] in ['user']:
99 record = UserRecord(dict=record)
100 elif record['type'] in ['slice']:
101 record = SliceRecord(dict=record)
102 elif record['type'] in ['node']:
103 record = NodeRecord(dict=record)
104 elif record['type'] in ['authority', 'ma', 'sa']:
105 record = AuthorityRecord(dict=record)
107 record = SfaRecord(dict=record)
108 str = record.save_to_string()
109 file(filename, "w").write(str)
114 def load_record_from_file(filename):
115 str = file(filename, "r").read()
116 record = SfaRecord(string=str)
121 def unique_call_id(): return uuid.uuid4().urn
125 required_options=['verbose', 'debug', 'registry', 'sm', 'auth', 'user']
127 # dummy to meet Sfi's expectations for its 'options' field
128 # i.e. s/t we can do setattr on
132 def __init__ (self,options=None):
133 if options is None: options=Sfi.DummyOptions()
134 for opt in Sfi.required_options:
135 if not hasattr(options,opt): setattr(options,opt,None)
136 if not hasattr(options,'sfi_dir'): options.sfi_dir=os.path.expanduser("~/.sfi/")
137 self.options = options
141 self.authority = None
142 self.hashrequest = False
143 sfa_logger_goes_to_console()
144 self.logger=sfa_logger()
146 def create_cmd_parser(self, command, additional_cmdargs=None):
147 cmdargs = {"list": "authority",
152 "aggregates": "[name]",
153 "registries": "[name]",
155 "get_trusted_certs": "cred",
157 "resources": "[name]",
158 "create": "name rspec",
159 "get_ticket": "name rspec",
160 "redeem_ticket": "ticket",
172 if additional_cmdargs:
173 cmdargs.update(additional_cmdargs)
175 if command not in cmdargs:
176 msg="Invalid command\n"
178 msg += ','.join(cmdargs.keys())
179 self.logger.critical(msg)
182 parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \
183 % (command, cmdargs[command]))
185 # user specifies remote aggregate/sm/component
186 if command in ("resources", "slices", "create", "delete", "start", "stop",
187 "restart", "shutdown", "get_ticket", "renew", "status"):
188 parser.add_option("-a", "--aggregate", dest="aggregate",
189 default=None, help="aggregate host")
190 parser.add_option("-p", "--port", dest="port",
191 default=AGGREGATE_PORT, help="aggregate port")
192 parser.add_option("-c", "--component", dest="component", default=None,
193 help="component hrn")
194 parser.add_option("-d", "--delegate", dest="delegate", default=None,
196 help="Include a credential delegated to the user's root"+\
197 "authority in set of credentials for this call")
199 # registy filter option
200 if command in ("list", "show", "remove"):
201 parser.add_option("-t", "--type", dest="type", type="choice",
202 help="type filter ([all]|user|slice|authority|node|aggregate)",
203 choices=("all", "user", "slice", "authority", "node", "aggregate"),
206 if command in ("resources"):
207 parser.add_option("-f", "--format", dest="format", type="choice",
208 help="display format ([xml]|dns|ip)", default="xml",
209 choices=("xml", "dns", "ip"))
211 if command in ("resources", "show", "list"):
212 parser.add_option("-o", "--output", dest="file",
213 help="output XML to file", metavar="FILE", default=None)
215 if command in ("show", "list"):
216 parser.add_option("-f", "--format", dest="format", type="choice",
217 help="display format ([text]|xml)", default="text",
218 choices=("text", "xml"))
220 if command in ("delegate"):
221 parser.add_option("-u", "--user",
222 action="store_true", dest="delegate_user", default=False,
223 help="delegate user credential")
224 parser.add_option("-s", "--slice", dest="delegate_slice",
225 help="delegate slice credential", metavar="HRN", default=None)
227 if command in ("version"):
228 parser.add_option("-R","--registry-version",
229 action="store_true", dest="version_registry", default=False,
230 help="probe registry version instead of slicemgr")
231 parser.add_option("-l","--local",
232 action="store_true", dest="version_local", default=False,
233 help="display version of the local client")
238 def create_parser(self):
240 # Generate command line parser
241 parser = OptionParser(usage="sfi [options] command [command_options] [command_args]",
242 description="Commands: gid,list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset")
243 parser.add_option("-r", "--registry", dest="registry",
244 help="root registry", metavar="URL", default=None)
245 parser.add_option("-s", "--slicemgr", dest="sm",
246 help="slice manager", metavar="URL", default=None)
247 default_sfi_dir = os.path.expanduser("~/.sfi/")
248 parser.add_option("-d", "--dir", dest="sfi_dir",
249 help="config & working directory - default is " + default_sfi_dir,
250 metavar="PATH", default=default_sfi_dir)
251 parser.add_option("-u", "--user", dest="user",
252 help="user name", metavar="HRN", default=None)
253 parser.add_option("-a", "--auth", dest="auth",
254 help="authority name", metavar="HRN", default=None)
255 parser.add_option("-v", "--verbose", action="count", dest="verbose", default=0,
256 help="verbose mode - cumulative")
257 parser.add_option("-D", "--debug",
258 action="store_true", dest="debug", default=False,
259 help="Debug (xml-rpc) protocol messages")
260 parser.add_option("-p", "--protocol", dest="protocol", default="xmlrpc",
261 help="RPC protocol (xmlrpc or soap)")
262 parser.add_option("-k", "--hashrequest",
263 action="store_true", dest="hashrequest", default=False,
264 help="Create a hash of the request that will be authenticated on the server")
265 parser.disable_interspersed_args()
270 def read_config(self):
271 config_file = self.options.sfi_dir + os.sep + "sfi_config"
273 config = Config (config_file)
275 self.logger.critical("Failed to read configuration file %s"%config_file)
276 self.logger.info("Make sure to remove the export clauses and to add quotes")
277 if self.options.verbose==0:
278 self.logger.info("Re-run with -v for more details")
280 self.logger.log_exc("Could not read config file %s"%config_file)
285 if (self.options.sm is not None):
286 self.sm_url = self.options.sm
287 elif hasattr(config, "SFI_SM"):
288 self.sm_url = config.SFI_SM
290 self.logger.error("You need to set e.g. SFI_SM='http://your.slicemanager.url:12347/' in %s" % config_file)
294 if (self.options.registry is not None):
295 self.reg_url = self.options.registry
296 elif hasattr(config, "SFI_REGISTRY"):
297 self.reg_url = config.SFI_REGISTRY
299 self.logger.errors("You need to set e.g. SFI_REGISTRY='http://your.registry.url:12345/' in %s" % config_file)
304 if (self.options.user is not None):
305 self.user = self.options.user
306 elif hasattr(config, "SFI_USER"):
307 self.user = config.SFI_USER
309 self.logger.errors("You need to set e.g. SFI_USER='plc.princeton.username' in %s" % config_file)
313 if (self.options.auth is not None):
314 self.authority = self.options.auth
315 elif hasattr(config, "SFI_AUTH"):
316 self.authority = config.SFI_AUTH
318 self.logger.error("You need to set e.g. SFI_AUTH='plc.princeton' in %s" % config_file)
326 # Establish Connection to SliceMgr and Registry Servers
328 def set_servers(self):
331 # Get key and certificate
332 key_file = self.get_key_file()
333 cert_file = self.get_cert_file(key_file)
334 self.key = Keypair(filename=key_file)
335 self.key_file = key_file
336 self.cert_file = cert_file
337 self.cert = Certificate(filename=cert_file)
338 # Establish connection to server(s)
339 self.logger.info("Contacting Registry at: %s"%self.reg_url)
340 self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, self.options)
341 self.logger.info("Contacting Slice Manager at: %s"%self.sm_url)
342 self.slicemgr = xmlrpcprotocol.get_server(self.sm_url, key_file, cert_file, self.options)
347 # Get various credential and spec files
349 # Establishes limiting conventions
350 # - conflates MAs and SAs
351 # - assumes last token in slice name is unique
353 # Bootstraps credentials
354 # - bootstrap user credential from self-signed certificate
355 # - bootstrap authority credential from user credential
356 # - bootstrap slice credential from user credential
360 def get_key_file(self):
361 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".pkey")
362 if (os.path.isfile(file)):
365 self.logger.error("Key file %s does not exist"%file)
369 def get_cert_file(self, key_file):
371 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert")
372 if (os.path.isfile(file)):
373 # use existing cert if it exists
377 # attempt to use gid as the cert.
378 gid = self._get_gid()
379 self.logger.info("Writing certificate to %s"%file)
380 gid.save_to_file(file)
382 # generate self signed certificate
383 k = Keypair(filename=key_file)
384 cert = Certificate(subject=self.user)
386 cert.set_issuer(k, self.user)
388 self.logger.info("Writing self-signed certificate to %s"%file)
389 cert.save_to_file(file)
393 def get_cached_gid(self, file):
398 if (os.path.isfile(file)):
399 gid = GID(filename=file)
403 def get_gid(self, opts, args):
405 Get the specify gid and save it to file
410 gid = self._get_gid(hrn)
411 self.logger.debug("Sfi.get_gid-> %s",gid.save_to_string(save_parents=True))
414 def _get_gid(self, hrn=None):
416 git_gid helper. Retrive the gid from the registry and save it to file.
422 gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid")
423 gid = self.get_cached_gid(gidfile)
425 user_cred = self.get_user_cred()
426 records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True))
428 raise RecordNotFound(args[0])
429 gid = GID(string=records[0]['gid'])
430 self.logger.info("Writing gid to %s"%gidfile)
431 gid.save_to_file(filename=gidfile)
435 def get_cached_credential(self, file):
437 Return a cached credential only if it hasn't expired.
439 if (os.path.isfile(file)):
440 credential = Credential(filename=file)
441 # make sure it isnt expired
442 if not credential.get_expiration or \
443 datetime.datetime.today() < credential.get_expiration():
447 def get_user_cred(self):
448 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cred")
449 return self.get_cred(file, 'user', self.user)
451 def get_auth_cred(self):
452 if not self.authority:
453 self.logger.critical("no authority specified. Use -a or set SF_AUTH")
455 file = os.path.join(self.options.sfi_dir, self.authority + ".cred")
456 return self.get_cred(file, 'authority', self.authority)
458 def get_slice_cred(self, name):
459 file = os.path.join(self.options.sfi_dir, "slice_" + get_leaf(name) + ".cred")
460 return self.get_cred(file, 'slice', name)
462 def get_cred(self, file, type, hrn):
463 # attempt to load a cached credential
464 cred = self.get_cached_credential(file)
467 cert_string = self.cert.save_to_string(save_parents=True)
468 user_name = self.user.replace(self.authority + ".", '')
469 if user_name.count(".") > 0:
470 user_name = user_name.replace(".", '_')
471 self.user = self.authority + "." + user_name
472 cred_str = self.registry.GetSelfCredential(cert_string, hrn, "user")
474 # bootstrap slice credential from user credential
475 user_cred = self.get_user_cred().save_to_string(save_parents=True)
476 cred_str = self.registry.GetCredential(user_cred, hrn, type)
479 self.logger.critical("Failed to get %s credential" % type)
482 cred = Credential(string=cred_str)
483 cred.save_to_file(file, save_parents=True)
484 self.logger.info("Writing %s credential to %s" %(type, file))
489 def get_rspec_file(self, rspec):
490 if (os.path.isabs(rspec)):
493 file = os.path.join(self.options.sfi_dir, rspec)
494 if (os.path.isfile(file)):
497 self.logger.critical("No such rspec file"%rspec)
500 def get_record_file(self, record):
501 if (os.path.isabs(record)):
504 file = os.path.join(self.options.sfi_dir, record)
505 if (os.path.isfile(file)):
508 self.logger.critical("No such registry record file %s"%record)
511 def load_publickey_string(self, fn):
513 key_string = f.read()
515 # if the filename is a private key file, then extract the public key
516 if "PRIVATE KEY" in key_string:
517 outfn = tempfile.mktemp()
518 cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
521 key_string = f.read()
527 def get_component_server_from_hrn(self, hrn):
528 # direct connection to the nodes component manager interface
529 user_cred = self.get_user_cred().save_to_string(save_parents=True)
530 records = self.registry.Resolve(hrn, user_cred)
531 records = filter_records('node', records)
533 self.logger.warning("No such component:%r"% opts.component)
536 return self.get_server(record['hostname'], CM_PORT, self.key_file, self.cert_file)
538 def get_server(self, host, port, keyfile, certfile):
540 Return an instance of an xmlrpc server connection
542 # port is appended onto the domain, before the path. Should look like:
543 # http://domain:port/path
544 host_parts = host.split('/')
545 host_parts[0] = host_parts[0] + ":" + str(port)
546 url = "http://%s" % "/".join(host_parts)
547 return xmlrpcprotocol.get_server(url, keyfile, certfile, self.options)
549 # xxx opts could be retrieved in self.options
550 def get_server_from_opts(self, opts):
552 Return instance of an xmlrpc connection to a slice manager, aggregate
553 or component server depending on the specified opts
555 server = self.slicemgr
556 # direct connection to an aggregate
557 if hasattr(opts, 'aggregate') and opts.aggregate:
558 server = self.get_server(opts.aggregate, opts.port, self.key_file, self.cert_file)
559 # direct connection to the nodes component manager interface
560 if hasattr(opts, 'component') and opts.component:
561 server = self.get_component_server_from_hrn(opts.component)
564 #==========================================================================
565 # Following functions implement the commands
567 # Registry-related commands
568 #==========================================================================
570 def dispatch(self, command, cmd_opts, cmd_args):
571 return getattr(self, command)(cmd_opts, cmd_args)
573 # list entires in named authority registry
574 def list(self, opts, args):
579 user_cred = self.get_user_cred().save_to_string(save_parents=True)
581 list = self.registry.List(hrn, user_cred)
583 raise Exception, "Not enough parameters for the 'list' command"
585 # filter on person, slice, site, node, etc.
586 # THis really should be in the self.filter_records funct def comment...
587 list = filter_records(opts.type, list)
589 print "%s (%s)" % (record['hrn'], record['type'])
592 if not file.startswith(os.sep):
593 file = os.path.join(self.options.sfi_dir, file)
594 save_records_to_file(file, list)
597 # show named registry record
598 def show(self, opts, args):
603 user_cred = self.get_user_cred().save_to_string(save_parents=True)
604 records = self.registry.Resolve(hrn, user_cred)
605 records = filter_records(opts.type, records)
607 print "No record of type", opts.type
608 for record in records:
609 if record['type'] in ['user']:
610 record = UserRecord(dict=record)
611 elif record['type'] in ['slice']:
612 record = SliceRecord(dict=record)
613 elif record['type'] in ['node']:
614 record = NodeRecord(dict=record)
615 elif record['type'] in ['authority', 'ma', 'sa']:
616 record = AuthorityRecord(dict=record)
618 record = SfaRecord(dict=record)
619 if (opts.format == "text"):
622 print record.save_to_string()
626 if not file.startswith(os.sep):
627 file = os.path.join(self.options.sfi_dir, file)
628 save_records_to_file(file, records)
631 def delegate(self, opts, args):
633 delegee_hrn = args[0]
634 if opts.delegate_user:
635 user_cred = self.get_user_cred()
636 cred = self.delegate_cred(user_cred, delegee_hrn)
637 elif opts.delegate_slice:
638 slice_cred = self.get_slice_cred(opts.delegate_slice)
639 cred = self.delegate_cred(slice_cred, delegee_hrn)
641 self.logger.warning("Must specify either --user or --slice <hrn>")
643 delegated_cred = Credential(string=cred)
644 object_hrn = delegated_cred.get_gid_object().get_hrn()
645 if opts.delegate_user:
646 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_"
647 + get_leaf(object_hrn) + ".cred")
648 elif opts.delegate_slice:
649 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_"
650 + get_leaf(object_hrn) + ".cred")
652 delegated_cred.save_to_file(dest_fn, save_parents=True)
654 self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
656 def delegate_cred(self, object_cred, hrn):
657 # the gid and hrn of the object we are delegating
658 if isinstance(object_cred, str):
659 object_cred = Credential(string=object_cred)
660 object_gid = object_cred.get_gid_object()
661 object_hrn = object_gid.get_hrn()
663 if not object_cred.get_privileges().get_all_delegate():
664 self.logger.error("Object credential %s does not have delegate bit set"%object_hrn)
667 # the delegating user's gid
668 caller_gid = self._get_gid(self.user)
669 caller_gidfile = os.path.join(self.options.sfi_dir, self.user + ".gid")
671 # the gid of the user who will be delegated to
672 delegee_gid = self._get_gid(hrn)
673 delegee_hrn = delegee_gid.get_hrn()
674 delegee_gidfile = os.path.join(self.options.sfi_dir, delegee_hrn + ".gid")
675 delegee_gid.save_to_file(filename=delegee_gidfile)
676 dcred = object_cred.delegate(delegee_gidfile, self.get_key_file(), caller_gidfile)
677 return dcred.save_to_string(save_parents=True)
679 # removed named registry record
680 # - have to first retrieve the record to be removed
681 def remove(self, opts, args):
682 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
690 return self.registry.Remove(hrn, auth_cred, type)
692 # add named registry record
693 def add(self, opts, args):
694 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
698 record_filepath = args[0]
699 rec_file = self.get_record_file(record_filepath)
700 record = load_record_from_file(rec_file).as_dict()
701 return self.registry.Register(record, auth_cred)
703 # update named registry entry
704 def update(self, opts, args):
705 user_cred = self.get_user_cred()
709 rec_file = self.get_record_file(args[0])
710 record = load_record_from_file(rec_file)
711 if record['type'] == "user":
712 if record.get_name() == user_cred.get_gid_object().get_hrn():
713 cred = user_cred.save_to_string(save_parents=True)
715 cred = self.get_auth_cred().save_to_string(save_parents=True)
716 elif record['type'] in ["slice"]:
718 cred = self.get_slice_cred(record.get_name()).save_to_string(save_parents=True)
719 except xmlrpcprotocol.ServerException, e:
720 # XXX smbaker -- once we have better error return codes, update this
721 # to do something better than a string compare
722 if "Permission error" in e.args[0]:
723 cred = self.get_auth_cred().save_to_string(save_parents=True)
726 elif record.get_type() in ["authority"]:
727 cred = self.get_auth_cred().save_to_string(save_parents=True)
728 elif record.get_type() == 'node':
729 cred = self.get_auth_cred().save_to_string(save_parents=True)
731 raise "unknown record type" + record.get_type()
732 record = record.as_dict()
733 return self.registry.Update(record, cred)
735 def get_trusted_certs(self, opts, args):
737 return uhe trusted certs at this interface
739 trusted_certs = self.registry.get_trusted_certs()
740 for trusted_cert in trusted_certs:
741 cert = Certificate(string=trusted_cert)
742 self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject())
745 def aggregates(self, opts, args):
747 return a list of details about known aggregates
749 user_cred = self.get_user_cred().save_to_string(save_parents=True)
754 result = self.registry.get_aggregates(user_cred, hrn)
758 def registries(self, opts, args):
760 return a list of details about known registries
762 user_cred = self.get_user_cred().save_to_string(save_parents=True)
766 result = self.registry.get_registries(user_cred, hrn)
771 # ==================================================================
772 # Slice-related commands
773 # ==================================================================
776 def version(self, opts, args):
777 if opts.version_local:
778 version=version_core()
780 if opts.version_registry:
783 server = self.get_server_from_opts(opts)
784 version=server.GetVersion()
785 for (k,v) in version.iteritems():
786 print "%-20s: %s"%(k,v)
788 # list instantiated slices
789 def slices(self, opts, args):
791 list instantiated slices
793 user_cred = self.get_user_cred().save_to_string(save_parents=True)
796 delegated_cred = self.delegate_cred(user_cred, get_authority(self.authority))
797 creds.append(delegated_cred)
798 server = self.get_server_from_opts(opts)
799 results = server.ListSlices(creds)
800 display_list(results)
803 # show rspec for named slice
804 def resources(self, opts, args):
805 user_cred = self.get_user_cred().save_to_string(save_parents=True)
806 server = self.slicemgr
808 server = self.get_server_from_opts(opts)
811 cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
813 call_options = {'geni_slice_urn': hrn_to_urn(hrn, 'slice')}
820 delegated_cred = self.delegate_cred(cred, get_authority(self.authority))
821 creds.append(delegated_cred)
822 result = server.ListResources(creds, call_options,unique_call_id())
824 if opts.file is None:
825 display_rspec(result, format)
828 if not file.startswith(os.sep):
829 file = os.path.join(self.options.sfi_dir, file)
830 save_rspec_to_file(result, file)
833 # created named slice with given rspec
834 def create(self, opts, args):
836 slice_urn = hrn_to_urn(slice_hrn, 'slice')
837 user_cred = self.get_user_cred()
838 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
841 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
842 creds.append(delegated_cred)
843 rspec_file = self.get_rspec_file(args[1])
844 rspec = open(rspec_file).read()
845 server = self.get_server_from_opts(opts)
846 result = server.CreateSliver(slice_urn, creds, rspec, [])
850 # get a ticket for the specified slice
851 def get_ticket(self, opts, args):
852 slice_hrn, rspec_path = args[0], args[1]
853 slice_urn = hrn_to_urn(slice_hrn, 'slice')
854 user_cred = self.get_user_cred()
855 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
858 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
859 creds.append(delegated_cred)
860 rspec_file = self.get_rspec_file(rspec_path)
861 rspec = open(rspec_file).read()
862 server = self.get_server_from_opts(opts)
863 ticket_string = server.GetTicket(slice_urn, creds, rspec, [])
864 file = os.path.join(self.options.sfi_dir, get_leaf(slice_hrn) + ".ticket")
865 self.logger.info("writing ticket to %s"%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.gidObject.get_hrn()
877 slice_urn = hrn_to_urn(slice_hrn, 'slice')
878 #slice_hrn = ticket.attributes['slivers'][0]['hrn']
879 user_cred = self.get_user_cred()
880 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
882 # get a list of node hostnames from the RSpec
883 tree = etree.parse(StringIO(ticket.rspec))
884 root = tree.getroot()
885 hostnames = root.xpath("./network/site/node/hostname/text()")
887 # create an xmlrpc connection to the component manager at each of these
888 # components and gall redeem_ticket
890 for hostname in hostnames:
892 self.logger.info("Calling redeem_ticket at %(hostname)s " % locals())
893 server = self.get_server(hostname, CM_PORT, self.key_file, \
894 self.cert_file, self.options.debug)
895 server.RedeemTicket(ticket.save_to_string(save_parents=True), slice_cred)
896 self.logger.info("Success")
897 except socket.gaierror:
898 self.logger.error("redeem_ticket failed: Component Manager not accepting requests")
900 self.logger.log_exc(e.message)
904 def delete(self, opts, args):
906 slice_urn = hrn_to_urn(slice_hrn, 'slice')
907 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
910 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
911 creds.append(delegated_cred)
912 server = self.get_server_from_opts(opts)
913 return server.DeleteSliver(slice_urn, creds)
916 def start(self, opts, args):
918 slice_urn = hrn_to_urn(slice_hrn, 'slice')
919 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
922 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
923 creds.append(delegated_cred)
924 server = self.get_server_from_opts(opts)
925 return server.Start(slice_urn, creds)
928 def stop(self, opts, args):
930 slice_urn = hrn_to_urn(slice_hrn, 'slice')
931 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
934 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
935 creds.append(delegated_cred)
936 server = self.get_server_from_opts(opts)
937 return server.Stop(slice_urn, creds)
940 def reset(self, opts, args):
942 slice_urn = hrn_to_urn(slice_hrn, 'slice')
943 server = self.get_server_from_opts(opts)
944 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
947 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
948 creds.append(delegated_cred)
949 return server.reset_slice(creds, slice_urn)
951 def renew(self, opts, args):
953 slice_urn = hrn_to_urn(slice_hrn, 'slice')
954 server = self.get_server_from_opts(opts)
955 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
958 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
959 creds.append(delegated_cred)
961 return server.RenewSliver(slice_urn, creds, time)
964 def status(self, opts, args):
966 slice_urn = hrn_to_urn(slice_hrn, 'slice')
967 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
970 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
971 creds.append(delegated_cred)
972 server = self.get_server_from_opts(opts)
973 print server.SliverStatus(slice_urn, creds)
976 def shutdown(self, opts, args):
978 slice_urn = hrn_to_urn(slice_hrn, 'slice')
979 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
982 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
983 creds.append(delegated_cred)
984 server = self.get_server_from_opts(opts)
985 return server.Shutdown(slice_urn, creds)
987 def print_help (self):
988 self.sfi_parser.print_help()
989 self.cmd_parser.print_help()
992 # Main: parse arguments and dispatch to command
995 self.sfi_parser = self.create_parser()
996 (options, args) = self.sfi_parser.parse_args()
997 self.options = options
999 self.logger.setLevelFromOptVerbose(self.options.verbose)
1000 if options.hashrequest:
1001 self.hashrequest = True
1004 self.logger.critical("No command given. Use -h for help.")
1008 self.cmd_parser = self.create_cmd_parser(command)
1009 (cmd_opts, cmd_args) = self.cmd_parser.parse_args(args[1:])
1013 self.logger.info("Command=%s" % command)
1014 if command in ("resources"):
1015 self.logger.debug("resources cmd_opts %s" % cmd_opts.format)
1016 elif command in ("list", "show", "remove"):
1017 self.logger.debug("cmd_opts.type %s" % cmd_opts.type)
1018 self.logger.debug('cmd_args %s',cmd_args)
1021 self.dispatch(command, cmd_opts, cmd_args)
1023 self.logger.critical ("Unknown command %s"%command)
1028 if __name__ == "__main__":