class NodeBase(object):
columns_mapping = {}
def get_range(self, *args, **kwargs):
return Node.objects.all()
def get_node_status_preference(self, user):
logger.info("Get preference for node status")
name = "monitor.policy.node.status"
try:
preference = Preference.objects.get(name=name)
except Preference.DoesNotExist as e:
logger.exception('Preference name %s does not exist', name)
raise_from(CheckPreferenceException, e)
else:
if preference.user in [None, user]:
# 'cpu_core' or 'cpu_util' for value
return preference.value
else:
return "cpu_util"
def convert_cpu_status(self, preference, cpu_util, node_id):
if preference == "cpu_util":
util = int(cpu_util)
if util < IDLE_THRESHOLD:
return "idle"
elif util > BUSY_THRESHOLD:
return "busy"
else:
return "used"
else:
if RunningJob.objects.filter(node__id=node_id).count() > 0:
return "busy"
else:
return "idle"
def search(self, query, argss):
if 'search' not in argss:
return query
else:
search = argss['search']
props = search['props']
keyword = search['keyword'].strip()
if keyword == "":
return query
q = Q()
for field in props:
prop = field
if field in self.columns_mapping:
prop = self.columns_mapping[field]
q |= Q(**{prop + "__icontains": keyword})
return query.filter(q)
def sort_fields(self, argss):
if 'sort' not in argss:
return ['id'], True
order = argss["sort"]
prop = order['prop']
if prop in self.columns_mapping:
prop = self.columns_mapping[order['prop']]
if order['order'] != "ascending":
prop = "-" + prop
return prop
# 字段排序!
def sort(self, query, argss):
return query.order_by(self.sort_fields(argss))
# 字段 过滤!
def filters(self, query, filters):
if len(filters) > 0 and filters is not None:
for field in filters:
if field['prop'] in self.columns_mapping:
prop = self.columns_mapping[field['prop']]
else:
prop = field['prop']
if len(field["values"]) > 0:
key = prop + "__{}".format(field["type"])
query = query.filter(
**{
key: field["values"]
}
)
return query
def params(self, args):
return args
class NodeList(NodeBase, APIView):
permission_classes = (AsUserRole,)
columns_mapping = {
"status": "cpu_util",
"groups": "groups__name"
}
def get(self, request):
argss = json.loads(
request.GET["args"]
)
argss = self.params(argss)
query = self.get_range()
# 根据 args中 filters 指定的字段进行过滤!
query = self.filters(query, argss['filters'])
# 根据字段进行查找
query = self.search(query, argss)
# 根据指定的字段进行排序!
query = self.sort(query, argss)
# 根据指定的数量进行返回数据!如果指定的个数多的话 按照最大进行返回
# 如果小于 那么就按照指定的数量进行返回!
filtered_total = query.count()
offset = argss['offset'] \
if int(argss['offset']) < filtered_total else 0
results = query[offset:offset + int(argss['length'])]
offset = offset + len(results)
preference = self.get_node_status_preference(request.user)
return Response(
{
'offset': offset,
'total': filtered_total,
'data': [self.trans_result(result, preference)
for result in results],
}
)
# 可以根据外键进行 查找其他 返回!
def trans_result(self, result, preference):
groups = []
for grp in result.groups.iterator():
groups.append(grp.name)
if result.gpu:
gpus = result.gpu.all()
gpu_cnt = gpus.count()
gpu_used = [0] * gpu_cnt
gpu_type = [""] * gpu_cnt
for gpu in gpus:
gpu_used[gpu.index] = int(gpu.occupation)
gpu_type[gpu.index] = gpu.type
else:
gpu_used = []
gpu_type = []
if result.fpga:
fpgas = result.fpga.all()
fpga_cnt = fpgas.count()
fpga_type = [""] * fpga_cnt
for fpga in fpgas:
fpga_type[fpga.index] = fpga.type
else:
fpga_type = []
power_status = status = "off"
if result.power_status is True:
power_status = "on"
status = self.convert_cpu_status(
preference,
result.cpu_util,
result.id
)
return {
"id": result.id,
"hostname": result.hostname,
"bmc_ipv4": result.bmc_ipv4,
"disk_total": int(result.disk_total),
"memory_total": int(result.memory_total),
"mgt_ipv4": result.mgt_ipv4,
"type": result.type,
"processors_total": result.cpu_total,
"power_status": power_status,
"groups": ",".join(groups),
"status": status,
"gpus": {
"used": gpu_used,
"type": gpu_type
},
"fpgas": {
"type": fpga_type,
}
}