發送請求攜帶參數python
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']}>
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':'1123','pwd': '666'}, # POST形式傳值 請求體 <QueryDict: {'pwd': ['666'], 'username': ['1123']}> headers={'a':'123'} # 請求頭數據 ) requests.body b'username=1123&pwd=666'
api須要post請求,而且有必定的數據格式linux
# 數據格式 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執行的返回值 ...
而咱們客戶端傳送這樣的數據格式的時候,用到了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這個模塊,最終獲得一個對象,以下django
{ status = True message = None data = os_platform:'',os_version:'',hostname:'','cpu':OBJ,'disk':OBJ} 這個OBJ會在交給本身寫的JSON.dump去處理 error = None }
而後通過serialize模塊處理json
#!/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 } }'''
這樣我就拿到了一個json數據,格式以下api
{ "disk": { "message": null, "error": null, "data": { "0": { "model": "SEAGATE ST300MM0006 LS08S0K2B5NV", "capacity": "279.396", "pd_type": "SAS", "slot": "0" }, "5": { "model": "S1AXNSAFB00549A Samsung SSD 840 PRO Series DXM06B0Q", "capacity": "476.939", "pd_type": "SATA", "slot": "5" }, "4": { "model": "S1AXNSAF303909M Samsung SSD 840 PRO Series DXM05B0Q", "capacity": "476.939", "pd_type": "SATA", "slot": "4" }, "3": { "model": "S1AXNSAF912433K Samsung SSD 840 PRO Series DXM06B0Q", "capacity": "476.939", "pd_type": "SATA", "slot": "3" }, "2": { "model": "S1SZNSAFA01085L Samsung SSD 850 PRO 512GB EXM01B6Q", "capacity": "476.939", "pd_type": "SATA", "slot": "2" }, "1": { "model": "SEAGATE ST300MM0006 LS08S0K2B5AH", "capacity": "279.396", "pd_type": "SAS", "slot": "1" } }, "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('....')
第一種:發送一個字符串auth_keycookie
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': '123456'} ) print(response.text) # 獲得是 django執行的返回值 ...
2. 在api處獲取到這個token,進行校驗,在處理post請求數據app
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('....')
存在的問題就是,有可能這個請求被截胡,極可能會被其餘人獲取到這個token
第二種:md5加密字符串 極可能會被其餘人獲取到這個token
## MD5加密的驗證TOKEN appid = '123456' 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執行的返回值 ...
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"}} # }'
第三種: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執行的返回值 ...
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('....')
第四種:經過時間規則限制,模仿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執行的返回值 ...
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('....')
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)
#!/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', '2')) 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))