一、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