示例#1
0
class AuthManager(object):
    """
        Manager to maintain multiple credential Handlers, one for each target account.
        For some handlers, if they need to perform periodic checks, they will be run
        as threads. Others, which only hold information, will just be objects.  
    
    """
    def __init__(self, factory=None):

        self.log = logging.getLogger('autopyfactory')
        self.log.info("Creating new authmanager...")
        self.aconfig = Config()
        self.handlers = []
        self.factory = factory
        if factory:
            self.sleep = int(
                self.factory.fcl.get('Factory', 'authmanager.sleep'))
        else:
            self.sleep = 5

    def reconfig(self, newconfig):

        hdiff = ConfigsDiff(self.aconfig, newconfig)
        self.aconfig = newconfig
        self._addhandlers(hdiff.added())

    def _addhandlers(self, newsections):

        for sect in newsections:
            try:
                pclass = self.aconfig.get(sect, 'plugin')
            except Exception, e:
                self.log.warn("No plugin attribute for section %s" % sect)
            if pclass == 'X509':
                self.log.debug("Creating X509 handler for %s" % sect)
                authpluginname = self.aconfig.get(sect, 'plugin')
                x509h = pluginmanager.getplugin(
                    ['autopyfactory', 'plugins', 'authmanager', 'auth'],
                    authpluginname, self, self.aconfig, sect)
                self.handlers.append(x509h)
            elif pclass == 'SSH':
                self.log.debug("Creating SSH handler for %s" % sect)
                authpluginname = self.aconfig.get(sect, 'plugin')
                sshh = pluginmanager.getplugin(
                    ['autopyfactory', 'plugins', 'authmanager', 'auth'],
                    authpluginname, self, self.aconfig, sect)
                self.handlers.append(sshh)
            else:
                self.log.warn("Unrecognized auth plugin %s" % pclass)
示例#2
0
class AuthManager(object):
    """
        Manager to maintain multiple credential Handlers, one for each target account.
        For some handlers, if they need to perform periodic checks, they will be run
        as threads. Others, which only hold information, will just be objects.  
    
    """
    def __init__(self, factory=None):
        
        self.log = logging.getLogger('autopyfactory')
        self.log.info("Creating new authmanager...")
        self.aconfig = Config() 
        self.handlers = []
        self.factory = factory
        if factory:
            self.sleep = int(self.factory.fcl.get('Factory', 'authmanager.sleep'))
        else:
            self.sleep = 5


    def reconfig(self, newconfig):  

        hdiff = ConfigsDiff(self.aconfig, newconfig)
        self.aconfig = newconfig
        self._addhandlers(hdiff.added())


    def _addhandlers(self, newsections):

        for sect in newsections:
            try:
                pclass = self.aconfig.get(sect, 'plugin')
            except Exception as e:
                self.log.warn("No plugin attribute for section %s" % sect)
            if pclass == 'X509':
                self.log.debug("Creating X509 handler for %s" % sect )
                authpluginname = self.aconfig.get(sect, 'plugin')
                x509h = pluginmanager.getplugin(['autopyfactory', 'plugins', 'authmanager', 'auth'], authpluginname, self, self.aconfig, sect)
                self.handlers.append(x509h)
            elif pclass == 'SSH':
                self.log.debug("Creating SSH handler for %s" % sect )
                authpluginname = self.aconfig.get(sect, 'plugin')
                sshh = pluginmanager.getplugin(['autopyfactory', 'plugins', 'authmanager', 'auth'], authpluginname, self, self.aconfig, sect)
                self.handlers.append(sshh)
            else:
                self.log.warn("Unrecognized auth plugin %s" % pclass )
    
        
    def activate(self):
        """ 
        start all Handlers, if needed
        """ 

        for ah in self.handlers:
            if isinstance(ah, threading.Thread) :
                self.log.debug("Handler [%s] is a thread. Starting..." % ah.name)
                ah.start()
            else:
                self.log.debug("Handler [%s] is not a thread. No action." % ah.name)

      
    def listNames(self):
        """
            Returns list of valid names of Handlers in this Manager. 
        """
        names = []
        for h in self.handlers:
            names.append(h.name)
        return names

#
#    API for X509Handler 
#
    def getProxyPath(self, profilelist):
            """
            Check all the handlers for matching profile name(s).
            profiles argument is a list 
            """
            pp = None
            for profile in profilelist:
                self.log.debug("Getting proxy path for profile %s" % profile)
                ph = None
                for h in self.handlers:
                    self.log.debug("Finding handler. Checking %s" % h.name)
                    if h.name == profile:
                        ph = h
                        break
                    
                if ph:  
                    self.log.debug("Found handler %s. Getting proxypath..." % ph.name)
                    pp = ph.getProxyPath()
                    self.log.debug("Proxypath is %s" % pp)
                    if pp:
                        break
            if not pp:
                subject = "Proxy problem on %s" % self.factory.factoryid
                messagestring = "Unable to get valid proxy from configured profiles: %s" % profilelist
                self.factory.sendAdminEmail(subject, messagestring)
                raise InvalidAuthFailure("Problem getting proxy for profile %s" % profilelist)
            
            return pp

#
#   API for SSHKeyHandler
#

    def getSSHKeyPair(self, profile):
        """
         Returns tuple (public, private, pass) key/phrase string from profile. 
        """
        pass
        
        
    def getSSHKeyPairPaths(self, profile):
        """
        Returns tuple (public, private, pass) key/passfile paths to files from profile. 
        """
        h = self._getHandler(profile)
        pub = h.getSSHPubKeyFilePath()
        priv = h.getSSHPrivKeyFilePath()
        pasf = h.getSSHPassFilePath()
        self.log.info('Got file paths for pub, priv, pass for SSH profile %s' % profile)
        return (pub,priv,pasf)


    def _getHandler(self, profile):
        """
        
        """
        handler = None
        for h in self.handlers:
            self.log.debug("Finding handler. Checking %s" % h.name)
            if h.name == profile:
                self.log.debug("Found handler for %s" % h.name)
                handler = h
        if handler is None:
            raise InvalidAuthFailure('No handler for %s ' % profile)
        return handler
示例#3
0
class APFGridSubmitter(object):

    __metaclass__ = APFGridSubmitterSingleton

    factorymock = None
    authman = None
    agis = None
    logserver = None
    cleanlogs = None    

   
    def __init__(self, **kwarg):
        self.log = core_utils.make_logger(baseLogger)
        self.config = Config()
        factoryconffile = os.path.expanduser('~/harvester/etc/autopyfactory/autopyfactory.conf')
        self.log.debug('Reading config: %s' % factoryconffile)
        okread = self.config.read(factoryconffile)
        self.log.debug('Successfully read %s' % okread)       

        # Setup Authmanager
        authconfigfile = os.path.expanduser(self.config.get('Factory','authConf'))
        
        ac = Config()
        self.log.debug('Reading config: %s' % authconfigfile)
        okread = ac.read(authconfigfile)
        self.log.debug('Successfully read %s' % okread) 
        if APFGridSubmitter.authman is None :
            APFGridSubmitter.authman = AuthManager()
            APFGridSubmitter.authman.reconfig(ac)
        self.authman = APFGridSubmitter.authman           
        APFGridSubmitter.authman.activate()

        # Setup factory mock object. 
        from autopyfactory.factory import Factory
        if APFGridSubmitter.factorymock is None:
            APFGridSubmitter.factorymock = Factory.getFactoryMock(fcl=self.config, am=self.authman)
        
        # Setup AGIS
        if APFGridSubmitter.agis is None:
            APFGridSubmitter.agisobj = Agis(None, self.config, None)
        self.agisobj = APFGridSubmitter.agisobj
        self.log.debug("AGIS object: %s" % self.agisobj)
        
        # Setup logserver
        self.log.debug("Handling LogServer...")
        if self.config.generic_get('Factory', 'logserver.enabled', 'getboolean'):
            self.log.info("LogServer enabled. Initializing...")
            self.logserver = LogServer(self.config)
            self.log.info('LogServer initialized. Starting...')
            self.logserver.start()
            self.log.debug('LogServer thread started.')
        else:
            self.log.info('LogServer disabled. Not running.')     
        self.log.debug('APFGridSubmitter initialized.')       


    def _print_config(self, config):
        s=""
        for section in config.sections():
            s+= "[%s]\n" % section
            for opt in config.options(section):
                s+="%s = %s\n" % (opt, config.get(section, opt))
        return s


    def submit_workers(self, workspec_list):
        '''
        Submit workers to a scheduling system like batch systems and computing elements.
        This method takes a list of WorkSpecs as input argument, and returns a list of tuples.
        Each tuple is composed of a return code and a dialog message.
        Nth tuple in the returned list corresponds to submission status and dialog message for Nth worker
        in the given WorkSpec list.
        A unique identifier is set to WorkSpec.batchID when submission is successful,
        so that they can be identified in the scheduling system.


        :param workspec_list: a list of work specs instances
        :return: A list of tuples. Each tuple is composed of submission status (True for success, False otherwise)
        and dialog message
        :rtype: [(bool, string),]
        
        
        For UPQ
        PQ name, e.g.    HARVESTER_BNL_APF_TEST/MCORE
        SCORE, SCORE_HIMEM, MCORE, and MCORE_HIMEM
    
        Workspec                     AGIS PQ/CEQ attribute. 
        WorkSpec.minRamCount         PQ.memory
        WorkSpec.nCore               PQ.corecount 
        WorkSpec.maxDiskCount        PQ.maxwdir  
        WorkSpec.maxWalltime         PQ.maxtime
        
        '''
        self.log.debug('start nWorkers={0}'.format(len(workspec_list)))
        self.log.debug("Update AGIS info...")
        qc = self.agisobj.getConfig()
        #self.log.debug('Agis config output %s' % self._print_config(qc))
        #self.log.debug('Agis config defaults= %s' % qc.defaults() )
        retlist = []
        
        # wsmap is indexed by computing site:
        # { <computingsite>  : [ws1, ws2, ws3 ],
        #   <computingsite2> : [ws4, ws5]
        # } 
        wsmap = {}
        jobmap = {}
        try:
            self.log.debug("Handling workspec_list with %d items..." % len(workspec_list))
            for workSpec in workspec_list:
                self.log.debug("Worker(workerId=%s queueName=%s computingSite=%s nCore=%s status=%s " % (workSpec.workerID, 
                                                                                   workSpec.queueName,
                                                                                   workSpec.computingSite,
                                                                                   workSpec.nCore, 
                                                                                   workSpec.status) )
                try:
                    wslist = wsmap[workSpec.computingSite]
                    wslist.append(workSpec)
                except KeyError:
                    wsmap[workSpec.computingSite] = [workSpec] 
                self.log.debug("wsmap = %s" % wsmap)
            
            for pq in wsmap.keys():
                found = False        
                apfqsections = []
                
                for s in qc.sections():
                    qcq = qc.get(s, 'wmsqueue').strip()
                    self.log.debug('Checking %s' % qcq)
                    if qcq == pq:
                        found = True
                        apfqsections.append(s)
                        self.log.debug("Found a queues config for %s" % pq )
                        
                self.log.info("Found %d sections for PQ %s" % (len(apfqsections), pq))
                if found:
                    # make apfq and submit
                    self.log.debug("One or more Agis configs found for PQ. Choosing one...")
                    section = random.choice(apfqsections)
                    pqc = qc.getSection(section)
                    ac = os.path.expanduser('~/harvester/etc/autopyfactory/autopyfactory.conf')
                    pqc.set(section, 'factoryconf', ac) 
                    self.log.debug("Section config= %s" % pqc)
                    self.log.debug("Making APF queue for PQ %s with label %s"% (pq, section))
                    apfq = SubmitAPFQueue( pqc, self.authman )
                    self.log.debug("Successfully made APFQueue")
                    joblist = []
                    for ws in wsmap[pq]:
                        jobentry = { "+workerid" : ws.workerID }
                        joblist.append(jobentry)
                    self.log.debug("joblist made= %s. Submitting..." % joblist)
                    jobinfo = apfq.submitlist(joblist)
                    self.log.debug("Got jobinfo %s" % jobinfo)
                    
                    wslist = wsmap[pq]
                    self.log.debug("wslist for pq %s is length %s" % (pq, len(wslist)))
                    for i in range(0, len(wslist)):
                        self.log.debug("Setting ws.batchID to %s" % jobinfo[i].jobid )
                        wslist[i].batchID = jobinfo[i].jobid
                        wslist[i].set_status(WorkSpec.ST_submitted)
                        retlist.append((True, ''))
                else:
                    self.log.info('No AGIS config found for PQ %s skipping.' % pq)        

        except Exception, e:
            self.log.error(traceback.format_exc(None))

        self.log.debug("return list=%s " % retlist)
        return retlist
示例#4
0
class AuthManager(object):
    """
        Manager to maintain multiple credential Handlers, one for each target account.
        For some handlers, if they need to perform periodic checks, they will be run
        as threads. Others, which only hold information, will just be objects.  
    
    """
    def __init__(self, factory=None):

        self.log = logging.getLogger('autopyfactory')
        self.log.info("Creating new authmanager...")
        self.aconfig = Config()
        self.handlers = []
        self.factory = factory
        if factory:
            self.sleep = int(
                self.factory.fcl.get('Factory', 'authmanager.sleep'))
        else:
            self.sleep = 5

    def reconfig(self, newconfig):
        self.log.debug("Performing reconfig() for auth handlers...")
        hdiff = ConfigsDiff(self.aconfig, newconfig)
        self.aconfig = newconfig

        self.log.debug("Deleting removed handlers...")
        self._delhandlers(hdiff.removed())
        self.log.debug("Deleting modified handlers...")
        self._delhandlers(hdiff.modified())
        self.log.debug("Re-creating modified handlers...")
        self._addhandlers(hdiff.modified())
        self.log.debug("Adding new handlers...")
        self._addhandlers(hdiff.added())
        self.log.info("Completed reconfig() on auth handlers.")

    def _addhandlers(self, newsections):
        for sect in newsections:
            try:
                pclass = self.aconfig.get(sect, 'plugin')
            except Exception as e:
                self.log.warn("No plugin attribute for section %s" % sect)
            if pclass == 'X509':
                self.log.debug("Creating X509 handler for %s" % sect)
                authpluginname = self.aconfig.get(sect, 'plugin')
                x509h = pluginmanager.getplugin(
                    ['autopyfactory', 'plugins', 'authmanager', 'auth'],
                    authpluginname, self, self.aconfig, sect)
                self.handlers.append(x509h)
            elif pclass == 'SSH' or 'GSISSH':
                self.log.debug("Creating SSH handler for %s" % sect)
                authpluginname = self.aconfig.get(sect, 'plugin')
                sshh = pluginmanager.getplugin(
                    ['autopyfactory', 'plugins', 'authmanager', 'auth'],
                    authpluginname, self, self.aconfig, sect)
                self.handlers.append(sshh)
            else:
                self.log.warn("Unrecognized auth plugin %s" % pclass)

    def _delhandlers(self, delsections):
        for sect in delsections:
            try:
                handler = self._gethandlerbyname(sect)
                if handler is not None:
                    if isinstance(handler, threading.Thread):
                        try:
                            handler.join()
                        except Exception:
                            self.log.warning(
                                'attempt to join() thread for handler %s failed, handler is not active'
                                % handler.name)
                # In any case, remove the handler object...
                    self.handlers.pop(handler)
            except Exception:
                self.log.warning(
                    'attempt to join() thread for handler %s failed, handler is not active'
                    % handler.name)

    def _gethandlerbyname(self, name):
        h = None
        for h in self.handlers:
            if h.name == name:
                self.log.debug("Found handler %s" % name)
                return h
        return h

    def activate(self):
        """ 
        start all Handlers, if needed
        """

        for ah in self.handlers:
            if isinstance(ah, threading.Thread):
                self.log.debug("Handler [%s] is a thread. Starting..." %
                               ah.name)
                ah.start()
            else:
                self.log.debug("Handler [%s] is not a thread. No action." %
                               ah.name)

    def listNames(self):
        """
            Returns list of valid names of Handlers in this Manager. 
        """
        names = []
        for h in self.handlers:
            names.append(h.name)
        return names

#
#    API for X509Handler
#

    def getProxyPath(self, profilelist):
        """
            Check all the handlers for matching profile name(s).
            profiles argument is a list 
            """
        pp = None
        for profile in profilelist:
            self.log.debug("Getting proxy path for profile %s" % profile)
            ph = None
            for h in self.handlers:
                self.log.debug("Finding handler. Checking %s" % h.name)
                if h.name == profile:
                    ph = h
                    break

            if ph:
                self.log.debug("Found handler %s. Getting proxypath..." %
                               ph.name)
                pp = ph.getProxyPath()
                self.log.debug("Proxypath is %s" % pp)
                if pp:
                    break
        if not pp:
            subject = "Proxy problem on %s" % self.factory.factoryid
            messagestring = "Unable to get valid proxy from configured profiles: %s" % profilelist
            self.factory.sendAdminEmail(subject, messagestring)
            raise InvalidAuthFailure("Problem getting proxy for profile %s" %
                                     profilelist)

        return pp

#
#   API for SSHKeyHandler
#

    def getSSHKeyPair(self, profile):
        """
         Returns tuple (public, private, pass) key/phrase string from profile. 
        """
        pass

    def getSSHKeyPairPaths(self, profile):
        """
        Returns tuple (public, private, pass) key/passfile paths to files from profile. 
        """
        h = self._getHandler(profile)
        pub = h.getSSHPubKeyFilePath()
        priv = h.getSSHPrivKeyFilePath()
        pasf = h.getSSHPassFilePath()
        self.log.info('Got file paths for pub, priv, pass for SSH profile %s' %
                      profile)
        return (pub, priv, pasf)


#
#   API for GSISSHKeyHandler
#

    def getGSISSHKey(self, profile):
        """
        Returns GSI proxy string from profile
        """
        pass

    def getGSISSHKeyPaths(self, profile):
        """
        Returns GSI proxy (private key) from path as a string
        """
        h = self._getHandler(profile)
        priv = h.getGSISSHPrivKeyFilePath()
        self.log.info('Got file paths for proxy for GSISSH profile %s' %
                      profile)
        return priv

    def _getHandler(self, profile):
        """
        
        """
        handler = None
        for h in self.handlers:
            self.log.debug("Finding handler. Checking %s" % h.name)
            if h.name == profile:
                self.log.debug("Found handler for %s" % h.name)
                handler = h
        if handler is None:
            raise InvalidAuthFailure('No handler for %s ' % profile)
        return handler