diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py
index b8c1f768e..a5e578760 100644
--- a/apps/assets/models/asset.py
+++ b/apps/assets/models/asset.py
@@ -96,7 +96,7 @@ class Asset(models.Model):
         return False, warning
 
     def is_unixlike(self):
-        if self.platform not in ("Windows", "Other"):
+        if self.platform not in ("Windows",):
             return True
         else:
             return False
@@ -132,6 +132,15 @@ class Asset(models.Model):
             info["gateways"] = [d.id for d in self.domain.gateway_set.all()]
         return info
 
+    def get_auth_info(self):
+        if self.admin_user:
+            return {
+                'username': self.admin_user.username,
+                'password': self.admin_user.password,
+                'private_key': self.admin_user.private_key_file,
+                'become': self.admin_user.become_info,
+            }
+
     def _to_secret_json(self):
         """
         Ansible use it create inventory, First using asset user,
@@ -175,4 +184,3 @@ class Asset(models.Model):
             except IntegrityError:
                 print('Error continue')
                 continue
-
diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py
index c8224c8c8..e2f318f71 100644
--- a/apps/ops/ansible/inventory.py
+++ b/apps/ops/ansible/inventory.py
@@ -29,7 +29,6 @@ class BaseHost(Host):
             }
             "groups": [],
             "vars": {},
-            "other_ansbile_vars":
         }
         """
         self.host_data = host_data
@@ -79,7 +78,7 @@ class BaseInventory(InventoryManager):
     variable_manager_class = VariableManager
     host_manager_class = BaseHost
 
-    def __init__(self, host_list=None):
+    def __init__(self, host_list=None, group_list=None):
         """
         用于生成动态构建Ansible Inventory. super().__init__ 会自动调用
         host_list: [{
@@ -98,11 +97,14 @@ class BaseInventory(InventoryManager):
             "vars": {},
           },
         ]
+        group_list: [
+          {"name: "", children: [""]},
+        ]
         :param host_list:
+        :param group_list
         """
-        if host_list is None:
-            host_list = []
-        self.host_list = host_list
+        self.host_list = host_list or []
+        self.group_list = group_list or []
         assert isinstance(host_list, list)
         self.loader = self.loader_class()
         self.variable_manager = self.variable_manager_class()
@@ -114,24 +116,34 @@ class BaseInventory(InventoryManager):
     def get_group(self, name):
         return self._inventory.groups.get(name, None)
 
-    def parse_sources(self, cache=False):
-        group_all = self.get_group('all')
-        ungrouped = self.get_group('ungrouped')
+    def get_or_create_group(self, name):
+        group = self.get_group(name)
+        if not group:
+            self.add_group(name)
+            return self.get_or_create_group(name)
+        else:
+            return group
 
+    def parse_groups(self):
+        for g in self.group_list:
+            parent = self.get_or_create_group(g.get("name"))
+            children = [self.get_or_create_group(n) for n in g.get('children', [])]
+            for child in children:
+                parent.add_child_group(child)
+
+    def parse_hosts(self):
         for host_data in self.host_list:
             host = self.host_manager_class(host_data=host_data)
             self.hosts[host_data['hostname']] = host
             groups_data = host_data.get('groups')
             if groups_data:
                 for group_name in groups_data:
-                    group = self.get_group(group_name)
-                    if group is None:
-                        self.add_group(group_name)
-                        group = self.get_group(group_name)
+                    group = self.get_or_create_group(group_name)
                     group.add_host(host)
-            else:
-                ungrouped.add_host(host)
-            group_all.add_host(host)
+
+    def parse_sources(self, cache=False):
+        self.parse_groups()
+        self.parse_hosts()
 
     def get_matched_hosts(self, pattern):
         return self.get_hosts(pattern)
diff --git a/apps/ops/inventory.py b/apps/ops/inventory.py
index 6e3d6325c..6230e8167 100644
--- a/apps/ops/inventory.py
+++ b/apps/ops/inventory.py
@@ -9,29 +9,18 @@ __all__ = [
 ]
 
 
-def make_proxy_command(asset):
-    gateway = asset.domain.random_gateway()
-
-    proxy_command = [
-        "ssh", "-p", str(gateway.port),
-        "{}@{}".format(gateway.username, gateway.ip),
-        "-W", "%h:%p", "-q",
-    ]
-
-    if gateway.password:
-        proxy_command.insert(0, "sshpass -p {}".format(gateway.password))
-    if gateway.private_key:
-        proxy_command.append("-i {}".format(gateway.private_key_file))
-
-    return {"ansible_ssh_common_args": "'-o ProxyCommand={}'".format(" ".join(proxy_command))}
-
-
 class JMSInventory(BaseInventory):
     """
     JMS Inventory is the manager with jumpserver assets, so you can
     write you own manager, construct you inventory
     """
     def __init__(self, hostname_list, run_as_admin=False, run_as=None, become_info=None):
+        """
+        :param hostname_list: ["test1", ]
+        :param run_as_admin: True 是否使用管理用户去执行, 每台服务器的管理用户可能不同
+        :param run_as: 是否统一使用某个系统用户去执行
+        :param become_info: 是否become成某个用户去执行
+        """
         self.hostname_list = hostname_list
         self.using_admin = run_as_admin
         self.run_as = run_as
@@ -41,23 +30,14 @@ class JMSInventory(BaseInventory):
         host_list = []
 
         for asset in assets:
-            vars = {}
-            if run_as_admin:
-                info = asset._to_secret_json()
-            else:
-                info = asset.to_json()
-
-            info["vars"] = vars
-            if asset.domain and asset.domain.has_gateway():
-                vars.update(make_proxy_command(asset))
-                info.update(vars)
-
+            info = self.convert_to_ansible(asset, run_as_admin=run_as_admin)
             host_list.append(info)
 
         if run_as:
             run_user_info = self.get_run_user_info()
             for host in host_list:
                 host.update(run_user_info)
+
         if become_info:
             for host in host_list:
                 host.update(become_info)
@@ -67,9 +47,57 @@ class JMSInventory(BaseInventory):
         assets = get_assets_by_hostname_list(self.hostname_list)
         return assets
 
+    def convert_to_ansible(self, asset, run_as_admin=False):
+        info = {
+            'id': asset.id,
+            'hostname': asset.hostname,
+            'ip': asset.ip,
+            'port': asset.port,
+            'vars': dict(),
+            'groups': [],
+        }
+        if asset.domain and asset.domain.has_gateway():
+            info["vars"].update(self.make_proxy_command(asset))
+        if run_as_admin:
+            info.update(asset.get_auth_info())
+        for node in asset.nodes.all():
+            info["groups"].append(node.value)
+        for label in asset.labels.all():
+            info["vars"].update({
+                label.name: label.value
+            })
+            info["groups"].append("{}:{}".format(label.name, label.value))
+        if asset.domain:
+            info["vars"].update({
+                "domain": asset.domain.name,
+            })
+            info["groups"].append("domain_"+asset.domain.name)
+        return info
+
     def get_run_user_info(self):
         system_user = get_system_user_by_name(self.run_as)
         if not system_user:
             return {}
         else:
             return system_user._to_secret_json()
+
+    @staticmethod
+    def make_proxy_command(asset):
+        gateway = asset.domain.random_gateway()
+        proxy_command_list = [
+            "ssh", "-p", str(gateway.port),
+            "{}@{}".format(gateway.username, gateway.ip),
+            "-W", "%h:%p", "-q",
+        ]
+
+        if gateway.password:
+            proxy_command_list.insert(
+                0, "sshpass -p {}".format(gateway.password)
+            )
+        if gateway.private_key:
+            proxy_command_list.append("-i {}".format(gateway.private_key_file))
+
+        proxy_command = "'-o ProxyCommand={}'".format(
+            " ".join(proxy_command_list)
+        )
+        return {"ansible_ssh_common_args": proxy_command}