def buildNetwork(self,config_path):
     config,ETC_DIR = loadConfig()
     
     self.servers=ServerNetwork()
     
     #build servers
     SERVER_DIR = config.get('main', 'SERVER_DIR')
     serverConfigPath = os.path.join(ETC_DIR,SERVER_DIR)
     self.mainDaemon.debug("Loading:"+str(serverConfigPath))
     serverConfigFileList = os.listdir(serverConfigPath)
     for serverConfigFile in serverConfigFileList:
         serverConfigFile = os.path.join(serverConfigPath,serverConfigFile)
         serverConfig = SafeConfigParser()
         serverConfig.read(serverConfigFile)
         #server = serverConfig.get('server', 'name')
         server = self._getNameFromFilePath(serverConfigFile)
         
         def buildServerObj(objNames,builderCallback):
             ''' Parse the serverObj field
             
             :param objNames: the name of the field we are parsing
             :param builderCallback: The function that takes the server config and name, building the object
             :return: A list of the server objects 
             '''
             #Handle a list or single string outlet
             try:
                 outlets = serverConfig.get('server', objNames)
             except NoOptionError:
                 outlets = "[]" 
                 
             if outlets.startswith("["):
                 outlets = json.loads(outlets)
             else:
                 outlets=[outlets]
             outletList=[]
             for outlet in outlets:
                 outletList.append(builderCallback(serverConfig,outlet,serverConfigPath))
             return outletList
         
         outletList = buildServerObj('outlets',self.__makeOutlet)
         testerList = buildServerObj('tests',self.__makeTester)
         controlList = buildServerObj('controls',self.__makeControl)
         
                     
         #Make the server with the outlets and testers
         self.servers.addServer(ServerNode(server,outletList,testerList,controlList))
     
     #add dependencies to our server forest
     for serverConfigFile in serverConfigFileList:
         serverConfigFile = os.path.join(serverConfigPath,serverConfigFile)
         serverConfig = SafeConfigParser()
         serverConfig.read(serverConfigFile)
         
         #server = serverConfig.get('server', 'name')
         server = self._getNameFromFilePath(serverConfigFile)
         
         #sanitize input
         if serverConfig.get("server","dependencies") != "":    
             dependencies = json.loads(serverConfig.get("server","dependencies"))
         else:
             dependencies=[]
         
         for dependency in dependencies:
             try:
                 self.servers.addDependency(server, dependency)
             except DependencyException as e:
                 if DependencyException:
                     self.mainDaemon.debug(e.msg +":" + str(e.list))
                 raise e
     return self.servers
class ServerNetworkFactory(object):
    '''
    A class to take the config file folder and turn it in to a server network
    
    :param MainDaemon: the :doc:`MainDaemon` singletron, only used for debug output
    '''
    def __init__(self,MainDaemon,reportDependencyexceptions=True):
        '''
        Constructor
        '''
        self.mainDaemon = MainDaemon
        return
    
    def _getNameFromFilePath(self,path):
        return os.path.splitext(os.path.basename(path))[0]
    
    def buildNetwork(self,config_path):
        config,ETC_DIR = loadConfig()
        
        self.servers=ServerNetwork()
        
        #build servers
        SERVER_DIR = config.get('main', 'SERVER_DIR')
        serverConfigPath = os.path.join(ETC_DIR,SERVER_DIR)
        self.mainDaemon.debug("Loading:"+str(serverConfigPath))
        serverConfigFileList = os.listdir(serverConfigPath)
        for serverConfigFile in serverConfigFileList:
            serverConfigFile = os.path.join(serverConfigPath,serverConfigFile)
            serverConfig = SafeConfigParser()
            serverConfig.read(serverConfigFile)
            #server = serverConfig.get('server', 'name')
            server = self._getNameFromFilePath(serverConfigFile)
            
            def buildServerObj(objNames,builderCallback):
                ''' Parse the serverObj field
                
                :param objNames: the name of the field we are parsing
                :param builderCallback: The function that takes the server config and name, building the object
                :return: A list of the server objects 
                '''
                #Handle a list or single string outlet
                try:
                    outlets = serverConfig.get('server', objNames)
                except NoOptionError:
                    outlets = "[]" 
                    
                if outlets.startswith("["):
                    outlets = json.loads(outlets)
                else:
                    outlets=[outlets]
                outletList=[]
                for outlet in outlets:
                    outletList.append(builderCallback(serverConfig,outlet,serverConfigPath))
                return outletList
            
            outletList = buildServerObj('outlets',self.__makeOutlet)
            testerList = buildServerObj('tests',self.__makeTester)
            controlList = buildServerObj('controls',self.__makeControl)
            
                        
            #Make the server with the outlets and testers
            self.servers.addServer(ServerNode(server,outletList,testerList,controlList))
        
        #add dependencies to our server forest
        for serverConfigFile in serverConfigFileList:
            serverConfigFile = os.path.join(serverConfigPath,serverConfigFile)
            serverConfig = SafeConfigParser()
            serverConfig.read(serverConfigFile)
            
            #server = serverConfig.get('server', 'name')
            server = self._getNameFromFilePath(serverConfigFile)
            
            #sanitize input
            if serverConfig.get("server","dependencies") != "":    
                dependencies = json.loads(serverConfig.get("server","dependencies"))
            else:
                dependencies=[]
            
            for dependency in dependencies:
                try:
                    self.servers.addDependency(server, dependency)
                except DependencyException as e:
                    if DependencyException:
                        self.mainDaemon.debug(e.msg +":" + str(e.list))
                    raise e
        return self.servers
    
    def __makeServerObj(self,objGeneratorName,objGeneratorFolder,objGeneratorPackageName,objGeneratorSubclass,objGeneratorNotFoundException,serverConfig,objSection,serverConfigPath):
        ''' Make an objSection from the config file path of an objSection, and the required socket
        
        :param serverConfig config ini path to the socket
        :param objSection a string to get the objSection objSection
        :param serverConfigPath:
        :returns an objSection type socket
        '''
        
        #get server specific config for objSection (socket number etc)
        outletParams = turpleList2Dict(serverConfig.items(objSection))
        
        #get objSection type so we can pull its config data
        outletConfig=serverConfig.get(objSection, objGeneratorName)
        outletConfigPath = os.path.join(objGeneratorFolder,outletConfig + ".ini")
        outletConfig = SafeConfigParser()
        
        #Create the objSection with server params and objSection config 
        outletConfig.read(outletConfigPath)
        outletConfigDict={}
        self.mainDaemon.debug("Loading:"+str(outletConfigPath))
        for section in outletConfig.sections(): 
            outletConfigDict[section] = turpleList2Dict(outletConfig.items(objGeneratorName))
        
        #Find from type the kind of objSection
        outlets = load(objGeneratorPackageName,subclasses=objGeneratorSubclass)
        outletType = outletConfigDict[objGeneratorName]['type']
        for outletClass in outlets:
            if outletClass.__name__ == outletType:
                return outletClass(objSection,outletConfigDict,outletParams)
        raise objGeneratorNotFoundException(outletConfigPath,outletType)
    
    def _getClassDictIndex(self,package,subclass):
        ''' Get a list of modules
        
        :param package: The package path to search
        :param subclass: The subclass to search for 
        :return: A list of the names of the classes ''' 
        classTypeDict = {}
        outlets = load(package,subclasses=subclass)
        for outletClass in outlets:
            if not outletClass.__name__ in classTypeDict:
                classTypeDict[outletClass.__name__] = outletClass.__doc__
        return classTypeDict
    
    def getOutletsDictIndex(self):
        ''' Get the index of available PDU types
        
        :return: A list of strings of PDU type names
        '''
        return self._getClassDictIndex(OUTLETS_PACKAGE,OutletTemplate)

    def getTestersDictIndex(self):
        ''' Get the index of available testers types
        
        :return: A list of strings of tester type names
        '''
        return self._getClassDictIndex(TESTERS_PACKAGE,TemplateTester)
    
    def getControllersDictIndex(self):
        ''' Get the index of available controller types
        
        :return: A list of strings of controller type names
        '''
        return self._getClassDictIndex(CONTROLLERS_PACKAGE,ControllerTemplate)
    
    def __makeOutlet(self,serverConfig,outlet,serverConfigPath):
        return self.__makeServerObj("pdu",self.mainDaemon.OUTLETS_DIR,OUTLETS_PACKAGE,OutletTemplate,OutletTypeNotFound,serverConfig,outlet,serverConfigPath)
    
    def __makeTester(self,serverConfig,tester,serverConfigPath):
        return self.__makeServerObj("tester",self.mainDaemon.TESTERS_DIR,TESTERS_PACKAGE,TemplateTester,TesterTypeNotFound,serverConfig,tester,serverConfigPath)
    
    def __makeControl(self,serverConfig,control,serverConfigPath):
        return self.__makeServerObj("controller",self.mainDaemon.CONTROLLERS_DIR,CONTROLLERS_PACKAGE,ControllerTemplate,ControllerTypeNotFound,serverConfig,control,serverConfigPath)