CMDB项目中遇到的问题
客户端
类的调用
class Response(object):
def __init__(self):
self.status = True
self.msg = None
self.data = None
@property
def dict(self):
return self.__dict__
response = Response()
class Disk(object):
def __init__(self):
self.response = response
@property
def info(self):
self.response.status = 100
self.response.msg = '魏新雨咋软'
self.response.data = {'1':{'capatablities': '100GB', 'model': 'hp2344'}}
return self.response.dict
class Memory(object):
def __init__(self):
self.response = response
@property
def info(self):
self.response.status = 100
self.response.msg = '陈骏啊, 萨宁啊'
self.response.data = {'#DISM1':{'capatablities': '8GB', 'model': 'kingstong222'}}
return self.response.dict
disk = Disk().info
memory = Memory().info
print(disk) # {'status': 100, 'msg': '陈骏啊, 萨宁啊', 'data': {'#DISM1': {'capatablities': '8GB', 'model': 'kingstong222'}}}
print(memory) # {'status': 100, 'msg': '陈骏啊, 萨宁啊', 'data': {'#DISM1': {'capatablities': '8GB', 'model': 'kingstong222'}}}
最后2者的输出结果是一样的, 因为无论是Disk对象还是Memory对象, 他们的属性self.response
指向的都是response这个对象, 所以最后的值是由最后一次赋值的结果
TypeError: Object of type 'Response' is not JSON serializable
原因: 返回的对象无法用json进行实例化(json.dumps(ret)), 最后返回的是个对象, 而不是字典
lib.response.py
class Response(object):
def __init__(self):
self.status = None
self.msg = None
self.data = None
@property
def dict(self):
return self.__dict__
src.plugins.disk.py
from .base import BasePlugin
import os
import traceback
from lib.response import Response
class Disk(BasePlugin):
def __init__(self, handler):
super().__init__(handler)
self.disk_path = os.path.join(self.filepath, 'disk.out')
# self.response = response_obj
self.error = traceback.format_exc()
self.response = Response()
def Windows(self):
return 'windows'
def Linux(self, handler):
# print('disk', response)
if not self.debug:
data = handler.cmd('sudo MegaCli -PDList -aALL')
else:
try:
data = open(self.disk_path, 'r', encoding='utf-8').read().split('Enclosure Device ID: 32')[1:]
disk_dict = self.LinuxParse(data)
self.response.status = 1000
self.response.msg = '采集磁盘成功'
self.response.data = disk_dict
except Exception:
self.response.status = 4000
self.response.msg = self.error
return self.response
def LinuxParse(self, data):
key_map = {
'PD Type': 'iface',
'Slot Number': 'slot',
'Inquiry Data': 'model',
'Raw Size': 'capacity',
}
disk_dict = {}
for item in data:
res = item.strip().split('\n')
info = {}
for row in res:
if len(row.strip().split(':')) == 2:
key, value = row.strip().split(':')
if key in key_map:
info[key_map[key]] = value.strip()
disk_dict[info['slot']] = info
return disk_dict
报错信息的处理
from .base import BasePlugin
import os
import traceback
from lib.response import Response
class Disk(BasePlugin):
def __init__(self, handler):
super().__init__(handler)
self.disk_path = os.path.join(self.filepath, 'disk.out')
self.response = Response()
self.error = traceback.format_exc()
def Windows(self):
return 'windows'
def Linux(self, handler):
# print('disk', response)
if not self.debug:
data = handler.cmd('sudo MegaCli -PDList -aALL')
else:
try:
data = open(self.disk_path, 'r', encoding='utf-8').read().split('Enclosure Device ID: 32')[1:]
disk_dict = self.LinuxParse(data)
self.response.status = 1000
self.response.msg = '采集磁盘成功'
self.response.data = disk_dict
except Exception:
self.response.status = 4000
self.response.msg = self.error
self.logger.error(self.error)
return self.response.dict
def LinuxParse(self, data):
key_map = {
'PD Type': 'iface',
'Slot Number': 'slot',
'Inquiry Data': 'model',
'Raw Size': 'capacity',
}
disk_dict = {}
for item in data:
res = item.strip().split('\n')
info = {}
for row in res:
if len(row.strip().split(':')) == 2:
key, value = row.strip().split(':')
if key in key_map:
info[key_map[key]] = value.strip()
disk_dict[info['slot']] = info
return disk_dict
问题
在初始化方法中定义了 self.error = traceback.format_exc()
, 这就导致了无论出现什么样的异常, 最后的报错信息都是NoneType: None
所以正确的逻辑是在出现异常的时候进行补货
from .base import BasePlugin
import os
import traceback
from lib.response import Response
class Disk(BasePlugin):
def __init__(self, handler):
super().__init__(handler)
self.disk_path = os.path.join(self.filepath, 'disk.out')
self.response = Response()
def Windows(self):
return 'windows'
def Linux(self, handler):
# print('disk', response)
if not self.debug:
data = handler.cmd('sudo MegaCli -PDList -aALL')
else:
try:
data = open(self.disk_path, 'r', encoding='utf-8').read().split('Enclosure Device ID: 32')[1:]
disk_dict = self.LinuxParse(data)
self.response.status = 1000
self.response.msg = '采集磁盘成功'
self.response.data = disk_dict
except Exception:
error_msg = traceback.format_exc()
self.response.status = 4000
self.response.msg = error_msg
self.logger.error(error_msg)
return self.response.dict
def LinuxParse(self, data):
key_map = {
'PD Type': 'iface',
'Slot Number': 'slot',
'Inquiry Data': 'model',
'Raw Size': 'capacity',
}
disk_dict = {}
for item in data:
res = item.strip().split('\n')
info = {}
for row in res:
if len(row.strip().split(':')) == 2:
key, value = row.strip().split(':')
if key in key_map:
info[key_map[key]] = value.strip()
disk_dict[info['slot']] = info
return disk_dict
API
TypeError: init() missing 1 required positional argument: 'app_module'
原因: 将app注册到MIDDLEWARE的列表中