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 # dummy to meet Sfi's expectations for its 'options' field
127 # i.e. s/t we can do setattr on
131 def __init__ (self,options=None):
132 if options is None: options=Sfi.DummyOptions()
133 for opt in Sfi.required_options:
134 if not hasattr(options,opt): setattr(options,opt,None)
135 if not hasattr(options,'sfi_dir'): options.sfi_dir=os.path.expanduser("~/.sfi/")
136 self.options = options
140 self.authority = None
141 self.hashrequest = False
142 sfa_logger_goes_to_console()
143 self.logger=sfa_logger()
145 def create_cmd_parser(self, command, additional_cmdargs=None):
146 cmdargs = {"list": "authority",
151 "aggregates": "[name]",
152 "registries": "[name]",
154 "get_trusted_certs": "cred",
156 "resources": "[name]",
157 "create": "name rspec",
158 "get_ticket": "name rspec",
159 "redeem_ticket": "ticket",
171 if additional_cmdargs:
172 cmdargs.update(additional_cmdargs)
174 if command not in cmdargs:
175 msg="Invalid command\n"
177 msg += ','.join(cmdargs.keys())
178 self.logger.critical(msg)
181 parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \
182 % (command, cmdargs[command]))
184 # user specifies remote aggregate/sm/component
185 if command in ("resources", "slices", "create", "delete", "start", "stop",
186 "restart", "shutdown", "get_ticket", "renew", "status"):
187 parser.add_option("-a", "--aggregate", dest="aggregate",
188 default=None, help="aggregate host")
189 parser.add_option("-p", "--port", dest="port",
190 default=AGGREGATE_PORT, help="aggregate port")
191 parser.add_option("-c", "--component", dest="component", default=None,
192 help="component hrn")
193 parser.add_option("-d", "--delegate", dest="delegate", default=None,
195 help="Include a credential delegated to the user's root"+\
196 "authority in set of credentials for this call")
198 # registy filter option
199 if command in ("list", "show", "remove"):
200 parser.add_option("-t", "--type", dest="type", type="choice",
201 help="type filter ([all]|user|slice|authority|node|aggregate)",
202 choices=("all", "user", "slice", "authority", "node", "aggregate"),
205 if command in ("resources"):
206 parser.add_option("-f", "--format", dest="format", type="choice",
207 help="display format ([xml]|dns|ip)", default="xml",
208 choices=("xml", "dns", "ip"))
210 if command in ("resources", "show", "list"):
211 parser.add_option("-o", "--output", dest="file",
212 help="output XML to file", metavar="FILE", default=None)
214 if command in ("show", "list"):
215 parser.add_option("-f", "--format", dest="format", type="choice",
216 help="display format ([text]|xml)", default="text",
217 choices=("text", "xml"))
219 if command in ("delegate"):
220 parser.add_option("-u", "--user",
221 action="store_true", dest="delegate_user", default=False,
222 help="delegate user credential")
223 parser.add_option("-s", "--slice", dest="delegate_slice",
224 help="delegate slice credential", metavar="HRN", default=None)
226 if command in ("version"):
227 parser.add_option("-R","--registry-version",
228 action="store_true", dest="version_registry", default=False,
229 help="probe registry version instead of slicemgr")
230 parser.add_option("-l","--local",
231 action="store_true", dest="version_local", default=False,
232 help="display version of the local client")
237 def create_parser(self):
239 # Generate command line parser
240 parser = OptionParser(usage="sfi [options] command [command_options] [command_args]",
241 description="Commands: gid,list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset")
242 parser.add_option("-r", "--registry", dest="registry",
243 help="root registry", metavar="URL", default=None)
244 parser.add_option("-s", "--slicemgr", dest="sm",
245 help="slice manager", metavar="URL", default=None)
246 default_sfi_dir = os.path.expanduser("~/.sfi/")
247 parser.add_option("-d", "--dir", dest="sfi_dir",
248 help="config & working directory - default is " + default_sfi_dir,
249 metavar="PATH", default=default_sfi_dir)
250 parser.add_option("-u", "--user", dest="user",
251 help="user name", metavar="HRN", default=None)
252 parser.add_option("-a", "--auth", dest="auth",
253 help="authority name", metavar="HRN", default=None)
254 parser.add_option("-v", "--verbose", action="count", dest="verbose", default=0,
255 help="verbose mode - cumulative")
256 parser.add_option("-D", "--debug",
257 action="store_true", dest="debug", default=False,
258 help="Debug (xml-rpc) protocol messages")
259 parser.add_option("-p", "--protocol", dest="protocol", default="xmlrpc",
260 help="RPC protocol (xmlrpc or soap)")
261 parser.add_option("-k", "--hashrequest",
262 action="store_true", dest="hashrequest", default=False,
263 help="Create a hash of the request that will be authenticated on the server")
264 parser.disable_interspersed_args()
269 def read_config(self):
270 config_file = self.options.sfi_dir + os.sep + "sfi_config"
272 config = Config (config_file)
274 self.logger.critical("Failed to read configuration file %s"%config_file)
275 self.logger.info("Make sure to remove the export clauses and to add quotes")
276 if self.options.verbose==0:
277 self.logger.info("Re-run with -v for more details")
279 self.logger.log_exc("Could not read config file %s"%config_file)
284 if (self.options.sm is not None):
285 self.sm_url = self.options.sm
286 elif hasattr(config, "SFI_SM"):
287 self.sm_url = config.SFI_SM
289 self.logger.error("You need to set e.g. SFI_SM='http://your.slicemanager.url:12347/' in %s" % config_file)
293 if (self.options.registry is not None):
294 self.reg_url = self.options.registry
295 elif hasattr(config, "SFI_REGISTRY"):
296 self.reg_url = config.SFI_REGISTRY
298 self.logger.errors("You need to set e.g. SFI_REGISTRY='http://your.registry.url:12345/' in %s" % config_file)
303 if (self.options.user is not None):
304 self.user = self.options.user
305 elif hasattr(config, "SFI_USER"):
306 self.user = config.SFI_USER
308 self.logger.errors("You need to set e.g. SFI_USER='plc.princeton.username' in %s" % config_file)
312 if (self.options.auth is not None):
313 self.authority = self.options.auth
314 elif hasattr(config, "SFI_AUTH"):
315 self.authority = config.SFI_AUTH
317 self.logger.error("You need to set e.g. SFI_AUTH='plc.princeton' in %s" % config_file)
325 # Establish Connection to SliceMgr and Registry Servers
327 def set_servers(self):
330 # Get key and certificate
331 key_file = self.get_key_file()
332 cert_file = self.get_cert_file(key_file)
333 self.key = Keypair(filename=key_file)
334 self.key_file = key_file
335 self.cert_file = cert_file
336 self.cert = Certificate(filename=cert_file)
337 # Establish connection to server(s)
338 self.logger.info("Contacting Registry at: %s"%self.reg_url)
339 self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, self.options)
340 self.logger.info("Contacting Slice Manager at: %s"%self.sm_url)
341 self.slicemgr = xmlrpcprotocol.get_server(self.sm_url, key_file, cert_file, self.options)
346 # Get various credential and spec files
348 # Establishes limiting conventions
349 # - conflates MAs and SAs
350 # - assumes last token in slice name is unique
352 # Bootstraps credentials
353 # - bootstrap user credential from self-signed certificate
354 # - bootstrap authority credential from user credential
355 # - bootstrap slice credential from user credential
359 def get_key_file(self):
360 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".pkey")
361 if (os.path.isfile(file)):
364 self.logger.error("Key file %s does not exist"%file)
368 def get_cert_file(self, key_file):
370 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert")
371 if (os.path.isfile(file)):
372 # use existing cert if it exists
376 # attempt to use gid as the cert.
377 gid = self._get_gid()
378 self.logger.info("Writing certificate to %s"%file)
379 gid.save_to_file(file)
381 # generate self signed certificate
382 k = Keypair(filename=key_file)
383 cert = Certificate(subject=self.user)
385 cert.set_issuer(k, self.user)
387 self.logger.info("Writing self-signed certificate to %s"%file)
388 cert.save_to_file(file)
392 def get_cached_gid(self, file):
397 if (os.path.isfile(file)):
398 gid = GID(filename=file)
402 def get_gid(self, opts, args):
404 Get the specify gid and save it to file
409 gid = self._get_gid(hrn)
410 self.logger.debug("Sfi.get_gid-> %s",gid.save_to_string(save_parents=True))
413 def _get_gid(self, hrn=None):
415 git_gid helper. Retrive the gid from the registry and save it to file.
421 gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid")
422 gid = self.get_cached_gid(gidfile)
424 user_cred = self.get_user_cred()
425 records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True))
427 raise RecordNotFound(args[0])
428 gid = GID(string=records[0]['gid'])
429 self.logger.info("Writing gid to %s"%gidfile)
430 gid.save_to_file(filename=gidfile)
434 def get_cached_credential(self, file):
436 Return a cached credential only if it hasn't expired.
438 if (os.path.isfile(file)):
439 credential = Credential(filename=file)
440 # make sure it isnt expired
441 if not credential.get_expiration or \
442 datetime.datetime.today() < credential.get_expiration():
446 def get_user_cred(self):
447 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cred")
448 return self.get_cred(file, 'user', self.user)
450 def get_auth_cred(self):
451 if not self.authority:
452 self.logger.critical("no authority specified. Use -a or set SF_AUTH")
454 file = os.path.join(self.options.sfi_dir, self.authority + ".cred")
455 return self.get_cred(file, 'authority', self.authority)
457 def get_slice_cred(self, name):
458 file = os.path.join(self.options.sfi_dir, "slice_" + get_leaf(name) + ".cred")
459 return self.get_cred(file, 'slice', name)
461 def get_cred(self, file, type, hrn):
462 # attempt to load a cached credential
463 cred = self.get_cached_credential(file)
466 cert_string = self.cert.save_to_string(save_parents=True)
467 user_name = self.user.replace(self.authority + ".", '')
468 if user_name.count(".") > 0:
469 user_name = user_name.replace(".", '_')
470 self.user = self.authority + "." + user_name
471 cred_str = self.registry.GetSelfCredential(cert_string, hrn, "user")
473 # bootstrap slice credential from user credential
474 user_cred = self.get_user_cred().save_to_string(save_parents=True)
475 cred_str = self.registry.GetCredential(user_cred, hrn, type)
478 self.logger.critical("Failed to get %s credential" % type)
481 cred = Credential(string=cred_str)
482 cred.save_to_file(file, save_parents=True)
483 self.logger.info("Writing %s credential to %s" %(type, file))
488 def get_rspec_file(self, rspec):
489 if (os.path.isabs(rspec)):
492 file = os.path.join(self.options.sfi_dir, rspec)
493 if (os.path.isfile(file)):
496 self.logger.critical("No such rspec file"%rspec)
499 def get_record_file(self, record):
500 if (os.path.isabs(record)):
503 file = os.path.join(self.options.sfi_dir, record)
504 if (os.path.isfile(file)):
507 self.logger.critical("No such registry record file %s"%record)
510 def load_publickey_string(self, fn):
512 key_string = f.read()
514 # if the filename is a private key file, then extract the public key
515 if "PRIVATE KEY" in key_string:
516 outfn = tempfile.mktemp()
517 cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
520 key_string = f.read()
526 def get_component_server_from_hrn(self, hrn):
527 # direct connection to the nodes component manager interface
528 user_cred = self.get_user_cred().save_to_string(save_parents=True)
529 records = self.registry.Resolve(hrn, user_cred)
530 records = filter_records('node', records)
532 self.logger.warning("No such component:%r"% opts.component)
535 return self.get_server(record['hostname'], CM_PORT, self.key_file, self.cert_file)
537 def get_server(self, host, port, keyfile, certfile):
539 Return an instance of an xmlrpc server connection
541 # port is appended onto the domain, before the path. Should look like:
542 # http://domain:port/path
543 host_parts = host.split('/')
544 host_parts[0] = host_parts[0] + ":" + str(port)
545 url = "http://%s" % "/".join(host_parts)
546 return xmlrpcprotocol.get_server(url, keyfile, certfile, self.options)
548 # xxx opts could be retrieved in self.options
549 def get_server_from_opts(self, opts):
551 Return instance of an xmlrpc connection to a slice manager, aggregate
552 or component server depending on the specified opts
554 server = self.slicemgr
555 # direct connection to an aggregate
556 if hasattr(opts, 'aggregate') and opts.aggregate:
557 server = self.get_server(opts.aggregate, opts.port, self.key_file, self.cert_file)
558 # direct connection to the nodes component manager interface
559 if hasattr(opts, 'component') and opts.component:
560 server = self.get_component_server_from_hrn(opts.component)
563 #==========================================================================
564 # Following functions implement the commands
566 # Registry-related commands
567 #==========================================================================
569 def dispatch(self, command, cmd_opts, cmd_args):
570 return getattr(self, command)(cmd_opts, cmd_args)
572 # list entires in named authority registry
573 def list(self, opts, args):
578 user_cred = self.get_user_cred().save_to_string(save_parents=True)
580 list = self.registry.List(hrn, user_cred)
582 raise Exception, "Not enough parameters for the 'list' command"
584 # filter on person, slice, site, node, etc.
585 # THis really should be in the self.filter_records funct def comment...
586 list = filter_records(opts.type, list)
588 print "%s (%s)" % (record['hrn'], record['type'])
591 if not file.startswith(os.sep):
592 file = os.path.join(self.options.sfi_dir, file)
593 save_records_to_file(file, list)
596 # show named registry record
597 def show(self, opts, args):
602 user_cred = self.get_user_cred().save_to_string(save_parents=True)
603 records = self.registry.Resolve(hrn, user_cred)
604 records = filter_records(opts.type, records)
606 print "No record of type", opts.type
607 for record in records:
608 if record['type'] in ['user']:
609 record = UserRecord(dict=record)
610 elif record['type'] in ['slice']:
611 record = SliceRecord(dict=record)
612 elif record['type'] in ['node']:
613 record = NodeRecord(dict=record)
614 elif record['type'] in ['authority', 'ma', 'sa']:
615 record = AuthorityRecord(dict=record)
617 record = SfaRecord(dict=record)
618 if (opts.format == "text"):
621 print record.save_to_string()
625 if not file.startswith(os.sep):
626 file = os.path.join(self.options.sfi_dir, file)
627 save_records_to_file(file, records)
630 def delegate(self, opts, args):
632 delegee_hrn = args[0]
633 if opts.delegate_user:
634 user_cred = self.get_user_cred()
635 cred = self.delegate_cred(user_cred, delegee_hrn)
636 elif opts.delegate_slice:
637 slice_cred = self.get_slice_cred(opts.delegate_slice)
638 cred = self.delegate_cred(slice_cred, delegee_hrn)
640 self.logger.warning("Must specify either --user or --slice <hrn>")
642 delegated_cred = Credential(string=cred)
643 object_hrn = delegated_cred.get_gid_object().get_hrn()
644 if opts.delegate_user:
645 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_"
646 + get_leaf(object_hrn) + ".cred")
647 elif opts.delegate_slice:
648 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_"
649 + get_leaf(object_hrn) + ".cred")
651 delegated_cred.save_to_file(dest_fn, save_parents=True)
653 self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
655 def delegate_cred(self, object_cred, hrn):
656 # the gid and hrn of the object we are delegating
657 if isinstance(object_cred, str):
658 object_cred = Credential(string=object_cred)
659 object_gid = object_cred.get_gid_object()
660 object_hrn = object_gid.get_hrn()
662 if not object_cred.get_privileges().get_all_delegate():
663 self.logger.error("Object credential %s does not have delegate bit set"%object_hrn)
666 # the delegating user's gid
667 caller_gid = self._get_gid(self.user)
668 caller_gidfile = os.path.join(self.options.sfi_dir, self.user + ".gid")
670 # the gid of the user who will be delegated to
671 delegee_gid = self._get_gid(hrn)
672 delegee_hrn = delegee_gid.get_hrn()
673 delegee_gidfile = os.path.join(self.options.sfi_dir, delegee_hrn + ".gid")
674 delegee_gid.save_to_file(filename=delegee_gidfile)
675 dcred = object_cred.delegate(delegee_gidfile, self.get_key_file(), caller_gidfile)
676 return dcred.save_to_string(save_parents=True)
678 # removed named registry record
679 # - have to first retrieve the record to be removed
680 def remove(self, opts, args):
681 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
689 return self.registry.Remove(hrn, auth_cred, type)
691 # add named registry record
692 def add(self, opts, args):
693 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
697 record_filepath = args[0]
698 rec_file = self.get_record_file(record_filepath)
699 record = load_record_from_file(rec_file).as_dict()
700 return self.registry.Register(record, auth_cred)
702 # update named registry entry
703 def update(self, opts, args):
704 user_cred = self.get_user_cred()
708 rec_file = self.get_record_file(args[0])
709 record = load_record_from_file(rec_file)
710 if record['type'] == "user":
711 if record.get_name() == user_cred.get_gid_object().get_hrn():
712 cred = user_cred.save_to_string(save_parents=True)
714 cred = self.get_auth_cred().save_to_string(save_parents=True)
715 elif record['type'] in ["slice"]:
717 cred = self.get_slice_cred(record.get_name()).save_to_string(save_parents=True)
718 except ServerException, e:
719 # XXX smbaker -- once we have better error return codes, update this
720 # to do something better than a string compare
721 if "Permission error" in e.args[0]:
722 cred = self.get_auth_cred().save_to_string(save_parents=True)
725 elif record.get_type() in ["authority"]:
726 cred = self.get_auth_cred().save_to_string(save_parents=True)
727 elif record.get_type() == 'node':
728 cred = self.get_auth_cred().save_to_string(save_parents=True)
730 raise "unknown record type" + record.get_type()
731 record = record.as_dict()
732 return self.registry.Update(record, cred)
734 def get_trusted_certs(self, opts, args):
736 return uhe trusted certs at this interface
738 trusted_certs = self.registry.get_trusted_certs()
739 for trusted_cert in trusted_certs:
740 cert = Certificate(string=trusted_cert)
741 self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject())
744 def aggregates(self, opts, args):
746 return a list of details about known aggregates
748 user_cred = self.get_user_cred().save_to_string(save_parents=True)
753 result = self.registry.get_aggregates(user_cred, hrn)
757 def registries(self, opts, args):
759 return a list of details about known registries
761 user_cred = self.get_user_cred().save_to_string(save_parents=True)
765 result = self.registry.get_registries(user_cred, hrn)
770 # ==================================================================
771 # Slice-related commands
772 # ==================================================================
775 def version(self, opts, args):
776 if opts.version_local:
777 version=version_core()
779 if opts.version_registry:
782 server = self.get_server_from_opts(opts)
783 version=server.GetVersion()
784 for (k,v) in version.items():
785 print "%-20s: %s"%(k,v)
787 # list instantiated slices
788 def slices(self, opts, args):
790 list instantiated slices
792 user_cred = self.get_user_cred().save_to_string(save_parents=True)
795 delegated_cred = self.delegate_cred(user_cred, get_authority(self.authority))
796 creds.append(delegated_cred)
797 server = self.get_server_from_opts(opts)
798 results = server.ListSlices(creds)
799 display_list(results)
802 # show rspec for named slice
803 def resources(self, opts, args):
804 user_cred = self.get_user_cred().save_to_string(save_parents=True)
805 server = self.slicemgr
807 server = self.get_server_from_opts(opts)
810 cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
812 call_options = {'geni_slice_urn': hrn_to_urn(hrn, 'slice')}
819 delegated_cred = self.delegate_cred(cred, get_authority(self.authority))
820 creds.append(delegated_cred)
821 result = server.ListResources(creds, call_options)
823 if opts.file is None:
824 display_rspec(result, format)
827 if not file.startswith(os.sep):
828 file = os.path.join(self.options.sfi_dir, file)
829 save_rspec_to_file(result, file)
832 # created named slice with given rspec
833 def create(self, opts, args):
835 slice_urn = hrn_to_urn(slice_hrn, 'slice')
836 user_cred = self.get_user_cred()
837 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
840 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
841 creds.append(delegated_cred)
842 rspec_file = self.get_rspec_file(args[1])
843 rspec = open(rspec_file).read()
844 server = self.get_server_from_opts(opts)
845 result = server.CreateSliver(slice_urn, creds, rspec, [])
849 # get a ticket for the specified slice
850 def get_ticket(self, opts, args):
851 slice_hrn, rspec_path = args[0], args[1]
852 slice_urn = hrn_to_urn(slice_hrn, 'slice')
853 user_cred = self.get_user_cred()
854 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
857 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
858 creds.append(delegated_cred)
859 rspec_file = self.get_rspec_file(rspec_path)
860 rspec = open(rspec_file).read()
861 server = self.get_server_from_opts(opts)
862 ticket_string = server.GetTicket(slice_urn, creds, rspec, [])
863 file = os.path.join(self.options.sfi_dir, get_leaf(slice_hrn) + ".ticket")
864 self.logger.info("writing ticket to %s"%file)
865 ticket = SfaTicket(string=ticket_string)
866 ticket.save_to_file(filename=file, save_parents=True)
868 def redeem_ticket(self, opts, args):
869 ticket_file = args[0]
871 # get slice hrn from the ticket
872 # use this to get the right slice credential
873 ticket = SfaTicket(filename=ticket_file)
875 slice_hrn = ticket.gidObject.get_hrn()
876 slice_urn = hrn_to_urn(slice_hrn, 'slice')
877 #slice_hrn = ticket.attributes['slivers'][0]['hrn']
878 user_cred = self.get_user_cred()
879 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
881 # get a list of node hostnames from the RSpec
882 tree = etree.parse(StringIO(ticket.rspec))
883 root = tree.getroot()
884 hostnames = root.xpath("./network/site/node/hostname/text()")
886 # create an xmlrpc connection to the component manager at each of these
887 # components and gall redeem_ticket
889 for hostname in hostnames:
891 self.logger.info("Calling redeem_ticket at %(hostname)s " % locals())
892 server = self.get_server(hostname, CM_PORT, self.key_file, \
893 self.cert_file, self.options.debug)
894 server.RedeemTicket(ticket.save_to_string(save_parents=True), slice_cred)
895 self.logger.info("Success")
896 except socket.gaierror:
897 self.logger.error("redeem_ticket failed: Component Manager not accepting requests")
899 self.logger.log_exc(e.message)
903 def delete(self, opts, args):
905 slice_urn = hrn_to_urn(slice_hrn, 'slice')
906 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
909 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
910 creds.append(delegated_cred)
911 server = self.get_server_from_opts(opts)
912 return server.DeleteSliver(slice_urn, creds)
915 def start(self, opts, args):
917 slice_urn = hrn_to_urn(slice_hrn, 'slice')
918 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
921 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
922 creds.append(delegated_cred)
923 server = self.get_server_from_opts(opts)
924 return server.Start(slice_urn, creds)
927 def stop(self, opts, args):
929 slice_urn = hrn_to_urn(slice_hrn, 'slice')
930 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
933 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
934 creds.append(delegated_cred)
935 server = self.get_server_from_opts(opts)
936 return server.Stop(slice_urn, creds)
939 def reset(self, opts, args):
941 slice_urn = hrn_to_urn(slice_hrn, 'slice')
942 server = self.get_server_from_opts(opts)
943 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
946 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
947 creds.append(delegated_cred)
948 return server.reset_slice(creds, slice_urn)
950 def renew(self, opts, args):
952 slice_urn = hrn_to_urn(slice_hrn, 'slice')
953 server = self.get_server_from_opts(opts)
954 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
957 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
958 creds.append(delegated_cred)
960 return server.RenewSliver(slice_urn, creds, time)
963 def status(self, opts, args):
965 slice_urn = hrn_to_urn(slice_hrn, 'slice')
966 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
969 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
970 creds.append(delegated_cred)
971 server = self.get_server_from_opts(opts)
972 print server.SliverStatus(slice_urn, creds)
975 def shutdown(self, opts, args):
977 slice_urn = hrn_to_urn(slice_hrn, 'slice')
978 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
981 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
982 creds.append(delegated_cred)
983 server = self.get_server_from_opts(opts)
984 return server.Shutdown(slice_urn, creds)
986 def print_help (self):
987 self.sfi_parser.print_help()
988 self.cmd_parser.print_help()
991 # Main: parse arguments and dispatch to command
994 self.sfi_parser = self.create_parser()
995 (options, args) = self.sfi_parser.parse_args()
996 self.options = options
998 self.logger.setLevelFromOptVerbose(self.options.verbose)
999 if options.hashrequest:
1000 self.hashrequest = True
1003 self.logger.critical("No command given. Use -h for help.")
1007 self.cmd_parser = self.create_cmd_parser(command)
1008 (cmd_opts, cmd_args) = self.cmd_parser.parse_args(args[1:])
1012 self.logger.info("Command=%s" % command)
1013 if command in ("resources"):
1014 self.logger.debug("resources cmd_opts %s" % cmd_opts.format)
1015 elif command in ("list", "show", "remove"):
1016 self.logger.debug("cmd_opts.type %s" % cmd_opts.type)
1017 self.logger.debug('cmd_args %s',cmd_args)
1020 self.dispatch(command, cmd_opts, cmd_args)
1022 self.logger.critical ("Unknown command %s"%command)
1027 if __name__ == "__main__":