django02_01 CMDB

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

         

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章