diff --git a/website/db/enterprise_device/enterprise_device.py b/website/db/enterprise_device/enterprise_device.py index cc26a58..2de52e0 100644 --- a/website/db/enterprise_device/enterprise_device.py +++ b/website/db/enterprise_device/enterprise_device.py @@ -309,8 +309,9 @@ class EnterpriseDeviceRepository(object): return 0 def list_entity_devices(self, entity_id: int, pageno: int, pagesize: int, classification: str = "", - status: int = 0) -> dict: + status: int = 0, group: int = 0) -> dict: """获取企业的设备列表""" + logging.info(status) with get_session() as session: try: session_count = ( @@ -321,23 +322,29 @@ class EnterpriseDeviceRepository(object): ) ) if classification: - session_count.filter(EnterpriseDevice.classification == classification) + session_count = session_count.filter(EnterpriseDevice.classification == classification) if status in consts.device_status_map and status != consts.device_status_default: - session_count.filter(EnterpriseDevice.status == status) + logging.info("filter status") + session_count = session_count.filter(EnterpriseDevice.status == status) + if group: + session_count = session_count.filter(EnterpriseDevice.node_id == group) count = session_count.count() session_device = ( session.query(EnterpriseDevice, DeviceClassification.name.label("classification_name")) - .join(DeviceClassification, DeviceClassification.id == EnterpriseDevice.classification, isouter=True) + .join(DeviceClassification, DeviceClassification.id == EnterpriseDevice.classification, + isouter=True) .filter( EnterpriseDevice.entity_id == entity_id, EnterpriseDevice.delete != 1, ) ) if classification: - session_device.filter(EnterpriseDevice.classification == classification) - if status: - session_device.filter(EnterpriseDevice.status == status) + session_device = session_device.filter(EnterpriseDevice.classification == classification) + if status in consts.device_status_map and status != consts.device_status_default: + session_device = session_device.filter(EnterpriseDevice.status == status) + if group: + session_device = session_count.filter(EnterpriseDevice.node_id == group) devices = session_device.order_by(EnterpriseDevice.id.desc()).limit(pagesize).offset( (pageno - 1) * pagesize).all() @@ -346,12 +353,11 @@ class EnterpriseDeviceRepository(object): logging.error("Failed to list devices") raise e - logging.info(devices) return {"count": count, "devices": devices} - def status_count(self, entity_id: int, classification: str=""): + def status_count(self, entity_id: int, classification: str = ""): with get_session() as session: try: session_count = ( @@ -374,4 +380,4 @@ class EnterpriseDeviceRepository(object): logging.error("Failed to get status count") raise e - return dict(result) \ No newline at end of file + return dict(result) diff --git a/website/db/enterprise_node/enterprise_node.py b/website/db/enterprise_node/enterprise_node.py index fc350ae..6e84884 100644 --- a/website/db/enterprise_node/enterprise_node.py +++ b/website/db/enterprise_node/enterprise_node.py @@ -97,7 +97,7 @@ class EnterpriseNodeRepository(object): return roots def build_tree( - self, session: Any, node: Dict[str, Any], name: str = "" + self, session: Any, node: Dict[str, Any], name: str = "" ) -> List[Any]: # sql = ( # "select id, name, suid, parent from enterprise_node where del=0 and parent=:parent" @@ -173,7 +173,7 @@ class EnterpriseNodeRepository(object): node = to_json(res) return node - def get_entity_suid_by_node_id(self, node_id: int) -> Union[dict, None]: + def get_entity_suid_by_node_id(self, node_id: int) -> dict: with get_session() as session: res = session.execute( text("select suid, entity_suid from enterprise_node where id=:id"), @@ -181,4 +181,14 @@ class EnterpriseNodeRepository(object): ) entity = to_json(res) - return entity if entity else None + return entity + + def simple_list(self, entity_id: int) -> List[Any]: + with get_session() as session: + sql = ( + "select id, name from enterprise_node where del=0 and entity_id=:entity_id" + ) + param = {"entity_id": entity_id} + res = session.execute(text(sql), param) + node_list = to_json_list(res) + return node_list diff --git a/website/handlers/enterprise_device/handler.py b/website/handlers/enterprise_device/handler.py index 133df95..dd38992 100644 --- a/website/handlers/enterprise_device/handler.py +++ b/website/handlers/enterprise_device/handler.py @@ -14,6 +14,7 @@ from website.db.enterprise_busi_model import ( ) from website.db.enterprise_busi_model import enterprise_busi_model_node_device as DB_BusiModelNodeDevice from website.db.enterprise_device import enterprise_device as DB_Device +from website.db.enterprise_node import enterprise_node as DB_Node from website.db.enterprise_node import enterprise_node_base_model_conf as DB_NodeBaseModelConf from website.handler import APIHandler, authenticated from website.util import date_util @@ -527,6 +528,7 @@ class StatusListHandler(APIHandler): @authenticated def post(self): entity_id = self.get_int_argument("entity_id") + group = self.get_int_argument("group") classification = self.get_escaped_argument("classification", "") status = self.get_int_argument("status", 1000) pageNo = self.get_int_argument("pageNo", 1) @@ -544,6 +546,7 @@ class StatusListHandler(APIHandler): pagesize=pageSize, classification=classification, status=status, + group=group ) count = res["count"] @@ -576,12 +579,21 @@ class StatusListHandler(APIHandler): self.finish({"count": count, "data": data, "status_count": status_dic}) +class StatusGroupHandler(APIHandler): + @authenticated + def post(self): + entity_id = self.get_int_argument("entity_id") + db_node = DB_Node.EnterpriseNodeRepository() + res = db_node.simple_list(entity_id) + self.finish({"result": res}) + + class StatusInfoHandler(APIHandler): """ """ @authenticated def post(self): - device_id = self.get_int_argument("device_id") + device_id = self.get_int_argument("id") if not device_id: raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "设备id不能为空") @@ -591,6 +603,7 @@ class StatusInfoHandler(APIHandler): if not res: raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "设备不存在") res = res[0] + node_id = res["node_id"] device_suid = res["suid"] device_name = res["name"] device_comment = res["comment"] @@ -599,6 +612,10 @@ class StatusInfoHandler(APIHandler): row_cls = db_cls.get_row_by_suid(suid=classification) device_classification_name = row_cls.name + db_node = DB_Node.EnterpriseNodeRepository() + node_info = db_node.get_node_by_id(node_id) + node_name = node_info["name"] + db_busi_model = DB_BusiModelNodeDevice.EnterpriseBusiModelNodeDeviceRepository() busi_models, _ = db_busi_model.get_busi_model_by_device(device_id=device_id) @@ -634,12 +651,14 @@ class StatusInfoHandler(APIHandler): self.finish({ "classification": device_classification_name, "name": device_name, + "comment": device_comment, "ID": device_suid, "cpu": random.randint(20, 30), "mem": random.randint(20, 30), "storage": random.randint(20, 30), "gpu": random.randint(20, 30), - "models": models + "models": models, + "group": node_name }) diff --git a/website/handlers/enterprise_device/url.py b/website/handlers/enterprise_device/url.py index f7a3d1f..c012806 100644 --- a/website/handlers/enterprise_device/url.py +++ b/website/handlers/enterprise_device/url.py @@ -21,6 +21,7 @@ handlers = [ handler.DeviceBaseModelCustomConfigHandler, ), ("/enterprise/device/status/list", handler.StatusListHandler), + ("/enterprise/device/status/group", handler.StatusGroupHandler), ("/enterprise/device/status/info", handler.StatusInfoHandler), ("/enterprise/device/status/log", handler.StatusLogHandler), ] diff --git a/website/handlers/enterprise_server/__init__.py b/website/handlers/enterprise_server/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/website/handlers/enterprise_server/handler.py b/website/handlers/enterprise_server/handler.py new file mode 100644 index 0000000..e7b459e --- /dev/null +++ b/website/handlers/enterprise_server/handler.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +import random + +from sqlalchemy import text + +from website import errors +from website import settings +from website.db.enterprise_device.enterprise_device import EnterpriseEntityRepository as EntRepo +from website.db_mysql import to_json_list, to_json +from website.handler import APIHandler, authenticated +from website.util import aes +from website.util import shortuuid + + +class AddHandler(APIHandler): + """ + - 描述:新建服务器 + - 请求方式:post + - 请求参数: + > - entity_id, int, 企业id + > - name, string, 服务器名称 + > - ip, string, + > - port, int, 默认端口 + > - username, string, 用户名 + > - passwd, string, + + - 返回值:无 + """ + + @authenticated + def post(self): + entity_id = self.get_int_argument('entity_id') + name = self.get_escaped_argument('name', '') + ip = self.get_escaped_argument('ip', '') + port = self.get_int_argument("port", 22) + username = self.get_escaped_argument('username', '') + passwd = self.get_escaped_argument('passwd', '') + + if not entity_id: + raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "entity_id is required") + e = EntRepo() + entity_suid = e.get_entity_suid(entity_id) + if not entity_suid: + raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "entity is invalid") + + with self.app_mysql.connect() as conn: + conn.execute( + text( + "insert into " + "enterprise_server(suid, entity_id, entity_suid, name, ip, port, username, passwd) " + "values(:suid, :entity_id, :entity_suid, :name, :ip, :port, :username, :passwd) " + ), + { + "suid": shortuuid.ShortUUID().random(10), + "entity_id": entity_id, + "entity_suid": entity_suid, + "name": name, + "ip": ip, + "port": port, + "username": username, + "passwd": aes.encrypt(settings.enterprise_aes_key, passwd) + } + ) + conn.commit() + + self.finish() + + +class ListHandler(APIHandler): + """ + - 描述:服务器列表 + - 请求方式:post + - 请求参数: + > - entity_id, int, 企业id + > - status, int, 1000/all/默认, 1001/在线,1002/离线 + > - pageNo, int, + > - pageSize, int + - 返回值: + ``` + { + "count": 123, + "data": [ + { + "id": 123, + "name": "xx", + "status": 1001, # 状态, 1001/在线,1002/离线 + "cpu": 123, + "mem": 123, + "storage": 213, + "gpu": 123, + }, + ... + ] + } +``` + """ + + @authenticated + def post(self): + entity_id = self.get_int_argument('entity_id') + status = self.get_int_argument("status") + pageNo = self.get_int_argument("pageNo", 1) + pageSize = self.get_int_argument("pageSize", 10) + if not entity_id: + raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "entity_id is required") + if status and status not in (1001, 1002): + raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "status is invalid") + + with self.app_mysql.connect() as conn: + p = {} + sql_count = "select count(1) from enterprise_server where entity_id=:entity_id" + sql_data = "select id, name, status from enterprise_server where entity_id=:entity_id" + p.update({"entity_id": entity_id}) + + if status: + sql_count += " and status=:status" + sql_data += " and status=:status" + p.update({"status": status}) + + count = conn.scalar(text(sql_count), p) + data = conn.execute(text(sql_data), p).limit(pageSize).offset((pageNo - 1) * pageSize) + + status_dic = {1001: 0, 1002: 0} + sql_status = "select status, count(id) c from enterprise_server where entity_id=:entity_id group by status" + status_cur = conn.execute(text(sql_status), p) + status_list = to_json_list(status_cur) + for item in status_list: + status_dic[item["status"]] = item["c"] + + for item in data: + item.update( + {"cpu": random.randint(20, 30), + "mem": random.randint(20, 30), + "storage": random.randint(20, 30), + "gpu": random.randint(20, 30), }) + + self.finish({"count": count, "data": to_json_list(data), "status": status_dic}) + + +class InfoHandler(APIHandler): + """ + - 描述:服务器信息 + - 请求方式:post + - 请求参数: + > - server_id, int, 服务器id + - 返回值: + ``` + { + "name": "xx", + "ip": "xxx", + "port": "xxx", + "username": "xxx", + "cpu": 123, + "mem": 123, + "storage": 213, + "gpu": 123, + } + ``` + """ + + @authenticated + def post(self): + server_id = self.get_int_argument('server_id') + with self.app_mysql.connect() as conn: + cur = conn.execute( + text("select name, ip, port, username from enterprise_server where id=:id"), + {"id": server_id}) + data = to_json(cur) + if data: + data.update( + {"cpu": random.randint(20, 30), + "mem": random.randint(20, 30), + "storage": random.randint(20, 30), + "gpu": random.randint(20, 30), }) + self.finish(data) + + +class DeleteHandler(APIHandler): + @authenticated + def post(self): + server_id = self.get_int_argument('server_id') + with self.app_mysql.connect() as conn: + conn.execute( + text("delete from enterprise_server where id=:id"), {"id": server_id} + ) + conn.commit() + self.finish() + + +class LogHandler(APIHandler): + """ + - 描述:服务器列表 + - 请求方式:post + - 请求参数: + > - server_id, int, 服务器id + > - pageNo, int + > - pageSize, int + - 返回值: + """ + + @authenticated + def post(self): + entity_id = self.get_int_argument('entity_id') + pageNo = self.get_int_argument('pageNo', 1) + pageSize = self.get_int_argument('pageSize', 10) + + with self.app_mysql.connect() as conn: + p = {} + sql_count = "select count(1) from enterprise_server where entity_id=:entity_id" + sql_data = "select id, name, ip, port from enterprise_server where entity_id=:entity_id" + p.update({"entity_id": entity_id}) + + count = conn.scalar(text(sql_count), p) + data = conn.execute(text(sql_data), p).order_by(text("id desc")).limit(pageSize).offset( + (pageNo - 1) * pageSize) + + data = to_json_list(data) + self.finish({"count": count, "data": data}) diff --git a/website/handlers/enterprise_server/url.py b/website/handlers/enterprise_server/url.py new file mode 100644 index 0000000..8c9b554 --- /dev/null +++ b/website/handlers/enterprise_server/url.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + +from website.handlers.enterprise_server import handler + +handlers = [ + ("/enterprise/server/add", handler.AddHandler), + ("/enterprise/server/list", handler.ListHandler), + ("/enterprise/server/info", handler.InfoHandler), + ("/enterprise/server/log", handler.LogHandler), + ("/enterprise/server/delete", handler.DeleteHandler) +] + +page_handlers = [] \ No newline at end of file