+ logger.info("delegated credential for {} to {} and wrote to {}"
+ .format(message, to_hrn, filename))
+
+ ####################
+ @declare_command("", """$ less +/myslice sfi_config
+[myslice]
+backend = http://manifold.pl.sophia.inria.fr:7080
+# the HRN that myslice uses, so that we are delegating to
+delegate = ple.upmc.slicebrowser
+# platform - this is a myslice concept
+platform = ple
+# username - as of this writing (May 2013) a simple login name
+username = thierry
+
+$ sfi myslice
+ will first collect the slices that you are part of, then make sure
+ all your credentials are up-to-date (read: refresh expired ones)
+ then compute delegated credentials for user 'ple.upmc.slicebrowser'
+ and upload them all on myslice backend, using 'platform' and 'user'.
+ A password will be prompted for the upload part.
+
+$ sfi -v myslice -- or sfi -vv myslice
+ same but with more and more verbosity
+
+$ sfi m -b http://mymanifold.foo.com:7080/
+ is synonym to sfi myslice as no other command starts with an 'm'
+ and uses a custom backend for this one call
+"""
+ ) # declare_command
+ def myslice(self, options, args):
+ """ This helper is for refreshing your credentials at myslice; it will
+ * compute all the slices that you currently have credentials on
+ * refresh all your credentials (you as a user and pi, your slices)
+ * upload them to the manifold backend server
+ for last phase, sfi_config is read to look for the [myslice] section,
+ and namely the 'backend', 'delegate' and 'user' settings
+ """
+
+ ##########
+ if len(args) > 0:
+ self.print_help()
+ sys.exit(1)
+ # enable info by default
+ logger.setLevelFromOptVerbose(self.options.verbose + 1)
+ # the rough sketch goes like this
+ # (0) produce a p12 file
+ self.client_bootstrap.my_pkcs12()
+
+ # (a) rain check for sufficient config in sfi_config
+ myslice_dict = {}
+ myslice_keys = ['backend', 'delegate', 'platform', 'username']
+ for key in myslice_keys:
+ value = None
+ # oct 2013 - I'm finding myself juggling with config files
+ # so a couple of command-line options can now override config
+ if hasattr(options, key) and getattr(options, key) is not None:
+ value = getattr(options, key)
+ else:
+ full_key = "MYSLICE_" + key.upper()
+ value = getattr(self.config_instance, full_key, None)
+ if value:
+ myslice_dict[key] = value
+ else:
+ print("Unsufficient config, missing key {} in [myslice] section of sfi_config"
+ .format(key))
+ if len(myslice_dict) != len(myslice_keys):
+ sys.exit(1)
+
+ # (b) figure whether we are PI for the authority where we belong
+ logger.info("Resolving our own id {}".format(self.user))
+ my_records = self.registry().Resolve(self.user, self.my_credential_string)
+ if len(my_records) != 1:
+ print("Cannot Resolve {} -- exiting".format(self.user))
+ sys.exit(1)
+ my_record = my_records[0]
+ my_auths_all = my_record['reg-pi-authorities']
+ logger.info(
+ "Found {} authorities that we are PI for".format(len(my_auths_all)))
+ logger.debug("They are {}".format(my_auths_all))
+
+ my_auths = my_auths_all
+ if options.delegate_auths:
+ my_auths = list(set(my_auths_all).intersection(
+ set(options.delegate_auths)))
+ logger.debug(
+ "Restricted to user-provided auths {}".format(my_auths))
+
+ # (c) get the set of slices that we are in
+ my_slices_all = my_record['reg-slices']
+ logger.info(
+ "Found {} slices that we are member of".format(len(my_slices_all)))
+ logger.debug("They are: {}".format(my_slices_all))
+
+ my_slices = my_slices_all
+ # if user provided slices, deal only with these - if they are found
+ if options.delegate_slices:
+ my_slices = list(set(my_slices_all).intersection(
+ set(options.delegate_slices)))
+ logger.debug(
+ "Restricted to user-provided slices: {}".format(my_slices))
+
+ # (d) make sure we have *valid* credentials for all these
+ hrn_credentials = []
+ hrn_credentials.append((self.user, 'user', self.my_credential_string,))
+ for auth_hrn in my_auths:
+ hrn_credentials.append(
+ (auth_hrn, 'auth', self.authority_credential_string(auth_hrn),))
+ for slice_hrn in my_slices:
+ try:
+ hrn_credentials.append(
+ (slice_hrn, 'slice', self.slice_credential_string(slice_hrn),))
+ except:
+ print("WARNING: could not get slice credential for slice {}"
+ .format(slice_hrn))
+
+ # (e) check for the delegated version of these
+ # xxx todo add an option -a/-A? like for 'sfi delegate' for when we ever
+ # switch to myslice using an authority instead of a user
+ delegatee_type = 'user'
+ delegatee_hrn = myslice_dict['delegate']
+ hrn_delegated_credentials = []
+ for (hrn, htype, credential) in hrn_credentials:
+ delegated_credential = self.client_bootstrap.delegate_credential_string(
+ credential, delegatee_hrn, delegatee_type)
+ # save these so user can monitor what she's uploaded
+ filename = os.path.join(self.options.sfi_dir,
+ "{}.{}_for_{}.{}.cred"
+ .format(hrn, htype, delegatee_hrn, delegatee_type))
+ with open(filename, 'w') as f:
+ f.write(delegated_credential)
+ logger.debug("(Over)wrote {}".format(filename))
+ hrn_delegated_credentials.append(
+ (hrn, htype, delegated_credential, filename, ))
+
+ # (f) and finally upload them to manifold server
+ # xxx todo add an option so the password can be set on the command line
+ # (but *NOT* in the config file) so other apps can leverage this
+ logger.info("Uploading on backend at {}".format(
+ myslice_dict['backend']))
+ uploader = ManifoldUploader(logger=logger,
+ url=myslice_dict['backend'],
+ platform=myslice_dict['platform'],
+ username=myslice_dict['username'],
+ password=options.password)
+ uploader.prompt_all()
+ (count_all, count_success) = (0, 0)
+ for (hrn, htype, delegated_credential, filename) in hrn_delegated_credentials:
+ # inspect
+ inspect = Credential(string=delegated_credential)
+ expire_datetime = inspect.get_expiration()
+ message = "{} ({}) [exp:{}]".format(hrn, htype, expire_datetime)
+ if uploader.upload(delegated_credential, message=message):
+ count_success += 1
+ count_all += 1
+ logger.info("Successfully uploaded {}/{} credentials"
+ .format(count_success, count_all))
+
+ # at first I thought we would want to save these,
+ # like 'sfi delegate does' but on second thought
+ # it is probably not helpful as people would not
+ # need to run 'sfi delegate' at all anymore
+ if count_success != count_all:
+ sys.exit(1)
+ # xxx should analyze result
+ return 0
+
+ @declare_command("cred", "")