1,网络编程与自动化介绍
背景:传统网络运维困境
网络自动化
基于编程实现的网络自动化
• 业界也有很多基于开源工具的网络自动化,例如Ansible、SaltStack、Puppet、Chef等。网
络工程师能力构建上更推荐具备代码编程能力。
2,编程语言概述与python介绍
编程语言
• 计算机语言另一种分类方式(根据语言层次)是机器语言、汇编语言和高级语言。机器语
言由0和1组成的指令构成,可以直接被机器识别。由于机器语言晦涩难懂,人们将0和1的
硬件指令做了简单的封装,便于识别和记忆(例如MOV、ADD),这就是汇编语言。这两
种语言都属于低级语言,其他语言都属于高级语言,例如C、C++、Java、Python、Pascal、
Lisp、Prolog、FoxPro、Fortran等都是高级语言。高级语言编写的程序不能直接被计算机
识别,必须经过转换成机器语言才能被执行。
计算技术栈与程序执行过程
• 对于计算机的技术栈和程序执行的过程。左侧是计算的技术栈,我们可以看到硬件的最底
层,是物理材料、晶体管来实现门电路和寄存器,再组成CPU的微架构。CPU的指令集是硬
件和软件的接口,应用程序通过指令集中定义的指令驱动硬件完成计算。
• 应用程序通过一定的软件算法完成业务功能。程序通常使用如C/C++/Java/Go/Python等高
级语言开发。高级语言需要编译成汇编语言,再由汇编器按照CPU指令集转换成二进制的
机器码。
• 一个程序在磁盘上存在的形式,是一堆指令和数据所组成二进制机器码,也就是我们通常
说的二进制文件。
高级编程语言-编译型语言
• 编译型语言编译的时候直接编译成机器可以执行的格式(例如.exe .dll .ocx)。编译和执行
是分开的,不能跨平台执行,例如X86程序不能在ARM架构服务器上运行。
高级编程语言-解释型语言
• JVM:Java虚拟机。
• PVM:Python虚拟机。
什么是python?
• Python同时也是动态类型语言。动态类型语言是指在程序运行的过程中自动决定对象的类
型,不需要声明变量的类型。
python代码执行过程
• 对于Python而言,Python源码不需要编译成二进制代码,它可以直接从源代码运行程序。
当我们运行Python代码的时候,Python解释器首先将源代码转换为字节码,然后再由
Python虚拟机来执行这些字节码。
• Python虚拟机(Python VM)不是一个独立的程序,不需要独立安装。
初识python代码-交互式运行
初识python代码-脚本式运行
python编码规范
python编码规范-标识符命名
• Python最基本的数据类型有布尔型(True/False)、整数、浮点型、字符串型。Python里
的所有数据(布尔值、整数、浮点、字符串,甚至大型数据结构、函数以及程序)都是以
对象(object)的形式存在的。这使得Python语言有很强的统一性。
• 运行结果分别为10,20,Richard,2,SyntaxError(语法错误)。
• 本文不对Python语法做针对介绍,更多Python语法请参考HCIP课程。
python编码规范-代码缩进
indentation error
缩进错误
• if…else…是一个完整的代码块,拥有相同的缩进。
• print(a)调用参数a,并且和if…else…在一个代码块,需要有相同的缩进。
python编码规范-使用注释
python编码规范-源码文件结构
• 解释器声明的作用是指定运行本文件的编译器的路径(非默认路径安装编译器或有多个
Python编译器)。Windows操作系统上可以省略本例中第一行解释器声明。
• 编码格式声明的作用是指定本程序使用的编码类型,以指定的编码类型读取源代码。
Python 2 默认使用的是 ASCII 编码 (不支持中文),Python 3 默认支持 UTF-8 编码 ( 支持
中文)。
• 文档字符串的作用是对本程序功能的总体介绍。
• time为Python内置模块,作用是提供处理时间相关的函数。
python的函数与模块
python的类与方法
• 对于函数和方法的官方定义:
• 函数 Function: A series of statements which returns some value to a caller. It can also
be passed zero or more arguments which may be used in the execution of the body.
• 方法 Method: A function which is defined inside a class body. If called as an attribute
of an instance of that class, the method will get the instance object as its first
argument (which is usually called self).
• 更多类的学习,请参考https://docs.python.org/3/tutorial/classes.html。
telnetlib介绍
• Telnet定义了网络虚拟终端(NVT,Network Virtual Terminal)。它描述了数据和命令序
列在Internet上传输的标准表示方式,以屏蔽不同平台和操作系统的差异,例如不同平台上
换行的指令不一样。
• Telnet通信采用带内信令方式,即Telnet命令在数据流中传输。为了区分Telnet命令和普通
数据,Telnet采用转义序列。每个转义序列由两个字节构成,前一个字节是(0xFF)叫做IAC
(Interpret As Command)“解释为命令”,标识了后面一个字节是命令。EOF也是一种
Telnet命令,十进制编码是236。
• 套接字(socket)是一个抽象层,应用程序通常通过"套接字"向网络发出请求或者应答网络
请求。
• 更多可参考https://docs.python.org/3/library/telnetlib.html
3,案例
使用telnetlib登陆设备
• 本案例出于学习角度让工程师了解代码和设备之间telnet交互过程使用telnetlib。在真实的
工作场景中因为安全原因更为推荐设备开启SSH功能而关闭Telnet功能。对应的Python模块
可以选择paramiko或netmiko。更多进阶内容请参考HCIP-Datacom-Network
Automation Developer。
• 本案例手工Telnet登录操作以windows为例:首先输入登录命令,telnet 192.168.10.10。
因在前序步骤中设备配置Telnet使用密码登录,所以此处回显信息为“Password:”。此时
输入密码 Huawei@123 完成验证,成功登录。
• Python中encode()和decode()函数的作用是,以指定的方式编码格式编码字符串和解码字
符串。本例中,password.encode(‘ascii‘) 表示将字符串’Huawei@123’转为为ASCII。此处
编码格式遵守telnetlib模块官方要求。
• Python字符串增加b,b’ str‘ 表示这是字符串是 bytes 对象。本例中,b’Password:’表示将
字符串’Password:’转换为bytes类型字符串。此处编码格式遵守telnetlib模块官方要求。
• 更多Python对象描述,请参考
https://docs.python.org/3/reference/datamodel.html#objects-values-and-types。
运行结果对比
实验
拓扑图
配置思路
1. 完成设备Telnet预配置:配置Telnet密码,开启Telnet功能和允许Telnet登录。
2. 编写Python脚本:调用telnetlib登陆设备,然后查看配置。
配置步骤
步骤 1 完成交换机的Telnet预配置
# 创建Telnet登陆密码
[Huawei]user-interface vty 0 4
[Huawei-ui-vty0-4]authentication-mode password
[Huawei-ui-vty0-4]set authentication password simple dnpn.xyz
[Huawei-ui-vty0-4]protocol inbound telnet
[Huawei-ui-vty0-4]user privilege level 15
使用Python脚本Telnet登录设备前,需要首先在设备上创建Telnet密码和开启Telnet功能。配置Telnet登陆密码为dnpn.xyz
# 开启Telnet服务,允许Telnet用户登录。
[Huawei]telnet server enable
Info: The Telnet server has been enabled.
SW1配置如下:
#
sysname Huawei
#
cluster enable
ntdp enable
ndp enable
#
drop illegal-mac alarm
#
diffserv domain default
#
drop-profile default
#
aaa
authentication-scheme default
authorization-scheme default
accounting-scheme default
domain default
domain default_admin
local-user admin password simple admin
local-user admin service-type http
#
interface Vlanif1
ip address 192.168.56.101 255.255.255.0
#
interface MEth0/0/1
#
interface GigabitEthernet0/0/1
#
#
interface NULL0
#
user-interface con 0
user-interface vty 0 4
user privilege level 15
set authentication password simple dnpn.xyz
#
return
桥接电脑虚拟网卡
电脑CMD管理员运行
Microsoft Windows [版本 10.0.10240]
(c) 2015 Microsoft Corporation. All rights reserved.
C:\Windows\system32>telnet 192.168.56.101
Login authentication
Password: <<----------输入设置的密码,无显示
Info: The max number of VTY users is 5, and the number
of current VTY users on line is 1.
The current login time is 2022-07-28 20:52:41.
Enter system view, return user view with Ctrl+Z.
[Huawei]
登录上去了
电脑安装python
见这篇博文Python安装教程-史上最全_壬杰的博客-CSDN博客_python安装
C:\Windows\system32>python
Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:43:08) [MSC v.1926 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
python代码:
import telnetlib
import time
host = '192.168.56.101'
password = 'dnpn.xyz'
tn = telnetlib.Telnet(host)
tn.read_until(b"Password:")
tn.write(password.encode('ascii') + b"\n")
tn.write(b'display cu \n')
time.sleep(1)
print(tn.read_very_eager().decode('ascii'))
tn.close()
Python脚本调用telnetlib模块登录SW1,执行display current-configuration,并输出回显内容
>>> tn.close()
>>> import telnetlib
>>> import time
>>>
>>> host = '192.168.56.101'
>>> password = 'dnpn.xyz'
>>>
>>> tn = telnetlib.Telnet(host)
>>>
>>> tn.read_until(b"Password:")
b'\r\r\n\r\nLogin authentication\r\n\r\n\r\nPassword:'
>>> tn.write(password.encode('ascii') + b"\n")
>>> tn.write(b'display cu \n')
>>> time.sleep(1)
>>>
>>> print(tn.read_very_eager().decode('ascii'))
Info: The max number of VTY users is 5, and the number
of current VTY users on line is 1.
The current login time is 2022-07-28 21:07:05.
#
sysname Huawei
#
cluster enable
ntdp enable
ndp enable
#
drop illegal-mac alarm
#
diffserv domain default
#
drop-profile default
#
aaa
authentication-scheme default
authorization-scheme default
accounting-scheme default
domain default
domain default_admin
local-user admin password simple admin
local-user admin service-type http
#
interface Vlanif1
ip address 192.168.56.101 255.255.255.0
---- More ----
>>> tn.close()
>>>
代码解析
步骤 1 导入模块
import telnetlib
import time
导入本段代码中需要使用的telnetlib和time两个模块。这两个模块都是Python自带的模块,无需安装。
本章节主要介绍Telnetlib作为客户端的常用类和方法,例如Telnet类下read_until、read_very_eager()、write()等方法。更多Telnet的方法请参考telnetlib官方文档:https://docs.python.org/3/library/telnetlib.html#telnet-example。
Python默认无间隔按顺序执行所有代码,在使用telnet向交换机发送配置命令时候可能会遇到响应不及时或者设备回显信息显示不全。此时,可以使用time模块下的sleep方法来人为暂停程序。
步骤 2 登录设备
调用telnetlib里Telnet类的多种方法登录SW1。
host = '192.168.56.101'
password = 'dnpn.xyz'
tn = telnetlib.Telnet(host)
首先创建两个变量,host和password分别为设备的登录地址和密码,与设备配置参数一致。因为本例中仅在设备配置telnet密码方式登陆,所以无需用户名。
telnetlib.Telent()表示调用telnetlib类下的Telnet()方法。这个方法中包含登陆的参数,包括IP地址和端口号等信息。不填写端口信息则默认为23号端口。
本例中tn = telnetlib.Telnet(host),表示登陆host='192.168.56.101'的设备,然后将telnetlib.Telnet(host)赋值给tn。
tn.read_until(b"Password:")
正常Telnet登陆192.168.56.101设备时候,会有如下回显信息:
请注意程序并不知道需要读取到什么信息为止,所以我们使用read_until()指示读取到括号内信息为止。
本例中tn.read_until(b"Password:")表示读取到显示 "Password:"为止。其中字符串“Password:”前的“b”表示将Python3中默认的unicode编码变为bytes。这是函数对输入数据的要求,具体内容可以查看telnetlib官方文档,若不携带则程序会报错。
tn.write(password.encode('ascii') + b"\n")
在代码读取到显示"Password:"后,程序需输入参数password。这个参数在前面已定义,作为Telent登录的密码。使用write()完成password的写入。
本例中tn.write(password.encode('ascii') + b"\n"),输入的内容由两个部分组成,password.encode('ascii') 和b"\n"。password.encode('ascii')表示转换password代表的字符串“Huawei@123”的编码类型为ASCII。“+”表示将该符号前后的字符串连接。“\n”为换行符,相当于输入后敲击回车键。所以本行代码含义为输入密码“Huawei@123”并敲击回车键。
步骤 3 输入配置命令
Telnet到设备后,使用Python脚本向设备输入执行命令。
tn.write(b'display cu \n')
继续使用write()向设备输入命令。输入的命令“display cu”为“display current-configuration”的缩写,其功能是显示设备的当前配置。
time.sleep(1)
time.sleep(1)的作用是将程序暂停1秒。用于等待交换机回显信息,然后再执行后续代码。如果没有设置等待时间,则程序会直接执行下一行代码,导致没有数据可供读取。
print(tn.read_very_eager().decode('ascii'))
print()表示显示括号内的内容到控制台。
tn.read_very_eager()表示读取当前的尽可能多的数据。
. decode('ascii'))表示将读取的数据解码为ASCII。
本例中这段代码的功能为将输入“display cu”后1秒内S1输出的信息显示到控制台。
步骤 4 关闭会话
tn.close()
调用close()关闭当前会话。设备vty连接数量有限,在执行完脚本后需要关闭此telnet会话。