#! /usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import datetime
from h3csnmp import easysnmp_conn
#这个模块是我自己写的获取华三SNMP信息的,可以自己写,主要用于获取设备的名称。
import logging
from pypinyin import lazy_pinyin
import json
import pandas as pd
import IPy
import subprocess
config_file = "/opt/app/scripts/jumpserver_token.config"
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='/var/log/netopslog/jumpserver.log',
filemode='a')
class JumpServer():
def __init__(self):
self.node_list = self.get_node_list()
def get_token(self):
#主要用户获取jumpserver的token值
url = 'http://10.0.6.XX/api/v1/authentication/auth/'
query_args = {
"username": "admin",
"password": "XXXXXXX"
}
response = requests.post(url, data=query_args)
return json.loads(response.text)['token']
def header_info(self):
#用户构建header头信息
token = self.get_token()
header_info = {"Authorization": 'Bearer ' + token}
return header_info
def get_node_list(self):
#用于获取jumpserver的节点信息,就是资产所属于的节点
req = requests.get('http://10.0.6.XXX/api/v1/assets/nodes/' , headers=self.header_info())
node_list_json = json.loads(req.content.decode())
node_list_df = pd.DataFrame.from_records(
node_list_json, columns=["id", "name", "full_value", "key"])
node_list_df["full_value"] = node_list_df["full_value"].str.replace(
" ", "")
return node_list_df
def IsExist(self, ip):
#用于判断资产是否已经存在于jumpserver中了,我这里判断的依据是根据IP来的,jumpserver中有很多参数可以选择,设备名称也可以。
exist = False
asset =self.get_asset()
for item in asset:
if ip == item['ip']:
exist = True
return exist
def get_asset(self):
#用于获取节点中已经存在的资产
req = requests.get('http://10.0.6.XXXX/api/v1/assets/assets/', headers=self.header_info())
asset_list_json = json.loads(req.content.decode())
return asset_list_json
def create_asset(self, fullpath, ip, prefix=""):
#用于创建资产,fullpath是你资产的节点位置,ip就是要添加的设备的IP地址,prefix是添加设备的名称
node_id = self.get_nodeid_by_fullpath(fullpath)
#获取节点名称的id值
if not node_id:
logging.error("没有找到对应节点 %s" % fullpath)
print("没有找到对应节点 %s" % fullpath)
exit(10)
#目前的功能是基于已经创建的节点添加资产的,没有做未创建节点自动添加节点的,此功能也可以自己写哦
data = {
"ip": ip,
"hostname": prefix,
"platform": "Other",
"admin_user": "28f0c429-4cb8-4490-8b82-3b531d18fcdb",
"nodes": node_id,
"is_active": True
}
#data中,主要是admin_user的获取,正常情况下,从jumpserver中你创建好设备的管理用户后,将其值写入到这就可以,当然也可以动态创建
req = requests.post('http://10.0.6.XXXXX/api/v1/assets/assets/' , headers=self.header_info(), data=data)
if req.status_code == 201:
#如果判断然后状态码是201的话,这个就是正常的,资产已经正常添加进去了
logging.info("%s add into %s SUCCESSED" % (ip, fullpath))
print("%s add into %s SUCCESSED" % (ip, fullpath))
else:
#否则就进行报错
logging.error("%s add into %s FALIED" % (ip, fullpath))
print("%s add into %s FALIED" % (ip, fullpath))
def get_nodeid_by_fullpath(self, fullpath=None):
#这个是获取节点的node_id的,即通过节点的路径,获取的node_id
node_id = self.node_list["full_value"] == fullpath
if node_id.any():
return self.node_list[node_id]["id"].str.cat()
else:
return None
def ping(host):
#这个函数是用来进行探测哪些地址可达的,如果可达之后,我们登录设备获取设备名称和IP地址
ip_reachable_dict = {}
#定义可达ip地址的空字典,key是设备的名称,value是设备的IP地址
ip_alive_list=[]
#定义可达IP地址的列表
cmd = 'fping %s' % host
#通过fping进行批量ping IP地址,需要注意的是,host是一个把所有IP地址通过空格连接起来的字符串
output = subprocess.getoutput(cmd).splitlines()
'''
输出格式为:
1.1.1.1 alive
2.2.2.2 unreachable
'''
for line in output:
对所有的输出进行判断,将可达的IP地址加入到可达IP地址列表
line = line.split()
if line[-1] == 'alive':
ip_alive_list.append(line[0])
for ip in ip_alive_list:
try:
snmpconn = easysnmp_conn(ip, 'password', 2)
#对IP地址进行snmp连接测试,并获取设备的sysname
dev_name = snmpconn.dev_name()
if ip_reachable_dict.get(dev_name):
#有的设备可能存在多个IP地址,我们默认就用最小的一个就行了,当然此处不进行判断也可以,只不过是覆盖而已
pass
else:
ip_reachable_dict[dev_name[2]]=ip
except Exception as e:
logging.error("%s,SNMP can't reachable"%ip)
#return "err","err"
return ip_reachable_dict
#将此设备名称和IP的字典作为返回值
if __name__ == "__main__":
Jumpserver = JumpServer()
#实例化
ip_input = input("请输入管理网段,多个网段用空格隔开 (eg:192.168.1.0/24):").split()
#输入要批量加入设备的IP网段,用空格区分开,此处没有进行格式错误的判断,老铁们可以自己做一下
ip_list = []
for line in ip_input:
#这个是将输入的IP网段中的所有IP地址全部加入到列表
ip = IPy.IP(line)
for j in ip:
ip_list.append(str(j))
ip=''
for i in ip_list:
#将所有的列表变为通过空格互联的字符串
ip =ip+' '+i
ip_reachable_dict=ping(ip)
#获取可达设备的IP和设备名称
print(ip_reachable_dict)
for dev_name,ip in ip_reachable_dict.items():
#根据指定的条件,把设备添加到对应的节点
if 'MGT' in dev_name:
fullpath = "/Default/01-网络/01-管理"
elif 'Core' in dev_name:
fullpath = "/Default/01-网络/02-核心"
elif 'FW' in dev_name:
fullpath = "/Default/04-网络/03-安全"
else:
fullpath="err"
if Jumpserver.IsExist(ip):
#对IP地址进行判断,如果IP存在,则不需要进行设备添加到Jumpserver
print('%s is exist'%ip)
logging.info('%s is exist'%ip)
pass
else:
if fullpath=='err':
#当设备名称没有上述的条件,进行报错
logging.error('%s(%s),wrong fullpath!'%(dev_name,ip))
pass
else:
#正常下,你的设备就添加到jumpserver啦
Jumpserver.create_asset(fullpath, ip, prefix=dev_name)
logging.info('%s(%s),has insert into %s !'%(dev_name,ip,fullpath))