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)
217 def create_parser(self):
219 # Generate command line parser
220 parser = OptionParser(usage="sfi [options] command [command_options] [command_args]",
221 description="Commands: gid,list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset")
222 parser.add_option("-r", "--registry", dest="registry",
223 help="root registry", metavar="URL", default=None)
224 parser.add_option("-s", "--slicemgr", dest="sm",
225 help="slice manager", metavar="URL", default=None)
226 default_sfi_dir = os.path.expanduser("~/.sfi/")
227 parser.add_option("-d", "--dir", dest="sfi_dir",
228 help="config & working directory - default is " + default_sfi_dir,
229 metavar="PATH", default=default_sfi_dir)
230 parser.add_option("-u", "--user", dest="user",
231 help="user name", metavar="HRN", default=None)
232 parser.add_option("-a", "--auth", dest="auth",
233 help="authority name", metavar="HRN", default=None)
234 parser.add_option("-v", "--verbose", action="count", dest="verbose", default=0,
235 help="verbose mode - cumulative")
236 parser.add_option("-D", "--debug",
237 action="store_true", dest="debug", default=False,
238 help="Debug (xml-rpc) protocol messages")
239 parser.add_option("-p", "--protocol", dest="protocol", default="xmlrpc",
240 help="RPC protocol (xmlrpc or soap)")
241 parser.add_option("-k", "--hashrequest",
242 action="store_true", dest="hashrequest", default=False,
243 help="Create a hash of the request that will be authenticated on the server")
244 parser.disable_interspersed_args()
250 # Establish Connection to SliceMgr and Registry Servers
252 def set_servers(self):
253 config_file = self.options.sfi_dir + os.sep + "sfi_config"
255 config = Config (config_file)
257 self.logger.critical("Failed to read configuration file %s"%config_file)
258 self.logger.info("Make sure to remove the export clauses and to add quotes")
259 if self.options.verbose==0:
260 self.logger.info("Re-run with -v for more details")
262 self.logger.log_exc("Could not read config file %s"%config_file)
267 if (self.options.sm is not None):
268 sm_url = self.options.sm
269 elif hasattr(config, "SFI_SM"):
270 sm_url = config.SFI_SM
272 self.logger.error("You need to set e.g. SFI_SM='http://your.slicemanager.url:12347/' in %s" % config_file)
276 if (self.options.registry is not None):
277 reg_url = self.options.registry
278 elif hasattr(config, "SFI_REGISTRY"):
279 reg_url = config.SFI_REGISTRY
281 self.logger.errors("You need to set e.g. SFI_REGISTRY='http://your.registry.url:12345/' in %s" % config_file)
286 if (self.options.user is not None):
287 self.user = self.options.user
288 elif hasattr(config, "SFI_USER"):
289 self.user = config.SFI_USER
291 self.logger.errors("You need to set e.g. SFI_USER='plc.princeton.username' in %s" % config_file)
295 if (self.options.auth is not None):
296 self.authority = self.options.auth
297 elif hasattr(config, "SFI_AUTH"):
298 self.authority = config.SFI_AUTH
300 self.logger.error("You need to set e.g. SFI_AUTH='plc.princeton' in %s" % config_file)
307 # Get key and certificate
308 key_file = self.get_key_file()
309 cert_file = self.get_cert_file(key_file)
310 self.key = Keypair(filename=key_file)
311 self.key_file = key_file
312 self.cert_file = cert_file
313 self.cert = Certificate(filename=cert_file)
314 # Establish connection to server(s)
315 self.logger.info("Contacting Registry at: %s"%reg_url)
316 self.registry = xmlrpcprotocol.get_server(reg_url, key_file, cert_file, self.options)
317 self.logger.info("Contacting Slice Manager at: %s"%sm_url)
318 self.slicemgr = xmlrpcprotocol.get_server(sm_url, key_file, cert_file, self.options)
323 # Get various credential and spec files
325 # Establishes limiting conventions
326 # - conflates MAs and SAs
327 # - assumes last token in slice name is unique
329 # Bootstraps credentials
330 # - bootstrap user credential from self-signed certificate
331 # - bootstrap authority credential from user credential
332 # - bootstrap slice credential from user credential
336 def get_key_file(self):
337 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".pkey")
338 if (os.path.isfile(file)):
341 self.logger.error("Key file %s does not exist"%file)
345 def get_cert_file(self, key_file):
347 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert")
348 if (os.path.isfile(file)):
349 # use existing cert if it exists
353 # attempt to use gid as the cert.
354 gid = self._get_gid()
355 self.logger.info("Writing certificate to %s"%file)
356 gid.save_to_file(file)
358 # generate self signed certificate
359 k = Keypair(filename=key_file)
360 cert = Certificate(subject=self.user)
362 cert.set_issuer(k, self.user)
364 self.logger.info("Writing self-signed certificate to %s"%file)
365 cert.save_to_file(file)
369 def get_cached_gid(self, file):
374 if (os.path.isfile(file)):
375 gid = GID(filename=file)
378 def get_gid(self, opts, args):
380 Get the specify gid and save it to file
385 gid = self._get_gid(hrn)
386 self.logger.debug("Sfi.get_gid-> %s",gid.save_to_string(save_parents=True))
389 def _get_gid(self, hrn=None):
391 git_gid helper. Retrive the gid from the registry and save it to file.
397 gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid")
398 gid = self.get_cached_gid(gidfile)
400 user_cred = self.get_user_cred()
401 records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True))
403 raise RecordNotFound(args[0])
404 gid = GID(string=records[0]['gid'])
405 self.logger.info("Writing gid to %s"%gidfile)
406 gid.save_to_file(filename=gidfile)
410 def get_cached_credential(self, file):
412 Return a cached credential only if it hasn't expired.
414 if (os.path.isfile(file)):
415 credential = Credential(filename=file)
416 # make sure it isnt expired
417 if not credential.get_expiration or \
418 datetime.datetime.today() < credential.get_expiration():
422 def get_user_cred(self):
423 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cred")
424 return self.get_cred(file, 'user', self.user)
426 def get_auth_cred(self):
427 if not self.authority:
428 self.logger.critical("no authority specified. Use -a or set SF_AUTH")
430 file = os.path.join(self.options.sfi_dir, self.authority + ".cred")
431 return self.get_cred(file, 'authority', self.authority)
433 def get_slice_cred(self, name):
434 file = os.path.join(self.options.sfi_dir, "slice_" + get_leaf(name) + ".cred")
435 return self.get_cred(file, 'slice', name)
437 def get_cred(self, file, type, hrn):
438 # attempt to load a cached credential
439 cred = self.get_cached_credential(file)
442 cert_string = self.cert.save_to_string(save_parents=True)
443 user_name = self.user.replace(self.authority + ".", '')
444 if user_name.count(".") > 0:
445 user_name = user_name.replace(".", '_')
446 self.user = self.authority + "." + user_name
447 cred_str = self.registry.GetSelfCredential(cert_string, hrn, "user")
449 # bootstrap slice credential from user credential
450 user_cred = self.get_user_cred().save_to_string(save_parents=True)
451 cred_str = self.registry.GetCredential(user_cred, hrn, type)
454 self.logger.critical("Failed to get %s credential" % type)
457 cred = Credential(string=cred_str)
458 cred.save_to_file(file, save_parents=True)
459 self.logger.info("Writing %s credential to %s" %(type, file))
464 def get_rspec_file(self, rspec):
465 if (os.path.isabs(rspec)):
468 file = os.path.join(self.options.sfi_dir, rspec)
469 if (os.path.isfile(file)):
472 self.logger.critical("No such rspec file"%rspec)
475 def get_record_file(self, record):
476 if (os.path.isabs(record)):
479 file = os.path.join(self.options.sfi_dir, record)
480 if (os.path.isfile(file)):
483 self.logger.critical("No such registry record file %s"%record)
486 def load_publickey_string(self, fn):
488 key_string = f.read()
490 # if the filename is a private key file, then extract the public key
491 if "PRIVATE KEY" in key_string:
492 outfn = tempfile.mktemp()
493 cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
496 key_string = f.read()
501 def get_component_server_from_hrn(self, hrn):
502 # direct connection to the nodes component manager interface
503 user_cred = self.get_user_cred().save_to_string(save_parents=True)
504 records = self.registry.Resolve(hrn, user_cred)
505 records = filter_records('node', records)
507 self.logger.warning("No such component:%r"% opts.component)
510 return self.get_server(record['hostname'], CM_PORT, self.key_file, \
511 self.cert_file, self.options)
513 def get_server(self, host, port, keyfile, certfile):
515 Return an instnace of an xmlrpc server connection
517 url = "http://%s:%s" % (host, port)
518 return xmlrpcprotocol.get_server(url, keyfile, certfile, self.options)
520 def get_server_from_opts(self, opts):
522 Return instance of an xmlrpc connection to a slice manager, aggregate
523 or component server depending on the specified opts
525 server = self.slicemgr
526 # direct connection to an aggregate
527 if hasattr(opts, 'aggregate') and opts.aggregate:
528 server = self.get_server(opts.aggregate, opts.port, self.key_file, self.cert_file)
529 # direct connection to the nodes component manager interface
530 if hasattr(opts, 'component') and opts.component:
531 server = self.get_component_server_from_hrn(opts.component)
534 #==========================================================================
535 # Following functions implement the commands
537 # Registry-related commands
538 #==========================================================================
540 def dispatch(self, command, cmd_opts, cmd_args):
541 return getattr(self, command)(cmd_opts, cmd_args)
543 # list entires in named authority registry
544 def list(self, opts, args):
546 self.parser.print_help()
549 user_cred = self.get_user_cred().save_to_string(save_parents=True)
551 list = self.registry.List(hrn, user_cred)
553 raise Exception, "Not enough parameters for the 'list' command"
555 # filter on person, slice, site, node, etc.
556 # THis really should be in the self.filter_records funct def comment...
557 list = filter_records(opts.type, list)
559 print "%s (%s)" % (record['hrn'], record['type'])
562 if not file.startswith(os.sep):
563 file = os.path.join(self.options.sfi_dir, file)
564 save_records_to_file(file, list)
567 # show named registry record
568 def show(self, opts, args):
570 self.parser.print_help()
573 user_cred = self.get_user_cred().save_to_string(save_parents=True)
574 records = self.registry.Resolve(hrn, user_cred)
575 records = filter_records(opts.type, records)
577 print "No record of type", opts.type
578 for record in records:
579 if record['type'] in ['user']:
580 record = UserRecord(dict=record)
581 elif record['type'] in ['slice']:
582 record = SliceRecord(dict=record)
583 elif record['type'] in ['node']:
584 record = NodeRecord(dict=record)
585 elif record['type'] in ['authority', 'ma', 'sa']:
586 record = AuthorityRecord(dict=record)
588 record = SfaRecord(dict=record)
589 if (opts.format == "text"):
592 print record.save_to_string()
596 if not file.startswith(os.sep):
597 file = os.path.join(self.options.sfi_dir, file)
598 save_records_to_file(file, records)
601 def delegate(self, opts, args):
603 delegee_hrn = args[0]
604 if opts.delegate_user:
605 user_cred = self.get_user_cred()
606 cred = self.delegate_cred(user_cred, delegee_hrn)
607 elif opts.delegate_slice:
608 slice_cred = self.get_slice_cred(opts.delegate_slice)
609 cred = self.delegate_cred(slice_cred, delegee_hrn)
611 self.logger.warning("Must specify either --user or --slice <hrn>")
613 delegated_cred = Credential(string=cred)
614 object_hrn = delegated_cred.get_gid_object().get_hrn()
615 if opts.delegate_user:
616 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_"
617 + get_leaf(object_hrn) + ".cred")
618 elif opts.delegate_slice:
619 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_"
620 + get_leaf(object_hrn) + ".cred")
622 delegated_cred.save_to_file(dest_fn, save_parents=True)
624 self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
626 def delegate_cred(self, object_cred, hrn):
627 # the gid and hrn of the object we are delegating
628 if isinstance(object_cred, str):
629 object_cred = Credential(string=object_cred)
630 object_gid = object_cred.get_gid_object()
631 object_hrn = object_gid.get_hrn()
633 if not object_cred.get_privileges().get_all_delegate():
634 self.logger.error("Object credential %s does not have delegate bit set"%object_hrn)
637 # the delegating user's gid
638 caller_gid = self._get_gid(self.user)
639 caller_gidfile = os.path.join(self.options.sfi_dir, self.user + ".gid")
641 # the gid of the user who will be delegated to
642 delegee_gid = self._get_gid(hrn)
643 delegee_hrn = delegee_gid.get_hrn()
644 delegee_gidfile = os.path.join(self.options.sfi_dir, delegee_hrn + ".gid")
645 delegee_gid.save_to_file(filename=delegee_gidfile)
646 dcred = object_cred.delegate(delegee_gidfile, self.get_key_file(), caller_gidfile)
647 return dcred.save_to_string(save_parents=True)
649 # removed named registry record
650 # - have to first retrieve the record to be removed
651 def remove(self, opts, args):
652 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
654 self.parser.print_help()
660 return self.registry.Remove(hrn, auth_cred, type)
662 # add named registry record
663 def add(self, opts, args):
664 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
666 self.parser.print_help()
668 record_filepath = args[0]
669 rec_file = self.get_record_file(record_filepath)
670 record = load_record_from_file(rec_file).as_dict()
671 return self.registry.Register(record, auth_cred)
673 # update named registry entry
674 def update(self, opts, args):
675 user_cred = self.get_user_cred()
677 self.parser.print_help()
679 rec_file = self.get_record_file(args[0])
680 record = load_record_from_file(rec_file)
681 if record['type'] == "user":
682 if record.get_name() == user_cred.get_gid_object().get_hrn():
683 cred = user_cred.save_to_string(save_parents=True)
685 cred = self.get_auth_cred().save_to_string(save_parents=True)
686 elif record['type'] in ["slice"]:
688 cred = self.get_slice_cred(record.get_name()).save_to_string(save_parents=True)
689 except ServerException, e:
690 # XXX smbaker -- once we have better error return codes, update this
691 # to do something better than a string compare
692 if "Permission error" in e.args[0]:
693 cred = self.get_auth_cred().save_to_string(save_parents=True)
696 elif record.get_type() in ["authority"]:
697 cred = self.get_auth_cred().save_to_string(save_parents=True)
698 elif record.get_type() == 'node':
699 cred = self.get_auth_cred().save_to_string(save_parents=True)
701 raise "unknown record type" + record.get_type()
702 record = record.as_dict()
703 return self.registry.Update(record, cred)
705 def get_trusted_certs(self, opts, args):
707 return uhe trusted certs at this interface
709 trusted_certs = self.registry.get_trusted_certs()
710 for trusted_cert in trusted_certs:
711 cert = Certificate(string=trusted_cert)
712 self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject())
715 def aggregates(self, opts, args):
717 return a list of details about known aggregates
719 user_cred = self.get_user_cred().save_to_string(save_parents=True)
724 result = self.registry.get_aggregates(user_cred, hrn)
728 def registries(self, opts, args):
730 return a list of details about known registries
732 user_cred = self.get_user_cred().save_to_string(save_parents=True)
736 result = self.registry.get_registries(user_cred, hrn)
741 # ==================================================================
742 # Slice-related commands
743 # ==================================================================
746 def version(self, opts, args):
747 server = self.get_server_from_opts(opts)
749 print server.GetVersion()
751 # list instantiated slices
752 def slices(self, opts, args):
754 list instantiated slices
756 user_cred = self.get_user_cred().save_to_string(save_parents=True)
759 delegated_cred = self.delegate_cred(user_cred, get_authority(self.authority))
760 creds.append(delegated_cred)
761 server = self.get_server_from_opts(opts)
762 results = server.ListSlices(creds)
763 display_list(results)
766 # show rspec for named slice
767 def resources(self, opts, args):
768 user_cred = self.get_user_cred().save_to_string(save_parents=True)
769 server = self.slicemgr
771 server = self.get_server_from_opts(opts)
774 cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
776 call_options = {'geni_slice_urn': hrn_to_urn(hrn, 'slice')}
783 delegated_cred = self.delegate_cred(cred, get_authority(self.authority))
784 creds.append(delegated_cred)
785 result = server.ListResources(creds, call_options)
787 display_rspec(result, format)
788 if (opts.file is not None):
790 if not file.startswith(os.sep):
791 file = os.path.join(self.options.sfi_dir, file)
792 save_rspec_to_file(result, file)
795 # created named slice with given rspec
796 def create(self, opts, args):
798 slice_urn = hrn_to_urn(slice_hrn, 'slice')
799 user_cred = self.get_user_cred()
800 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
803 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
804 creds.append(delegated_cred)
805 rspec_file = self.get_rspec_file(args[1])
806 rspec = open(rspec_file).read()
807 server = self.get_server_from_opts(opts)
808 result = server.CreateSliver(slice_urn, creds, rspec, [])
812 # get a ticket for the specified slice
813 def get_ticket(self, opts, args):
814 slice_hrn, rspec_path = args[0], args[1]
815 slice_urn = hrn_to_urn(slice_hrn, 'slice')
816 user_cred = self.get_user_cred()
817 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
820 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
821 creds.append(delegated_cred)
822 rspec_file = self.get_rspec_file(rspec_path)
823 rspec = open(rspec_file).read()
824 server = self.get_server_from_opts(opts)
825 ticket_string = server.GetTicket(slice_urn, creds, rspec, [])
826 file = os.path.join(self.options.sfi_dir, get_leaf(slice_hrn) + ".ticket")
827 self.logger.info("writing ticket to %s"%file)
828 ticket = SfaTicket(string=ticket_string)
829 ticket.save_to_file(filename=file, save_parents=True)
831 def redeem_ticket(self, opts, args):
832 ticket_file = args[0]
834 # get slice hrn from the ticket
835 # use this to get the right slice credential
836 ticket = SfaTicket(filename=ticket_file)
838 slice_hrn = ticket.gidObject.get_hrn()
839 slice_urn = hrn_to_urn(slice_hrn, 'slice')
840 #slice_hrn = ticket.attributes['slivers'][0]['hrn']
841 user_cred = self.get_user_cred()
842 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
844 # get a list of node hostnames from the RSpec
845 tree = etree.parse(StringIO(ticket.rspec))
846 root = tree.getroot()
847 hostnames = root.xpath("./network/site/node/hostname/text()")
849 # create an xmlrpc connection to the component manager at each of these
850 # components and gall redeem_ticket
852 for hostname in hostnames:
854 self.logger.info("Calling redeem_ticket at %(hostname)s " % locals())
855 server = self.get_server(hostname, CM_PORT, self.key_file, \
856 self.cert_file, self.options.debug)
857 server.RedeemTicket(ticket.save_to_string(save_parents=True), slice_cred)
858 self.logger.info("Success")
859 except socket.gaierror:
860 self.logger.error("redeem_ticket failed: Component Manager not accepting requests")
862 self.logger.log_exc(e.message)
866 def delete(self, opts, args):
868 slice_urn = hrn_to_urn(slice_hrn, 'slice')
869 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
872 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
873 creds.append(delegated_cred)
874 server = self.get_server_from_opts(opts)
875 return server.DeleteSliver(slice_urn, creds)
878 def start(self, opts, args):
880 slice_urn = hrn_to_urn(slice_hrn, 'slice')
881 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
884 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
885 creds.append(delegated_cred)
886 server = self.get_server_from_opts(opts)
887 return server.Start(slice_urn, creds)
890 def stop(self, opts, args):
892 slice_urn = hrn_to_urn(slice_hrn, 'slice')
893 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
896 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
897 creds.append(delegated_cred)
898 server = self.get_server_from_opts(opts)
899 return server.Stop(slice_urn, creds)
902 def reset(self, opts, args):
904 slice_urn = hrn_to_urn(slice_hrn, 'slice')
905 server = self.get_server_from_opts(opts)
906 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
909 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
910 creds.append(delegated_cred)
911 return server.reset_slice(creds, slice_urn)
913 def renew(self, opts, args):
915 slice_urn = hrn_to_urn(slice_hrn, 'slice')
916 server = self.get_server_from_opts(opts)
917 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
920 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
921 creds.append(delegated_cred)
923 return server.RenewSliver(slice_urn, creds, time)
926 def status(self, opts, args):
928 slice_urn = hrn_to_urn(slice_hrn, 'slice')
929 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
932 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
933 creds.append(delegated_cred)
934 server = self.get_server_from_opts(opts)
935 print server.SliverStatus(slice_urn, creds)
938 def shutdown(self, opts, args):
940 slice_urn = hrn_to_urn(slice_hrn, 'slice')
941 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
944 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
945 creds.append(delegated_cred)
946 server = self.get_server_from_opts(opts)
947 return server.Shutdown(slice_urn, creds)
951 # Main: parse arguments and dispatch to command
954 parser = self.create_parser()
955 (options, args) = parser.parse_args()
956 self.options = options
958 self.logger.setLevelFromOptVerbose(self.options.verbose)
959 if options.hashrequest:
960 self.hashrequest = True
963 self.logger.critical("No command given. Use -h for help.")
967 self.parser = self.create_cmd_parser(command)
968 (cmd_opts, cmd_args) = self.parser.parse_args(args[1:])
972 self.logger.info("Command=%s" % command)
973 if command in ("resources"):
974 self.logger.debug("resources cmd_opts %s" % cmd_opts.format)
975 elif command in ("list", "show", "remove"):
976 self.logger.debug("cmd_opts.type %s" % cmd_opts.type)
977 self.logger.debug('cmd_args %s',cmd_args)
980 self.dispatch(command, cmd_opts, cmd_args)
982 self.logger.critical ("Unknown command %s"%command)
987 if __name__ == "__main__":