天天看點

運維前線:一線運維專家的運維方法、技巧與實踐2.6 進階進階

<b>2.6 進階進階</b>

<b></b>

2.6.1 曆史查詢功能

操作曆史,應該是管理系統必備的功能之一。django-echelon就是一個很好的功能子產品,該功能子產品可以單獨使用于任何的django項目中,非常友善,接下來我們講解如何将該功能添加到cmdb系統中,設定步驟具體如下。

(1)修改settings.py設定。

①添加echelon app:

installed_apps = (

'......',

'echelon',

)

②添加echelon中間件:

middleware_classes = (

'echelon.middleware.echelonmiddleware',

(2)修改urls.py設定:

# encoding:utf8

from django.conf.urls import patterns, include, url

urlpatterns = patterns('',

  '......',

                       # 操作曆史

                       url(r'^cmdb/changelog/', include('echelon.urls')),

(3)将echelon代碼複制到django項目的主目錄中,将html代碼複制到templates目

錄中。

(4)重新整理db,建立資料表:

$ python manage.py syncdb

(5)把操作曆史的url資訊添加到前端頁面的導航欄中就可以了(配置cmdb/cmdb_menu.py程式),具體操作如下:

cmdb_top_menu = [

#導航名稱、url、圖示、子導航資訊

[u'操作曆史 ', '/cmdb/changelog/', 'time', []],

]

(6)啟動django服務,打開前端頁面,然後點選操作曆史,就可以看到使用者的操作資訊了(見圖2-14),具體如下。

圖2-14 使用者的操作資訊

以上代碼都可以在open-cmdb庫上找到源代碼。

2.6.2 api功能

cmdb作為一個資料源中心,很多運維工具都會調用cmdb資料進行使用,是以api接口就非常有必要了,由于各個系統的需求不一樣,從頭到尾開發一套适用于各個系統的cmdb api也比較困難,那麼有沒有什麼簡單的方法呢?答案肯定是有,這裡我推薦django api利器django rest framework。

django rest framework是一個非常強大、靈活的api建構工具,它能很容易、很快速地幫我們建構web api。下面來講解建構的過程,具體步驟如下。

(1)安裝django rest framework。

主要安裝3個子產品:djangorestframework、markdown、django-filter。具體代碼如下:

pip install djangorestframework

pip install markdown

pip install django-filter

(2)配置settings.py:

     '......',

     'rest_framework',

rest_framework = {

    # use django's standard `django.contrib.auth` permissions,

    # or allow read-only access for unauthenticated users.

    'default_permission_classes': [

        'rest_framework.permissions.djangomodelpermissionsoranonreadonly'

    ]

}

(3)設定urls.py:

urlpatterns += patterns(

'',

url(r'^api/', include(myproject.api.router.urls)),

url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),

(4)建立我們的cmdb api(根據models資訊來建立,這裡隻附上一個簡單的講解,具體的内容請看源碼):

# -*- coding: utf-8 -*-

# 導入cmdb.models子產品

import cmdb.models

# 從rest_framework中導入子產品

from rest_framework import routers, serializers, viewsets

# 給需要生成api的model定義一個資料序列

# serializers define the api representation.

class idcserializer(serializers.hyperlinkedmodelserializer):

    class meta:

        # 使用的model名稱

        model = cmdb.models.idc

        # 字段序列

        fields = ('url', 'name', 'memo')

# 定義視圖

class idcviewset(viewsets.modelviewset):

    # 查詢所有資料,這個可以根據自己的需要來展示幾個

    queryset = cmdb.models.idc.objects.all()

    # 序列化資訊

    serializer_class = idcserializer

# 配置路由注冊,自動生成api url

# routers provide an easy way of automatically determining the url conf.

router = routers.defaultrouter()

router.register(r'idcs', idcviewset)

(5)配置導航欄資訊:

cmdb_menu.py cmdb_top_menu = [ [u'api文檔 ', '/api/', 'book', []], ]

(6)啟動django服務,展示如下(圖2-15)。

圖2-15 啟動django服務

通過api文檔,可以看到全部的api資訊,如圖2-16所示。

圖2-16 全部的api資訊

點選idc的具體url,就能看到展示的資訊和用法,如圖2-17所示。

到這裡cmdb api就完成了最基本的功能,後續還需要讀者自己去調整頁面和授

權等。

圖2-17 展示的資訊和用法

2.6.3 資料表結構

對于資料表結構,前面的定義是比較簡單的,有興趣的讀者可以根據自己的實際需求去增加,這裡僅列舉一個簡單的優化例子——idc表優化。

idc表前面就一個idc名稱字段,這裡将根據作者所在公司的需求來做優化,優化後的字段具體如下:

class idc(models.model):

# 機房名稱字段

name = models.charfield(u'機房名稱', max_length=200, unique=true)

# 名稱縮寫

short_name = models.charfield(u'名稱縮寫', max_length=200, unique=true)

# 機房地域

zone = models.charfield(u'機房地域', max_length=200, blank=true)

# 機房地域縮寫

zone_short_name = models.charfield(u'地域縮寫', max_length=200, blank=true)

# 機房位址

address = models.charfield(u'機房位址', max_length=200, blank=true)

# 機櫃u數

unit_size = models.positiveintegerfield(u'機櫃u數', default=42, help_text="機房每個機櫃擁有unit數目")

# 機櫃電數

power_size = models.positiveintegerfield(u'機櫃電數', default=12, help_text="機房每個機櫃擁有電力(an)數目")

interface_type_choices = (

    (0, '光纖'),

    (1, '普通'),

    (2, '其他'),

# 網絡接入方式是光纖、普通還是其他

interface_type = models.smallintegerfield(

    '網絡接入', choices=interface_type_choices, default=0)

# 機房所有裝置的總帶寬

bandwidth_equipment = models.bigintegerfield(u'裝置帶寬', default=0, help_text="裝置帶寬(mbps)")

# 機房可用帶寬

bandwidth_usable = models.bigintegerfield(u'可用帶寬', default=0, help_text="可使用最大帶寬(mbps)")

# 實體接入帶寬

bandwidth_line = models.bigintegerfield(u'接入帶寬', default=0, help_text="實體接入帶寬(mbps)")

# 保底帶寬

bandwidth_min = models.bigintegerfield(u'保底帶寬', default=0, help_text="保底帶寬(mbps)")

# 報警閥值

bandwidth_threshold  = models.bigintegerfield(u'報警門檻值', default=0, help_text="報警門檻值(mbps)")

line_model_choices = (

    (0, '單線'),

    (1, '雙線'),

    (2, 'bgp'),

# 機房線路類型是單線、雙線還是bgp

line_model = models.smallintegerfield(

    '線路類型', choices=line_model_choices, default=0)

# 接入線路條數

line_count = models.integerfield(u'線路條數', default=1, help_text="接入線路條數")

# 是否備援

line_redundancy = models.booleanfield("是否備援", default=false, help_text="接入線路是否備援")

# 是否限速,限速大小

speed_limit = models.integerfield(u'限速大小', default=0, help_text="限速大小(mbps, 0:不限速)")

charge_type_choices = (

    (0, '峰值'),

    (1, '95值'),

    (2, '保底'),

    (3, '計時'),

    (4, '包月'),

    (5, '包年'),

# 計費模式

charge_type = models.smallintegerfield(

    '計費模式', choices=charge_type_choices, default=0)

# 是否直連isp

isp_direct_link = models.booleanfield("是否直連isp", default=false)

# 所屬營運商,這裡需要再建立一個isp的類

isp = models.foreignkey("isp", verbose_name="營運商")

     # 聯系人

contact = models.foreignkey(userprofile, related_name="idc_contact", verbose_name="聯系人", help_text="idc機房聯系人")

# idc經理

manager = models.foreignkey(userprofile, related_name="idc_manager", verbose_name="經理", help_text="idc經理")

# 值班人

duty_officer = models.foreignkey(userprofile, related_name="duty_officer", verbose_name="值班人", help_text="idc機房值班聯系人")

# idc報障郵箱

support_email = models.emailfield(u'報障郵箱', help_text="idc報障郵箱")

# 公司聯系人

company_contact = models.foreignkey(userprofile, related_name="xsj_contact", verbose_name="公司聯系人", help_text="公司聯系人")

# 開通時間

start_time = models.datetimefield(u'開通時間',

                                  auto_now_add=true)

# 到期時間

end_time = models.datetimefield(u'到期時間',

                                  default=datetime.datetime(2140, 1, 1, 0, 0, 1))

memo = models.charfield(u'備注', max_length=200, blank=true)

def __unicode__(self):

    return self.name

class meta:

    db_table = 'idc'

現在這個表結構就是一個複雜的資料表結構,通過修改base_admin.py就可以直接展示了。

2.6.4 使用者管理功能

django有一套自己的使用者管理、使用者組管理和權限管理,我們在初始化django項目的時候,django會預設建立user、permission、group這3個表及對應的關聯關系表。

本章所介紹的這套簡單的cmdb系統,已經将展示、添加、編輯和删除都子產品化了。通過模闆建構使用者管理也是一件很輕松的事情,隻需要把django自帶的使用者資訊提取出來套用模闆即可,具體步驟如下。

(1)在cmdb/base_admin.py中設定。

導入user子產品:

from django.contrib.auth.models import user

'user': {

# model名稱

'model': user,

# form表單

'form': user_checkfrom,

#名稱 'name': u'使用者管理 ',

#是否可以導入資訊

'import': '',

# table展示字段

'list_display': ['username',

'password', 'email', 'is_superuser', 'is_active', 'is_staff',

'groups',

'user_permissions'],

#編輯隻讀字段

'readonly': ['username'],

#動作

'action_list': [(u'編輯 ', 'pencil', '/cmdb/user/modify/'),]

},

(2)把使用者管理的url資訊添加到前端頁面的導航欄中。(配置cmdb/cmdb_menu.py程式),具體操作如下:

[u'使用者管理 ', '/cmdb/user/show/', 'user', []],

(3)啟動django服務,打開前端頁面,點選使用者管理,資訊如圖2-18所示。

圖2-18 使用者組管理資訊

(4)到這裡一個簡單的使用者管理功能就實作了,如果讀者需要更詳細的使用者資訊,可以去建立一個userprofile表,然後關聯到django自帶的user資訊中,限于篇幅,本章就不逐一詳細介紹了。

2.6.5 使用者組管理功能

使用者組管理和使用者管理的原理是相通的,添加方式也是一樣的,這裡隻是簡述講解一下添加的步驟。

(1)在cmdb/base_admin.py中設定:

'group': {

'model': group,

'form': group_checkfrom,

# 名稱

'name': u'使用者組管理',

# 是否可以導入資訊

'list_display': ['name',

'permissions'],

# 編輯隻讀字段

'readonly': ['name', ],

# 動作

'action_list': [(u'編輯', 'pencil', '/cmdb/group/modify/'),]

(2)把使用者組管理的url資訊添加到前端頁面的導航欄中就可以了(配置cmdb/cmdb_menu.py程式),具體操作如下:

[u'使用者組管理 ', '/cmdb/group/show/', 'list', []],

(3)啟動django服務,打開前端頁面,點選使用者組管理(預設為空),資訊如圖2-19所示。

圖2-19 添加使用者組管理

(4)到這裡組管理功能也實作成功了,現在我們就可以建立自己想要的組資訊,把相應的使用者添加到組中了。

到此為止,我們已經基于cmdb完善了使用者、使用者組、操作曆史、開放api幾大實用功能。通過這些建構,可以将cmdb和自動化運維平台的其他系統逐一打通,建構屬于自己的平台。