From f392c0ca19c019a092c62ffb4fd6f1f2f1d2da5c Mon Sep 17 00:00:00 2001
From: rabbitali <shusheng.wen@outlook.com>
Date: Mon, 24 Apr 2023 15:35:07 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B7=BB=E5=8A=A0=E4=B8=BB?=
 =?UTF-8?q?=E6=9C=BA=E6=8E=A5=E5=8F=A3=E4=B8=BB=E6=9C=BA=E5=90=8D=E7=A7=B0?=
 =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E8=A7=84=E5=88=99;=E6=9B=B4=E6=96=B0?=
 =?UTF-8?q?=E6=B3=A8=E5=86=8C=E7=94=A8=E6=88=B7=E6=8E=A5=E5=8F=A3=E7=9A=84?=
 =?UTF-8?q?=E5=8F=82=E6=95=B0=E6=A0=A1=E9=AA=8C=E8=A7=84=E5=88=99,?=
 =?UTF-8?q?=E4=B8=8E=E5=89=8D=E7=AB=AF=E4=BF=9D=E6=8C=81=E4=B8=80=E8=87=B4?=
 =?UTF-8?q?;=E6=9B=B4=E6=96=B0=E6=89=B9=E9=87=8F=E6=B7=BB=E5=8A=A0?=
 =?UTF-8?q?=E4=B8=BB=E6=9C=BA=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 aops-zeus.spec                 |  2 +-
 setup.py                       |  3 ++-
 zeus/function/verify/acount.py |  5 +++--
 zeus/function/verify/host.py   |  4 +++-
 zeus/host_manager/view.py      | 38 ++++++++++++++++++++++++++--------
 5 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/aops-zeus.spec b/aops-zeus.spec
index ab83ead..2a6f94d 100644
--- a/aops-zeus.spec
+++ b/aops-zeus.spec
@@ -9,7 +9,7 @@ Source0:	%{name}-%{version}.tar.gz
 
 BuildRequires:  python3-setuptools
 Requires:   aops-vulcanus >= v1.2.0
-Requires:   python3-marshmallow >= 3.13.0 python3-flask python3-flask-restful
+Requires:   python3-marshmallow >= 3.13.0 python3-flask python3-flask-restful python3-gevent
 Requires:   python3-requests python3-uWSGI python3-sqlalchemy python3-werkzeug python3-PyMySQL
 Requires:   python3-paramiko >= 2.11.0 python3-redis python3-prometheus-api-client
 Provides:   aops-zeus
diff --git a/setup.py b/setup.py
index 46d4408..469ee11 100644
--- a/setup.py
+++ b/setup.py
@@ -19,7 +19,8 @@ setup(
         'Werkzeug',
         'paramiko>=2.11.0',
         "redis",
-        'prometheus_api_client'
+        'prometheus_api_client',
+        'gevent'
     ],
     author='cmd-lsw-yyy-zyc',
     data_files=[
diff --git a/zeus/function/verify/acount.py b/zeus/function/verify/acount.py
index b8bd67f..dfc3220 100644
--- a/zeus/function/verify/acount.py
+++ b/zeus/function/verify/acount.py
@@ -15,6 +15,7 @@ Time:
 Author:
 Description: For host related interfaces
 """
+from vulcanus.restful.serialize.validate import ValidateRules
 from marshmallow import Schema
 from marshmallow import fields
 
@@ -23,8 +24,8 @@ class LoginSchema(Schema):
     """
     validators for parameter of /manage/account/login
     """
-    username = fields.String(required=True, validate=lambda s: len(s) > 0)
-    password = fields.String(required=True, validate=lambda s: len(s) > 0)
+    username = fields.String(required=True, validate=ValidateRules.account_name_check)
+    password = fields.String(required=True, validate=ValidateRules.account_password_check)
 
 
 class AddUserSchema(LoginSchema):
diff --git a/zeus/function/verify/host.py b/zeus/function/verify/host.py
index f955975..4866947 100644
--- a/zeus/function/verify/host.py
+++ b/zeus/function/verify/host.py
@@ -15,6 +15,7 @@ Time:
 Author:
 Description: For host related interfaces
 """
+from vulcanus.restful.serialize.validate import ValidateRules
 from marshmallow import Schema
 from marshmallow import fields
 from marshmallow import validate
@@ -101,7 +102,8 @@ class AddHostSchema(Schema):
     """
     ssh_user = fields.String(required=True, validate=lambda s: len(s) > 0)
     password = fields.String(required=True, validate=lambda s: len(s) > 0)
-    host_name = fields.String(required=True, validate=lambda s: len(s) > 0)
+    host_name = fields.String(required=True,
+                              validate=[validate.Length(min=1, max=50), ValidateRules.space_character_check])
     host_ip = fields.IP(required=True)
     ssh_port = fields.Integer(required=True, validate=lambda s: 65535 >= s > 0)
     host_group_name = fields.String(required=True, validate=lambda s: len(s) > 0)
diff --git a/zeus/host_manager/view.py b/zeus/host_manager/view.py
index a5af075..8dd4c2b 100644
--- a/zeus/host_manager/view.py
+++ b/zeus/host_manager/view.py
@@ -16,10 +16,12 @@ Author:
 Description: Restful APIs for host
 """
 import json
-import socket
 from io import BytesIO
 from typing import Iterable, List, Tuple, Union
+from gevent import monkey; monkey.patch_all(ssl=False)
+import socket
 
+import gevent
 import paramiko
 from flask import request, send_file
 from marshmallow import Schema
@@ -523,14 +525,8 @@ class AddHostBatch(BaseResponse):
                                  message="invalid host info or all hosts has been added",
                                  data=self.add_result)
 
-        # Generate Rsa-key pair and save public_key on host
-        multi_thread = MultiThreadHandler(lambda data: self.update_rsa_key_to_host(*data),
-                                          valid_hosts, None)
-        multi_thread.create_thread()
-        result = multi_thread.get_result()
-
-        # Add host
-        status = proxy.add_host_batch(result)
+        # save public_key on host and add host to database
+        status = proxy.add_host_batch(self.save_key_to_client(valid_hosts))
         if status != state.SUCCEED:
             self.update_add_result(valid_hosts,
                                    {"result": self.add_failed, "reason": "Insert Database error"})
@@ -605,6 +601,30 @@ class AddHostBatch(BaseResponse):
             valid_host.append((host, password))
         return valid_host
 
+    def save_key_to_client(self, host_connect_infos: List[tuple]) -> list:
+        """
+        save key to client
+
+        Args:
+            host_connect_infos (list): client connect info
+
+        Returns:
+            host object list
+        """
+        # 30 connections are created at a time.
+        tasks = [host_connect_infos[index:index + 30] for index in range(0, len(host_connect_infos), 30)]
+        result = []
+
+        for task in tasks:
+            jobs = [gevent.spawn(self.update_rsa_key_to_host, *host_connect_info)
+                    for host_connect_info in task]
+
+            gevent.joinall(jobs)
+            for job in jobs:
+                result.append(job.value)
+
+        return result
+
     @staticmethod
     def update_rsa_key_to_host(host: Host, password: str) -> Host:
         """
-- 
Gitee

