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('成功')

感谢老男孩教育的公开课视频

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