简单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数据库设计

原文地址:https://www.cnblogs.com/jasonenbo/p/6730805.html