aigoppb
作者aigoppb2015-04-08 16:28
系统运维工程师, 某金融单位

Django开发自动化资产管理系统

字数 18649阅读 18589评论 1赞 0

前言

  做运维工程师最头疼的估计就是做资产统计,在exec表中记录服务器的资产信息。记得我曾经去面试的时候,面试官问过我这个问题,我说我在用exec表,瞬间被鄙视了!骚年们,为了不被鄙视,一起加油吧!  

一、Django环境安装

1.1、基础环境安装

1
[root@tshare365 ~]# yum install python-devel mysql-devel zlib-devel openssl-devel  mysql mysql-server zlib zlib-devel python-pip -y

1.2、安装Django

1
[root@tshare365 local]# pip install 'django==1.6.5'

二、创建工程和应用

1
2
3
[root@tshare365 ~]# cd /usr/local/
[root@tshare365 local]# django-admin.py startproject Tshare365CMDB
[root@tshare365 Tshare365CMDB]# django-admin.py startapp hostinfo

三、应用配置

3.1、修改工程配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'hostinfo', #添加我们创建的应用
)
MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
  #  'django.middleware.csrf.CsrfViewMiddleware',  注释 csrf 校验
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
 
LANGUAGE_CODE = 'zh-cn'   #修改成中文
 
TIME_ZONE = 'Asia/Shanghai'   #修改时区

3.2、定义搜集主机信息的数据模型(也就是字段名和数据类型)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@tshare365 Tshare365CMDB]# vim hostinfo/models.py 
 
from django.db import models
 
# Create your models here.
class Host(models.Model):
    hostname = models.CharField(max_length=50)
    ip = models.IPAddressField()
    osversion = models.CharField(max_length=50)
    memory = models.CharField(max_length=50)
    disk = models.CharField(max_length=50)
    vendor_id = models.CharField(max_length=50)
    model_name = models.CharField(max_length=50)
    cpu_core = models.CharField(max_length=50)
    product = models.CharField(max_length=50)
    Manufacturer = models.CharField(max_length=50)
    sn = models.CharField(max_length=50)

3.3、初始化模型数据库并生成数据库文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@tshare365 Tshare365CMDB]# python manage.py  syncdb
Creating tables ...
Creating table django_admin_log
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_groups
Creating table auth_user_user_permissions
Creating table auth_user
Creating table django_content_type
Creating table django_session
Creating table hostinfo_host
 
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use 'root'): admin     #登陆后台用户名
Email address: 123@qq.com
Password:                                       #登陆后台密码
Password (again):                
Superuser created successfully.
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
[root@tshare365 Tshare365CMDB]#

3.4、注册后台admin并显示注册信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@tshare365 Tshare365CMDB]# vim hostinfo/admin.py 
 
from django.contrib import admin
from hostinfo.models import Host
class HostAdmin(admin.ModelAdmin):
    list_display = [
                'hostname',
                'ip',
                'osversion',
                'memory',
                'disk',
                'vendor_id',
                'model_name',
                'cpu_core',
                'product',
                'Manufacturer',
                'sn']
 
admin.site.register(Host,HostAdmin)

3.5、定义用户的响应请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
[root@tshare365 Tshare365CMDB]# vim hostinfo/views.py 
 
from django.shortcuts import render
from django.shortcuts import render
from django.http import HttpResponse
from hostinfo.models import Host
 
# Create your views here.
def index(req):
    print req
    if req.method == 'POST':
        hostname = req.POST.get('hostname')
        ip = req.POST.get('ip')
        osversion = req.POST.get('osversion')
        memory = req.POST.get('memory')
        disk = req.POST.get('disk')
        vendor_id = req.POST.get('vendor_id')
        model_name = req.POST.get('model_name')
        cpu_core = req.POST.get('cpu_core')
        product = req.POST.get('product')
        Manufacturer = req.POST.get('Manufacturer')
        sn = req.POST.get('sn')
        try:
            host = Host.objects.get(hostname=hostname)
        except:
            host = Host()
  
        host.hostname = hostname
        host.ip = ip
        host.osversion = osversion
        host.memory = memory
        host.disk = disk
        host.vendor_id = vendor_id
        host.model_name = model_name
        host.cpu_core = cpu_core
        host.product = product
        host.Manufacturer = Manufacturer
        host.sn = sn
        host.save()
  
        return HttpResponse('ok')
    else:
        return HttpResponse('no data')

3.6、添加应用的url访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@tshare365 Tshare365CMDB]# vim Tshare365CMDB/urls.py
 
from django.conf.urls import patterns, include, url
 
from django.contrib import admin
admin.autodiscover()
 
urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'Tshare365CMDB.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),
 
    url(r'^admin/', include(admin.site.urls)),
    url(r'^hostinfo$','hostinfo.views.index'),
)

四、启动Django服务

1
[root@tshare365 Tshare365CMDB]# python manage.py runserver 0.0.0.0:80

1

2

 

五、以下是用Python实现对Linux主机的信息采集脚本

搜集的信息主要包括:主机名、ip、系统版本、硬盘、内存、cpu的个数、cpu的厂商、序列号和生产商

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python
# site www.tshare365.com
from subprocess import Popen,PIPE
import urllib,urllib2
import pickle
import json
import re
 
###[hostname message]#####
def get_HostnameInfo(file):
    with open(file,'r') as fd:
        data = fd.read().split('n')
        for line in data:
            if line.startswith('HOSTNAME'):
                hostname = line.split('=')[1]
                break
    return hostname
 
#####[ipaddr message]#####
def get_Ipaddr():
    P = Popen(['ifconfig'],stdout=PIPE)
    data = P.stdout.read()
    list = []
    str = ''
    option = False
    lines = data.split('n')
    for line in lines:
        if not line.startswith(' '):
            list.append(str)
            str = line
        else:
            str += line
    while True:
        if '' in list:
            list.remove('')
        else:
            break
    r_devname = re.compile('(ethd*|lo)')
    r_mac = re.compile('HWaddrs([A-F0-9:]{17})')
    r_ip = re.compile('addr:([d.]{7,15})')
    for line in list:
        devname = r_devname.findall(line)
        mac = r_mac.findall(line)
        ip = r_ip.findall(line)
        if mac:
            return  ip[0]
  
#####[osversion message]#####
def get_OsVerion(file):
    with open(file) as fd:
       lines = fd.readlines()
       os_version = lines[0][:-8]
    return os_version
 
#####[memory message]#####
def get_MemoryInfo(file):
   with open(file) as fd:
        data_list = fd.read().split('n')
        MemTotal_line = data_list[0]
        Memory_K = MemTotal_line.split()[1]
        Memory_G = float(Memory_K)/1000/1000
        Memory_G2 = '%.2f' % Memory_G
        memory = Memory_G2 + 'G'
        return memory
 
#####[disk message]#####
def get_DiskInfo():
    p = Popen(['fdisk','-l'],stdout=PIPE,stderr=PIPE)
    stdout,stderr = p.communicate()
    diskdata = stdout
 
    disk_initial_size = 0
    re_disk_type = re.compile(r'Disk /dev/[shd]{1}.*:s+[d.sw]*,s+([d]+).*')
    disk_size_bytes = re_disk_type.findall(diskdata)
    for size in disk_size_bytes:
        disk_initial_size += int(size)
        disk_size_total_bytes = '%.2f'  % (float(disk_initial_size)/1000/1000/1000)
        disk_size_total_G = disk_size_total_bytes + 'G'
        disk = disk_size_total_G
    return disk
 
#####[cpu message]#####
def get_CpuInfo():
    p = Popen(['cat','/proc/cpuinfo'],stdout=PIPE,stderr=PIPE)
    stdout, stderr = p.communicate()
    cpudata = stdout.strip()
 
    cpu_dict = {}
    re_cpu_cores = re.compile(r'processors+:s+([d])')
    re_vendor_id = re.compile(r'vendor_ids+:s([w]+)')
    re_model_name = re.compile(r'model names+:s+(.*)')
 
    res_cpu_cores = re_cpu_cores.findall(cpudata)
    cpu_dict['Cpu_Cores'] = int(res_cpu_cores[-1]) + 1
    res_vendor_id = re_vendor_id.findall(cpudata)
    cpu_dict['Vendor_Id'] = res_vendor_id[-1]
    res_model_name = re_model_name.findall(cpudata)
    cpu_dict['Model_Name'] = res_model_name[-1]
    return cpu_dict
 
#####[Demi message]#####
def get_dmidecode():
    P = Popen(['dmidecode'],stdout=PIPE)
    data = P.stdout.read()
    lines = data.split('nn')
    dmidecode_line =  lines[2]
    line = [i.strip() for i in dmidecode_line.split('n') if i]
    Manufacturer = line[2].split(': ')[-1]
    product = line[3].split(': ')[-1]
    sn = line[5].split(': ')[-1]
    return Manufacturer,product,sn
 
if __name__ == '__main__':
    #####[get data]#####
    hostname = get_HostnameInfo('/etc/sysconfig/network')
    ip = get_Ipaddr()
    osversion = get_OsVerion('/etc/issue')
    memory = get_MemoryInfo('/proc/meminfo')
    disk = get_DiskInfo()
    Vendor_Id = get_CpuInfo()['Vendor_Id']
    Model_Name = get_CpuInfo()['Model_Name']
    Cpu_Cores = get_CpuInfo()['Cpu_Cores']
    Manufacturer,product,sn = get_dmidecode()
 
    #####[get dict]##### 
    hostinfo = {
    'hostname':hostname,
    'ip':ip,
    'osversion':osversion,
    'memory':memory,
    'disk':disk,
    'vendor_id':Vendor_Id,
    'model_name':Model_Name,
    'cpu_core':Cpu_Cores,
    'product':product,
    'Manufacturer':Manufacturer,
    'sn':sn,
    }
  
    data = urllib.urlencode(hostinfo)
    req = urllib2.urlopen('http://192.168.1.87/hostinfo',data)

 

此脚本需要注意两处:

1、脚本目前只能在CentOS系统上运行,非CentOS系统会报异常,比如文件找不到等

2、执行脚本前需要先安装一个包(demidecode),这个包可以搜集主机的部分信息

1
2
[root@tshare365 ~]# yum -y install dmidecode
[root@tshare365 ~]# python post_hostinfo.py

刷新admin页面查看hosts信息

4

在自动化运维中,我们可以通过自动化工具将post_hostinfo.py脚本推送到其他节点上或者在在cobbler安装系统的时候就增加此脚本,并在crontab中定时执行,以此实现自动化资产管理

 

本博客自此介绍,后续还会继续完善此项目,如果有什么问题,请留言!

 

 

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

0

添加新评论1 条评论

#peter_211系统运维工程师, ichano
2016-06-29 15:20
好文。
Ctrl+Enter 发表