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 # port is appended onto the domain, before the path. Should look like:
518 # http://domain:port/path
519 host_parts = host.split('/')
520 host_parts[0] = host_parts[0] + ":" + str(port)
521 url = "http://%s" % "/".join(host_parts)
522 return xmlrpcprotocol.get_server(url, keyfile, certfile, self.options)
524 def get_server_from_opts(self, opts):
526 Return instance of an xmlrpc connection to a slice manager, aggregate
527 or component server depending on the specified opts
529 server = self.slicemgr
530 # direct connection to an aggregate
531 if hasattr(opts, 'aggregate') and opts.aggregate:
532 server = self.get_server(opts.aggregate, opts.port, self.key_file, self.cert_file)
533 # direct connection to the nodes component manager interface
534 if hasattr(opts, 'component') and opts.component:
535 server = self.get_component_server_from_hrn(opts.component)
538 #==========================================================================
539 # Following functions implement the commands
541 # Registry-related commands
542 #==========================================================================
544 def dispatch(self, command, cmd_opts, cmd_args):
545 return getattr(self, command)(cmd_opts, cmd_args)
547 # list entires in named authority registry
548 def list(self, opts, args):
550 self.parser.print_help()
553 user_cred = self.get_user_cred().save_to_string(save_parents=True)
555 list = self.registry.List(hrn, user_cred)
557 raise Exception, "Not enough parameters for the 'list' command"
559 # filter on person, slice, site, node, etc.
560 # THis really should be in the self.filter_records funct def comment...
561 list = filter_records(opts.type, list)
563 print "%s (%s)" % (record['hrn'], record['type'])
566 if not file.startswith(os.sep):
567 file = os.path.join(self.options.sfi_dir, file)
568 save_records_to_file(file, list)
571 # show named registry record
572 def show(self, opts, args):
574 self.parser.print_help()
577 user_cred = self.get_user_cred().save_to_string(save_parents=True)
578 records = self.registry.Resolve(hrn, user_cred)
579 records = filter_records(opts.type, records)
581 print "No record of type", opts.type
582 for record in records:
583 if record['type'] in ['user']:
584 record = UserRecord(dict=record)
585 elif record['type'] in ['slice']:
586 record = SliceRecord(dict=record)
587 elif record['type'] in ['node']:
588 record = NodeRecord(dict=record)
589 elif record['type'] in ['authority', 'ma', 'sa']:
590 record = AuthorityRecord(dict=record)
592 record = SfaRecord(dict=record)
593 if (opts.format == "text"):
596 print record.save_to_string()
600 if not file.startswith(os.sep):
601 file = os.path.join(self.options.sfi_dir, file)
602 save_records_to_file(file, records)
605 def delegate(self, opts, args):
607 delegee_hrn = args[0]
608 if opts.delegate_user:
609 user_cred = self.get_user_cred()
610 cred = self.delegate_cred(user_cred, delegee_hrn)
611 elif opts.delegate_slice:
612 slice_cred = self.get_slice_cred(opts.delegate_slice)
613 cred = self.delegate_cred(slice_cred, delegee_hrn)
615 self.logger.warning("Must specify either --user or --slice <hrn>")
617 delegated_cred = Credential(string=cred)
618 object_hrn = delegated_cred.get_gid_object().get_hrn()
619 if opts.delegate_user:
620 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_"
621 + get_leaf(object_hrn) + ".cred")
622 elif opts.delegate_slice:
623 dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_"
624 + get_leaf(object_hrn) + ".cred")
626 delegated_cred.save_to_file(dest_fn, save_parents=True)
628 self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
630 def delegate_cred(self, object_cred, hrn):
631 # the gid and hrn of the object we are delegating
632 if isinstance(object_cred, str):
633 object_cred = Credential(string=object_cred)
634 object_gid = object_cred.get_gid_object()
635 object_hrn = object_gid.get_hrn()
637 if not object_cred.get_privileges().get_all_delegate():
638 self.logger.error("Object credential %s does not have delegate bit set"%object_hrn)
641 # the delegating user's gid
642 caller_gid = self._get_gid(self.user)
643 caller_gidfile = os.path.join(self.options.sfi_dir, self.user + ".gid")
645 # the gid of the user who will be delegated to
646 delegee_gid = self._get_gid(hrn)
647 delegee_hrn = delegee_gid.get_hrn()
648 delegee_gidfile = os.path.join(self.options.sfi_dir, delegee_hrn + ".gid")
649 delegee_gid.save_to_file(filename=delegee_gidfile)
650 dcred = object_cred.delegate(delegee_gidfile, self.get_key_file(), caller_gidfile)
651 return dcred.save_to_string(save_parents=True)
653 # removed named registry record
654 # - have to first retrieve the record to be removed
655 def remove(self, opts, args):
656 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
658 self.parser.print_help()
664 return self.registry.Remove(hrn, auth_cred, type)
666 # add named registry record
667 def add(self, opts, args):
668 auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
670 self.parser.print_help()
672 record_filepath = args[0]
673 rec_file = self.get_record_file(record_filepath)
674 record = load_record_from_file(rec_file).as_dict()
675 return self.registry.Register(record, auth_cred)
677 # update named registry entry
678 def update(self, opts, args):
679 user_cred = self.get_user_cred()
681 self.parser.print_help()
683 rec_file = self.get_record_file(args[0])
684 record = load_record_from_file(rec_file)
685 if record['type'] == "user":
686 if record.get_name() == user_cred.get_gid_object().get_hrn():
687 cred = user_cred.save_to_string(save_parents=True)
689 cred = self.get_auth_cred().save_to_string(save_parents=True)
690 elif record['type'] in ["slice"]:
692 cred = self.get_slice_cred(record.get_name()).save_to_string(save_parents=True)
693 except ServerException, e:
694 # XXX smbaker -- once we have better error return codes, update this
695 # to do something better than a string compare
696 if "Permission error" in e.args[0]:
697 cred = self.get_auth_cred().save_to_string(save_parents=True)
700 elif record.get_type() in ["authority"]:
701 cred = self.get_auth_cred().save_to_string(save_parents=True)
702 elif record.get_type() == 'node':
703 cred = self.get_auth_cred().save_to_string(save_parents=True)
705 raise "unknown record type" + record.get_type()
706 record = record.as_dict()
707 return self.registry.Update(record, cred)
709 def get_trusted_certs(self, opts, args):
711 return uhe trusted certs at this interface
713 trusted_certs = self.registry.get_trusted_certs()
714 for trusted_cert in trusted_certs:
715 cert = Certificate(string=trusted_cert)
716 self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject())
719 def aggregates(self, opts, args):
721 return a list of details about known aggregates
723 user_cred = self.get_user_cred().save_to_string(save_parents=True)
728 result = self.registry.get_aggregates(user_cred, hrn)
732 def registries(self, opts, args):
734 return a list of details about known registries
736 user_cred = self.get_user_cred().save_to_string(save_parents=True)
740 result = self.registry.get_registries(user_cred, hrn)
745 # ==================================================================
746 # Slice-related commands
747 # ==================================================================
750 def version(self, opts, args):
751 server = self.get_server_from_opts(opts)
753 print server.GetVersion()
755 # list instantiated slices
756 def slices(self, opts, args):
758 list instantiated slices
760 user_cred = self.get_user_cred().save_to_string(save_parents=True)
763 delegated_cred = self.delegate_cred(user_cred, get_authority(self.authority))
764 creds.append(delegated_cred)
765 server = self.get_server_from_opts(opts)
766 results = server.ListSlices(creds)
767 display_list(results)
770 # show rspec for named slice
771 def resources(self, opts, args):
772 user_cred = self.get_user_cred().save_to_string(save_parents=True)
773 server = self.slicemgr
775 server = self.get_server_from_opts(opts)
778 cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
780 call_options = {'geni_slice_urn': hrn_to_urn(hrn, 'slice')}
787 delegated_cred = self.delegate_cred(cred, get_authority(self.authority))
788 creds.append(delegated_cred)
789 result = server.ListResources(creds, call_options)
791 display_rspec(result, format)
792 if (opts.file is not None):
794 if not file.startswith(os.sep):
795 file = os.path.join(self.options.sfi_dir, file)
796 save_rspec_to_file(result, file)
799 # created named slice with given rspec
800 def create(self, opts, args):
802 slice_urn = hrn_to_urn(slice_hrn, 'slice')
803 user_cred = self.get_user_cred()
804 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
807 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
808 creds.append(delegated_cred)
809 rspec_file = self.get_rspec_file(args[1])
810 rspec = open(rspec_file).read()
811 server = self.get_server_from_opts(opts)
812 result = server.CreateSliver(slice_urn, creds, rspec, [])
816 # get a ticket for the specified slice
817 def get_ticket(self, opts, args):
818 slice_hrn, rspec_path = args[0], args[1]
819 slice_urn = hrn_to_urn(slice_hrn, 'slice')
820 user_cred = self.get_user_cred()
821 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
824 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
825 creds.append(delegated_cred)
826 rspec_file = self.get_rspec_file(rspec_path)
827 rspec = open(rspec_file).read()
828 server = self.get_server_from_opts(opts)
829 ticket_string = server.GetTicket(slice_urn, creds, rspec, [])
830 file = os.path.join(self.options.sfi_dir, get_leaf(slice_hrn) + ".ticket")
831 self.logger.info("writing ticket to %s"%file)
832 ticket = SfaTicket(string=ticket_string)
833 ticket.save_to_file(filename=file, save_parents=True)
835 def redeem_ticket(self, opts, args):
836 ticket_file = args[0]
838 # get slice hrn from the ticket
839 # use this to get the right slice credential
840 ticket = SfaTicket(filename=ticket_file)
842 slice_hrn = ticket.gidObject.get_hrn()
843 slice_urn = hrn_to_urn(slice_hrn, 'slice')
844 #slice_hrn = ticket.attributes['slivers'][0]['hrn']
845 user_cred = self.get_user_cred()
846 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
848 # get a list of node hostnames from the RSpec
849 tree = etree.parse(StringIO(ticket.rspec))
850 root = tree.getroot()
851 hostnames = root.xpath("./network/site/node/hostname/text()")
853 # create an xmlrpc connection to the component manager at each of these
854 # components and gall redeem_ticket
856 for hostname in hostnames:
858 self.logger.info("Calling redeem_ticket at %(hostname)s " % locals())
859 server = self.get_server(hostname, CM_PORT, self.key_file, \
860 self.cert_file, self.options.debug)
861 server.RedeemTicket(ticket.save_to_string(save_parents=True), slice_cred)
862 self.logger.info("Success")
863 except socket.gaierror:
864 self.logger.error("redeem_ticket failed: Component Manager not accepting requests")
866 self.logger.log_exc(e.message)
870 def delete(self, opts, args):
872 slice_urn = hrn_to_urn(slice_hrn, 'slice')
873 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
876 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
877 creds.append(delegated_cred)
878 server = self.get_server_from_opts(opts)
879 return server.DeleteSliver(slice_urn, creds)
882 def start(self, opts, args):
884 slice_urn = hrn_to_urn(slice_hrn, 'slice')
885 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
888 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
889 creds.append(delegated_cred)
890 server = self.get_server_from_opts(opts)
891 return server.Start(slice_urn, creds)
894 def stop(self, opts, args):
896 slice_urn = hrn_to_urn(slice_hrn, 'slice')
897 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
900 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
901 creds.append(delegated_cred)
902 server = self.get_server_from_opts(opts)
903 return server.Stop(slice_urn, creds)
906 def reset(self, opts, args):
908 slice_urn = hrn_to_urn(slice_hrn, 'slice')
909 server = self.get_server_from_opts(opts)
910 slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
913 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
914 creds.append(delegated_cred)
915 return server.reset_slice(creds, slice_urn)
917 def renew(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)
927 return server.RenewSliver(slice_urn, creds, time)
930 def status(self, opts, args):
932 slice_urn = hrn_to_urn(slice_hrn, 'slice')
933 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
936 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
937 creds.append(delegated_cred)
938 server = self.get_server_from_opts(opts)
939 print server.SliverStatus(slice_urn, creds)
942 def shutdown(self, opts, args):
944 slice_urn = hrn_to_urn(slice_hrn, 'slice')
945 slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
948 delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
949 creds.append(delegated_cred)
950 server = self.get_server_from_opts(opts)
951 return server.Shutdown(slice_urn, creds)
955 # Main: parse arguments and dispatch to command
958 parser = self.create_parser()
959 (options, args) = parser.parse_args()
960 self.options = options
962 self.logger.setLevelFromOptVerbose(self.options.verbose)
963 if options.hashrequest:
964 self.hashrequest = True
967 self.logger.critical("No command given. Use -h for help.")
971 self.parser = self.create_cmd_parser(command)
972 (cmd_opts, cmd_args) = self.parser.parse_args(args[1:])
976 self.logger.info("Command=%s" % command)
977 if command in ("resources"):
978 self.logger.debug("resources cmd_opts %s" % cmd_opts.format)
979 elif command in ("list", "show", "remove"):
980 self.logger.debug("cmd_opts.type %s" % cmd_opts.type)
981 self.logger.debug('cmd_args %s',cmd_args)
984 self.dispatch(command, cmd_opts, cmd_args)
986 self.logger.critical ("Unknown command %s"%command)
991 if __name__ == "__main__":