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
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)
127 self.authority = None
129 self.hashrequest = False
130 sfa_logger_goes_to_console()
131 self.logger=sfa_logger()
133 def create_cmd_parser(self, command, additional_cmdargs=None):
134 cmdargs = {"list": "authority",
139 "aggregates": "[name]",
140 "registries": "[name]",
142 "get_trusted_certs": "cred",
144 "resources": "[name]",
145 "create": "name rspec",
146 "get_ticket": "name rspec",
147 "redeem_ticket": "ticket",
159 if additional_cmdargs:
160 cmdargs.update(additional_cmdargs)
162 if command not in cmdargs:
163 msg="Invalid command\n"
165 msg += ','.join(cmdargs.keys())
166 self.logger.critical(msg)
169 parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \
170 % (command, cmdargs[command]))
172 # user specifies remote aggregate/sm/component
173 if command in ("resources", "slices", "create", "delete", "start", "stop",
174 "restart", "shutdown", "get_ticket", "renew", "status"):
175 parser.add_option("-a", "--aggregate", dest="aggregate",
176 default=None, help="aggregate host")
177 parser.add_option("-p", "--port", dest="port",
178 default=AGGREGATE_PORT, help="aggregate port")
179 parser.add_option("-c", "--component", dest="component", default=None,
180 help="component hrn")
181 parser.add_option("-d", "--delegate", dest="delegate", default=None,
183 help="Include a credential delegated to the user's root"+\
184 "authority in set of credentials for this call")
186 # registy filter option
187 if command in ("list", "show", "remove"):
188 parser.add_option("-t", "--type", dest="type", type="choice",
189 help="type filter ([all]|user|slice|authority|node|aggregate)",
190 choices=("all", "user", "slice", "authority", "node", "aggregate"),
193 if command in ("resources"):
194 parser.add_option("-f", "--format", dest="format", type="choice",
195 help="display format ([xml]|dns|ip)", default="xml",
196 choices=("xml", "dns", "ip"))
198 if command in ("resources", "show", "list"):
199 parser.add_option("-o", "--output", dest="file",
200 help="output XML to file", metavar="FILE", default=None)
202 if command in ("show", "list"):
203 parser.add_option("-f", "--format", dest="format", type="choice",
204 help="display format ([text]|xml)", default="text",
205 choices=("text", "xml"))
207 if command in ("delegate"):
208 parser.add_option("-u", "--user",
209 action="store_true", dest="delegate_user", default=False,
210 help="delegate user credential")
211 parser.add_option("-s", "--slice", dest="delegate_slice",
212 help="delegate slice credential", metavar="HRN", default=None)
214 if command in ("version"):
215 parser.add_option("-R","--registry-version",
216 action="store_true", dest="probe_registry", default=False,
217 help="probe registry version instead of slicemgr")
222 def create_parser(self):
224 # Generate command line parser
225 parser = OptionParser(usage="sfi [options] command [command_options] [command_args]",
226 description="Commands: gid,list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset")
227 parser.add_option("-r", "--registry", dest="registry",
228 help="root registry", metavar="URL", default=None)
229 parser.add_option("-s", "--slicemgr", dest="sm",
230 help="slice manager", metavar="URL", default=None)
231 default_sfi_dir = os.path.expanduser("~/.sfi/")
232 parser.add_option("-d", "--dir", dest="sfi_dir",
233 help="config & working directory - default is " + default_sfi_dir,
234 metavar="PATH", default=default_sfi_dir)
235 parser.add_option("-u", "--user", dest="user",
236 help="user name", metavar="HRN", default=None)
237 parser.add_option("-a", "--auth", dest="auth",
238 help="authority name", metavar="HRN", default=None)
239 parser.add_option("-v", "--verbose", action="count", dest="verbose", default=0,
240 help="verbose mode - cumulative")
241 parser.add_option("-D", "--debug",
242 action="store_true", dest="debug", default=False,
243 help="Debug (xml-rpc) protocol messages")
244 parser.add_option("-p", "--protocol", dest="protocol", default="xmlrpc",
245 help="RPC protocol (xmlrpc or soap)")
246 parser.add_option("-k", "--hashrequest",
247 action="store_true", dest="hashrequest", default=False,
248 help="Create a hash of the request that will be authenticated on the server")
249 parser.disable_interspersed_args()
255 # Establish Connection to SliceMgr and Registry Servers
257 def set_servers(self):
258 config_file = self.options.sfi_dir + os.sep + "sfi_config"
260 config = Config (config_file)
262 self.logger.critical("Failed to read configuration file %s"%config_file)
263 self.logger.info("Make sure to remove the export clauses and to add quotes")
264 if self.options.verbose==0:
265 self.logger.info("Re-run with -v for more details")
267 self.logger.log_exc("Could not read config file %s"%config_file)
272 if (self.options.sm is not None):
273 sm_url = self.options.sm
274 elif hasattr(config, "SFI_SM"):
275 sm_url = config.SFI_SM
277 self.logger.error("You need to set e.g. SFI_SM='http://your.slicemanager.url:12347/' in %s" % config_file)
281 if (self.options.registry is not None):
282 reg_url = self.options.registry
283 elif hasattr(config, "SFI_REGISTRY"):
284 reg_url = config.SFI_REGISTRY
286 self.logger.errors("You need to set e.g. SFI_REGISTRY='http://your.registry.url:12345/' in %s" % config_file)
291 if (self.options.user is not None):
292 self.user = self.options.user
293 elif hasattr(config, "SFI_USER"):
294 self.user = config.SFI_USER
296 self.logger.errors("You need to set e.g. SFI_USER='plc.princeton.username' in %s" % config_file)
300 if (self.options.auth is not None):
301 self.authority = self.options.auth
302 elif hasattr(config, "SFI_AUTH"):
303 self.authority = config.SFI_AUTH
305 self.logger.error("You need to set e.g. SFI_AUTH='plc.princeton' in %s" % config_file)
312 # Get key and certificate
313 key_file = self.get_key_file()
314 cert_file = self.get_cert_file(key_file)
315 self.key = Keypair(filename=key_file)
316 self.key_file = key_file
317 self.cert_file = cert_file
318 self.cert = Certificate(filename=cert_file)
319 # Establish connection to server(s)
320 self.logger.info("Contacting Registry at: %s"%reg_url)
321 self.registry = xmlrpcprotocol.get_server(reg_url, key_file, cert_file, self.options)
322 self.logger.info("Contacting Slice Manager at: %s"%sm_url)
323 self.slicemgr = xmlrpcprotocol.get_server(sm_url, key_file, cert_file, self.options)
328 # Get various credential and spec files
330 # Establishes limiting conventions
331 # - conflates MAs and SAs
332 # - assumes last token in slice name is unique
334 # Bootstraps credentials
335 # - bootstrap user credential from self-signed certificate
336 # - bootstrap authority credential from user credential
337 # - bootstrap slice credential from user credential
341 def get_key_file(self):
342 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".pkey")
343 if (os.path.isfile(file)):
346 self.logger.error("Key file %s does not exist"%file)
350 def get_cert_file(self, key_file):
352 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert")
353 if (os.path.isfile(file)):
354 # use existing cert if it exists
358 # attempt to use gid as the cert.
359 gid = self._get_gid()
360 self.logger.info("Writing certificate to %s"%file)
361 gid.save_to_file(file)
363 # generate self signed certificate
364 k = Keypair(filename=key_file)
365 cert = Certificate(subject=self.user)
367 cert.set_issuer(k, self.user)
369 self.logger.info("Writing self-signed certificate to %s"%file)
370 cert.save_to_file(file)
374 def get_cached_gid(self, file):
379 if (os.path.isfile(file)):
380 gid = GID(filename=file)
384 def get_gid(self, opts, args):
386 Get the specify gid and save it to file
391 gid = self._get_gid(hrn)
392 self.logger.debug("Sfi.get_gid-> %s",gid.save_to_string(save_parents=True))
395 def _get_gid(self, hrn=None):
397 git_gid helper. Retrive the gid from the registry and save it to file.
403 gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid")
404 gid = self.get_cached_gid(gidfile)
406 user_cred = self.get_user_cred()
407 records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True))
409 raise RecordNotFound(args[0])
410 gid = GID(string=records[0]['gid'])
411 self.logger.info("Writing gid to %s"%gidfile)
412 gid.save_to_file(filename=gidfile)
416 def get_cached_credential(self, file):
418 Return a cached credential only if it hasn't expired.
420 if (os.path.isfile(file)):
421 credential = Credential(filename=file)
422 # make sure it isnt expired
423 if not credential.get_expiration or \
424 datetime.datetime.today() < credential.get_expiration():
428 def get_user_cred(self):
429 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cred")
430 return self.get_cred(file, 'user', self.user)
432 def get_auth_cred(self):
433 if not self.authority:
434 self.logger.critical("no authority specified. Use -a or set SF_AUTH")
436 file = os.path.join(self.options.sfi_dir, self.authority + ".cred")
437 return self.get_cred(file, 'authority', self.authority)
439 def get_slice_cred(self, name):
440 file = os.path.join(self.options.sfi_dir, "slice_" + get_leaf(name) + ".cred")
441 return self.get_cred(file, 'slice', name)
443 def get_cred(self, file, type, hrn):
444 # attempt to load a cached credential
445 cred = self.get_cached_credential(file)
448 cert_string = self.cert.save_to_string(save_parents=True)
449 user_name = self.user.replace(self.authority + ".", '')
450 if user_name.count(".") > 0:
451 user_name = user_name.replace(".", '_')
452 self.user = self.authority + "." + user_name
453 cred_str = self.registry.GetSelfCredential(cert_string, hrn, "user")
455 # bootstrap slice credential from user credential
456 user_cred = self.get_user_cred().save_to_string(save_parents=True)
457 cred_str = self.registry.GetCredential(user_cred, hrn, type)
460 self.logger.critical("Failed to get %s credential" % type)
463 cred = Credential(string=cred_str)
464 cred.save_to_file(file, save_parents=True)
465 self.logger.info("Writing %s credential to %s" %(type, file))
470 def get_rspec_file(self, rspec):
471 if (os.path.isabs(rspec)):
474 file = os.path.join(self.options.sfi_dir, rspec)
475 if (os.path.isfile(file)):
478 self.logger.critical("No such rspec file"%rspec)
481 def get_record_file(self, record):
482 if (os.path.isabs(record)):
485 file = os.path.join(self.options.sfi_dir, record)
486 if (os.path.isfile(file)):
489 self.logger.critical("No such registry record file %s"%record)
492 def load_publickey_string(self, fn):
494 key_string = f.read()
496 # if the filename is a private key file, then extract the public key
497 if "PRIVATE KEY" in key_string:
498 outfn = tempfile.mktemp()
499 cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
502 key_string = f.read()
508 def get_component_server_from_hrn(self, hrn):
509 # direct connection to the nodes component manager interface
510 user_cred = self.get_user_cred().save_to_string(save_parents=True)
511 records = self.registry.Resolve(hrn, user_cred)
512 records = filter_records('node', records)
514 self.logger.warning("No such component:%r"% opts.component)
517 return self.get_server(record['hostname'], CM_PORT, self.key_file, self.cert_file)
519 def get_server(self, host, port, keyfile, certfile):
521 Return an instance of an xmlrpc server connection
523 # port is appended onto the domain, before the path. Should look like:
524 # http://domain:port/path
525 host_parts = host.split('/')
526 host_parts[0] = host_parts[0] + ":" + str(port)
527 url = "http://%s" % "/".join(host_parts)
528 return xmlrpcprotocol.get_server(url, keyfile, certfile, self.options)
530 # xxx opts could be retrieved in self.options
531 def get_server_from_opts(self, opts):
533 Return instance of an xmlrpc connection to a slice manager, aggregate
534 or component server depending on the specified opts
536 server = self.slicemgr
537 # direct connection to an aggregate
538 if hasattr(opts, 'aggregate') and opts.aggregate:
539 server = self.get_server(opts.aggregate, opts.port, self.key_file, self.cert_file)
540 # direct connection to the nodes component manager interface
541 if hasattr(opts, 'component') and opts.component:
542 server = self.get_component_server_from_hrn(opts.component)
545 #==========================================================================
546 # Following functions implement the commands
548 # Registry-related commands
549 #==========================================================================
551 def dispatch(self, command, cmd_opts, cmd_args):
552 return getattr(self, command)(cmd_opts, cmd_args)
554 # list entires in named authority registry
555 def list(self, opts, args):
557 self.parser.print_help()
560 user_cred = self.get_user_cred().save_to_string(save_parents=True)
562 list = self.registry.List(hrn, user_cred)
564 raise Exception, "Not enough parameters for the 'list' command"
566 # filter on person, slice, site, node, etc.
567 # THis really should be in the self.filter_records funct def comment...
568 list = filter_records(opts.type, list)
570 print "%s (%s)" % (record['hrn'], record['type'])
573 if not file.startswith(os.sep):
574 file = os.path.join(self.options.sfi_dir, file)
575 save_records_to_file(file, list)
578 # show named registry record
579 def show(self, opts, args):
581 self.parser.print_help()
584 user_cred = self.get_user_cred().save_to_string(save_parents=True)
585 records = self.registry.Resolve(hrn, user_cred)
586 records = filter_records(opts.type, records)
588 print "No record of type", opts.type
589 for record in records:
590 if record['type'] in ['user']:
591 record = UserRecord(dict=record)
592 elif record['type'] in ['slice']:
593 record = SliceRecord(dict=record)
594 elif record['type'] in ['node']:
595 record = NodeRecord(dict=record)
596 elif record['type'] in ['authority', 'ma', 'sa']:
597 record = AuthorityRecord(dict=record)
599 record = SfaRecord(dict=record)
600 if (opts.format == "text"):
603 print record.save_to_string()
607 if not file.startswith(os.sep):
608 file = os.path.join(self.options.sfi_dir, file)
609 save_records_to_file(file, records)
612 def delegate(self, opts, args):
614 delegee_hrn = args[0]
615 if opts.delegate_user:
616 user_cred = self.get_user_cred()
617 cred = self.delegate_cred(user_cred, delegee_hrn)
618 elif opts.delegate_slice:
619 slice_cred = self.get_slice_cred(opts.delegate_slice)
620 cred = self.delegate_cred(slice_cred, delegee_hrn)
622 self.logger.warning("Must specify either --user or --slice <hrn>")
624 delegated_cred = Credential(string=cred)
625 object_hrn = delegated_cred.get_gid_object().get_hrn()
626 if opts.delegate_user:
627 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_"
628 + get_leaf(object_hrn) + ".cred")
629 elif opts.delegate_slice:
630 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_"
631 + get_leaf(object_hrn) + ".cred")
633 delegated_cred.save_to_file(dest_fn, save_parents=True)
635 self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
637 def delegate_cred(self, object_cred, hrn):
638 # the gid and hrn of the object we are delegating
639 if isinstance(object_cred, str):
640 object_cred = Credential(string=object_cred)
641 object_gid = object_cred.get_gid_object()
642 object_hrn = object_gid.get_hrn()
644 if not object_cred.get_privileges().get_all_delegate():
645 self.logger.error("Object credential %s does not have delegate bit set"%object_hrn)
648 # the delegating user's gid
649 caller_gid = self._get_gid(self.user)
650 caller_gidfile = os.path.join(self.options.sfi_dir, self.user + ".gid")
652 # the gid of the user who will be delegated to
653 delegee_gid = self._get_gid(hrn)
654 delegee_hrn = delegee_gid.get_hrn()
655 delegee_gidfile = os.path.join(self.options.sfi_dir, delegee_hrn + ".gid")
656 delegee_gid.save_to_file(filename=delegee_gidfile)
657 dcred = object_cred.delegate(delegee_gidfile, self.get_key_file(), caller_gidfile)
658 return dcred.save_to_string(save_parents=True)
660 # removed named registry record
661 # - have to first retrieve the record to be removed
662 def remove(self, opts, args):
663 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
665 self.parser.print_help()
671 return self.registry.Remove(hrn, auth_cred, type)
673 # add named registry record
674 def add(self, opts, args):
675 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
677 self.parser.print_help()
679 record_filepath = args[0]
680 rec_file = self.get_record_file(record_filepath)
681 record = load_record_from_file(rec_file).as_dict()
682 return self.registry.Register(record, auth_cred)
684 # update named registry entry
685 def update(self, opts, args):
686 user_cred = self.get_user_cred()
688 self.parser.print_help()
690 rec_file = self.get_record_file(args[0])
691 record = load_record_from_file(rec_file)
692 if record['type'] == "user":
693 if record.get_name() == user_cred.get_gid_object().get_hrn():
694 cred = user_cred.save_to_string(save_parents=True)
696 cred = self.get_auth_cred().save_to_string(save_parents=True)
697 elif record['type'] in ["slice"]:
699 cred = self.get_slice_cred(record.get_name()).save_to_string(save_parents=True)
700 except ServerException, e:
701 # XXX smbaker -- once we have better error return codes, update this
702 # to do something better than a string compare
703 if "Permission error" in e.args[0]:
704 cred = self.get_auth_cred().save_to_string(save_parents=True)
707 elif record.get_type() in ["authority"]:
708 cred = self.get_auth_cred().save_to_string(save_parents=True)
709 elif record.get_type() == 'node':
710 cred = self.get_auth_cred().save_to_string(save_parents=True)
712 raise "unknown record type" + record.get_type()
713 record = record.as_dict()
714 return self.registry.Update(record, cred)
716 def get_trusted_certs(self, opts, args):
718 return uhe trusted certs at this interface
720 trusted_certs = self.registry.get_trusted_certs()
721 for trusted_cert in trusted_certs:
722 cert = Certificate(string=trusted_cert)
723 self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject())
726 def aggregates(self, opts, args):
728 return a list of details about known aggregates
730 user_cred = self.get_user_cred().save_to_string(save_parents=True)
735 result = self.registry.get_aggregates(user_cred, hrn)
739 def registries(self, opts, args):
741 return a list of details about known registries
743 user_cred = self.get_user_cred().save_to_string(save_parents=True)
747 result = self.registry.get_registries(user_cred, hrn)
752 # ==================================================================
753 # Slice-related commands
754 # ==================================================================
757 def version(self, opts, args):
758 if opts.probe_registry:
761 server = self.get_server_from_opts(opts)
762 for (k,v) in server.GetVersion().items():
763 print "%-20s: %s"%(k,v)
765 # list instantiated slices
766 def slices(self, opts, args):
768 list instantiated slices
770 user_cred = self.get_user_cred().save_to_string(save_parents=True)
773 delegated_cred = self.delegate_cred(user_cred, get_authority(self.authority))
774 creds.append(delegated_cred)
775 server = self.get_server_from_opts(opts)
776 results = server.ListSlices(creds)
777 display_list(results)
780 # show rspec for named slice
781 def resources(self, opts, args):
782 user_cred = self.get_user_cred().save_to_string(save_parents=True)
783 server = self.slicemgr
785 server = self.get_server_from_opts(opts)
788 cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
790 call_options = {'geni_slice_urn': hrn_to_urn(hrn, 'slice')}
797 delegated_cred = self.delegate_cred(cred, get_authority(self.authority))
798 creds.append(delegated_cred)
799 result = server.ListResources(creds, call_options)
801 display_rspec(result, format)
802 if (opts.file is not None):
804 if not file.startswith(os.sep):
805 file = os.path.join(self.options.sfi_dir, file)
806 save_rspec_to_file(result, file)
809 # created named slice with given rspec
810 def create(self, opts, args):
812 slice_urn = hrn_to_urn(slice_hrn, 'slice')
813 user_cred = self.get_user_cred()
814 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
817 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
818 creds.append(delegated_cred)
819 rspec_file = self.get_rspec_file(args[1])
820 rspec = open(rspec_file).read()
821 server = self.get_server_from_opts(opts)
822 result = server.CreateSliver(slice_urn, creds, rspec, [])
826 # get a ticket for the specified slice
827 def get_ticket(self, opts, args):
828 slice_hrn, rspec_path = args[0], args[1]
829 slice_urn = hrn_to_urn(slice_hrn, 'slice')
830 user_cred = self.get_user_cred()
831 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
834 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
835 creds.append(delegated_cred)
836 rspec_file = self.get_rspec_file(rspec_path)
837 rspec = open(rspec_file).read()
838 server = self.get_server_from_opts(opts)
839 ticket_string = server.GetTicket(slice_urn, creds, rspec, [])
840 file = os.path.join(self.options.sfi_dir, get_leaf(slice_hrn) + ".ticket")
841 self.logger.info("writing ticket to %s"%file)
842 ticket = SfaTicket(string=ticket_string)
843 ticket.save_to_file(filename=file, save_parents=True)
845 def redeem_ticket(self, opts, args):
846 ticket_file = args[0]
848 # get slice hrn from the ticket
849 # use this to get the right slice credential
850 ticket = SfaTicket(filename=ticket_file)
852 slice_hrn = ticket.gidObject.get_hrn()
853 slice_urn = hrn_to_urn(slice_hrn, 'slice')
854 #slice_hrn = ticket.attributes['slivers'][0]['hrn']
855 user_cred = self.get_user_cred()
856 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
858 # get a list of node hostnames from the RSpec
859 tree = etree.parse(StringIO(ticket.rspec))
860 root = tree.getroot()
861 hostnames = root.xpath("./network/site/node/hostname/text()")
863 # create an xmlrpc connection to the component manager at each of these
864 # components and gall redeem_ticket
866 for hostname in hostnames:
868 self.logger.info("Calling redeem_ticket at %(hostname)s " % locals())
869 server = self.get_server(hostname, CM_PORT, self.key_file, \
870 self.cert_file, self.options.debug)
871 server.RedeemTicket(ticket.save_to_string(save_parents=True), slice_cred)
872 self.logger.info("Success")
873 except socket.gaierror:
874 self.logger.error("redeem_ticket failed: Component Manager not accepting requests")
876 self.logger.log_exc(e.message)
880 def delete(self, opts, args):
882 slice_urn = hrn_to_urn(slice_hrn, 'slice')
883 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
886 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
887 creds.append(delegated_cred)
888 server = self.get_server_from_opts(opts)
889 return server.DeleteSliver(slice_urn, creds)
892 def start(self, opts, args):
894 slice_urn = hrn_to_urn(slice_hrn, 'slice')
895 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
898 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
899 creds.append(delegated_cred)
900 server = self.get_server_from_opts(opts)
901 return server.Start(slice_urn, creds)
904 def stop(self, opts, args):
906 slice_urn = hrn_to_urn(slice_hrn, 'slice')
907 slice_cred = self.get_slice_cred(args[0]).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.Stop(slice_urn, creds)
916 def reset(self, opts, args):
918 slice_urn = hrn_to_urn(slice_hrn, 'slice')
919 server = self.get_server_from_opts(opts)
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 return server.reset_slice(creds, slice_urn)
927 def renew(self, opts, args):
929 slice_urn = hrn_to_urn(slice_hrn, 'slice')
930 server = self.get_server_from_opts(opts)
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)
937 return server.RenewSliver(slice_urn, creds, time)
940 def status(self, opts, args):
942 slice_urn = hrn_to_urn(slice_hrn, 'slice')
943 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
946 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
947 creds.append(delegated_cred)
948 server = self.get_server_from_opts(opts)
949 print server.SliverStatus(slice_urn, creds)
952 def shutdown(self, opts, args):
954 slice_urn = hrn_to_urn(slice_hrn, 'slice')
955 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
958 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
959 creds.append(delegated_cred)
960 server = self.get_server_from_opts(opts)
961 return server.Shutdown(slice_urn, creds)
965 # Main: parse arguments and dispatch to command
968 parser = self.create_parser()
969 (options, args) = parser.parse_args()
970 self.options = options
972 self.logger.setLevelFromOptVerbose(self.options.verbose)
973 if options.hashrequest:
974 self.hashrequest = True
977 self.logger.critical("No command given. Use -h for help.")
981 self.parser = self.create_cmd_parser(command)
982 (cmd_opts, cmd_args) = self.parser.parse_args(args[1:])
986 self.logger.info("Command=%s" % command)
987 if command in ("resources"):
988 self.logger.debug("resources cmd_opts %s" % cmd_opts.format)
989 elif command in ("list", "show", "remove"):
990 self.logger.debug("cmd_opts.type %s" % cmd_opts.type)
991 self.logger.debug('cmd_args %s',cmd_args)
994 self.dispatch(command, cmd_opts, cmd_args)
996 self.logger.critical ("Unknown command %s"%command)
1001 if __name__ == "__main__":