#! /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))

如果您觉得对你有用,可以打赏一下哦
在这里插入图片描述

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐