CMDB开发-资产采集功能开发

一:资产采集功能开发
①agent方式

通过在客户端写一些脚本,然后加入到定时任务,每隔一段时间执行一下命令采集硬件信息,发给API,API根据收到的数据更新数据库相关信息。

思路核心代码(未完善)

import subprocess
import requests
# request是第三方模块,pip3 install requests

# ################## 采集数据 ##################
result = subprocess.getoutput('ipconfig')
# result要做正则处理获取想要数据

# 整理资产信息
data_dict ={
    'nic': {},
    'disk':{},
    'mem':{}
}

# ################## 发送数据给API ##################
requests.post('http://www.127.0.0.1:8000/assets.html',data=data_dict)
②SSH类的方式

先去API那,API从数据库中取出没有进行资产采集的主机列表,然后去对应的主机列表里边基于paramiko模块执行命令,收集到数据,把数据发给API,然后进行数据库的更新。

思路核心代码(未完善)

# 基于paramiko模块, pip3 install paramiko
import requests
import paramiko

# ################## 获取今日未采集主机名 ##################
result = requests.get('http://www.127.0.0.1:8000/assets.html')
result = ['c1.com','c2.com']


# ################## 通过paramiko连接远程服务器,执行命令 ##################
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.14.36', port=22, username='wupeiqi', password='123')

# 执行命令
stdin, stdout, stderr = ssh.exec_command('df')

# 获取命令结果
result = stdout.read()

# 关闭连接
ssh.close()
print(result)

data_dict = {result}

# ################## 发送数据 ##################
requests.post('http://www.127.0.0.1:8000/assets.html',data=data_dict)
③基于saltstack

先去API那里,API从数据库里边拿到没有采集资产的主机给中控机,然后基于saltstack去对应的主机那里执行命令,saltstack把要执行的命令先放到队列里,然后主机执行队列里面对应的命令,把命令执行结果(数据)放到另外一个队列里边,saltstack再去这个队列里边拿数据,然后发给API,API进行数据的更新。

面试问为什么不考虑使用ansible?

答:因为ansible就是基于ssh的,跟第二种是差不多的,我把他归到了ssh类里边

要先下载saltstack,去阿里镜像站epel源和网络源配置好就可以下载
大致流程

# 1. 安装saltstack
# rpm --import https://repo.saltstack.com/yum/redhat/6/x86_64/latest/SALTSTACK-GPG-KEY.pub

"""
        Master: yum install salt-master
       Master准备:
            a. 配置文件,监听本机IP
                vim /etc/salt/master
                interface: 本机IP地址
            b. 启动master
                /etc/init.d/salt-master start


        Slave: yum install salt-minion
        Slave准备:
            a. 配置文件,连接那个master
                vim /etc/salt/minion
                master: 远程master地址
            b. 启动slave
                /etc/init.d/salt-minion start

2. 创建关系
    查看
    Master:salt-key -L
        Accepted Keys:
        Denied Keys:
        Unaccepted Keys:
            c1.com
            c2.com
            c3.com
        Rejected Keys:
    接受
    Master:salt-key -a c1.com
        Accepted Keys:
            c1.com
            c2.com
        Denied Keys:
        Unaccepted Keys:
            c3.com
        Rejected Keys:


3. 执行命令
    master:
        salt 'c1.com' cmd.run 'ifconfig'

    import salt.client
    local = salt.client.LocalClient()
    result = local.cmd('c2.salt.com', 'cmd.run', ['ifconfig'])

"""
# ################## 获取今日未采集主机名 ##################
#result = requests.get('http://www.127.0.0.1:8000/assets.html')
# result = ['c1.com','c2.com']


# ################## 远程服务器执行命令 ##################
# import subprocess
# result = subprocess.getoutput("salt 'c1.com' cmd.run 'ifconfig'")
#
# import salt.client
# local = salt.client.LocalClient()
# result = local.cmd('c2.salt.com', 'cmd.run', ['ifconfig'])


# ################## 发送数据 ##################
# requests.post('http://www.127.0.0.1:8000/assets.html',data=data_dict)
CMDB插件开发

目录结构,主目录下主要有这几个文件夹,src是拿来写逻辑代码的,

  • src下面的plugins文件夹是存放插件的,主要是为了可插拔,我们写好一个Base类,然后未来想添加采集网卡信息,内存信息或者硬盘信息等,就再创建相应的文件,里面写上对应的类,继承自Base类就好了,
  • package文件实现将采集到的数据进行打包,我们每加一个插件,就去配置文件里面记录上,然后package里边通过反射进行打包数据,否则每次加插件都要改package文件,容易出问题。
    在这里插入图片描述
CMDB采集资产
CMDB采集资产数据标识规定

我觉得每个公司在开发CMDB的时候,或者说一个运维平台的时候,我们需要先指定好规则,让大家去遵守,设计CMDB首先要确定资产数据的唯一标识,IP这个会变的,不行,一开始想用SN号,也就是主板上的序列号,这个对物理机来讲是唯一的,但是公司里面有虚拟机的,所以不行,我用了主机名来做标识,约定好主机名不能改,大部分情况下也是不能随便改了,但是如果某个需求必须改,又出现问题了,所以我先把第一次的主机名先放到文件里边,到时候去这个文件里边拿,那么后面主机名改了也不影响了。系统重装的时候怎么办?系统重装如果是批量装机,我们点按钮,我们是可以看到那个主机名的。

知识拾遗之线程线程池

进程池与线程池,线程池是Python3才有的

from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import ProcessPoolExecutor
import time
def task(arg):
    print(arg)
    time.sleep(1)

# pool = ProcessPoolExecutor(5)
pool = ThreadPoolExecutor(5)

for i in range(50):
    pool.submit(task,i)

使用线程池开多个线程来向API发数据。线程池规定了每次最多开多少个线程,防止线程开多了,上下文切换,也就是CPU在线程之间切换的频率太快了,相当于是看一本书,没看几个字就要传给下一个人。

class AutoSSH(AutoBase):
    def process(self):
        """
        根据主机名获取资产信息,将其发送到API
        :return:
        """
        task = self.get_asset() # 采集到数据
        if not task['status']:
            # 打印错误日志,true表示正确运行信息,false表示错误信息
            Logger().log(task['message'], False)

        pool = ThreadPoolExecutor(10)
        for item in task['data']:
            hostname = item['hostname']
            pool.submit(self.run, hostname) # 开多线程调用run方法把数据发送到API
        pool.shutdown(wait=True)
采集资产之日志记录

回调函数,获取资产,发到API,API可能出错呀,这个出错我们不能草草了之,什么时候出错,或者运行正常了,都用日志记录下来,并且日志存储的路径可以在配置文件里边改。取到公司的时候,应用程序的目录要做迁移的时候,千万不能把日志写死在某个文件上,否则随着程序的运行,越来越大越来越大就不行了

def callback(self, status, response):
   """
   提交资产后的回调函数
   :param status: 是否请求成功
   :param response: 请求成功,则是响应内容对象;请求错误,则是异常对象
   :return:
   """
   if not status:
       Logger().log(str(response), False)
       return
   ret = json.loads(response.text)
   if ret['code'] == 1000:
       Logger().log(ret['message'], True)
   else:
       Logger().log(ret['message'], False)
序列号发送数据到API的数据

发送数据到API,不能传对象,像字典,列表,这些可以进行json序列化,但是如果想传我们自己写的类给API怎么办,这时候需要进行序列化的自定制

import json
from datetime import date
from datetime import datetime

class JsonCustomEncoder(json.JSONEncoder):
    def default(self, field):
        if isinstance(field, datetime):
            return field.strftime('%Y-%m-%d %H')
        elif isinstance(field, date):
            return field.strftime('%Y-%m-%d')
        elif isinstance(field, Response):
            return field.__dict__ # 类的字典
        else:
            return json.JSONEncoder.default(self, field)

class Response(object):
    def __init__(self):
        self.status =True
        self.data = "asdf"
data = {
    'k1': 123,
    'k2': datetime.now(),
    'k3': Response()
}
ds = json.dumps(data, cls=JsonCustomEncoder)
print(ds)
使用request模块汇报资产数据
request模块使用介绍

利用request模块可以吧数据去采集到通过URL可以以POST或者get请求发数据给api

  • get请求是以params参数传过去的
  • 通过json参数发送数据在服务端里面可以使用request.body里面去获取数据,使用request.post/get是获取不到的
import requests
host_data = {
    'status': True,
    'data':{
        'hostname': 'c1.com',
        'disk': {'status':True,'data': 'xxx'},
        'mem': {'status':True,'data': 'xxx'},
        'nic': {'status':True,'data': 'xxx'},
    }
}

# response封装了请求发过去之后返回来的所有的值
response = requests.post(
    url='http://127.0.0.1:8000/api/asset/',
    json=host_data,
    headers={'authkey': authkey_time}   # 从请求头里边发过去
)
print(response.text)   # 它的文本信息


# requests.get(url='http://127.0.0.1:8000/api/asset/?k1=123')
# requests.get(url='http://127.0.0.1:8000/api/asset/',params={'k1':'v1','k2':'v2'})
# requests.post(
#     url='http://127.0.0.1:8000/api/asset/',
#     params={'k1':'v1','k2':'v2'}, # GET形式传值
#     data={'username':'1123','pwd': '666'}, # POST形式传值
#     headers={'a':'123'} # 请求头数据
# )
API认证

发送数据给API的时候,要注意的问题,如果随便一个人都可以往API发送数据,这样肯定不好,所以必须要做到,API只接受我们采集的服务器的资产信息,

解决这个问题的思路:
最容易想到的是把数据进行加密,然后发给后台,后台解密就行了,这种方式好不好,好,别人拿到我们的数据也不知道是什么,但是这个加密和解密都要时间,数据是很敏感的时候,可以这样做,但是我们的资产并不是那么敏感的信息,

  1. 最开始的时候,我是打算在客户端发资产信息到API的时候,在请求头里边多发一个字符串过来,然后在API里边从request.META把这个字符串取出来做验证,如果字符串不对或者没有我就不允许别人提交数据过来
  2. 但是这样有一个缺点,就是假如黑客拿到了这个请求头的字符串,那么就可以往我们这发数据了,所以我这个字符串必须一直在变,因此我客户端在请求头里面带上auth_key的时候,这个auth_key是使用一串随机字符串和当前的时间进行md5加密,就可以实现动态的auth_key,实现这个动态的auth_key之后还不行,设想一种情况,虽然我的auth_key是动态的,但是其中有一个key被破解了,它还是能登录上,因此我的API先获取一下服务端的当前时间,客户端把auth_key发过来的时候,把它那个创建auth_key的那个时间戳也发过来,假如我服务端的时间戳减去客户端的时间戳,这个时间间隔太长了,比如超过10s说明就不是我们的资产信息了,我就不把数据发过来。假如在这10s之内黑客就破解了怎么办了,
  3. 解决办法是我把这些发过的这些请求头和URL的数据放到Redis数据库里边,设置一个10s的超时时间,然后通过了时间验证后我去Redis数据库里边比对一下,如果已经有相同的数据了,说明是黑客发过来的(因为如果是我们自己发的,每次都会变的),这样就解决了这个问题,
  4. 这两个防护都通过之后,在进行Md5值加密,把客户端发过来的客户端的时间戳和那串字符串,进行MD5值加密,如果生成的字符串和客户端发过来的字符串相同,那么就认为是OK的
CMDBuild 是一个开源的配置管理数据库 (CMDB) 系统,用于管理 IT 资产和服务。下面是 CMDBuild 的搭建和使用步骤: 1. 安装 Java 运行环境 CMDBuild 是基于 Java 开发的 Web 应用程序,所以需要先安装 Java 运行环境。你可以从 Oracle 官网下载安装包并按照提示安装即可。 2. 下载 CMDBuild 你可以从 CMDBuild 官网下载最新的稳定版本。下载完成后,解压缩到你想要安装的目录下。 3. 安装 PostgreSQL 数据库 CMDBuild 需要使用 PostgreSQL 数据库才能正常运行。你可以从 PostgreSQL 官网下载安装包并按照提示安装。 4. 创建 CMDBuild 数据库 在安装完 PostgreSQL 数据库之后,你需要创建一个新的数据库来存储 CMDBuild 的数据。在 PostgreSQL 命令行界面输入以下命令: ``` createdb -U postgres -O postgres -E UTF8 cmdbuild ``` 其中,cmdbuild 是你想要创建的数据库名。 5. 修改 CMDBuild 配置文件 进入 CMDBuild 安装目录下的 `WEB-INF` 文件夹,修改 `classes` 文件夹下的 `database.conf` 文件。将以下内容修改为你的 PostgreSQL 数据库信息: ``` # Database connection settings db.url=jdbc:postgresql://localhost:5432/cmdbuild db.username=postgres db.password=postgres ``` 6. 启动 CMDBuild 在 CMDBuild 安装目录下运行以下命令启动 CMDBuild: ``` java -jar cmdbuild.war ``` 在启动成功后,你可以在浏览器中访问 `http://localhost:8080/cmdbuild/` 来使用 CMDBuild。 以上就是 CMDBuild 的搭建和使用步骤。希望对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值