一、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
原文地址:http://xiaofangliu.blog.51cto.com/4766193/1692842