antiCisco blogs


блоги по технологиям и оборудованию cisco от инструкторов

Опубликовано 2 Март , 2012

К сожалению, большая часть сетевого оборудования не имеет никакого API для удаленного управления, а если имеет, то зачастую написание клиента ради отправки нескольких команд совершенно не оправдывает затраченных усилий.

К счастью, уже давно существует инструмент для автоматизации таких задач под названием expect. А еще существует более удобная обертка к нему под названием expect-lite, которую мы сегодня и рассмотрим. Для примера мы напишем скрипт, который будет будет заводить порты коммутатора в нужный нам VLAN.

Добываем софт

  1. Ставим expect. Системно-зависимо, для UNIX есть в репозитариях/портах, для винды есть сборка с cygwin на сайте из пункта 2.
  2. Качаем expect-lite с сайта авторов, распаковываем, кладем файл expect-lite в нужное нам место.

Основы

По сути, expect умеет отправлять строки, принимать что-то обратно и выполнять действия на основании принятого. Отправляемые строки начинаются с символом «>>», ожидаемые строки или содержащиеся в них выражения с «<». Если ожидаемая строка не приходит, скрипт завершается. Если использовать «<<» вместо «<», expect будет ожидать точного совпадения полученной строки с указанной. Все, что начинается с «#» считается комментарием и игнорируется.

Скрипту можно передавать параметры в виде аргументов expect-lite вида «var1=value1 var2=value2 …» и потом ссылаться на них в скрипте через $var1 и так далее.

Приступаем

Логинимся на железку

Создадим файл типа portsetup.els и напишем в него следующее:

>>telnet $host
<Username
>>$user
<Password
>>$password
<>
>>enable
<Password
>>$enablePassword
<#

Будем считать, что коммутатор живет по адресу 10.91.19.2, и на нем есть юзер cisco с паролем cisco. Попробуем выполнить:

./expect-lite host=10.91.19.2 user=cisco password=cisco enablePassword=cisco ./portsetup.els

Смотрим на результат:

Const: host = 10.91.19.2
Const: user = cisco
Const: password = cisco
Const: enablePassword = cisco
Warning: Remote Host=none, using Localhost
spawn bash
INFO: CONST FOUND: host = 10.91.19.2

[dmbaturin@arcueid:~/bin/expect-lite]$ telnet 10.91.19.2
Trying 10.91.19.2...
Connected to 10.91.19.2.
Escape character is '^]'.


User Access Verification

Username: INFO: CONST FOUND: user = cisco
cisco
Password: INFO: CONST FOUND: password = cisco


switch>enable
Password: INFO: CONST FOUND: enablePassword = cisco

switch#exit 
Connection closed by foreign host.
[dmbaturin@arcueid:~/bin/expect-lite]$ 

##Overall Result: PASS 

Скрипт успешно пообщался с железкой на тему аутентификации. Можно сразу заметить важную особенность: expect игнорирует все полученные строки, кроме явно указанных к ожиданию.

Приступаем к действиям

И тут мы сразу сталкиваемся с проблемой выбора. Порт может быть trunk или access, не писать же два разных скрипта для них. Для этой цели в expect-lite есть условия. Выглядят они следующим образом:

? условие ? действие если условие верно :: действие если условие неверно

Команды можно группировать с помощью квадратных скобок. С группами команд с обеих частях условия у expect-lite какие-то проблемы, поэтому лучше использовать два условия.

# Clear existing config
>>default interface $intf
<(config)

# Enter interface config
>>nterface $intf
<(config-if)

# Access mode
? $mode == access ? [ 
                        >>switchport mode access
                        <(config-if)
                        >>switchport access vlan $vlan
                        <(config-if)
                    ]   

# Trunk mode
? $mode == trunk ? [ 
                         >>switchport mode trunk
                         <(config-if)
                         >>switchport trunk allowed vlan $vlan
                         <(config-if)
                    ]   

Добавим к этому корректный выход:

>>exit
<(config)
>>exit
<#
>>exit

# Команда *TERM завершает работу скрипта
*TERM

Собираем все вместе

*NOWARN
*NODEBUG
*NOINFO
*NOEXP_INFO

# Login to the switch
>>telnet $host
<Username
>>$user
<Password
>>$password
<>

# Enter privileged mode
>>enable
<Password
>>$enablePassword
<#

# Enter configuration mode
>>configure terminal
<(config)

# Clear interface config
>>default interface $intf
<(config)

# Enter interface config
>>interface $intf
<(config-if)

# Configure access mode
? $mode == access ? [
		        >>switchport mode access
                        <(config-if)
			>>switchport access vlan $vlan
			<(config-if)
		    ]

# Configure trunk mode
? $mode == trunk ? [
			 >>switchport mode trunk
			 <(config-if)
			 >>switchport trunk allowed vlan $vlan
			 <(config-if)
         	   ]

# Exit properly
>>exit
<(config)
>>exit
<#
>>exit

# Terminate the script
*TERM

Четыре команды в начале скрипта уменьшают количество выводимых отладочных сообщений до минимума.

Пробуем запустить:

./expect-lite host=10.91.19.2 user=cisco password=cisco enablePassword=cisco mode=access vlan=10 intf="fa 0/19" ./portsetup.els
Const: host = 10.91.19.2
Const: user = cisco
Const: password = cisco
Const: enablePassword = cisco
Const: mode = access
Const: vlan = 10
Const: intf = fa 0/19
Warning: Remote Host=none, using Localhost
spawn bash

expect-lite directive: *NOWARN 

expect-lite directive: *NODEBUG 

expect-lite directive: *NOINFO 

expect-lite directive: *NOEXP_INFO 

[dmbaturin@arcueid:~/bin/expect-lite]$ telnet 10.91.19.2
Trying 10.91.19.2...
Connected to 10.91.19.2.
Escape character is '^]'.

User Access Verification

Username: cisco
Password: 

switch>enable
Password: 
switch#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
switch(config)#default interface fa 0/19
Interface FastEthernet0/19 set to default configuration
switch(config)#interface fa 0/19
switch(config-if)#switchport mode access
switch(config-if)#switchport access vlan 10
switch(config-if)#exit
switch(config)#exit
switch#
expect-lite directive: *TERM 

Для большинства целей должно хватить. А для дальнейшего ознакомления на сайте автора есть подробная документация.

 

Метки:
Опубликовано: Без рубрики

 

One Response to “Автоматизация с expect-lite”

comment rss - Trackback

  1. Супер, спасибо Дань за просвещение!

    Так глядишь и я перестану бояться программирования 🙂

» Оставить комментарий

Вы должны войти чтобы прокомментировать.