Python之路【第二十二篇】CMDB項目

淺談ITIL

TIL即IT基礎架構庫(Information Technology Infrastructure Library, ITIL,信息技術基礎架構庫)由英國政府部門CCTA(Central Computing and Telecommunications Agency)在20世紀80年代末制訂,現由英國商務部OGC(Office of Government Commerce)負責管理,主要適用於IT服務管理(ITSM)。ITIL爲企業的IT服務管理實踐提供了一個客觀、嚴謹、可量化的標準和規範html

ITIL 就是一個標準規範,他並非一個軟件和系統,舉例來講若是想本身構建一個IT服務的系統能夠按照這個規範去實現。有一個指定方針!前端

ITIL分爲如下內容python

一、事件管理(Incident Management)數據庫

事故管理負責記錄、歸類和安排專家處理事故並監督整個處理過程直至事故獲得解決和終止。事故管理的目的是在儘量最小地影響客戶和用戶業務的狀況下使IT系統恢復到服務級別協議所定義的服務級別。django

註釋:故障申報處理模塊,出現故障把事故給相應的人去處理!一步一步的解決!編程

二、問題管理(Problem Management)json

問題管理是指經過調查和分析IT基礎架構的薄弱環節、查明事故產生的潛在緣由,並制定解決事故的方案和防止事故再次發生的措施,將因爲問題和事故對業務產生的負面影響減少到最低的服務管理流程。與事故管理強調事故恢復的速度不一樣,問題管理強調的是找出事故產生的根源,從而制定恰當的解決方案或防止其再次發生的預防措施。api

註釋:相似知識庫、提供一些幫助,定位問題和預防的措施。緩存

三、配置管理(Configuration Management)安全

配置管理是識別和確認系統的配置項,記錄和報告配置項狀態和變動請求,檢驗配置項的正確性和完整性等活動構成的過程,其目的是提供IT基礎架構的邏輯模型,支持其它服務管理流程特別是變動管理和發佈管理的運做。

註釋:識別和確認系統的配置項,配置項能夠是硬件、也能夠是軟件!

若是是硬件:一個主機、一個硬盤、一個鼠標均可以是配置項。

若是是軟件:好比公司購買的軟件

作的CMDB就是ITIL的「配置管理」,SaltStack最明顯的做用就是批量管理,還有一個做用就是配置管理,他能夠把你的機器配置成你想要的狀態!你想要這個機器配置什麼服務、什麼軟件!這也能夠叫配置管理!

這個配置管理能夠看作CMDB的中的一項功能

四、變動管理(Change Management)

變動管理是指爲在最短的中斷時間內完成基礎架構或服務的任一方面的變動而對其進行控制的服務管理流程。變動管理的目標是確保在變動實施過程當中使用標準的方法和步驟,儘快地實施變動,以將由變動所致使的業務中斷對業務的影響減少到最低。

註釋:個人理解是舉例來講:在服務器須要替換的時候、修改主機名、這個都須要流程化、標準化。

五、發佈管理(Release Management)

發佈管理是指對通過測試後導入實際應用的新增或修改後的配置項進行分發和宣傳的管理流程。發佈管理之前又稱爲軟件控制與分發

註釋:代碼發佈,它能夠作爲一個獨立的系統!

 

若是想在公司作自動化,按照這個5大塊來作就不會偏離自動化偏離太遠,ITIL真正實施的不多由於很大!不過咱們能夠借鑑它來參考去作咱們自動化的東西!

上面5大塊具體實現的目標:

'''
事件管理的目標是在不影響業務的狀況下,儘量快速的恢復服務,從而保證最佳的效率和服務的可持續性。事件管理流程的創建包括事件分類,肯定事件的優先級和創建事件的升級機制。

問題管理是調查基礎設施和全部可用信息,包括事件數據庫,來肯定引發事件發生的真正潛在緣由,一塊兒提供的服務中可能存在的故障。

配置管理的目標是:定義和控制服務與基礎設施的部件,並保持準確的配置信息。

變動管理的目標是:以受控的方式,確保全部變動獲得評估、批准、實施和評審。

發佈管理的目標是:在實際運行環境的發佈中,交付、分發並跟蹤一個或多個變動。

服務檯:服務檯是IT部門和IT服務用戶之間的單一聯繫點。它經過提供一個集中和專職的服務聯繫點促進了組織業務流程與服務管理基礎架構集成。服務檯的主要目標是協調客戶(用戶)和IT部門之間的聯繫,爲IT服務運做提供支持,從而提升客戶的滿意度。
服務檯:以上的流程是咱們運維和研發同窗在後臺實現的,若是要後期要交給其餘用戶,就須要一個入口。完整的前端結合!
'''

CMDB介紹

CMDB --Configuration Management Database 配置管理數據庫, CMDB存儲與管理企業IT架構中設備的各類配置信息,它與全部服務支持和服務交付流程都緊密相聯,支持這些流程的運轉、發揮配置信息的價值,同時依賴於相關流程保證數據的準確性。

在實際的項目中,CMDB經常被認爲是構建其它ITIL流程的基礎而優先考慮,ITIL項目的成敗與是否成功創建CMDB有很是大的關係。
70%~80%的IT相關問題與環境的變動有着直接的關係。實施變動管理的難點和重點並非工具,而是流程。即經過一個自動化的、可重複的流程管理變動,使得當變動發生的時候,有一個標準化的流程去執行,可以預測到這個變動對整個系統管理產生的影響,並對這些影響進行評估和控制。而變動管理流程自動化的實現關鍵就是CMDB。

爲何70%~80%的IT現骨幹問題與環境的變動有着直接的關係,舉例來講,若是在交大的公司中好比百度,好比兩個部門的一個是百度地圖一個是百度貼吧!由於若是系統比較龐大的話,沒有一我的能完徹底全的瞭解整個系統的架構,若是在這種狀況下,百度地圖的同窗修改了一個藉口,那麼他不知道是否影響百度貼吧。萬一百度貼吧有調用呢!因此在這種狀況下就須要一個存儲着整個系統架構和對應關係的系統,記錄着它們之間的關係映射!

因此CMDB中至少包含以下的功能:整合、調和、同步、映射和可視化。

  • 整合是指可以充分利用來自其餘數據源的信息,對CMDB中包含的記錄源屬性進行存取,將多個數據源合併至一個視圖中,生成連同來自CMDB和其餘數據源信息在內的報告;
  • 調和能力是指經過對來自每一個數據源的匹配字段進行對比,保證CMDB中的記錄在多個數據源中沒有重複現象,維持CMDB中每一個配置項目數據源的完整性;自動調整流程使得初始實施、數據庫管理員的手動運做和現場維護支持工做降至最低;
  • 同步指確保CMDB中的信息可以反映聯合數據源的更新狀況,在聯合數據源更新頻率的基礎上肯定CMDB更新日程,按照通過批准的變動來更新 CMDB,找出未被批准的變動;
  • 應用映射與可視化,說明應用間的關係並反應應用和其餘組件之間的依存關係,瞭解變動形成的影響並幫助診斷問題。

而且在作自動化的前提是標準化,咱們在作CMDB的時候就至關於作標準化的過程,並能僅僅告訴研發和運維同窗怎麼怎麼作,若是沒有一個系統強制要求他這樣作那麼以前的流程和標準對於運維和研發來講他們已經習慣了,是很難實施的!

自動化的前提就是標準化和流程化!

CMDB自定義用戶認證

本身建立一個表,作一個one-to-one去管理User表,至關於擴展它!就至關於有兩張表.一個是Django自帶的表一個是我擴展的表,因此在查詢的時候比較麻煩!看下面代碼

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
#必須導入User模塊
class UserProfile(models.Model):
    '''
    用戶表
    '''
    #使用Django提供的用戶表,直接繼承就能夠了.在原生的User表裏擴展!(原生的User表裏就有用戶名和密碼)
    #必定要使用OneToOne,若是是正常的ForeignKey的話就表示User中的記錄能夠對應UserProfile中的多條記錄!
    #而且OneToOne的實現不是在SQL級別實現的而是在代碼基本實現的!
    user = models.OneToOneField(User)
    #名字
    name = models.CharField(max_length=32)
    #屬組
    groups = models.ManyToManyField("UserGroup")
    #朋友
    friends = models.ManyToManyField('self',related_name='my_friends')
    status = models.ForeignKey("UserStatus",related_name='user_status',blank=True,null=True)

而且在調用的時候還須要去調用這個User表而不是直接調用UserProfile

{{ request.user.userprofile.name }}

那如今我要就寫一張表有兩種方式
1 徹底本身寫
2 或者是說在Django的基礎上先繼承在擴展,上面的方式就直接是集成沒有擴展
若是是簡單的項目的話,就使用One-To-One的直接繼承就好了.
若是是大項目的話建議使用第二種方式.既然是自定義的話裏面不少都須要本身寫

#!/usr/bin/env python
#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser
)


class UserProfileManager(BaseUserManager):
    def create_user(self, email, name, password=None):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=self.normalize_email(email),
            name=name,
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, name, password):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        user = self.create_user(email,
            password=password,
            name=name
        )
        user.is_admin = True
        user.save(using=self._db)
        return user

class UserProfile(AbstractBaseUser):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    name = models.CharField(max_length=32)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = UserProfileManager()
    #USERNAME_FIELD 告訴Django那個爲用戶名字段
    USERNAME_FIELD = 'email'
    #指定必須字段,用戶名默認就是必須字段了,咱們在指定一個必須字段
    REQUIRED_FIELDS = ['name']

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def __str__(self):              # __unicode__ on Python 2
        return self.email

    #這個方法是用來控制admin的權限的
    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True
    #用來判斷是否有權限查看其餘app的默認返回True
    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True
    #靜態方法,默認返回self.
    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin

而且咱們建立的表,Django默認去Django的Model裏去找,若是不想放進Model裏面而是本身寫的表的話
怎麼辦?Django默認仍是本身的認證表,咱們的明確的告訴Django不要用你本身的表了用個人表!
在哪裏改呢?在setting裏指定!

AUTH_USER_MODEL = 'assets.UserProfile'

而且在model裏引入

from assets.user_models import UserProfile

如今在註冊admin以後有個問題,就是當咱們註冊了admin以後咱們在修改密碼以後發現
在修改密碼以後,密碼是明文的了!以下圖

這是什麼緣由呢?就是由於你重寫了那麼Admin你也得從新配置下!

#!/usr/bin/env python
#-*- coding:utf-8 -*-


from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField

from assets.models import UserProfile


class UserCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = UserProfile
        fields = ('email', 'name')

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    """A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    password hash display field.
    """
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = UserProfile
        fields = ('email', 'password', 'name', 'is_active', 'is_admin')

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]


class UserAdmin(BaseUserAdmin):
    # The forms to add and change user instances
    form = UserChangeForm
    add_form = UserCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ('email', 'name', 'is_admin')
    list_filter = ('is_admin',)
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Personal info', {'fields': ('name',)}),
        ('Permissions', {'fields': ('is_admin',)}),
    )
    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'date_of_birth', 'password1', 'password2')}
        ),
    )
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()

# Now register the new UserAdmin...
#admin.site.register(UserProfile, UserAdmin)
# ... and, since we're not using Django's built-in permissions,
# unregister the Group model from admin.
#admin.site.unregister(Group)

而後在Djangoadmin中導入

#!/usr/bin/env python
#-*- coding:utf-8 -*-
from django.contrib import admin
from assets import models
from assets.user_admin import UserAdmin
# Register your models here.
'''
下面的意思就是默認使用的是:
admin.site.register(models.UserProfile)
給他綁定上咱們自定義的admin
admin.site.register(models.UserProfile,UserAdmin)
'''
admin.site.register(models.UserProfile,UserAdmin)

就OK了,咱們在使用的時候就不要在去調用User表了,而直接使用我們定義的表就能夠了。

而後順便再看下Group是作什麼用的,Django默認給咱們有一個Group組,若是不們不想用直接取消就能夠了

from django.contrib.auth.models import Group
admin.site.unregister(Group)


#完整實例~~

#!/usr/bin/env python
#-*- coding:utf-8 -*-
from django.contrib import admin
from assets import models
from assets.user_admin import UserAdmin
from django.contrib.auth.models import Group

# Register your models here.
'''
下面的意思就是默認使用的是:
admin.site.register(models.UserProfile)
給他綁定上咱們自定義的admin
admin.site.register(models.UserProfile,UserAdmin)
'''
admin.site.register(models.UserProfile,UserAdmin)
admin.site.unregister(Group)

效果以下:

這樣就不適用Django組了在Admin中!

CMDB表結構設計

確認配置項,都要存什麼設備:

服務器:
    -內存
    -CPU
    -Disk
    -網卡
    -raid
    -sn
    -型號
    -系統版本
    -狀態

存儲設備:
    -型號
    -Disk

網絡設備:
    -網口數量
    -網卡信息(MAC地址等信息)
    -網卡速度
    -背板帶寬
    -系統版本
    -管理IP

軟件資產:
    -用途
    -版本

機房:
    -機房信息
    -機櫃(最大U位,電源最大負載)
    -U位

設備有管理員
設備所屬業務線:這裏重要

業務線這裏要寫成有層級關係的業務線!
‘’‘
爲何呢?舉例來講,百度貼吧的業務線,他下面有數據庫的機器,有作緩存的、有作前端的。
一個業務線下面有好幾個業務線!而且不能規定他有多少層!
這裏很重要!相似多級評論~~~~~
’‘’

Restful API接口規範的設計與實現

理解RESTful架構 :http://www.ruanyifeng.com/blog/2011/09/restful 

RESTful API 設計指南 :http://www.ruanyifeng.com/blog/2014/05/restful_api.html 

瞭解Restful API設計規範後若是能使用起來是最好了,平時須要注意的是URL中不能有動詞。

咱們總結一下什麼是RESTful架構:

  1. 每個URI表明一種資源;
  2. 客戶端和服務器之間,傳遞這種資源的某種表現層;
  3. 客戶端經過四個HTTP動詞,對服務器端資源進行操做,實現"表現層狀態轉化"。

最多見的一種設計錯誤,就是URI包含動詞。由於"資源"表示一種實體,因此應該是名詞,URI不該該有動詞,動詞應該放在HTTP協議中。
舉例來講,某個URI是/posts/show/1,其中show是動詞,這個URI就設計錯了,正確的寫法應該是/posts/1,而後用GET方法表示show。
若是某些動做是HTTP動詞表示不了的,你就應該把動做作成一種資源。好比網上匯款,從帳戶1向帳戶2匯款500元,錯誤的URI是:
  POST /accounts/1/transfer/500/to/2
正確的寫法是把動詞transfer改爲名詞transaction,資源不能是動詞,可是能夠是一種服務:
  POST /transaction HTTP/1.1
  Host: 127.0.0.1
  from=1&to=2&amount=500.00
另外一個設計誤區,就是在URI中加入版本號:
  http://www.example.com/app/1.0/foo
  http://www.example.com/app/1.1/foo
  http://www.example.com/app/2.0/foo
由於不一樣的版本,能夠理解成同一種資源的不一樣表現形式,因此應該採用同一個URI。版本號能夠在HTTP請求頭信息的Accept字段中進行區分(參見Versioning REST Services)http://www.informit.com/articles/article.aspx?p=1566460:

Django API框架

 重中之重:接口設計好

  • 可對內外靈活開放接口
  • 接口定義要標準化
  • 必定要提供排錯依據 
  • 數據返回要標準
  • 要能增刪改查
  • 全部異常要抓住爲了排錯
  • 接口安全要注意

接口定義要標準化 (不能說隨便起個名字 返回的數據的格式標準化)

在別人調用你接口的時候的,要提示它由於什麼緣由致使出錯了,好比他提交的數據不合法/或者服務器問題,爲何要作這個:防止給本身找麻煩,由於別人在調用你端口的時候剛開始很容易出錯)

理解API:

APIApplication Programming Interface,應用程序編程接口)是一些預先定義的函數,目的是提供應用程序與開發人員基於某軟件或硬件得以訪問一組例程的能力,而又無需訪問源碼,或理解內部工做機制的細節。

簡單理解API是咱們提供的一個URL當用戶按照指定的格式提交到URL中,咱們在內部的views裏執行操做,而後返回給用戶狀態or數據!

那麼有沒有現成的提供了以上「重中之重的API設計裏提到的那些API設計原則呢」?

django-rest-framework    

django-rest-framework 是一款比較不錯的API模塊,他爲咱們定義了不少功能和規範而且能夠經過網頁查看API

Some reasons you might want to use REST framework:

一、安裝django-rest-framework

pip install djangorestframework

二、配置Django settings中註冊APP

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'assets',
    'rest_framework',
]

三、在Project中總URL重引入APP中的URL

from django.conf.urls import url,include
from django.contrib import admin
from assets import rest_urls

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include(rest_urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

四、配置Serializers序列化數據,這裏配置展現什麼數據而且被rest_views調用

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from django.contrib.auth.models import Group
from rest_framework import serializers
from assets.models import UserProfile
from assets import models

#定義前端展現什麼,吧許菊進行序列化
class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('url', 'name', 'email')

五、和APP中的URL分開因此獨立建立url&views

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from django.conf.urls import url, include
from rest_framework import routers
from assets import rest_views

router = routers.DefaultRouter()
#這裏是url名稱(看代碼下面的圖)
router.register(r'users', rest_views.UserViewSet)
router.register(r'groups', rest_views.GroupViewSet)
router.register(r'assets', rest_views.AssetViewSet)
router.register(r'servers', rest_views.ServerViewSet)

# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
    #這裏的route.urls這個把默認的路由分發改爲類的形式了
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

views

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from django.contrib.auth.models import Group
from rest_framework import viewsets

from assets.serializers import UserSerializer, GroupSerializer,AssetSerializer,ServerSerializer
from assets.models import UserProfile
from assets import models

class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """
    #這裏是從獲取數據命名必須爲:queryset & serializer_class
    #可是這裏獲取全部數據的命令實際是否展現不是在這裏設置的在serializers中設置
    queryset = UserProfile.objects.all()
    serializer_class = UserSerializer

六、測試

修改Serializers顯示內容

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from django.contrib.auth.models import Group
from rest_framework import serializers
from assets.models import UserProfile
from assets import models

#定義前端展現什麼,吧許菊進行序列化
class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('url', 'name', 'email','password','is_admin')

打開URL

 

 

進入users表裏

效果以下:

能夠在Serializers中定義好須要展現什麼API就能夠幫你展現,而且會幫你寫好提示以下!

而且支持json格式以下圖:

注API適用場景

在什麼狀況適用API呢?

外部和內部須要快速訪問數據的時候適用,若是是本身的APP或者Project下不能適用,雖然可使用可是至關於一個環了原本能夠從本身內部快速取出來的(本身寫的代碼取)若是從APP取就慢不少了,至關於繞了一圈!

固然API也能夠本身寫不用他這個框架,可是提示的內容和標準本身在寫API的時候須要注意!

API安全

那麼問題來了API,上面寫的API隨便誰均可以調用API進行操做,確定這個是不安全的!那怎麼辦呢?

方案以下:

原理:

原理:
一、客戶端與服務器都存放着用於驗證的Token字段,值字段不管經過什麼方法外部的黑客都是沒法獲取的。
二、客戶端吧本地的用戶名+時間戳+Token的組合進行MD5加密生成一段新的md5-token
三、客戶端訪問的時候攜帶:用戶名、時間戳、生成的一段新的md5-token
四、服務端收到請求後,先判斷用戶名、時間戳是否合法(時間戳和當前時間不能大於2分鐘)
五、用戶名和時間戳都合法了,在去Redis中判斷是否有當前用戶的key判斷是否在這2分鐘有訪問過,我這裏設置Redis2分鐘過時,即合法用戶第一次訪問後,把他的用戶名加入到Redis中做爲key:MD5做爲vlaue存儲。若是存在說明是在2分鐘內訪問的。拒絕
六、以上都經過以後說明是合法用戶和合法請求,而後在判斷MD5值是否相等若是相同認證經過,執行相關Veiws而後並返回相關的狀態或數據

 

更多內容摘自Aelx老師的博客:http://www.cnblogs.com/alex3714/articles/5420433.html

相關文章
相關標籤/搜索