From 7e38dd8fabdd0f2c40daa50dbfe09cd5c3e2ca9e Mon Sep 17 00:00:00 2001 From: pycook Date: Tue, 8 Aug 2023 13:16:07 +0800 Subject: [PATCH 1/6] upgrade celery --- Makefile | 2 +- cmdb-api/Pipfile | 8 +-- cmdb-api/api/app.py | 2 +- cmdb-api/api/lib/perm/auth.py | 15 ++-- cmdb-api/celery_worker.py | 2 +- cmdb-api/requirements.txt | 41 ++--------- cmdb-api/settings.example.py | 11 +-- docs/cmdb.sql | 130 +--------------------------------- docs/local.md | 4 +- docs/local_en.md | 4 +- 10 files changed, 31 insertions(+), 188 deletions(-) diff --git a/Makefile b/Makefile index 99b1122..aa01399 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ api: cd cmdb-api && pipenv run flask run -h 0.0.0.0 worker: - cd cmdb-api && pipenv run celery worker -A celery_worker.celery -E -Q one_cmdb_async --concurrency=1 -D && pipenv run celery worker -A celery_worker.celery -E -Q acl_async --concurrency=1 -D + cd cmdb-api && pipenv run celery -A celery_worker.celery worker -E -Q one_cmdb_async --concurrency=1 -D && pipenv run celery -A celery_worker.celery worker -E -Q acl_async --concurrency=1 -D ui: cd cmdb-ui && yarn run serve diff --git a/cmdb-api/Pipfile b/cmdb-api/Pipfile index 7c4ca41..901072e 100644 --- a/cmdb-api/Pipfile +++ b/cmdb-api/Pipfile @@ -14,7 +14,7 @@ Flask-RESTful = "==0.3.10" Flask-SQLAlchemy = "==2.5.0" SQLAlchemy = "==1.4.49" PyMySQL = "==1.1.0" -redis = "==3.2.1" +redis = "==4.6.0" # Migrations Flask-Migrate = "==2.5.2" # Deployment @@ -32,10 +32,10 @@ Flask-Caching = ">=1.0.0" environs = "==4.2.0" marshmallow = "==2.20.2" # async tasks -celery = "==4.3.0" +celery = "==5.3.1" celery_once = "==3.0.1" more-itertools = "==5.0.0" -kombu = "==4.4.0" +kombu = "==5.3.1" # common setting timeout-decorator = "==0.5.0" WTForms = "==3.0.0" @@ -50,7 +50,7 @@ toposort = ">=1.5" requests = ">=2.22.0" PyJWT = "==2.4.0" elasticsearch = "==7.17.9" -future = "==0.18.2" +future = "==0.18.3" itsdangerous = "==2.1.2" Jinja2 = "==3.1.2" jinja2schema = "==0.1.4" diff --git a/cmdb-api/api/app.py b/cmdb-api/api/app.py index 4df68fc..5c2ca7a 100644 --- a/cmdb-api/api/app.py +++ b/cmdb-api/api/app.py @@ -129,7 +129,7 @@ def register_extensions(app): rd.init_app(app) if app.config.get('USE_ES'): es.init_app(app) - celery.conf.update(app.config) + celery.conf.update(app.config.get('CELERY')) def register_blueprints(app): diff --git a/cmdb-api/api/lib/perm/auth.py b/cmdb-api/api/lib/perm/auth.py index 3b999ef..327af69 100644 --- a/cmdb-api/api/lib/perm/auth.py +++ b/cmdb-api/api/lib/perm/auth.py @@ -7,10 +7,8 @@ from functools import wraps import jwt from flask import abort from flask import current_app -from flask import g from flask import request from flask import session -from flask_login import current_user from flask_login import login_user from api.lib.perm.acl.acl import ACLManager @@ -65,12 +63,10 @@ def _auth_with_key(): def _auth_with_session(): - if isinstance(getattr(g, 'user', None), User): - login_user(current_user) - return True if "acl" in session and "userName" in (session["acl"] or {}): login_user(UserCache.get(session["acl"]["userName"])) return True + return False @@ -158,9 +154,12 @@ def _auth_with_acl_token(): def auth_required(func): - if request.json is not None: - setattr(request, 'values', request.json) - else: + try: + if request.json is not None: + setattr(request, 'values', request.json) + else: + setattr(request, 'values', request.values.to_dict()) + except: setattr(request, 'values', request.values.to_dict()) @wraps(func) diff --git a/cmdb-api/celery_worker.py b/cmdb-api/celery_worker.py index 5692141..5f6dbbd 100644 --- a/cmdb-api/celery_worker.py +++ b/cmdb-api/celery_worker.py @@ -3,7 +3,7 @@ from api.app import create_app from api.extensions import celery -# celery worker -A celery_worker.celery -l DEBUG -E -Q xxxx +# celery -A celery_worker.celery worker -l DEBUG -E -Q xxxx app = create_app() app.app_context().push() diff --git a/cmdb-api/requirements.txt b/cmdb-api/requirements.txt index be049a2..ac5cf22 100644 --- a/cmdb-api/requirements.txt +++ b/cmdb-api/requirements.txt @@ -1,20 +1,9 @@ -i https://mirrors.aliyun.com/pypi/simple alembic==1.7.7 -amqp==2.6.1 -aniso8601==9.0.1 -attrs==23.1.0 -backports.zoneinfo==0.2.1 -bcrypt==4.0.1 -beautifulsoup4==4.12.2 -billiard==3.6.4.0 bs4==0.0.1 -cachelib==0.9.0 -celery==4.3.0 +celery==5.3.1 celery-once==3.0.1 -certifi==2023.7.22 -charset-normalizer==3.1.0 click==8.1.3 -dnspython==2.3.0 elasticsearch==7.17.9 email-validator==1.3.1 environs==4.2.0 @@ -27,51 +16,31 @@ Flask-Login==0.6.2 Flask-Migrate==2.5.2 Flask-RESTful==0.3.10 Flask-SQLAlchemy==2.5.0 -future==0.18.2 +future==0.18.3 gunicorn==21.0.1 -idna==3.4 -importlib-metadata==6.8.0 -importlib-resources= -=6.0.0 itsdangerous==2.1.2 Jinja2==3.1.2 jinja2schema==0.1.4 jsonschema==4.18.0 -jsonschema-specifications==2023.6.1 -kombu==4.4.0 +kombu==5.3.1 Mako==1.2.4 MarkupSafe==2.1.3 marshmallow==2.20.2 -meld3==2.0.1 -mistune==3.0.1 more-itertools==5.0.0 msgpack-python==0.5.6 Pillow==9.3.0 -pkgutil_resolve_name==1.3.10 -pyasn1==0.5.0 -pyasn1-modules==0.3.0 pycryptodome==3.12.0 PyJWT==2.4.0 PyMySQL==1.1.0 -python-dateutil==2.8.2 -python-dotenv==1.0.0 python-ldap==3.4.0 -pytz==2023.3 PyYAML==6.0 -redis==3.2.1 -referencing==0.29.1 +redis==4.6.0 requests==2.31.0 -rpds-py==0.8.8 six==1.12.0 -soupsieve==2.4.1 SQLAlchemy==1.4.49 supervisor==4.0.3 timeout-decorator==0.5.0 toposort==1.10 treelib==1.6.1 -tzlocal==5.0.1 -urllib3==1.26.16 -vine==1.3.0 Werkzeug==2.3.6 -WTForms==3.0.0 -zipp==3.16.0 \ No newline at end of file +WTForms==3.0.0 \ No newline at end of file diff --git a/cmdb-api/settings.example.py b/cmdb-api/settings.example.py index fc22f59..ce66b4b 100644 --- a/cmdb-api/settings.example.py +++ b/cmdb-api/settings.example.py @@ -53,13 +53,16 @@ MAIL_PASSWORD = '' DEFAULT_MAIL_SENDER = '' # # queue -CELERY_RESULT_BACKEND = "redis://127.0.0.1:6379/2" -BROKER_URL = 'redis://127.0.0.1:6379/2' -BROKER_VHOST = '/' +CELERY = { + "broker_url": 'redis://127.0.0.1:6379/2', + "result_backend": "redis://127.0.0.1:6379/2", + "broker_vhost": "/", + "broker_connection_retry_on_startup": True +} ONCE = { 'backend': 'celery_once.backends.Redis', 'settings': { - 'url': BROKER_URL, + 'url': CELERY['broker_url'], } } diff --git a/docs/cmdb.sql b/docs/cmdb.sql index feeaa4e..aa6d672 100644 --- a/docs/cmdb.sql +++ b/docs/cmdb.sql @@ -650,7 +650,7 @@ CREATE TABLE `c_ad_ci_types` ( KEY `ix_c_ad_ci_types_uid` (`uid`), KEY `ix_c_ad_ci_types_agent_id` (`agent_id`), KEY `ix_c_ad_ci_types_deleted` (`deleted`), - CONSTRAINT `c_ad_ci_types_ibfk2` FOREIGN KEY (`adr_id`) REFERENCES `c_adr` (`id`), + CONSTRAINT `c_ad_ci_types_ibfk2` FOREIGN KEY (`adr_id`) REFERENCES `c_ad_rules` (`id`), CONSTRAINT `c_ad_ci_types_ibfk_1` FOREIGN KEY (`type_id`) REFERENCES `c_ci_types` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -705,134 +705,6 @@ INSERT INTO `c_ad_rules` VALUES (NULL,0,'2023-07-11 16:57:01',NULL,1,'阿里云' /*!40000 ALTER TABLE `c_ad_rules` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `c_adc` --- - -DROP TABLE IF EXISTS `c_adc`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `c_adc` ( - `deleted_at` datetime DEFAULT NULL, - `deleted` tinyint(1) DEFAULT NULL, - `created_at` datetime DEFAULT NULL, - `updated_at` datetime DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - `a` int(11) DEFAULT NULL, - `b` int(11) DEFAULT NULL, - `unique_value` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL, - `c` json DEFAULT NULL, - `d` int(11) DEFAULT NULL, - `e` tinyint(1) DEFAULT NULL, - `f` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL, - `g` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `a` (`a`), - KEY `b` (`b`), - KEY `ix_c_adc_d` (`d`), - KEY `ix_c_adc_f` (`f`), - KEY `ix_c_adc_unique_value` (`unique_value`), - KEY `ix_c_adc_deleted` (`deleted`), - CONSTRAINT `c_adc_ibfk_1` FOREIGN KEY (`a`) REFERENCES `c_ci_types` (`id`), - CONSTRAINT `c_adc_ibfk_2` FOREIGN KEY (`b`) REFERENCES `c_adt` (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `c_adc` --- - -LOCK TABLES `c_adc` WRITE; -/*!40000 ALTER TABLE `c_adc` DISABLE KEYS */; -INSERT INTO `c_adc` VALUES (NULL,0,'2023-05-11 16:14:59','2023-05-23 17:47:17',20,28,1,'21980106042SHC600012','{\"sn\": \"21980106042SHC600012\", \"ips\": [\"146.242.2.234\", \"192.168.3.85\"], \"status\": \"\", \"ci_type\": \"switch\", \"manager_ip\": \"192.168.3.85\", \"unique_key\": \"sn\", \"description\": \"S5720S-52X-LI-AC \\r\\nHuawei Versatile Routing Platform Software \\r\\n VRP (R) software,Version 5.170 (S5720 V200R021C00SPC100) \\r\\n Copyright (C) 2007 Huawei Technologies Co., Ltd.\", \"device_name\": \"HUAWEI S5720 Routing Switch\", \"device_model\": \"2011.2.23.429\", \"manufacturer\": \"HUAWEI Technology Co.,Ltd\"}',NULL,1,'admin','2023-05-23 17:47:17'),(NULL,0,'2023-05-11 16:15:00','2023-05-23 17:47:17',22,28,1,'2102350HND9WJ3000319','{\"sn\": \"2102350HND9WJ3000319\", \"ips\": [\"169.254.3.1\", \"192.168.1.3\", \"192.168.3.95\"], \"status\": \"\", \"ci_type\": \"switch\", \"manager_ip\": \"192.168.1.3\", \"unique_key\": \"sn\", \"description\": \"Huawei AC6003-8 Huawei Versatile Routing Platform Software VRP (R) software,Version 5.170 (AC6003-8 V200R019C00SPC500) Copyright (C) 2011-2020 Huawei Technologies Co., Ltd\", \"device_name\": \"AC6003-8\", \"device_model\": \"2011.2.240.12\", \"manufacturer\": \"HUAWEI Technology Co.,Ltd\"}',NULL,1,'admin','2023-05-23 17:47:17'),(NULL,0,'2023-05-11 16:15:00','2023-05-23 17:47:17',23,28,1,'102130117737','{\"sn\": \"102130117737\", \"ips\": [\"10.86.21.1\", \"20.86.21.1\", \"192.168.1.1\", \"192.168.3.1\", \"192.168.10.1\", \"192.168.20.1\", \"192.168.21.1\", \"192.168.25.1\", \"192.168.28.1\", \"192.168.29.1\", \"192.168.126.1\", \"192.168.127.253\", \"192.168.138.1\"], \"status\": \"\", \"ci_type\": \"switch\", \"manager_ip\": \"10.86.21.1\", \"unique_key\": \"sn\", \"description\": \"S6730S-H24X6C-A \\r\\nHuawei Versatile Routing Platform Software \\r\\n VRP (R) software,Version 5.170 (S6730 V200R021C00SPC100) \\r\\n Copyright (C) 2007 Huawei Technologies Co., Ltd.\", \"device_name\": \"HUAWEI S6730 Routing Switch\", \"device_model\": \"2011.2.23.763\", \"manufacturer\": \"HUAWEI Technology Co.,Ltd\"}',NULL,1,'admin','2023-05-23 17:47:17'),(NULL,0,'2023-05-11 16:15:00','2023-05-23 17:47:16',24,28,1,'2102359589DMH1000063','{\"sn\": \"2102359589DMH1000063\", \"ips\": [\"192.168.1.6\", \"192.168.3.82\", \"192.168.126.6\"], \"status\": \"\", \"ci_type\": \"switch\", \"manager_ip\": \"192.168.1.6\", \"unique_key\": \"sn\", \"description\": \"S5720-52X-EI-AC \\r\\nHuawei Versatile Routing Platform Software \\r\\n VRP (R) software,Version 5.170 (S5720 V200R019C10SPC500) \\r\\n Copyright (C) 2007 Huawei Technologies Co., Ltd.\", \"device_name\": \"HUAWEI S5720 Routing Switch\", \"device_model\": \"2011.2.23.306\", \"manufacturer\": \"HUAWEI Technology Co.,Ltd\"}',NULL,1,'admin','2023-05-23 17:47:16'),(NULL,0,'2023-05-11 16:15:00','2023-05-23 17:47:16',27,28,1,'21980105972SHA600431','{\"sn\": \"21980105972SHA600431\", \"ips\": [\"192.168.1.8\", \"192.168.126.8\"], \"status\": \"\", \"ci_type\": \"switch\", \"manager_ip\": \"192.168.1.8\", \"unique_key\": \"sn\", \"description\": \"S5720S-28X-PWR-LI-AC \\r\\nHuawei Versatile Routing Platform Software \\r\\n VRP (R) software,Version 5.170 (S5720 V200R021C00SPC100) \\r\\n Copyright (C) 2007 Huawei Technologies Co., Ltd.\", \"device_name\": \"HUAWEI S5720 Routing Switch\", \"device_model\": \"2011.2.23.422\", \"manufacturer\": \"HUAWEI Technology Co.,Ltd\"}',NULL,1,'admin','2023-05-23 17:47:16'),(NULL,0,'2023-05-11 16:15:59','2023-05-23 17:47:16',28,28,1,'2102352360W0EC001814','{\"sn\": \"2102352360W0EC001814\", \"ips\": [\"10.172.130.9\", \"10.172.131.9\", \"10.172.132.9\", \"10.172.133.9\"], \"status\": \"\", \"ci_type\": \"switch\", \"manager_ip\": \"10.172.130.9\", \"unique_key\": \"sn\", \"description\": \"S5700-24TP-SI-AC \\r\\nHuawei Versatile Routing Platform Software \\r\\n VRP (R) software,Version 5.150 (S5700 V200R005C00SPC500) \\r\\n Copyright (C) 2007 Huawei Technologies Co., Ltd.\", \"device_name\": \"Quidway S5700 Routing Switch\", \"device_model\": \"2011.2.23.145\", \"manufacturer\": \"HUAWEI Technology Co.,Ltd\"}',NULL,1,'admin','2023-05-23 17:47:16'),(NULL,0,'2023-05-11 16:15:59','2023-05-23 17:47:16',30,28,1,'2102352360W0F4000579','{\"sn\": \"2102352360W0F4000579\", \"ips\": [\"10.86.21.10\", \"192.168.1.5\", \"192.168.3.91\", \"192.168.29.5\", \"192.168.126.5\"], \"status\": \"\", \"ci_type\": \"switch\", \"manager_ip\": \"192.168.1.5\", \"unique_key\": \"sn\", \"description\": \"S5700-24TP-SI-AC \\r\\nHuawei Versatile Routing Platform Software \\r\\n VRP (R) software,Version 5.150 (S5700 V200R005C00SPC500) \\r\\n Copyright (C) 2007 Huawei Technologies Co., Ltd.\", \"device_name\": \"Quidway S5700 Routing Switch\", \"device_model\": \"2011.2.23.145\", \"manufacturer\": \"HUAWEI Technology Co.,Ltd\"}',NULL,1,'admin','2023-05-23 17:47:16'),(NULL,0,'2023-05-11 16:16:00','2023-05-23 17:47:16',32,28,1,'2102352360W0F2000671','{\"sn\": \"2102352360W0F2000671\", \"ips\": [\"192.168.1.7\", \"192.168.3.90\", \"192.168.29.7\", \"192.168.126.7\"], \"status\": \"\", \"ci_type\": \"switch\", \"manager_ip\": \"192.168.1.7\", \"unique_key\": \"sn\", \"description\": \"S5700-24TP-SI-AC \\r\\nHuawei Versatile Routing Platform Software \\r\\n VRP (R) software,Version 5.150 (S5700 V200R005C00SPC500) \\r\\n Copyright (C) 2007 Huawei Technologies Co., Ltd.\", \"device_name\": \"Quidway S5700 Routing Switch\", \"device_model\": \"2011.2.23.145\", \"manufacturer\": \"HUAWEI Technology Co.,Ltd\"}',NULL,1,'admin','2023-05-23 17:47:16'),(NULL,0,'2023-05-11 16:16:00','2023-05-23 19:18:34',33,28,1,'102190453258','{\"sn\": \"102190453258\", \"ips\": [\"10.172.135.254\", \"58.33.167.78\", \"112.64.24.202\", \"192.168.0.1\"], \"status\": \"\", \"ci_type\": \"switch\", \"manager_ip\": \"10.172.135.254\", \"unique_key\": \"sn\", \"description\": \"Huawei Versatile Routing Platform Software\\r\\nSoftware Version: VRP (R) Software, Version 5.170 USG6300E V600R007C20SPC300\\r\\nCopyright (C) 2014-2021 Huawei Technologies Co., Ltd.\\r\\n\", \"device_name\": \"USG6305E\", \"device_model\": \"2011.2.321.1.198\", \"manufacturer\": \"HUAWEI Technology Co.,Ltd\"}',NULL,1,'admin','2023-05-23 19:18:34'),(NULL,0,'2023-05-11 16:16:00','2023-05-23 19:18:34',34,28,1,'W02160041614','{\"sn\": \"W02160041614\", \"ips\": [\"192.168.1.253\", \"192.168.3.81\", \"192.168.138.81\"], \"status\": \"\", \"ci_type\": \"switch\", \"manager_ip\": \"192.168.3.81\", \"unique_key\": \"sn\", \"description\": \"S5731S-H24T4XC-A \\r\\nHuawei Versatile Routing Platform Software \\r\\n VRP (R) software,Version 5.170 (S5731 V200R021C00SPC100) \\r\\n Copyright (C) 2007 Huawei Technologies Co., Ltd.\", \"device_name\": \"HUAWEI S5731 Routing Switch\", \"device_model\": \"2011.2.23.705\", \"manufacturer\": \"HUAWEI Technology Co.,Ltd\"}',NULL,1,'admin','2023-05-23 19:18:34'); -/*!40000 ALTER TABLE `c_adc` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `c_adr` --- - -DROP TABLE IF EXISTS `c_adr`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `c_adr` ( - `deleted_at` datetime DEFAULT NULL, - `deleted` tinyint(1) DEFAULT NULL, - `created_at` datetime DEFAULT NULL, - `updated_at` datetime DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - `a` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL, - `b` enum('http','snmp','agent') COLLATE utf8_unicode_ci DEFAULT NULL, - `c` tinyint(1) DEFAULT NULL, - `d` int(11) DEFAULT NULL, - `e` json DEFAULT NULL, - `f` json DEFAULT NULL, - `g` tinyint(1) DEFAULT NULL, - `h` text COLLATE utf8_unicode_ci, - `i` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `ix_c_adr_d` (`d`), - KEY `ix_c_adr_c` (`c`), - KEY `ix_c_adr_deleted` (`deleted`), - KEY `ix_c_adr_b` (`b`) -) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `c_adr` --- - -LOCK TABLES `c_adr` WRITE; -/*!40000 ALTER TABLE `c_adr` DISABLE KEYS */; -INSERT INTO `c_adr` VALUES (NULL,0,'2023-05-23 11:14:22',NULL,1,'阿里云','http',1,NULL,'{\"icon\": {\"name\": \"caise-aliyun\"}}',NULL,0,NULL,NULL),(NULL,0,'2023-05-23 11:14:22',NULL,2,'腾讯云','http',1,NULL,'{\"icon\": {\"name\": \"caise-tengxunyun\"}}',NULL,0,NULL,NULL),(NULL,0,'2023-05-23 11:14:22',NULL,3,'华为云','http',1,NULL,'{\"icon\": {\"name\": \"caise-huaweiyun\"}}',NULL,0,NULL,NULL),(NULL,0,'2023-05-23 11:14:22',NULL,4,'AWS','http',1,NULL,'{\"icon\": {\"name\": \"caise-aws\"}}',NULL,0,NULL,NULL),(NULL,0,'2023-05-23 11:14:22',NULL,5,'交换机','snmp',1,NULL,'{\"icon\": {\"name\": \"caise-jiaohuanji\"}}',NULL,0,NULL,NULL),(NULL,0,'2023-05-23 11:14:22',NULL,6,'路由器','snmp',1,NULL,'{\"icon\": {\"name\": \"caise-luyouqi\"}}',NULL,0,NULL,NULL),(NULL,0,'2023-05-23 11:14:22',NULL,7,'防火墙','snmp',1,NULL,'{\"icon\": {\"name\": \"caise-fanghuoqiang\"}}',NULL,0,NULL,NULL),(NULL,0,'2023-05-23 11:14:22',NULL,8,'打印机','snmp',1,NULL,'{\"icon\": {\"name\": \"caise-dayinji\"}}',NULL,0,NULL,NULL),(NULL,0,'2023-05-23 14:43:42',NULL,9,'物理机','agent',1,NULL,'{\"icon\": {\"name\": \"caise-wuliji\", \"color\": \"\"}}','[]',0,NULL,NULL),(NULL,0,'2023-05-23 14:43:52',NULL,10,'虚拟机','agent',1,NULL,'{\"icon\": {\"name\": \"caise-xuniji\", \"color\": \"\"}}','[]',0,NULL,NULL),(NULL,0,'2023-05-23 14:44:08',NULL,11,'网卡','agent',1,NULL,'{\"icon\": {\"name\": \"caise-wangka\", \"color\": \"\"}}','[]',0,NULL,NULL),(NULL,0,'2023-05-23 14:44:18',NULL,12,'硬盘','agent',1,NULL,'{\"icon\": {\"name\": \"caise-yingpan\", \"color\": \"\"}}','[]',0,NULL,NULL),(NULL,0,'2023-05-23 14:44:53',NULL,13,'MySQL','agent',1,NULL,'{\"icon\": {\"name\": \"caise-mySQL\", \"color\": \"\"}}','[]',0,NULL,NULL),(NULL,0,'2023-05-23 14:45:06',NULL,14,'MongoDB','agent',1,NULL,'{\"icon\": {\"name\": \"caise-mongodb\", \"color\": \"\"}}','[]',0,NULL,NULL),(NULL,0,'2023-05-23 14:45:27',NULL,15,'MSSQL','agent',1,NULL,'{\"icon\": {\"name\": \"caise-SQLServer\", \"color\": \"\"}}','[]',0,NULL,NULL),(NULL,0,'2023-05-23 14:45:43',NULL,16,'Nginx','agent',1,NULL,'{\"icon\": {\"name\": \"caise-nginx\", \"color\": \"\"}}','[]',0,NULL,NULL),(NULL,0,'2023-05-23 14:45:54',NULL,17,'Tomcat','agent',1,NULL,'{\"icon\": {\"name\": \"caise-tomcat\", \"color\": \"\"}}','[]',0,NULL,NULL),(NULL,0,'2023-05-23 14:46:12',NULL,18,'Apache','agent',1,NULL,'{\"icon\": {\"name\": \"caise-apache\", \"color\": \"\"}}','[]',0,NULL,NULL); -/*!40000 ALTER TABLE `c_adr` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `c_adt` --- - -DROP TABLE IF EXISTS `c_adt`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `c_adt` ( - `deleted_at` datetime DEFAULT NULL, - `deleted` tinyint(1) DEFAULT NULL, - `created_at` datetime DEFAULT NULL, - `updated_at` datetime DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - `a` int(11) DEFAULT NULL, - `b` int(11) DEFAULT NULL, - `c` json DEFAULT NULL, - `d` json DEFAULT NULL, - `e` tinyint(1) DEFAULT NULL, - `f` varchar(8) COLLATE utf8_unicode_ci DEFAULT NULL, - `g` text COLLATE utf8_unicode_ci, - `h` int(11) DEFAULT NULL, - `i` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL, - `j` json DEFAULT NULL, - `k` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `a` (`a`), - KEY `b` (`b`), - KEY `ix_c_adt_deleted` (`deleted`), - KEY `ix_c_adt_k` (`k`), - KEY `ix_c_adt_f` (`f`), - CONSTRAINT `c_adt_ibfk_1` FOREIGN KEY (`a`) REFERENCES `c_ci_types` (`id`), - CONSTRAINT `c_adt_ibfk_2` FOREIGN KEY (`b`) REFERENCES `c_adr` (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `c_adt` --- - -LOCK TABLES `c_adt` WRITE; -/*!40000 ALTER TABLE `c_adt` DISABLE KEYS */; -INSERT INTO `c_adt` VALUES (NULL,0,'2023-05-23 14:47:58','2023-05-23 15:18:32',1,28,5,'{\"sn\": \"switch_sn\", \"ips\": \"ips\", \"manager_ip\": \"manage_ip\", \"description\": \"description\", \"device_name\": \"netdev_name\", \"device_model\": \"netdev_type\", \"manufacturer\": \"netdev_manufacturer1\"}',NULL,0,'0x1111','',3600,NULL,'{\"nodes\": [{\"id\": \"09973a8f-9347-446e-9700-388cc430da01\", \"ip\": \"\", \"version\": \"\", \"community\": \"\"}]}',1),(NULL,0,'2023-05-23 14:48:15',NULL,2,29,6,NULL,NULL,0,NULL,NULL,3600,NULL,NULL,1),(NULL,0,'2023-05-23 14:48:24',NULL,3,30,7,NULL,NULL,0,NULL,NULL,3600,NULL,NULL,1),(NULL,0,'2023-05-23 17:27:21',NULL,4,4,9,NULL,NULL,0,NULL,NULL,300,NULL,NULL,1); -/*!40000 ALTER TABLE `c_adt` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `c_attribute_histories` -- diff --git a/docs/local.md b/docs/local.md index c01400c..7083331 100644 --- a/docs/local.md +++ b/docs/local.md @@ -28,8 +28,8 @@ cp cmdb-api/settings.example.py cmdb-api/settings.py - 后端: 进入**cmdb-api**目录执行 `pipenv run flask run -h 0.0.0.0` - 前端: 进入**cmdb-ui**目录执行`yarn run serve` - worker: - - 进入**cmdb-api**目录执行 `pipenv run celery worker -A celery_worker.celery -E -Q one_cmdb_async --concurrency=1 -D` - - 进入**cmdb-api**目录执行 `pipenv run celery worker -A celery_worker.celery -E -Q acl_async --concurrency=1 -D` + - 进入**cmdb-api**目录执行 `pipenv run celery -A celery_worker.celery worker -E -Q one_cmdb_async --concurrency=1 -D` + - 进入**cmdb-api**目录执行 `pipenv run celery -A celery_worker.celery worker -E -Q acl_async --concurrency=1 -D` - 浏览器打开: [http://127.0.0.1:8000](http://127.0.0.1:8000) - 如果是非本机访问, 要修改**cmdb-ui/.env**里**VUE_APP_API_BASE_URL**里的 IP 地址为后端服务的 ip 地址 diff --git a/docs/local_en.md b/docs/local_en.md index a518a9c..9526c9f 100644 --- a/docs/local_en.md +++ b/docs/local_en.md @@ -26,8 +26,8 @@ - backend: in **cmdb-api** directory: `pipenv run flask run -h 0.0.0.0` - frontend: in **cmdb-ui** directory: `yarn run serve` - worker: - - in **cmdb-api** directory: `pipenv run celery worker -A celery_worker.celery -E -Q one_cmdb_async --concurrency=1 -D` - - in **cmdb-api** directory: `pipenv run celery worker -A celery_worker.celery -E -Q acl_async --concurrency=1 -D` + - in **cmdb-api** directory: `pipenv run celery -A celery_worker.celery worker -E -Q one_cmdb_async --concurrency=1 -D` + - in **cmdb-api** directory: `pipenv run celery -A celery_worker.celery worker -E -Q acl_async --concurrency=1 -D` - homepage: [http://127.0.0.1:8000](http://127.0.0.1:8000) - if not run localhost: please change ip address(**VUE_APP_API_BASE_URL**) in config file **cmdb-ui/.env** into your backend ip address From cb01b577a50c0c9b1ae8d4cd55ce38223865ac41 Mon Sep 17 00:00:00 2001 From: pycook Date: Tue, 8 Aug 2023 16:33:24 +0800 Subject: [PATCH 2/6] fix celery config --- cmdb-api/api/app.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmdb-api/api/app.py b/cmdb-api/api/app.py index 5c2ca7a..d6fcdd0 100644 --- a/cmdb-api/api/app.py +++ b/cmdb-api/api/app.py @@ -129,7 +129,9 @@ def register_extensions(app): rd.init_app(app) if app.config.get('USE_ES'): es.init_app(app) - celery.conf.update(app.config.get('CELERY')) + + app.config.update(app.config.get("CELERY")) + celery.conf.update(app.config) def register_blueprints(app): From 684c1ab924e41a9ecf06b1b04baa42aea83f286e Mon Sep 17 00:00:00 2001 From: EvanSung Date: Thu, 10 Aug 2023 10:43:59 +0800 Subject: [PATCH 3/6] optimize(auth): auth request json --- cmdb-api/api/lib/perm/auth.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/cmdb-api/api/lib/perm/auth.py b/cmdb-api/api/lib/perm/auth.py index 327af69..76e2481 100644 --- a/cmdb-api/api/lib/perm/auth.py +++ b/cmdb-api/api/lib/perm/auth.py @@ -154,12 +154,9 @@ def _auth_with_acl_token(): def auth_required(func): - try: - if request.json is not None: - setattr(request, 'values', request.json) - else: - setattr(request, 'values', request.values.to_dict()) - except: + if request.get_json(silent=True) is not None: + setattr(request, 'values', request.json) + else: setattr(request, 'values', request.values.to_dict()) @wraps(func) From 9756f70044f44952dc1ec049c73675fec96eae2b Mon Sep 17 00:00:00 2001 From: "hu.sima" Date: Thu, 10 Aug 2023 15:30:01 +0800 Subject: [PATCH 4/6] style: format common setting --- cmdb-api/api/lib/common_setting/const.py | 16 ++-- cmdb-api/api/lib/common_setting/department.py | 17 ++-- cmdb-api/api/lib/common_setting/employee.py | 81 +++++++------------ .../api/lib/common_setting/resp_format.py | 5 ++ cmdb-api/api/models/common_setting.py | 63 +++++++-------- cmdb-api/api/tasks/common_setting.py | 13 +-- .../api/views/common_setting/department.py | 2 +- cmdb-api/api/views/common_setting/employee.py | 2 - 8 files changed, 83 insertions(+), 116 deletions(-) diff --git a/cmdb-api/api/lib/common_setting/const.py b/cmdb-api/api/lib/common_setting/const.py index c9edccd..2768f56 100644 --- a/cmdb-api/api/lib/common_setting/const.py +++ b/cmdb-api/api/lib/common_setting/const.py @@ -4,11 +4,11 @@ COMMON_SETTING_QUEUE = "common_setting_async" class OperatorType(BaseEnum): - EQUAL = 1 # 等于 - NOT_EQUAL = 2 # 不等于 - IN = 3 # 包含 - NOT_IN = 4 # 不包含 - GREATER_THAN = 5 # 大于 - LESS_THAN = 6 # 小于 - IS_EMPTY = 7 # 为空 - IS_NOT_EMPTY = 8 # 不为空 + EQUAL = 1 + NOT_EQUAL = 2 + IN = 3 + NOT_IN = 4 + GREATER_THAN = 5 + LESS_THAN = 6 + IS_EMPTY = 7 + IS_NOT_EMPTY = 8 diff --git a/cmdb-api/api/lib/common_setting/department.py b/cmdb-api/api/lib/common_setting/department.py index ce149b9..e810b06 100644 --- a/cmdb-api/api/lib/common_setting/department.py +++ b/cmdb-api/api/lib/common_setting/department.py @@ -7,6 +7,7 @@ from wtforms import IntegerField from wtforms import StringField from wtforms import validators +from api.extensions import db from api.lib.common_setting.resp_format import ErrFormat from api.lib.perm.acl.role import RoleCRUD from api.models.common_setting import Department, Employee @@ -94,11 +95,9 @@ class DepartmentTree(object): for top_d in top_departments: department_id = top_d['department_id'] - # 检查 department_id 是否作为其他部门的 parent sub_deps = self.get_department_by_parent_id(department_id) employees = [] if self.append_employee: - # 要包含员工 employees = self.get_employees_by_d_id(department_id) top_d['employees'] = employees @@ -127,7 +126,6 @@ class DepartmentTree(object): sub_deps = self.get_department_by_parent_id(d['department_id']) employees = [] if self.append_employee: - # 要包含员工 employees = self.get_employees_by_d_id(d['department_id']) d['employees'] = employees @@ -184,7 +182,6 @@ class DepartmentCRUD(object): def check_department_parent_id_allow(d_id, department_parent_id): if department_parent_id == 0: return - # 检查 department_parent_id 是否在许可范围内 allow_p_d_id_list = DepartmentCRUD.get_allow_parent_d_id_by(d_id) target = list( filter(lambda d: d['department_id'] == department_parent_id, allow_p_d_id_list)) @@ -263,9 +260,6 @@ class DepartmentCRUD(object): @staticmethod def get_allow_parent_d_id_by(department_id): - """ - 获取可以成为 department_id 的 department_parent_id 的 list - """ tree_list = DepartmentCRUD.get_department_tree_list() allow_d_id_list = [] @@ -307,7 +301,6 @@ class DepartmentCRUD(object): if len(all_deps) == 0: return [] - # 一级部门 top_deps = list(filter(lambda d: d['department_parent_id'] == -1, all_deps)) if len(top_deps) == 0: return [] @@ -321,7 +314,6 @@ class DepartmentCRUD(object): top_d['department_name'], identifier_root ) - # 检查 department_id 是否作为其他部门的 parent sub_ds = list(filter(lambda d: d['department_parent_id'] == identifier_root, all_deps)) if len(sub_ds) == 0: tree_list.append(tree) @@ -350,6 +342,13 @@ class DepartmentCRUD(object): DepartmentCRUD.parse_sub_department_node( next_sub_ds, all_ds, tree, d['department_id']) + @staticmethod + def get_department_by_query(query, to_dict=True): + results = query.all() + if not results: + return [] + return results if not to_dict else [r.to_dict() for r in results] + @staticmethod def get_departments_and_ids(department_parent_id, block): query = Department.query.filter( diff --git a/cmdb-api/api/lib/common_setting/employee.py b/cmdb-api/api/lib/common_setting/employee.py index a59cc5a..6cf27f8 100644 --- a/cmdb-api/api/lib/common_setting/employee.py +++ b/cmdb-api/api/lib/common_setting/employee.py @@ -18,6 +18,18 @@ from api.lib.common_setting.const import COMMON_SETTING_QUEUE, OperatorType from api.lib.common_setting.resp_format import ErrFormat from api.models.common_setting import Employee, Department +acl_user_columns = [ + 'email', + 'mobile', + 'nickname', + 'username', + 'password', + 'block', + 'avatar', +] +employee_pop_columns = ['password'] +can_not_edit_columns = ['email'] + def edit_acl_user(uid, **kwargs): user_data = {column: kwargs.get( @@ -68,9 +80,6 @@ class EmployeeCRUD(object): @staticmethod def get_employee_by_uid_with_create(_uid): - """ - 根据 uid 获取员工信息,不存在则创建 - """ try: return EmployeeCRUD.get_employee_by_uid(_uid).to_dict() except Exception as e: @@ -100,7 +109,6 @@ class EmployeeCRUD(object): acl_uid=user_info['uid'], ) return existed.to_dict() - # 创建员工 if not user_info.get('nickname', None): user_info['nickname'] = user_info['name'] @@ -143,9 +151,6 @@ class EmployeeCRUD(object): if len(e_list) > 0: from api.tasks.common_setting import edit_employee_department_in_acl - # fixme: comment next line - # edit_employee_department_in_acl(e_list, new_department_id, current_user.uid) - edit_employee_department_in_acl.apply_async( args=(e_list, new_department_id, current_user.uid), queue=COMMON_SETTING_QUEUE @@ -218,8 +223,6 @@ class EmployeeCRUD(object): else: employees = Employee.get_by(to_dict=False) - keep_cols = EmployeeCRUD.get_current_user_view_columns() - all_departments = Department.get_by(to_dict=False) d_id_map = {d.department_id: d.department_name for d in all_departments} e_id_map = {e.employee_id: e.nickname for e in employees} @@ -249,8 +252,7 @@ class EmployeeCRUD(object): data['department_name'] = department_name data['nickname_direct_supervisor'] = nickname_direct_supervisor - tmp = {export_columns_map[k]: data[k] for k in export_columns_map.keys() if - k in keep_cols or k in sub_columns} + tmp = {export_columns_map[k]: data[k] for k in export_columns_map.keys()} data_list.append(tmp) @@ -355,7 +357,6 @@ class EmployeeCRUD(object): existed = EmployeeCRUD.get_employee_by_id(_id) value = get_block_value(kwargs.get('block')) if value is True: - # 判断该用户是否为 部门负责人,或者员工的直接上级 check_department_director_id_or_direct_supervisor_id(_id) if is_acl: @@ -449,7 +450,7 @@ class EmployeeCRUD(object): @staticmethod def get_expr_by_condition(column, operator, value, relation): """ - 根据conditions返回expr: (and_list, or_list) + get expr: (and_list, or_list) """ attr = EmployeeCRUD.get_attr_by_column(column) # 根据operator生成条件表达式 @@ -483,7 +484,6 @@ class EmployeeCRUD(object): else: abort(400, ErrFormat.not_support_operator.format(operator)) - # 根据relation生成复合条件 if relation == "&": return expr, [] elif relation == "|": @@ -493,7 +493,6 @@ class EmployeeCRUD(object): @staticmethod def check_condition(column, operator, value, relation): - # 对于condition中column为空的,报错 if column is None or operator is None or relation is None: return abort(400, ErrFormat.conditions_field_missing) @@ -642,19 +641,6 @@ def get_user_map(key='uid', acl=None): return data -acl_user_columns = [ - 'email', - 'mobile', - 'nickname', - 'username', - 'password', - 'block', - 'avatar', -] -employee_pop_columns = ['password'] -can_not_edit_columns = ['email'] - - def format_params(params): for k in ['_key', '_secret']: params.pop(k, None) @@ -664,19 +650,22 @@ def format_params(params): class CreateEmployee(object): def __init__(self): self.acl = ACLManager() - self.useremail_map = {} + self.all_acl_users = self.acl.get_all_users() - def check_acl_user(self, email): - user_info = self.useremail_map.get(email, None) - if user_info: - return user_info - return None + def check_acl_user(self, user_data): + target_email = list(filter(lambda x: x['email'] == user_data['email'], self.all_acl_users)) + if target_email: + return target_email[0] + + target_username = list(filter(lambda x: x['username'] == user_data['username'], self.all_acl_users)) + if target_username: + return target_username[0] def add_acl_user(self, **kwargs): user_data = {column: kwargs.get( column, '') for column in acl_user_columns if kwargs.get(column, '')} try: - existed = self.check_acl_user(user_data['email']) + existed = self.check_acl_user(user_data) if not existed: return self.acl.create_user(user_data) return existed @@ -685,8 +674,6 @@ class CreateEmployee(object): def create_single(self, **kwargs): EmployeeCRUD.check_email_unique(kwargs['email']) - self.useremail_map = self.useremail_map if self.useremail_map else get_user_map( - 'email', self.acl) user = self.add_acl_user(**kwargs) kwargs['acl_uid'] = user['uid'] kwargs['last_login'] = user['last_login'] @@ -699,8 +686,6 @@ class CreateEmployee(object): ) def create_single_with_import(self, **kwargs): - self.useremail_map = self.useremail_map if self.useremail_map else get_user_map( - 'email', self.acl) user = self.add_acl_user(**kwargs) kwargs['acl_uid'] = user['uid'] kwargs['last_login'] = user['last_login'] @@ -743,9 +728,6 @@ class CreateEmployee(object): return end_d_id def format_department_id(self, employee): - """ - 部门名称转化为ID,不存在则创建 - """ department_name_map = {} try: department_name = employee.get('department_name', '') @@ -762,16 +744,13 @@ class CreateEmployee(object): def batch_create(self, employee_list): err_list = [] - self.useremail_map = get_user_map('email', self.acl) for employee in employee_list: try: - # 获取username username = employee.get('username', None) if username is None: employee['username'] = employee['email'] - # 校验通过后获取department_id employee = self.format_department_id(employee) err = employee.get('err', None) if err: @@ -783,7 +762,7 @@ class CreateEmployee(object): raise Exception( ','.join(['{}: {}'.format(filed, ','.join(msg)) for filed, msg in form.errors.items()])) - data = self.create_single_with_import(**form.data) + self.create_single_with_import(**form.data) except Exception as e: err_list.append({ 'email': employee.get('email', ''), @@ -797,12 +776,12 @@ class CreateEmployee(object): class EmployeeAddForm(Form): username = StringField(validators=[ - validators.DataRequired(message="username不能为空"), + validators.DataRequired(message=ErrFormat.username_is_required), validators.Length(max=255), ]) email = StringField(validators=[ - validators.DataRequired(message="邮箱不能为空"), - validators.Email(message="邮箱格式不正确"), + validators.DataRequired(message=ErrFormat.email_is_required), + validators.Email(message=ErrFormat.email_format_error), validators.Length(max=255), ]) password = StringField(validators=[ @@ -811,7 +790,7 @@ class EmployeeAddForm(Form): position_name = StringField(validators=[]) nickname = StringField(validators=[ - validators.DataRequired(message="用户名不能为空"), + validators.DataRequired(message=ErrFormat.nickname_is_required), validators.Length(max=255), ]) sex = StringField(validators=[]) @@ -822,7 +801,7 @@ class EmployeeAddForm(Form): class EmployeeUpdateByUidForm(Form): nickname = StringField(validators=[ - validators.DataRequired(message="用户名不能为空"), + validators.DataRequired(message=ErrFormat.nickname_is_required), validators.Length(max=255), ]) avatar = StringField(validators=[]) diff --git a/cmdb-api/api/lib/common_setting/resp_format.py b/cmdb-api/api/lib/common_setting/resp_format.py index 88f5284..1d3b8d9 100644 --- a/cmdb-api/api/lib/common_setting/resp_format.py +++ b/cmdb-api/api/lib/common_setting/resp_format.py @@ -49,3 +49,8 @@ class ErrFormat(CommonErrFormat): acl_add_user_to_role_failed = "ACL 添加用户到角色失败: {}" acl_import_user_failed = "ACL 导入用户[{}]失败: {}" + nickname_is_required = "用户名不能为空" + username_is_required = "username不能为空" + email_is_required = "邮箱不能为空" + email_format_error = "邮箱格式错误" + diff --git a/cmdb-api/api/models/common_setting.py b/cmdb-api/api/models/common_setting.py index 741f664..2bcc4f6 100644 --- a/cmdb-api/api/models/common_setting.py +++ b/cmdb-api/api/models/common_setting.py @@ -13,40 +13,39 @@ class Department(ModelWithoutPK): __tablename__ = 'common_department' department_id = db.Column(db.Integer, primary_key=True, autoincrement=True) - department_name = db.Column(db.VARCHAR(255), default='', comment='部门名称') + department_name = db.Column(db.VARCHAR(255), default='') department_director_id = db.Column( - db.Integer, default=0, comment='部门负责人ID') - department_parent_id = db.Column(db.Integer, default=1, comment='上级部门ID') + db.Integer, default=0) + department_parent_id = db.Column(db.Integer, default=1) - sort_value = db.Column(db.Integer, default=0, comment='排序值') + sort_value = db.Column(db.Integer, default=0) - acl_rid = db.Column(db.Integer, comment='ACL中rid', default=0) + acl_rid = db.Column(db.Integer, default=0) class Employee(ModelWithoutPK): __tablename__ = 'common_employee' employee_id = db.Column(db.Integer, primary_key=True, autoincrement=True) - email = db.Column(db.VARCHAR(255), default='', comment='邮箱') - username = db.Column(db.VARCHAR(255), default='', comment='用户名') - nickname = db.Column(db.VARCHAR(255), default='', comment='姓名') - sex = db.Column(db.VARCHAR(64), default='', comment='性别') - position_name = db.Column(db.VARCHAR(255), default='', comment='职位名称') - mobile = db.Column(db.VARCHAR(255), default='', comment='电话号码') - avatar = db.Column(db.VARCHAR(255), default='', comment='头像') + email = db.Column(db.VARCHAR(255), default='') + username = db.Column(db.VARCHAR(255), default='') + nickname = db.Column(db.VARCHAR(255), default='') + sex = db.Column(db.VARCHAR(64), default='') + position_name = db.Column(db.VARCHAR(255), default='') + mobile = db.Column(db.VARCHAR(255), default='') + avatar = db.Column(db.VARCHAR(255), default='') - direct_supervisor_id = db.Column(db.Integer, default=0, comment='直接上级ID') + direct_supervisor_id = db.Column(db.Integer, default=0) department_id = db.Column(db.Integer, - db.ForeignKey('common_department.department_id'), - comment='部门ID', + db.ForeignKey('common_department.department_id') ) - acl_uid = db.Column(db.Integer, comment='ACL中uid', default=0) - acl_rid = db.Column(db.Integer, comment='ACL中rid', default=0) - acl_virtual_rid = db.Column(db.Integer, comment='ACL中虚拟角色rid', default=0) - last_login = db.Column(db.TIMESTAMP, nullable=True, comment='上次登录时间') - block = db.Column(db.Integer, comment='锁定状态', default=0) + acl_uid = db.Column(db.Integer, default=0) + acl_rid = db.Column(db.Integer, default=0) + acl_virtual_rid = db.Column(db.Integer, default=0) + last_login = db.Column(db.TIMESTAMP, nullable=True) + block = db.Column(db.Integer, default=0) _department = db.relationship( 'Department', backref='common_employee.department_id', @@ -55,14 +54,11 @@ class Employee(ModelWithoutPK): class EmployeeInfo(Model): - """ - 员工信息 - """ __tablename__ = 'common_employee_info' - info = db.Column(db.JSON, default={}, comment='员工信息') + info = db.Column(db.JSON, default={}) employee_id = db.Column(db.Integer, db.ForeignKey( - 'common_employee.employee_id'), comment='员工ID') + 'common_employee.employee_id')) employee = db.relationship( 'Employee', backref='common_employee.employee_id', lazy='joined') @@ -74,16 +70,13 @@ class CompanyInfo(Model): class InternalMessage(Model): - """ - 内部消息 - """ __tablename__ = "common_internal_message" - title = db.Column(db.VARCHAR(255), nullable=True, comment='标题') - content = db.Column(db.TEXT, nullable=True, comment='内容') - path = db.Column(db.VARCHAR(255), nullable=True, comment='跳转路径') - is_read = db.Column(db.Boolean, default=False, comment='是否已读') - app_name = db.Column(db.VARCHAR(128), nullable=False, comment='应用名称') - category = db.Column(db.VARCHAR(128), nullable=False, comment='分类') - message_data = db.Column(db.JSON, nullable=True, comment='数据') + title = db.Column(db.VARCHAR(255), nullable=True) + content = db.Column(db.TEXT, nullable=True) + path = db.Column(db.VARCHAR(255), nullable=True) + is_read = db.Column(db.Boolean, default=False) + app_name = db.Column(db.VARCHAR(128), nullable=False) + category = db.Column(db.VARCHAR(128), nullable=False) + message_data = db.Column(db.JSON, nullable=True) employee_id = db.Column(db.Integer, db.ForeignKey('common_employee.employee_id'), comment='ID') diff --git a/cmdb-api/api/tasks/common_setting.py b/cmdb-api/api/tasks/common_setting.py index 4594218..ca0f669 100644 --- a/cmdb-api/api/tasks/common_setting.py +++ b/cmdb-api/api/tasks/common_setting.py @@ -13,13 +13,9 @@ from api.models.common_setting import Department @celery.task(name="common_setting.edit_employee_department_in_acl", queue=COMMON_SETTING_QUEUE) def edit_employee_department_in_acl(e_list, new_d_id, op_uid): """ - 在 ACL 员工更换部门 - :param e_list: 员工列表 {acl_rid: 11, department_id: 22} - :param new_d_id: 新部门 ID - :param op_uid: 操作人 ID - - 在老部门中删除员工 - 在新部门中添加员工 + :param e_list:{acl_rid: 11, department_id: 22} + :param new_d_id + :param op_uid """ db.session.remove() @@ -43,7 +39,6 @@ def edit_employee_department_in_acl(e_list, new_d_id, op_uid): new_department_acl_rid = new_department.acl_rid if new_d_rid_in_acl == new_department.acl_rid else new_d_rid_in_acl for employee in e_list: - # 根据 部门ID获取部门 acl_rid old_department = Department.get_by( first=True, department_id=employee.get('department_id'), to_dict=False) if not old_department: @@ -61,7 +56,6 @@ def edit_employee_department_in_acl(e_list, new_d_id, op_uid): acl_rid=old_d_rid_in_acl ) d_acl_rid = old_department.acl_rid if old_d_rid_in_acl == old_department.acl_rid else old_d_rid_in_acl - # 在老部门中删除员工 payload = { 'app_id': 'acl', 'parent_id': d_acl_rid, @@ -71,7 +65,6 @@ def edit_employee_department_in_acl(e_list, new_d_id, op_uid): except Exception as e: result.append(ErrFormat.acl_remove_user_from_role_failed.format(str(e))) - # 在新部门中添加员工 payload = { 'app_id': 'acl', 'child_ids': [employee_acl_rid], diff --git a/cmdb-api/api/views/common_setting/department.py b/cmdb-api/api/views/common_setting/department.py index f9d9c7b..9a8dd4a 100644 --- a/cmdb-api/api/views/common_setting/department.py +++ b/cmdb-api/api/views/common_setting/department.py @@ -100,7 +100,7 @@ class DepartmentSortView(APIView): def put(self): """ - 修改部门排序,只能在同一个上级内排序 + only can sort in the same parent """ department_list = request.json.get('department_list', None) if department_list is None: diff --git a/cmdb-api/api/views/common_setting/employee.py b/cmdb-api/api/views/common_setting/employee.py index 85aa0b0..804f54b 100644 --- a/cmdb-api/api/views/common_setting/employee.py +++ b/cmdb-api/api/views/common_setting/employee.py @@ -150,12 +150,10 @@ class EmployeeViewExportExcel(APIView): url_prefix = (f'{prefix}/export_all',) def get(self): - # 规定了静态文件的存储位置 excel_filename = 'all_employee_info.xlsx' excel_path = current_app.config['UPLOAD_DIRECTORY_FULL'] excel_path_with_filename = os.path.join(excel_path, excel_filename) - # 根据parameter查表,自连接通过上级id获取上级名字列 block_status = int(request.args.get('block_status', -1)) data_list = EmployeeCRUD.get_export_employee_list(block_status) From 28dea81036f54752212c678e4cce919acd7ac4ab Mon Sep 17 00:00:00 2001 From: "hu.sima" Date: Thu, 10 Aug 2023 16:29:52 +0800 Subject: [PATCH 5/6] fix: remove unused column --- cmdb-api/api/lib/common_setting/department.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cmdb-api/api/lib/common_setting/department.py b/cmdb-api/api/lib/common_setting/department.py index e810b06..8da3c58 100644 --- a/cmdb-api/api/lib/common_setting/department.py +++ b/cmdb-api/api/lib/common_setting/department.py @@ -45,7 +45,6 @@ def get_all_employee_list(block=0, to_dict=True): 'email', 'mobile', 'direct_supervisor_id', - 'annual_leave', 'block', 'department_id', ] From 4cecdb10fbe51a128939dfa1812daf7931ebd5ac Mon Sep 17 00:00:00 2001 From: "hu.sima" Date: Thu, 10 Aug 2023 18:55:32 +0800 Subject: [PATCH 6/6] fix: remove useless --- cmdb-api/api/lib/common_setting/employee.py | 153 ------------------ cmdb-api/api/views/common_setting/employee.py | 26 --- 2 files changed, 179 deletions(-) diff --git a/cmdb-api/api/lib/common_setting/employee.py b/cmdb-api/api/lib/common_setting/employee.py index 6cf27f8..1f9e3a8 100644 --- a/cmdb-api/api/lib/common_setting/employee.py +++ b/cmdb-api/api/lib/common_setting/employee.py @@ -212,159 +212,6 @@ class EmployeeCRUD(object): *criterion ).count() - @staticmethod - def import_employee(employee_list): - return CreateEmployee().batch_create(employee_list) - - @staticmethod - def get_export_employee_list(block_status): - if block_status >= 0: - employees = Employee.get_by(block=block_status, to_dict=False) - else: - employees = Employee.get_by(to_dict=False) - - all_departments = Department.get_by(to_dict=False) - d_id_map = {d.department_id: d.department_name for d in all_departments} - e_id_map = {e.employee_id: e.nickname for e in employees} - - export_columns_map = { - 'username': "用户名", - 'nickname': '姓名', - 'email': '邮箱', - 'department_name': '部门', - 'sex': '性别', - 'mobile': '手机号', - 'position_name': '岗位', - 'nickname_direct_supervisor': '直属上级', - 'last_login': '上次登录时间', - } - - data_list = [] - for e in employees: - department_name = d_id_map.get(e.department_id, '') - nickname_direct_supervisor = e_id_map.get(e.direct_supervisor_id, '') - try: - last_login = str(e.last_login) if e.last_login else '' - except: - last_login = '' - data = e.to_dict() - data['last_login'] = last_login - data['department_name'] = department_name - data['nickname_direct_supervisor'] = nickname_direct_supervisor - - tmp = {export_columns_map[k]: data[k] for k in export_columns_map.keys()} - - data_list.append(tmp) - - return data_list - - @staticmethod - def batch_employee(column_name, column_value, employee_id_list): - if not column_value: - abort(400, ErrFormat.value_is_required) - if column_name in ['password', 'block']: - return EmployeeCRUD.batch_edit_password_or_block_column(column_name, employee_id_list, column_value, True) - - elif column_name in ['department_id']: - return EmployeeCRUD.batch_edit_employee_department(employee_id_list, column_value) - - elif column_name in [ - 'direct_supervisor_id', 'position_name' - ]: - return EmployeeCRUD.batch_edit_column(column_name, employee_id_list, column_value, False) - - else: - abort(400, ErrFormat.column_name_not_support) - - @staticmethod - def batch_edit_employee_department(employee_id_list, column_value): - err_list = [] - employee_list = [] - for _id in employee_id_list: - try: - existed = EmployeeCRUD.get_employee_by_id(_id) - employee = dict( - e_acl_rid=existed.acl_rid, - department_id=existed.department_id - ) - employee_list.append(employee) - existed.update(department_id=column_value) - - except Exception as e: - err_list.append({ - 'employee_id': _id, - 'err': str(e), - }) - from api.tasks.common_setting import edit_employee_department_in_acl - edit_employee_department_in_acl.apply_async( - args=(employee_list, column_value, current_user.uid), - queue=COMMON_SETTING_QUEUE - ) - return err_list - - @staticmethod - def batch_edit_password_or_block_column(column_name, employee_id_list, column_value, is_acl=False): - if column_name == 'block': - err_list = [] - success_list = [] - for _id in employee_id_list: - try: - employee = EmployeeCRUD.edit_employee_block_column( - _id, is_acl, **{column_name: column_value}) - success_list.append(employee) - except Exception as e: - err_list.append({ - 'employee_id': _id, - 'err': str(e), - }) - return err_list - else: - return EmployeeCRUD.batch_edit_column(column_name, employee_id_list, column_value, is_acl) - - @staticmethod - def batch_edit_column(column_name, employee_id_list, column_value, is_acl=False): - err_list = [] - for _id in employee_id_list: - try: - EmployeeCRUD.edit_employee_single_column( - _id, is_acl, **{column_name: column_value}) - except Exception as e: - err_list.append({ - 'employee_id': _id, - 'err': str(e), - }) - - return err_list - - @staticmethod - def edit_employee_single_column(_id, is_acl=False, **kwargs): - existed = EmployeeCRUD.get_employee_by_id(_id) - - if is_acl: - return edit_acl_user(existed.acl_uid, **kwargs) - - try: - for column in employee_pop_columns: - if kwargs.get(column): - kwargs.pop(column) - - return existed.update(**kwargs) - except Exception as e: - return abort(400, str(e)) - - @staticmethod - def edit_employee_block_column(_id, is_acl=False, **kwargs): - existed = EmployeeCRUD.get_employee_by_id(_id) - value = get_block_value(kwargs.get('block')) - if value is True: - check_department_director_id_or_direct_supervisor_id(_id) - - if is_acl: - kwargs['block'] = value - edit_acl_user(existed.acl_uid, **kwargs) - data = existed.to_dict() - return data - @staticmethod def check_email_unique(email, _id=0): criterion = [ diff --git a/cmdb-api/api/views/common_setting/employee.py b/cmdb-api/api/views/common_setting/employee.py index 804f54b..56adf8b 100644 --- a/cmdb-api/api/views/common_setting/employee.py +++ b/cmdb-api/api/views/common_setting/employee.py @@ -145,29 +145,3 @@ class EmployeePositionView(APIView): result = EmployeeCRUD.get_all_position() return self.jsonify(result) - -class EmployeeViewExportExcel(APIView): - url_prefix = (f'{prefix}/export_all',) - - def get(self): - excel_filename = 'all_employee_info.xlsx' - excel_path = current_app.config['UPLOAD_DIRECTORY_FULL'] - excel_path_with_filename = os.path.join(excel_path, excel_filename) - - block_status = int(request.args.get('block_status', -1)) - data_list = EmployeeCRUD.get_export_employee_list(block_status) - - headers = data_list[0].keys() - from openpyxl import Workbook - - wb = Workbook() - ws = wb.active - # insert header - for col_num, col_data in enumerate(headers, start=1): - ws.cell(row=1, column=col_num, value=col_data) - - for row_num, row_data in enumerate(data_list, start=2): - for col_num, col_data in enumerate(row_data.values(), start=1): - ws.cell(row=row_num, column=col_num, value=col_data) - wb.save(excel_path_with_filename) - return send_from_directory(excel_path, excel_filename, as_attachment=True)