SDN实战

SDN小demo

关于项目

项目名称:基于Cisco NX-API REST实现对NXOS 9000v的远程管理系统

项目目标:编写一个程序实现对多台N9KV可视化配置与管理

实现方式:以python脚本为基础编写程序通过对NX-API REST的调用实现功能

环境介绍

python版本:python3.6.7

NXOS 9000v:思科的一个虚拟虚拟交换机与传统的思科交换机差不多,可以进行相关功能的配置但是转发数据的能力与实际设备相差甚远,一般用于测试与验证。[思科关于NXOS 9000v的文档]

环境搭建

1.安装Python3

  1. 首先去Python官网下载所需Python版本
  2. 在安装时建议选择在这里插入图片描述,会自动帮你配置环境变量。
  3. 安装好后再dos中输入python -V 进行验证是否安装成功。
  4. 需要用pip去安装requests包,即在dos中pip install requests,验证安装成功在dos中输入pip list 会显示requests相关信息即安装成功。(可能需要安装pip,可以去百度)

2.搭建NXOS 9000v(以下统称为N9KV)

有四种方式来实现对N9KV的搭建:

  • 使用Workstation完成单机搭建
  • 使用ESXi 6.0完成组网测试
  • 利用Dcloud/VIRL资源做练习
  • 使用EVE平台实现复杂场景搭建

以上四种方式各有利弊,本人使用了第一种方式来搭建N9KV,如想知道其他搭建方式的可联系本小白。

使用Workstation完成单机搭建N9KV

以下是环境搭建的关键步骤:

  1. 下载N9KV镜像。链接: https://pan.baidu.com/s/1yABOanA_WqNIyjRTw4CM4Q 提取码: xc1s

  2. 安装此虚拟机的标准配置是:8G memory(最小5G),4vCPU,4G hard disk,1 serial port,1 NIC

  3. 需要注意的地方,红色部分第一个网络适配器是给交换机的配置端口需要用桥接模式并于其他网络是配置进行区分,其他网络适配器需要与此区分;蓝色部分需要添加一个穿行端口在交换机第一次启动后使用管道的方式进行配置端口(mg 0)进行配置。

SDN实战_第1张图片

  1. 完成上述步骤后就可启动交换机,当加载完1268M数据后,使用putty软件通过管道的方式进行N9KV的初始化配置。

SDN实战_第2张图片

  1. 当putty中出现Abort Power On Auto Prvisioning时输入yes,后会出现possaword是否需要加密的信息(自己随意,本小白选择了no),即可进行密码的设置,后会出现是否dialog(no)。以上就完成了基本的配置。

  2. 即可登录,登陆后首先给管理口配置(mg 0)IP地址,即进入管理模式:int mg 0 后ip add 你的ip地址/子网掩码。因为不支持自动加载镜像,需要做如下操作:switch(config)# boot nxos bootflash:nxos.9.2.3.bin如不进行此步操作你的N9KV下一次将无法启动。配置完后切记保存switch(config)# copy running-config startup-config

  3. 这时在交换机开启的状态下你可以用putty用两种方式来进行配置与管理交换机**1.接着使用管道的方式2.**使用ssh的方式输入你刚刚个mg 0配置的ip地址进行管理与配置。(经本人实验如果需要使用ssh的方式,需先用管道的方式将交换机启动)

  4. 以上就是用Workstation搭建N9KV的关键过程。

使用北向接口配置与管理N9KV

有两种北向接口方式来配置N9KV:

  1. REST‐API CLI
  2. NX‐API REST

本小白使用方式2实现功能以下介绍的为方式2,如需方式1的相关材料可联系本小白,也可去思科官网完成学习与练习。

确定了方式我们就可进行脚本编写实现对N9KV的管理与配置。参考文档

以下是本小白的demo:

import tkinter as tk
import os
from tkinter import *
from tkinter import Entry
import createVlan
import tkinter.messagebox
import json
import selectSystemInfo
import selectVlanInfo
import selectMacAddress
import SaveFigure
import selectStpInfo
import configStp
ip = ''
user = ''
password = ''


def identityIp():
    window3 = tk.Tk()
    window3.title('验证登陆')
    window3.geometry('500x600')
    lab = tk.Label(text="验证登陆", font=('Arial', 14), master=window3)
    lab.place(x=200, y=100)
    lab1 = tk.Label(text="IP", font=('Arial', 14), master=window3)
    lab1.place(x=130, y=150)
    lab3 = tk.Label(text="用户名", font=('Arial', 14), master=window3)
    lab3.place(x=130, y=200)
    lab2 = tk.Label(text="密码", font=('Arial', 14), master=window3)
    lab2.place(x=130, y=250)
    ent = tk.Entry(window3, font=('Arial', 14))
    ent.place(x=200, y=150)
    ent2 = tk.Entry(window3, font=('Arial', 14))
    ent2.place(x=200, y=200)
    ent3 = tk.Entry(window3, font=('Arial', 14), show="*")
    ent3.place(x=200, y=250)

    def getIp():
        global ip
        global user
        global password
        ip = ent.get()
        user = ent2.get()
        password = ent3.get()
        show()
    but = tk.Button(text="确定登陆", font=('Arial', 14), master=window3, command=getIp)
    but.place(x=200, y=300)
    window3.mainloop()


def show():
    infoJson = selectSystemInfo.selectSystemInfo(ip, user, password)
    info = json.loads(json.dumps(infoJson))
    windows = tk.Tk()
    windows.title("Demo")
    windows.geometry('1000x600')

    lable1 = tk.Label(text="HOSTNAME:", font=('Arial', 13), master=windows)
    lable1.place(x=120, y=30)
    lable1_var = tk.Label(text=info["name"], font=('Arial', 13), master=windows)
    lable1_var.place(x=220, y=30)

    lable2 = tk.Label(text="SERIAL NUMBER:", font=('Arial', 13), master=windows)
    lable2.place(x=420, y=30)
    lable2_var = tk.Label(text=info["serial"], font=('Arial', 13), master=windows)
    lable2_var.place(x=565, y=30)

    lable3 = tk.Label(text="UPTIME:", font=('Arial', 13), master=windows)
    lable3.place(x=730, y=30)
    lable3_var = tk.Label(text=info["systemUpTime"], font=('Arial', 13), master=windows)
    lable3_var.place(x=800, y=30)
    link = tk.Label(text='__________________________________________________________________________________'
                         '__________________________________________________________________________________'
                         '________________________________', master=windows)
    link.place(x=10, y=60)

    # VLan
    Label_1 = tk.Label(text="VLAN:", font=('Arial', 20), master=windows)
    Label_1.place(x=150, y=200)
    ButtonVlanSelect = tk.Button(text="Select", font=('Arial', 15), command=vlanSelect, master=windows)
    ButtonVlanSelect.place(x=300, y=200)
    ButtonVlanConfig = tk.Button(text="Config", font=('Arial', 15), command=vlanConfig, master=windows)
    ButtonVlanConfig.place(x=450, y=200)

    # SP
    def stp():
        configStp.configStp(user, password, ip)
    Label_2 = tk.Label(text="Stp:", font=('Arial', 20), master=windows)
    Label_2.place(x=150, y=350)
    ButtonSpSelect = tk.Button(text="Select", font=('Arial', 15), command=spSelect, master=windows)
    ButtonSpSelect.place(x=300, y=350)
    ButtonSpConfig = tk.Button(text="Config", font=('Arial', 15), command=stp, master=windows)
    ButtonSpConfig.place(x=450, y=350)
    # Mac
    def selectMac():
        info = selectMacAddress.selectMacAddress(ip, user, password)
        tk.messagebox.showinfo(message=info)
    lable3 = tk.Label(text="Mac", font=('Arial', 20), master=windows)
    lable3.place(x=150, y=500)
    button3_1 = tk.Button(windows, font=('Arial', 15), text="查看Mac", command=selectMac)
    button3_1.place(x=300, y=500)

    # Save
    def save():
        SaveFigure.save(ip, user, password)
    Button_save = tk.Button(text="Save", font=('Arial', 20), master=windows, command=save)
    Button_save.place(x=800, y=530)
    windows.mainloop()


def vlanSelect():
    wind1 = tk.Tk()
    wind1.title("vlan select")
    wind1.geometry('1200x600')

    idE = tk.Entry(wind1, font=('Arial', 14))
    idE.place(x=200, y=100)


    def get():
        id = idE.get()
        info = selectVlanInfo.selectVlanInfo(id, user, password, ip)
        labInfo = tk.Label(text=info, font=('Arial', 14), master=wind1, width=70, height=6, wraplength=600, justify='left', anchor="nw")
        labInfo.place(x=500, y=150)
        labDn = tk.Label(text=info["dn"], font=('Arial', 14), master=wind1)
        labDn.place(x=500, y=300)
        LabVlan = tk.Label(text=info["clearTs"], font=('Arial', 14), master=wind1)
        LabVlan.place(x=500, y=400)
        LabInB = tk.Label(text=info["inBcastOctets"], font=('Arial', 14), master=wind1)
        LabInB.place(x=500, y=500)

    idButton = tk.Button(text="select", font=('Arial', 14), master=wind1, command=get)
    idButton.place(x=460, y=90)
    # vlan = selectVlanInfo.selectVlanInfo(id)
    Lab1 = tk.Label(text="Info:", font=('Arial', 15), master=wind1)
    Lab1.place(x=200, y=150)
    Lab2 = tk.Label(text="DN:", font=('Arial', 15), master=wind1)
    Lab2.place(x=200, y=300)
    Lab3 = tk.Label(text="VlanInfo:", font=('Arial', 15), master=wind1)
    Lab3.place(x=200, y=400)
    Lab4 = tk.Label(text="inBcastOctets", font=('Arial', 15), master=wind1)
    Lab4.place(x=200, y=500)


    wind1.mainloop()


def vlanConfig():
    wind2 = tk.Tk()
    wind2.title("vlan config")
    wind2.geometry('800x600')
    a = StringVar()
    a.set('ID<3967')
    ent = tk.Entry(wind2, font=('Arial', 15), textvariable=a)
    ent.place(x=50, y=123)

    def creat():
        id = ent.get()
        if int(id) > 3967:
            tkinter.messagebox.showinfo(message="请输入小于3967的数")
            return
        else:
            createVlan.createVlan(id, user, password, ip)

    button = tk.Button(text="创建Vlan", font=('Arial', 15), master=wind2, command=creat)
    button.place(x=300, y=123)

    wind2.mainloop()


def spSelect():
   try:
        msg = selectStpInfo.selectStpInfo(user, password, ip)
        tk.messagebox.showinfo(message=msg)
   except:
       tk.messagebox.showinfo(message="error")



def stpConfig():
    win4 = tk.Tk()
    win4.title("sp config")
    win4.geometry('800x600')
    def stp():
        configStp.configStp(user, password, ip)
    button = tk.Button(text="button", font=('Arial', 15), master=win4, command=stp)
    button.place(x=80, y=100)
    win4.mainloop()


if __name__ == '__main__':
    identityIp()

查询N9KV信息

import requests, urllib3

def selectSystemInfo(ip,user,password):
    # Disable Self-Signed Cert warning for demo
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    # Assign requests.Session instance to session variable
    session = requests.Session()

    # Define URL and PAYLOAD variables
    URL = "https://"+str(ip)+"/api/aaaLogin.json"
    PAYLOAD = {
              "aaaUser": {
                "attributes": {
                  "name": user,
                  "pwd": password
                   }
                }
              }

    # Obtain an authentication cookie
    session.post(URL,json=PAYLOAD,verify=False)

    # Define SYS_URL variable
    SYS_URL = "https://"+str(ip)+"/api/mo/sys.json"

    # Obtain system information by making session.get call
    # then convert it to JSON format then filter to system attributes
    sys_info = session.get(SYS_URL,verify=False).json()["imdata"][0]["topSystem"]["attributes"]

    # Print hostname, serial nmber, uptime and current state information
    # obtained from the NXOSv9k
    return sys_info


创建vlan

import requests, urllib3
import tkinter.messagebox

# Disable Self-Signed Cert warning for demo
def createVlan(vlan_id ,user, password, ip="192.168.1.30"):
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    # Assign requests.Session instance to session variable
    session = requests.Session()

    # Define URL and PAYLOAD variables
    URL = "https://"+str(ip)+"/api/aaaLogin.json"
    PAYLOAD = {
        "aaaUser": {
            "attributes": {
                "name": user,
                "pwd": password
            }
        }
    }

    # Obtain an authentication cookie
    session.post(URL, json=PAYLOAD, verify=False)

    # Define SYS_URL variable
    # 创建vlan2
    SYS_URL = "https://"+str(ip)+"/api/mo/sys/bd.json"
    PAYLOAD = {
        "bdEntity": {
            "children": [
                {
                    "l2BD": {
                        "attributes": {
                            "fabEncap": "vlan-"+str(vlan_id),
                            "pcTag": "1"
                        }}}]}}
    session.post(SYS_URL, json=PAYLOAD, verify=False)
    vlan_info = session.get(SYS_URL, verify=False).json
    a = str(200)
    if a in str(vlan_info):
        tkinter.messagebox.showinfo(title="State", message="创建成功")
    else:
        tkinter.messagebox.showinfo(title="State", message="创建失败")

查询vlan信息

import requests, urllib3
import json
# Disable Self-Signed Cert warning for demo


def selectVlanInfo(id, user, password, ip='192.168.1.30'):
	# Disable Self-Signed Cert warning for demo
	urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

	# Assign requests.Session instance to session variable
	session = requests.Session()
	# Define URL and PAYLOAD variables
	URL = "https://" + str(ip) + "/api/aaaLogin.json"
	PAYLOAD = {
		"aaaUser": {
			"attributes": {
				"name": user,
				"pwd": password
			}
		}
	}

	# Obtain an authentication cookie
	session.post(URL, json=PAYLOAD, verify=False)

	# Define SYS_URL variable
	# 查询vlan2信息
	SYS_URL = "https://" + str(ip) + "/api/node/mo/sys/bd/bd-[vlan-" + str(id) + "]/dbgVlanStats.json"

	# Obtain system information by making session.get call
	# then convert it to JSON format then filter to system attributes

	vlan_info = session.get(SYS_URL, verify=False).json()["imdata"][0]["l2VlanStats"]["attributes"]

	vlan_info_loads = json.loads(json.dumps(vlan_info))
	return vlan_info_loads

设置STP为RSTP

import requests, urllib3
import tkinter.messagebox
# Disable Self-Signed Cert warning for demo


def configStp(user, password, ip='192.168.1.30'):
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    # Assign requests.Session instance to session variable
    session = requests.Session()

    # Define URL and PAYLOAD variables
    URL = "https://"+str(ip)+"/api/aaaLogin.json"
    PAYLOAD = {
              "aaaUser": {
                "attributes": {
                  "name": user,
                  "pwd": password
                   }
                }
              }

    # Obtain an authentication cookie
    session.post(URL, json=PAYLOAD, verify=False)

    # Define SYS_URL variable
    # 创建vlan2
    SYS_URL = "https://"+str(ip)+"/api/mo/sys/stp/inst.json"
    PAYLOAD = {
                  "stpInst": {
                    "attributes": {
                      "mode": "pvrst"
                    }
                  }
                }
    session.post(SYS_URL, json=PAYLOAD, verify=False)
    stp_info = session.get(SYS_URL, verify=False).json
    a = str(200)
    if a in str(stp_info):
        tkinter.messagebox.showinfo(title="State", message="创建成功")
    else:
        tkinter.messagebox.showinfo(title="State", message="创建失败")

查询STP信息

import requests, urllib3
import json
# Disable Self-Signed Cert warning for demo
def selectStpInfo(user, password, ip='192.168.1.30'):
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    # Assign requests.Session instance to session variable
    session = requests.Session()

    # Define URL and PAYLOAD variables
    URL = "https://"+str(ip)+"/api/aaaLogin.json"
    PAYLOAD = {
              "aaaUser": {
                "attributes": {
                  "name": user,
                  "pwd": password
                   }
                }
              }

    # Obtain an authentication cookie
    session.post(URL,json=PAYLOAD,verify=False)

    # Define SYS_URL variable
    # 查询STP信息
    SYS_URL = "https://"+str(ip)+"/api/mo/sys/stp.json?rsp-subtree=full"

    # Obtain system information by making session.get call
    # then convert it to JSON format then filter to system attributes
    STP_info = session.get(SYS_URL, verify=False).json()


    info = json.loads(json.dumps(STP_info))
    protocol = info["imdata"][0]["stpEntity"]["children"][0]["stpInst"]["children"][15]["stpVlan"]["attributes"]["protocol"]
    msg = "Spanning tree enabled protocol "+protocol
    return msg

查看MAC地址表信息

import requests, urllib3
# Disable Self-Signed Cert warning for demo


def selectMacAddress(ip, user, password):
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    # Assign requests.Session instance to session variable
    session = requests.Session()

    # Define URL and PAYLOAD variables
    URL = "https://"+str(ip)+"/api/aaaLogin.json"
    PAYLOAD = {
              "aaaUser": {
                "attributes": {
                  "name": user,
                  "pwd": password
                   }
                }
              }

    # Obtain an authentication cookie
    session.post(URL, json=PAYLOAD, verify=False)

    # Define SYS_URL variable
    SYS_URL = "https://"+str(ip)+"/api/mo/sys/mac/table.json?rsp-subtree=full"

    # Obtain system information by making session.get call
    # then convert it to JSON format then filter to system attributes
    MACtable_info = session.get(SYS_URL, verify=False).json()

    # Print raw data

    return MACtable_info

保存配置

import requests, urllib3
import tkinter.messagebox


def save(ip, user, password):
    # Disable Self-Signed Cert warning for demo
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    # Assign requests.Session instance to session variable
    session = requests.Session()

    # Define URL and PAYLOAD variables
    URL = "https://"+str(ip)+"/api/aaaLogin.json"
    PAYLOAD = {
              "aaaUser": {
                "attributes": {
                  "name": user,
                  "pwd": password
                   }
                }
              }

    # Obtain an authentication cookie
    session.post(URL, json=PAYLOAD, verify=False)

    # Define SYS_URL variable
    SYS_URL = "https://"+str(ip)+"//api/mo/sys/action.json"
    PAYLOAD = {
        "actionLSubj": {
            "attributes": {
            "dn": "sys/action/lsubj-[sys]"
            },
            "children" : [{
                 "topSystemCopyRSLTask": {
                       "attributes": {
                         "adminSt": "start",
                         "dn": "sys/action/lsubj-[sys]/topSystemCopyRSLTask",
                         "freq": "one-shot"
                       }
                 }
                }]
        }
        }
    session.post(SYS_URL, json=PAYLOAD, verify=False)
    info = session.get(SYS_URL, verify=False).json
    a = str(200)
    if a in str(info):
        tkinter.messagebox.showinfo(title="State", message="保存成功")
    else:
        tkinter.messagebox.showinfo(title="State", message="保存失败")

你可能感兴趣的:(计算机网络)