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)
128 self.authority = None
130 self.hashrequest = False
131 sfa_logger_goes_to_console()
132 self.logger=sfa_logger()
134 def create_cmd_parser(self, command, additional_cmdargs=None):
135 cmdargs = {"list": "authority",
140 "aggregates": "[name]",
141 "registries": "[name]",
143 "get_trusted_certs": "cred",
145 "resources": "[name]",
146 "create": "name rspec",
147 "get_ticket": "name rspec",
148 "redeem_ticket": "ticket",
160 if additional_cmdargs:
161 cmdargs.update(additional_cmdargs)
163 if command not in cmdargs:
164 msg="Invalid command\n"
166 msg += ','.join(cmdargs.keys())
167 self.logger.critical(msg)
170 parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \
171 % (command, cmdargs[command]))
173 # user specifies remote aggregate/sm/component
174 if command in ("resources", "slices", "create", "delete", "start", "stop",
175 "restart", "shutdown", "get_ticket", "renew", "status"):
176 parser.add_option("-a", "--aggregate", dest="aggregate",
177 default=None, help="aggregate host")
178 parser.add_option("-p", "--port", dest="port",
179 default=AGGREGATE_PORT, help="aggregate port")
180 parser.add_option("-c", "--component", dest="component", default=None,
181 help="component hrn")
182 parser.add_option("-d", "--delegate", dest="delegate", default=None,
184 help="Include a credential delegated to the user's root"+\
185 "authority in set of credentials for this call")
187 # registy filter option
188 if command in ("list", "show", "remove"):
189 parser.add_option("-t", "--type", dest="type", type="choice",
190 help="type filter ([all]|user|slice|authority|node|aggregate)",
191 choices=("all", "user", "slice", "authority", "node", "aggregate"),
194 if command in ("resources"):
195 parser.add_option("-f", "--format", dest="format", type="choice",
196 help="display format ([xml]|dns|ip)", default="xml",
197 choices=("xml", "dns", "ip"))
199 if command in ("resources", "show", "list"):
200 parser.add_option("-o", "--output", dest="file",
201 help="output XML to file", metavar="FILE", default=None)
203 if command in ("show", "list"):
204 parser.add_option("-f", "--format", dest="format", type="choice",
205 help="display format ([text]|xml)", default="text",
206 choices=("text", "xml"))
208 if command in ("delegate"):
209 parser.add_option("-u", "--user",
210 action="store_true", dest="delegate_user", default=False,
211 help="delegate user credential")
212 parser.add_option("-s", "--slice", dest="delegate_slice",
213 help="delegate slice credential", metavar="HRN", default=None)
215 if command in ("version"):
216 parser.add_option("-R","--registry-version",
217 action="store_true", dest="version_registry", default=False,
218 help="probe registry version instead of slicemgr")
219 parser.add_option("-l","--local",
220 action="store_true", dest="version_local", default=False,
221 help="display version of the local client")
226 def create_parser(self):
228 # Generate command line parser
229 parser = OptionParser(usage="sfi [options] command [command_options] [command_args]",
230 description="Commands: gid,list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset")
231 parser.add_option("-r", "--registry", dest="registry",
232 help="root registry", metavar="URL", default=None)
233 parser.add_option("-s", "--slicemgr", dest="sm",
234 help="slice manager", metavar="URL", default=None)
235 default_sfi_dir = os.path.expanduser("~/.sfi/")
236 parser.add_option("-d", "--dir", dest="sfi_dir",
237 help="config & working directory - default is " + default_sfi_dir,
238 metavar="PATH", default=default_sfi_dir)
239 parser.add_option("-u", "--user", dest="user",
240 help="user name", metavar="HRN", default=None)
241 parser.add_option("-a", "--auth", dest="auth",
242 help="authority name", metavar="HRN", default=None)
243 parser.add_option("-v", "--verbose", action="count", dest="verbose", default=0,
244 help="verbose mode - cumulative")
245 parser.add_option("-D", "--debug",
246 action="store_true", dest="debug", default=False,
247 help="Debug (xml-rpc) protocol messages")
248 parser.add_option("-p", "--protocol", dest="protocol", default="xmlrpc",
249 help="RPC protocol (xmlrpc or soap)")
250 parser.add_option("-k", "--hashrequest",
251 action="store_true", dest="hashrequest", default=False,
252 help="Create a hash of the request that will be authenticated on the server")
253 parser.disable_interspersed_args()
259 # Establish Connection to SliceMgr and Registry Servers
261 def set_servers(self):
262 config_file = self.options.sfi_dir + os.sep + "sfi_config"
264 config = Config (config_file)
266 self.logger.critical("Failed to read configuration file %s"%config_file)
267 self.logger.info("Make sure to remove the export clauses and to add quotes")
268 if self.options.verbose==0:
269 self.logger.info("Re-run with -v for more details")
271 self.logger.log_exc("Could not read config file %s"%config_file)
276 if (self.options.sm is not None):
277 sm_url = self.options.sm
278 elif hasattr(config, "SFI_SM"):
279 sm_url = config.SFI_SM
281 self.logger.error("You need to set e.g. SFI_SM='http://your.slicemanager.url:12347/' in %s" % config_file)
285 if (self.options.registry is not None):
286 reg_url = self.options.registry
287 elif hasattr(config, "SFI_REGISTRY"):
288 reg_url = config.SFI_REGISTRY
290 self.logger.errors("You need to set e.g. SFI_REGISTRY='http://your.registry.url:12345/' in %s" % config_file)
295 if (self.options.user is not None):
296 self.user = self.options.user
297 elif hasattr(config, "SFI_USER"):
298 self.user = config.SFI_USER
300 self.logger.errors("You need to set e.g. SFI_USER='plc.princeton.username' in %s" % config_file)
304 if (self.options.auth is not None):
305 self.authority = self.options.auth
306 elif hasattr(config, "SFI_AUTH"):
307 self.authority = config.SFI_AUTH
309 self.logger.error("You need to set e.g. SFI_AUTH='plc.princeton' in %s" % config_file)
316 # Get key and certificate
317 key_file = self.get_key_file()
318 cert_file = self.get_cert_file(key_file)
319 self.key = Keypair(filename=key_file)
320 self.key_file = key_file
321 self.cert_file = cert_file
322 self.cert = Certificate(filename=cert_file)
323 # Establish connection to server(s)
324 self.logger.info("Contacting Registry at: %s"%reg_url)
325 self.registry = xmlrpcprotocol.get_server(reg_url, key_file, cert_file, self.options)
326 self.logger.info("Contacting Slice Manager at: %s"%sm_url)
327 self.slicemgr = xmlrpcprotocol.get_server(sm_url, key_file, cert_file, self.options)
332 # Get various credential and spec files
334 # Establishes limiting conventions
335 # - conflates MAs and SAs
336 # - assumes last token in slice name is unique
338 # Bootstraps credentials
339 # - bootstrap user credential from self-signed certificate
340 # - bootstrap authority credential from user credential
341 # - bootstrap slice credential from user credential
345 def get_key_file(self):
346 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".pkey")
347 if (os.path.isfile(file)):
350 self.logger.error("Key file %s does not exist"%file)
354 def get_cert_file(self, key_file):
356 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert")
357 if (os.path.isfile(file)):
358 # use existing cert if it exists
362 # attempt to use gid as the cert.
363 gid = self._get_gid()
364 self.logger.info("Writing certificate to %s"%file)
365 gid.save_to_file(file)
367 # generate self signed certificate
368 k = Keypair(filename=key_file)
369 cert = Certificate(subject=self.user)
371 cert.set_issuer(k, self.user)
373 self.logger.info("Writing self-signed certificate to %s"%file)
374 cert.save_to_file(file)
378 def get_cached_gid(self, file):
383 if (os.path.isfile(file)):
384 gid = GID(filename=file)
388 def get_gid(self, opts, args):
390 Get the specify gid and save it to file
395 gid = self._get_gid(hrn)
396 self.logger.debug("Sfi.get_gid-> %s",gid.save_to_string(save_parents=True))
399 def _get_gid(self, hrn=None):
401 git_gid helper. Retrive the gid from the registry and save it to file.
407 gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid")
408 gid = self.get_cached_gid(gidfile)
410 user_cred = self.get_user_cred()
411 records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True))
413 raise RecordNotFound(args[0])
414 gid = GID(string=records[0]['gid'])
415 self.logger.info("Writing gid to %s"%gidfile)
416 gid.save_to_file(filename=gidfile)
420 def get_cached_credential(self, file):
422 Return a cached credential only if it hasn't expired.
424 if (os.path.isfile(file)):
425 credential = Credential(filename=file)
426 # make sure it isnt expired
427 if not credential.get_expiration or \
428 datetime.datetime.today() < credential.get_expiration():
432 def get_user_cred(self):
433 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cred")
434 return self.get_cred(file, 'user', self.user)
436 def get_auth_cred(self):
437 if not self.authority:
438 self.logger.critical("no authority specified. Use -a or set SF_AUTH")
440 file = os.path.join(self.options.sfi_dir, self.authority + ".cred")
441 return self.get_cred(file, 'authority', self.authority)
443 def get_slice_cred(self, name):
444 file = os.path.join(self.options.sfi_dir, "slice_" + get_leaf(name) + ".cred")
445 return self.get_cred(file, 'slice', name)
447 def get_cred(self, file, type, hrn):
448 # attempt to load a cached credential
449 cred = self.get_cached_credential(file)
452 cert_string = self.cert.save_to_string(save_parents=True)
453 user_name = self.user.replace(self.authority + ".", '')
454 if user_name.count(".") > 0:
455 user_name = user_name.replace(".", '_')
456 self.user = self.authority + "." + user_name
457 cred_str = self.registry.GetSelfCredential(cert_string, hrn, "user")
459 # bootstrap slice credential from user credential
460 user_cred = self.get_user_cred().save_to_string(save_parents=True)
461 cred_str = self.registry.GetCredential(user_cred, hrn, type)
464 self.logger.critical("Failed to get %s credential" % type)
467 cred = Credential(string=cred_str)
468 cred.save_to_file(file, save_parents=True)
469 self.logger.info("Writing %s credential to %s" %(type, file))
474 def get_rspec_file(self, rspec):
475 if (os.path.isabs(rspec)):
478 file = os.path.join(self.options.sfi_dir, rspec)
479 if (os.path.isfile(file)):
482 self.logger.critical("No such rspec file"%rspec)
485 def get_record_file(self, record):
486 if (os.path.isabs(record)):
489 file = os.path.join(self.options.sfi_dir, record)
490 if (os.path.isfile(file)):
493 self.logger.critical("No such registry record file %s"%record)
496 def load_publickey_string(self, fn):
498 key_string = f.read()
500 # if the filename is a private key file, then extract the public key
501 if "PRIVATE KEY" in key_string:
502 outfn = tempfile.mktemp()
503 cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
506 key_string = f.read()
512 def get_component_server_from_hrn(self, hrn):
513 # direct connection to the nodes component manager interface
514 user_cred = self.get_user_cred().save_to_string(save_parents=True)
515 records = self.registry.Resolve(hrn, user_cred)
516 records = filter_records('node', records)
518 self.logger.warning("No such component:%r"% opts.component)
521 return self.get_server(record['hostname'], CM_PORT, self.key_file, self.cert_file)
523 def get_server(self, host, port, keyfile, certfile):
525 Return an instance of an xmlrpc server connection
527 # port is appended onto the domain, before the path. Should look like:
528 # http://domain:port/path
529 host_parts = host.split('/')
530 host_parts[0] = host_parts[0] + ":" + str(port)
531 url = "http://%s" % "/".join(host_parts)
532 return xmlrpcprotocol.get_server(url, keyfile, certfile, self.options)
534 # xxx opts could be retrieved in self.options
535 def get_server_from_opts(self, opts):
537 Return instance of an xmlrpc connection to a slice manager, aggregate
538 or component server depending on the specified opts
540 server = self.slicemgr
541 # direct connection to an aggregate
542 if hasattr(opts, 'aggregate') and opts.aggregate:
543 server = self.get_server(opts.aggregate, opts.port, self.key_file, self.cert_file)
544 # direct connection to the nodes component manager interface
545 if hasattr(opts, 'component') and opts.component:
546 server = self.get_component_server_from_hrn(opts.component)
549 #==========================================================================
550 # Following functions implement the commands
552 # Registry-related commands
553 #==========================================================================
555 def dispatch(self, command, cmd_opts, cmd_args):
556 return getattr(self, command)(cmd_opts, cmd_args)
558 # list entires in named authority registry
559 def list(self, opts, args):
564 user_cred = self.get_user_cred().save_to_string(save_parents=True)
566 list = self.registry.List(hrn, user_cred)
568 raise Exception, "Not enough parameters for the 'list' command"
570 # filter on person, slice, site, node, etc.
571 # THis really should be in the self.filter_records funct def comment...
572 list = filter_records(opts.type, list)
574 print "%s (%s)" % (record['hrn'], record['type'])
577 if not file.startswith(os.sep):
578 file = os.path.join(self.options.sfi_dir, file)
579 save_records_to_file(file, list)
582 # show named registry record
583 def show(self, opts, args):
588 user_cred = self.get_user_cred().save_to_string(save_parents=True)
589 records = self.registry.Resolve(hrn, user_cred)
590 records = filter_records(opts.type, records)
592 print "No record of type", opts.type
593 for record in records:
594 if record['type'] in ['user']:
595 record = UserRecord(dict=record)
596 elif record['type'] in ['slice']:
597 record = SliceRecord(dict=record)
598 elif record['type'] in ['node']:
599 record = NodeRecord(dict=record)
600 elif record['type'] in ['authority', 'ma', 'sa']:
601 record = AuthorityRecord(dict=record)
603 record = SfaRecord(dict=record)
604 if (opts.format == "text"):
607 print record.save_to_string()
611 if not file.startswith(os.sep):
612 file = os.path.join(self.options.sfi_dir, file)
613 save_records_to_file(file, records)
616 def delegate(self, opts, args):
618 delegee_hrn = args[0]
619 if opts.delegate_user:
620 user_cred = self.get_user_cred()
621 cred = self.delegate_cred(user_cred, delegee_hrn)
622 elif opts.delegate_slice:
623 slice_cred = self.get_slice_cred(opts.delegate_slice)
624 cred = self.delegate_cred(slice_cred, delegee_hrn)
626 self.logger.warning("Must specify either --user or --slice <hrn>")
628 delegated_cred = Credential(string=cred)
629 object_hrn = delegated_cred.get_gid_object().get_hrn()
630 if opts.delegate_user:
631 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_"
632 + get_leaf(object_hrn) + ".cred")
633 elif opts.delegate_slice:
634 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_"
635 + get_leaf(object_hrn) + ".cred")
637 delegated_cred.save_to_file(dest_fn, save_parents=True)
639 self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
641 def delegate_cred(self, object_cred, hrn):
642 # the gid and hrn of the object we are delegating
643 if isinstance(object_cred, str):
644 object_cred = Credential(string=object_cred)
645 object_gid = object_cred.get_gid_object()
646 object_hrn = object_gid.get_hrn()
648 if not object_cred.get_privileges().get_all_delegate():
649 self.logger.error("Object credential %s does not have delegate bit set"%object_hrn)
652 # the delegating user's gid
653 caller_gid = self._get_gid(self.user)
654 caller_gidfile = os.path.join(self.options.sfi_dir, self.user + ".gid")
656 # the gid of the user who will be delegated to
657 delegee_gid = self._get_gid(hrn)
658 delegee_hrn = delegee_gid.get_hrn()
659 delegee_gidfile = os.path.join(self.options.sfi_dir, delegee_hrn + ".gid")
660 delegee_gid.save_to_file(filename=delegee_gidfile)
661 dcred = object_cred.delegate(delegee_gidfile, self.get_key_file(), caller_gidfile)
662 return dcred.save_to_string(save_parents=True)
664 # removed named registry record
665 # - have to first retrieve the record to be removed
666 def remove(self, opts, args):
667 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
675 return self.registry.Remove(hrn, auth_cred, type)
677 # add named registry record
678 def add(self, opts, args):
679 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
683 record_filepath = args[0]
684 rec_file = self.get_record_file(record_filepath)
685 record = load_record_from_file(rec_file).as_dict()
686 return self.registry.Register(record, auth_cred)
688 # update named registry entry
689 def update(self, opts, args):
690 user_cred = self.get_user_cred()
694 rec_file = self.get_record_file(args[0])
695 record = load_record_from_file(rec_file)
696 if record['type'] == "user":
697 if record.get_name() == user_cred.get_gid_object().get_hrn():
698 cred = user_cred.save_to_string(save_parents=True)
700 cred = self.get_auth_cred().save_to_string(save_parents=True)
701 elif record['type'] in ["slice"]:
703 cred = self.get_slice_cred(record.get_name()).save_to_string(save_parents=True)
704 except ServerException, e:
705 # XXX smbaker -- once we have better error return codes, update this
706 # to do something better than a string compare
707 if "Permission error" in e.args[0]:
708 cred = self.get_auth_cred().save_to_string(save_parents=True)
711 elif record.get_type() in ["authority"]:
712 cred = self.get_auth_cred().save_to_string(save_parents=True)
713 elif record.get_type() == 'node':
714 cred = self.get_auth_cred().save_to_string(save_parents=True)
716 raise "unknown record type" + record.get_type()
717 record = record.as_dict()
718 return self.registry.Update(record, cred)
720 def get_trusted_certs(self, opts, args):
722 return uhe trusted certs at this interface
724 trusted_certs = self.registry.get_trusted_certs()
725 for trusted_cert in trusted_certs:
726 cert = Certificate(string=trusted_cert)
727 self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject())
730 def aggregates(self, opts, args):
732 return a list of details about known aggregates
734 user_cred = self.get_user_cred().save_to_string(save_parents=True)
739 result = self.registry.get_aggregates(user_cred, hrn)
743 def registries(self, opts, args):
745 return a list of details about known registries
747 user_cred = self.get_user_cred().save_to_string(save_parents=True)
751 result = self.registry.get_registries(user_cred, hrn)
756 # ==================================================================
757 # Slice-related commands
758 # ==================================================================
761 def version(self, opts, args):
762 if opts.version_local:
763 version=version_core()
765 if opts.version_registry:
768 server = self.get_server_from_opts(opts)
769 version=server.GetVersion()
770 for (k,v) in version.items():
771 print "%-20s: %s"%(k,v)
773 # list instantiated slices
774 def slices(self, opts, args):
776 list instantiated slices
778 user_cred = self.get_user_cred().save_to_string(save_parents=True)
781 delegated_cred = self.delegate_cred(user_cred, get_authority(self.authority))
782 creds.append(delegated_cred)
783 server = self.get_server_from_opts(opts)
784 results = server.ListSlices(creds)
785 display_list(results)
788 # show rspec for named slice
789 def resources(self, opts, args):
790 user_cred = self.get_user_cred().save_to_string(save_parents=True)
791 server = self.slicemgr
793 server = self.get_server_from_opts(opts)
796 cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
798 call_options = {'geni_slice_urn': hrn_to_urn(hrn, 'slice')}
805 delegated_cred = self.delegate_cred(cred, get_authority(self.authority))
806 creds.append(delegated_cred)
807 result = server.ListResources(creds, call_options)
809 if opts.file is None:
810 display_rspec(result, format)
813 if not file.startswith(os.sep):
814 file = os.path.join(self.options.sfi_dir, file)
815 save_rspec_to_file(result, file)
818 # created named slice with given rspec
819 def create(self, opts, args):
821 slice_urn = hrn_to_urn(slice_hrn, 'slice')
822 user_cred = self.get_user_cred()
823 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
826 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
827 creds.append(delegated_cred)
828 rspec_file = self.get_rspec_file(args[1])
829 rspec = open(rspec_file).read()
830 server = self.get_server_from_opts(opts)
831 result = server.CreateSliver(slice_urn, creds, rspec, [])
835 # get a ticket for the specified slice
836 def get_ticket(self, opts, args):
837 slice_hrn, rspec_path = args[0], args[1]
838 slice_urn = hrn_to_urn(slice_hrn, 'slice')
839 user_cred = self.get_user_cred()
840 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
843 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
844 creds.append(delegated_cred)
845 rspec_file = self.get_rspec_file(rspec_path)
846 rspec = open(rspec_file).read()
847 server = self.get_server_from_opts(opts)
848 ticket_string = server.GetTicket(slice_urn, creds, rspec, [])
849 file = os.path.join(self.options.sfi_dir, get_leaf(slice_hrn) + ".ticket")
850 self.logger.info("writing ticket to %s"%file)
851 ticket = SfaTicket(string=ticket_string)
852 ticket.save_to_file(filename=file, save_parents=True)
854 def redeem_ticket(self, opts, args):
855 ticket_file = args[0]
857 # get slice hrn from the ticket
858 # use this to get the right slice credential
859 ticket = SfaTicket(filename=ticket_file)
861 slice_hrn = ticket.gidObject.get_hrn()
862 slice_urn = hrn_to_urn(slice_hrn, 'slice')
863 #slice_hrn = ticket.attributes['slivers'][0]['hrn']
864 user_cred = self.get_user_cred()
865 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
867 # get a list of node hostnames from the RSpec
868 tree = etree.parse(StringIO(ticket.rspec))
869 root = tree.getroot()
870 hostnames = root.xpath("./network/site/node/hostname/text()")
872 # create an xmlrpc connection to the component manager at each of these
873 # components and gall redeem_ticket
875 for hostname in hostnames:
877 self.logger.info("Calling redeem_ticket at %(hostname)s " % locals())
878 server = self.get_server(hostname, CM_PORT, self.key_file, \
879 self.cert_file, self.options.debug)
880 server.RedeemTicket(ticket.save_to_string(save_parents=True), slice_cred)
881 self.logger.info("Success")
882 except socket.gaierror:
883 self.logger.error("redeem_ticket failed: Component Manager not accepting requests")
885 self.logger.log_exc(e.message)
889 def delete(self, opts, args):
891 slice_urn = hrn_to_urn(slice_hrn, 'slice')
892 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
895 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
896 creds.append(delegated_cred)
897 server = self.get_server_from_opts(opts)
898 return server.DeleteSliver(slice_urn, creds)
901 def start(self, opts, args):
903 slice_urn = hrn_to_urn(slice_hrn, 'slice')
904 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
907 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
908 creds.append(delegated_cred)
909 server = self.get_server_from_opts(opts)
910 return server.Start(slice_urn, creds)
913 def stop(self, opts, args):
915 slice_urn = hrn_to_urn(slice_hrn, 'slice')
916 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
919 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
920 creds.append(delegated_cred)
921 server = self.get_server_from_opts(opts)
922 return server.Stop(slice_urn, creds)
925 def reset(self, opts, args):
927 slice_urn = hrn_to_urn(slice_hrn, 'slice')
928 server = self.get_server_from_opts(opts)
929 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
932 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
933 creds.append(delegated_cred)
934 return server.reset_slice(creds, slice_urn)
936 def renew(self, opts, args):
938 slice_urn = hrn_to_urn(slice_hrn, 'slice')
939 server = self.get_server_from_opts(opts)
940 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
943 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
944 creds.append(delegated_cred)
946 return server.RenewSliver(slice_urn, creds, time)
949 def status(self, opts, args):
951 slice_urn = hrn_to_urn(slice_hrn, 'slice')
952 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
955 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
956 creds.append(delegated_cred)
957 server = self.get_server_from_opts(opts)
958 print server.SliverStatus(slice_urn, creds)
961 def shutdown(self, opts, args):
963 slice_urn = hrn_to_urn(slice_hrn, 'slice')
964 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
967 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
968 creds.append(delegated_cred)
969 server = self.get_server_from_opts(opts)
970 return server.Shutdown(slice_urn, creds)
972 def print_help (self):
973 self.sfi_parser.print_help()
974 self.cmd_parser.print_help()
977 # Main: parse arguments and dispatch to command
980 self.sfi_parser = self.create_parser()
981 (options, args) = self.sfi_parser.parse_args()
982 self.options = options
984 self.logger.setLevelFromOptVerbose(self.options.verbose)
985 if options.hashrequest:
986 self.hashrequest = True
989 self.logger.critical("No command given. Use -h for help.")
993 self.cmd_parser = self.create_cmd_parser(command)
994 (cmd_opts, cmd_args) = self.cmd_parser.parse_args(args[1:])
998 self.logger.info("Command=%s" % command)
999 if command in ("resources"):
1000 self.logger.debug("resources cmd_opts %s" % cmd_opts.format)
1001 elif command in ("list", "show", "remove"):
1002 self.logger.debug("cmd_opts.type %s" % cmd_opts.type)
1003 self.logger.debug('cmd_args %s',cmd_args)
1006 self.dispatch(command, cmd_opts, cmd_args)
1008 self.logger.critical ("Unknown command %s"%command)
1013 if __name__ == "__main__":