一、CMDB开发流程概述
cmdb根据流程划分为三个部分:服务器,中控机,后台管理。通过中控机与服务器交互,收集所需采集的硬件、服务端相关信息。并将数据传递到后台数据库,由后台管理程序呈现。
1、后台管理
使用django 框架,安装数据库及创建web应用;
创建API 用于中控机的通信,及数据操作;
存储中控机手机到得数据,并向中控机下发通过资产录入 进来的主机列表;
2、中控机
主要进行对服务器的远程操作,及数据采集;
3、服务器
进行数据采集的客户端,按中控机的认证方式完成认证,如保存中控机私钥等;
安装响应的采集命令
-- dmidecode 用于采集内存信息
-- MegaCli 用于采集硬盘信息
二、环境准备及规划
1、后台管理(应用django1.8.2)
1.1数据库设计
1.1)用户相关表
定义用户类型表,用与用户权限分类:
class UserType(models.Model):
caption = models.CharField(max_length=32, db_index=True, unique=True)
code = models.CharField(max_length=32, db_index=True, unique=True)
def __unicode__(self):
return self.caption
class Meta:
verbose_name_plural = "用户类型"
定义用户存放表
class UserProfile(models.Model):
user_type = models.ForeignKey('UserType')
#用户创建时需选择响应类型,与UserType表为多对一的关系
name = models.CharField(u'名字', max_length=32)
email = models.EmailField(u'邮箱')
phone = models.CharField(u'座机', max_length=50)
mobile = models.CharField(u'手机', max_length=32)
memo = models.TextField(u'备注', blank=True)
create_at = models.DateTimeField(blank=True, auto_now_add=True)
update_at = models.DateTimeField(blank=True, auto_now=True)
class Meta:
verbose_name = '用户信息'
verbose_name_plural = "用户信息"
def __unicode__(self):
return self.name
定义 AdinInfo/UserGroup表分存放用户名密码、用户分组
1.2)主机信息相关表定义
根据实际情况,定义主机 机柜 机房 主机应用及操作日志等相关表;
1.2 应用程序编写
API url接口程序
web_api主机列表生成函数
def get_untreated_servers():
response = BaseResponse()
try:
current_date = datetime.date.today()
values = ('server__hostname',)
condition = Q()
con_date = Q()
con_date.connector = 'OR'
con_date.children.append(("latest_date__lt", current_date))
con_date.children.append(("latest_date", None))
con_status = Q()
# 在线状态的服务器(1000:上架;1001:在线)
con_status.children.append(('device_status__code', '1001'))
condition.add(con_date, 'AND')
condition.add(con_status, 'AND')
result = dal_asset.get_q(condition, *values)
result = list(result)
response.status = True
response.data = result
except Exception, e:
response.message = str(e)
return response
# ############# 服务器相关信息 #############
class ServerHelper(object):
# 获取服务器对象
@staticmethod
def get_server_obj(sn):
response = BaseResponse()
try:
result = dal_server.get_obj_by_sn(sn)
if not result:
raise Exception('not found server obj')
response.data = result
response.status = True
except Exception,e:
response.message = e.message
return response
web_api 收到来自中控及信息,进行数据处理,此过程包含大量的数据对比,资源更新 删除 添加等 大量操作程序。
操作基本操作并记录日志,更新相关硬件信息。创建dal包,以操作网卡为示例,如下:
# ############# 操作网卡信息 #############
# 操作网卡,并记录操作日志
# 添加网卡
# 删除网卡
# 更新网卡信息
class HandleNic(object):
@staticmethod
def process(server_obj,client_nic,user_obj):
response = BaseResponse()
try:
status = client_nic['status']
if status == 0:
raise Exception('nic plugin is error')
client_nic_dict = client_nic['data']
nic_objs = dal_nic.get_objs_by_server(server_obj)
nic_names = map(lambda x:x,(item.name for item in nic_objs))
update_list = agorithm.get_intersection(set(client_nic_dict.keys()),set(nic_names))
add_list = agorithm.get_exclude(client_nic_dict.keys(),update_list)
del_list = agorithm.get_exclude(nic_names,update_list)
HandleNic._add_nic(add_list, client_nic_dict, server_obj,user_obj)
HandleNic._update_nic(update_list, nic_objs, client_nic_dict, server_obj, user_obj)
HandleNic._del_nic(del_list, nic_objs, server_obj, user_obj)
response.status = True
except Exception,e:
response.message = e.message
#write error log
print e.message
return response
创建dal包,用于存放数据操作程序,具体与数据库交互的程序。如用户认证:
from web_models import models
def get_count(**kwargs):
count = models.AdminInfo.objects.filter(**kwargs).count()
return count
def get_single(**kwargs):
obj = models.AdminInfo.objects.get(**kwargs)
return obj
1.3后台管理应用
思路通上API应用程序,不同之处是应需要添加与前端交互的forms模块等;
1.4前端程序
templates中创建应用目录,区分存放应用前台文件;
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2、中控机
2.1中控机程序
中控机为Python程序可基于saltstack/ansible等程序进行对服务器的批量数据采集。
接受来自API的主机信息
插件编写,plugins模块进行对服务器数据采集,如:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#内存数据采集
import os
import subprocess
import commands
import BasePlugin
from lib.commons import convert
from lib.commons import log
class MemoryPlugin(BasePlugin.BasePlugin):
def linux(self):
result = {'status':0,'data':{}}
try:
#shell_command = "/usr/bin/sudo dmidecode -q -t 17 2>/dev/null"
shell_command = "sudo dmidecode -q -t 17 2>/dev/null"
output = self.exec_shell_cmd(shell_command)
result['data'] = self.parse(output)
result['status'] = 1
except Exception,e:
print e
result['error'] = e
return result
def parse(self,content):
'''
解析shell命令返回结果
:param content: shell 命令结果
:return:解析后的结果
'''
ram_dict = {}
key_map = {
'Size':'capacity',
'Locator':'slot',
'Type':'model',
'Speed':'speed',
'Manufacturer':'manufactory',
'Serial Number':'sn',
}
devices = content.split('Memory Device')
for item in devices:
item = item.strip()
if not item:
continue
if item.startswith('#'):
continue
segment = {}
lines = item.split('\n\t')
for line in lines:
if len(line.split(':'))>1:
key,value = line.split(':')
else:
key = line.split(':')[0]
value = ""
if key_map.has_key(key):
if key == 'Size':
segment[key_map['Size']] = convert.convert_mb_to_gb(value,0)
else:
segment[key_map[key.strip()]] = value.strip()
ram_dict[segment['slot']] = segment
return ram_dict
3、服务器
打通与中控机的交互
将公钥保存至服务器A、服务器B...
服务器上安装
-- dmidecode 用于采集内存信息
-- MegaCli 用于采集硬盘信息
其他:
如需生成后台验证码安装Pillow,及相关应用包
http://www.reader8.cn/jiaocheng/20120906/2009724.html
转载于:https://blog.51cto.com/xiaofangliu/1692842