目录

  • client端

    • 简述整体数据采集流程
    • 代码编写:
      • settings部分
      • plugin manage部分

client端

简述整体数据采集流程

代码编写:

settings部分

通常,脚本的settings就是配置文件,用户如果需要对脚本进行自定义的一些操作(例如,添加自己的ssh账号密码,选择调试debug模式等)需要在配置文件中进行修改。
但是脚本端一般也有自己私有的配置文件,用于存储一些程序固定的变量,一些隐藏的信息,或者是不想让用户随意修改的配置。这就又需要一个default_settings。

用户可操作settings(外配置)

通常这里我们用来存放一些,之后需要经常使用的固定变量。例如程序的基础路径,对外通信的账号密码以及秘钥,调试模式的默认参数……

在这里我们还要额外针对本程序定义一个关于加载模块的路径和类对应的字典:

PLUGINS_DICT = {'basic': "src.plugins.basic.Basic",'board': "src.plugins.board.Board",'cpu': "src.plugins.cpu.Cpu",'disk': "src.plugins.disk.Disk",'memory': "src.plugins.memory.Memory",'nic': "src.plugins.nic.Nic",
}

用户不可操作的settings(内配置)

随便些什么吧,暂时好像还没用到,不过感觉可以把密钥封装在这里面,在server端也一样隐藏保存一个密钥。

串联两个settings

import os
import importlib
from . import global_settings
# from config import settingsclass Settings(object):def __init__(self):# ######## 找到默认配置 ########for name in dir(global_settings):if name.isupper():value = getattr(global_settings,name)setattr(self,name,value)# ######## 找到自定义配置 ######### 根据字符串导入模块settings_module = os.environ.get('USER_SETTINGS')if not settings_module:returnm = importlib.import_module(settings_module)# 注意这句话,这种创建settings的方法是借鉴了Django模块,利用参数的大写,来筛选获取必要的配置值。for name in dir(m):if name.isupper():value = getattr(m,name)setattr(self,name,value)
  • dir()内置函数的作用:
    用于获取目标(文件)中有哪些方法或可调用参数。
    同时也可以用来查询某种类型的数据,有哪些可调用方法,例如查询str类型就可以dir(''),list类型dir(['a','b'])

  • importlib模块----动态导入模块
>>> v='src.plugins.basic.Basic'
>>> v.rsplit('.')
['src', 'plugins', 'basic', 'Basic']
>>> v.rsplit('.',1)
['src.plugins.basic', 'Basic']

利用字符串切割获取类的路径(字符串形式用importlib获取)
以及类名,通过getattr方法获取目标类对象

plugin manage部分

针对每种不同的硬件,资产采集应该有不同的采集方式以及对应的数据结构化方式。
最开始的时候我很疑惑为什么老师用的方式不是直接使用模块来进行采集,因为在很多相关的博客推送上看到,用于linux监控的模块很多,也很强大。
仔细查询资料之后,我发现“硬件信息采集”和“linux信息监控”是完全两个概念。前者的确没有非常好的解决方案,只能通过subprocess模块向linux主机发送命令并且采集/proc/文件夹下信息才可以完成。

所以这个plugin_manage其实就是负责:

  1. 获取单个硬件信息模块的位置并且运行;
  2. 针对不同的采集方式,装饰输出对应的命令;

由于client端有三种采集方式,传递到API后端的方式有两种,做以下图示意:

代码部分

  1. 利用之前在settings中设置的plugins_dict,导出并且运行单个硬件模块采集的信息,并且存储到result_dict
response={}
for k,v in self.plugin_dict.items():# 'basic':'src.plugins.basic.Basic'ret={"status":True,'data':None}try:# 朋友,记住这个反射的用法,在server端数据库更新的时候还会用到module_path,class_name=v.rsplit('.', 1)m=import_module(module_path)cls=getattr(m,class_name)if hasattr(cls,'initial'):obj=cls.initial()# 这个initial是为了给对象实例化的时候添加一点自定的初始化操作else:# 当然没有的话,就是简单的实例化了obj=cls()result=cls().process(self.command,self.debug)ret['data']=resultexcept Exception as e:ret['status']=Falseret['data']="[%s][%s] 采集数据出现错误 : %s" %(self.hostname if self.hostname else "AGENT",k,traceback.format_exc())response[k]=ret
  1. 规范化三种不同采集方式的命令输出:

原先老师的写法是把每种调用方式写成私有方法再进行调用的。但是这边为了贴代码方便所以就整合到一个command方法里了。并不影响上面函数的调用。

def command(self,cmd):if self.mode== "AGENT":output = subprocess.getoutput(cmd)return outputelif self.mode=="SALT":salt_cmd = "salt '%s' cmd.run '%s'" % (self.hostname, cmd)output = subprocess.getoutput(salt_cmd)return outputelif self.mode=="SSH":import paramikossh = paramiko.SSHClient()ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())ssh.connect(hostname=self.hostname, port=self.ssh_port, username=self.ssh_user, password=self.ssh_pwd)stdin, stdout, stderr = ssh.exec_command(cmd)result = stdout.read()ssh.close()return resultelse:raise Exception('no such mode (agent/ssh/salt is allowed)')

扩展的知识部分:

为什么要用cmd命令,而不是利用模块?

这个是我最最最开始纠结的点,明明是一个python程序,为什么不贯彻到底用python来解决这个资产采集,既可以很好的控制数据结构,还可以借用别人的模块来实现平台通用。

刚开始我查询了一些模块资料,发现python作为自动化运维利器,在获取以及监控linux数据这点上真的不是一般的优秀。下面简单的记录几个,在以后遇到类似项目的时候,可以想的起来用:

  • platform:
    这个模块给予的信息,应该是最直观的。
>>> platform.uname()
uname_result(system='Windows', node='LAPTOP-AV9UPVQJ', release='10', version='10.0.14393', machine='AMD64', processor='Intel64 Family 6 Model 158 Stepping 9, GenuineIntel')
>>> platform.python_build()
('v3.6.1:69c0db5', 'Mar 21 2017 18:41:36')
>>> platform.python_compiler()
'MSC v.1900 64 bit (AMD64)'

但是这个模块,目前我看到的资料显示,除了上面的主机信息可以通过一个uname方法直接完全取出(也可以单个单个取),以及还有一些我没放的检查主机python版本的方法之外,没有其他功能了。这个模块的版本目前比较低,只有0.1还是0.2,放在python标准库里,可以直接import。
所以他的应用场景我觉得比较局限,用于检测目标机器上的python版本和运行环境比较合适。

  • wmi:
    针对windows平台的一个模块,尚未深入研究,但是考虑到未来对windows平台的一些监控,还是贴一下网址吧:

    转载自伯乐在线:http://python.jobbole.com/86349/

  • psutil:
    这个是,本来让我产生错觉“哇,在下已经找到了最优解”的一个模块。
    相比platform的文档少,功能少,wmi的平台支持单一。这个psutil简直太可爱了……

    官方文档:
    https://pypi.python.org/pypi/psutil
    http://pythonhosted.org/psutil/
    操作实例:
    http://blog.csdn.net/bubu8633/article/details/8258342
    还有多平台支持,单个方法获取单个数据(硬盘,网卡IO,存储占用)……真的是清纯不做作,踏实又肯干

但是最后让我醒悟过来的还是,这个cmdb的功能目标是:获取硬件信息而不是获取硬件运行指标。利用psutil能获得硬盘占用信息,存储占用信息,但是不能获得硬盘型号,网卡型号……

所以获取硬件信息(硬盘大小,网卡ip,存储类型)还是需要通过命令去获得。

怎么把命令从python程序中递交出去?

subprocess大法好!(这是个坑,晚点再填吧)

递交什么命令,查询什么文件?

dmidecode大法好!(这是个坑,晚点再填吧)

http://www.iyunv.com/thread-291062-1-1.html
上面的连接中的帖子,提供了一个尝试使用dmidecode这个工具的方法。并不能说很好,但是给我入门尝试使用并且查看dmidecode提供的信息已经很不错了。
首先这个工具是在linux上的,查看的时候需要root权限。因为我的测试环境是用户级别的Ubuntu,不能直接用root用户登录,所以sudo之后还要输入密码(但是其实是可以在配置文件里面设置特殊用户组sudo不使用密码的,之前试了一下直接把机子弄得没法用了所以这台就先晚点再试吧)。在centos等发行版中,还是支持root用户不需要输入密码的。

刚才在查看老师board模块代码的时候,看到老师使用了特别的命令

scott@scott-virtual-machine:~$ sudo dmidecode -t1
[sudo] scott 的密码:
# dmidecode 3.0
Getting SMBIOS data from sysfs.
SMBIOS 2.7 present.Handle 0x0001, DMI type 1, 27 bytes
System InformationManufacturer: VMware, Inc.Product Name: VMware Virtual PlatformVersion: NoneSerial Number: VMware-56 4d b1 e1 37 53 d3 c3-41 4c dc 75 07 6f 32 b5UUID: E1B14D56-5337-C3D3-414C-DC75076F32B5Wake-up Type: Power SwitchSKU Number: Not SpecifiedFamily: Not Specified

之前看帖子里的例子,用的是sudo dmidecode |less,发现这个返回回来的信息真的是奇长无比……而老师的命令好像是可以直接拿到一个类的信息。所以机智的我以此类推:

scott@scott-virtual-machine:~$ sudo dmidecode -t2
# dmidecode 3.0
Getting SMBIOS data from sysfs.
SMBIOS 2.7 present.Handle 0x0002, DMI type 2, 15 bytes
Base Board InformationManufacturer: Intel CorporationProduct Name: 440BX Desktop Reference PlatformVersion: NoneSerial Number: NoneAsset Tag: Not SpecifiedFeatures: NoneLocation In Chassis: Not SpecifiedChassis Handle: 0x0000Type: UnknownContained Object Handles: 0

同理这个dmidecode后面跟的-t确实有划分获取dmidecode信息的功能。掌握了这个特别的技巧之后,我不禁又要去搜搜这个dmidecode的进阶技巧了

http://msiyuetian.blog.51cto.com/8637744/1787978
我们通过 dmidecode 命令可以获取厂商、产品型号、序列号等、但是 dmidecode 命令输出的信息太多,我们只需要 System Information 下的 Manufacturer、Product Name、Serial Number 三个信息.

上面的这篇文章采用的仍然是startwith匹配的方式去获取,其中有一个利用空行为空来排除空行对信息列表的影响的列表生成式,有较好的参考作用,mark一下。

在网上搜索了一下,果然有收获,连接如下:http://linux-wiki.cn/wiki/dmidecode
老师使用的这个-t其实可以用表达更加明确的方式:

命令后缀 作用
-q or --quiet 不显示太多信息,比如某条数据是从哪里读来的等等,为了得到简洁的信息,此条很有用。
-t or --type TYPE 指定要哪方面的内容
-s or --string KEYWORD 显示特定的关键字
-u or --dump 直接显示DMI表信息而不接吗,以16进制的文本方式显示

-t 后的参数

后缀 作用
bios bios的各项信息
system 系统信息,在我的笔记本上可以看到版本、型号、序号等信息。
baseboard 主板信息
chassis 机架信息,包括制造商,机架类型,机架高度,SN号,电源模块数
processor CPU信息
memory 内存信息
cache 缓存信息
connector PCI设备信息
slot 插槽信息

链接中还有其他后缀的信息,例如-s可以用于获取单属性参数。

中控机模式下,需要怎么把请求发送给服务器?

saltstack大法好!(这是个坑,晚点再填吧)
ssh大法好!(这是个坑,晚点再填吧)

转载于:https://www.cnblogs.com/scott-lv/p/7521827.html

CMDB整体项目梳理(1)相关推荐

  1. cmdb整体项目梳理(2)

    目录 单个模块获取信息 加密发送部分 对client端的总结 单个模块获取信息 以cpu为例来聊聊不同的获取方法和获取的数据类型 首先展示一下成果,这里使用的还是老师的方法,利用cat /proc/c ...

  2. SpringCloud微框架系列整体模块梳理

    转载自:https://www.cnblogs.com/softidea/p/6498125.html SpringCloud微框架系列整体模块梳理 以下为Spring Cloud的核心功能: 分布式 ...

  3. 【电商系统】—项目梳理(一)

    [电商系统]-项目梳理(一) 熟悉文档,查看原型.读懂需求 了解前端设计稿,设计前端业务架构 了解后台接口文档,制定相关对接规范 协调资源 搭建前端架构

  4. 网站建设的整体项目三步骤

    ​ 说到网站建设,对于每个公司来说都是一个长期坚守的过程,在网站的运营,推广上已有一定的执行标准.虽然说各家有各家独自的方法,但是宵云科技小编认为,网站建设团队的部门协作,各个项目的互相配合,最终带给 ...

  5. DayDayUp:计算机技术与软件专业技术资格证书之《系统集成项目管理工程师》课程讲解之十大知识领域之1个整体—项目整体管理

    DayDayUp:计算机技术与软件专业技术资格证书之<系统集成项目管理工程师>课程讲解之十大知识领域之1个整体-项目整体管理 目录 一.项目整体管理 1.1.项目整体管理概述 1.1.1. ...

  6. 深度学习网络模型——RepVGG网络详解、RepVGG网络训练花分类数据集整体项目实现

    深度学习网络模型--RepVGG网络详解.RepVGG网络训练花分类数据集整体项目实现 0 前言 1 RepVGG Block详解 2 结构重参数化 2.1 融合Conv2d和BN 2.2 Conv2 ...

  7. 合并报表编制采用的理论_合并报表操作的整体思路梳理

    众所周转,财务报表合并是财务核算里的重点也是难点.注册会计师-会计教材中合并报表章节,介绍的<合并财务报表>部分,也是对现行企业会计准则及其应用指南的总结性陈述.整体思路一共分为五个部分: ...

  8. 【渗透工具】-SQL注入-SQLMap项目梳理

    文章目录 概述8个目录文件 详细说明4个重点目录 软件说明doc 插件库plugins 绕过脚本tamper data数据目录 使用说明 查看软件信息 和 General 基础用法 -h 1.Targ ...

  9. 仿微信朋友圈项目梳理

    项目功能简介: 用户通过手机号验证码进行登录和注册 可以浏览动态列表中的所有动态 登录成功后用户可以发表自己的动态 也可以对自己认可欣赏的动态进行点赞和评论 也可以通过动态结识志同道合的朋友 进行聊天 ...

最新文章

  1. VC6迁移到VS2008几个问题——良好的代码,从我做起,从现在开始。
  2. pairplot 中参数hue的作用就是在图像中将输出的散点图按照hue指定的特征或标签的类别的颜色种类进行区分
  3. details和summary
  4. 解决Mac下npm权限问题
  5. 吉他谱——再回首pic
  6. JQuery移除事件
  7. 归并排序,快速排序,冒泡排序,选择排序,基数排序,桶排序,堆排序(c++实现)
  8. 我历时3年才写了10余篇源码文章,但收获了100w+阅读
  9. JAVA中小细节(易忽视和易错点)
  10. 多任务场景下单线程异步多线程多进程
  11. Study之2 Glance相关操作-devstack
  12. tar (child): lbzip2: Cannot exec: No such file or directory 解决方法
  13. 软件测试英语笔试,软件测试英文面试笔试题
  14. Spring Boot整合H2内存数据库配置及常见问题处理
  15. Leetcode142. Linked List Cycle II环形链表2
  16. 阿里专家与你分享:你必须了解的Java多线程技术
  17. 轮流取石子游戏c语言答案,取石子游戏
  18. Python爬取古诗词
  19. 获取SD卡序列号和厂商ID
  20. “无法连接到打印机。您输入的打印机名不正确 或者指定的打印机没有连接到服务器上”终极解决方法

热门文章

  1. syslog-ng客户端,服务器配置
  2. 谋求“同股不同权”,旷视赴港上市渐近
  3. 订阅发布系统得解耦与冗余
  4. oracle唯一索引能删除吗,Oracle:ora-02429:无法用于删除强制唯一/主键的索引 解决...
  5. Makefile模板的改进
  6. python中path的用法,python中path的用法
  7. 【java】Java 8 - 移除Permgen 使用元空间
  8. 【java】java Parallel GC 该怎么看?
  9. 05-java向Neo4j添加节点及其关系
  10. 95-180-055-源码-Watermark-AutoMaticWatermarkContext