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)
379 def get_gid(self, opts, args):
381 Get the specify gid and save it to file
386 gid = self._get_gid(hrn)
387 self.logger.debug("Sfi.get_gid-> %s",gid.save_to_string(save_parents=True))
390 def _get_gid(self, hrn=None):
392 git_gid helper. Retrive the gid from the registry and save it to file.
398 gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid")
399 gid = self.get_cached_gid(gidfile)
401 user_cred = self.get_user_cred()
402 records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True))
404 raise RecordNotFound(args[0])
405 gid = GID(string=records[0]['gid'])
406 self.logger.info("Writing gid to %s"%gidfile)
407 gid.save_to_file(filename=gidfile)
411 def get_cached_credential(self, file):
413 Return a cached credential only if it hasn't expired.
415 if (os.path.isfile(file)):
416 credential = Credential(filename=file)
417 # make sure it isnt expired
418 if not credential.get_expiration or \
419 datetime.datetime.today() < credential.get_expiration():
423 def get_user_cred(self):
424 file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cred")
425 return self.get_cred(file, 'user', self.user)
427 def get_auth_cred(self):
428 if not self.authority:
429 self.logger.critical("no authority specified. Use -a or set SF_AUTH")
431 file = os.path.join(self.options.sfi_dir, self.authority + ".cred")
432 return self.get_cred(file, 'authority', self.authority)
434 def get_slice_cred(self, name):
435 file = os.path.join(self.options.sfi_dir, "slice_" + get_leaf(name) + ".cred")
436 return self.get_cred(file, 'slice', name)
438 def get_cred(self, file, type, hrn):
439 # attempt to load a cached credential
440 cred = self.get_cached_credential(file)
443 cert_string = self.cert.save_to_string(save_parents=True)
444 user_name = self.user.replace(self.authority + ".", '')
445 if user_name.count(".") > 0:
446 user_name = user_name.replace(".", '_')
447 self.user = self.authority + "." + user_name
448 cred_str = self.registry.GetSelfCredential(cert_string, hrn, "user")
450 # bootstrap slice credential from user credential
451 user_cred = self.get_user_cred().save_to_string(save_parents=True)
452 cred_str = self.registry.GetCredential(user_cred, hrn, type)
455 self.logger.critical("Failed to get %s credential" % type)
458 cred = Credential(string=cred_str)
459 cred.save_to_file(file, save_parents=True)
460 self.logger.info("Writing %s credential to %s" %(type, file))
465 def get_rspec_file(self, rspec):
466 if (os.path.isabs(rspec)):
469 file = os.path.join(self.options.sfi_dir, rspec)
470 if (os.path.isfile(file)):
473 self.logger.critical("No such rspec file"%rspec)
476 def get_record_file(self, record):
477 if (os.path.isabs(record)):
480 file = os.path.join(self.options.sfi_dir, record)
481 if (os.path.isfile(file)):
484 self.logger.critical("No such registry record file %s"%record)
487 def load_publickey_string(self, fn):
489 key_string = f.read()
491 # if the filename is a private key file, then extract the public key
492 if "PRIVATE KEY" in key_string:
493 outfn = tempfile.mktemp()
494 cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
497 key_string = f.read()
503 def get_component_server_from_hrn(self, hrn):
504 # direct connection to the nodes component manager interface
505 user_cred = self.get_user_cred().save_to_string(save_parents=True)
506 records = self.registry.Resolve(hrn, user_cred)
507 records = filter_records('node', records)
509 self.logger.warning("No such component:%r"% opts.component)
512 return self.get_server(record['hostname'], CM_PORT, self.key_file, self.cert_file)
514 def get_server(self, host, port, keyfile, certfile):
516 Return an instance of an xmlrpc server connection
518 # port is appended onto the domain, before the path. Should look like:
519 # http://domain:port/path
520 host_parts = host.split('/')
521 host_parts[0] = host_parts[0] + ":" + str(port)
522 url = "http://%s" % "/".join(host_parts)
523 return xmlrpcprotocol.get_server(url, keyfile, certfile, self.options)
525 # xxx opts could be retrieved in self.options
526 def get_server_from_opts(self, opts):
528 Return instance of an xmlrpc connection to a slice manager, aggregate
529 or component server depending on the specified opts
531 server = self.slicemgr
532 # direct connection to an aggregate
533 if hasattr(opts, 'aggregate') and opts.aggregate:
534 server = self.get_server(opts.aggregate, opts.port, self.key_file, self.cert_file)
535 # direct connection to the nodes component manager interface
536 if hasattr(opts, 'component') and opts.component:
537 server = self.get_component_server_from_hrn(opts.component)
540 #==========================================================================
541 # Following functions implement the commands
543 # Registry-related commands
544 #==========================================================================
546 def dispatch(self, command, cmd_opts, cmd_args):
547 return getattr(self, command)(cmd_opts, cmd_args)
549 # list entires in named authority registry
550 def list(self, opts, args):
552 self.parser.print_help()
555 user_cred = self.get_user_cred().save_to_string(save_parents=True)
557 list = self.registry.List(hrn, user_cred)
559 raise Exception, "Not enough parameters for the 'list' command"
561 # filter on person, slice, site, node, etc.
562 # THis really should be in the self.filter_records funct def comment...
563 list = filter_records(opts.type, list)
565 print "%s (%s)" % (record['hrn'], record['type'])
568 if not file.startswith(os.sep):
569 file = os.path.join(self.options.sfi_dir, file)
570 save_records_to_file(file, list)
573 # show named registry record
574 def show(self, opts, args):
576 self.parser.print_help()
579 user_cred = self.get_user_cred().save_to_string(save_parents=True)
580 records = self.registry.Resolve(hrn, user_cred)
581 records = filter_records(opts.type, records)
583 print "No record of type", opts.type
584 for record in records:
585 if record['type'] in ['user']:
586 record = UserRecord(dict=record)
587 elif record['type'] in ['slice']:
588 record = SliceRecord(dict=record)
589 elif record['type'] in ['node']:
590 record = NodeRecord(dict=record)
591 elif record['type'] in ['authority', 'ma', 'sa']:
592 record = AuthorityRecord(dict=record)
594 record = SfaRecord(dict=record)
595 if (opts.format == "text"):
598 print record.save_to_string()
602 if not file.startswith(os.sep):
603 file = os.path.join(self.options.sfi_dir, file)
604 save_records_to_file(file, records)
607 def delegate(self, opts, args):
609 delegee_hrn = args[0]
610 if opts.delegate_user:
611 user_cred = self.get_user_cred()
612 cred = self.delegate_cred(user_cred, delegee_hrn)
613 elif opts.delegate_slice:
614 slice_cred = self.get_slice_cred(opts.delegate_slice)
615 cred = self.delegate_cred(slice_cred, delegee_hrn)
617 self.logger.warning("Must specify either --user or --slice <hrn>")
619 delegated_cred = Credential(string=cred)
620 object_hrn = delegated_cred.get_gid_object().get_hrn()
621 if opts.delegate_user:
622 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_"
623 + get_leaf(object_hrn) + ".cred")
624 elif opts.delegate_slice:
625 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_"
626 + get_leaf(object_hrn) + ".cred")
628 delegated_cred.save_to_file(dest_fn, save_parents=True)
630 self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
632 def delegate_cred(self, object_cred, hrn):
633 # the gid and hrn of the object we are delegating
634 if isinstance(object_cred, str):
635 object_cred = Credential(string=object_cred)
636 object_gid = object_cred.get_gid_object()
637 object_hrn = object_gid.get_hrn()
639 if not object_cred.get_privileges().get_all_delegate():
640 self.logger.error("Object credential %s does not have delegate bit set"%object_hrn)
643 # the delegating user's gid
644 caller_gid = self._get_gid(self.user)
645 caller_gidfile = os.path.join(self.options.sfi_dir, self.user + ".gid")
647 # the gid of the user who will be delegated to
648 delegee_gid = self._get_gid(hrn)
649 delegee_hrn = delegee_gid.get_hrn()
650 delegee_gidfile = os.path.join(self.options.sfi_dir, delegee_hrn + ".gid")
651 delegee_gid.save_to_file(filename=delegee_gidfile)
652 dcred = object_cred.delegate(delegee_gidfile, self.get_key_file(), caller_gidfile)
653 return dcred.save_to_string(save_parents=True)
655 # removed named registry record
656 # - have to first retrieve the record to be removed
657 def remove(self, opts, args):
658 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
660 self.parser.print_help()
666 return self.registry.Remove(hrn, auth_cred, type)
668 # add named registry record
669 def add(self, opts, args):
670 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
672 self.parser.print_help()
674 record_filepath = args[0]
675 rec_file = self.get_record_file(record_filepath)
676 record = load_record_from_file(rec_file).as_dict()
677 return self.registry.Register(record, auth_cred)
679 # update named registry entry
680 def update(self, opts, args):
681 user_cred = self.get_user_cred()
683 self.parser.print_help()
685 rec_file = self.get_record_file(args[0])
686 record = load_record_from_file(rec_file)
687 if record['type'] == "user":
688 if record.get_name() == user_cred.get_gid_object().get_hrn():
689 cred = user_cred.save_to_string(save_parents=True)
691 cred = self.get_auth_cred().save_to_string(save_parents=True)
692 elif record['type'] in ["slice"]:
694 cred = self.get_slice_cred(record.get_name()).save_to_string(save_parents=True)
695 except ServerException, e:
696 # XXX smbaker -- once we have better error return codes, update this
697 # to do something better than a string compare
698 if "Permission error" in e.args[0]:
699 cred = self.get_auth_cred().save_to_string(save_parents=True)
702 elif record.get_type() in ["authority"]:
703 cred = self.get_auth_cred().save_to_string(save_parents=True)
704 elif record.get_type() == 'node':
705 cred = self.get_auth_cred().save_to_string(save_parents=True)
707 raise "unknown record type" + record.get_type()
708 record = record.as_dict()
709 return self.registry.Update(record, cred)
711 def get_trusted_certs(self, opts, args):
713 return uhe trusted certs at this interface
715 trusted_certs = self.registry.get_trusted_certs()
716 for trusted_cert in trusted_certs:
717 cert = Certificate(string=trusted_cert)
718 self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject())
721 def aggregates(self, opts, args):
723 return a list of details about known aggregates
725 user_cred = self.get_user_cred().save_to_string(save_parents=True)
730 result = self.registry.get_aggregates(user_cred, hrn)
734 def registries(self, opts, args):
736 return a list of details about known registries
738 user_cred = self.get_user_cred().save_to_string(save_parents=True)
742 result = self.registry.get_registries(user_cred, hrn)
747 # ==================================================================
748 # Slice-related commands
749 # ==================================================================
752 def version(self, opts, args):
753 server = self.get_server_from_opts(opts)
755 print server.GetVersion()
757 # list instantiated slices
758 def slices(self, opts, args):
760 list instantiated slices
762 user_cred = self.get_user_cred().save_to_string(save_parents=True)
765 delegated_cred = self.delegate_cred(user_cred, get_authority(self.authority))
766 creds.append(delegated_cred)
767 server = self.get_server_from_opts(opts)
768 results = server.ListSlices(creds)
769 display_list(results)
772 # show rspec for named slice
773 def resources(self, opts, args):
774 user_cred = self.get_user_cred().save_to_string(save_parents=True)
775 server = self.slicemgr
777 server = self.get_server_from_opts(opts)
780 cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
782 call_options = {'geni_slice_urn': hrn_to_urn(hrn, 'slice')}
789 delegated_cred = self.delegate_cred(cred, get_authority(self.authority))
790 creds.append(delegated_cred)
791 result = server.ListResources(creds, call_options)
793 display_rspec(result, format)
794 if (opts.file is not None):
796 if not file.startswith(os.sep):
797 file = os.path.join(self.options.sfi_dir, file)
798 save_rspec_to_file(result, file)
801 # created named slice with given rspec
802 def create(self, opts, args):
804 slice_urn = hrn_to_urn(slice_hrn, 'slice')
805 user_cred = self.get_user_cred()
806 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
809 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
810 creds.append(delegated_cred)
811 rspec_file = self.get_rspec_file(args[1])
812 rspec = open(rspec_file).read()
813 server = self.get_server_from_opts(opts)
814 result = server.CreateSliver(slice_urn, creds, rspec, [])
818 # get a ticket for the specified slice
819 def get_ticket(self, opts, args):
820 slice_hrn, rspec_path = args[0], args[1]
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(rspec_path)
829 rspec = open(rspec_file).read()
830 server = self.get_server_from_opts(opts)
831 ticket_string = server.GetTicket(slice_urn, creds, rspec, [])
832 file = os.path.join(self.options.sfi_dir, get_leaf(slice_hrn) + ".ticket")
833 self.logger.info("writing ticket to %s"%file)
834 ticket = SfaTicket(string=ticket_string)
835 ticket.save_to_file(filename=file, save_parents=True)
837 def redeem_ticket(self, opts, args):
838 ticket_file = args[0]
840 # get slice hrn from the ticket
841 # use this to get the right slice credential
842 ticket = SfaTicket(filename=ticket_file)
844 slice_hrn = ticket.gidObject.get_hrn()
845 slice_urn = hrn_to_urn(slice_hrn, 'slice')
846 #slice_hrn = ticket.attributes['slivers'][0]['hrn']
847 user_cred = self.get_user_cred()
848 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
850 # get a list of node hostnames from the RSpec
851 tree = etree.parse(StringIO(ticket.rspec))
852 root = tree.getroot()
853 hostnames = root.xpath("./network/site/node/hostname/text()")
855 # create an xmlrpc connection to the component manager at each of these
856 # components and gall redeem_ticket
858 for hostname in hostnames:
860 self.logger.info("Calling redeem_ticket at %(hostname)s " % locals())
861 server = self.get_server(hostname, CM_PORT, self.key_file, \
862 self.cert_file, self.options.debug)
863 server.RedeemTicket(ticket.save_to_string(save_parents=True), slice_cred)
864 self.logger.info("Success")
865 except socket.gaierror:
866 self.logger.error("redeem_ticket failed: Component Manager not accepting requests")
868 self.logger.log_exc(e.message)
872 def delete(self, opts, args):
874 slice_urn = hrn_to_urn(slice_hrn, 'slice')
875 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
878 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
879 creds.append(delegated_cred)
880 server = self.get_server_from_opts(opts)
881 return server.DeleteSliver(slice_urn, creds)
884 def start(self, opts, args):
886 slice_urn = hrn_to_urn(slice_hrn, 'slice')
887 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
890 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
891 creds.append(delegated_cred)
892 server = self.get_server_from_opts(opts)
893 return server.Start(slice_urn, creds)
896 def stop(self, opts, args):
898 slice_urn = hrn_to_urn(slice_hrn, 'slice')
899 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
902 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
903 creds.append(delegated_cred)
904 server = self.get_server_from_opts(opts)
905 return server.Stop(slice_urn, creds)
908 def reset(self, opts, args):
910 slice_urn = hrn_to_urn(slice_hrn, 'slice')
911 server = self.get_server_from_opts(opts)
912 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
915 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
916 creds.append(delegated_cred)
917 return server.reset_slice(creds, slice_urn)
919 def renew(self, opts, args):
921 slice_urn = hrn_to_urn(slice_hrn, 'slice')
922 server = self.get_server_from_opts(opts)
923 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
926 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
927 creds.append(delegated_cred)
929 return server.RenewSliver(slice_urn, creds, time)
932 def status(self, opts, args):
934 slice_urn = hrn_to_urn(slice_hrn, 'slice')
935 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
938 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
939 creds.append(delegated_cred)
940 server = self.get_server_from_opts(opts)
941 print server.SliverStatus(slice_urn, creds)
944 def shutdown(self, opts, args):
946 slice_urn = hrn_to_urn(slice_hrn, 'slice')
947 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
950 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
951 creds.append(delegated_cred)
952 server = self.get_server_from_opts(opts)
953 return server.Shutdown(slice_urn, creds)
957 # Main: parse arguments and dispatch to command
960 parser = self.create_parser()
961 (options, args) = parser.parse_args()
962 self.options = options
964 self.logger.setLevelFromOptVerbose(self.options.verbose)
965 if options.hashrequest:
966 self.hashrequest = True
969 self.logger.critical("No command given. Use -h for help.")
973 self.parser = self.create_cmd_parser(command)
974 (cmd_opts, cmd_args) = self.parser.parse_args(args[1:])
978 self.logger.info("Command=%s" % command)
979 if command in ("resources"):
980 self.logger.debug("resources cmd_opts %s" % cmd_opts.format)
981 elif command in ("list", "show", "remove"):
982 self.logger.debug("cmd_opts.type %s" % cmd_opts.type)
983 self.logger.debug('cmd_args %s',cmd_args)
986 self.dispatch(command, cmd_opts, cmd_args)
988 self.logger.critical ("Unknown command %s"%command)
993 if __name__ == "__main__":