一 发送数据到api(Django的URL)

发送请求携带参数

requests.get(url='http://127.0.0.1:8000/api/asset/?k1=123')   # <QueryDict: {'k1': ['123']}>
requests.get(url='http://127.0.0.1:8000/api/asset/',params={'k1':'v1','k2':'v2'}) # <QueryDict: {'k2': ['v2'], 'k1': ['v1']}>

get传参

requests.post(
url='http://127.0.0.1:8000/api/asset/',
params={'k1':'v1','k2':'v2'}, # GET形式传值 URL<QueryDict: {'k2': ['v2'], 'k1': ['v1']}>
data={'username':'','pwd': ''}, # POST形式传值 请求体 <QueryDict: {'pwd': ['666'], 'username': ['1123']}>
headers={'a':''} # 请求头数据
)
requests.body b'username=1123&pwd=666'

post传参

api需要post请求,并且有一定的数据格式

# 数据格式
host_data = {
'status': True,
'data':{
'hostname': 'c1.com',
'disk': {'status':True,'data': 'xxx'},
'mem': {'status':True,'data': 'xxx'},
'nic': {'status':True,'data': 'xxx'},
}
} # 模拟给API发送资产信息
response = requests.post(
url='http://127.0.0.1:8000/api/asset/',
# 序列化
# data=host_data, # 列表 <QueryDict: {'data': ['nic', 'disk', 'hostname', 'mem'], 'status': ['True']}>
json=host_data, # reuest.body 里面 # 字典 b'{"status": true,
# "data": {
# "disk": {"status": true, "data": "xxx"},
# "nic": {"status": true, "data": "xxx"},
# "hostname": "c1.com",
# "mem": {"status": true, "data": "xxx"}}
# }'
)
print(response.text) # 得到是 django执行的返回值 ...

post序列化请求

而我们客户端传送这样的数据格式的时候,用到了lib下的serialize,response俩个模块来对数据进行格式化

#!/usr/bin/env python
# -*- coding:utf-8 -*- class BaseResponse(object):
def __init__(self):
self.status = True
self.message = None
self.data = None
self.error = None

response模块

每一个资产信息都继承了response这个模块,最终得到一个对象,如下

{
status = True
message = None
data = os_platform:'',os_version:'',hostname:'','cpu':OBJ,'disk':OBJ} 这个OBJ会在交给自己写的JSON.dump去处理
error = None
}

资产对象字典

然后经过serialize模块处理

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import json as default_json
from json.encoder import JSONEncoder
from .response import BaseResponse # 例子来源于本目录TEST {"k1": 123, "k2": "2018-03-13 18", "k3": {"status": true, "data": "asdf"}}
class JsonEncoder(JSONEncoder):
# O 就是字典的VULe
def default(self, o):
if isinstance(o, BaseResponse):
# 用O.__DICT__处理 { "k3": {"status": true, "data": "asdf"}} 字典套字典
return o.__dict__
# 用默认的数据类型
return JSONEncoder.default(self, o) # 自己写的JSON数,JSON.DUMP 只能序列PYTHON内部数据格式,对象不行,时间对象
class Json(object):
@staticmethod
def dumps(response, ensure_ascii=True): # cls=JsonEncoder 自定义序列化
return default_json.dumps(response, ensure_ascii=ensure_ascii, cls=JsonEncoder) # 传过来的是response.date,也就是说传过来的是
'''{ data = {os_platform:'',os_version:'',hostname:'','cpu':OBJ} 这个OBJ是BaseResponse对象,所以格式化成
cpu:{
self.status = True
self.message = None
self.data = None
self.error = None
}
}'''

serialize模块

这样我就拿到了一个json数据,格式如下

{
"disk": {
"message": null,
"error": null,
"data": {
"": {
"model": "SEAGATE ST300MM0006 LS08S0K2B5NV",
"capacity": "279.396",
"pd_type": "SAS",
"slot": ""
},
"": {
"model": "S1AXNSAFB00549A Samsung SSD 840 PRO Series DXM06B0Q",
"capacity": "476.939",
"pd_type": "SATA",
"slot": ""
},
"": {
"model": "S1AXNSAF303909M Samsung SSD 840 PRO Series DXM05B0Q",
"capacity": "476.939",
"pd_type": "SATA",
"slot": ""
},
"": {
"model": "S1AXNSAF912433K Samsung SSD 840 PRO Series DXM06B0Q",
"capacity": "476.939",
"pd_type": "SATA",
"slot": ""
},
"": {
"model": "S1SZNSAFA01085L Samsung SSD 850 PRO 512GB EXM01B6Q",
"capacity": "476.939",
"pd_type": "SATA",
"slot": ""
},
"": {
"model": "SEAGATE ST300MM0006 LS08S0K2B5AH",
"capacity": "279.396",
"pd_type": "SAS",
"slot": ""
}
},
"status": true
},
"os_version": "CentOS release 6.6 (Final)",
"os_platform": "linux",
"hostname": "bj.com"
}

包含基本信息和硬盘

api处接受到请求的处理

 if request.method == 'POST':  # GET 模式不用走这里,因为BODY 里面没有值,肯定会报错
import json
host_info = json.loads(str(request.body,encoding='utf-8'))
print(host_info)
}
return HttpResponse('....')

post请求处理

二 api验证

第一种:发送一个字符串auth_key

1. 首先可以发送请求的时候,发过来一个验证token

host_data = {
'status': True,
'data':{
'hostname': 'c1.com',
'disk': {'status':True,'data': 'xxx'},
'mem': {'status':True,'data': 'xxx'},
'nic': {'status':True,'data': 'xxx'},
}
} # 模拟给API发送资产信息
response = requests.post(
url='http://127.0.0.1:8000/api/asset/',
# 序列化
json=host_data, }'
# 模拟发送个验证TOKEN
headers={'authkey': ''}
)
print(response.text) # 得到是 django执行的返回值 ...

post序列化验证请求

2. 在api处获取到这个token,进行校验,在处理post请求数据

from django.shortcuts import render, HttpResponse
from django.views.decorators.csrf import csrf_exempt, csrf_protect @csrf_exempt
def asset(request):
auth_key = request.GET.get('HTTP_AUTHKEY')
auth_key = request.META['HTTP_AUTHKEY'] # 会存在这里面反过来的KEY
ck = 123456
if auth_key != ck:
return HttpResponse('授权失败')
if request.method == 'POST': # GET 模式不用走这里,因为BODY 里面没有值,肯定会报错
import json
host_info = json.loads(str(request.body,encoding='utf-8'))
print(host_info)
# {'status': True,
# 'data': {
# 'hostname': 'c1.com',
# 'mem': {'status': True, 'data': 'xxx'},
# 'disk': {'status': True, 'data': 'xxx'},
# 'nic': {'status': True, 'data': 'xxx'}}
# }
return HttpResponse('....')

post验证请求处理

存在的问题就是,有可能这个请求被截胡,很可能会被其他人获取到这个token

第二种:md5加密字符串    很可能会被其他人获取到这个token

## MD5加密的验证TOKEN
appid = ''
m = hashlib.md5()
m.update(bytes(appid,encoding='utf-8'))
authkey = m.hexdigest()
print(authkey) # e10adc3949ba59abbe56e057f20f883e host_data = {
'status': True,
'data':{
'hostname': 'c1.com',
'disk': {'status':True,'data': 'xxx'},
'mem': {'status':True,'data': 'xxx'},
'nic': {'status':True,'data': 'xxx'},
}
} # 模拟给API发送资产信息
response = requests.post(
url='http://127.0.0.1:8000/api/asset/',
# 序列化
# data=host_data, # 列表 <QueryDict: {'data': ['nic', 'disk', 'hostname', 'mem'], 'status': ['True']}>
json=host_data, # reuest.body 里面 # 字典 b'{"status": true, # 模拟发送个验证TOKEN
headers={'authkey': authkey}
)
print(response.text) # 得到是 django执行的返回值 ...

post序列化请求md5字符串验证

from django.shortcuts import render, HttpResponse
from django.views.decorators.csrf import csrf_exempt, csrf_protect @csrf_exempt
def asset(request):
print(request.method)
print(request.POST)
print(request.GET)
print(request.body) auth_key = request.GET.get('HTTP_AUTHKEY')
auth_key = request.META['HTTP_AUTHKEY'] # 会存在这里面反过来的KEY
ck = 123456
if auth_key != ck:
return HttpResponse('授权失败')
if request.method == 'POST': # GET 模式不用走这里,因为BODY 里面没有值,肯定会报错
import json
host_info = json.loads(str(request.body,encoding='utf-8'))
print(host_info)
# {'status': True,
# 'data': {
# 'hostname': 'c1.com',
# 'mem': {'status': True, 'data': 'xxx'},
# 'disk': {'status': True, 'data': 'xxx'},
# 'nic': {'status': True, 'data': 'xxx'}}
# }
return HttpResponse('....')
# 获取到的数据格式
# request.body 内容
# 字典 b'{"status": true,
# "data": {
# "disk": {"status": true, "data": "xxx"},
# "nic": {"status": true, "data": "xxx"},
# "hostname": "c1.com",
# "mem": {"status": true, "data": "xxx"}}
# }'

post处理加密字符串认证

第三种:md5时间动态加密字符串    漏洞更多,很可能会被其他人获取到这个token,可以访问很多的url

# 时间动态加密
current_time = time.time()
app_id = "8kasoimnasodn8687asdfkmasdf"
app_id_time = "%s|%s" %(app_id,current_time,) m = hashlib.md5()
m.update(bytes(app_id_time,encoding='utf-8'))
authkey = m.hexdigest() # 将加密验证TOKEN和时间带过去
authkey_time = "%s|%s" %(authkey,current_time,)
print(authkey_time)
# 2746e6acc0c36f31d68dd6a166b434be|1520910092.340296 host_data = {
'status': True,
'data':{
'hostname': 'c1.com',
'disk': {'status':True,'data': 'xxx'},
'mem': {'status':True,'data': 'xxx'},
'nic': {'status':True,'data': 'xxx'},
}
} # 模拟给API发送资产信息
response = requests.post(
url='http://127.0.0.1:8000/api/asset/',
# 序列化
json=host_data, # reuest.body 里面 # 字典 b'{"status": true, # 模拟发送个验证TOKEN
headers={'authkey': authkey_time}
)
print(response.text) # 得到是 django执行的返回值 ...

post序列化请求md5动态时间验证

from django.shortcuts import render, HttpResponse
from django.views.decorators.csrf import csrf_exempt, csrf_protect
import hashlib
import time ck = "8kasoimnasodn8687asdfkmasdf" auth_list = [] @csrf_exempt
def asset(request):
# 发过来的验证TOKEN auth_key:2746e6acc0c36f31d68dd6a166b434be|client_ctime:1520910092.340296
# 客户端发过来的时间验证
auth_key_time = request.META['HTTP_AUTHKEY']
auth_key_client, client_ctime = auth_key_time.split('|') # 我这里的时间验证
key_time = "%s|%s" % (ck, client_ctime,)
m = hashlib.md5()
m.update(bytes(key_time, encoding='utf-8'))
authkey = m.hexdigest() if authkey != auth_key_client: # 判断 2次加密后的TOKEN
return HttpResponse('授权失败')
return HttpResponse('....')

post处理加密时间认证

第四种:通过时间规则限制,模仿cookie

# 时间动态加密
current_time = time.time()
app_id = "8kasoimnasodn8687asdfkmasdf"
app_id_time = "%s|%s" %(app_id,current_time,) m = hashlib.md5()
m.update(bytes(app_id_time,encoding='utf-8'))
authkey = m.hexdigest() # 将加密验证TOKEN和时间带过去
authkey_time = "%s|%s" %(authkey,current_time,)
print(authkey_time)
# 2746e6acc0c36f31d68dd6a166b434be|1520910092.340296 host_data = {
'status': True,
'data':{
'hostname': 'c1.com',
'disk': {'status':True,'data': 'xxx'},
'mem': {'status':True,'data': 'xxx'},
'nic': {'status':True,'data': 'xxx'},
}
} # 模拟给API发送资产信息
response = requests.post(
url='http://127.0.0.1:8000/api/asset/',
# 序列化
json=host_data, # reuest.body 里面 # 字典 b'{"status": true, # 模拟发送个验证TOKEN
headers={'authkey': authkey_time}
)
print(response.text) # 得到是 django执行的返回值 ...

psot序列化请求md5动态时间验证

from django.shortcuts import render, HttpResponse
from django.views.decorators.csrf import csrf_exempt, csrf_protect
import hashlib
import time ck = "8kasoimnasodn8687asdfkmasdf" # 访问时间列表,应该设置过期时间,MEMCACHE,REDIS都可以做
auth_list = [] @csrf_exempt
def asset(request):
# 发过来的验证TOKEN 客户端发过来的时间验证
auth_key_time = request.META['HTTP_AUTHKEY']
# auth_key_client:2746e6acc0c36f31d68dd6a166b434be | client_ctime:1520910092.340296
auth_key_client, client_ctime = auth_key_time.split('|') # 1。时间规则 久远排除掉
server_current_time = time.time()
if server_current_time - 5 > float(client_ctime):
return HttpResponse('时间太久远了') # 2。是不是来过
if auth_key_time in auth_list:
return HttpResponse('已经访问过了,所以你是木马') # 3。我这里的时间验证
key_time = "%s|%s" % (ck, client_ctime,)
m = hashlib.md5()
m.update(bytes(key_time, encoding='utf-8'))
authkey = m.hexdigest() if authkey != auth_key_client:
return HttpResponse('授权失败')
# 访问成功
auth_list.append(auth_key_time)
print(auth_list)
return HttpResponse('....')

post处理加密动态时间认证

三 表结构

from django.db import models

class UserProfile(models.Model):
"""
用户信息
"""
name = models.CharField(u'姓名', max_length=32)
email = models.EmailField(u'邮箱')
phone = models.CharField(u'座机', max_length=32)
mobile = models.CharField(u'手机', max_length=32) class Meta:
verbose_name_plural = "用户表" def __str__(self):
return self.name class AdminInfo(models.Model):
"""
用户登陆相关信息
"""
user_info = models.OneToOneField("UserProfile") username = models.CharField(u'用户名', max_length=64)
password = models.CharField(u'密码', max_length=64) class Meta:
verbose_name_plural = "管理员表" def __str__(self):
return self.user_info.name class UserGroup(models.Model):
"""
用户组
"""
name = models.CharField(max_length=32, unique=True)
users = models.ManyToManyField('UserProfile') class Meta:
verbose_name_plural = "用户组表" def __str__(self):
return self.name class BusinessUnit(models.Model):
"""
业务线
"""
name = models.CharField('业务线', max_length=64, unique=True)
contact = models.ForeignKey('UserGroup', verbose_name='业务联系人', related_name='c') # 多个人
manager = models.ForeignKey('UserGroup', verbose_name='系统管理员', related_name='m') # 多个人 class Meta:
verbose_name_plural = "业务线表" def __str__(self):
return self.name class IDC(models.Model):
"""
机房信息
"""
name = models.CharField('机房', max_length=32)
floor = models.IntegerField('楼层', default=1) class Meta:
verbose_name_plural = "机房表" def __str__(self):
return self.name class Tag(models.Model):
"""
资产标签
"""
name = models.CharField('标签', max_length=32, unique=True) class Meta:
verbose_name_plural = "标签表" def __str__(self):
return self.name class Asset(models.Model):
"""
资产信息表,所有资产公共信息(交换机,服务器,防火墙等)
"""
device_type_choices = (
(1, '服务器'),
(2, '交换机'),
(3, '防火墙'),
)
device_status_choices = (
(1, '上架'),
(2, '在线'),
(3, '离线'),
(4, '下架'),
) device_type_id = models.IntegerField(choices=device_type_choices, default=1)
device_status_id = models.IntegerField(choices=device_status_choices, default=1) cabinet_num = models.CharField('机柜号', max_length=30, null=True, blank=True)
cabinet_order = models.CharField('机柜中序号', max_length=30, null=True, blank=True) idc = models.ForeignKey('IDC', verbose_name='IDC机房', null=True, blank=True)
business_unit = models.ForeignKey('BusinessUnit', verbose_name='属于的业务线', null=True, blank=True) tag = models.ManyToManyField('Tag') latest_date = models.DateField(null=True)
create_at = models.DateTimeField(auto_now_add=True) class Meta:
verbose_name_plural = "资产表" def __str__(self):
return "%s-%s-%s" % (self.idc.name, self.cabinet_num, self.cabinet_order) class Server(models.Model):
"""
服务器信息
"""
asset = models.OneToOneField('Asset') hostname = models.CharField(max_length=128, unique=True)
sn = models.CharField('SN号', max_length=64, db_index=True)
manufacturer = models.CharField(verbose_name='制造商', max_length=64, null=True, blank=True)
model = models.CharField('型号', max_length=64, null=True, blank=True) manage_ip = models.GenericIPAddressField('管理IP', null=True, blank=True) os_platform = models.CharField('系统', max_length=16, null=True, blank=True)
os_version = models.CharField('系统版本', max_length=16, null=True, blank=True) cpu_count = models.IntegerField('CPU个数', null=True, blank=True)
cpu_physical_count = models.IntegerField('CPU物理个数', null=True, blank=True)
cpu_model = models.CharField('CPU型号', max_length=128, null=True, blank=True) create_at = models.DateTimeField(auto_now_add=True, blank=True) class Meta:
verbose_name_plural = "服务器表" def __str__(self):
return self.hostname class NetworkDevice(models.Model):
asset = models.OneToOneField('Asset')
management_ip = models.CharField('管理IP', max_length=64, blank=True, null=True)
vlan_ip = models.CharField('VlanIP', max_length=64, blank=True, null=True)
intranet_ip = models.CharField('内网IP', max_length=128, blank=True, null=True)
sn = models.CharField('SN号', max_length=64, unique=True)
manufacture = models.CharField(verbose_name=u'制造商', max_length=128, null=True, blank=True)
model = models.CharField('型号', max_length=128, null=True, blank=True)
port_num = models.SmallIntegerField('端口个数', null=True, blank=True)
device_detail = models.CharField('设置详细配置', max_length=255, null=True, blank=True) class Meta:
verbose_name_plural = "网络设备" class Disk(models.Model):
"""
硬盘信息
"""
slot = models.CharField('插槽位', max_length=8)
model = models.CharField('磁盘型号', max_length=32)
capacity = models.FloatField('磁盘容量GB')
pd_type = models.CharField('磁盘类型', max_length=32)
server_obj = models.ForeignKey('Server',related_name='disk') class Meta:
verbose_name_plural = "硬盘表" def __str__(self):
return self.slot class NIC(models.Model):
"""
网卡信息
"""
name = models.CharField('网卡名称', max_length=128)
hwaddr = models.CharField('网卡mac地址', max_length=64)
netmask = models.CharField(max_length=64)
ipaddrs = models.CharField('ip地址', max_length=256)
up = models.BooleanField(default=False)
server_obj = models.ForeignKey('Server',related_name='nic') class Meta:
verbose_name_plural = "网卡表" def __str__(self):
return self.name class Memory(models.Model):
"""
内存信息
"""
slot = models.CharField('插槽位', max_length=32)
manufacturer = models.CharField('制造商', max_length=32, null=True, blank=True)
model = models.CharField('型号', max_length=64)
capacity = models.FloatField('容量', null=True, blank=True)
sn = models.CharField('内存SN号', max_length=64, null=True, blank=True)
speed = models.CharField('速度', max_length=16, null=True, blank=True) server_obj = models.ForeignKey('Server',related_name='memory') class Meta:
verbose_name_plural = "内存表" def __str__(self):
return self.slot class AssetRecord(models.Model):
"""
资产变更记录,creator为空时,表示是资产汇报的数据。
"""
asset_obj = models.ForeignKey('Asset', related_name='ar')
content = models.TextField(null=True)
creator = models.ForeignKey('UserProfile', null=True, blank=True)
create_at = models.DateTimeField(auto_now_add=True) class Meta:
verbose_name_plural = "资产记录表" def __str__(self):
return "%s-%s-%s" % (self.asset_obj.idc.name, self.asset_obj.cabinet_num, self.asset_obj.cabinet_order) class ErrorLog(models.Model):
"""
错误日志,如:agent采集数据错误 或 运行错误
"""
asset_obj = models.ForeignKey('Asset', null=True, blank=True)
title = models.CharField(max_length=16)
content = models.TextField()
create_at = models.DateTimeField(auto_now_add=True) class Meta:
verbose_name_plural = "错误日志表" def __str__(self):
return self.title

全部表结构设计

表结构创建好了之后,登陆到admin添加信息

  --   用户,用户组,业务线,机房  可以提前添加

  --   数据库和收集来的资产数据对比

    新数据又,数据库没有—新增
    数据库有。新数据没有 — 拔走
    数据库也有,新数据也有,但是数据不一样 — 更新

  --   我们变更数据库信息的时候建议

    应该先有一些基本信息,然后在汇报的时候再有详细信息    资产  -  服务器(主机名,序列号...)

四 数据库资产变更

@method_decorator(auth.api_auth)  # 装饰器,必须执行api_auth,规则限制
def post(self, request, *args, **kwargs):
"""
更新或者添加资产信息
:param request:
:param args:
:param kwargs:
:return: 1000 成功;1001 接口授权失败;1002 数据库中资产不存在
""" server_info = json.loads(request.body.decode('utf-8')) server_info = json.loads(server_info) # 有一步测试,将RET返回 遇到问题。第一种新加。第二种,是不是应该先有一些基本信息,然后在汇报的时候再有详细信息 资产-服务器
# ret = {'code': 1000, 'message': ''}
# print(server_info) # server_info 最新汇报服务器所有信息
hostname = server_info['hostname'] ret = {'code': 1000, 'message': '[%s]更新完成' % hostname} # 根据主机名去数据库中获取相关信息
server_obj = models.Server.objects.filter(hostname=hostname).select_related('asset').first() # 如果数据库没有这个主机,我们不录入
if not server_obj:
ret['code'] = 1002
ret['message'] = '[%s]资产不存在' % hostname
return JsonResponse(ret) # 数据库变更
for k,v in config.PLUGINS_DICT.items():
module_path,cls_name = v.rsplit('.',1)
cls = getattr(importlib.import_module(module_path),cls_name)
response = cls.process(server_obj,server_info,None)
if not response.status:
ret['code'] = 1003
ret['message'] = '[%s]资产变更异常' % hostname
if hasattr(cls,'update_last_time'):
cls.update_last_time(server_obj,None) # ========》 server_obj服务器对象 ;server_info 《==========
# 硬盘 或 网卡 或 内存
# 硬盘:增删改
# 1. server_obj反向关联硬盘表,获取数据库中硬盘信息
# [
# {'slot': "#1", 'size': '100'},
# {'slot': "#2", 'size': '60'},
# {'slot': "#3", 'size': '88'},
# ]
# old_list = ['#1','#2','#3']
# 2. server_info['disk'] 新汇报的硬盘数据
# {
# "#1":{'slot': "#1", 'size': '90'},
# "#4":{'slot': "#4", 'size': '40'},
# }
# new_list = ['#1','#4']
#3. 更新['#1'] 删除['#2','#3'] 增加 ['#4'] #4. # 增加 ['#4']
"""
for i in ['#4']:
data_dict = dic[i]
models.Diks.objces.create(**data_dict)
""" return JsonResponse(ret)

post资产数据和数据库数据变更

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import traceback
import datetime
from utils.response import BaseResponse
from utils import agorithm
from repository import models from django.db.models import Q
import datetime def get_untreated_servers():
response = BaseResponse()
try:
current_date = datetime.date.today() condition = Q() # 今日未采集的资产
con_date = Q()
con_date.connector = 'OR'
con_date.children.append(("asset__latest_date__lt", current_date))
con_date.children.append(("asset__latest_date", None)) # 在线状态的服务器
con_status = Q()
con_status.children.append(('asset__device_status_id', '')) condition.add(con_date, 'AND')
condition.add(con_status, 'AND') result = models.Server.objects.filter(condition).values('hostname')
response.data = list(result)
response.status = True
except Exception as e:
response.message = str(e)
models.ErrorLog.objects.create(asset_obj=None, title='get_untreated_servers', content=traceback.format_exc())
return response # ############# 操作基本信息(cpu和主板) #############
# 操作基本,并记录操作日志
# 更新cpu和主板信息
class HandleBasic(object):
# 处理基本信息,包括主板和CPU信息
@staticmethod
def process(server_obj, server_info, user_obj):
response = BaseResponse()
try:
log_list = []
main_board = server_info['main_board']['data']
cpu = server_info['cpu']['data']
if server_obj.os_platform != server_info['os_platform']:
log_list.append('系统由%s变更为%s' % (server_obj.os_platform, server_info['os_platform'],))
server_obj.os_platform = server_info['os_platform'] if server_obj.os_version != server_info['os_version']:
log_list.append(u'系统版本由%s变更为%s' % (server_obj.os_version, server_info['os_version'],))
server_obj.os_version = server_info['os_version'] if server_obj.sn != main_board['sn']:
log_list.append(u'主板SN号由%s变更为%s' % (server_obj.sn, main_board['sn'],))
server_obj.sn = main_board['sn'] if server_obj.manufacturer != main_board['manufacturer']:
log_list.append(u'主板厂商由%s变更为%s' % (server_obj.manufacturer, main_board['manufacturer'],))
server_obj.manufacturer = main_board['manufacturer'] if server_obj.model != main_board['model']:
log_list.append(u'主板型号由%s变更为%s' % (server_obj.model, main_board['model'],))
server_obj.model = main_board['model'] if server_obj.cpu_count != cpu['cpu_count']:
log_list.append(u'CPU逻辑核数由%s变更为%s' % (server_obj.cpu_count, cpu['cpu_count'],))
server_obj.cpu_count = cpu['cpu_count'] if server_obj.cpu_physical_count != cpu['cpu_physical_count']:
log_list.append(
u'CPU物理核数由%s变更为%s' % (server_obj.cpu_physical_count, cpu['cpu_physical_count'],))
server_obj.cpu_physical_count = cpu['cpu_physical_count'] if server_obj.cpu_model != cpu['cpu_model']:
log_list.append(u'CPU型号由%s变更为%s' % (server_obj.cpu_model, cpu['cpu_model'],))
server_obj.cpu_model = cpu['cpu_model'] server_obj.save()
if log_list:
models.AssetRecord.objects.create(asset_obj=server_obj.asset, creator=user_obj,
content=';'.join(log_list))
except Exception as e:
response.status = False
models.ErrorLog.objects.create(asset_obj=server_obj.asset, title='basic-run',
content=traceback.format_exc())
return response @staticmethod
def update_last_time(server_obj, user_obj):
response = BaseResponse()
try:
current_date = datetime.date.today()
server_obj.asset.latest_date = current_date
server_obj.asset.save()
models.AssetRecord.objects.create(asset_obj=server_obj.asset, creator=user_obj, content='资产汇报')
except Exception as e:
response.status = False
models.ErrorLog.objects.create(asset_obj=server_obj.asset, title='basic-run',
content=traceback.format_exc()) return response # ############# 操作网卡信息 #############
# 操作网卡,并记录操作日志
# 添加网卡
# 删除网卡
# 更新网卡信息
class HandleNic(object):
@staticmethod
def process(server_obj, server_info, user_obj):
response = BaseResponse()
try:
# 获取数据库中的所有网卡信息
# server_info,服务器最新汇报的数据 server_info['nic']
nic_info = server_info['nic']
if not nic_info['status']:
response.status = False
models.ErrorLog.objects.create(asset_obj=server_obj.asset, title='nic-agent', content=nic_info['error'])
return response client_nic_dict = nic_info['data']
nic_obj_list = models.NIC.objects.filter(server_obj=server_obj)
nic_name_list = map(lambda x: x, (item.name for item in nic_obj_list)) update_list = agorithm.get_intersection(set(client_nic_dict.keys()), set(nic_name_list))
add_list = agorithm.get_exclude(client_nic_dict.keys(), update_list)
del_list = agorithm.get_exclude(nic_name_list, update_list)
# ==> 要删除、更新,添加 HandleNic._add_nic(add_list, client_nic_dict, server_obj, user_obj)
HandleNic._update_nic(update_list, nic_obj_list, client_nic_dict, server_obj, user_obj)
HandleNic._del_nic(del_list, nic_obj_list, server_obj, user_obj) except Exception as e:
response.status = False
models.ErrorLog.objects.create(asset_obj=server_obj.asset, title='nic-run', content=traceback.format_exc()) return response @staticmethod
def _add_nic(add_list, client_nic_dict, server_obj, user_obj):
for item in add_list:
cur_nic_dict = client_nic_dict[item]
cur_nic_dict['name'] = item
log_str = '[新增网卡]{name}:mac地址为{hwaddr};状态为{up};掩码为{netmask};IP地址为{ipaddrs}'.format(**cur_nic_dict)
cur_nic_dict['server_obj'] = server_obj
models.NIC.objects.create(**cur_nic_dict)
models.AssetRecord.objects.create(asset_obj=server_obj.asset, creator=user_obj, content=log_str) @staticmethod
def _del_nic(del_list, nic_objs, server_obj, user_obj):
for item in nic_objs:
if item.name in del_list:
log_str = '[移除网卡]{name}:mac地址为{hwaddr};状态为{up};掩码为{netmask};IP地址为{ipaddrs}'.format(**item.__dict__)
item.delete()
models.AssetRecord.objects.create(asset_obj=server_obj.asset, creator=user_obj, content=log_str) @staticmethod
def _update_nic(update_list, nic_objs, client_nic_dict, server_obj, user_obj): for item in nic_objs:
if item.name in update_list:
log_list = [] new_hwaddr = client_nic_dict[item.name]['hwaddr']
if item.hwaddr != new_hwaddr:
log_list.append(u"[更新网卡]%s:mac地址由%s变更为%s" % (item.name, item.hwaddr, new_hwaddr))
item.hwaddr = new_hwaddr
new_up = client_nic_dict[item.name]['up']
if item.up != new_up:
log_list.append(u"[更新网卡]%s:状态由%s变更为%s" % (item.name, item.up, new_up))
item.up = new_up new_netmask = client_nic_dict[item.name]['netmask']
if item.netmask != new_netmask:
log_list.append(u"[更新网卡]%s:掩码由%s变更为%s" % (item.name, item.netmask, new_netmask))
item.netmask = new_netmask new_ipaddrs = client_nic_dict[item.name]['ipaddrs']
if item.ipaddrs != new_ipaddrs:
log_list.append(u"[更新网卡]%s:IP地址由%s变更为%s" % (item.name, item.ipaddrs, new_ipaddrs))
item.ipaddrs = new_ipaddrs item.save()
if log_list:
models.AssetRecord.objects.create(asset_obj=server_obj.asset, creator=user_obj,
content=';'.join(log_list)) # ############# 操作内存信息 #############
# 操作内存,并记录操作日志
# 添加内存
# 删除内存
# 更新内存信息
class HandleMemory(object):
@staticmethod
def process(server_obj, server_info, user_obj):
response = BaseResponse()
try:
mem_info = server_info['memory']
if not mem_info['status']:
models.ErrorLog.objects.create(asset_obj=server_obj.asset, title='memory-agent',
content=mem_info['error'])
response.status = False
return response client_mem_dict = mem_info['data'] mem_obj_list = models.Memory.objects.filter(server_obj=server_obj) mem_slots = map(lambda x: x, (item.slot for item in mem_obj_list)) update_list = agorithm.get_intersection(set(client_mem_dict.keys()), set(mem_slots))
add_list = agorithm.get_exclude(client_mem_dict.keys(), update_list)
del_list = agorithm.get_exclude(mem_slots, update_list) HandleMemory._add_memory(add_list, client_mem_dict, server_obj, user_obj)
HandleMemory._update_memory(update_list, mem_obj_list, client_mem_dict, server_obj, user_obj)
HandleMemory._del_memory(del_list, mem_obj_list, server_obj, user_obj)
except Exception as e:
response.status = False
models.ErrorLog.objects.create(asset_obj=server_obj.asset, title='memory-run',
content=traceback.format_exc()) return response @staticmethod
def _add_memory(add_list, client_mem_dict, server_obj, user_obj):
for item in add_list:
cur_mem_dict = client_mem_dict[item]
log_str = '[新增内存]插槽为{slot};容量为{capacity};类型为{model};速度为{speed};厂商为{manufacturer};SN号为{sn}'.format(
**cur_mem_dict)
cur_mem_dict['server_obj'] = server_obj
models.Memory.objects.create(**cur_mem_dict)
models.AssetRecord.objects.create(asset_obj=server_obj.asset, creator=user_obj, content=log_str) @staticmethod
def _del_memory(del_list, mem_objs, server_obj, user_obj):
for item in mem_objs:
if item.slot in del_list:
log_str = '[移除内存]插槽为{slot};容量为{capacity};类型为{model};速度为{speed};厂商为{manufacturer};SN号为{sn}'.format(
**item.__dict__)
item.delete()
models.AssetRecord.objects.create(asset_obj=server_obj.asset, creator=user_obj, content=log_str) @staticmethod
def _update_memory(update_list, mem_objs, client_mem_dict, server_obj, user_obj):
for item in mem_objs:
if item.slot in update_list:
log_list = [] new_manufacturer = client_mem_dict[item.slot]['manufacturer']
if item.manufacturer != new_manufacturer:
log_list.append(u"[更新内存]%s:厂商由%s变更为%s" % (item.slot, item.manufacturer, new_manufacturer))
item.manufacturer = new_manufacturer new_model = client_mem_dict[item.slot]['model']
if item.model != new_model:
log_list.append(u"[更新内存]%s:型号由%s变更为%s" % (item.slot, item.model, new_model))
item.model = new_model new_capacity = client_mem_dict[item.slot]['capacity']
if item.capacity != new_capacity:
log_list.append(u"[更新内存]%s:容量由%s变更为%s" % (item.slot, item.capacity, new_capacity))
item.capacity = new_capacity new_sn = client_mem_dict[item.slot]['sn']
if item.sn != new_sn:
log_list.append(u"[更新内存]%s:SN号由%s变更为%s" % (item.slot, item.sn, new_sn))
item.sn = new_sn new_speed = client_mem_dict[item.slot]['speed']
if item.speed != new_speed:
log_list.append(u"[更新内存]%s:速度由%s变更为%s" % (item.slot, item.speed, new_speed))
item.speed = new_speed item.save()
if log_list:
models.AssetRecord.objects.create(asset_obj=server_obj.asset, creator=user_obj,
content=';'.join(log_list)) # ############# 操作硬盘信息 #############
# 操作硬盘,并记录操作日志
# 添加硬盘
# 删除硬盘
# 更新硬盘信息
class HandleDisk(object):
@staticmethod
def process(server_obj, server_info, user_obj):
response = BaseResponse()
try:
disk_info = server_info['disk']
if not disk_info['status']:
response.status = False
models.ErrorLog.objects.create(asset_obj=server_obj.asset, title='disk-agent',
content=disk_info['error'])
return response client_disk_dict = disk_info['data'] disk_obj_list = models.Disk.objects.filter(server_obj=server_obj) disk_slots = map(lambda x: x, (item.slot for item in disk_obj_list)) update_list = agorithm.get_intersection(set(client_disk_dict.keys()), set(disk_slots))
add_list = agorithm.get_exclude(client_disk_dict.keys(), update_list)
del_list = agorithm.get_exclude(disk_slots, update_list) HandleDisk._add_disk(add_list, client_disk_dict, server_obj, user_obj)
HandleDisk._update_disk(update_list, disk_obj_list, client_disk_dict, server_obj, user_obj)
HandleDisk._del_disk(del_list, disk_obj_list, server_obj, user_obj) except Exception as e:
response.status = False
models.ErrorLog.objects.create(asset_obj=server_obj.asset, title='disk-run', content=traceback.format_exc())
return response @staticmethod
def _add_disk(add_list, client_disk_dict, server_obj, user_obj):
for item in add_list:
cur_disk_dict = client_disk_dict[item]
log_str = '[新增硬盘]插槽为{slot};容量为{capacity};硬盘类型为{pd_type};型号为{model}'.format(**cur_disk_dict)
cur_disk_dict['server_obj'] = server_obj
models.Disk.objects.create(**cur_disk_dict)
models.AssetRecord.objects.create(asset_obj=server_obj.asset, creator=user_obj, content=log_str) @staticmethod
def _del_disk(del_list, disk_objs, server_obj, user_obj):
for item in disk_objs:
if item.slot in del_list:
log_str = '[移除硬盘]插槽为{slot};容量为{capacity};硬盘类型为{pd_type};型号为{model}'.format(**item.__dict__)
item.delete()
models.AssetRecord.objects.create(asset_obj=server_obj.asset, creator=user_obj, content=log_str) @staticmethod
def _update_disk(update_list, disk_objs, client_disk_dict, server_obj, user_obj):
for item in disk_objs:
if item.slot in update_list:
log_list = [] new_model = client_disk_dict[item.slot]['model']
if item.model != new_model:
log_list.append(u"[更新硬盘]插槽为%s:型号由%s变更为%s" % (item.slot, item.model, new_model))
item.model = new_model new_capacity = client_disk_dict[item.slot]['capacity']
new_capacity = float(new_capacity)
if item.capacity != new_capacity:
log_list.append(u"[更新硬盘]插槽为%s:容量由%s变更为%s" % (item.slot, item.capacity, new_capacity))
item.capacity = new_capacity new_pd_type = client_disk_dict[item.slot]['pd_type']
if item.pd_type != new_pd_type:
log_list.append(u"[更新硬盘]插槽为%s:硬盘类型由%s变更为%s" % (item.slot, item.pd_type, new_pd_type))
item.pd_type = new_pd_type item.save()
if log_list:
models.AssetRecord.objects.create(asset_obj=server_obj.asset, creator=user_obj,
content=';'.join(log_list))

各个资产的增删改查

运维平台cmdb开发-day2的更多相关文章

  1. 运维平台cmdb开发-day1

    序读项目由来 终极目标,运维平台.自动化.装机,监控,安装软件,部署基础服务,资产管理,之前是excel,现在是客户端自动获取,变更记录 后台管理 api 采集资产 四种模式agent 定时,每天执行 ...

  2. 运维平台cmdb开发-day3

    后台管理 1. 访问过程 我们在前面2天得到了各个客户端的资产数据信息,我们将各个这个数据打包发送到api,这个api其实就是django的url传参,之后按照数据的格式对比数据库增删改 2. 后台页 ...

  3. #研发解决方案#iDB-数据库自动化运维平台

    郑昀 创建于2015/12/2 最后更新于2015/12/2 关键词:数据库,MySQL,自动化运维,AutoDDL,刷库,帐号授权,审核,回滚 提纲: 数据库自动化运维什么?别人家是怎么玩的? 我们 ...

  4. 《开源安全运维平台:OSSIM最佳实践》内容简介

    <开源安全运维平台:OSSIM最佳实践 > 李晨光 著 清华大学出版社出版 内 容 简 介在传统的异构网络环境中,运维人员往往利用各种复杂的监管工具来管理网络,由于缺乏一种集成安全运维平台 ...

  5. 《开源安全运维平台OSSIM最佳实践》

    <开源安全运维平台OSSIM最佳实践> 经多年潜心研究开源技术,历时三年创作的<开源安全运维平台OSSIM最佳实践>一书即将出版.该书用80多万字记录了,作者10多年的IT行业 ...

  6. saltstack---自动化运维平台

    https://github.com/ixrjog/adminset[自动化运维平台:CMDB.CD.DevOps.资产管理.任务编排.持续交付.系统监控.运维管理.配置管理 ] https://ww ...

  7. sso 自动化运维平台

    单点登录SSO(Single Sign-On)是身份管理中的一部分.本文中作者开发了一个自动化运维平台中的统一认证接口,单点登录平台通过提供统一的认证平台,实现单点登录.因此,应用系统并不需要开发用户 ...

  8. python自动化运维之CMDB篇-大米哥

    python自动化运维之CMDB篇 视频地址:复制这段内容后打开百度网盘手机App,操作更方便哦 链接:https://pan.baidu.com/s/1Oj_sglTi2P1CMjfMkYKwCQ  ...

  9. 运维平台之CMDB系统建设

    CMDB是运维的基础核心系统,所有的元数据和共享数据管理源,类似于业务中的账号平台的作用.本篇文章,我将从概念篇.模型篇.到实现与实施篇具体的进行阐述. CMDB也称配置管理,配置管理一直被认为是 I ...

随机推荐

  1. Python面向对象 --- 新旧式类、私有方法、类属性和类方法、静态方法

    一.Python面向对象中的新旧式类 1)新式类(推荐使用):在定义类时,类后边括号里要继承基类(object).在python3.x中若没有指定父类,会默认使用的是object作为基类:在pytho ...

  2. web.xml文件模板

     Servlet 2.3 deployment descriptor 注:web.xml中提示错误The content of element type "web-app" mus ...

  3. python︱用pyodbc连接数据库

    直接连接数据库和创建一个游标(cursor) 数据查询(SQL语句为 select -from..where) 1.pyodbc连接 import pyodbc cnxn = pyodbc.conne ...

  4. 基于EasyDSS流媒体服务器实现的直播流管理与鉴权的后台方案

    本文转自EasyDSS团队Marvin的博客:http://blog.csdn.net/marvin1311/article/details/73548929 最新版本的EasyDSS流媒体解决方案, ...

  5. 深入理解Eureka之源码解析

    转载请标明出处: http://blog.csdn.net/forezp/article/details/73017664 本文出自方志朋的博客 Eureka的一些概念 Register:服务注册 当 ...

  6. Vim技能修炼教程(7) - 可视模式

    可视模式 可视模式是与正常模式.插入模式一起并列的模式.它的作用就像图形化编辑器下用鼠标来选择一个块. 在vim下,使用正常模式和ex命令,连搜带跳行的,未必就比用鼠标慢. 我们先做一个例子找找感觉, ...

  7. Android 4.0 Camera架构分析之Camera初始化

    Android Camera 采用C/S架构,client 与server两个独立的线程之间使用Binder通信,这已经是众所周知的了.这里将介绍Camera从设备开机,到进入相机应用是如何完成初始化 ...

  8. HDU - 4336:Card Collector(min-max容斥求期望)

    In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, fo ...

  9. JSP学习(二)JSP指令

    JSP指令 JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分. JSP指令的基本语法格式:<%@ 指令 属性名= ...

  10. Codeforces 382E Ksenia and Combinatorics 【组合计数】*

    Codeforces 382E Ksenia and Combinatorics Ksenia has her winter exams. Today she is learning combinat ...