def handleMyProxy(self): """ check myproxy credential and delegate again it if necessary. takes no input and returns no output, bur raises exception if delegation failed """ if not self.cmdconf[ 'requiresREST']: # If the command doesn't contact the REST, we can't delegate the proxy. return if self.options.proxy: # if user passed a proxy as option we don't contact myproxy return if not self.options.proxy: # Get the DN of the task workers from the server. all_task_workers_dns = server_info(self.crabserver, subresource='delegatedn') for authorizedDNs in all_task_workers_dns['services']: self.credentialHandler.setRetrievers(authorizedDNs) self.logger.debug( "Registering user credentials on myproxy for %s" % authorizedDNs) try: (credentialName, myproxyTimeleft) = \ self.credentialHandler.createNewMyProxy(timeleftthreshold=60 * 60 * 24 * RENEW_MYPROXY_THRESHOLD) p1 = True msg1 = "Credential exists on myproxy: username: %s - validity: %s" %\ (credentialName, str(timedelta(seconds=myproxyTimeleft))) except Exception as ex: p1 = False msg1 = "Error trying to create credential:\n %s" % str(ex) if (not p1): from CRABClient.ClientExceptions import ProxyCreationException raise ProxyCreationException( "Problems delegating My-proxy.\n%s" % msg1) self.logger.debug("Result of myproxy credential check:\n %s", msg1)
def createNewVomsProxySimple(self, time_left_threshold=0): proxy_created = False proxy = self.proxy() self.logger.debug("Checking credentials") proxy_file_name = proxy.getProxyFilename() if not os.path.isfile(proxy_file_name): self.logger.debug("Proxy file %s not found" % proxy_file_name) proxy_time_left = 0 else: self.logger.debug("Found proxy file %s" % proxy_file_name) self.logger.debug("Getting proxy life time left") proxy_time_left = proxy.getTimeLeft() hours, minutes, seconds = int(proxy_time_left / 3600), int( (proxy_time_left % 3600) / 60), int( (proxy_time_left % 3600) % 60) self.logger.debug("Proxy valid for %02d:%02d:%02d hours" % (hours, minutes, seconds)) if proxy_time_left < time_left_threshold: msg = "Creating proxy for %s hours with VO role '%s' and VO group '%s'" \ % (self.defaultDelegation['proxyValidity'], self.defaultDelegation['role'], self.defaultDelegation['group']) self.logger.debug(msg) proxy.create() proxy_time_left = proxy.getTimeLeft() group, role = proxy.getUserGroupAndRoleFromProxy( proxy.getProxyFilename()) if proxy_time_left > 0 and group == self.defaultDelegation[ 'group'] and role == self.defaultDelegation['role']: self.logger.debug("Proxy created") proxy_created = True else: raise ProxyCreationException("Problems creating proxy") return proxy_created
def getUserCertEndDate(self): """ Return the number of seconds until the expiration of the user cert in .globus/usercert.pem or $X509_USER_CERT if set """ cmd = 'openssl x509 -noout -dates -in %s' % self.certLocation stdout, stderr, rc = execute_command(cmd, logger=self.logger) if rc != 0: self.logger.error(stdout + '\n' + stderr) msg = "\n".join(['Error executing %s:' % cmd, stdout, stderr]) raise ProxyCreationException(msg) out = stdout.rstrip().split('notAfter=')[1] possibleFormats = ['%b %d %H:%M:%S %Y %Z', '%b %d %H:%M:%S %Y %Z'] exptime = None for frmt in possibleFormats: try: exptime = datetime.strptime(out, frmt) except ValueError: pass # try next format if not exptime: # If we cannot decode the output in any way print # a message and fallback to voms-proxy-info command self.logger.warning( 'Cannot decode "openssl x509 -noout -in %s -dates" date format.' % self.certLocation) timeleft = 0 else: # if everything is fine then we are ready to return!! timeleft = (exptime - datetime.utcnow()).total_seconds() daystoexp = int(timeleft // (60. * 60 * 24)) return daystoexp
def create(self, username=None, retrievers=None, validity=720): """ creates a new credential in myproxy.cern.ch args: username: string: the username of the credential, usually the has of the user DN args: retrievers: string: regexp indicating list of DN's authorized to retrieve this credential args: validity: integer: how long this credential will be valid for in hours, default is 30 days example of the command we want : command : export GT_PROXY_MODE=rfc myproxy-init -d -n -s myproxy.cern.ch -x -R '/DC=ch/DC=cern/OU=computers/CN=vocms0105.cern.ch|/DC=ch/DC=cern/OU=computers/CN=crab-(preprod|prod|dev)-tw(02|01).cern.ch|/DC=ch/DC=cern/OU=computers/CN=(ddi|ddidk|mytw).cern.ch|/DC=ch/DC=cern/OU=computers/CN=stefanov(m|m2).cern.ch' -x -Z '/DC=ch/DC=cern/OU=computers/CN=vocms0105.cern.ch|/DC=ch/DC=cern/OU=computers/CN=crab-(preprod|prod|dev)-tw(02|01).cern.ch|/DC=ch/DC=cern/OU=computers/CN=(ddi|ddidk|mytw).cern.ch|/DC=ch/DC=cern/OU=computers/CN=stefanov(m|m2).cern.ch' -l 'be1f4dc5be8664cbd145bf008f5399adf42b086f' -t 168:00 -c 3600:00 """ cmd = 'export GT_PROXY_MODE=rfc ; myproxy-init -d -n -s myproxy.cern.ch' cmd += ' -C %s' % self.certLocation cmd += ' -y %s' % self.keyLocation cmd += ' -x -R \'%s\'' % retrievers cmd += ' -x -Z \'%s\'' % retrievers cmd += ' -l %s' % username cmd += ' -t 168 -c %s' % validity # validity of the retrieved proxy: 7 days = 168 hours stdout, stderr, rc = execute_command(cmd, logger=self.logger) if rc != 0: self.logger.error(stdout + '\n' + stderr) msg = "\n".join(['Error executing %s:' % cmd, stdout, stderr]) raise ProxyCreationException(msg)
def createNewVomsProxySimple(self, timeLeftThreshold = 0): proxy = self.proxy() self.logger.debug("Checking credentials") proxyFileName = proxy.getProxyFilename() if not os.path.isfile(proxyFileName): self.logger.debug("Proxy file %s not found" % (proxyFileName)) proxyTimeLeft = 0 else: self.logger.debug("Found proxy file %s" % (proxyFileName)) self.logger.debug("Getting proxy life time left") proxyTimeLeft = proxy.getTimeLeft() hours, minutes, seconds = int(proxyTimeLeft/3600), int((proxyTimeLeft%3600)/60), int((proxyTimeLeft%3600)%60) self.logger.debug("Proxy valid for %02d:%02d:%02d hours" % (hours, minutes, seconds)) ## Create a new proxy if the current one is expired or if we were instructed ## to change the proxy for a new one. proxyCreated = False if proxyTimeLeft < timeLeftThreshold: msg = "Creating new proxy for %s hours" % (self.defaultDelegation['proxyValidity']) msg += " with VO group '%s' and VO role '%s'." % (self.defaultDelegation['group'], self.defaultDelegation['role']) self.logger.debug(msg) ## Create the proxy. proxy.create() ## Check that the created proxy has the expected VO group and role (what we have ## set in the defaultDelegation dictionary). proxyTimeLeft = proxy.getTimeLeft() group, role = proxy.getUserGroupAndRoleFromProxy(proxy.getProxyFilename()) if proxyTimeLeft > 0 and group == self.defaultDelegation['group'] and role == self.defaultDelegation['role']: self.logger.debug("Proxy created.") proxyCreated = True else: raise ProxyCreationException("Problems creating proxy.") return proxyCreated
def getSubject(self): cmd = 'voms-proxy-info --identity --file %s' % self.proxyFile stdout, stderr, rc = execute_command(cmd, logger=self.logger) if rc != 0: self.logger.error(stdout + '\n' + stderr) msg = "\n".join(['Error executing %s:' % cmd, stdout, stderr]) raise ProxyCreationException(msg) return stdout.rstrip()
def getTimeLeft(self): cmd = 'voms-proxy-info --actimeleft --timeleft --file %s' % self.proxyFile stdout, stderr, rc = execute_command(cmd, logger=self.logger) if rc != 0: self.logger.error(stdout + '\n' + stderr) msg = "\n".join(['Error executing %s:' % cmd, stdout, stderr]) raise ProxyCreationException(msg) # pick the shorter between actimeleft and timeleft times = stdout.split('\n') timeLeft = min(int(times[0]), int(times[1])) return timeLeft
def createNewVomsProxy(self, timeLeftThreshold=0, proxyCreatedByCRAB=False, proxyOptsSetPlace=None): """ Handles the proxy creation: - checks if a valid proxy still exists - performs the creation if it is expired - returns a dictionary with keys: filename timelect actimeleft userdn """ proxyInfo = {} ## TODO add the change to have user-cert/key defined in the config. #proxy = self.vomsProxy() try: proxy = VomsProxy(logger=self.defaultDelegation['logger']) proxy.setVOGroupVORole(group=self.defaultDelegation['group'], role=self.defaultDelegation['role']) except ProxyCreationException as ex: self.logger.debug(ex) raise EnvironmentException('Problem with Grid environment: %s ' % str(ex)) self.logger.debug("Checking credentials") proxyFileName = proxy.getFilename() proxyInfo['filename'] = proxyFileName if not os.path.isfile(proxyFileName): self.logger.debug("Proxy file %s not found" % (proxyFileName)) proxyTimeLeft = 0 else: self.logger.debug("Found proxy file %s" % (proxyFileName)) self.logger.debug("Getting proxy life time left") proxyTimeLeft = proxy.getTimeLeft() hours, minutes, seconds = int(proxyTimeLeft / 3600), int( (proxyTimeLeft % 3600) / 60), int((proxyTimeLeft % 3600) % 60) self.logger.debug("Proxy valid for %02d:%02d:%02d hours" % (hours, minutes, seconds)) ## Create a new proxy if the current one is expired proxyInfo['timeleft'] = proxyTimeLeft if proxyTimeLeft < timeLeftThreshold or self.proxyChanged: msg = "Creating new proxy for %s hours" % ( self.defaultDelegation['proxyValidity']) self.logger.debug(msg) ## Create the proxy. proxy.create() proxyTimeLeft = proxy.getTimeLeft() proxyInfo['timeleft'] = proxyTimeLeft if proxyTimeLeft > 0: self.logger.debug("Proxy created.") else: raise ProxyCreationException("Problems creating proxy.") return proxyInfo
def getGroupAndRole(self): cmd = 'voms-proxy-info --fqan --file %s' % self.proxyFile stdout, stderr, rc = execute_command(cmd, logger=self.logger) if rc != 0: self.logger.error(stdout + '\n' + stderr) msg = "\n".join(['Error executing %s:' % cmd, stdout, stderr]) raise ProxyCreationException(msg) fqans = str(stdout) primaryFqan = fqans.split('\n')[0] attributes = primaryFqan.split('/') if len(attributes) > 4: group = attributes[2] role = attributes[3].split('=')[1] else: group = '' role = attributes[2].split('=')[1] return group, role
def create(self, timeLeftThreshold=720): # is there a proxy already ? # does it have correct group and role ? # is it valid long enough ? # all OK, do nothing # need a new proxy cmd = 'voms-proxy-init --rfc' cmd += ' --cert %s' % self.certLocation cmd += ' --key %s' % self.keyLocation cmd += ' --out %s' % self.proxyFile cmd += ' --valid %s' % self.desiredValidity vomsString = 'cms:/cms' if self.group: vomsString += '/%s' % self.group if self.role and self.role != 'NULL': vomsString += '/Role=%s' % self.role cmd += ' --voms %s' % vomsString stdout, stderr, rc = execute_command(cmd, logger=self.logger, redirect=False) if rc != 0: self.logger.error(stdout + '\n' + stderr) msg = "\n".join(['Error executing %s:' % cmd, stdout, stderr]) raise ProxyCreationException(msg)
def createNewMyProxy(self, timeleftthreshold=0, nokey=False): """ Handles the MyProxy creation Let the following variables be timeleftthreshold: the proxy in myproxy should be delegated for at least this time (14 days) myproxytimeleft: current validity of your proxy in myproxy usercertDaysLeft: the number of days left before your user certificate expire myproxyDesiredValidity: delegate the proxy in myproxy for that time (30 days) If we need to renew the proxy in myproxy because its atributes has changed or because it is valid for less time than timeleftthreshold then we do it. Before doing that, we check when the user certificate is expiring. If it's within the timeleftthreshold (myproxytimeleft < timeleftthreshold) we delegate the proxy just for the time we need (checking first if we did not already do it since at some point usercertDaysLeft ~= myproxytimeleft and we don't need to delegate it at every command even though myproxytimeleft < timeleftthreshold). Note that a warning message is printed at every command it usercertDaysLeft < timeleftthreshold """ myproxy = Proxy(self.defaultDelegation) myproxy.userDN = myproxy.getSubjectFromCert(self.certLocation) myproxytimeleft = 0 self.logger.debug("Getting myproxy life time left for %s" % self.defaultDelegation["myProxySvr"]) # return an integer that indicates the number of seconds to the expiration of the proxy in myproxy myproxytimeleft = myproxy.getMyProxyTimeLeft(serverRenewer=True, nokey=nokey) self.logger.debug("Myproxy is valid: %i" % myproxytimeleft) trustRetrListChanged = myproxy.trustedRetrievers != self.defaultDelegation[ 'serverDN'] #list on the REST and on myproxy are different if myproxytimeleft < timeleftthreshold or self.proxyChanged or trustRetrListChanged: # checking the enddate of the user certificate usercertDaysLeft = myproxy.getUserCertEnddate() if usercertDaysLeft == 0: msg = "%sYOUR USER CERTIFICATE IS EXPIRED (OR WILL EXPIRE TODAY). YOU CANNOT USE THE CRAB3 CLIENT. PLEASE REQUEST A NEW CERTIFICATE HERE https://gridca.cern.ch/gridca/ AND SEE https://ca.cern.ch/ca/Help/?kbid=024010%s"\ % (colors.RED, colors.NORMAL) raise ProxyCreationException(msg) #if the certificate is going to expire print a warning. This is going to bre printed at every command if #the myproxytimeleft is inferior to the timeleftthreshold if usercertDaysLeft < self.myproxyDesiredValidity: self.logger.info("%sYour user certificate is going to expire in %s days. https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookStartingGrid#ObtainingCert %s"\ % (colors.RED, usercertDaysLeft, colors.NORMAL) ) #check if usercertDaysLeft ~= myproxytimeleft which means we already delegated the proxy for as long as we could if abs( usercertDaysLeft * 60 * 60 * 24 - myproxytimeleft ) < 60 * 60 * 24 and not trustRetrListChanged: #less than one day between usercertDaysLeft and myproxytimeleft return #adjust the myproxy delegation time accordingly to the user cert validity self.logger.info("%sDelegating your proxy for %s days instead of %s %s"\ % (colors.RED, usercertDaysLeft, self.myproxyDesiredValidity, colors.NORMAL) ) myproxy.myproxyValidity = "%i:00" % (usercertDaysLeft * 24) # creating the proxy self.logger.debug("Delegating a myproxy for %s hours" % myproxy.myproxyValidity) try: myproxy.delegate(serverRenewer=True, nokey=nokey) myproxytimeleft = myproxy.getMyProxyTimeLeft( serverRenewer=True, nokey=nokey) if myproxytimeleft <= 0: raise ProxyCreationException("It seems your proxy has not been delegated to myproxy. Please check the logfile for the exact error "+\ "(it might simply you typed a wrong password)") else: self.logger.debug("My-proxy delegated.") except Exception as ex: msg = ex._message if hasattr(ex, '_message') else str(ex) raise ProxyCreationException( "Problems delegating My-proxy. %s" % msg)
def createNewVomsProxy(self, timeLeftThreshold=0, doProxyGroupRoleCheck=False, proxyCreatedByCRAB=False, proxyOptsSetPlace=None): """ Handles the proxy creation: - checks if a valid proxy still exists - performs the creation if it is expired """ ## TODO add the change to have user-cert/key defined in the config. proxy = self.proxy() ## Not sure if proxy.userDN is used. We don't have this in createNewVomsProxySimple... proxy.userDN = proxy.getSubjectFromCert(self.certLocation) self.logger.debug("Checking credentials") proxyFileName = proxy.getProxyFilename() if not os.path.isfile(proxyFileName): self.logger.debug("Proxy file %s not found" % (proxyFileName)) proxyTimeLeft = 0 else: self.logger.debug("Found proxy file %s" % (proxyFileName)) self.logger.debug("Getting proxy life time left") proxyTimeLeft = proxy.getTimeLeft() hours, minutes, seconds = int(proxyTimeLeft / 3600), int( (proxyTimeLeft % 3600) / 60), int((proxyTimeLeft % 3600) % 60) self.logger.debug("Proxy valid for %02d:%02d:%02d hours" % (hours, minutes, seconds)) if doProxyGroupRoleCheck: ## Get the VO group and role in the proxy. group, role = proxy.getUserGroupAndRoleFromProxy(proxyFileName) proxyAttrs = {'group': group, 'role': role} ## Make sure proxyOptsSetPlace is a dictionary and has the expected keys. if not isinstance(proxyOptsSetPlace, dict): proxyOptsSetPlace = {} proxyOptsSetPlace.setdefault('set_in', {}) proxyOptsSetPlace['set_in'].setdefault('group', "") proxyOptsSetPlace['set_in'].setdefault('role', "") proxyOptsSetPlace.setdefault('for_set_use', "") ## If the proxy (not created by CRAB) is not expired, ... if (proxyTimeLeft > timeLeftThreshold) and not proxyCreatedByCRAB and \ (self.defaultDelegation['group'] != None and self.defaultDelegation['role'] != None): ## ... we check if the VO group and VO role in the proxy are the same as the ## ones in defaultDelegation (which were either specified by the user in the ## CRAB configuration file or in the command options, or were taken from the ## request cache, or otherwise were given default values). if (group != self.defaultDelegation['group'] or role != self.defaultDelegation['role']): ## If they are not the same, force the user to either create a new proxy with ## the same VO group and VO role as in defaultDelegation, or to change the VO ## group/role in the configuration file (or in the command options, whatever ## corresponds). msgadd1, msgadd2, previous = [], [], "" for attr in ['group', 'role']: msgadd1.append("VO %s '%s'" % (attr, proxyAttrs[attr])) if proxyAttrs[attr] != self.defaultDelegation[attr]: if proxyOptsSetPlace['set_in'][attr] == previous: if proxyOptsSetPlace['set_in'][attr] in [ "config", "cmdopts", "cache" ]: msgadd2.append( "VO %s '%s'" % (attr, self.defaultDelegation[attr])) else: msgadd2.append("VO %s '%s'" % (attr, proxyAttrs[attr])) else: previous = proxyOptsSetPlace['set_in'][attr] if proxyOptsSetPlace['set_in'][ attr] == "config": msgadd2.append("in the CRAB configuration file you have specified to use " + \ "VO %s '%s'" % (attr, self.defaultDelegation[attr])) elif proxyOptsSetPlace['set_in'][ attr] == "cmdopts": msgadd2.append("in the crab command options you have specified to use " + \ "VO %s '%s'" % (attr, self.defaultDelegation[attr])) elif proxyOptsSetPlace['set_in'][ attr] == "cache": msgadd2.append("in the .requestcache file, inside the given CRAB project directory, it says that this task used " + \ "VO %s '%s'" % (attr, self.defaultDelegation[attr])) else: setmsg = "" if proxyOptsSetPlace[ 'for_set_use'] == "config": setmsg = "(in the CRAB configuration file) " elif proxyOptsSetPlace[ 'for_set_use'] == "cmdopts": setmsg = "(in the crab command options) " msgadd2.append("you have not explicitely specified %sto use " % (setmsg) + \ "VO %s '%s'" % (attr, proxyAttrs[attr])) msg = "Proxy file %s exists with %s, but %s." % ( proxyFileName, " and ".join(msgadd1), " and ".join(msgadd2)) self.logger.info(msg) while True: msg = "Do you want to overwrite the proxy (Y/N)?" self.logger.info(msg) answer = raw_input() if answer in ['y', 'Y', 'n', 'N']: msg = "Answer was: %s" % (answer) self.logger.debug(msg) break if answer.upper() == 'Y': self.proxyChanged = True if answer.upper() == 'N': if proxyOptsSetPlace['for_set_use'] == "config": msg = "Then please modify the CRAB configuration file" msg += " in order to match the existing proxy." elif proxyOptsSetPlace['for_set_use'] == "cmdopts": msg = "Then please specify the crab command options --voGroup and/or --voRole" msg += " in order to match the existing proxy." msg += "\nNote: If the options --voGroup/--voRole are not specified," msg += " the defaults ''/'NULL' are assumed." else: ## Should never get into this branch of the if, but just in case. msg = "Then please modify the VO group and/or VO role in the place" msg += " you have specified them in order to match the existing proxy." self.logger.info(msg) raise StopExecution ## Create a new proxy if the current one is expired or if we were instructed ## to change the proxy for a new one. if proxyTimeLeft < timeLeftThreshold or self.proxyChanged: msg = "Creating new proxy for %s hours" % ( self.defaultDelegation['proxyValidity']) msg += " with VO group '%s' and VO role '%s'." % ( self.defaultDelegation['group'], self.defaultDelegation['role']) self.logger.debug(msg) ## Create the proxy. proxy.create() ## Check that the created proxy has the expected VO group and role (what ## we have set in the defaultDelegation dictionary). proxyTimeLeft = proxy.getTimeLeft() group, role = proxy.getUserGroupAndRoleFromProxy( proxy.getProxyFilename()) if proxyTimeLeft > 0 and group == self.defaultDelegation[ 'group'] and role == self.defaultDelegation['role']: self.logger.debug("Proxy created.") else: raise ProxyCreationException("Problems creating proxy.") return proxy.getProxyFilename()
def createNewVomsProxy(self, time_left_threshold=0, proxy_created_by_crab=False): """ Handles the proxy creation: - checks if a valid proxy still exists - performs the creation if it is expired """ ## TODO add the change to have user-cert/key defined in the config. proxy = self.proxy() proxy.userDN = proxy.getSubjectFromCert(self.certLocation) self.logger.debug("Checking credentials") proxy_file_name = proxy.getProxyFilename() if not os.path.isfile(proxy_file_name): self.logger.debug("Proxy file %s not found" % proxy_file_name) proxy_time_left = 0 else: self.logger.debug("Found proxy file %s" % proxy_file_name) self.logger.debug("Getting proxy life time left") proxy_time_left = proxy.getTimeLeft() hours, minutes, seconds = int(proxy_time_left / 3600), int( (proxy_time_left % 3600) / 60), int( (proxy_time_left % 3600) % 60) self.logger.debug("Proxy valid for %02d:%02d:%02d hours" % (hours, minutes, seconds)) ## If the proxy is not expired, we check if role and/or group are changed. if proxy_time_left > time_left_threshold and self.defaultDelegation[ 'role'] != None and self.defaultDelegation[ 'group'] != None and not proxy_created_by_crab: group, role = proxy.getUserGroupAndRoleFromProxy(proxy_file_name) if group != self.defaultDelegation[ 'group'] or role != self.defaultDelegation['role']: ## Ask the user what he wants to do. Keep it or leave it? while True: self.logger.info(("Proxy file %s exists with VO group = '%s' and VO role = '%s', but you have specified to use VO group = '%s' and VO role = '%s'." + "\nDo you want to overwrite the proxy (Y/N)?") \ % (proxy_file_name, group, role, self.defaultDelegation['group'], self.defaultDelegation['role'])) res = raw_input() if res in ['y', 'Y', 'n', 'N']: break ## If he wants to overwrite the proxy then we do it, otherwise we exit asking to modify the config. if res.upper() == 'Y': self.proxyChanged = True else: raise ProxyCreationException( "Please modify the User.voRole and User.voGroup parameters in your configuration file to match the existing proxy" ) ## If the proxy is expired, or we changed role and/or group, we need to create a new proxy. if proxy_time_left < time_left_threshold or self.proxyChanged: ## Create the proxy. self.logger.debug("Creating new proxy for %s hours" % self.defaultDelegation['proxyValidity']) proxy.create() proxy_time_left = proxy.getTimeLeft() group, role = proxy.getUserGroupAndRoleFromProxy( proxy.getProxyFilename()) if proxy_time_left > 0 and group == self.defaultDelegation[ 'group'] and role == self.defaultDelegation['role']: self.logger.debug("Proxy created.") else: raise ProxyCreationException("Problems creating proxy.") return proxy.userDN, proxy.getProxyFilename()
def createNewMyProxy2(self, timeleftthreshold=0, nokey=False): """ Handles the MyProxy creation. In this version the credential name will be simply <username>_CRAB like e.g. belforte_CRAB where username is the CERN username Let the following variables be timeleftthreshold: the proxy in myproxy should be delegated for at least this time (14 days) myproxytimeleft: current validity of your proxy in myproxy usercertDaysLeft: the number of days left before your user certificate expire myproxyDesiredValidity: delegate the proxy in myproxy for that time (30 days) If we need to renew the proxy in myproxy because its atributes has changed or because it is valid for less time than timeleftthreshold then we do it. Before doing that, we check when the user certificate is expiring. If it's within the timeleftthreshold (myproxytimeleft < timeleftthreshold) we delegate the proxy just for the time we need (checking first if we did not already do it since at some point usercertDaysLeft ~= myproxytimeleft and we don't need to delegate it at every command even though myproxytimeleft < timeleftthreshold). Note that a warning message is printed at every command it usercertDaysLeft < timeleftthreshold :returns a tupla with info in the credential in myprosxy: (credentialName, myproxytimeleft) credentialName : username to use in myproxy -l username myproxytimeleft: validity of the credential in seconds """ defaultDelegation = self.defaultDelegation defaultDelegation['myproxyAccount'] = None from CRABClient.UserUtilities import getUsername username = getUsername(proxyFile=self.proxyInfo['filename'], logger=self.logger) credentialName = username + '_CRAB' defaultDelegation['userName'] = credentialName myproxy = Proxy(defaultDelegation) #userDNFromCert = myproxy.getSubjectFromCert(self.certLocation) #if userDNFromCert: # myproxy.userDN = userDNFromCert myproxytimeleft = 0 self.logger.debug("Getting myproxy life time left for %s" % self.defaultDelegation["myProxySvr"]) # return an integer that indicates the number of seconds to the expiration of the proxy in myproxy # Also catch the exception in case WMCore encounters a problem with the proxy itself (one such case was #4532) try: myproxytimeleft = myproxy.getMyProxyTimeLeft(serverRenewer=True, nokey=nokey) except CredentialException as ex: msg = "WMCore could not computer valid time for credential %s .\n Error detail: " % credentialName msg += "%s" % str(ex._message) msg += "\nTry to remove old myproxy credentials as per https://twiki.cern.ch/twiki/bin/view/CMSPublic/CRAB3FAQ#crab_command_fails_with_Impossib" self.logger.error(msg) raise ProxyCreationException("no valid credential for %s" % credentialName) except Exception as ex: logging.exception( "Problems calculating proxy lifetime, logging stack trace and raising ProxyCreationException" ) # WMException may contain the _message attribute. Otherwise, take the exception as a string. msg = ex._message if hasattr(ex, "_message") else str(ex) # pylint: disable=protected-access, no-member raise ProxyCreationException( "Problems calculating the time left until the expiration of the proxy." + " Please reset your environment or contact [email protected] if the problem persists.\n%s" % msg) self.logger.debug("Myproxy is valid: %i", myproxytimeleft) trustRetrListChanged = myproxy.trustedRetrievers != self.defaultDelegation[ 'serverDN'] #list on the REST and on myproxy are different if myproxytimeleft < timeleftthreshold or self.proxyChanged or trustRetrListChanged: # checking the enddate of the user certificate usercertDaysLeft = myproxy.getUserCertEnddate() if usercertDaysLeft == 0: msg = "%sYOUR USER CERTIFICATE IS EXPIRED (OR WILL EXPIRE TODAY)." % colors.RED msg += " YOU CANNOT USE THE CRAB3 CLIENT." msg += " PLEASE REQUEST A NEW CERTIFICATE HERE https://gridca.cern.ch/gridca/" msg += " AND SEE https://ca.cern.ch/ca/Help/?kbid=024010%s" % colors.NORMAL raise ProxyCreationException(msg) #if the certificate is going to expire print a warning. This is going to bre printed at every command if #the myproxytimeleft is inferior to the timeleftthreshold if usercertDaysLeft < self.myproxyDesiredValidity: msg = "%sYour user certificate is going to expire in %s days." % ( colors.RED, usercertDaysLeft) msg += " See: https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookStartingGrid#ObtainingCert %s" % colors.NORMAL self.logger.info(msg) #check if usercertDaysLeft ~= myproxytimeleft which means we already delegated the proxy for as long as we could if abs( usercertDaysLeft * 60 * 60 * 24 - myproxytimeleft ) < 60 * 60 * 24 and not trustRetrListChanged: #less than one day between usercertDaysLeft and myproxytimeleft return (credentialName, myproxytimeleft) #adjust the myproxy delegation time accordingly to the user cert validity self.logger.info( "%sDelegating your proxy for %s days instead of %s %s", colors.RED, usercertDaysLeft, self.myproxyDesiredValidity, colors.NORMAL) myproxy.myproxyValidity = "%i:00" % (usercertDaysLeft * 24) # creating the proxy self.logger.debug("Delegating a myproxy for %s hours", myproxy.myproxyValidity) try: myproxy.delegate(serverRenewer=True, nokey=nokey) myproxytimeleft = myproxy.getMyProxyTimeLeft( serverRenewer=True, nokey=nokey) if myproxytimeleft <= 0: raise ProxyCreationException("It seems your proxy has not been delegated to myproxy. Please check the logfile for the exact error "+\ "(it might simply you typed a wrong password)") else: self.logger.debug("My-proxy delegated.") except Exception as ex: msg = ex._message if hasattr(ex, '_message') else str(ex) # pylint: disable=protected-access, no-member raise ProxyCreationException( "Problems delegating My-proxy. %s" % msg) return (credentialName, myproxytimeleft)
def handleProxy(self, proxyOptsSetPlace): """ Init the user proxy, and delegate it if necessary. """ if not self.options.proxy: if self.cmdconf['initializeProxy']: self.proxy.setVOGroupVORole(self.voGroup, self.voRole) self.proxy.proxyInfo = self.proxy.createNewVomsProxy(timeLeftThreshold=720, \ doProxyGroupRoleCheck=self.cmdconf['doProxyGroupRoleCheck'], \ proxyCreatedByCRAB=self.proxyCreated, \ proxyOptsSetPlace=proxyOptsSetPlace) self.proxyfilename = self.proxy.proxyInfo['filename'] if self.cmdconf[ 'requiresREST']: ## If the command doesn't contact the REST, we can't delegate the proxy. baseurl = getUrl(self.instance, resource='info') ## Get the DN of the task workers from the server. all_task_workers_dns = server_info( subresource='delegatedn', serverurl=self.serverurl, proxyfilename=self.proxyfilename, baseurl=baseurl, logger=self.logger) for serverdn in all_task_workers_dns['services']: self.proxy.setServerDN(serverdn) self.proxy.setMyProxyServer('myproxy.cern.ch') self.logger.debug( "Registering user credentials for server %s" % serverdn) try: (credentialName, myproxyTimeleft) = self.proxy.createNewMyProxy( timeleftthreshold=60 * 60 * 24 * RENEW_MYPROXY_THRESHOLD, nokey=True) p1 = True msg1 = "Credential exists on myproxy: username: %s - validity: %s" %\ (credentialName, str(timedelta(seconds=myproxyTimeleft))) except Exception as ex: p1 = False msg1 = "Error trying to create credential:\n %s" % str( ex) try: (credentialName, myproxyTimeleft) = self.proxy.createNewMyProxy2( timeleftthreshold=60 * 60 * 24 * RENEW_MYPROXY_THRESHOLD, nokey=True) p2 = True msg2 = "Credential exists on myproxy: username: %s - validity: %s" %\ (credentialName, str(timedelta(seconds=myproxyTimeleft))) except Exception as ex: p2 = False msg2 = "Error trying to create credential:\n %s" % str( ex) if (not p1) and (not p2): from CRABClient.ClientExceptions import ProxyCreationException raise ProxyCreationException( "Problems delegating My-proxy.\n%s\n%s" % (msg1, msg2)) self.logger.debug( "Result of myproxy credential check:\n %s\n %s", msg1, msg2) else: self.proxyfilename = self.options.proxy os.environ['X509_USER_PROXY'] = self.options.proxy self.logger.debug('Skipping proxy creation')
def createNewMyProxy(self, timeleftthreshold=0): """ Handles the MyProxy creation Let the following variables be timeleftthreshold: the proxy in myproxy should be delegated for at least this time (14 days) myproxytimeleft: current validity of your proxy in myproxy usercertDaysLeft: the number of days left before your user certificate expire myproxyDesiredValidity: delegate the proxy in myproxy for that time (30 days) If we need to renew the proxy in myproxy because its atributes has changed or because it is valid for less time than timeleftthreshold then we do it. Before doing that, we check when the user certificate is expiring. If it's within the timeleftthreshold (myproxytimeleft < timeleftthreshold) we delegate the proxy just for the time we need (checking first if we did not already do it since at some point usercertDaysLeft ~= myproxytimeleft and we don't need to delegate it at every command even though myproxytimeleft < timeleftthreshold). Note that a warning message is printed at every command it usercertDaysLeft < timeleftthreshold :returns a tupla with info in the credential in myprosxy: (credentialName, myproxytimeleft) credentialName : username to use in myproxy -l username myproxytimeleft: validity of the credential in seconds """ # create a WMCore/Proxy object to get DN proxy = VomsProxy(logger=self.defaultDelegation['logger']) userDNFromProxy = proxy.getSubject() # now use that to compute the credential name to pass in input to a new Proxy object credentialName = sha1(userDNFromProxy.encode('utf-8')).hexdigest() myproxy = MyProxy(logger=self.defaultDelegation['logger']) myproxyDesiredValidity = self.defaultDelegation['myproxyValidity'] myproxytimeleft = 0 self.logger.debug("Getting myproxy life time left for %s" % credentialName) # return an integer that indicates the number of seconds to the expiration of the proxy in myproxy # Also catch the exception in case WMCore encounters a problem with the proxy itself (one such case was #4532) try: myproxytimeleft, trustedRetrievers = myproxy.getInfo( username=credentialName) except Exception as ex: logging.exception( "Problems calculating proxy lifetime, logging stack trace and raising ProxyCreationException" ) # WMException may contain the _message attribute. Otherwise, take the exception as a string. msg = ex._message if hasattr(ex, "_message") else str(ex) # pylint: disable=protected-access, no-member raise ProxyCreationException( "Problems calculating the time left until the expiration of the proxy.\n" + " Please reset your environment or contact [email protected] if the problem persists.\n%s" % msg) self.logger.debug("Myproxy is valid: %i" % myproxytimeleft) trustRetrListChanged = trustedRetrievers != self.defaultDelegation[ 'retrievers'] #list on the REST and on myproxy are different if myproxytimeleft < timeleftthreshold or trustRetrListChanged: # checking the enddate of the user certificate usercertDaysLeft = myproxy.getUserCertEndDate() if usercertDaysLeft == 0: msg = "%sYOUR USER CERTIFICATE IS EXPIRED (OR WILL EXPIRE TODAY)." % colors.RED msg += " YOU CANNOT USE THE CRAB3 CLIENT." msg += " PLEASE REQUEST A NEW CERTIFICATE HERE https://gridca.cern.ch/gridca/" msg += " AND SEE https://ca.cern.ch/ca/Help/?kbid=024010%s" % colors.NORMAL raise ProxyCreationException(msg) #if the certificate is going to expire print a warning. This is going to bre printed at every command if #the myproxytimeleft is inferior to the timeleftthreshold if usercertDaysLeft < self.myproxyDesiredValidity: msg = "%sYour user certificate is going to expire in %s days." % ( colors.RED, usercertDaysLeft) msg += " See: https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookStartingGrid#ObtainingCert %s" % colors.NORMAL self.logger.info(msg) #check if usercertDaysLeft ~= myproxytimeleft which means we already delegated the proxy for as long as we could if abs( usercertDaysLeft * 60 * 60 * 24 - myproxytimeleft ) < 60 * 60 * 24 and not trustRetrListChanged: #less than one day between usercertDaysLeft and myproxytimeleft return (credentialName, myproxytimeleft) #adjust the myproxy delegation time accordingly to the user cert validity self.logger.info( "%sDelegating your proxy for %s days instead of %s %s", colors.RED, usercertDaysLeft, self.myproxyDesiredValidity, colors.NORMAL) myproxyDesiredValidity = "%i:00" % (usercertDaysLeft * 24) # creating the proxy self.logger.debug("Delegating a myproxy for %s hours", myproxyDesiredValidity) try: myproxy.create(username=credentialName, retrievers=self.defaultDelegation['retrievers'], validity=myproxyDesiredValidity) myproxytimeleft, _ = myproxy.getInfo(username=credentialName) if myproxytimeleft <= 0: raise ProxyCreationException("It seems your proxy has not been delegated to myproxy. Please check the logfile for the exact error "+\ "(Maybe you simply typed a wrong password)") self.logger.debug("My-proxy delegated.") except Exception as ex: msg = ex._message if hasattr(ex, '_message') else str(ex) # pylint: disable=protected-access, no-member raise ProxyCreationException( "Problems delegating My-proxy. %s" % msg) return (credentialName, myproxytimeleft)