10-自动配置
本章节下载: 10-自动配置 (603.30 KB)
自动配置功能是指设备在启动时自动获取并执行配置文件。网络管理员只需将配置文件保存在指定的存储介质上,启动设备,即可实现自动配置,从而简化了网络配置,大大降低了网络管理员的工作量,便于实现对设备的集中管理。
自动配置的实现方式如表1-1所示:
配置方式 |
配置文件保存位置 |
应用场景 |
服务器自动配置 |
文件服务器 |
网络规模较大,设备位置相对分散 |
U盘自动配置 |
U盘 |
· 小规模网络:设备位置相对集中且缺少多余设备作为文件服务器 · 大规模网络:仅有少量设备的配置需要更新 |
设备上如果可以同时实现服务器自动配置和U盘自动配置时,则优先使用U盘自动配置。
设备空配置启动时,首先自动检查存储介质的根目录下是否存在autocfg.py、autocfg.tcl 或autocfg.cfg配置文件。如果存在,则直接执行此文件;如果不存在,则通过自动从文件服务器上获取并执行配置脚本文件或配置文件,实现自动配置功能。autocfg.py、autocfg.tcl和autocfg.cfg配置文件同时只能在设备上存在一个。
服务器自动配置是指在一个网络中存在文件服务器、DHCP服务器和DNS服务器的情况下,新加入或无配置文件的设备上电启动时,设备会自动运行DHCP Client服务,通过DHCP Server获取配置文件所在的URL地址或TFTP Server IP、TFTP Server name以及配置文件的文件名。最后从对应文件服务器(HTTP、TFTP、SFTP或FTP)下载配置文件进行配置加载并启动的过程。
服务器自动配置支持在IPv4和IPv6网络中实现,两种网络配置思路相同,本节仅以IPv4网络配置为例。
服务器自动配置的典型组网环境如图1-1所示。设备需要在DHCP服务器、文件服务器(TFTP服务器、HTTP服务器、SFTP服务器或FTP服务器)和DNS服务器的配合下,实现服务器自动配置功能。
· DHCP服务器:DHCP服务器为执行服务器自动配置的设备分配IP地址,并向设备通告获取自动配置文件或配置脚本的途径。
· 文件服务器:文件服务器用于保存自动配置的配置文件或脚本。
· DNS服务器:DNS服务器为设备获取到配置文件名称或获取文件服务器的IP地址。
主机名文件中保存有主机IP地址与主机名的映射关系,请按照以下方式来准备主机名文件:
(1) 创建主机名文件,文件名必须设置为“network.cfg”。
(2) 按照以下格式手工在文件中添加主机IP地址与主机名的映射关系,保证一行一条映射。
ip host host-name ip-address
例如,主机名文件中可以包括以下内容,则IP地址为101.101.101.101的设备使用的配置文件名为host1.cfg:
ip host host1 101.101.101.101
ip host host2 101.101.101.102
ip host client1 101.101.101.103
ip host client2 101.101.101.104
主机名必须与主机的配置文件名保持一致。
设备在进行自动配置时,系统按照如下规则选取符合条件的接口:
(1) 若有处于链路状态UP的管理以太网接口,则优先选取管理以太网接口。
(2) 若没有处于链路状态UP的管理以太网接口,有处于链路状态UP的二层以太网接口,则选取默认VLAN对应的VLAN接口。
(3) 若没有处于链路状态UP的二层以太网接口,则按照接口类型字典序、接口编号从小到大的顺序依次选择处于链路状态UP的三层以太网接口。
(4) 若没有处于链路状态UP的三层以太网接口,则在30秒后开始下次服务器自动配置接口选择过程。
建议管理员将设备的管理以太网接口连入网络中,这样可以加快服务器自动配置的速度。
设备通过服务器自动配置的流程如下:
(1) 设备按顺序选择获取配置文件的接口,并向DHCP服务器发送IP地址请求报文。选择获取配置文件的接口的顺序参见“选择获取配置文件的接口”。
(2) DHCP服务器收到IP地址请求报文后,会向设备发送一个回应报文。如果设备在超时时间内未收到回应报文,则会按顺序选择下一个接口发送IP地址请求报文。
(3) 设备解析回应报文:
¡ 获取回应报文中携带的IP地址,将此IP地址作为接口的IP地址用于和DHCP服务器连接。如果接口上已有IP地址,则会修改此IP地址,等自动配置完成后,再回退成原IP地址。
¡ 获取报文中携带的协议信息(HTTP、TFTP、SFTP或FTP)、配置文件名信息、文件服务器地址。
(4) 如果没有获取到配置文件名或配置文件名不符合规范,则会使用文件服务器中的network.cfg,如果不存在network.cfg,则会文件服务器中的使用device.cfg。如果device.cfg也不存在,则获取配置文件失败,重新选择接口,执行步骤(1)。
(5) 域名解析,如果回应报文中携带的文件服务器地址是域名而不是IP地址,则会通过DNS服务器将文件服务器的域名解析为IP地址。
(6) 设备根据解析到的协议、文件服务器地址、配置文件名从文件服务器下载配置文件或脚本。
(7) 下载成功后,下发配置或者执行脚本。
(8) 设备下发配置或者执行脚本完成后,则会自动删除该配置文件或脚本。
¡ 准备配置文件
¡ 准备配置脚本
(2) 配置文件服务器
(3) 配置DHCP服务器
(4) (可选)配置DNS服务器
(5) (可选)配置网关
(6) 完成自动配置
(7) (可选)终止自动配置
配置文件包括特定配置文件、部分或全部公用配置文件以及缺省配置文件(device.cfg)三种类型,如表1-2所示。
配置文件类型 |
适用的设备 |
文件名要求 |
支持的文件服务器 |
特定配置文件 |
具有特定配置需求的设备 |
配置文件名.cfg 为了方便辨识文件名,尽量不要使用包含空格的配置文件名。 |
· HTTP服务器 · TFTP服务器 · SFTP服务器 · FTP服务器 |
部分或全部共用配置文件 |
配置需求全部或者部分相同的设备 |
配置文件名.cfg 为了方便辨识文件名,尽量不要使用包含空格的配置文件名 |
· HTTP服务器 · TFTP服务器 · SFTP服务器 · FTP服务器 |
缺省配置文件 |
所有设备 包含一般设备启动的公用配置信息 |
device.cfg |
TFTP服务器 |
管理员可以根据网络中不同设备的需求和文件服务器类型选择配置:
(1) 在文件服务器上为每个具有特定配置需求的设备准备特定配置文件。
(2) 在文件服务器上以.cfg为后缀名为部分或全部具有相同配置的设备保存一个配置文件。
(3) 在TFTP服务器上保存名为device.cfg的缺省配置文件为既没有特定配置文件也没有部分或全部共用配置文件的设备提供缺省配置。
如果DHCP服务器未下发配置文件名,管理员还可以在文件服务器上创建主机名文件提供主机名和设备IP地址的对应关系,以保证执行自动配置的设备获取到对应的配置文件。
配置脚本可以实现自动更新版本、下发配置等功能。
目前设备支持的配置脚本包括Python脚本和Tcl脚本。Python脚本使用的文件后缀固定为.py,Tcl脚本使用的文件后缀固定为.tcl。关于Python脚本的详细介绍,请参见“基础配置指导”中的“Python”。关于Tcl脚本的详细介绍,请参见“基础配置指导”中的“Tcl”。
使用Tcl脚本配置文件对设备进行自动配置时,若配置文件中的命令行错误(例如:命令行拼写错误、视图错误、设备不支持所配置的命令等),那么设备在执行到错误命令行时将直接中断自动配置操作。
使用Python脚本配置文件对设备进行自动配置时,若配置文件中的命令行错误(例如:命令行拼写错误、视图错误、设备不支持所配置的命令等),则本次自动配置将失败,进行下一轮自动配置。
使用Python脚本配置文件对设备进行自动配置时,设备处于启动阶段(非稳定运行状态),所以,Python脚本中请不要使用display system stable state命令显示结果为Stable来作为执行动作的判断条件。
使用配置脚本与使用配置文件有如下区别:
· 在文件服务器上只支持配置特定配置脚本和部分或全部共用配置脚本两种形式,不支持缺省配置脚本。
· 在文件服务器上不支持使用主机名文件提供主机名和IP地址的对应关系。
有关“特定配置”、“部分或全部共用配置”、“缺省配置”以及“主机名和IP地址的对应关系”请参见“1.2.7 准备配置文件”。
管理员可以根据网络中不同设备的需求和文件服务器类型选择配置:
(1) 在文件服务器上为每个具有特定配置需求的设备准备特定配置脚本。
(2) 在文件服务器上以.tcl或.py为后缀名为部分或全部具有相同配置的设备保存一个配置文件。
设备可以通过HTTP、TFTP、SFTP或FTP获取配置文件,管理员需要根据选用的方式在文件服务器上配置相应的HTTP服务、TFTP服务、SFTP服务或FTP服务。
DHCP服务器为执行服务器自动配置的设备分配IP地址,并向设备通告获取自动配置文件或配置脚本的途径。
DHCP服务器可以根据管理员需要的配置文件类型,进行相应的配置(下发配置脚本和下发配置文件实现一致,下面以下发配置文件为例):
· 如果管理员为每台设备分配特定配置文件,则需要在DHCP服务器上配置静态绑定关系,为每台设备分配特定的IP地址和配置文件名。由于一个地址池下只能配置一条配置文件名的命令,所以DHCP服务器上每一个地址池视图只能配置一个静态绑定关系。
· 如果管理员为局域网内的部分设备分配相同的配置文件,可以在DHCP服务器上为使用部分共用配置文件的设备配置静态绑定关系,并指定文件服务器和部分共用配置文件名。这时,这部分静态绑定关系需要在同一个DHCP地址池中配置。也可以使用动态分配IP地址的方式,管理员需要划分合适的动态地址段,为这部分设备分配IP地址,并指定文件服务器和部分共用配置文件名。
· 如果管理员为局域网内的所有设备分配相同的配置文件,则需要在DHCP服务器上配置动态分配IP地址的方式。为设备动态分配IP地址的同时,分配全部共用配置文件名。如果采用这种方式,全部共用配置文件中只能包含这些设备共有的配置,每个设备特有的配置还需要其他方式完成(如管理员使用Telnet登录到设备上手工配置)。
以上三种分配方式可以同时在一台DHCP服务器上配置。
配置DHCP客户端使用的远程启动配置文件时:
· 对于TFTP服务器需要指定启动文件名,如果启动文件名中有特殊字符时,需要依据RFC规范进行转译后才能使用。
· 对于HTTP服务器需要指定HTTP形式的URL,形式为http://HTTP服务器IP地址:端口号/路径/文件名。如果URL中的路径或文件名中有特殊字符时,需要依据RFC规范进行转译后才能使用。如果不指定端口号,则表示使用默认端口号。
· 对于FTP服务器需要指定FTP形式的URL,形式为ftp://用户名:密码@FTP服务器IP地址:端口号/路径/文件名。如果URL中的用户名、密码、路径或文件名中有特殊字符时,需要依据RFC规范进行转译后才能使用。如果不指定端口号,则表示使用默认端口号,如果不指定路径,则表示使用服务器的根目录。
· 对于SFTP服务器需要指定SFTP形式的URL,形式为sftp://用户名:密码@SFTP服务器IP地址:端口号/路径/文件名。如果URL中的用户名、密码、路径或文件名中有特殊字符时,需要依据RFC规范进行转译后才能使用。如果不指定端口号,则表示使用默认端口号,如果不指定路径,则表示使用服务器的根目录。
(1) 进入系统视图。
system-view
(2) 开启DHCP服务。
dhcp enable
缺省情况下,DHCP服务处于关闭状态。
(3) 创建DHCP地址池,并进入DHCP地址池视图。
dhcp server ip-pool pool-name
(4) 为客户端分配IP地址。请至少选择其中一项进行配置。
¡ 配置DHCP地址池动态分配的主网段。
network network-address [ mask-length | mask mask ]
缺省情况下,未配置动态分配的主网段。
¡ 配置静态地址绑定。
static-bind ip-address ip-address [ mask-length | mask mask ] { client-identifier client-identifier | hardware-address hardware-address [ ethernet | token-ring ] }
缺省情况下,未配置静态地址绑定。
多次执行本命令,可以配置多个静态地址绑定。同一地址只能绑定给一个客户端。若需修改绑定必须先解除绑定。
(5) 配置DHCP客户端使用的远程启动配置文件的HTTP形式URL。
bootfile-name url
缺省情况下,未配置DHCP客户端使用的远程启动配置文件的HTTP形式URL。
(1) 进入系统视图。
system-view
(2) 开启DHCP服务。
dhcp enable
缺省情况下,DHCP服务处于关闭状态。
(3) 创建DHCP地址池,并进入DHCP地址池视图。
dhcp server ip-pool pool-name
(4) 为客户端分配IP地址。请至少选择其中一项进行配置。
¡ 配置DHCP地址池动态分配的主网段。
network network-address [ mask-length | mask mask ]
缺省情况下,未配置动态分配的主网段。
¡ 配置静态地址绑定。
static-bind ip-address ip-address [ mask-length | mask mask ] { client-identifier client-identifier | hardware-address hardware-address [ ethernet | token-ring ] }
缺省情况下,未配置静态地址绑定。
多次执行本命令,可以配置多个静态地址绑定。同一地址只能绑定给一个客户端。若需修改绑定必须先解除绑定。
(5) 指定TFTP服务器。请选择其中一项进行配置。
¡ 配置DHCP客户端使用的TFTP服务器地址。
tftp-server ip-address ip-address
缺省情况下,未配置DHCP客户端使用的TFTP服务器地址。
¡ 配置DHCP客户端使用的TFTP服务器名。
tftp-server domain-name domain-name
缺省情况下,未配置DHCP客户端使用的TFTP服务器名。
使用此方式指定TFTP服务器需要在网络中架设DNS服务器。
(6) 配置DHCP客户端使用的启动配置文件名。
bootfile-name bootfile-name
缺省情况下,未配置DHCP客户端使用的启动配置文件名。
(1) 进入系统视图。
system-view
(2) 开启DHCP服务。
dhcp enable
缺省情况下,DHCP服务处于关闭状态。
(3) 创建DHCP地址池,并进入DHCP地址池视图。
dhcp server ip-pool pool-name
(4) 为客户端分配IP地址。请至少选择其中一项进行配置。
¡ 配置DHCP地址池动态分配的主网段。
network network-address [ mask-length | mask mask ]
缺省情况下,未配置动态分配的主网段。
¡ 配置静态地址绑定。
static-bind ip-address ip-address [ mask-length | mask mask ] { client-identifier client-identifier | hardware-address hardware-address [ ethernet | token-ring ] }
缺省情况下,未配置静态地址绑定。
多次执行本命令,可以配置多个静态地址绑定。同一地址只能绑定给一个客户端。若需修改绑定必须先解除绑定。
(5) 配置DHCP客户端使用的远程启动配置文件的SFTP形式URL。
bootfile-name url
缺省情况下,未配置DHCP客户端使用的远程启动配置文件的SFTP形式URL。
(1) 进入系统视图。
system-view
(2) 开启DHCP服务。
dhcp enable
缺省情况下,DHCP服务处于关闭状态。
(3) 创建DHCP地址池,并进入DHCP地址池视图。
dhcp server ip-pool pool-name
(4) 为客户端分配IP地址。请至少选择其中一项进行配置。
¡ 配置DHCP地址池动态分配的主网段。
network network-address [ mask-length | mask mask ]
缺省情况下,未配置动态分配的主网段。
¡ 配置静态地址绑定。
static-bind ip-address ip-address [ mask-length | mask mask ] { client-identifier client-identifier | hardware-address hardware-address [ ethernet | token-ring ] }
缺省情况下,未配置静态地址绑定。
多次执行本命令,可以配置多个静态地址绑定。同一地址只能绑定给一个客户端。若需修改绑定必须先解除绑定。
(5) 配置DHCP客户端使用的远程启动配置文件的FTP形式URL。
bootfile-name url
缺省情况下,未配置DHCP客户端使用的远程启动配置文件的FTP形式URL。
在使用服务器自动配置功能时,在如下两种情况时,管理员需要配置DNS服务器:
· 为设备获取到配置文件名称。当TFTP服务器上不存在主机名文件时,执行服务器自动配置的设备可以通过DNS服务器将设备自己的IP地址解析为主机名,并使用该主机名从TFTP服务器获取到同名的配置文件;
· 获取文件服务器的IP地址。如果设备从DHCP应答报文中获取到文件服务器的域名,设备还可以通过DNS服务器将文件服务器的域名解析为文件服务器的IP地址。
关于DNS服务器的详细介绍,请参见“三层技术-IP业务配置指导”中的“域名解析”。
如果DHCP服务器、文件服务器和DNS服务器与执行服务器自动配置的设备不在同一网段,则需要部署网关设备,使得各个服务器和设备之间路由可达,并在网关上配置DHCP中继功能。
如果DHCP应答报文中不包括TFTP服务器IP地址和域名信息,或TFTP服务器IP地址和域名信息不合法,设备将以广播方式向TFTP服务器发送请求消息。由于广播报文只能在本网段内传播,如果设备与TFTP服务器不在同一个网段,则需要在网关设备上配置UDP Helper功能,将广播报文转换成单播报文,转发给指定的TFTP服务器。有关UDP Helper功能的详细介绍,请参见“三层技术-IP业务配置指导”中的“UDP-helper”。
(1) 上电启动需要进行自动配置的设备。
(2) 设备进入服务器自动配置,获取并执行配置文件成功,则整个服务器自动配置过程结束。
(3) 在完成自动配置的设备上保存配置。
save
建议在配置文件执行完成后保存配置。本命令的详细介绍请参见“基础配置命令参考”中的“配置文件管理”。
如果获取不到自动配置文件,则本次自动配置尝试失败,设备将继续尝试自动配置。用户可以等待尝试次数达到上限,设备自动结束自动配置,或根据提示信息,使用<Ctrl+C>或<Ctrl+D>快捷键手工终止自动配置。自动配置失败并结束后,设备将以空配置启动。
设备空配置启动进入自动配置流程后,首先尝试通过从U盘进行自动配置。U盘自动配置支持如下两种方式:
· 使用索引文件指定的配置文件进行自动配置。
· 直接使用配置文件进行自动配置。
设备将优先使用索引文件指定的配置文件进行自动配置,若无索引文件,则再使用配置文件进行自动配置。
管理员将索引文件和配置文件保存在U盘上,设备在启动时可以自动从U盘上的索引文件获取并执行配置文件,实现自动配置功能。
通过索引文件进行自动配置的流程如下:
(1) 设备检测到U盘在位。
(2) 设备检测U盘中是否存在“smart_config.ini”索引文件。
¡ 如果存在“smart_config.ini”索引文件,则进入步骤(3)。
¡ 如果不存在“smart_config.ini”索引文件,则仅使用配置文件进行自动配置。
(3) 设备检测“smart_config.ini”索引文件格式的合法性。
¡ 如果合法,则进入步骤(4)。
¡ 如果不合法,则U盘自动配置失败,流程结束,在U盘中生成错误报告。
(4) 设备将“smart_config.ini”索引文件中指定的数据变更时间标志与设备中记录的上次U盘自动配置的时间标志进行比较。
¡ 如果不相同,则进入步骤(5)。
¡ 如果相同,则U盘自动配置失败,流程结束,在U盘中生成错误报告。
(5) 设备按照“smart_config.ini”索引文件中的描述信息从U盘中获取配置文件,并将其保存至默认的存储介质中。
¡ 如果获取配置文件成功,则进入步骤(6)。
¡ 如果获取配置文件失败,则U盘自动配置失败,流程结束,在U盘中生成错误报告。
(6) 设备根据获取的配置文件或者指定的激活方式,判断是否需要重启激活。
¡ 如果不需要重启,则在线激活相应文件,进入步骤(7)。
¡ 如果需要重启,设备会将相应的文件设置为下次启动文件,自动重启成功后,进入步骤(7)。
(7) U盘自动配置成功。自动配置成功后,会将U盘中配置文件的配置覆盖设备当前的配置,并将该配置设置为设备下次启动时的配置。流程结束,将U盘从设备中拔出。
U盘自动配置之前,需要先制作索引文件并将索引文件保存至U盘根目录下。把需要加载的配置文件保存至索引文件指定的U盘目录下。
使用索引文件进行自动配置时,索引文件的名称必须为“smart_config.ini”。
用户可以在PC上编辑U盘自动配置索引文件,具体步骤如下:
(1) 新建一个空的文本文档。
(2) 按照U盘自动配置索引文件模板编辑文件内容。
(3) 将此文本文档另存为“smart_config.ini”。
(4) 将索引文件smart_config.ini拷贝至U盘,此文件必须保存至U盘根目录下。
索引文件中各字段的含义如表1-3所示。
字段 |
描述 |
|
BEGIN LSW |
必选字段。起始标志,此字段不能修改 |
|
GLOBAL CONFIG |
必选字段。全局配置起始标志,此字段不能修改 |
|
TIMESN |
必选字段。数据变更时间标志,字符串格式,长度范围为1~16,不能包含空格。建议格式:年月日.时分秒。 例如,2011年06月28日08时09分10秒,可设置为TIMESN=20110628.080910。 每个TIMESN对应某台升级的设备。在U盘自动配置过程中,设备会在重启前记录此TIMESN(升级后不需要重启的则在升级完成后记录),下次升级不可使用此TIMESN。如果由于某些原因造成在设备重启后升级失败,则需要将TIMESN重新修改后再进行U盘自动配置 |
|
AUTODELFILE |
可选字段。表示是否允许升级后自动删除原有系统软件 · AUTODELFILE=YES:删除 · AUTODELFILE=NO:不删除 缺省情况下,AUTODELFILE为NO。如果该字段不存在、为空或是不合法值,均表示为缺省情况 有两种AUTODELFILE字段:全局字段和单台设备字段。 位于[GLOBAL CONFIG]字段内的是全局字段,位于[DEVICE DESCRIPTION]内的是单台设备字段。 如果单台设备设置了此字段的值为YES或NO,则以单台设备设置的生效。如果单台设备没有设置此字段或者此字段为空,则以全局设置的生效 |
|
AUTOOVERWRITEFILE |
可选字段。表示从U盘拷贝配置文件到设备上时,如果设备上有同名配置文件,是否允许覆盖设备上的同名配置文件 · AUTOOVERWRITEFILE =YES:覆盖 · AUTOOVERWRITEFILE =NO:不覆盖 缺省情况下,AUTOOVERWRITEFILE为YES。如果该字段不存在、为空或是不合法值,均表示为缺省情况 |
|
ACTIVEMODE |
可选字段。表示文件拷贝完成后的文件激活方式。 · DEFAULT:按照各个文件的默认方式激活。其中,系统软件默认激活方式是重启设备;配置文件、补丁文件默认激活方式是不重启设备,在线激活 · REBOOT:采用重启设备的方式激活。缺省情况下,ACTIVEMODE为DEFAULT。如果该字段不存在、为空或是不合法值,均表示为缺省情况。有两种ACTIVEMODE字段:全局字段和单台设备字段。位于[GLOBAL CONFIG]字段内的是全局字段,位于[DEVICE DESCRIPTION]内的是单台设备字段 如果单台设备设置了此字段的值为DEFAULT或REBOOT,则以单台设备设置的生效。如果单台设备没有设置此字段或者此字段为空,则以全局设置的生效 |
|
DEVICE DESCRIPTION |
必选字段。单台设备文件信息描述起始标志 DEVICE DESCRIPTION字段下表示单台设备信息的每个字段不可以重复出现,否则将不匹配这个DEVICE。 DEVICE按照文件中定义的顺序从上到下进行匹配,匹配到一组之后不会再匹配其它DEVICE |
|
OPTION |
可选字段。单台设备文件信息有效标志,表示该设备文件信息是否有效。 · OPTION=OK:有效 · OPTION=NOK:无效,此单台设备的文件信息都无需判断 缺省情况下,OPTION为OK。如果该字段不存在、为空或是不合法值,均表示为缺省情况 |
|
SN |
可选字段。设备序列号。如果SN=DEFAULT,表示不匹配ESN序列号,否则需要和设备匹配SN。 缺省情况下,ESN为DEFAULT。如果该字段不存在或为空,则表示为缺省情况 |
待升级的设备将在索引文件中按DEVICE从上往下进行匹配,匹配的优先级为:MAC > SN > DEVICETYPE > DEFAULT。一旦匹配上,则按匹配上的DEVICE信息加载文件,如果此过程出错,将不会再次进行匹配,只会输出错误报告 |
MAC |
可选字段。设备MAC地址,格式为:XXXX-XXXX-XXXX,X为十六进制数。如果MAC=DEFAULT,表示不匹配MAC地址,否则需要和设备匹配MAC地址 缺省情况下,MAC为DEFAULT。如果该字段不存在或为空,则表示为缺省情况 |
|
DEVICETYPE |
可选字段。表示与设备的类型匹配,例如S12700。如果DEVICETYPE=DEFAULT,表示不匹配设备类型。否则需要和设备的类型匹配 缺省情况下,DEVICETYPE为DEFAULT。如果该字段不存在或为空,则表示为缺省情况 |
|
DIRECTORY |
可选字段。配置文件或软件包在U盘中存放的目录。 此字段为空或不存在时,表示文件位于U盘根目录下。 DIRECTORY=/abc,表示文件位于U盘的abc文件夹下。 缺省情况下,DIRECTORY字段为空。 索引文件中文件目录的格式必须与设备的文件系统一致,且索引文件中文件目录需要符合如下要求: · 目录深度小于等于4级。目录必须以“/”开头,每一级目录以“/”隔开,但不能以“/”结束,例如/abc/test是合法目录,/abc/test/则是非法目录。 · 每一级目录的字符串长度范围是1~15。 · 目录名使用的字符不可以是空格、“~” 、“*” 、“/” 、“\” 、“:” 、“'” 、“"” 、“<” 、“>” 、“|” 、“?” 、“[” 、“]”、“%” 等字符,目录名称不区分大小写 |
|
SYSTEM-IPE= |
可选字段。系统版本名称,后缀名为“.ipe” |
|
SYSTEM-BOOT-BIN= |
可选字段。Boot软件包名称,后缀名为“.bin” |
|
SYSTEM-SYSTEM-BIN= |
可选字段。system软件包名称,后缀名为“.bin” |
|
SYSTEM-FEATURE-BIN= |
可选字段。特性软件包名称,后缀名为“.bin |
|
SYSTEM-PATCH-BIN= |
可选字段。系统软件名称,后缀名为“.bin” |
|
SYSTEM-CONFIG |
可选字段。配置文件名称,后缀名为“.cfg” |
|
END LSW |
必选字段。文件结束标志 |
索引文件模板如下:
BEGIN LSW
[GLOBAL CONFIG]
TIMESN=
AUTOOVERWRITEFILE=
AUTODELFILE=
ACTIVEMODE=
[DEVICE DESCRIPTION]
OPTION=
SN=
MAC=
AUTODELFILE=
ACTIVEMODE=
DEVICETYPE=
DIRECTORY=
SYSTEM-IPE=
SYSTEM-BOOT-BIN=
SYSTEM-SYSTEM-BIN=
SYSTEM-FEATURE-BIN=
SYSTEM-FEATURE-BIN=
SYSTEM-FEATURE-BIN=
SYSTEM-PATCH-BIN=
SYSTEM-CONFIG=
END LSW
编辑U盘自动配置索引文件时,请确保索引文件内容的正确性。待升级的设备将在索引文件中按DEVICE从上往下进行匹配,匹配的优先级为:MAC > SN > DEVICETYPE。一旦匹配上,则按匹配上的DEVICE信息进行加载文件,如果此过程出错,将终止整个U盘自动配置进程,并输出错误报告。成功升级的设备不会回滚配置。
通过索引文件自动配置时,设备会根据索引文件确认需要加载的文件:
(1) 第一步确认索引文件中是否指定了IPE文件:如果在索引文件中指定了IPE文件,则确认加载IPE文件,然后跳过第二步进行第三步;如果在索引文件中没有指定IPE文件,则设备会跳过第一步进行第二步。
(2) 第二步确认索引文件中是否指定了Boot、System和Feature文件:如果在索引文件中指定了Boot、System和Feature文件,则确认加载对应的文件,其中Boot和System文件为必选,Feature文件为可选。确认加载对应的文件后会进行第三步。如果在索引文件中没有指定Boot、System和Feature文件,则跳过第二步并进行第三步。
(3) 第三步确认索引文件中是否指定了Patch文件:如果在索引文件中指定了Patch文件,则确认加载Patch文件,然后跳过第三步进行第四步;如果在索引文件中没有指定Patch文件,则设备会跳过第三步进行第四步。
(4) 第四步确认索引文件中是否指定了CFG配置文件:如果在索引文件中是否指定了CFG配置文件则确认加载CFG配置文件。在进行第四步后设备会开始加载需要加载的文件。如果在索引文件中未指定CFG配置文件,则设备会跳过加载文件的步骤。
在进行第四步后设备会开始加载需要加载的文件,如果加载失败,则设备会终止U盘自动配置进程。
· 编写索引文件时,按照固定格式输入一行后必须回车换行后再进行新内容的编写,编写完成请注意保存索引文件。
· 如果某项关键字没有匹配或者没有搜索到,则认为该项的参数内容为空。
· 当设备的“GLOBAL CONFIG”中的全局配置与匹配的“DEVICE DESCRIPTION”中的单台设备配置的相同字段的配置不同时,以“DEVICE DESCRIPTION”中的配置为准。
(1) 开启U盘自动配置功能。
a. 进入系统视图。
system-view
b. 开启U盘自动配置功能。
autodeploy udisk enable
缺省情况下,U盘自动配置功能处于开启状态。
若设备预先关闭了U盘自动配置功能,则配置本命令后需要保存配置并重启设备后才能生效。
c. 保存当前配置。
save
(2) 制作索引文件。
(3) 将制作好的索引文件保存到U盘根目录下,将索引文件中定义的开局文件保存到指定目录,缺省为根目录。
(4) 将U盘插入主设备的USB1接口,即usba0:。配置文件会从主设备自动同步到备设备。
(5) 观察指示灯。
U盘自动配置成功时,系统(SYS)指示灯绿色快速闪烁5秒;U盘自动配置失败时,系统(SYS)指示灯黄色快速闪烁10秒。如果配置文件下发失败,设备会把失败的日志写到U盘根目录下,日志文件名为“配置文件全名.log”。管理员可以根据日志信息进行问题定位和处理。指示灯状态与设备型号有关,请以设备实际情况为准。
(6) 可以执行display current-configuration命令查看U盘中的配置是否已正确加载,该命令的详细介绍请参见“基础配置命令参考”中的“配置文件管理”。
(7) U盘自动配置完成后需拔出U盘。
管理员将配置文件保存在U盘上,设备在启动时可以自动从U盘上获取并执行配置文件,实现自动配置功能。
使用配置文件进行自动配置的流程如下:
(1) 设备检测到U盘在位。
(2) 设备检测U盘中是否存在“smart_config.ini”索引文件。
¡ 如果存在“smart_config.ini”索引文件,则使用索引文件指定的配置文件进行自动配置。
¡ 如果不存在“smart_config.ini”索引文件,则进入步骤(3)。
(4) 设备启动过程中,检测U盘中是否存在.cfg格式的配置文件。
¡ 如果存在,则进入步骤(5)。
¡ 如果不存在,则U盘自动配置流程结束。
(5) 设备从U盘获取到配置文件后,比较该配置文件与设备上的当前主配置文件内容是否相同:
¡ 如果文件内容相同,设备将直接使用当前主用配置文件,不使用U盘上的配置文件。
¡ 如果文件内容不相同,则设备将U盘中的配置文件复制到本地,并执行步骤(6)。
设备本地存储中有重名配置文件时,根据本地配置文件的属性采用如下处理方式:
- 如果本地重名配置文件为当前主用配置文件,则设备将该文件以“原名_bak.cfg”为名称另存。
- 如果本地重名配置文件不是当前主用配置文件,则设备直接使用U盘中的配置文件覆盖本地重名文件。
(6) 设备执行U盘配置文件。
¡ 若设备执行U盘配置文件成功,则自动将U盘中配置文件的配置设置为设备当前的配置,并从U盘拷贝的配置文件设置为下次启动的主用配置文件。
¡ 若设备执行U盘配置文件中的某条命令失败时,则会忽略U盘配置文件中的所有配置,使用设备之前保存的配置文件;如果设备之前未保存配置文件,则设备空配置启动。
(1) 准备一个没有分区的U盘。
(2) 查询设备的序列号。
display device manuinfo
该命令的详细介绍请参见“基础配置命令参考”中的“设备管理”。
(3) 创建配置文件名为“设备序列号.cfg”或“autodeploy.cfg”的配置文件,并保存在U盘的根目录中。
若U盘中同时存在“设备序列号.cfg”和“autodeploy.cfg”文件时,设备优先使用配置文件“设备序列号.cfg”。
(1) 开启U盘自动配置功能。
a. 进入系统视图。
system-view
b. 开启U盘自动配置功能。
autodeploy udisk enable
缺省情况下,U盘自动配置功能处于开启状态。
若设备预先关闭了U盘自动配置功能,则配置本命令后需要保存配置并重启设备后才能生效。
c. 保存当前配置。
save
(2) 将U盘插入主设备的USB1接口,即usba0:。配置文件会从主设备自动同步到备设备。
(3) 手动重启设备并观察指示灯。
U盘自动配置成功时,系统(SYS)指示灯绿色快速闪烁5秒;U盘自动配置失败时,系统(SYS)指示灯黄色快速闪烁10秒。如果配置文件下发失败,设备会把失败的日志写到U盘根目录下,日志文件名为“配置文件全名.log”。管理员可以根据日志信息进行问题定位和处理。指示灯状态与设备型号有关,请以设备实际情况为准。
(4) 设备启动完成后,可以执行display current-configuration命令查看U盘中的配置是否已正确加载,该命令的详细介绍请参见“基础配置命令参考”中的“配置文件管理”。
(5) U盘自动配置完成后需拔出U盘。
如图1-2所示,某公司下属两个部门:市场部门和研发部门,两个部门通过不同的网关设备连入网络。要求连接终端主机的设备Switch D、Switch E、Switch F和Switch G执行自动配置功能,启动后自动获取并执行配置文件,以实现:
· 网络管理员能够通过Telnet方式登录、控制设备。
· 登录设备时需要进行认证,且登录不同部门的设备使用的用户名和密码不能相同,以提供一定的安全保证。
具体组网情况如下:
· Switch A作为DHCP服务器,分别为市场部和研发部的主机分配IP地址和其他网络配置参数。
· 网关Switch B和Switch C作为DHCP中继设备。
· 一台运行TFTP管理软件的TFTP服务器上保存配置文件。
(1) Switch A的配置
# 配置接口IP地址
<SwitchA> system-view
[SwitchA] vlan 2
[SwitchA-vlan2] port ten-gigabitethernet 1/0/1
[SwitchA-vlan2] quit
[SwitchA] interface vlan-interface 2
[SwitchA-Vlan-interface2] ip address 192.168.1.42 24
[SwitchA-Vlan-interface2] quit
# 开启DHCP服务。
[SwitchA] dhcp enable
# 配置VLAN接口2工作在DHCP服务器模式。
[SwitchA] interface vlan-interface 2
[SwitchA-Vlan-interface2] dhcp select server
[SwitchA-Vlan-interface2] quit
# 配置DHCP地址池market,为市场部动态分配192.168.2.0/24网段的地址,并指定TFTP server地址、网关地址和配置文件名。
[SwitchA] dhcp server ip-pool market
[SwitchA-dhcp-pool-market] network 192.168.2.0 24
[SwitchA-dhcp-pool-market] tftp-server ip-address 192.168.1.40
[SwitchA-dhcp-pool-market] gateway-list 192.168.2.1
[SwitchA-dhcp-pool-market] bootfile-name market.cfg
[SwitchA-dhcp-pool-market] quit
# 配置DHCP地址池rd,为研发部动态分配192.168.3.0/24网段的地址,并指定TFTP server地址、网关地址和配置文件名。
[SwitchA] dhcp server ip-pool rd
[SwitchA-dhcp-pool-rd] network 192.168.3.0 24
[SwitchA-dhcp-pool-rd] tftp-server ip-address 192.168.1.40
[SwitchA-dhcp-pool-rd] gateway-list 192.168.3.1
[SwitchA-dhcp-pool-rd] bootfile-name rd.cfg
[SwitchA-dhcp-pool-rd] quit
# 配置到达DHCP中继的静态路由。
[SwitchA] ip route-static 192.168.2.0 24 192.168.1.41
[SwitchA] ip route-static 192.168.3.0 24 192.168.1.43
[SwitchA] quit
(2) Switch B的配置
# 配置接口的IP地址
<SwitchB> system-view
[SwitchB] vlan 2
[SwitchB-vlan2] port ten-gigabitethernet 1/0/3
[SwitchB-vlan2] quit
[SwitchB] interface vlan-interface 2
[SwitchB-Vlan-interface2] ip address 192.168.1.41 24
[SwitchB-Vlan-interface2] quit
[SwitchB] vlan 3
[SwitchB-vlan3] port ten-gigabitethernet 1/0/1
[SwitchB-vlan3] port ten-gigabitethernet 1/0/2
[SwitchB-vlan3] quit
[SwitchB] interface vlan-interface 3
[SwitchB-Vlan-interface3] ip address 192.168.2.1 24
[SwitchB-Vlan-interface3] quit
# 开启DHCP服务。
[SwitchB] dhcp enable
# 配置VLAN接口3工作在DHCP中继模式。
[SwitchB] interface vlan-interface 3
[SwitchB-Vlan-interface3] dhcp select relay
# 配置DHCP服务器的地址。
[SwitchB-Vlan-interface3] dhcp relay server-address 192.168.1.42
(3) Switch C的配置
# 配置接口的IP地址
<SwitchC> system-view
[SwitchC] vlan 2
[SwitchC-vlan2] port ten-gigabitethernet 1/0/3
[SwitchC-vlan2] quit
[SwitchC] interface vlan-interface 2
[SwitchC-Vlan-interface2] ip address 192.168.1.43 24
[SwitchC-Vlan-interface2] quit
[SwitchC] vlan 3
[SwitchC-vlan3] port ten-gigabitethernet 1/0/1
[SwitchC-vlan3] port ten-gigabitethernet 1/0/2
[SwitchC-vlan3] quit
[SwitchC] interface vlan-interface 3
[SwitchC-Vlan-interface3] ip address 192.168.3.1 24
[SwitchC-Vlan-interface3] quit
# 开启DHCP服务。
[SwitchC] dhcp enable
# 配置VLAN接口3工作在DHCP中继模式。
[SwitchC] interface vlan-interface 3
[SwitchC-Vlan-interface3] dhcp select relay
# 配置DHCP服务器的地址。
[SwitchC-Vlan-interface3] dhcp relay server-address 192.168.1.42
(4) TFTP服务器配置
在TFTP server创建配置文件market.cfg,文件内容如下:
#
sysname Market
#
telnet server enable
#
vlan 3
#
local-user market
password simple build22345
service-type telnet
quit
#
interface Vlan-interface3
ip address dhcp-alloc
quit
#
interface ten-gigabitethernet 1/0/1
port access vlan 3
quit
#
user-interface vty 0 63
authentication-mode scheme
user-role network-admin
#
return
在TFTP服务器创建配置文件rd.cfg,文件内容如下:
#
sysname RD
#
telnet server enable
#
vlan 3
#
local-user rd
password simple create22345
service-type telnet
quit
#
interface Vlan-interface3
ip address dhcp-alloc
quit
#
interface ten-gigabitethernet 1/0/1
port access vlan 3
quit
#
user-interface vty 0 63
authentication-mode scheme
user-role network-admin
#
return
# 启动TFTP管理软件,并指定TFTP的工作路径为保存上述配置文件的路径。
# 以Windows XP系统的主机为例,需保证TFTP服务器与DHCP中继之间路由可达。
(1) Switch D、Switch E、Switch F和Switch G在没有配置文件的情况下启动。启动成功后,在Switch A上查看地址池中的地址绑定信息。
<SwitchA> display dhcp server ip-in-use
IP address Client-identifier/ Lease expiration Type
Hardware address
192.168.2.2 3030-3066-2e65-3233- May 6 05:21:25 2013 Auto(C)
642e-3561-6633-2d56-
6c61-6e2d-696e-7465-
7266-6163-6533
192.168.2.3 3030-3066-2e65-3230- May 6 05:22:50 2013 Auto(C)
302e-3232-3033-2d56-
6c61-6e2d-696e-7465-
7266-6163-6533
192.168.3.2 3030-6530-2e66-6330- May 6 05:23:15 2013 Auto(C)
302e-3335-3131-2d56-
6c61-6e2d-696e-7465-
7266-6163-6531
192.168.3.3 3030-6530-2e66-6330- May 6 05:24:10 2013 Auto(C)
302e-3335-3135-2d56-
6c61-6e2d-696e-7465-
7266-6163-6532
(2) 在Switch A上执行如下命令:
<SwitchA> telnet 192.168.2.2
(3) 输入用户名market、密码build22345后,可以登录Switch D或Switch E。
如图1-3所示,Switch A启动后自动从HTTP服务器获取Tcl脚本启动配置文件,并执行该文件,以实现:
· 网络管理员能够通过Telnet方式登录、控制设备。
· 登录设备时需要进行认证,以提供一定的安全保证。
(1) 配置DHCP服务器
# 开启DHCP服务,创建名称为1的DHCP地址池,配置地址池动态分配IP地址的网段为192.168.1.0/24。
<DeviceA> system-view
[DeviceA] dhcp enable
[DeviceA] dhcp server ip-pool 1
[DeviceA-dhcp-pool-1] network 192.168.1.0 24
# 配置DHCP客户端远程启动配置文件为HTTP形式的URL。
[DeviceA-dhcp-pool-1] bootfile-name http://192.168.1.40/device.tcl
(2) 配置HTTP服务器,保证Switch A可以从HTTP服务器成功下载配置文件device.tcl。
# 在HTTP服务器创建配置文件device.tcl,文件内容如下:
system-view
telnet server enable
local-user user
password simple hello22345
service-type telnet
quit
user-interface vty 0 63
authentication-mode scheme
user-role network-admin
quit
interface ten-gigabitethernet 1/0/1
port link-mode route
ip address dhcp-alloc
return
# 启动HTTP管理软件,开启HTTP服务(配置过程略)。
(1) Switch A在没有配置文件的情况下启动。启动成功后,在Device A上查看地址池中的地址绑定信息。
<DeviceA> display dhcp server ip-in-use
IP address Client identifier/ Lease expiration Type
Hardware address
192.168.1.2 0030-3030-632e-3239- Dec 12 17:41:15 2013 Auto(C)
3035-2e36-3736-622d-
4574-6830-2f30-2f32
(2) 在Device A上执行如下命令:
<SwitchA> telnet 192.168.1.2
(3) 输入用户名user、密码hello22345后,用户可以登录Switch A。
如图1-4所示,Switch A启动后自动从HTTP服务器获取Python脚本启动配置文件,并执行该文件,以实现:
· 网络管理员能够通过Telnet方式登录、控制设备。
· 登录设备时需要进行认证,以提供一定的安全保证。
图1-4 服务器自动配置组网图(HTTP Python方式)
(1) 配置DHCP服务器
# 开启DHCP服务,创建名称为1的DHCP地址池,配置地址池动态分配IP地址的网段为192.168.1.0/24。
<DeviceA> system-view
[DeviceA] dhcp enable
[DeviceA] dhcp server ip-pool 1
[DeviceA-dhcp-pool-1] network 192.168.1.0 24
# 配置DHCP客户端远程启动配置文件为HTTP形式的URL。
[DeviceA-dhcp-pool-1] bootfile-name http://192.168.1.40/device.py
(2) 配置HTTP服务器,保证Switch A可以从HTTP服务器成功下载配置文件device.py。
# 在HTTP服务器创建配置文件device.py,文件内容如下:
#!usr/bin/python
import plathformtools
plathformtools.CLI(‘system-view ;telnet server enable ;local-user user ;password simple hello22345 ;service-type telnet ;quit ;user-interface vty 0 63 ;authentication-mode scheme ;user-role network-admin ;quit ;interface ten-gigabitethernet 1/0/1 ;port link-mode route ; ip address dhcp-alloc ;return’)
# 启动HTTP管理软件,开启HTTP服务(配置过程略)。
(1) Switch A在没有配置文件的情况下启动。启动成功后,在Device A上查看地址池中的地址绑定信息。
<DeviceA> display dhcp server ip-in-use
IP address Client identifier/ Lease expiration Type
Hardware address
192.168.1.2 0030-3030-632e-3239- Dec 12 17:41:15 2013 Auto(C)
3035-2e36-3736-622d-
4574-6830-2f30-2f32
(2) 在Device A上执行如下命令:
<DeviceA> telnet 192.168.1.2
(3) 输入用户名user、密码hello22345后,用户可以登录Switch A。
如图1-5所示,Switch A启动后自动从SFTP服务器自动获取并执行配置文件,以实现:
· 网络管理员能够通过Telnet方式登录、控制设备。
· 登录设备时需要进行认证,以提供一定的安全保证。
(1) 配置DHCP服务器
# 开启DHCP服务,创建名称为1的DHCP地址池,配置地址池动态分配IP地址的网段为192.168.1.0/24。
<DeviceA> system-view
[DeviceA] dhcp enable
[DeviceA] dhcp server ip-pool 1
[DeviceA-dhcp-pool-1] network 192.168.1.0 24
# 配置DHCP客户端远程启动配置文件为SFTP形式的URL,user和pass为SFTP 服务器中对应用户及其密码。
[DeviceA-dhcp-pool-1] bootfile-name sftp://user%dd:pass@192.168.1.40:22/device.cfg
(2) 配置SFTP服务器,保证Switch A可以从SFTP服务器成功下载配置文件device.cfg。
# 在SFTP服务器创建配置文件device.cfg,文件内容如下:
#
telnet server enable
#
local-user user
password simple hello12345
service-type telnet
quit
#
user-interface vty 0 63
authentication-mode scheme
user-role network-admin
quit
#
interface ten-gigabitethernet 1/0/1
port link-mode route
ip address dhcp-alloc
return
# 启动SFTP管理软件,开启SFTP服务(配置过程略)。
(1) Switch A在没有配置文件的情况下启动。启动成功后,在Device A上查看地址池中的地址绑定信息。
<DeviceA> display dhcp server ip-in-use
IP address Client identifier/ Lease expiration Type
Hardware address
192.168.1.2 0030-3030-632e-3239- Dec 12 17:41:15 2013 Auto(C)
3035-2e36-3736-622d-
4574-6830-2f30-2f32
(2) 在Device A上执行如下命令:
<SwitchA> telnet 192.168.1.2
(3) 输入用户名user、密码hello12345后,用户可以登录Switch A。
如图1-6所示,Switch A启动后自动从FTP服务器自动获取并执行配置文件,以实现:
· 网络管理员能够通过Telnet方式登录、控制设备。
· 登录设备时需要进行认证,以提供一定的安全保证。
(1) 配置DHCP服务器
# 开启DHCP服务,创建名称为1的DHCP地址池,配置地址池动态分配IP地址的网段为192.168.1.0/24。
<DeviceA> system-view
[DeviceA] dhcp enable
[DeviceA] dhcp server ip-pool 1
[DeviceA-dhcp-pool-1] network 192.168.1.0 24
# 配置DHCP客户端远程启动配置文件为FTP形式的URL,user和pass为FTP 服务器中对应用户及其密码。
[DeviceA-dhcp-pool-1] bootfile-name ftp://user:pass@192.168.1.40:22/device.cfg
(2) 配置FTP服务器,保证Switch A可以从FTP服务器成功下载配置文件device.cfg。
# 在FTP服务器创建配置文件device.cfg,文件内容如下:
#
telnet server enable
#
local-user user
password simple hello12345
service-type telnet
quit
#
user-interface vty 0 63
authentication-mode scheme
user-role network-admin
quit
#
interface ten-gigabitethernet 1/0/1
port link-mode route
ip address dhcp-alloc
return
# 启动FTP管理软件,开启FTP服务(配置过程略)。
(1) Switch A在没有配置文件的情况下启动。启动成功后,在Device A上查看地址池中的地址绑定信息。
<DeviceA> display dhcp server ip-in-use
IP address Client identifier/ Lease expiration Type
Hardware address
192.168.1.2 0030-3030-632e-3239- Dec 12 17:41:15 2013 Auto(C)
3035-2e36-3736-622d-
4574-6830-2f30-2f32
(2) 在Device A上执行如下命令:
<SwitchA> telnet 192.168.1.2
(3) 输入用户名user、密码hello12345后,用户可以登录Switch A。
如图1-7所示,Switch A和Switch B通过管理以太网口分别与HTTP服务器和Device A相连。Device A上开启DHCP服务。为网络中的设备动态分配192.168.1.0/24网段的IP地址。
现要求通过自动配置实现Switch A和Switch B根据脚本自动执行IRF配置的相关命令。然后再连接Switch A和Switch B之间的线缆,完成IRF的建立。
图1-7 服务器自动配置实现IRF零配置组网图
(1) 配置设备接口地址,保证设备间路由可达。
配置HTTP服务器。启动HTTP管理软件,开启HTTP服务(配置过程略)。针对IRF零配置,HTTP服务器上需要配置Python脚本文件、配置文件、sn.txt和软件启动包等文件。以下是关于各文件的介绍:
· Python脚本文件:Python脚本是设备进行IRF零配置操作的主要文件,需要管理员自行准备并保存在HTTP服务器上。Python脚本需要完成的操作:
¡ 设备判断flash是否存在足够的存储空间(可选);
¡ 设备从HTTP服务器下载配置文件;
¡ 设备从HTTP服务器下载启动软件包(可选);
¡ 设备从HTTP服务器下载sn.txt文件;
¡ 配置设备下次启动时使用的启动软件包(可选);
¡ 解析sn.txt文件并修改设备的IRF成员编号;
¡ 配置设备下次启动时使用的配置文件;
¡ 设备重新启动。
Python脚本的具体内容如下(Python脚本中标注有简单的中文注释,使用时请将中文注释删除):
#!usr/bin/python
import comware
from time import strftime,gmtime,sleep
import signal
import os
import string
import commands
import hashlib
#python_config_file_mode
#'python_static'
#python_serial_number
#U can use 2 modes to obtain the config file
#- 'python_static'
#- 'python_serial_number'
python_config_file_mode = "python_serial_number"
#配置本次软件升级设备flash所需的最小剩余空间,单位为KB
#Required space to copy config kickstart and system image in KB
required_space = 500000
#配置HTTP服务器的相关参数:用户名、密码、HTTP服务器IP地址、VPN实例名称、登录的超时时间
#transfer information
username = ""
password = ""
hostname = "192.168.1.40"
protocol = "http"
vrf = ""
config_timeout = 120
irf_timeout = 120
image_timeout = 2100
#HTTP服务器的下载路径
#Server File Path
server_path = ""
#下载到本地设备时,存放到Flash根目录下
#Loacl File path
local_path = "flash:/"
#下载到设备之后的配置文件名
#Local config name
config_local_name = "startup.cfg"
#HTTP服务器上的配置文件名
#Server config name
config_server_name = "startup.cfg"
#下载到本地的启动软件包
#Local boot name
boot_local_name = "xxxx.ipe"
#HTTP服务器上的启动软件包
#Server boot name
boot_server_name = "xxxx.ipe"
#下载到本地的SN文件名
#Local irf name
irf_local_name = "sn.txt"
#HTTP服务器上的sn文件名
#Server irf name
irf_server_name = "sn.txt"
#设备本地上记录升级日志的log文件名
python_log_name = ""
#在设备上记录升级日志的方法
#Write Log File
def write2Log(info):
global python_log_name, local_path
if python_log_name == "":
try:
python_log_name = "%s%s_python_%s_script.log" %(local_path, strftime("%Y%m%d%H%M%S", gmtime()), os.getpid())
except Exception as inst:
print inst
fd = open(python_log_name, "a")
fd.write(info)
fd.flush()
fd.close()
#删除下载到本地的文件
#Remove File
def removeFile(filename):
try:
os.remove(filename)
except os.error:
pass
#计算该设备需要删除的文件数量
#Cleanup one device temp files
def cleanDeviceFiles(str, oDevNode):
global config_local_name, boot_local_name, irf_local_name
sFilePath = getPath(oDevNode[0], oDevNode[1])
if str == "error":
removeFile("%s%s" %(sFilePath, config_local_name))
removeFile("%s%s" %(sFilePath, boot_local_name))
removeFile("%s%s" %(sFilePath, irf_local_name))
removeFile("%s%s.md5" %(sFilePath, config_local_name))
removeFile("%s%s.md5" %(sFilePath, boot_local_name))
removeFile("%s%s.md5" %(sFilePath, irf_local_name))
write2Log("\ndelete %s all files\n" %sFilePath)
print "\ndelete %s all files" %sFilePath
#Cleanup files
def cleanupFiles(str):
aSlotRange = []
if ("get_standby_slot" in dir(comware)):
aSlotRange = aSlotRange + comware.get_standby_slot()
aSlotRange.append(comware.get_self_slot())
i = 0
while i < len(aSlotRange):
if(aSlotRange[i] != None):
cleanDeviceFiles(str, aSlotRange[i])
i = i + 1
#计算设备flash上的剩余空间大小
#Verify if free space is available to download config, boot-loader image
def verifyfreespace(path):
global required_space
try:
s = os.statvfs(path)
freespace = (s.f_bavail * s.f_frsize) /1024
write2Log("\nthe %s free space is %s" %(path, freespace))
print "\n####the %s free space is %s####" %(path, freespace)
if required_space > freespace:
write2Log("\nthe %s space is not enough" % path)
print "\n####the %s space is not enough####" % path
return False
except Exception as inst:
write2Log("\nverify %s free space exception: %s" % (path, inst))
print "\n####verify %s free space exception: %s####" % (path, inst)
return False
return True
#判断设备上的剩余空间是否充足
#verify device freespace
def verifyDeviceFree(obj):
path = getPath(obj[0], obj[1])
if True != verifyfreespace(path):
return False
return True
#check all mpu free space
def verifyAllFreeSpace():
aSlotRange = []
if ("get_standby_slot" in dir(comware)):
aSlotRange = aSlotRange + comware.get_standby_slot()
aSlotRange.append(comware.get_self_slot())
bAllEnough = True
i = 0
while i < len(aSlotRange):
if(aSlotRange[i] != None) and (True != verifyDeviceFree(aSlotRange[i])):
bAllEnough = False
i = i + 1
return bAllEnough
def doExit(str):
if str == "success":
write2Log("\nThe script is running success!")
print "\n#### The script is running success! ####"
cleanupFiles("success")
comd = "reboot force"
comware.CLI(comd, False)
exit(0)
if str == "error":
write2Log("\nThe script is running failed!")
print "\n#### The script is running failed! ####"
cleanupFiles("error")
exit(1)
else:
exit(0)
#获取软件升级时chassis号和slot号参数
#get Chassis and Slot
def getChassisSlot(style):
if style == "master":
obj = comware.get_self_slot()
if len(obj) <= 0:
write2Log("\nget %s chassis and slot failed" % style)
print "\n####get %s chassis and slot failed####" % style
return None
return obj
#获取启动软件包发生错误返回的信息
#signal terminal handler function
def sig_handler_no_exit(signum, function):
write2Log("\nSIGTERM Handler while configuring boot-loader variables")
print "\n####SIGTERM Handler while configuring boot-loader variables####"
#软件升级过程发生错误时返回的信息
#signal terminal handler
def sigterm_handler(signum, function):
write2Log("\nSIGTERM Handler")
print "\n####SIGTERM Handler####"
cleanupFiles("error")
doExit("error")
#从HTTP服务器上下载文件
#transfer file
def doCopyFile(src = "", des = "", login_timeout = 10):
global username, password, hostname, protocol, vrf
print "INFO: Starting Copy of %s" % src
try:
removeFile(des)
obj = comware.Transfer(protocol, hostname, src, des, vrf, login_timeout, username, password)
if obj.get_error() != None:
write2Log("\ncopy %s failed: %s" % (src, obj.get_error()))
print "\n####copy %s failed: %s####" % (src, obj.get_error())
return False
except Exception as inst:
write2Log("\ncopy %s exception: %s" % (src, inst))
print "\n####copy %s exception: %s####" % (src, inst)
return False
write2Log("\ncopy file %s to %s success" % (src, des))
print "INFO: Completed Copy of %s" % src
return True
#Get MD5SUM from md5ConfigFile
def getMD5SumGiven(keyword, filename):
try:
file = open(filename, "r")
line = file.readline()
while "" != line:
if not string.find(line, keyword, 0, len(keyword)):
line = line.split("=")
line = line[1]
line = line.strip()
file.close()
return line
line = file.readline()
file.close()
except Exception as inst:
write2Log("\nget %s md5 exception: %s" % (filename, inst))
print "\n####get %s md5 exception: %s####" % (filename, inst)
return ""
#verify MD5SUM of the file
def verifyMD5sumofFile(md5sumgiven, filename):
if md5sumgiven == "":
write2Log("\nverify %s md5 error: the %s md5 file is error" %(filename, filename))
print "\n####verify %s md5 error: the %s md5 file is error####" %(filename, filename)
return False
try:
m = hashlib.md5()
f = open(filename, 'rb')
buffer = 8192
while 1:
chunk = f.read(buffer)
if not chunk:
break
m.update(chunk)
f.close()
md5calculated = m.hexdigest()
except Exception as inst:
write2Log("\nverify %s md5 exception: %s" % (filename, inst))
print "\n####verify %s md5 exception: %s####" % (filename, inst)
return False
if md5sumgiven == md5calculated:
return True
write2Log("\nverify %s md5 error: md5sumgiven is %s filemd5 is %s" %(filename, md5sumgiven, md5calculated))
print "\n####verify %s md5 error: md5sumgiven is %s filemd5 is %s####" %(filename, md5sumgiven, md5calculated)
return False
#Check MD5 file
def checkFile(src, dest):
src = "%s.md5" % src
destmd5 = "%s.md5" % dest
bFlag = doCopyFile(src, destmd5, 120)
if (True == bFlag) and (True == verifyMD5sumofFile(getMD5SumGiven("md5sum", destmd5), dest)):
write2Log("\ncheckFile success: %s" % destmd5)
print "\n####checkFile success: %s####" % destmd5
return True
elif (True != bFlag):
write2Log("\n%s is not exist! Don't verify the MD5 file!" % destmd5)
print "INFO: %s is not exist! Don't verify the MD5 file!" % destmd5
return True
return False
#Get config file according to the mode
def getCfgFileName():
global config_server_name
if (python_config_file_mode == "python_serial_number") and (os.environ.has_key('DEV_SERIAL')):
config_server_name = "%s.cfg" % os.environ['DEV_SERIAL']
return config_server_name
else:
return config_server_name
#copy file to all standby slot
def syncFileToStandby(sSrcFile, sFileName):
try:
aSlotRange = []
if ("get_standby_slot" in dir(comware)):
aSlotRange = aSlotRange + comware.get_standby_slot()
i = 0
while i < len(aSlotRange):
if(aSlotRange[i] != None):
sDestFile = "%s%s" %(getPath(aSlotRange[i][0], aSlotRange[i][1]), sFileName)
removeFile(sDestFile)
open(sDestFile,"wb").write(open(sSrcFile,"rb").read())
write2Log("\nsync file to standby %s" % (sDestFile))
print "\n####sync file to standby %s####" % (sDestFile)
i = i + 1
except Exception as inst:
write2Log("\nsync file to standby %s exception: %s" % (sSrcFile, inst))
print "\n####sync file to standby %s exception: %s####" % (sSrcFile, inst)
#根据脚本开始处定义的全局变量,下载启动软件包、配置文件、sn文件等
#Procedure to copy config file using global information
def copyAndCheckFile(src, dest, timeout):
global server_path, local_path
srcTmp = "%s%s" % (server_path, src)
sDestFile = "%s%s" % (local_path, dest)
if (True == doCopyFile(srcTmp, sDestFile, timeout)) and (True == checkFile(srcTmp, sDestFile)):
syncFileToStandby(sDestFile, dest)
return True
else:
srcTmp = "%sdefault_%s" %(server_path, src)
if (True == doCopyFile(srcTmp, sDestFile, timeout)) and (True == checkFile(srcTmp, sDestFile)):
syncFileToStandby(dest)
return True
return False
# split the Chassis and Slot
def splitChassisSlot(chassisID, slotID):
chassis_slot = ""
if chassisID != -1:
chassis_slot = " chassis %d" % chassisID
if slotID != -1:
chassis_slot = "%s slot %d" %(chassis_slot, slotID)
return chassis_slot
#从HTTP服务器上下载启动软件包
def copyBootImage():
global image_timeout, local_path, boot_server_name, boot_local_name
src = "%s" % boot_server_name
return copyAndCheckFile(src, boot_local_name, image_timeout)
#从HTTP服务器上下载配置文件
def copyCfgFile():
global config_timeout, local_path, config_local_name
src = "%s" % getCfgFileName()
return copyAndCheckFile(src, config_local_name, config_timeout)
#从HTTP服务器上下载sn.txt文件
def copyIrfStack():
global irf_timeout, local_path, irf_local_name, irf_server_name
src = "%s" % irf_server_name
return copyAndCheckFile(src, irf_local_name, config_timeout)
#执行boot-loader命令,为设备指定下次主用启动文件
# Procedure to Install Boot Image
def installBoot(chassis_slot, sFile, style):
result = None
write2Log("\ninstall%s%s begin" %(chassis_slot, style))
print "INFO: Install%s%s Start, Please Wait..." %(chassis_slot, style)
comd = "boot-loader file %s%s%s" % (sFile, chassis_slot, style)
try:
result = comware.CLI(comd, False)
if result == None:
write2Log("\nboot-loader file %s%s%s failed" % (sFile, chassis_slot, style))
print "\n####boot-loader file %s%s%s failed####" % (sFile, chassis_slot, style)
return False
except Exception as inst:
write2Log("\nboot-loader %s exception: %s" % (sFile, inst))
print "\n####boot-loader %s exception: %s####" % (sFile, inst)
return False
return True
#Procedure to install boot image
def installBootImage():
global boot_local_name
aSlotRange = [comware.get_self_slot()]
if ("get_standby_slot" in dir(comware)):
aSlotRange = aSlotRange + comware.get_standby_slot()
bInstallOk = True
i = 0
while i < len(aSlotRange):
sFile = "%s%s" %(getPath(aSlotRange[0][0], aSlotRange[0][1]), boot_local_name)
if False == installBoot(splitChassisSlot(aSlotRange[i][0], aSlotRange[i][1]), sFile, " main"):
bInstallOk = False
i = i + 1
return bInstallOk
#执行startup saved-configuration命令为设备指定下次启动配置文件
def startupCfg():
global local_path, config_local_name
result = None
dest = "%s%s" %(local_path, config_local_name)
write2Log("\nstartup saved-configuration %s begin" %dest)
print "INFO: Startup Saved-configuration Start"
comd = "startup saved-configuration %s main" % dest
try:
result = comware.CLI(comd, False)
if result == None:
write2Log("\nstartup saved-configuration %s failed" % dest)
print "\n####startup saved-configuration %s failed####" % dest
return False
except Exception as inst:
write2Log("\nstartup %s exception: %s" % (dest, inst))
print "\n####startup %s exception: %s####" % (dest, inst)
return False
write2Log("\nstartup saved-configuration %s success" % dest)
print "INFO: Completed Startup Saved-configuration"
return True
def getIrfCfg(line, num):
line = line.split()
number = None
if 3 == len(line):
number = line[num]
else :
number = None
return number
def getMemberID():
aMemId = comware.get_self_slot()
memId = None
if aMemId[0] == -1 :
memId = aMemId[1]
else :
memId = aMemId[0]
return memId
def getNewMemberID():
global irf_local_name, local_path, env
filename = "%s%s" %(local_path, irf_local_name)
serNum = os.environ['DEV_SERIAL']
print "\n####Test Chassis SN or Slot SN %s" % serNum
reNum = None
try:
file = open(filename, "r")
line = file.readline()
while "" != line:
if (serNum == getIrfCfg(line, 0)):
file.close()
reNum = getIrfCfg(line, 2)
return reNum
line = file.readline()
file.close()
except Exception as inst:
write2Log("\nget renumberID exception: %s" % inst)
print "\n####get renumberID exception: %s####" % inst
write2Log("\nget %s renumberID failed" % filename)
print "\n#### get %s renumberID failed ####" % filename
return reNum
#判断设备是否是处于已经建立IRF
def isIrfDevice():
try:
result = comware.CLI("display irf", False)
if result == None:
return False
except Exception as inst:
return False
return True
#解析sn.txt文件并使用renumber修改设备的IRF成员编号
def getIrfComd():
comd = None
newMemberID = getNewMemberID()
aMemId = comware.get_self_slot()
if None == newMemberID:
return None
if False == isIrfDevice():
comd = "system-view ; irf member %s ; chassis convert mode irf" % newMemberID
else:
comd = "system-view ; irf member %s renumber %s" % (getMemberID(), newMemberID)
return comd
def stackIrfCfg():
global env
if (not os.environ.has_key('DEV_SERIAL')):
write2Log("\nenviron variable 'DEV_SERIAL' is not found!")
print "\n####environ variable 'DEV_SERIAL' is not found!####"
return False
comd = getIrfComd()
if None == comd:
return False
result = None
write2Log("\nstartup stack irf begin")
print "INFO: Startup stack irf Start"
try:
result = comware.CLI(comd, False)
if result == None:
write2Log("\nstartup stack irf failed: %s" % comd)
print "\n####startup stack irf failed: %s####" %comd
return False
except Exception as inst:
write2Log("\nstartup stack irf exception: %s command: %s" % (inst, comd))
print "\n####startup stack irf exception: %s command: %s####" % (inst, comd)
return False
write2Log("\nstartup stack irf success")
print "INFO: Completed Startup Stack Irf"
return True
#check if all standby slots are ready
def ifAllStandbyReady():
if (("get_slot_range" in dir(comware)) == False):
return True
aSlotRange = comware.get_slot_range()
bAllReady = True
for i in range(aSlotRange["MinSlot"], aSlotRange["MaxSlot"]):
oSlotInfo = comware.get_slot_info(i)
if (oSlotInfo != None) and (oSlotInfo["Role"] == "Standby") and (oSlotInfo["Status"] == "Fail"):
bAllReady = False
write2Log("\nSlot %s is not ready!" %i)
print "\n####Slot %s is not ready!####" %i
return bAllReady
#if have any standby slot was not ready sleep for waiting
def waitStandbyReady():
while ifAllStandbyReady() == False:
sleep(10)
#python main
#when download file user can stop script
waitStandbyReady()
signal.signal(signal.SIGTERM, sigterm_handler)
if (True == verifyAllFreeSpace()) and (True == copyBootImage()) and (True == copyCfgFile()) and (True == copyIrfStack()):
#after download file user can not stop script
signal.signal(signal.SIGTERM, sig_handler_no_exit)
if (True == installBootImage()) and (True == startupCfg()) and (True == stackIrfCfg()):
doExit("success")
doExit("error")
· 配置文件:配置文件包含了所有设备进行IRF的相关命令,管理员可以在已经成功创建IRF的设备上,将配置文件导出并修改然后保存在HTTP服务器上,供需要创建类似拓扑IRF的设备下载使用。
· sn.txt文件:每个设备都有唯一的设备序列号,sn.txt文件根据设备的序列号来指定设备在IRF组中的成员编码。设备通过运行Python脚本来解析sn.txt文件,然后修改设备的IRF成员编号,并根据自身的成员编号来完成相应的IRF配置。
· 软件启动包:软件启动包是设备启动、运行的必备软件,需保存在HTTP服务器上。如果现有设备(包括主设备和从设备)的启动软件包全部一致且不需要升级软件版本,可不需要准备该文件。
(2) 在Device A上配置DHCP服务器
# 开启DHCP服务,创建名称为1的DHCP地址池,配置地址池动态分配IP地址的网段为192.168.1.0/24。
<DeviceA> system-view
[DeviceA] dhcp enable
[DeviceA] dhcp server ip-pool 1
[DeviceA-dhcp-pool-1] network 192.168.1.0 24
# 配置DHCP客户端远程启动配置文件为HTTP形式的URL。
[DeviceA-dhcp-pool-1] bootfile-name http://192.168.1.40/device.py
[DeviceA-dhcp-pool-1] quit
# 配置接口Ten-GigabitEthernet1/0/1工作在DHCP服务器模式。
[DeviceA] interface ten-gigabitethernet 1/0/1
[DeviceA-Ten-GigabitEthernet1/0/1] dhcp select server
[DeviceA-Ten-GigabitEthernet1/0/1] quit
(3) 设备根据DHCP服务器获取到Python脚本文件,执行Python脚本下载配置文件和软件启动包;解析sn.txt文件生成IRF成员编号。然后,所有设备会执行重启操作。
(4) 设备重启完毕后,连接Switch A和Switch B之间的线缆,连接好线缆后设备将进行IRF选举,选举失败的一台设备会再次重启。当设备自动重启后,Switch A和Switch B成功组成IRF。
下面以Switch A为例验证设备是否成功组成IRF,Switch B和Switch A类似,不再赘述。
# 显示IRF中所有成员设备的相关信息。
<Switch A> display irf
MemberID Slot Role Priority CPU-Mac Description
1 1 Standby 1 00e0-fc0f-8c02 ---
*+2 1 Master 30 00e0-fc0f-8c14 ---
--------------------------------------------------
* indicates the device is the master.
+ indicates the device through which the user logs in.
The Bridge MAC of the IRF is: 000c-1000-1111
Auto upgrade : yes
Mac persistent : always
Domain ID : 0
Auto merge : yes
以上显示信息表明IRF已经成功建立。
不同款型规格的资料略有差异, 详细信息请向具体销售和400咨询。H3C保留在没有任何通知或提示的情况下对资料内容进行修改的权利!