上篇博客中已经介绍过Django的安装和基本使用,如果大家还有不明白请参考我的博客
Python [4] Django的安装和基础运行环境简介
http://467754239.blog.51cto.com/4878013/1613612
这篇博客和大家聊聊Python结合Django实现IT资产管理
基础环境:
1
2
3
4
|
系统版本:CentOS 6.4 64bit
Python版本:2.6
Django版本:1.6.5
ip地址:192.168.1.210
|
一、安装Django环境
1
2
3
4
5
|
# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
# sed -i 's@^#@@' /etc/yum.repos.d/epel.repo
# sed -i 's@mirrorlist@#mirrorlist@' /etc/yum.repos.d/epel.repo
# yum -y install python-pip
# pip install 'django==1.6.5'
|
二、创建工程和应用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
[root@localhost ~]
# django-admin.py startproject Simplecmdb
[root@localhost ~]
# cd Simplecmdb/
[root@localhost Simplecmdb]
# django-admin.py startapp hostinfo
[root@localhost Simplecmdb]
# tree ./
./
├── hostinfo
│ ├── admin.py
│ ├── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── manage.py
└── Simplecmdb
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
2 directories, 10 files
|
三、配置应用
1、修改工程配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
[root@localhost Simplecmdb]
# vim Simplecmdb/settings.py
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',#注释此行(默认禁止第三方curl工具使用)
'django.contrib.auth.middleware.AuthenticationMiddleware'
,
'django.contrib.messages.middleware.MessageMiddleware'
,
'django.middleware.clickjacking.XFrameOptionsMiddleware'
,
)
LANGUAGE_CODE =
'zh-cn'
#修改字符集
TIME_ZONE =
'Asia/Shanghai'
#修改时区
|
2、添加应用的url访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[root@localhost Simplecmdb]
# cat Simplecmdb/urls.py
from django.conf.urls
import
patterns, include, url
from django.contrib
import
admin
admin.autodiscover()
urlpatterns = patterns(
''
,
# Examples:
# url(r'^$', 'Simplecmdb.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r
'^admin/'
, include(admin.site.urls)),
url(r
'^hostinfo$'
,
'hostinfo.views.index'
),
#访问的url路径
)
|
1
2
3
4
|
解释:hostinfo.views.index
hostinfo:创建的应用和工程在同一级目录
views:视图文件,定义请求的响应就是由这个文件定义的
index:是视图文件中定义的一个函数名
|
3、定义搜集主机信息的数据模型(也就是字段名和数据类型)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
[root@localhost Simplecmdb]
# cat 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)
|
4、初始化模型数据库并生成数据库文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
[root@localhost Simplecmdb]
# 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'
): root
Email address: zhengyansheng@nihao.com
Password:
#后台admin的登陆密码
Password (again):
Superuser created successfully.
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
|
5、注册后台admin并显示注册信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
[root@localhost Simplecmdb]
# vim hostinfo/admin.py #注册数据库
from django.contrib
import
admin
from hostinfo.models
import
Host
# Register your models here.
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)
|
6、定义用户的响应请求
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
|
[root@localhost Simplecmdb]
# vim hostinfo/views.py
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'
)
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'
)
|
三、运行django的工程服务
1
2
3
4
5
6
7
8
9
|
[root@localhost ~]
# cd /root/Simplecmdb/
[root@localhost Simplecmdb]
# python manage.py runserver 0.0.0.0:80
Validating models...
0 errors found
March 02, 2015 - 16:11:12
Django version 1.6.5, using settings
'Simplecmdb.settings'
Starting development server at http:
//0
.0.0.0:80/
Quit the server with CONTROL-C.
|
四、浏览器访问页面
1、访问主页面
1
|
因为我们没有传送任何数据,所以返回我们定义的字符串
"no data"
|
1
|
注册的账号是root,密码为123456
|
五、以下是用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
142
143
144
145
|
[root@localhost ~]
# cat post_hostinfo.py
#!/usr/bin/env python
#coding:utf8
#author:Allentuns
#time:2015-02-14
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(
'(eth\d*|lo)'
)
r_mac = re.compile(
'HWaddr\s([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.\s\w]*,\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
'processor\s+:\s+([\d])'
)
re_vendor_id = re.compile(r
'vendor_id\s+:\s([\w]+)'
)
re_model_name = re.compile(r
'model name\s+:\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
(
'\n\n'
)
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.210:80/hostinfo'
,data)
|
此脚本需要注意两处:
1、脚本目前只能在CentOS系统上运行,非CentOS系统会报异常,比如文件找不到等
2、执行脚本前需要先安装一个包(demidecode),这个包可以搜集主机的部分信息
1
2
|
[root@localhost ~]
# yum -y install dmidecode
[root@localhost ~]
# python post_hostinfo.py
|
然后刷新后台admin的页面
以上配置还有问题,就是不能保证主机的唯一性,如果反复执行上述脚本会得到以下结果
这个问题可以这样解决,用户执行脚本然后传递参数到服务器,服务器可以做个判断,如果传递的参数已经存在,那么我们不保存此信息,如果是更新,那么我们重新赋值并保存到数据库中
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
|
[root@localhost Simplecmdb]
# cat hostinfo/views.py
from django.shortcuts
import
render
from django.http
import
HttpResponse
from hostinfo.models
import
Host
# Create your views here.
def index(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'
)
|
最终显示的效果如下:
六、主机分组
1、如下图所示:在web高可用集群中,多台服务器提供同一类服务是非常正常的,就比如web前端使用多台nginx和keepalived做高可用,后端应用比如tomcat提供用于的请求响应,像以上这两类我们可以单独进行分组划分。
2、修改配置文件定义主机组
首先在hostinfo应用中添加定义组的数据结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
[root@localhost Simplecmdb]
# 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)
#添加以下行
class HostGroup(models.Model):
groupname = models.CharField(max_length=50)
members = models.ManyToManyField(Host)
|
其次检查语法并同步数据库
1
2
3
4
5
6
7
8
|
[root@localhost Simplecmdb]
# python manage.py validate
0 errors found
[root@localhost Simplecmdb]
# python manage.py syncdb
Creating tables ...
Creating table hostinfo_hostgroup_members
Creating table hostinfo_hostgroup
Installing custom SQL ...
Installing indexes ...
|
最后注册admin并能在admin页面显示
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
|
[root@localhost Simplecmdb]
# vim hostinfo/admin.py
from django.contrib
import
admin
from hostinfo.models
import
Host
from hostinfo.models
import
HostGroup
#添加此行
# Register your models here.
class HostAdmin(admin.ModelAdmin):
list_display = [
'hostname'
,
'ip'
,
'osversion'
,
'memory'
,
'disk'
,
'vendor_id'
,
'model_name'
,
'cpu_core'
,
'product'
,
'Manufacturer'
,
'sn'
]
#添加以下行
class HostGroupAdmin(admin.ModelAdmin):
list_display = [
'groupname'
]
admin.site.register(Host,HostAdmin)
admin.site.register(HostGroup,HostGroupAdmin)
|
浏览器访问admin页面
问题来了,怎么Member都显示的是Host object啊?其实原因出在这里
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
[root@localhost Simplecmdb]
# 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)
class HostGroup(models.Model):
groupname = models.CharField(max_length=50)
members = models.ManyToManyField(Host)
|
Host和HostGroup都是类,而HostGroup中的members引用上面的Host类,返回值就是一个对象,我们应该在Host类中添加定义一个函数,然后返回我们想要的值就Ok啦
修改代码如下:
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@localhost Simplecmdb]
# 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)
def __str__(self):
return
self.
hostname
class HostGroup(models.Model):
groupname = models.CharField(max_length=50)
members = models.ManyToManyField(Host)
|
然后同步数据库
1
2
3
4
5
|
[root@localhost Simplecmdb]
# python manage.py syncdb
Creating tables ...
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
|
再次刷新之前的页面
3、定义组名和添加组成员
上述所涉及到的还存在一定的问题:我们总不能手动一个个上传此Python脚本到各个客户机,然后在执行此脚本,显然不符合自动化的要求;按自动化的思路来讲,我们应该主动发现同网段的所有主机,然后自动加主机加入到同一个新组中,然后对这个组进行执行上传、执行脚本的工作。这样就省去了很多的麻烦,后续也会继续补上此类的脚本。
Python[6] IT资产管理(下)
http://467754239.blog.51cto.com/4878013/1616806
本文转自zys467754239 51CTO博客,原文链接:http://blog.51cto.com/467754239/1616551,如需转载请自行联系原作者