简单cmdb
项目开篇
CMDB是运维自动化项目,它可以减少人工干预,减少人工成本。
装机、实时监控、自动化部署,建立在它们的基础上是资产信息变更记录(资产管控自动进行汇报)
在对获取资产信息时,简述有四种方案。
方案A(Agent方法,基于Shell命令实现)
Agent方式,可以将服务器上面的Agent程序作定时任务,定时将资产信息提交到指定API录入数据库
优点:速度快 缺点:需要为每台服务器部署一个Agent程序
方案B(SSH形式,基于Paramiko模块)
中控机在获取未采集资产信息的服务器(服务器主机名,密码),依赖于Paramiko(py模块)通过SSH方式去获取
优点:无Agent 缺点:速度慢
如果在服务器较少的情况下,可应用此方法
import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname='c1.salt.com', port=22, username='wupeiqi', password='123') # 执行命令 stdin, stdout, stderr = ssh.exec_command('df') # 获取命令结果 result = stdout.read() # 关闭连接 ssh.close()
方案C(RPC形式,基于saltstack第三方工具)
此方案本质上和第二种方案大致是差不多的流程,中控机在获取到未采集资产信息的服务器(主机名),再而将命令放入一个队列中,服务器来获取。服务器将结果放入另一个队列中,中控机获取将服务信息发送到API进而录入数据库。
import salt.client local = salt.client.LocalClient() local.cmd('*', 'cmd.run', ['whoami'])
优点:快,开发成本低 缺点:依赖于第三方工具
方案D(基于pubpet,了解)
省略号...
小结:
- 采集资产信息有三种不同的形式
- API提供相关处理的接口
- 管理平台为用户提供可视化操作
程序可插拔机制
关于程序的可插拔机制。
开发一套程序时,要使其有充分的扩展性。接下来可以写一些伪代码...
假设项目名为AutoClient, 目录结构如下:
AutoClient/
|-- bin/
| |-- auto_client.py
|-- config/
| |-- settings.py
|-- lib/
| |--
|-- log/
| |-- error.log
| |-- run.log
|-- src/
| |-- plugins/
| |-- __init__.py
| |-- base.py
| |-- cpu.py
| |-- disk.py
| |-- ...
| |-- package.py
| |-- scripts.py
|-- README
例如,采集资产信息有上述描述的三种形式(agent,ssh,salt,),而将要做的一件事就是要让程序兼容这三种形式
在配置文件中写一点东西、配置文件就先写这些(settings.py)
# 采集资产的方式,选项有:agent(默认), salt, ssh MODE = 'agent' # 采集硬件数据的插件 PLUGINS_DICT = { 'cpu': 'src.plugins.cpu.CpuPlugin', 'disk': 'src.plugins.disk.DiskPlugin', 'main_board': 'src.plugins.main_board.MainBoardPlugin', 'memory': 'src.plugins.memory.MemoryPlugin', 'nic': 'src.plugins.nic.NicPlugin', }
继而写一些公用的(base.py)
# 导入settings文件 from AutoCMDB.conf import settings class BasePlugin(object): def __init__(self): """ 验证配置文件 """ mode_list = ['agent', 'ssh', 'salt'] if settings.MODE in mode_list: self.mode = settings.MODE else: raise Exception('配置文件发生错误') def ssh(self, cmd): pass def agent(self, cmd): pass def salt(self, cmd): pass def shell_cmd(self, cmd): """ 执行判断模式 :param cmd: :return: """ if self.mode == 'agent': result = self.agent(cmd) elif self.mode == 'ssh': result = self.ssh(cmd) else: result = self.salt(cmd) return result def execute(self): """ 执行判断平台 :return: 目标 拿到资产采集信息 """ result = self.shell_cmd('查看平台命令') if result == 'win': return self.window() elif result == 'linux': return self.linux() else: raise Exception('只支持windows') def window(self): raise Exception('...') def linux(self): raise Exception('...') class DiskPlugin(BasePlugin): def window(self): # 正则表达式匹配想要的信息 return '硬盘' def linux(self): # 正则表达式匹配想要的信息 return '硬盘' obj = DiskPlugin() result = obj.execute()
上述代码看似很多,但是这样写有什么好处或者说有什么用意
这样写程序的可插拔性就很强了,例如采集硬盘信息只需在DiskPlugin的window或者linux写代码,此时不用再去判断什么模式,只需要将命令传输即可
其次,做内存、CPU、网卡信息按照硬盘那样去写。而后将各个单独存入相应的文件,这更使程序简洁明了。
接下来呢,想要同时获取CPU、内存、网卡的资产信息
那么配置文件的插件PLUGINS_DICT可以派上用场了。依托于它,可根据反射去做(package.py)
# 导入settings from AutoCMDB.conf import settings # 动态导入模块 import importlib response = {} for k, v in settings.PLUGINS_DICT.items(): moudle_path, cls_name = v.rsplit('.', 1) if hasattr(importlib.import_module(moudle_path), cls_name): func = getattr(importlib.import_module(moudle_path), cls_name) response[k] = func().execute() # 这样response便封装了所有资产信息
CMDB数据库设计