CMDB--autoclient
autoclient
1.项目目录结构规划
bin:项目启动文件
conf:配置文件
lib:引入第三方库,库文件
src:业务逻辑
2.高级配置文件的实现
实现的核心代码:
集成全局的配置
for k in dir(global_settings):
if k.isupper():
v = getattr(global_settings, k)
setattr(self, k, v)
集成自定制的配置
for k in dir(config):
if k.isupper():
v = getattr(config, k)
setattr(self, k, v)
3.项目实现方案以及解决方案:
3.1首先面向过程的问题:
写起来简单容易,但是问题在于:面向过程的编程思想,不利于将来的维护和拓展,并且业务逻辑代码在start.py文件中,不符合高内聚低耦合原则
原则就是:各个模块或者各个类以及函数之间都是独立的
3.2可插拔式采集解决上述问题,将每个模块定义一个文件
硬件,主板,cpu....
代码写起来,start.py文件执行文件里面,一个个导入插件,一个个实例化
由于查找需求,不要查的文件需要注释掉,这里参考的是django的中间件概念,从路径下导入一个个类,实现可插拔式的采集(通过#注释)
PLUGINS_DICT = {
'basic' : 'src.plugins.basic.Basic',
'cpu' : 'src.plugins.cpu.Cpu',
'disk' : 'src.plugins.disk.Disk',
'board' : 'src.plugins.board.Board',
'memory' : 'src.plugins.memory.Memory',
}
将plugins变成一个包,定义一个类PluginsManager,设置一个方法,execute ---从配置文件中读取要采集的插件信息, 并且执行。在start.py文件中不按照原先的导入路径,导入这个管理采集插件的类,执行实例化,并且执行下面的execute的方法
for k, v in self.plugins_dict.items():
ret = {"status":None, 'data':None}
'''
k: basic
v: src.plugins.basic.Basic
'''
问题来了,将这个v怎么解决 ,切分
module_path, class_name = v.rsplit('.',1) ### ['src.plugins.basic', 'Basic']
由于切下来的是字符串,不可以from module_path import class_name
如何将字符串形式的模块导入进来-----importlib,其中里面有个模块import_module
response={}
for k,v in self.plugins_dict.items():
module_path,class_name=v.rsplit('.',1)
m=importlib.import_module(module_path)
cls=getattr(m,class_name)
res=cls().process()
response[k]=res
return response
3.3 代码采集冗余:
解决方法1:继承,写一个函数--------缺点每次新加的插件就比较麻烦要继承
解决方案2:init.py文件中,写入一个command方法。将函数作为一个参数传进去,也就是函数的参数地址
def command(self, cmd):
if self.mode == 'agent':
import subprocess
res = subprocess.getoutput(cmd)
return res
elif self.mode == 'ssh':
import paramiko
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.200.30', port=22, username='root', password='997997')
# 执行命令
stdin, stdout, stderr = ssh.exec_command(cmd)
# 获取命令结果
result = stdout.read()
# 关闭连接
ssh.close()
return result
elif self.mode == 'salt':
import salt.client
local = salt.client.LocalClient()
result = local.cmd('c2.salt.com', 'cmd.run', [cmd])
return result
else:
raise Exception ('只支持agent/ssh/salt模式')
命令采集完了将数据进行分析,每个插件写一个parse分析函数
4.debug开发模式:
命令执行,将结果拿到放到文件夹files文件里面,读取到项目里面,运行开发模式下代码
5.采集的代码,报错的信息完整提交
import traceback
def run():
try:
int('asasda')
except Exception as e:
print(traceback.format_exc())
run()
##可以拿到完整的报错信息
程序的道路上一去不复返