python-cmdb資產管理項目

CMDB項目介紹及簡單架構實現

1  CMDB介紹

屬於運維自動化項目

1.1 傳統運維缺點

  1. 日常工作繁瑣
  2. 應用運行環境不統一
  3. 部署效率低
  4. 無用報警信息多
  5. 資產管理和應用管理混亂
    • EXCEL表格記錄服務器的資產非常麻煩,會導致服務器的記錄越來越亂

1.2 運維自動化可以運維標準化

  1. OS的選擇統一化,同一個項目使用同樣的OS系統所需要的各類軟件
  2. 軟件安裝標準化,例如JAVA虛擬機,php,nginx,mysql等各類應用軟件需所需要的版本,安裝目錄,數據存放目錄,日誌存放目錄等
  3. 應用包目錄統一標準化,及應用命名標準化
  4. 啓動腳本統一目錄和名字,需要變化的部分使用參數傳遞
  5. 配置文件標準化,需要變化的部分使用參數傳遞
  6. 日誌輸出,日誌目錄,日誌名字標準化
  7. 應用生成的數據要實現統一的目錄存放
  8. 主機/虛擬機命名的標準化,虛擬機管理使用標準化模板
  9. 使用docker比較容易實現軟件運行的環境標準化

1.3 公司的基本組織架構

  • 業務部門
  • UI設計
  • 開發
    • 前端:HTML,CSS,JS,VUE.js
    • 後端:不分離項目,接口(Djiango開發)
  • 運維
    • 項目部署
    • 服務器管理(網關) 
  • 測試
    • 功能測試
    • 性能測試
    • 壓力測試而

2 CMDB實現

2.1 項目架構

網站   <-------->數據庫  <------------>   API  <--------------服務器資產

2.2 paramiko模塊簡單使用

用於遠程鏈接和操控服務器

安裝:

pip3 iinstall paramiko

基於用戶名密碼遠程執行

import paramiko

# 創建SSH對象
ssh = paramiko.SSHClient()
# 允許連接不在know_hosts文件中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連接服務器
ssh.connect(hostname='192.168.100.101', port=22, username='root', password='redhat')
# 執行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 獲取命令結果
result = stdout.read()
# 關閉連接
ssh.close()
print(result)

 執行結果

基於用戶名密碼上傳下載文件

import paramiko
transport = paramiko.Transport(('192.168.100.101',22))
transport.connect(username='root',password='redhat')
sftp = paramiko.SFTPClient.from_transport(transport)
#將本地的test_paramiko_file.txt文件上傳到服務器的/tmp下
sftp.put('test_paramiko_file.txt','/tmp/test_paramiko_file.txt')
transport.close()

檢查服務器/tmp目錄

 

下載結果

密鑰連接

import paramiko

private_key = paramiko.RSAKey.from_private_key_file('/home/ningherui/.ssh/id_rsa')

# 創建SSH對象
ssh = paramiko.SSHClient()
# 允許連接不在know_hosts文件中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連接服務器
ssh.connect(hostname='192.168.100.101', port=22, username='root', pkey=private_key)
# 執行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 獲取命令結果
result = stdout.read()
# 關閉連接
ssh.close()
print(result.decode('utf-8'))
print('--------------------------')
print(result.decode('utf-8')[0:9])

執行結果

3 CMDB的簡單實現

3.1 創建APP

創建一個autoserver的Django項目,並在這個項目中創建兩個App(api和web)

ningherui@ningherui-Lenovo-YOGA-720-15IKB:~/PycharmProjects/autoserver$ python3 manage.py startapp api

ningherui@ningherui-Lenovo-YOGA-720-15IKB:~/PycharmProjects/autoserver$ python3 manage.py startapp web

3.2  開發一個簡單的api

配置路由分發

/home/ningherui/PycharmProjects/autoserver/autoserver/urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('api.urls')),
]

在api的APP下創建urls

/home/ningherui/PycharmProjects/autoserver/api/urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include
from api import views
urlpatterns = [
    url('get_data', views.get_data),
]

定義views上網get_data

/home/ningherui/PycharmProjects/autoserver/api/views.py

from django.shortcuts import render,HttpResponse

# Create your views here.
def get_data(request):

    print(request.GET)
    print(request.POST)
    return HttpResponse('成功')

運行autoserver的項目

 

訪問http://127.0.0.1:8000/api/get_data 返回成功

3.3 基於paramiko開發腳本收集服務器資產信息

編寫一個腳本,定期執行獲取服務器的資產信息

import requests
def get_server_info(hostname):
    """
    獲取服務器信息
    :return:
    """
    import paramiko

    private_key = paramiko.RSAKey.from_private_key_file('/home/ningherui/.ssh/id_rsa')

    # 創建SSH對象
    ssh = paramiko.SSHClient()
    # 允許連接不在know_hosts文件中的主機
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # 連接服務器
    ssh.connect(hostname=hostname, port=22, username='root', pkey=private_key)

    # 執行命令
    stdin, stdout, stderr = ssh.exec_command('df')
    # 獲取命令結果
    result = stdout.read()

    # 關閉連接
    ssh.close()
    #對資產信息進行篩選,篩選出需要的數據
    return result.decode('utf-8')[0:9]
def run():
    #獲取服務器的信息
    info = get_server_info('192.168.100.101')
    print('連接遠程服務器獲取資產信息:',info)
    #將服務器信息發送到API平臺(負責入庫)
    # http://127.0.0.1:8000/api/get_data
    #需要import requests
    result = requests.get(
        url='http://127.0.0.1:8000/api/get_data',
        params={'host':'192.168.100.101','info':info}
    )
    print('把資產信息發送到API',result.text)
if __name__ == '__main__':
    run()

執行

查看autoserver的程序也收到請求

[09/Feb/2021 04:51:09] "GET /api/get_data?host=192.168.100.101 HTTP/1.1" 200 6
<QueryDict: {'host': ['192.168.100.101']}>
<QueryDict: {}>
[09/Feb/2021 04:52:30] "GET /api/get_data?host=192.168.100.101 HTTP/1.1" 200 6
[09/Feb/2021 04:55:29] "GET /api/get_data?host=192.168.100.101&info=Filesyste HTTP/1.1" 200 6
<QueryDict: {'host': ['192.168.100.101'], 'info': ['Filesyste']}>
<QueryDict: {}>

表示get請求發送成功

3.4 測試POST功能

import requests
def get_server_info(hostname):
    """
    獲取服務器信息
    :return:
    """
    import paramiko

    private_key = paramiko.RSAKey.from_private_key_file('/home/ningherui/.ssh/id_rsa')

    # 創建SSH對象
    ssh = paramiko.SSHClient()
    # 允許連接不在know_hosts文件中的主機
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # 連接服務器
    ssh.connect(hostname=hostname, port=22, username='root', pkey=private_key)

    # 執行命令
    stdin, stdout, stderr = ssh.exec_command('df')
    # 獲取命令結果
    result = stdout.read()

    # 關閉連接
    ssh.close()
    #對資產信息進行篩選,篩選出需要的數據
    return result.decode('utf-8')[0:9]
def run():
    #獲取服務器的信息
    info = get_server_info('192.168.100.101')
    print('連接遠程服務器獲取資產信息:',info)
    #將服務器信息發送到API平臺(負責入庫)
    # http://127.0.0.1:8000/api/get_data
    #需要import requests
    # result = requests.get(
    #     url='http://127.0.0.1:8000/api/get_data',
    #     params={'host':'192.168.100.101','info':info}
    # )
    result = requests.post(
        url='http://127.0.0.1:8000/api/get_data',
        data={'host':'192.168.100.101','info':info}
    )

    print('把資產信息發送到API',result.text)
if __name__ == '__main__':
    run()

執行有CSRF認證,403錯誤

使用裝飾器跳過csrf的認證

/home/ningherui/PycharmProjects/autoserver/api/views.py

from django.shortcuts import render,HttpResponse
from django.views.decorators.csrf import csrf_exempt
# Create your views here.  
#http請求頭:content-type(請求數據格式)
#有時候當不能使用request.GET 和request.POST獲取時,可以使用request.body獲取
@csrf_exempt def get_data(request): print(request.GET) print(request.POST) return HttpResponse('成功')

再次執行,成功

查看autoserver結果

<QueryDict: {}>
<QueryDict: {'host': ['192.168.100.101'], 'info': ['Filesyste']}>
[09/Feb/2021 05:15:26] "POST /api/get_data HTTP/1.1" 200 6

獲取數據之後,需要把數據放入數據庫,使用web頁面顯示

3.5 配置web頁面功能

配置web路由

/home/ningherui/PycharmProjects/autoserver/autoserver/urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include
from web import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('api.urls')),
    path('index/', views.index),
]

配置web的view

/home/ningherui/PycharmProjects/autoserver/web/views.py

from django.shortcuts import render

# Create your views here.
def index(request):
    """
    後臺管理首頁
    :param request:
    :return:
    """
    return render(request,'index.html')

開發indexl.html頁面,刪除autoserver本來的templates,在web下創建新的templates,並創建一個新的index.html

/home/ningherui/PycharmProjects/autoserver/web/templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>你好,世界</h1>
</body>
</html>

訪問http://127.0.0.1:8000/index/

這時並不能直接訪問,找不到頁面,需要在autoserver中註冊APP

/home/ningherui/PycharmProjects/autoserver/autoserver/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'api.apps.ApiConfig',
    'web.apps.WebConfig'
]

再次訪問http://127.0.0.1:8000/index/

4 CMDB實現過程

中控機通過Paramiko(py模塊)登錄到各個服務器上,然後執行命令的方式去獲取各個服務器上的信息

優點:無Agent 缺點:速度慢

CMDB由三部分組成,分別是:後臺管理,API接口部分,採集資產部分

採集資產:

  • 通過paramiko模塊基於ssl創建連接,並進行遠程命令的執行,以此獲取服務器的資產信息然後再進行資產信息的篩選(結構化),然後將資產信息通過api接口發送到服務端

API接口:

  • 接收採集的資產信息,並負責入庫.
  • 資產變更記錄處理 
  • 給第三方程序提供接口

後臺管理: 爲運維或運維經理提供交互,管理資產,數據統計報表等    

5 使用json格式傳輸數據

Django開發的Request數據讀取

  1. 讀取request.body,原始數據:username=ajex&password=asdc
  2. Django讀取Content-Type請求頭,如果請求頭是application/x-www-form-urlencodes,那麼django就會解析request.body的數據,生成一個QueryDict對象(類似與字典),然後將字典賦值給request.POST

request.POST.get('username')

request.POST.get('password')

代碼如下:

/home/ningherui/PycharmProjects/djangoProject1/paramiko_module/paramiko_study/app.py

import requests
def get_server_info(hostname):
    """
    獲取服務器信息
    :return:
    """
    import paramiko

    private_key = paramiko.RSAKey.from_private_key_file('/home/ningherui/.ssh/id_rsa')

    # 創建SSH對象
    ssh = paramiko.SSHClient()
    # 允許連接不在know_hosts文件中的主機
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # 連接服務器
    ssh.connect(hostname=hostname, port=22, username='root', pkey=private_key)

    # 執行命令
    stdin, stdout, stderr = ssh.exec_command('df')
    # 獲取命令結果
    result = stdout.read()

    # 關閉連接
    ssh.close()
    #對資產信息進行篩選,篩選出需要的數據
    return result.decode('utf-8')[0:9]
def run():
    #獲取服務器的信息
    info = get_server_info('192.168.100.101')
    print('連接遠程服務器獲取資產信息:',info)
    #將服務器信息發送到API平臺(負責入庫)
    # http://127.0.0.1:8000/api/get_data
    #需要import requests
    # result = requests.get(
    #     url='http://127.0.0.1:8000/api/get_data',
    #     params={'host':'192.168.100.101','info':info}
    # )
    # result = requests.post(
    #     url='http://127.0.0.1:8000/api/get_data',
    #     data={'host':'192.168.100.101','info':info}
    # )
    #使用json格式數據傳輸
    result = requests.post(
        url='http://127.0.0.1:8000/api/get_data',
        json={'host': '192.168.100.101', 'info': info}
    )

    print('把資產信息發送到API',result.text)
if __name__ == '__main__':
    run()

/home/ningherui/PycharmProjects/autoserver/api/views.py

from django.shortcuts import render,HttpResponse
from django.views.decorators.csrf import csrf_exempt
# Create your views here.
@csrf_exempt
def get_data(request):
    print(request.body)
    #序列化和反序列化
    data_str = request.body.decode('utf-8')
    import json
    data_json = json.loads(data_str)
    print(data_str,type(data_str))
    print(data_json)
    print(request.GET)
    print(request.POST)
    host= request.POST.get('host')
    info = request.POST.get('info')
    #獲取數據之後,把他們放到數據庫,然後使用web的APP展示數據
    return HttpResponse('成功')

結果如下:

Quit the server with CONTROL-C.
b'{"host": "192.168.100.101", "info": "Filesyste"}'
{"host": "192.168.100.101", "info": "Filesyste"} <class 'str'>
{'host': '192.168.100.101', 'info': 'Filesyste'}
<QueryDict: {}>
<QueryDict: {}>

views修改爲

import json
from django.shortcuts import render,HttpResponse
from django.views.decorators.csrf import csrf_exempt
# Create your views here.
@csrf_exempt
def get_data(request):
    print(request.body)
    #序列化和反序列化
    content = request.body.decode('utf-8')
    server_info_dict = json.loads(content)
    print(server_info_dict)

    #獲取數據之後,把他們放到數據庫,然後使用web的APP展示數據
    return HttpResponse('成功')

感謝老男孩教育的公開課視頻

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