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)
122 def unique_call_id(): return uuid.uuid4().urn
126 required_options=['verbose', 'debug', 'registry', 'sm', 'auth', 'user']
128 # dummy to meet Sfi's expectations for its 'options' field
129 # i.e. s/t we can do setattr on
133 def __init__ (self,options=None):
134 if options is None: options=Sfi.DummyOptions()
135 for opt in Sfi.required_options:
136 if not hasattr(options,opt): setattr(options,opt,None)
137 if not hasattr(options,'sfi_dir'): options.sfi_dir=os.path.expanduser("~/.sfi/")
138 self.options = options
142 self.authority = None
143 self.hashrequest = False
144 sfa_logger_goes_to_console()
145 self.logger=sfa_logger()
147 def create_cmd_parser(self, command, additional_cmdargs=None):
148 cmdargs = {"list": "authority",
153 "aggregates": "[name]",
154 "registries": "[name]",
156 "get_trusted_certs": "cred",
158 "resources": "[name]",
159 "create": "name rspec",
160 "get_ticket": "name rspec",
161 "redeem_ticket": "ticket",
173 if additional_cmdargs:
174 cmdargs.update(additional_cmdargs)
176 if command not in cmdargs:
177 msg="Invalid command\n"
179 msg += ','.join(cmdargs.keys())
180 self.logger.critical(msg)
183 parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \
184 % (command, cmdargs[command]))
186 # user specifies remote aggregate/sm/component
187 if command in ("resources", "slices", "create", "delete", "start", "stop",
188 "restart", "shutdown", "get_ticket", "renew", "status"):
189 parser.add_option("-a", "--aggregate", dest="aggregate",
190 default=None, help="aggregate host")
191 parser.add_option("-p", "--port", dest="port",
192 default=AGGREGATE_PORT, help="aggregate port")
193 parser.add_option("-c", "--component", dest="component", default=None,
194 help="component hrn")
195 parser.add_option("-d", "--delegate", dest="delegate", default=None,
197 help="Include a credential delegated to the user's root"+\
198 "authority in set of credentials for this call")
200 # registy filter option
201 if command in ("list", "show", "remove"):
202 parser.add_option("-t", "--type", dest="type", type="choice",
203 help="type filter ([all]|user|slice|authority|node|aggregate)",
204 choices=("all", "user", "slice", "authority", "node", "aggregate"),
207 if command in ("resources"):
208 parser.add_option("-f", "--format", dest="format", type="choice",
209 help="display format ([xml]|dns|ip)", default="xml",
210 choices=("xml", "dns", "ip"))
212 if command in ("resources", "show", "list"):
213 parser.add_option("-o", "--output", dest="file",
214 help="output XML to file", metavar="FILE", default=None)
216 if command in ("show", "list"):
217 parser.add_option("-f", "--format", dest="format", type="choice",
218 help="display format ([text]|xml)", default="text",
219 choices=("text", "xml"))
221 if command in ("delegate"):
222 parser.add_option("-u", "--user",
223 action="store_true", dest="delegate_user", default=False,
224 help="delegate user credential")
225 parser.add_option("-s", "--slice", dest="delegate_slice",
226 help="delegate slice credential", metavar="HRN", default=None)
228 if command in ("version"):
229 parser.add_option("-R","--registry-version",
230 action="store_true", dest="version_registry", default=False,
231 help="probe registry version instead of slicemgr")
232 parser.add_option("-l","--local",
233 action="store_true", dest="version_local", default=False,
234 help="display version of the local client")
239 def create_parser(self):
241 # Generate command line parser
242 parser = OptionParser(usage="sfi [options] command [command_options] [command_args]",
243 description="Commands: gid,list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset")
244 parser.add_option("-r", "--registry", dest="registry",
245 help="root registry", metavar="URL", default=None)
246 parser.add_option("-s", "--slicemgr", dest="sm",
247 help="slice manager", metavar="URL", default=None)
248 default_sfi_dir = os.path.expanduser("~/.sfi/")
249 parser.add_option("-d", "--dir", dest="sfi_dir",
250 help="config & working directory - default is " + default_sfi_dir,
251 metavar="PATH", default=default_sfi_dir)
252 parser.add_option("-u", "--user", dest="user",
253 help="user name", metavar="HRN", default=None)
254 parser.add_option("-a", "--auth", dest="auth",
255 help="authority name", metavar="HRN", default=None)
256 parser.add_option("-v", "--verbose", action="count", dest="verbose", default=0,
257 help="verbose mode - cumulative")
258 parser.add_option("-D", "--debug",
259 action="store_true", dest="debug", default=False,
260 help="Debug (xml-rpc) protocol messages")
261 parser.add_option("-p", "--protocol", dest="protocol", default="xmlrpc",
262 help="RPC protocol (xmlrpc or soap)")
263 parser.add_option("-k", "--hashrequest",
264 action="store_true", dest="hashrequest", default=False,
265 help="Create a hash of the request that will be authenticated on the server")
266 parser.disable_interspersed_args()
271 def read_config(self):
272 config_file = self.options.sfi_dir + os.sep + "sfi_config"
274 config = Config (config_file)
276 self.logger.critical("Failed to read configuration file %s"%config_file)
277 self.logger.info("Make sure to remove the export clauses and to add quotes")
278 if self.options.verbose==0:
279 self.logger.info("Re-run with -v for more details")
281 self.logger.log_exc("Could not read config file %s"%config_file)
286 if (self.options.sm is not None):
287 self.sm_url = self.options.sm
288 elif hasattr(config, "SFI_SM"):
289 self.sm_url = config.SFI_SM
291 self.logger.error("You need to set e.g. SFI_SM='http://your.slicemanager.url:12347/' in %s" % config_file)
295 if (self.options.registry is not None):
296 self.reg_url = self.options.registry
297 elif hasattr(config, "SFI_REGISTRY"):
298 self.reg_url = config.SFI_REGISTRY
300 self.logger.errors("You need to set e.g. SFI_REGISTRY='http://your.registry.url:12345/' in %s" % config_file)
305 if (self.options.user is not None):
306 self.user = self.options.user
307 elif hasattr(config, "SFI_USER"):
308 self.user = config.SFI_USER
310 self.logger.errors("You need to set e.g. SFI_USER='plc.princeton.username' in %s" % config_file)
314 if (self.options.auth is not None):
315 self.authority = self.options.auth
316 elif hasattr(config, "SFI_AUTH"):
317 self.authority = config.SFI_AUTH
319 self.logger.error("You need to set e.g. SFI_AUTH='plc.princeton' in %s" % config_file)
327 # Establish Connection to SliceMgr and Registry Servers
329 def set_servers(self):
332 # Get key and certificate
333 key_file = self.get_key_file()
334 cert_file = self.get_cert_file(key_file)
335 self.key = Keypair(filename=key_file)
336 self.key_file = key_file
337 self.cert_file = cert_file
338 self.cert = Certificate(filename=cert_file)
339 # Establish connection to server(s)
340 self.logger.info("Contacting Registry at: %s"%self.reg_url)
341 self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, self.options)
342 self.logger.info("Contacting Slice Manager at: %s"%self.sm_url)
343 self.slicemgr = xmlrpcprotocol.get_server(self.sm_url, key_file, cert_file, self.options)
348 # Get various credential and spec files
350 # Establishes limiting conventions
351 # - conflates MAs and SAs
352 # - assumes last token in slice name is unique
354 # Bootstraps credentials
355 # - bootstrap user credential from self-signed certificate
356 # - bootstrap authority credential from user credential
357 # - bootstrap slice credential from user credential
361 def get_key_file(self):
362 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".pkey")
363 if (os.path.isfile(file)):
366 self.logger.error("Key file %s does not exist"%file)
370 def get_cert_file(self, key_file):
372 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert")
373 if (os.path.isfile(file)):
374 # use existing cert if it exists
378 # attempt to use gid as the cert.
379 gid = self._get_gid()
380 self.logger.info("Writing certificate to %s"%file)
381 gid.save_to_file(file)
383 # generate self signed certificate
384 k = Keypair(filename=key_file)
385 cert = Certificate(subject=self.user)
387 cert.set_issuer(k, self.user)
389 self.logger.info("Writing self-signed certificate to %s"%file)
390 cert.save_to_file(file)
394 def get_cached_gid(self, file):
399 if (os.path.isfile(file)):
400 gid = GID(filename=file)
404 def get_gid(self, opts, args):
406 Get the specify gid and save it to file
411 gid = self._get_gid(hrn)
412 self.logger.debug("Sfi.get_gid-> %s",gid.save_to_string(save_parents=True))
415 def _get_gid(self, hrn=None):
417 git_gid helper. Retrive the gid from the registry and save it to file.
423 gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid")
424 gid = self.get_cached_gid(gidfile)
426 user_cred = self.get_user_cred()
427 records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True))
429 raise RecordNotFound(args[0])
430 gid = GID(string=records[0]['gid'])
431 self.logger.info("Writing gid to %s"%gidfile)
432 gid.save_to_file(filename=gidfile)
436 def get_cached_credential(self, file):
438 Return a cached credential only if it hasn't expired.
440 if (os.path.isfile(file)):
441 credential = Credential(filename=file)
442 # make sure it isnt expired
443 if not credential.get_expiration or \
444 datetime.datetime.today() < credential.get_expiration():
448 def get_user_cred(self):
449 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cred")
450 return self.get_cred(file, 'user', self.user)
452 def get_auth_cred(self):
453 if not self.authority:
454 self.logger.critical("no authority specified. Use -a or set SF_AUTH")
456 file = os.path.join(self.options.sfi_dir, self.authority + ".cred")
457 return self.get_cred(file, 'authority', self.authority)
459 def get_slice_cred(self, name):
460 file = os.path.join(self.options.sfi_dir, "slice_" + get_leaf(name) + ".cred")
461 return self.get_cred(file, 'slice', name)
463 def get_cred(self, file, type, hrn):
464 # attempt to load a cached credential
465 cred = self.get_cached_credential(file)
468 cert_string = self.cert.save_to_string(save_parents=True)
469 user_name = self.user.replace(self.authority + ".", '')
470 if user_name.count(".") > 0:
471 user_name = user_name.replace(".", '_')
472 self.user = self.authority + "." + user_name
473 cred_str = self.registry.GetSelfCredential(cert_string, hrn, "user")
475 # bootstrap slice credential from user credential
476 user_cred = self.get_user_cred().save_to_string(save_parents=True)
477 cred_str = self.registry.GetCredential(user_cred, hrn, type)
480 self.logger.critical("Failed to get %s credential" % type)
483 cred = Credential(string=cred_str)
484 cred.save_to_file(file, save_parents=True)
485 self.logger.info("Writing %s credential to %s" %(type, file))
490 def get_rspec_file(self, rspec):
491 if (os.path.isabs(rspec)):
494 file = os.path.join(self.options.sfi_dir, rspec)
495 if (os.path.isfile(file)):
498 self.logger.critical("No such rspec file"%rspec)
501 def get_record_file(self, record):
502 if (os.path.isabs(record)):
505 file = os.path.join(self.options.sfi_dir, record)
506 if (os.path.isfile(file)):
509 self.logger.critical("No such registry record file %s"%record)
512 def load_publickey_string(self, fn):
514 key_string = f.read()
516 # if the filename is a private key file, then extract the public key
517 if "PRIVATE KEY" in key_string:
518 outfn = tempfile.mktemp()
519 cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
522 key_string = f.read()
528 def get_component_server_from_hrn(self, hrn):
529 # direct connection to the nodes component manager interface
530 user_cred = self.get_user_cred().save_to_string(save_parents=True)
531 records = self.registry.Resolve(hrn, user_cred)
532 records = filter_records('node', records)
534 self.logger.warning("No such component:%r"% opts.component)
537 return self.get_server(record['hostname'], CM_PORT, self.key_file, self.cert_file)
539 def get_server(self, host, port, keyfile, certfile):
541 Return an instance of an xmlrpc server connection
543 # port is appended onto the domain, before the path. Should look like:
544 # http://domain:port/path
545 host_parts = host.split('/')
546 host_parts[0] = host_parts[0] + ":" + str(port)
547 url = "http://%s" % "/".join(host_parts)
548 return xmlrpcprotocol.get_server(url, keyfile, certfile, self.options)
550 # xxx opts could be retrieved in self.options
551 def get_server_from_opts(self, opts):
553 Return instance of an xmlrpc connection to a slice manager, aggregate
554 or component server depending on the specified opts
556 server = self.slicemgr
557 # direct connection to an aggregate
558 if hasattr(opts, 'aggregate') and opts.aggregate:
559 server = self.get_server(opts.aggregate, opts.port, self.key_file, self.cert_file)
560 # direct connection to the nodes component manager interface
561 if hasattr(opts, 'component') and opts.component:
562 server = self.get_component_server_from_hrn(opts.component)
565 #==========================================================================
566 # Following functions implement the commands
568 # Registry-related commands
569 #==========================================================================
571 def dispatch(self, command, cmd_opts, cmd_args):
572 return getattr(self, command)(cmd_opts, cmd_args)
574 # list entires in named authority registry
575 def list(self, opts, args):
580 user_cred = self.get_user_cred().save_to_string(save_parents=True)
582 list = self.registry.List(hrn, user_cred)
584 raise Exception, "Not enough parameters for the 'list' command"
586 # filter on person, slice, site, node, etc.
587 # THis really should be in the self.filter_records funct def comment...
588 list = filter_records(opts.type, list)
590 print "%s (%s)" % (record['hrn'], record['type'])
593 if not file.startswith(os.sep):
594 file = os.path.join(self.options.sfi_dir, file)
595 save_records_to_file(file, list)
598 # show named registry record
599 def show(self, opts, args):
604 user_cred = self.get_user_cred().save_to_string(save_parents=True)
605 records = self.registry.Resolve(hrn, user_cred)
606 records = filter_records(opts.type, records)
608 print "No record of type", opts.type
609 for record in records:
610 if record['type'] in ['user']:
611 record = UserRecord(dict=record)
612 elif record['type'] in ['slice']:
613 record = SliceRecord(dict=record)
614 elif record['type'] in ['node']:
615 record = NodeRecord(dict=record)
616 elif record['type'] in ['authority', 'ma', 'sa']:
617 record = AuthorityRecord(dict=record)
619 record = SfaRecord(dict=record)
620 if (opts.format == "text"):
623 print record.save_to_string()
627 if not file.startswith(os.sep):
628 file = os.path.join(self.options.sfi_dir, file)
629 save_records_to_file(file, records)
632 def delegate(self, opts, args):
634 delegee_hrn = args[0]
635 if opts.delegate_user:
636 user_cred = self.get_user_cred()
637 cred = self.delegate_cred(user_cred, delegee_hrn)
638 elif opts.delegate_slice:
639 slice_cred = self.get_slice_cred(opts.delegate_slice)
640 cred = self.delegate_cred(slice_cred, delegee_hrn)
642 self.logger.warning("Must specify either --user or --slice <hrn>")
644 delegated_cred = Credential(string=cred)
645 object_hrn = delegated_cred.get_gid_object().get_hrn()
646 if opts.delegate_user:
647 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_"
648 + get_leaf(object_hrn) + ".cred")
649 elif opts.delegate_slice:
650 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_"
651 + get_leaf(object_hrn) + ".cred")
653 delegated_cred.save_to_file(dest_fn, save_parents=True)
655 self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
657 def delegate_cred(self, object_cred, hrn):
658 # the gid and hrn of the object we are delegating
659 if isinstance(object_cred, str):
660 object_cred = Credential(string=object_cred)
661 object_gid = object_cred.get_gid_object()
662 object_hrn = object_gid.get_hrn()
664 if not object_cred.get_privileges().get_all_delegate():
665 self.logger.error("Object credential %s does not have delegate bit set"%object_hrn)
668 # the delegating user's gid
669 caller_gid = self._get_gid(self.user)
670 caller_gidfile = os.path.join(self.options.sfi_dir, self.user + ".gid")
672 # the gid of the user who will be delegated to
673 delegee_gid = self._get_gid(hrn)
674 delegee_hrn = delegee_gid.get_hrn()
675 delegee_gidfile = os.path.join(self.options.sfi_dir, delegee_hrn + ".gid")
676 delegee_gid.save_to_file(filename=delegee_gidfile)
677 dcred = object_cred.delegate(delegee_gidfile, self.get_key_file(), caller_gidfile)
678 return dcred.save_to_string(save_parents=True)
680 # removed named registry record
681 # - have to first retrieve the record to be removed
682 def remove(self, opts, args):
683 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
691 return self.registry.Remove(hrn, auth_cred, type)
693 # add named registry record
694 def add(self, opts, args):
695 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
699 record_filepath = args[0]
700 rec_file = self.get_record_file(record_filepath)
701 record = load_record_from_file(rec_file).as_dict()
702 return self.registry.Register(record, auth_cred)
704 # update named registry entry
705 def update(self, opts, args):
706 user_cred = self.get_user_cred()
710 rec_file = self.get_record_file(args[0])
711 record = load_record_from_file(rec_file)
712 if record['type'] == "user":
713 if record.get_name() == user_cred.get_gid_object().get_hrn():
714 cred = user_cred.save_to_string(save_parents=True)
716 cred = self.get_auth_cred().save_to_string(save_parents=True)
717 elif record['type'] in ["slice"]:
719 cred = self.get_slice_cred(record.get_name()).save_to_string(save_parents=True)
720 except ServerException, e:
721 # XXX smbaker -- once we have better error return codes, update this
722 # to do something better than a string compare
723 if "Permission error" in e.args[0]:
724 cred = self.get_auth_cred().save_to_string(save_parents=True)
727 elif record.get_type() in ["authority"]:
728 cred = self.get_auth_cred().save_to_string(save_parents=True)
729 elif record.get_type() == 'node':
730 cred = self.get_auth_cred().save_to_string(save_parents=True)
732 raise "unknown record type" + record.get_type()
733 record = record.as_dict()
734 return self.registry.Update(record, cred)
736 def get_trusted_certs(self, opts, args):
738 return uhe trusted certs at this interface
740 trusted_certs = self.registry.get_trusted_certs()
741 for trusted_cert in trusted_certs:
742 cert = Certificate(string=trusted_cert)
743 self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject())
746 def aggregates(self, opts, args):
748 return a list of details about known aggregates
750 user_cred = self.get_user_cred().save_to_string(save_parents=True)
755 result = self.registry.get_aggregates(user_cred, hrn)
759 def registries(self, opts, args):
761 return a list of details about known registries
763 user_cred = self.get_user_cred().save_to_string(save_parents=True)
767 result = self.registry.get_registries(user_cred, hrn)
772 # ==================================================================
773 # Slice-related commands
774 # ==================================================================
777 def version(self, opts, args):
778 if opts.version_local:
779 version=version_core()
781 if opts.version_registry:
784 server = self.get_server_from_opts(opts)
785 version=server.GetVersion()
786 for (k,v) in version.iteritems():
787 print "%-20s: %s"%(k,v)
789 # list instantiated slices
790 def slices(self, opts, args):
792 list instantiated slices
794 user_cred = self.get_user_cred().save_to_string(save_parents=True)
797 delegated_cred = self.delegate_cred(user_cred, get_authority(self.authority))
798 creds.append(delegated_cred)
799 server = self.get_server_from_opts(opts)
800 results = server.ListSlices(creds)
801 display_list(results)
804 # show rspec for named slice
805 def resources(self, opts, args):
806 user_cred = self.get_user_cred().save_to_string(save_parents=True)
807 server = self.slicemgr
809 server = self.get_server_from_opts(opts)
812 cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
814 call_options = {'geni_slice_urn': hrn_to_urn(hrn, 'slice')}
821 delegated_cred = self.delegate_cred(cred, get_authority(self.authority))
822 creds.append(delegated_cred)
823 result = server.ListResources(creds, call_options,unique_call_id())
825 if opts.file is None:
826 display_rspec(result, format)
829 if not file.startswith(os.sep):
830 file = os.path.join(self.options.sfi_dir, file)
831 save_rspec_to_file(result, file)
834 # created named slice with given rspec
835 def create(self, opts, args):
837 slice_urn = hrn_to_urn(slice_hrn, 'slice')
838 user_cred = self.get_user_cred()
839 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
842 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
843 creds.append(delegated_cred)
844 rspec_file = self.get_rspec_file(args[1])
845 rspec = open(rspec_file).read()
846 server = self.get_server_from_opts(opts)
847 result = server.CreateSliver(slice_urn, creds, rspec, [])
851 # get a ticket for the specified slice
852 def get_ticket(self, opts, args):
853 slice_hrn, rspec_path = args[0], args[1]
854 slice_urn = hrn_to_urn(slice_hrn, 'slice')
855 user_cred = self.get_user_cred()
856 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
859 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
860 creds.append(delegated_cred)
861 rspec_file = self.get_rspec_file(rspec_path)
862 rspec = open(rspec_file).read()
863 server = self.get_server_from_opts(opts)
864 ticket_string = server.GetTicket(slice_urn, creds, rspec, [])
865 file = os.path.join(self.options.sfi_dir, get_leaf(slice_hrn) + ".ticket")
866 self.logger.info("writing ticket to %s"%file)
867 ticket = SfaTicket(string=ticket_string)
868 ticket.save_to_file(filename=file, save_parents=True)
870 def redeem_ticket(self, opts, args):
871 ticket_file = args[0]
873 # get slice hrn from the ticket
874 # use this to get the right slice credential
875 ticket = SfaTicket(filename=ticket_file)
877 slice_hrn = ticket.gidObject.get_hrn()
878 slice_urn = hrn_to_urn(slice_hrn, 'slice')
879 #slice_hrn = ticket.attributes['slivers'][0]['hrn']
880 user_cred = self.get_user_cred()
881 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
883 # get a list of node hostnames from the RSpec
884 tree = etree.parse(StringIO(ticket.rspec))
885 root = tree.getroot()
886 hostnames = root.xpath("./network/site/node/hostname/text()")
888 # create an xmlrpc connection to the component manager at each of these
889 # components and gall redeem_ticket
891 for hostname in hostnames:
893 self.logger.info("Calling redeem_ticket at %(hostname)s " % locals())
894 server = self.get_server(hostname, CM_PORT, self.key_file, \
895 self.cert_file, self.options.debug)
896 server.RedeemTicket(ticket.save_to_string(save_parents=True), slice_cred)
897 self.logger.info("Success")
898 except socket.gaierror:
899 self.logger.error("redeem_ticket failed: Component Manager not accepting requests")
901 self.logger.log_exc(e.message)
905 def delete(self, opts, args):
907 slice_urn = hrn_to_urn(slice_hrn, 'slice')
908 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
911 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
912 creds.append(delegated_cred)
913 server = self.get_server_from_opts(opts)
914 return server.DeleteSliver(slice_urn, creds)
917 def start(self, opts, args):
919 slice_urn = hrn_to_urn(slice_hrn, 'slice')
920 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
923 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
924 creds.append(delegated_cred)
925 server = self.get_server_from_opts(opts)
926 return server.Start(slice_urn, creds)
929 def stop(self, opts, args):
931 slice_urn = hrn_to_urn(slice_hrn, 'slice')
932 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
935 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
936 creds.append(delegated_cred)
937 server = self.get_server_from_opts(opts)
938 return server.Stop(slice_urn, creds)
941 def reset(self, opts, args):
943 slice_urn = hrn_to_urn(slice_hrn, 'slice')
944 server = self.get_server_from_opts(opts)
945 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
948 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
949 creds.append(delegated_cred)
950 return server.reset_slice(creds, slice_urn)
952 def renew(self, opts, args):
954 slice_urn = hrn_to_urn(slice_hrn, 'slice')
955 server = self.get_server_from_opts(opts)
956 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
959 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
960 creds.append(delegated_cred)
962 return server.RenewSliver(slice_urn, creds, time)
965 def status(self, opts, args):
967 slice_urn = hrn_to_urn(slice_hrn, 'slice')
968 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
971 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
972 creds.append(delegated_cred)
973 server = self.get_server_from_opts(opts)
974 print server.SliverStatus(slice_urn, creds)
977 def shutdown(self, opts, args):
979 slice_urn = hrn_to_urn(slice_hrn, 'slice')
980 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
983 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
984 creds.append(delegated_cred)
985 server = self.get_server_from_opts(opts)
986 return server.Shutdown(slice_urn, creds)
988 def print_help (self):
989 self.sfi_parser.print_help()
990 self.cmd_parser.print_help()
993 # Main: parse arguments and dispatch to command
996 self.sfi_parser = self.create_parser()
997 (options, args) = self.sfi_parser.parse_args()
998 self.options = options
1000 self.logger.setLevelFromOptVerbose(self.options.verbose)
1001 if options.hashrequest:
1002 self.hashrequest = True
1005 self.logger.critical("No command given. Use -h for help.")
1009 self.cmd_parser = self.create_cmd_parser(command)
1010 (cmd_opts, cmd_args) = self.cmd_parser.parse_args(args[1:])
1014 self.logger.info("Command=%s" % command)
1015 if command in ("resources"):
1016 self.logger.debug("resources cmd_opts %s" % cmd_opts.format)
1017 elif command in ("list", "show", "remove"):
1018 self.logger.debug("cmd_opts.type %s" % cmd_opts.type)
1019 self.logger.debug('cmd_args %s',cmd_args)
1022 self.dispatch(command, cmd_opts, cmd_args)
1024 self.logger.critical ("Unknown command %s"%command)
1029 if __name__ == "__main__":