Commit d32f070b authored by ibuler's avatar ibuler

[Update] 修改Inverntoy,增加更多属性

parent c5af4d47
......@@ -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
......@@ -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)
......
......@@ -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}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment