cmdb采集数据的版本

在局部配置文件中配置MODE=‘ agent‘,或者MODE=‘ssh’,或者MODE=‘’saltstack ‘,  实现只需要修改这个配置,就会使用对应的方案进行采集数据

第一种版本:

启动文件中直接判断

start.py

from lib.config.config import settings
import subprocess

from src.plugins import board,disk,memory
if __name__ == ‘__main__‘:
    mode = settings.MODE

    if mode == ‘agent‘:
        res = subprocess.getoutput(‘ifconfig‘)
        ip = res[30:50]
        print(ip)

    elif mode == ‘ssh‘:
        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=‘root‘, password=‘123‘)
        # 执行命令
        stdin, stdout, stderr = ssh.exec_command(‘ifconfig‘)
        # 获取命令结果
        result = stdout.read()
        print(result)
        # 关闭连接
        ssh.close()
    else:
        import salt.client

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

如果采集不同的信息,还需要一次次的修改命令并且启动文件不能写业务逻辑代码

存在的问题:

   1. 面向过程的写法, 代码不容易扩展, 后续不好维护

   2. 不符合软件设计的原则  ()      高内聚低耦合         a. 这是一个代码的设计思想         b. 在写函数或者类的时候, 代码中尽量不要多一行和次函数或者 类无关的代码

         原则:            def getUserInfo():               ### 获取用户信息的函数

               getOrderDetail()               pass

            def getOrderDetail():               ### 获取订单详情的代码         

改进的方法:???

面向对象的思想??

在src文件夹中创文件夹plugins,将所需要采集的信息如ip,cpu,内存等信息分成一个个py文件各个写入自己的类??

board.py 收集服务器ip的文件

from lib.config.config import settings
import subprocess

class Board():
    def process(self):
        # return "board info"

        if settings.MODE == ‘agent‘:
            res = subprocess.getoutput(‘ifconfig‘)
            print(res[30:50])
        elif settings.MODE == ‘ssh‘:
            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=‘root‘, password=‘123‘)
            # 执行命令
            stdin, stdout, stderr = ssh.exec_command(‘ifconfig‘)
            # 获取命令结果
            result = stdout.read()
            print(result)
            # 关闭连接
            ssh.close()
        else:
            import salt.client

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

        return  "boaed_info"

disk.py 

from lib.config.config import settings
import subprocess
class Disk():
    def process(self):
        # return "disk info"

        if settings.MODE == ‘agent‘:
            res = subprocess.getoutput(‘df -h‘)
            print(res[30:50])
        elif settings.MODE == ‘ssh‘:
            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=‘root‘, password=‘123‘)
            # 执行命令
            stdin, stdout, stderr = ssh.exec_command(‘df -h‘)
            # 获取命令结果
            result = stdout.read()
            print(result)
            # 关闭连接
            ssh.close()
        else:
            import salt.client

            local = salt.client.LocalClient()
            result = local.cmd(‘c2.salt.com‘, ‘cmd.run‘, [‘df -h‘])

        return "disk_info"

memory.py

class Memory():
    def process(self):
        # return ‘memory info‘

        if settings.MODE == ‘agent‘:
            res = subprocess.getoutput(‘cat memory‘)
            print(res[30:50])
        elif settings.MODE == ‘ssh‘:
            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=‘root‘, password=‘123‘)
            # 执行命令
            stdin, stdout, stderr = ssh.exec_command(‘cat memory‘)
            # 获取命令结果
            result = stdout.read()
            print(result)
            # 关闭连接
            ssh.close()
        else:
            import salt.client

            local = salt.client.LocalClient()
            result = local.cmd(‘c2.salt.com‘, ‘cmd.run‘, [‘cat memory‘])

        return "memory_info"

然后在start.py文件中调用

from src.plugins import board,disk,memory
if __name__ == ‘__main__‘:

    print(board.Board.process())
    print(disk.Disk.process())
    print(memory.Memory.process())
存在的问题:    不是特别的方便

版本2:

解决的方法:

   参考django的中间件

   实现可插拔式的采集

在custom_settings局部文件中写人

PLUGINS_DICT = {

    ‘board‘: ‘src.plugins.board.Board‘,
    ‘disk‘: ‘src.plugins.disk.Disk‘,
    ‘memory‘: ‘src.plugins.memory.Memory‘,

}

在src文件夹中plugins文件夹中创一个__init__.py文件来管理插拔信息

__init__.py

from lib.config.config import settings

import importlib

#管理插件信息的类
class PluginsManger(object):

    def __init__(self):
        self.plugins_dict = settings.PLUGINS_DICT

    #读取配置文件中的pluginsdict, 并执行对应模块中的process方法
    def execute(self):
        response = {}
        for k,v in self.plugins_dict.items():
            ‘‘‘
          k:  board,...
          v:  src.plugins.board.Board   字符串
           ‘‘‘
            #1.导入模块路径
            moudle_path,class_name = v.rsplit(‘.‘, 1)
            #2.导入这个路径

            moudle_name = importlib.import_module(moudle_path)

            #3.导入对应的类
            classobj = getattr(moudle_name, class_name)

            #4.执行类下面对应的process方法

            res = classobj().process()
            response[k] = res
        return response

start.py

from src.plugins import PluginsManger

if __name__ == ‘__main__‘:
    res = PluginsManger().execute()
    print(res)
存在的问题:   代码过于冗余

解决的方法:

   a. 写一个父类, 此父类有一个公共方法, 执行对应的代码

   b. 就是以下这种方法

版本3:

??将采集数据的代码(也就是board,cpu,disk,memory中相同的代码)放入到__init__.py 中新创的函数__cmd_run中,然后将命令cmd当成传入,传入的方式就是在调用excute函数中执行调用process函数,然后在每个board,cpu,disk,memory类中process方法获取到这个函数,然后调用传入cmd,然后再抽离将每个方案采集数据的形式都分成一个个函数,再传入cmd

然后每个方案采集数据都不同,ssh需要传入username,password,port,host,   saltstack需要传入host,   agent什么都不需要传,所以在start文件调用PluginsManger类的时候需要传入host,然后将其变成对象属性,而ssh需要传入很多参数,就在custom_settings中传入,再将其变成对象的属性??

custom_settings.py

MODE = ‘agent‘

SSH_USERNAME = ‘root‘

SSH_PASSWORD = ‘123‘

SHH_PORT = 22

PLUGINS_DICT = {

    ‘board‘: ‘src.plugins.board.Board‘,
    ‘disk‘: ‘src.plugins.disk.Disk‘,
    ‘memory‘: ‘src.plugins.memory.Memory‘,

}

__init__.py

from lib.config.config import settings

import importlib
import subprocess

#管理插件信息的类
class PluginsManger(object):

    def __init__(self, hostname=None):
        self.plugins_dict = settings.PLUGINS_DICT
        self.hostname = hostname

        if settings.mode == ‘ssh‘:
            self.port = settings.SSH_PORT
            self.username = settings.SSH_USERNAME
            self.pwd = settings.SSH_PASSWORD

    #读取配置文件中的pluginsdict, 并执行对应模块中的process方法
    def execute(self):
        response = {}
        for k,v in self.plugins_dict.items():
            ‘‘‘
          k:  board,...
          v:  src.plugins.board.Board   字符串
           ‘‘‘
            #1.导入模块路径
            moudle_path,class_name = v.rsplit(‘.‘, 1)
            #2.导入这个路径

            moudle_name = importlib.import_module(moudle_path)

            #3.导入对应的类
            classobj = getattr(moudle_name, class_name)

            #4.执行类下面对应的process方法

            res = classobj().process(self.__cmd_run)
            response[k] = res
        return response

    def __cmd_run(self,cmd):
        if settings.MODE == ‘agent‘:
           return self.cmd_agent(cmd)
        elif settings.MODE == ‘ssh‘:
            return self.cmd_ssh(cmd)
        else:
            return self.cmd_salt(cmd)

    def cmd_agent(self,cmd):
        res = subprocess.getoutput(cmd)
        return res

    def cmd_ssh(self, cmd):
        import paramiko

        # 创建SSH对象
        ssh = paramiko.SSHClient()
        # 允许连接不在know_hosts文件中的主机
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        # 连接服务器
        ssh.connect(hostname=self.hostname, port= self.port, username=self.username, password=self.pwd)
        # 执行命令
        stdin, stdout, stderr = ssh.exec_command(cmd)
        # 获取命令结果
        result = stdout.read()

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

    def cmd_salt(self,cmd):
        command = "salt %s cmd.run %s" %(self.hostname,cmd)
        res = subprocess.getoutput(command)
        return res

board.py

class Board():
    def process(self, command_func):
        res = command_func(‘ifconfig‘)
        data = self.parse_output(res)
        return data

    def parse_output(self, res):
        pass

cpu.py

class Cpu():
    def process(self,command_func):
        command_func()

disk.py

class Disk():
    def process(self, command_func):
       command_func(‘df -h‘)

memory.py

class Memory():
    def process(self,command_func):
        command_func(‘cat memory‘)

from src.plugins import PluginsManger

if __name__ == ‘__main__‘:

    res = PluginsManger().execute()
    print(res)

start.py

MODE = ‘agent‘

SSH_USERNAME = ‘root‘

SSH_PASSWORD = ‘123‘

SHH_PORT = 22

PLUGINS_DICT = {

    ‘board‘: ‘src.plugins.board.Board‘,
    ‘disk‘: ‘src.plugins.disk.Disk‘,
    ‘memory‘: ‘src.plugins.memory.Memory‘,

}

custom_settings

from conf import custom_settings
from . import global_settings

class Settings():
    def __init__(self):
        ### 全局设置
        for key in dir(global_settings):
            if key.isupper():
                v = getattr(global_settings, key)  # 第一个是对象,第二个key
                setattr(self, key,
                        v)  # self代表的是当前的对象settings,key就是配置文件的大写的配置,v 就是self.配置的值,所以这样就可以通过settings这个对象点的方式获取到值

    ### 自定制配置
        for key in dir(custom_settings):
            if key.isupper():
                v = getattr(custom_settings, key)  # 第一个是对象,第二个key
                setattr(self, key,
                        v)  # self代表的是当前的对象settings,key就是配置文件的大写的配置,v 就是self.配置的值,所以这样就可以通过settings这个对象点的方式获取到值

settings = Settings()

config.py

EMAIL_USER = ‘test‘

global_settings.py

from lib.config.config import settings

import importlib
import subprocess

#管理插件信息的类
class PluginsManger(object):

    def __init__(self, hostname=None):
        self.plugins_dict = settings.PLUGINS_DICT
        self.hostname = hostname

        if settings.mode == ‘ssh‘:
            self.port = settings.SSH_PORT
            self.username = settings.SSH_USERNAME
            self.pwd = settings.SSH_PASSWORD

    #读取配置文件中的pluginsdict, 并执行对应模块中的process方法
    def execute(self):
        response = {}
        for k,v in self.plugins_dict.items():
            ‘‘‘
          k:  board,...
          v:  src.plugins.board.Board   字符串
           ‘‘‘
            #1.导入模块路径
            moudle_path,class_name = v.rsplit(‘.‘, 1)
            #2.导入这个路径

            moudle_name = importlib.import_module(moudle_path)

            #3.导入对应的类
            classobj = getattr(moudle_name, class_name)

            #4.执行类下面对应的process方法

            res = classobj().process(self.__cmd_run)
            response[k] = res
        return response

    def __cmd_run(self,cmd):
        if settings.MODE == ‘agent‘:
           return self.cmd_agent(cmd)
        elif settings.MODE == ‘ssh‘:
            return self.cmd_ssh(cmd)
        else:
            return self.cmd_salt(cmd)

    def cmd_agent(self,cmd):
        res = subprocess.getoutput(cmd)
        return res

    def cmd_ssh(self, cmd):
        import paramiko

        # 创建SSH对象
        ssh = paramiko.SSHClient()
        # 允许连接不在know_hosts文件中的主机
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        # 连接服务器
        ssh.connect(hostname=self.hostname, port= self.port, username=self.username, password=self.pwd)
        # 执行命令
        stdin, stdout, stderr = ssh.exec_command(cmd)
        # 获取命令结果
        result = stdout.read()

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

    def cmd_salt(self,cmd):
        command = "salt %s cmd.run %s" %(self.hostname,cmd)
        res = subprocess.getoutput(command)
        return res

__init__.py

class Board():
    def process(self, command_func):
        res = command_func(‘ifconfig‘)
        data = self.parse_output(res)
        return data

    def parse_output(self, res):
        pass

board.py

class Cpu():
    def process(self,command_func):
        command_func()

cpu.py

class Disk():
    def process(self, command_func):
       command_func(‘df -h‘)

disk.py

class Memory():
    def process(self,command_func):
        command_func(‘cat memory‘)

memory.py

USER = ‘root‘
port = 23

s1.py

import s1

print(dir(s1))
# [‘USER‘, ‘__builtins__‘, ‘__cached__‘, ‘__doc__‘, ‘__file__‘, ‘__loader__‘, ‘__name__‘, ‘__package__‘, ‘__spec__‘, ‘port‘]

print(s1)
print(s1.USER)

for key in dir(s1):
    if key.isupper():  # 我们只要大写的,因为配置文件里面规定大写,小写就排除掉
        print(key)

s2.py

原文地址:https://www.cnblogs.com/huangxuanya/p/11623005.html

时间: 2024-07-30 10:07:50

cmdb采集数据的版本的相关文章

《ServerSuperIO Designer IDE使用教程》- 7.增加机器学习算法,通讯采集数据与算法相结合。发布:4.2.5 版本

v4.2.5更新内容:1.修复服务实例设置ClearSocketSession参数时,可能出现资源无法释放而造成异常的情况.2.修复关闭宿主程序后进程仍然无法退出的问题.2.增加机器学习框架.3.优化核心代码.下载地址:官方下载 7.增加机器学习算法,通讯采集数据与算法相结合 7.1概述 ServerSuperIO发展到现在,缺少两部分内容:图形组态和算法分析.图形组态部分很快就要做出来了,不管从形式上还是内容上,比市场上同类产品要好很多:算法分析部分现在已经开发出来了,现在支持决策树和KMea

cmdb客户端采集数据的完善

file文件自己去拷贝(这里不提供) custom_settings.py import os BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 获取到根路径 MODE = 'agent' SSH_USERNAME = 'root' SSH_PASSWORD = '123' SHH_PORT = 22 DEBUG = True #代码调试,如果为True就会读取file中文件的内容,如果不是会执行linux

C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)

转自原文C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子) 阅读目录 1.HtmlAgilityPack简介 2.XPath技术介绍与使用 3.采集天气网站案例 4.资源 第一次接触HtmlAgilityPack是在5年前,一些意外,让我从技术部门临时调到销售部门,负责建立一些流程和寻找潜在客户,最后在阿里巴巴找到了很多客户信息,非常全面,刚开始是手动复制到Excel,是真尼玛的累,虽然那个时候C#还很菜,也想能不能通过程序来批量获取(所以平时想法要多才好).几

基于PHP采集数据入库程序(一)

前几天有一朋友要我帮做一个采集新闻信息的程序,抽了点时间写了个PHP版本的,随笔记录下. 说到采集,无非就是远程获取信息->提取所需内容->分类存储->读取->展示 也算是简单"小偷程序"的加强版吧 下面是对应核心代码(别拿去做坏事哦^_^) 所要采集的内容是某游戏网站上的公告,如下图: 可先利用file_get_contents和简单正则获取基本页面信息 整理下基本信息,采集入库: <?php include_once("conn.php&qu

linux使用UVC采集数据

V4L2是V4L的升级版本,linux下视频设备程序提供了一套接口规范. 常用的结构体在内核目录include/linux/videodev2.h中定义 struct v4l2_requestbuffers  //申请帧缓冲,对应命令VIDIOC_REQBUFS struct v4l2_capability      //视频设备的功能,对应命令VIDIOC_QUERYCAP struct v4l2_input           //视频输入信息,对应命令VIDIOC_ENUMINPUT st

基于PHP采集数据入库程序(二)

在上篇基于PHP采集数据入库程序(二) 中提到采集新闻信息页的列表数据,接下来讲讲关于采集新闻具体内容 这是上篇博客的最终数据表截图: 接下来要做的操作就是从数据库中读取所需要采集的URL,进行页面抓取就行 新建一个content表 不过需要注意的一点是,不能再采用采集URL这种id递增的方法去采集,因为数据表中可能出现id断续,比如id=9,id=11,当采集到id=10的时候,URL是空白的,这样可能会导致采集到了空字段. 这里用到的一个技巧是数据库的查询语句,在我们采集完第一条数据的时候,

使用ScrapySharp快速从网页中采集数据

转自原文 使用ScrapySharp快速从网页中采集数据 ScrapySharp是一个帮助我们快速实现网页数据采集的库,它主要提供了如下两个功能 从Url获取Html数据 提供CSS选择器的方式解析Html节点 安装: ScrapySharp可以直接从Nuget上下载,直接从Package Console里面输入如下命令即可: PM> Install-Package ScrapySharp Html下载 首先我们来看看它的Html下载功能,它是通过ScrapingBrowser类来实现的: va

Flume简介与使用(二)——Thrift Source采集数据

Flume简介与使用(二)——Thrift Source采集数据 继上一篇安装Flume后,本篇将介绍如何使用Thrift Source采集数据. Thrift是Google开发的用于跨语言RPC通信,它拥有功能强大的软件堆栈和代码生成引擎,允许定义一个简单的IDL文件来生成不同语言的代码,服务器端和客户端通过共享这个IDL文件来构建来完成通信. Flume的Thrift Source是其实现的众多Source中的一个,Flume已经实现了服务器端,因此我们可以用任意自己熟悉的语言编写自己的Th

[PHP自动化-进阶]001.模拟登录并采集数据

引言:PHP可以通过libcurl实现模拟登录,提交数据,违法乱纪,烧杀抢虐等等事项. 简单说明一下"libcurl",补一下脑: libcurl目前支持http.https.ftp.gopher.telnet.dict.file和ldap协议. libcurl同时也支持 HTTPS认证.HTTP POST.HTTP PUT. FTP 上传(这个也能通过PHP的FTP扩展完成).HTTP 基于表单的上传.代理.cookies和用户名+密码的认证. 使用curl可以实现Get和Post请