# -*- coding: UTF-8 -*-
import logging
import traceback
from itertools import chain
import simplejson as json
from django.contrib.auth.models import Group
from django.db.models import F, Value, IntegerField
from django.http import HttpResponse
from common.utils.extend_json_encoder import ExtendJSONEncoder
from common.utils.permission import superuser_required
from common.utils.convert import Convert
from sql.models import ResourceGroup, Users, Instance
from sql.utils.resource_group import user_instances
from sql.utils.workflow_audit import Audit
logger = logging.getLogger("default")
@superuser_required
def group(request):
"""获取资源组列表"""
limit = int(request.POST.get("limit"))
offset = int(request.POST.get("offset"))
limit = offset + limit
search = request.POST.get("search", "")
# 过滤搜索条件
group_obj = ResourceGroup.objects.filter(group_name__icontains=search, is_deleted=0)
group_count = group_obj.count()
group_list = group_obj[offset:limit].values(
"group_id", "group_name", "ding_webhook"
)
# QuerySet 序列化
rows = [row for row in group_list]
result = {"total": group_count, "rows": rows}
# 返回查询结果
return HttpResponse(
json.dumps(result, cls=ExtendJSONEncoder, bigint_as_string=True),
content_type="application/json",
)
def associated_objects(request):
"""
获取资源组已关联对象信息
type:(0, '用户'), (1, '实例')
"""
group_id = int(request.POST.get("group_id"))
object_type = request.POST.get("type")
limit = int(request.POST.get("limit"))
offset = int(request.POST.get("offset"))
limit = offset + limit
search = request.POST.get("search")
# 获取关联数据
resource_group = ResourceGroup.objects.get(group_id=group_id)
rows_users = resource_group.users_set.all()
rows_instances = resource_group.instance_set.all()
# 过滤搜索
if search:
rows_users = rows_users.filter(display__contains=search)
rows_instances = rows_instances.filter(instance_name__contains=search)
rows_users = rows_users.annotate(
object_id=F("id"),
object_type=Value(0, output_field=IntegerField()),
object_name=F("display"),
group_id=F("resource_group__group_id"),
group_name=F("resource_group__group_name"),
).values("object_type", "object_id", "object_name", "group_id", "group_name")
rows_instances = rows_instances.annotate(
object_id=F("id"),
object_type=Value(1, output_field=IntegerField()),
object_name=F("instance_name"),
group_id=F("resource_group__group_id"),
group_name=F("resource_group__group_name"),
).values("object_type", "object_id", "object_name", "group_id", "group_name")
# 过滤对象类型
if object_type == "0":
rows_obj = rows_users
count = rows_obj.count()
rows = [row for row in rows_obj][offset:limit]
elif object_type == "1":
rows_obj = rows_instances
count = rows_obj.count()
rows = [row for row in rows_obj][offset:limit]
else:
rows = list(chain(rows_users, rows_instances))
count = len(rows)
rows = rows[offset:limit]
result = {"status": 0, "msg": "ok", "total": count, "rows": rows}
return HttpResponse(
json.dumps(result, cls=ExtendJSONEncoder), content_type="application/json"
)
def unassociated_objects(request):
"""
获取资源组未关联对象信息
type:(0, '用户'), (1, '实例')
"""
group_id = int(request.POST.get("group_id"))
object_type = int(request.POST.get("object_type"))
# 获取关联数据
resource_group = ResourceGroup.objects.get(group_id=group_id)
if object_type == 0:
associated_user_ids = [user.id for user in resource_group.users_set.all()]
rows = (
Users.objects.exclude(pk__in=associated_user_ids)
.annotate(object_id=F("pk"), object_name=F("display"))
.values("object_id", "object_name")
)
elif object_type == 1:
associated_instance_ids = [ins.id for ins in resource_group.instance_set.all()]
rows = (
Instance.objects.exclude(pk__in=associated_instance_ids)
.annotate(object_id=F("pk"), object_name=F("instance_name"))
.values("object_id", "object_name")
)
else:
raise ValueError("关联对象类型不正确")
rows = [row for row in rows]
result = {"status": 0, "msg": "ok", "rows": rows, "total": len(rows)}
return HttpResponse(json.dumps(result), content_type="application/json")
def instances(request):
"""获取资源组关联实例列表"""
group_name = request.POST.get("group_name")
group_id = ResourceGroup.objects.get(group_name=group_name).group_id
tag_code = request.POST.get("tag_code")
db_type = request.POST.get("db_type")
# 先获取资源组关联所有实例列表
ins = ResourceGroup.objects.get(group_id=group_id).instance_set.all()
# 过滤项
filter_dict = dict()
# db_type
if db_type:
filter_dict["db_type"] = db_type
if tag_code:
filter_dict["instance_tag__tag_code"] = tag_code
filter_dict["instance_tag__active"] = True
ins = (
ins.filter(**filter_dict)
.order_by(Convert("instance_name", "gbk").asc())
.values("id", "type", "db_type", "instance_name")
)
rows = [row for row in ins]
result = {"status": 0, "msg": "ok", "data": rows}
return HttpResponse(json.dumps(result), content_type="application/json")
def user_all_instances(request):
"""获取用户所有实例列表(通过资源组间接关联)"""
user = request.user
type = request.GET.get("type")
db_type = request.GET.getlist("db_type[]")
tag_codes = request.GET.getlist("tag_codes[]")
instances = (
user_instances(user, type, db_type, tag_codes)
.order_by(Convert("instance_name", "gbk").asc())
.values("id", "type", "db_type", "instance_name")
)
rows = [row for row in instances]
result = {"status": 0, "msg": "ok", "data": rows}
return HttpResponse(json.dumps(result), content_type="application/json")
@superuser_required
def addrelation(request):
"""
添加资源组关联对象
type:(0, '用户'), (1, '实例')
"""
group_id = int(request.POST.get("group_id"))
object_type = request.POST.get("object_type")
object_list = json.loads(request.POST.get("object_info"))
try:
resource_group = ResourceGroup.objects.get(group_id=group_id)
obj_ids = [int(obj.split(",")[0]) for obj in object_list]
if object_type == "0": # 用户
resource_group.users_set.add(*Users.objects.filter(pk__in=obj_ids))
elif object_type == "1": # 实例
resource_group.instance_set.add(*Instance.objects.filter(pk__in=obj_ids))
result = {"status": 0, "msg": "ok"}
except Exception as e:
logger.error(traceback.format_exc())
result = {"status": 1, "msg": str(e)}
return HttpResponse(json.dumps(result), content_type="application/json")
def auditors(request):
"""获取资源组的审批流程"""
group_name = request.POST.get("group_name")
workflow_type = request.POST["workflow_type"]
result = {
"status": 0,
"msg": "ok",
"data": {"auditors": "", "auditors_display": ""},
}
if group_name:
group_id = ResourceGroup.objects.get(group_name=group_name).group_id
audit_auth_groups = Audit.settings(
group_id=group_id, workflow_type=workflow_type
)
else:
result["status"] = 1
result["msg"] = "参数错误"
return HttpResponse(json.dumps(result), content_type="application/json")
# 获取权限组名称
if audit_auth_groups:
# 校验配置
for auth_group_id in audit_auth_groups.split(","):
try:
Group.objects.get(id=auth_group_id)
except Exception:
result["status"] = 1
result["msg"] = "审批流程权限组不存在,请重新配置!"
return HttpResponse(json.dumps(result), content_type="application/json")
audit_auth_groups_name = "->".join(
[
Group.objects.get(id=auth_group_id).name
for auth_group_id in audit_auth_groups.split(",")
]
)
result["data"]["auditors"] = audit_auth_groups
result["data"]["auditors_display"] = audit_auth_groups_name
return HttpResponse(json.dumps(result), content_type="application/json")
@superuser_required
def changeauditors(request):
"""设置资源组的审批流程"""
auth_groups = request.POST.get("audit_auth_groups")
group_name = request.POST.get("group_name")
workflow_type = request.POST.get("workflow_type")
result = {"status": 0, "msg": "ok", "data": []}
# 调用工作流修改审核配置
group_id = ResourceGroup.objects.get(group_name=group_name).group_id
audit_auth_groups = [
str(Group.objects.get(name=auth_group).id)
for auth_group in auth_groups.split(",")
]
try:
Audit.change_settings(group_id, workflow_type, ",".join(audit_auth_groups))
except Exception as msg:
logger.error(traceback.format_exc())
result["msg"] = str(msg)
result["status"] = 1
# 返回结果
return HttpResponse(json.dumps(result), content_type="application/json")