需求
在CMDB系统中,我们需要对资产进行采集和资产入库,包括serverBasic、disk、memory、nic信息等,客户端需要采集这些硬件的信息,服务端则负责资产入库,但是需要采集的硬件并不是固定不变的,我们需要根据实际情况适当的添加或者减少硬件信息的采集,所以在生产环境中,我们把每个硬件信息的采集和入库做成插件,相互独立,可在配置文件中增减或者移除。
 
知识点:
字符串的形式导入插件方式:(字符串的格式也就是插件这个类的路径,这种格式正好也是类的导入格式)
# 根据字符串形式导入模块,并且找到其中的类并执行
import importlib

v = "src.plugins.nic.Nic"
module_path,cls_name = v.rsplit('.',maxsplit=1)
m = importlib.import_module(module_path)
cls = getattr(m,cls_name)
obj = cls()
obj.process()
 
 
设计: (参考django中间件的加载方式)
在settings配置文件中做好插件配置,在加载插件的方法中,使用字符串形式导入类的方法,循环加载各个插件。
settings.py
Django【设计】可插拔的插件方式实现
 
plugins/__init__.py下的加载插件方法:
def exec_plugin(self):
        server_info = {}
        for k,v in self.plugin_items.items():
            # 找到v字符串:src.plugins.nic.Nic,
            # src.plugins.disk.Disk
            info = {'status':True,'data': None,'msg':None}
            try:
                module_path,cls_name = v.rsplit('.',maxsplit=1)
                module = importlib.import_module(module_path)
                cls = getattr(module,cls_name)

                if hasattr(cls,'initial'):
                    obj = cls.initial()
                else:
                    obj = cls()
                ret = obj.process(self.exec_cmd,self.test)
                info['data'] = ret
            except Exception as e:
                info['status'] = False
                info['msg'] = traceback.format_exc()

            server_info[k] = info
        return server_info

 

 

 
应用实例(及整个业务逻辑):
客户端
执行流程:run.py >> script.py >> client.py >> plugins
run.py,设置全局变量,主函数启动
import sys
import os

BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASEDIR)

# 设置全局变量(手动配置路径)
os.environ['AUTO_CLIENT_SETTINGS'] = "conf.settings"

# # 导入插件管理类
# from src.plugins import PluginManager

from src import script

if __name__ == '__main__':
    script.start()
View Code
 
script.py,约束采集信息模式(agent,ssh,salt),兼容三种模式
from lib.config import settings
from .client import AgentClient
from .client import SaltSshClient

def start():
    # 这个函数用来判断模式,并约束可选模式
    if settings.MODE == 'AGENT':
        obj = AgentClient()
    elif settings.MODE == "SSH" or settings.MODE == 'SALT':
        obj = SaltSshClient()
    else:
        raise Exception('模式仅支持:AGENT/SSH/SALT')
    obj.exec()
View Code
 

相关文章: