Ejemplo n.º 1
0
 def getData(self):
     DN = self.__disetConfig.getDN()
     group = self.__disetConfig.getGroup()
     credDict = self.__getCredDict(DN, group)
     data = {
         'menu':
         self.__getGroupMenu(credDict, group),
         'user':
         credDict,
         'validGroups': [],
         'setup':
         self.__disetConfig.getSetup()
         or gConfig.getValue("/DIRAC/Setup", ""),
         'validSetups':
         gConfig.getSections("/DIRAC/Setups")['Value'],
         'extensions':
         self.__extensions,
         'extVersion':
         self.getExtJSVersion()
     }
     if 'properties' in credDict:
         credDict.pop('properties')
     #Add valid groups if known
     if DN:
         result = Registry.getGroupsForDN(DN)
         if result['OK']:
             data['validGroups'] = result['Value']
     #Calculate baseURL
     baseURL = [
         Conf.rootURL().strip("/"),
         "s:%s" % data['setup'],
         "g:%s" % credDict.get('group', 'anon')
     ]
     data['baseURL'] = "/%s" % "/".join(baseURL)
     return data
Ejemplo n.º 2
0
    def completeDelegation(self, requestId, userDN, delegatedPem):
        """
    Complete a delegation and store it in the db
    """
        retVal = self.retrieveDelegationRequest(requestId, userDN)
        if not retVal['OK']:
            return retVal
        request = retVal['Value']
        chain = X509Chain(keyObj=request.getPKey())
        retVal = chain.loadChainFromString(delegatedPem)
        if not retVal['OK']:
            return retVal
        retVal = chain.isValidProxy(ignoreDefault=True)
        noGroupFlag = False
        if not retVal['OK']:
            if retVal['Message'] == "Proxy does not have an explicit group":
                noGroupFlag = True
            else:
                return retVal

        result = chain.isVOMS()
        if result['OK'] and result['Value']:
            return S_ERROR(
                "Proxies with VOMS extensions are not allowed to be uploaded")

        retVal = request.checkChain(chain)
        if not retVal['OK']:
            return retVal
        if not retVal['Value']:
            return S_ERROR("Received chain does not match request: %s" %
                           retVal['Message'])

        retVal = chain.getDIRACGroup()
        if not retVal['OK']:
            return retVal
        userGroup = retVal['Value']
        if not userGroup:
            userGroup = Registry.getDefaultUserGroup()

        retVal = Registry.getGroupsForDN(userDN)
        if not retVal['OK']:
            return retVal
        if not userGroup in retVal['Value']:
            return S_ERROR("%s group is not valid for %s" %
                           (userGroup, userDN))

        # For proxies without embedded DIRAC group only one default is allowed
        # Cleaning all the proxies for this DN if any before uploading the new one.
        if noGroupFlag:
            retVal = self.deleteProxy(userDN)
            if not retVal['OK']:
                return retVal

        retVal = self.storeProxy(userDN, userGroup, chain)
        if not retVal['OK']:
            return retVal
        retVal = self.deleteRequest(requestId)
        if not retVal['OK']:
            return retVal
        return S_OK()
Ejemplo n.º 3
0
  def getGroupsToUpload( self ):
    uploadGroups = []

    if self.__piParams.uploadProxy or Registry.getGroupOption( self.__piParams.diracGroup, "AutoUploadProxy", False ):
      uploadGroups.append( self.__piParams.diracGroup )

    if not self.__piParams.uploadPilot:
      if not Registry.getGroupOption( self.__piParams.diracGroup, "AutoUploadPilotProxy", False ):
        return uploadGroups

    issuerCert = self.getIssuerCert()
    resultUserDN = issuerCert.getSubjectDN() #pylint: disable=no-member
    if not resultUserDN['OK']:
      return resultUserDN
    userDN = resultUserDN[ 'Value' ]

    resultGroups = Registry.getGroupsForDN( userDN )
    if not resultGroups[ 'OK' ]:
      gLogger.error( "No groups defined for DN %s" % userDN )
      return []
    availableGroups = resultGroups[ 'Value' ]

    for group in availableGroups:
      groupProps = Registry.getPropertiesForGroup( group )
      if Properties.PILOT in groupProps or Properties.GENERIC_PILOT in groupProps:
        uploadGroups.append( group )
    return uploadGroups
Ejemplo n.º 4
0
    def getGroupsToUpload(self):
        uploadGroups = []

        if self.__piParams.uploadProxy or Registry.getGroupOption(
                self.__piParams.diracGroup, "AutoUploadProxy", False):
            uploadGroups.append(self.__piParams.diracGroup)

        if not self.__piParams.uploadPilot:
            if not Registry.getGroupOption(self.__piParams.diracGroup,
                                           "AutoUploadPilotProxy", False):
                return uploadGroups

        issuerCert = self.getIssuerCert()
        userDN = issuerCert.getSubjectDN()['Value']

        result = Registry.getGroupsForDN(userDN)
        if not result['OK']:
            gLogger.error("No groups defined for DN %s" % userDN)
            return []
        availableGroups = result['Value']

        pilotGroups = []
        for group in availableGroups:
            groupProps = Registry.getPropertiesForGroup(group)
            if Properties.PILOT in groupProps or Properties.GENERIC_PILOT in groupProps:
                uploadGroups.append(group)
        return uploadGroups
Ejemplo n.º 5
0
    def __getPUSProxy(self,
                      userDN,
                      userGroup,
                      requiredLifetime,
                      requestedVOMSAttr=None):

        result = Registry.getGroupsForDN(userDN)
        if not result['OK']:
            return result

        validGroups = result['Value']
        if not userGroup in validGroups:
            return S_ERROR('Invalid group %s for user' % userGroup)

        voName = Registry.getVOForGroup(userGroup)
        if not voName:
            return S_ERROR('Can not determine VO for group %s' % userGroup)

        retVal = self.__getVOMSAttribute(userGroup, requestedVOMSAttr)
        if not retVal['OK']:
            return retVal
        vomsAttribute = retVal['Value']['attribute']
        vomsVO = retVal['Value']['VOMSVO']

        puspServiceURL = Registry.getVOOption(voName, 'PUSPServiceURL')
        if not puspServiceURL:
            return S_ERROR('Can not determine PUSP service URL for VO %s' %
                           voName)

        user = userDN.split(":")[-1]

        puspURL = "%s?voms=%s:%s&proxy-renewal=false&disable-voms-proxy=false" \
                  "&rfc-proxy=true&cn-label=user:%s" % ( puspServiceURL, vomsVO, vomsAttribute, user )

        try:
            proxy = urllib.urlopen(puspURL).read()
        except Exception as e:
            return S_ERROR('Failed to get proxy from the PUSP server')

        chain = X509Chain()
        chain.loadChainFromString(proxy)
        chain.loadKeyFromString(proxy)

        result = chain.getCredentials()
        if not result['OK']:
            return S_ERROR('Failed to get a valid PUSP proxy')
        credDict = result['Value']
        if credDict['identity'] != userDN:
            return S_ERROR(
                'Requested DN does not match the obtained one in the PUSP proxy'
            )
        timeLeft = credDict['secondsLeft']

        result = chain.generateProxyToString(lifeTime=timeLeft,
                                             diracGroup=userGroup)
        if not result['OK']:
            return result
        proxyString = result['Value']
        return S_OK((proxyString, timeLeft))
Ejemplo n.º 6
0
  def completeDelegation( self, requestId, userDN, delegatedPem ):
    """
    Complete a delegation and store it in the db
    """
    retVal = self.retrieveDelegationRequest( requestId, userDN )
    if not retVal[ 'OK' ]:
      return retVal
    request = retVal[ 'Value' ]
    chain = X509Chain( keyObj = request.getPKey() )
    retVal = chain.loadChainFromString( delegatedPem )
    if not retVal[ 'OK' ]:
      return retVal
    retVal = chain.isValidProxy( ignoreDefault = True )
    noGroupFlag = False
    if not retVal[ 'OK' ]:
      if DErrno.cmpError( retVal, DErrno.ENOGROUP ):
        noGroupFlag = True
      else:
        return retVal

    result = chain.isVOMS()
    if result[ 'OK' ] and result[ 'Value' ]:
      return S_ERROR( "Proxies with VOMS extensions are not allowed to be uploaded" )

    retVal = request.checkChain( chain )
    if not retVal[ 'OK' ]:
      return retVal
    if not retVal[ 'Value' ]:
      return S_ERROR( "Received chain does not match request: %s" % retVal[ 'Message' ] )

    retVal = chain.getDIRACGroup()
    if not retVal[ 'OK' ]:
      return retVal
    userGroup = retVal[ 'Value' ]
    if not userGroup:
      userGroup = Registry.getDefaultUserGroup()

    retVal = Registry.getGroupsForDN( userDN )
    if not retVal[ 'OK' ]:
      return retVal
    if not userGroup in retVal[ 'Value' ]:
      return S_ERROR( "%s group is not valid for %s" % ( userGroup, userDN ) )

    # For proxies without embedded DIRAC group only one default is allowed
    # Cleaning all the proxies for this DN if any before uploading the new one.
    if noGroupFlag:
      retVal = self.deleteProxy( userDN )
      if not retVal[ 'OK' ]:
        return retVal

    retVal = self.storeProxy( userDN, userGroup, chain )
    if not retVal[ 'OK' ]:
      return retVal
    retVal = self.deleteRequest( requestId )
    if not retVal[ 'OK' ]:
      return retVal
    return S_OK()
Ejemplo n.º 7
0
 def __getGroups( self, DN = False ):
   if not DN:
     credDict = self.getClientCredentials()
     if not credDict:
       return WErr( 401, "No certificate received to issue a token" )
     DN = credDict[ 'subject' ]
     if not credDict[ 'validDN' ]:
      return WErr( 401, "Unknown DN %s" % DN )
   result = Registry.getGroupsForDN( DN )
   if not result[ 'OK' ]:
     return WErr( 500, result[ 'Message' ] )
   return WOK( { 'groups' : result[ 'Value' ] } )
Ejemplo n.º 8
0
  def __getPUSProxy( self, userDN, userGroup, requiredLifetime, requestedVOMSAttr = None ):

    result = Registry.getGroupsForDN( userDN )
    if not result['OK']:
      return result

    validGroups = result['Value']
    if not userGroup in validGroups:
      return S_ERROR( 'Invalid group %s for user' % userGroup )

    voName = Registry.getVOForGroup( userGroup )
    if not voName:
      return S_ERROR( 'Can not determine VO for group %s' % userGroup )

    retVal = self.__getVOMSAttribute( userGroup, requestedVOMSAttr )
    if not retVal[ 'OK' ]:
      return retVal
    vomsAttribute = retVal[ 'Value' ][ 'attribute' ]
    vomsVO = retVal[ 'Value' ][ 'VOMSVO' ]

    puspServiceURL = Registry.getVOOption( voName, 'PUSPServiceURL' )
    if not puspServiceURL:
      return S_ERROR( 'Can not determine PUSP service URL for VO %s' % voName )

    user = userDN.split(":")[-1]

    puspURL = "%s?voms=%s:%s&proxy-renewal=false&disable-voms-proxy=false" \
              "&rfc-proxy=true&cn-label=user:%s" % ( puspServiceURL, vomsVO, vomsAttribute, user )

    try:
      proxy = urllib.urlopen( puspURL ).read()
    except Exception as e:
      return S_ERROR( 'Failed to get proxy from the PUSP server' )

    chain = X509Chain()
    chain.loadChainFromString( proxy )
    chain.loadKeyFromString( proxy )

    result = chain.getCredentials()
    if not result['OK']:
      return S_ERROR( 'Failed to get a valid PUSP proxy' )
    credDict = result['Value']
    if credDict['identity'] != userDN:
      return S_ERROR( 'Requested DN does not match the obtained one in the PUSP proxy' )
    timeLeft = credDict['secondsLeft']

    result = chain.generateProxyToString( lifeTime = timeLeft,
                                          diracGroup = userGroup )
    if not result['OK']:
      return result
    proxyString = result['Value']
    return S_OK( ( proxyString, timeLeft ) )
Ejemplo n.º 9
0
    def completeDelegation(self, requestId, userDN, delegatedPem):
        """
    Complete a delegation and store it in the db
    """
        retVal = self.retrieveDelegationRequest(requestId, userDN)
        if not retVal['OK']:
            return retVal
        request = retVal['Value']
        chain = X509Chain(keyObj=request.getPKey())
        retVal = chain.loadChainFromString(delegatedPem)
        if not retVal['OK']:
            return retVal
        retVal = chain.isValidProxy()
        if not retVal['OK']:
            return retVal
        if not retVal['Value']:
            return S_ERROR("Chain received is not a valid proxy: %s" %
                           retVal['Message'])

        retVal = request.checkChain(chain)
        if not retVal['OK']:
            return retVal
        if not retVal['Value']:
            return S_ERROR("Received chain does not match request: %s" %
                           retVal['Message'])

        retVal = chain.getDIRACGroup()
        if not retVal['OK']:
            return retVal
        userGroup = retVal['Value']
        if not userGroup:
            userGroup = Registry.getDefaultUserGroup()

        retVal = Registry.getGroupsForDN(userDN)
        if not retVal['OK']:
            return retVal
        if not userGroup in retVal['Value']:
            return S_ERROR("%s group is not valid for %s" %
                           (userGroup, userDN))

        retVal = self.__checkVOMSisAlignedWithGroup(userGroup, chain)
        if not retVal['OK']:
            return retVal

        retVal = self.storeProxy(userDN, userGroup, chain)
        if not retVal['OK']:
            return retVal
        retVal = self.deleteRequest(requestId)
        if not retVal['OK']:
            return retVal
        return S_OK()
Ejemplo n.º 10
0
    def completeDelegation(self, requestId, userDN, delegatedPem):
        """
    Complete a delegation and store it in the db
    """
        retVal = self.retrieveDelegationRequest(requestId, userDN)
        if not retVal['OK']:
            return retVal
        request = retVal['Value']
        chain = X509Chain(keyObj=request.getPKey())
        retVal = chain.loadChainFromString(delegatedPem)
        if not retVal['OK']:
            return retVal
        retVal = chain.isValidProxy(ignoreDefault=True)
        if not retVal['OK']:
            return retVal

        result = chain.isVOMS()
        if result['OK'] and result['Value']:
            return S_ERROR(
                "Proxies with VOMS extensions are not allowed to be uploaded")

        retVal = request.checkChain(chain)
        if not retVal['OK']:
            return retVal
        if not retVal['Value']:
            return S_ERROR("Received chain does not match request: %s" %
                           retVal['Message'])

        retVal = chain.getDIRACGroup()
        if not retVal['OK']:
            return retVal
        userGroup = retVal['Value']
        if not userGroup:
            userGroup = Registry.getDefaultUserGroup()

        retVal = Registry.getGroupsForDN(userDN)
        if not retVal['OK']:
            return retVal
        if not userGroup in retVal['Value']:
            return S_ERROR("%s group is not valid for %s" %
                           (userGroup, userDN))

        retVal = self.storeProxy(userDN, userGroup, chain)
        if not retVal['OK']:
            return retVal
        retVal = self.deleteRequest(requestId)
        if not retVal['OK']:
            return retVal
        return S_OK()
Ejemplo n.º 11
0
  def completeDelegation( self, requestId, userDN, delegatedPem ):
    """
    Complete a delegation and store it in the db
    """
    retVal = self.retrieveDelegationRequest( requestId, userDN )
    if not retVal[ 'OK' ]:
      return retVal
    request = retVal[ 'Value' ]
    chain = X509Chain( keyObj = request.getPKey() )
    retVal = chain.loadChainFromString( delegatedPem )
    if not retVal[ 'OK' ]:
      return retVal
    retVal = chain.isValidProxy()
    if not retVal[ 'OK' ]:
      return retVal
    if not retVal[ 'Value' ]:
      return S_ERROR( "Chain received is not a valid proxy: %s" % retVal[ 'Message' ] )

    retVal = request.checkChain( chain )
    if not retVal[ 'OK' ]:
      return retVal
    if not retVal[ 'Value' ]:
      return S_ERROR( "Received chain does not match request: %s" % retVal[ 'Message' ] )

    retVal = chain.getDIRACGroup()
    if not retVal[ 'OK' ]:
      return retVal
    userGroup = retVal[ 'Value' ]
    if not userGroup:
      userGroup = Registry.getDefaultUserGroup()

    retVal = Registry.getGroupsForDN( userDN )
    if not retVal[ 'OK' ]:
      return retVal
    if not userGroup in retVal[ 'Value' ]:
      return S_ERROR( "%s group is not valid for %s" % ( userGroup, userDN ) )

    retVal = self.__checkVOMSisAlignedWithGroup( userGroup, chain )
    if not retVal[ 'OK' ]:
      return retVal

    retVal = self.storeProxy( userDN, userGroup, chain )
    if not retVal[ 'OK' ]:
      return retVal
    retVal = self.deleteRequest( requestId )
    if not retVal[ 'OK' ]:
      return retVal
    return S_OK()
Ejemplo n.º 12
0
    def _checkCredentials(self, resourceDict, credDict):
        """ Check if we can get a job given the passed credentials
    """
        if Properties.GENERIC_PILOT in credDict['properties']:
            # You can only match groups in the same VO
            if credDict['group'] == "hosts":
                # for the host case the VirtualOrganization parameter
                # is mandatory in resourceDict
                vo = resourceDict.get('VirtualOrganization', '')
            else:
                vo = Registry.getVOForGroup(credDict['group'])
            if 'OwnerGroup' not in resourceDict:
                result = Registry.getGroupsForVO(vo)
                if result['OK']:
                    resourceDict['OwnerGroup'] = result['Value']
                else:
                    raise RuntimeError(result['Message'])
        else:
            # If it's a private pilot, the DN has to be the same
            if Properties.PILOT in credDict['properties']:
                self.log.notice(
                    "Setting the resource DN to the credentials DN")
                resourceDict['OwnerDN'] = credDict['DN']
            # If it's a job sharing. The group has to be the same and just check that the DN (if any)
            # belongs to the same group
            elif Properties.JOB_SHARING in credDict['properties']:
                resourceDict['OwnerGroup'] = credDict['group']
                self.log.notice(
                    "Setting the resource group to the credentials group")
                if 'OwnerDN' in resourceDict and resourceDict[
                        'OwnerDN'] != credDict['DN']:
                    ownerDN = resourceDict['OwnerDN']
                    result = Registry.getGroupsForDN(resourceDict['OwnerDN'])
                    if not result['OK']:
                        raise RuntimeError(result['Message'])
                    if credDict['group'] not in result['Value']:
                        # DN is not in the same group! bad boy.
                        self.log.warn(
                            "You cannot request jobs from this DN, as it does not belong to your group!",
                            "(%s)" % ownerDN)
                        resourceDict['OwnerDN'] = credDict['DN']
            # Nothing special, group and DN have to be the same
            else:
                resourceDict['OwnerDN'] = credDict['DN']
                resourceDict['OwnerGroup'] = credDict['group']

        return resourceDict
Ejemplo n.º 13
0
  def completeDelegation( self, requestId, userDN, delegatedPem ):
    """
    Complete a delegation and store it in the db
    """
    retVal = self.retrieveDelegationRequest( requestId, userDN )
    if not retVal[ 'OK' ]:
      return retVal
    request = retVal[ 'Value' ]
    chain = X509Chain( keyObj = request.getPKey() )
    retVal = chain.loadChainFromString( delegatedPem )
    if not retVal[ 'OK' ]:
      return retVal
    retVal = chain.isValidProxy( ignoreDefault = True )
    if not retVal[ 'OK' ]:
      return retVal

    result = chain.isVOMS()
    if result[ 'OK' ] and result[ 'Value' ]:
      return S_ERROR( "Proxies with VOMS extensions are not allowed to be uploaded" )

    retVal = request.checkChain( chain )
    if not retVal[ 'OK' ]:
      return retVal
    if not retVal[ 'Value' ]:
      return S_ERROR( "Received chain does not match request: %s" % retVal[ 'Message' ] )

    retVal = chain.getDIRACGroup()
    if not retVal[ 'OK' ]:
      return retVal
    userGroup = retVal[ 'Value' ]
    if not userGroup:
      userGroup = Registry.getDefaultUserGroup()

    retVal = Registry.getGroupsForDN( userDN )
    if not retVal[ 'OK' ]:
      return retVal
    if not userGroup in retVal[ 'Value' ]:
      return S_ERROR( "%s group is not valid for %s" % ( userGroup, userDN ) )

    retVal = self.storeProxy( userDN, userGroup, chain )
    if not retVal[ 'OK' ]:
      return retVal
    retVal = self.deleteRequest( requestId )
    if not retVal[ 'OK' ]:
      return retVal
    return S_OK()
Ejemplo n.º 14
0
  def _checkCredentials(self, resourceDict, credDict):
    """ Check if we can get a job given the passed credentials
    """
    if Properties.GENERIC_PILOT in credDict['properties']:
      # You can only match groups in the same VO
      if credDict['group'] == "hosts":
        # for the host case the VirtualOrganization parameter
        # is mandatory in resourceDict
        vo = resourceDict.get('VirtualOrganization', '')
      else:
        vo = Registry.getVOForGroup(credDict['group'])
      if 'OwnerGroup' not in resourceDict:
        result = Registry.getGroupsForVO(vo)
        if result['OK']:
          resourceDict['OwnerGroup'] = result['Value']
        else:
          raise RuntimeError(result['Message'])
    else:
      # If it's a private pilot, the DN has to be the same
      if Properties.PILOT in credDict['properties']:
        self.log.notice("Setting the resource DN to the credentials DN")
        resourceDict['OwnerDN'] = credDict['DN']
      # If it's a job sharing. The group has to be the same and just check that the DN (if any)
      # belongs to the same group
      elif Properties.JOB_SHARING in credDict['properties']:
        resourceDict['OwnerGroup'] = credDict['group']
        self.log.notice("Setting the resource group to the credentials group")
        if 'OwnerDN' in resourceDict and resourceDict['OwnerDN'] != credDict['DN']:
          ownerDN = resourceDict['OwnerDN']
          result = Registry.getGroupsForDN(resourceDict['OwnerDN'])
          if not result['OK']:
            raise RuntimeError(result['Message'])
          if credDict['group'] not in result['Value']:
            # DN is not in the same group! bad boy.
            self.log.notice("You cannot request jobs from DN %s. It does not belong to your group!" % ownerDN)
            resourceDict['OwnerDN'] = credDict['DN']
      # Nothing special, group and DN have to be the same
      else:
        resourceDict['OwnerDN'] = credDict['DN']
        resourceDict['OwnerGroup'] = credDict['group']

    return resourceDict
Ejemplo n.º 15
0
 def getData( self ):
   data = { 'menu' : self.__getGroupMenu(),
            'user' :  self.__credDict,
            'validGroups' : [],
            'setup' : self.__setup,
            'validSetups' : gConfig.getSections( "/DIRAC/Setups" )[ 'Value' ],
            'extensions' : self.__extensions,
            'extVersion' : self.getExtJSVersion() }
   #Add valid groups if known
   DN = self.__credDict.get( "DN", "" )
   if DN:
     result = Registry.getGroupsForDN( DN )
     if result[ 'OK' ]:
       data[ 'validGroups' ] = result[ 'Value' ]
   #Calculate baseURL
   baseURL = [ Conf.rootURL().strip( "/" ),
               "s:%s" % data[ 'setup' ],
               "g:%s" % self.__credDict.get( 'group', '' )  ]
   data[ 'baseURL' ] = "/%s" % "/".join( baseURL )
   return data
Ejemplo n.º 16
0
  def getPilotGroupsToUpload( self ):
    pilotUpload = Registry.getGroupOption( self.__piParams.diracGroup, "AutoUploadPilotProxy", self.__piParams.uploadPilot )
    if not pilotUpload:
      return []

    issuerCert = self.getIssuerCert()
    userDN = issuerCert.getSubjectDN()[ 'Value' ]

    result = Registry.getGroupsForDN( userDN )
    if not result[ 'OK' ]:
      gLogger.error( "No groups defined for DN %s" % userDN )
      return []
    availableGroups = result[ 'Value' ]

    pilotGroups = []
    for group in availableGroups:
      groupProps = Registry.getPropertiesForGroup( group )
      if Properties.PILOT in groupProps or Properties.GENERIC_PILOT in groupProps:
        pilotGroups.append( group )
    return pilotGroups
Ejemplo n.º 17
0
  def _checkCredentials( self, resourceDict, credDict ):
    """ Check if we can get a job given the passed credentials
    """
    # Check credentials if not generic pilot
    if Properties.GENERIC_PILOT in credDict[ 'properties' ]:
      # You can only match groups in the same VO
      vo = Registry.getVOForGroup( credDict[ 'group' ] )
      result = Registry.getGroupsForVO( vo )
      if result[ 'OK' ]:
        resourceDict[ 'OwnerGroup' ] = result[ 'Value' ]
      else:
        raise RuntimeError( result['Message'] )
    else:
      # If it's a private pilot, the DN has to be the same
      if Properties.PILOT in credDict[ 'properties' ]:
        self.log.notice( "Setting the resource DN to the credentials DN" )
        resourceDict[ 'OwnerDN' ] = credDict[ 'DN' ]
      # If it's a job sharing. The group has to be the same and just check that the DN (if any)
      # belongs to the same group
      elif Properties.JOB_SHARING in credDict[ 'properties' ]:
        resourceDict[ 'OwnerGroup' ] = credDict[ 'group' ]
        self.log.notice( "Setting the resource group to the credentials group" )
        if 'OwnerDN'  in resourceDict and resourceDict[ 'OwnerDN' ] != credDict[ 'DN' ]:
          ownerDN = resourceDict[ 'OwnerDN' ]
          result = Registry.getGroupsForDN( resourceDict[ 'OwnerDN' ] )
          if not result[ 'OK' ]:
            raise RuntimeError( result['Message'] )
          if credDict[ 'group' ] not in result[ 'Value' ]:
            # DN is not in the same group! bad boy.
            self.log.notice( "You cannot request jobs from DN %s. It does not belong to your group!" % ownerDN )
            resourceDict[ 'OwnerDN' ] = credDict[ 'DN' ]
      # Nothing special, group and DN have to be the same
      else:
        resourceDict[ 'OwnerDN' ] = credDict[ 'DN' ]
        resourceDict[ 'OwnerGroup' ] = credDict[ 'group' ]

    return resourceDict
Ejemplo n.º 18
0
 def getData(self):
     data = {
         'menu': self.__getGroupMenu(),
         'user': self.__credDict,
         'validGroups': [],
         'setup': self.__setup,
         'validSetups': gConfig.getSections("/DIRAC/Setups")['Value'],
         'extensions': self.__extensions,
         'extVersion': self.getExtJSVersion()
     }
     #Add valid groups if known
     DN = self.__credDict.get("DN", "")
     if DN:
         result = Registry.getGroupsForDN(DN)
         if result['OK']:
             data['validGroups'] = result['Value']
     #Calculate baseURL
     baseURL = [
         Conf.rootURL().strip("/"),
         "s:%s" % data['setup'],
         "g:%s" % self.__credDict.get('group', '')
     ]
     data['baseURL'] = "/%s" % "/".join(baseURL)
     return data
Ejemplo n.º 19
0
 def getData( self ):
   DN = self.__disetConfig.getDN()
   group = self.__disetConfig.getGroup()
   credDict = self.__getCredDict( DN, group )
   data = { 'menu' : self.__getGroupMenu( credDict, group ),
            'user' :  credDict,
            'validGroups' : [],
            'setup' : self.__disetConfig.getSetup() or gConfig.getValue( "/DIRAC/Setup", "" ),
            'validSetups' : gConfig.getSections( "/DIRAC/Setups" )[ 'Value' ],
            'extensions' : self.__extensions,
            'extVersion' : self.getExtJSVersion() }
   if 'properties' in credDict:
     credDict.pop( 'properties' )
   #Add valid groups if known
   if DN:
     result = Registry.getGroupsForDN( DN )
     if result[ 'OK' ]:
       data[ 'validGroups' ] = result[ 'Value' ]
   #Calculate baseURL
   baseURL = [ Conf.rootURL().strip( "/" ),
               "s:%s" % data[ 'setup' ],
               "g:%s" % credDict.get( 'group', 'anon' )  ]
   data[ 'baseURL' ] = "/%s" % "/".join( baseURL )
   return data
Ejemplo n.º 20
0
  def selectJob( self, resourceDescription ):
    """ Main job selection function to find the highest priority job
        matching the resource capacity
    """

    startTime = time.time()
    resourceDict = self.__processResourceDescription( resourceDescription )

    credDict = self.getRemoteCredentials()
    #Check credentials
    if Properties.GENERIC_PILOT not in credDict[ 'properties' ]:
      #Not a generic pilot and requires a DN??? This smells fishy
      if 'OwnerDN' in resourceDict and resourceDict[ 'OwnerDN' ] != credDict[ 'DN' ]:
        ownerDN = resourceDict[ 'OwnerDN' ]
        if Properties.JOB_SHARING in credDict[ 'properties' ]:
          #Job sharing, is the DN in the same group?
          result = Registry.getGroupsForDN( ownerDN )
          if not result[ 'OK' ]:
            return S_ERROR( "Requested owner DN %s does not have any group!" % ownerDN )
          groups = result[ 'Value' ]
          if credDict[ 'group' ] not in groups:
            #DN is not in the same group! bad body.
            gLogger.notice( "You cannot request jobs from DN %s. It does not belong to your group!" % ownerDN )
            resourceDict[ 'OwnerDN' ] = credDict[ 'DN' ]
        else:
          #No generic pilot and not JobSharing? DN has to be the same!
          gLogger.notice( "You can only match jobs for your DN (%s)" % credDict[ 'DN' ] )
          resourceDict[ 'OwnerDN' ] = credDict[ 'DN' ]
      if Properties.PILOT not in credDict[ 'properties' ]:
        #No pilot? Group has to be the same!
        if 'OwnerGroup' in resourceDict and resourceDict[ 'OwnerGroup' ] != credDict[ 'group' ]:
          gLogger.notice( "You can only match jobs for your group (%s)" % credDict[ 'group' ] )
        resourceDict[ 'OwnerGroup' ] = credDict[ 'group' ]

    # Check the pilot DIRAC version
    if self.checkPilotVersion:
      if not 'DIRACVersion' in resourceDict:
        return S_ERROR( 'Version check requested and not provided by Pilot' )

      # Check if the matching Request provides a VirtualOrganization
      if 'VirtualOrganization' in resourceDict:
        voName = resourceDict['VirtualOrganization']
      # Check if the matching Request provides an OwnerGroup
      elif 'OwnerGroup' in resourceDict:
        voName = Registry.getVOForGroup( resourceDict['OwnerGroup'] )
      # else take the default VirtualOrganization for the installation
      else:
        voName = Registry.getVOForGroup( '' )

      self.pilotVersion = gConfig.getValue( '/Operations/%s/%s/Versions/PilotVersion' % ( voName, self.setup ), '' )
      if self.pilotVersion and resourceDict['DIRACVersion'] != self.pilotVersion:
        return S_ERROR( 'Pilot version does not match the production version %s:%s' % \
                       ( resourceDict['DIRACVersion'], self.pilotVersion ) )

    # Get common site mask and check the agent site
    result = gJobDB.getSiteMask( siteState = 'Active' )
    if result['OK']:
      maskList = result['Value']
    else:
      return S_ERROR( 'Internal error: can not get site mask' )

    if not 'Site' in resourceDict:
      return S_ERROR( 'Missing Site Name in Resource JDL' )

    siteName = resourceDict['Site']
    if resourceDict['Site'] not in maskList:
      if 'GridCE' in resourceDict:
        del resourceDict['Site']
      else:
        return S_ERROR( 'Site not in mask and GridCE not specified' )

    resourceDict['Setup'] = self.serviceInfoDict['clientSetup']

    if DEBUG:
      print "Resource description:"
      for key, value in resourceDict.items():
        print key.rjust( 20 ), value

    # Check if Job Limits are imposed onto the site
    extraConditions = {}
    if self.siteJobLimits:
      result = self.getExtraConditions( siteName )
      if result['OK']:
        extraConditions = result['Value']
    if extraConditions:
      gLogger.info( 'Job Limits for site %s are: %s' % ( siteName, str( extraConditions ) ) )

    result = gTaskQueueDB.matchAndGetJob( resourceDict, extraConditions = extraConditions )

    if DEBUG:
      print result

    if not result['OK']:
      return result
    result = result['Value']
    if not result['matchFound']:
      return S_ERROR( 'No match found' )

    jobID = result['jobId']
    resAtt = gJobDB.getJobAttributes( jobID, ['OwnerDN', 'OwnerGroup', 'Status'] )
    if not resAtt['OK']:
      return S_ERROR( 'Could not retrieve job attributes' )
    if not resAtt['Value']:
      return S_ERROR( 'No attributes returned for job' )
    if not resAtt['Value']['Status'] == 'Waiting':
      gLogger.error( 'Job %s matched by the TQ is not in Waiting state' % str( jobID ) )
      result = gTaskQueueDB.deleteJob( jobID )

    result = gJobDB.setJobStatus( jobID, status = 'Matched', minor = 'Assigned' )
    result = gJobLoggingDB.addLoggingRecord( jobID,
                                           status = 'Matched',
                                           minor = 'Assigned',
                                           source = 'Matcher' )

    result = gJobDB.getJobJDL( jobID )
    if not result['OK']:
      return S_ERROR( 'Failed to get the job JDL' )

    resultDict = {}
    resultDict['JDL'] = result['Value']
    resultDict['JobID'] = jobID

    matchTime = time.time() - startTime
    gLogger.info( "Match time: [%s]" % str( matchTime ) )
    gMonitor.addMark( "matchTime", matchTime )

    # Get some extra stuff into the response returned
    resOpt = gJobDB.getJobOptParameters( jobID )
    if resOpt['OK']:
      for key, value in resOpt['Value'].items():
        resultDict[key] = value
    resAtt = gJobDB.getJobAttributes( jobID, ['OwnerDN', 'OwnerGroup'] )
    if not resAtt['OK']:
      return S_ERROR( 'Could not retrieve job attributes' )
    if not resAtt['Value']:
      return S_ERROR( 'No attributes returned for job' )

    resultDict['DN'] = resAtt['Value']['OwnerDN']
    resultDict['Group'] = resAtt['Value']['OwnerGroup']
    return S_OK( resultDict )
Ejemplo n.º 21
0
    def selectJob(self, resourceDescription):
        """ Main job selection function to find the highest priority job
        matching the resource capacity
    """

        startTime = time.time()
        resourceDict = self.__processResourceDescription(resourceDescription)

        credDict = self.getRemoteCredentials()
        #Check credentials
        if Properties.GENERIC_PILOT not in credDict['properties']:
            #Not a generic pilot and requires a DN??? This smells fishy
            if 'OwnerDN' in resourceDict and resourceDict[
                    'OwnerDN'] != credDict['DN']:
                ownerDN = resourceDict['OwnerDN']
                if Properties.JOB_SHARING in credDict['properties']:
                    #Job sharing, is the DN in the same group?
                    result = Registry.getGroupsForDN(ownerDN)
                    if not result['OK']:
                        return S_ERROR(
                            "Requested owner DN %s does not have any group!" %
                            ownerDN)
                    groups = result['Value']
                    if credDict['group'] not in groups:
                        #DN is not in the same group! bad body.
                        gLogger.notice(
                            "You cannot request jobs from DN %s. It does not belong to your group!"
                            % ownerDN)
                        resourceDict['OwnerDN'] = credDict['DN']
                else:
                    #No generic pilot and not JobSharing? DN has to be the same!
                    gLogger.notice("You can only match jobs for your DN (%s)" %
                                   credDict['DN'])
                    resourceDict['OwnerDN'] = credDict['DN']
            if Properties.PILOT not in credDict['properties']:
                #No pilot? Group has to be the same!
                if 'OwnerGroup' in resourceDict and resourceDict[
                        'OwnerGroup'] != credDict['group']:
                    gLogger.notice(
                        "You can only match jobs for your group (%s)" %
                        credDict['group'])
                resourceDict['OwnerGroup'] = credDict['group']

        # Check the pilot DIRAC version
        if self.checkPilotVersion:
            if not 'DIRACVersion' in resourceDict:
                return S_ERROR(
                    'Version check requested and not provided by Pilot')

            # Check if the matching Request provides a VirtualOrganization
            if 'VirtualOrganization' in resourceDict:
                voName = resourceDict['VirtualOrganization']
            # Check if the matching Request provides an OwnerGroup
            elif 'OwnerGroup' in resourceDict:
                voName = Registry.getVOForGroup(resourceDict['OwnerGroup'])
            # else take the default VirtualOrganization for the installation
            else:
                voName = Registry.getVOForGroup('')

            self.pilotVersion = gConfig.getValue(
                '/Operations/%s/%s/Versions/PilotVersion' %
                (voName, self.setup), '')
            if self.pilotVersion and resourceDict[
                    'DIRACVersion'] != self.pilotVersion:
                return S_ERROR( 'Pilot version does not match the production version %s:%s' % \
                               ( resourceDict['DIRACVersion'], self.pilotVersion ) )

        # Get common site mask and check the agent site
        result = gJobDB.getSiteMask(siteState='Active')
        if result['OK']:
            maskList = result['Value']
        else:
            return S_ERROR('Internal error: can not get site mask')

        if not 'Site' in resourceDict:
            return S_ERROR('Missing Site Name in Resource JDL')

        siteName = resourceDict['Site']
        if resourceDict['Site'] not in maskList:
            if 'GridCE' in resourceDict:
                del resourceDict['Site']
            else:
                return S_ERROR('Site not in mask and GridCE not specified')

        resourceDict['Setup'] = self.serviceInfoDict['clientSetup']

        if DEBUG:
            print "Resource description:"
            for key, value in resourceDict.items():
                print key.rjust(20), value

        # Check if Job Limits are imposed onto the site
        extraConditions = {}
        if self.siteJobLimits:
            result = self.getExtraConditions(siteName)
            if result['OK']:
                extraConditions = result['Value']
        if extraConditions:
            gLogger.info('Job Limits for site %s are: %s' %
                         (siteName, str(extraConditions)))

        result = gTaskQueueDB.matchAndGetJob(resourceDict,
                                             extraConditions=extraConditions)

        if DEBUG:
            print result

        if not result['OK']:
            return result
        result = result['Value']
        if not result['matchFound']:
            return S_ERROR('No match found')

        jobID = result['jobId']
        resAtt = gJobDB.getJobAttributes(jobID,
                                         ['OwnerDN', 'OwnerGroup', 'Status'])
        if not resAtt['OK']:
            return S_ERROR('Could not retrieve job attributes')
        if not resAtt['Value']:
            return S_ERROR('No attributes returned for job')
        if not resAtt['Value']['Status'] == 'Waiting':
            gLogger.error('Job %s matched by the TQ is not in Waiting state' %
                          str(jobID))
            result = gTaskQueueDB.deleteJob(jobID)

        result = gJobDB.setJobStatus(jobID, status='Matched', minor='Assigned')
        result = gJobLoggingDB.addLoggingRecord(jobID,
                                                status='Matched',
                                                minor='Assigned',
                                                source='Matcher')

        result = gJobDB.getJobJDL(jobID)
        if not result['OK']:
            return S_ERROR('Failed to get the job JDL')

        resultDict = {}
        resultDict['JDL'] = result['Value']
        resultDict['JobID'] = jobID

        matchTime = time.time() - startTime
        gLogger.info("Match time: [%s]" % str(matchTime))
        gMonitor.addMark("matchTime", matchTime)

        # Get some extra stuff into the response returned
        resOpt = gJobDB.getJobOptParameters(jobID)
        if resOpt['OK']:
            for key, value in resOpt['Value'].items():
                resultDict[key] = value
        resAtt = gJobDB.getJobAttributes(jobID, ['OwnerDN', 'OwnerGroup'])
        if not resAtt['OK']:
            return S_ERROR('Could not retrieve job attributes')
        if not resAtt['Value']:
            return S_ERROR('No attributes returned for job')

        resultDict['DN'] = resAtt['Value']['OwnerDN']
        resultDict['Group'] = resAtt['Value']['OwnerGroup']
        return S_OK(resultDict)
Ejemplo n.º 22
0
  def selectJob( self, resourceDescription ):
    """ Main job selection function to find the highest priority job
        matching the resource capacity
    """

    startTime = time.time()
    resourceDict = self.__processResourceDescription( resourceDescription )

    credDict = self.getRemoteCredentials()
    #Check credentials if not generic pilot
    if Properties.GENERIC_PILOT in credDict[ 'properties' ]:
      #You can only match groups in the same VO
      vo = Registry.getVOForGroup( credDict[ 'group' ] )
      result = Registry.getGroupsForVO( vo )
      if result[ 'OK' ]:
        resourceDict[ 'OwnerGroup' ] = result[ 'Value' ]
    else:
      #If it's a private pilot, the DN has to be the same
      if Properties.PILOT in credDict[ 'properties' ]:
        gLogger.notice( "Setting the resource DN to the credentials DN" )
        resourceDict[ 'OwnerDN' ] = credDict[ 'DN' ]
      #If it's a job sharing. The group has to be the same and just check that the DN (if any)
      # belongs to the same group
      elif Properties.JOB_SHARING in credDict[ 'properties' ]:
        resourceDict[ 'OwnerGroup' ] = credDict[ 'group' ]
        gLogger.notice( "Setting the resource group to the credentials group" )
        if 'OwnerDN'  in resourceDict and resourceDict[ 'OwnerDN' ] != credDict[ 'DN' ]:
          ownerDN = resourceDict[ 'OwnerDN' ]
          result = Registry.getGroupsForDN( resourceDict[ 'OwnerDN' ] )
          if not result[ 'OK' ] or credDict[ 'group' ] not in result[ 'Value' ]:
            #DN is not in the same group! bad boy.
            gLogger.notice( "You cannot request jobs from DN %s. It does not belong to your group!" % ownerDN )
            resourceDict[ 'OwnerDN' ] = credDict[ 'DN' ]
      #Nothing special, group and DN have to be the same
      else:
        resourceDict[ 'OwnerDN' ] = credDict[ 'DN' ]
        resourceDict[ 'OwnerGroup' ] = credDict[ 'group' ]

    # Check the pilot DIRAC version
    if self.__opsHelper.getValue( "Pilot/CheckVersion", True ):
      if 'ReleaseVersion' not in resourceDict:
        if not 'DIRACVersion' in resourceDict:
          return S_ERROR( 'Version check requested and not provided by Pilot' )
        else:
          pilotVersion = resourceDict['DIRACVersion']
      else:
        pilotVersion = resourceDict['ReleaseVersion']

      validVersions = self.__opsHelper.getValue( "Pilot/Version", [] )
      if validVersions and pilotVersion not in validVersions:
        return S_ERROR( 'Pilot version does not match the production version %s not in ( %s )' % \
                       ( pilotVersion, ",".join( validVersions ) ) )
      #Check project if requested
      validProject = self.__opsHelper.getValue( "Pilot/Project", "" )
      if validProject:
        if 'ReleaseProject' not in resourceDict:
          return S_ERROR( "Version check requested but expected project %s not received" % validProject )
        if resourceDict[ 'ReleaseProject' ] != validProject:
          return S_ERROR( "Version check requested but expected project %s != received %s" % ( validProject,
                                                                                               resourceDict[ 'ReleaseProject' ] ) )

    # Update pilot information
    pilotInfoReported = False
    pilotReference = resourceDict.get( 'PilotReference', '' )
    if pilotReference:
      if "PilotInfoReportedFlag" in resourceDict and not resourceDict['PilotInfoReportedFlag']:
        gridCE = resourceDict.get( 'GridCE', 'Unknown' )
        site = resourceDict.get( 'Site', 'Unknown' )
        benchmark = benchmark = resourceDict.get( 'PilotBenchmark', 0.0 )
        gLogger.verbose('Reporting pilot info for %s: gridCE=%s, site=%s, benchmark=%f' % (pilotReference,gridCE,site,benchmark) )
        result = gPilotAgentsDB.setPilotStatus( pilotReference, status = 'Running',
                                                gridSite = site,
                                                destination = gridCE,
                                                benchmark = benchmark )
        if result['OK']:
          pilotInfoReported = True                                        
    
    #Check the site mask
    if not 'Site' in resourceDict:
      return S_ERROR( 'Missing Site Name in Resource JDL' )

    # Get common site mask and check the agent site
    result = gJobDB.getSiteMask( siteState = 'Active' )
    if not result['OK']:
      return S_ERROR( 'Internal error: can not get site mask' )
    maskList = result['Value']

    siteName = resourceDict['Site']
    if siteName not in maskList:
      
      # if 'GridCE' not in resourceDict:
      #  return S_ERROR( 'Site not in mask and GridCE not specified' )
      # Even if the site is banned, if it defines a CE, it must be able to check it
      # del resourceDict['Site']
      
      # Banned site can only take Test jobs 
      resourceDict['JobType'] = 'Test'

    resourceDict['Setup'] = self.serviceInfoDict['clientSetup']

    gLogger.verbose( "Resource description:" )
    for key in resourceDict:
      gLogger.verbose( "%s : %s" % ( key.rjust( 20 ), resourceDict[ key ] ) )

    negativeCond = self.__limiter.getNegativeCondForSite( siteName )
    result = gTaskQueueDB.matchAndGetJob( resourceDict, negativeCond = negativeCond )

    if DEBUG:
      print result

    if not result['OK']:
      return result
    result = result['Value']
    if not result['matchFound']:
      return S_ERROR( 'No match found' )

    jobID = result['jobId']
    resAtt = gJobDB.getJobAttributes( jobID, ['OwnerDN', 'OwnerGroup', 'Status'] )
    if not resAtt['OK']:
      return S_ERROR( 'Could not retrieve job attributes' )
    if not resAtt['Value']:
      return S_ERROR( 'No attributes returned for job' )
    if not resAtt['Value']['Status'] == 'Waiting':
      gLogger.error( 'Job matched by the TQ is not in Waiting state', str( jobID ) )
      result = gTaskQueueDB.deleteJob( jobID )
      if not result[ 'OK' ]:
        return result
      return S_ERROR( "Job %s is not in Waiting state" % str( jobID ) )

    attNames = ['Status','MinorStatus','ApplicationStatus','Site']
    attValues = ['Matched','Assigned','Unknown',siteName]
    result = gJobDB.setJobAttributes( jobID, attNames, attValues )
    # result = gJobDB.setJobStatus( jobID, status = 'Matched', minor = 'Assigned' )
    result = gJobLoggingDB.addLoggingRecord( jobID,
                                           status = 'Matched',
                                           minor = 'Assigned',
                                           source = 'Matcher' )

    result = gJobDB.getJobJDL( jobID )
    if not result['OK']:
      return S_ERROR( 'Failed to get the job JDL' )

    resultDict = {}
    resultDict['JDL'] = result['Value']
    resultDict['JobID'] = jobID

    matchTime = time.time() - startTime
    gLogger.info( "Match time: [%s]" % str( matchTime ) )
    gMonitor.addMark( "matchTime", matchTime )

    # Get some extra stuff into the response returned
    resOpt = gJobDB.getJobOptParameters( jobID )
    if resOpt['OK']:
      for key, value in resOpt['Value'].items():
        resultDict[key] = value
    resAtt = gJobDB.getJobAttributes( jobID, ['OwnerDN', 'OwnerGroup'] )
    if not resAtt['OK']:
      return S_ERROR( 'Could not retrieve job attributes' )
    if not resAtt['Value']:
      return S_ERROR( 'No attributes returned for job' )

    if self.__opsHelper.getValue( "JobScheduling/CheckMatchingDelay", True ):
      self.__limiter.updateDelayCounters( siteName, jobID )

    # Report pilot-job association
    if pilotReference:
      result = gPilotAgentsDB.setCurrentJobID( pilotReference, jobID )
      result = gPilotAgentsDB.setJobForPilot( jobID, pilotReference, updateStatus=False )

    resultDict['DN'] = resAtt['Value']['OwnerDN']
    resultDict['Group'] = resAtt['Value']['OwnerGroup']
    resultDict['PilotInfoReportedFlag'] = pilotInfoReported
    return S_OK( resultDict )
Ejemplo n.º 23
0
    def selectJob(self, resourceDescription):
        """ Main job selection function to find the highest priority job
        matching the resource capacity
    """

        startTime = time.time()
        resourceDict = self.__processResourceDescription(resourceDescription)

        credDict = self.getRemoteCredentials()
        #Check credentials if not generic pilot
        if Properties.GENERIC_PILOT in credDict['properties']:
            #You can only match groups in the same VO
            vo = Registry.getVOForGroup(credDict['group'])
            result = Registry.getGroupsForVO(vo)
            if result['OK']:
                resourceDict['OwnerGroup'] = result['Value']
        else:
            #If it's a private pilot, the DN has to be the same
            if Properties.PILOT in credDict['properties']:
                gLogger.notice("Setting the resource DN to the credentials DN")
                resourceDict['OwnerDN'] = credDict['DN']
            #If it's a job sharing. The group has to be the same and just check that the DN (if any)
            # belongs to the same group
            elif Properties.JOB_SHARING in credDict['properties']:
                resourceDict['OwnerGroup'] = credDict['group']
                gLogger.notice(
                    "Setting the resource group to the credentials group")
                if 'OwnerDN' in resourceDict and resourceDict[
                        'OwnerDN'] != credDict['DN']:
                    ownerDN = resourceDict['OwnerDN']
                    result = Registry.getGroupsForDN(resourceDict['OwnerDN'])
                    if not result['OK'] or credDict['group'] not in result[
                            'Value']:
                        #DN is not in the same group! bad boy.
                        gLogger.notice(
                            "You cannot request jobs from DN %s. It does not belong to your group!"
                            % ownerDN)
                        resourceDict['OwnerDN'] = credDict['DN']
            #Nothing special, group and DN have to be the same
            else:
                resourceDict['OwnerDN'] = credDict['DN']
                resourceDict['OwnerGroup'] = credDict['group']

        # Check the pilot DIRAC version
        if self.__opsHelper.getValue("Pilot/CheckVersion", True):
            if 'ReleaseVersion' not in resourceDict:
                if not 'DIRACVersion' in resourceDict:
                    return S_ERROR(
                        'Version check requested and not provided by Pilot')
                else:
                    pilotVersion = resourceDict['DIRACVersion']
            else:
                pilotVersion = resourceDict['ReleaseVersion']

            validVersions = self.__opsHelper.getValue("Pilot/Version", [])
            if validVersions and pilotVersion not in validVersions:
                return S_ERROR( 'Pilot version does not match the production version %s not in ( %s )' % \
                               ( pilotVersion, ",".join( validVersions ) ) )
            #Check project if requested
            validProject = self.__opsHelper.getValue("Pilot/Project", "")
            if validProject:
                if 'ReleaseProject' not in resourceDict:
                    return S_ERROR(
                        "Version check requested but expected project %s not received"
                        % validProject)
                if resourceDict['ReleaseProject'] != validProject:
                    return S_ERROR(
                        "Version check requested but expected project %s != received %s"
                        % (validProject, resourceDict['ReleaseProject']))

        # Update pilot information
        pilotInfoReported = resourceDict.get('PilotInfoReportedFlag', False)
        pilotReference = resourceDict.get('PilotReference', '')
        if pilotReference and not pilotInfoReported:
            gridCE = resourceDict.get('GridCE', 'Unknown')
            site = resourceDict.get('Site', 'Unknown')
            benchmark = benchmark = resourceDict.get('PilotBenchmark', 0.0)
            gLogger.verbose(
                'Reporting pilot info for %s: gridCE=%s, site=%s, benchmark=%f'
                % (pilotReference, gridCE, site, benchmark))
            result = gPilotAgentsDB.setPilotStatus(pilotReference,
                                                   status='Running',
                                                   gridSite=site,
                                                   destination=gridCE,
                                                   benchmark=benchmark)
            if result['OK']:
                pilotInfoReported = True

        #Check the site mask
        if not 'Site' in resourceDict:
            return S_ERROR('Missing Site Name in Resource JDL')

        # Get common site mask and check the agent site
        result = gJobDB.getSiteMask(siteState='Active')
        if not result['OK']:
            return S_ERROR('Internal error: can not get site mask')
        maskList = result['Value']

        siteName = resourceDict['Site']
        if siteName not in maskList:

            # if 'GridCE' not in resourceDict:
            #  return S_ERROR( 'Site not in mask and GridCE not specified' )
            # Even if the site is banned, if it defines a CE, it must be able to check it
            # del resourceDict['Site']

            # Banned site can only take Test jobs
            resourceDict['JobType'] = 'Test'

        resourceDict['Setup'] = self.serviceInfoDict['clientSetup']

        gLogger.verbose("Resource description:")
        for key in resourceDict:
            gLogger.verbose("%s : %s" % (key.rjust(20), resourceDict[key]))

        negativeCond = self.__limiter.getNegativeCondForSite(siteName)
        result = gTaskQueueDB.matchAndGetJob(resourceDict,
                                             negativeCond=negativeCond)

        if DEBUG:
            print result

        if not result['OK']:
            return result
        result = result['Value']
        if not result['matchFound']:
            return S_ERROR('No match found')

        jobID = result['jobId']
        resAtt = gJobDB.getJobAttributes(jobID,
                                         ['OwnerDN', 'OwnerGroup', 'Status'])
        if not resAtt['OK']:
            return S_ERROR('Could not retrieve job attributes')
        if not resAtt['Value']:
            return S_ERROR('No attributes returned for job')
        if not resAtt['Value']['Status'] == 'Waiting':
            gLogger.error('Job matched by the TQ is not in Waiting state',
                          str(jobID))
            result = gTaskQueueDB.deleteJob(jobID)
            if not result['OK']:
                return result
            return S_ERROR("Job %s is not in Waiting state" % str(jobID))

        attNames = ['Status', 'MinorStatus', 'ApplicationStatus', 'Site']
        attValues = ['Matched', 'Assigned', 'Unknown', siteName]
        result = gJobDB.setJobAttributes(jobID, attNames, attValues)
        # result = gJobDB.setJobStatus( jobID, status = 'Matched', minor = 'Assigned' )
        result = gJobLoggingDB.addLoggingRecord(jobID,
                                                status='Matched',
                                                minor='Assigned',
                                                source='Matcher')

        result = gJobDB.getJobJDL(jobID)
        if not result['OK']:
            return S_ERROR('Failed to get the job JDL')

        resultDict = {}
        resultDict['JDL'] = result['Value']
        resultDict['JobID'] = jobID

        matchTime = time.time() - startTime
        gLogger.info("Match time: [%s]" % str(matchTime))
        gMonitor.addMark("matchTime", matchTime)

        # Get some extra stuff into the response returned
        resOpt = gJobDB.getJobOptParameters(jobID)
        if resOpt['OK']:
            for key, value in resOpt['Value'].items():
                resultDict[key] = value
        resAtt = gJobDB.getJobAttributes(jobID, ['OwnerDN', 'OwnerGroup'])
        if not resAtt['OK']:
            return S_ERROR('Could not retrieve job attributes')
        if not resAtt['Value']:
            return S_ERROR('No attributes returned for job')

        if self.__opsHelper.getValue("JobScheduling/CheckMatchingDelay", True):
            self.__limiter.updateDelayCounters(siteName, jobID)

        # Report pilot-job association
        if pilotReference:
            result = gPilotAgentsDB.setCurrentJobID(pilotReference, jobID)
            result = gPilotAgentsDB.setJobForPilot(jobID,
                                                   pilotReference,
                                                   updateStatus=False)

        resultDict['DN'] = resAtt['Value']['OwnerDN']
        resultDict['Group'] = resAtt['Value']['OwnerGroup']
        resultDict['PilotInfoReportedFlag'] = pilotInfoReported
        return S_OK(resultDict)
Ejemplo n.º 24
0
    def getProxy(self, userDict):
        """ Generate user proxy

        :param dict userDict: user description dictionary with possible fields:
               FullName, UserName, DN, EMail, DiracGroup

        :return: S_OK(basestring)/S_ERROR() -- basestring is a proxy string
    """

        userDN = userDict.get('DN')
        if not userDN:
            return S_ERROR('Incomplete user information')

        diracGroup = userDict.get('DiracGroup')
        if not diracGroup:
            return S_ERROR('Incomplete user information')

        result = Registry.getGroupsForDN(userDN)
        if not result['OK']:
            return result

        validGroups = result['Value']
        if diracGroup not in validGroups:
            return S_ERROR('Invalid group %s for user' % diracGroup)

        voName = Registry.getVOForGroup(diracGroup)
        if not voName:
            return S_ERROR('Can not determine VO for group %s' % diracGroup)

        csVOMSMapping = Registry.getVOMSAttributeForGroup(diracGroup)
        if not csVOMSMapping:
            return S_ERROR("No VOMS mapping defined for group %s in the CS" %
                           diracGroup)
        vomsAttribute = csVOMSMapping
        vomsVO = Registry.getVOMSVOForGroup(diracGroup)

        puspServiceURL = self.parameters.get('ServiceURL')
        if not puspServiceURL:
            return S_ERROR('Can not determine PUSP service URL for VO %s' %
                           voName)

        user = userDN.split(":")[-1]

        puspURL = "%s?voms=%s:%s&proxy-renewal=false&disable-voms-proxy=false" \
                  "&rfc-proxy=true&cn-label=user:%s" % (puspServiceURL, vomsVO, vomsAttribute, user)

        try:
            proxy = urllib.urlopen(puspURL).read()
        except Exception as e:
            return S_ERROR('Failed to get proxy from the PUSP server')

        chain = X509Chain()
        chain.loadChainFromString(proxy)
        chain.loadKeyFromString(proxy)

        result = chain.getCredentials()
        if not result['OK']:
            return S_ERROR('Failed to get a valid PUSP proxy')
        credDict = result['Value']
        if credDict['identity'] != userDN:
            return S_ERROR(
                'Requested DN does not match the obtained one in the PUSP proxy'
            )
        timeLeft = credDict['secondsLeft']

        result = chain.generateProxyToString(lifeTime=timeLeft,
                                             diracGroup=diracGroup)
        if not result['OK']:
            return result
        proxyString = result['Value']
        return S_OK((proxyString, timeLeft))