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 if opts.file is None:
802 display_rspec(result, format)
805 if not file.startswith(os.sep):
806 file = os.path.join(self.options.sfi_dir, file)
807 save_rspec_to_file(result, file)
810 # created named slice with given rspec
811 def create(self, opts, args):
813 slice_urn = hrn_to_urn(slice_hrn, 'slice')
814 user_cred = self.get_user_cred()
815 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
818 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
819 creds.append(delegated_cred)
820 rspec_file = self.get_rspec_file(args[1])
821 rspec = open(rspec_file).read()
822 server = self.get_server_from_opts(opts)
823 result = server.CreateSliver(slice_urn, creds, rspec, [])
827 # get a ticket for the specified slice
828 def get_ticket(self, opts, args):
829 slice_hrn, rspec_path = args[0], args[1]
830 slice_urn = hrn_to_urn(slice_hrn, 'slice')
831 user_cred = self.get_user_cred()
832 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
835 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
836 creds.append(delegated_cred)
837 rspec_file = self.get_rspec_file(rspec_path)
838 rspec = open(rspec_file).read()
839 server = self.get_server_from_opts(opts)
840 ticket_string = server.GetTicket(slice_urn, creds, rspec, [])
841 file = os.path.join(self.options.sfi_dir, get_leaf(slice_hrn) + ".ticket")
842 self.logger.info("writing ticket to %s"%file)
843 ticket = SfaTicket(string=ticket_string)
844 ticket.save_to_file(filename=file, save_parents=True)
846 def redeem_ticket(self, opts, args):
847 ticket_file = args[0]
849 # get slice hrn from the ticket
850 # use this to get the right slice credential
851 ticket = SfaTicket(filename=ticket_file)
853 slice_hrn = ticket.gidObject.get_hrn()
854 slice_urn = hrn_to_urn(slice_hrn, 'slice')
855 #slice_hrn = ticket.attributes['slivers'][0]['hrn']
856 user_cred = self.get_user_cred()
857 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
859 # get a list of node hostnames from the RSpec
860 tree = etree.parse(StringIO(ticket.rspec))
861 root = tree.getroot()
862 hostnames = root.xpath("./network/site/node/hostname/text()")
864 # create an xmlrpc connection to the component manager at each of these
865 # components and gall redeem_ticket
867 for hostname in hostnames:
869 self.logger.info("Calling redeem_ticket at %(hostname)s " % locals())
870 server = self.get_server(hostname, CM_PORT, self.key_file, \
871 self.cert_file, self.options.debug)
872 server.RedeemTicket(ticket.save_to_string(save_parents=True), slice_cred)
873 self.logger.info("Success")
874 except socket.gaierror:
875 self.logger.error("redeem_ticket failed: Component Manager not accepting requests")
877 self.logger.log_exc(e.message)
881 def delete(self, opts, args):
883 slice_urn = hrn_to_urn(slice_hrn, 'slice')
884 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
887 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
888 creds.append(delegated_cred)
889 server = self.get_server_from_opts(opts)
890 return server.DeleteSliver(slice_urn, creds)
893 def start(self, opts, args):
895 slice_urn = hrn_to_urn(slice_hrn, 'slice')
896 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
899 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
900 creds.append(delegated_cred)
901 server = self.get_server_from_opts(opts)
902 return server.Start(slice_urn, creds)
905 def stop(self, opts, args):
907 slice_urn = hrn_to_urn(slice_hrn, 'slice')
908 slice_cred = self.get_slice_cred(args[0]).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.Stop(slice_urn, creds)
917 def reset(self, opts, args):
919 slice_urn = hrn_to_urn(slice_hrn, 'slice')
920 server = self.get_server_from_opts(opts)
921 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
924 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
925 creds.append(delegated_cred)
926 return server.reset_slice(creds, slice_urn)
928 def renew(self, opts, args):
930 slice_urn = hrn_to_urn(slice_hrn, 'slice')
931 server = self.get_server_from_opts(opts)
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)
938 return server.RenewSliver(slice_urn, creds, time)
941 def status(self, opts, args):
943 slice_urn = hrn_to_urn(slice_hrn, 'slice')
944 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
947 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
948 creds.append(delegated_cred)
949 server = self.get_server_from_opts(opts)
950 print server.SliverStatus(slice_urn, creds)
953 def shutdown(self, opts, args):
955 slice_urn = hrn_to_urn(slice_hrn, 'slice')
956 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
959 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
960 creds.append(delegated_cred)
961 server = self.get_server_from_opts(opts)
962 return server.Shutdown(slice_urn, creds)
966 # Main: parse arguments and dispatch to command
969 parser = self.create_parser()
970 (options, args) = parser.parse_args()
971 self.options = options
973 self.logger.setLevelFromOptVerbose(self.options.verbose)
974 if options.hashrequest:
975 self.hashrequest = True
978 self.logger.critical("No command given. Use -h for help.")
982 self.parser = self.create_cmd_parser(command)
983 (cmd_opts, cmd_args) = self.parser.parse_args(args[1:])
987 self.logger.info("Command=%s" % command)
988 if command in ("resources"):
989 self.logger.debug("resources cmd_opts %s" % cmd_opts.format)
990 elif command in ("list", "show", "remove"):
991 self.logger.debug("cmd_opts.type %s" % cmd_opts.type)
992 self.logger.debug('cmd_args %s',cmd_args)
995 self.dispatch(command, cmd_opts, cmd_args)
997 self.logger.critical ("Unknown command %s"%command)
1002 if __name__ == "__main__":