Что такое Tcl
Tcl (читается «тикль», иногда «текл») — интерпретируемый язык программирования, разработанный в конце 80-х для встраивания в консольные приложения. Спектр возможностей современного Tcl довольно широк: тут и поддержка ООП, и развитые средства regexp, динамические массивы и т.д.
Реализация этого языка в устройствах Cisco имеет несколько вариантов:
- Интерпретатор Tcl с интерфейсом командной строки. Встроен в разные версии платформы Cisco IOS, включая IOS XE и XR и доступен для широкой линейки устройств. Позволяет выполнять команды Tcl, запускать готовые скрипты в виде файлов и т.д. Устройства, использующие в качестве операционной системы не IOS а, например, Cat OS или ASA (в одноименном брандмауэре) командной строки интерпретатора не содержат.
- Т.н. «встроенный менеджер событий» или EEM — система отслеживания событий, позволяющая автоматически на них реагировать в режиме реального времени. Например, осуществлять мониторинг удаленного хоста с уведомлением по e-mail. EEM-сценарии (аплеты) пишутся на Tcl, но сам EEM не предоставляет отдельной командной строки Tcl. Пример использования см. тут. EEM доступен на платформе Nexus (NX OS) и ASA с версии 9.2(1) и выше.
- Системы голосового меню IVR (Interactive Voice Responce).
Как определить наличие командного интерпретатора зная модель устройства либо версию IOS? Для этого существует Cisco Feature Navigator:
Пункт меню Research Features позволяет выбрать конкретную версию IOS для заданного IOS Train Release или конкретной аппаратной платформы. Пункт меню Research Software позволяет найти все версии IOS с поддержкой Tcl для заданного hardware. Кликаем, фильтруем поле Filter by по названию (Feature name) «Cisco IOS scripting w/ Tcl» (или просто «Tcl»), название фичи добавляем в список, выбираем Train release и получаем список всех версий IOS, содержащих данную фичу:
К сожалению, база CFN неполная и иногда не показывает всю информацию. Так, для платформы CAT2960S навигатор показал наличие Tcl в релизе IOS 15.2E1 и не показал в релизе 15.2E9, хотя по факту интерпретатор Tcl есть и там, и там.
Что же можно сделать в Cisco IOS используя Tcl? Довольно много: просматривать и изменять конфигурацию, создавать интерактивные сценарии, оперировать объектами MIB и даже… написать целый веб-шелл!
В общем виде программа на языке Tcl содержит последовательность команд, разделенных переводом строки или точкой с запятой. Пример, не требующий пояснений:
puts "Hello, world!"; puts "My first Tcl IOS script!"
Некоторые операторы:
#
комментарий до конца строки
set a 1
приcвоение a=1
$a
получение значения переменной
{ }
блочный оператор — определяет тело цикла или условия
[ ]
оператор подстановки — при выполнении вместо квадратных скобок будет подставлено вычисленное значение содержащегося в них выражения
== <= <>
операторы сравнения
puts "text"
вывод строки «text» в stdout (т.е., на консоль)
puts $a
аналогично для значения переменной a
gets stdin
читает значения из консоли
set a [gets stdin]
ввод значения из консоли и присвоение его переменной a
for {set i 1} {$i < 10} {inrc i} {....}
цикл for
Более полный список см. progopedia.ru/language/tcl
Интерпретатор Tcl запускается командой tclsh из priveleged EXEC-режима:
sw#Tclsh
sw(tcl)#
Выполним первый скрипт:
Tcl чувствителен к регистру, поэтому Puts "Hello, world"
вызовет ошибку, а вот регистр команд оболочки IOS неважен. Все вводимые команды сначала обрабатываются интерпретатором Tcl, если введенная команда является исполнимой с т.з. Tcl, она исполняется и результат выводится на устройство TTY. Если команда не может быть выполнена интерпретатором, она передается парсеру команд IOS. Т.о., один скрипт может комбинировать операторы Tcl и команды IOS. Cреда IOS не содержит полноценного текстового редактора, поэтому pre-defined скрипты нужно создавать внешними средствами и уже потом копировать на flash или в память. Запуск файла со скриптом на выполнение осуществляется командой
tclsh flash:filename
Допустимы множественные сеансы интерпретатора Tcl из разных сессий TTY.
Внутренние команды интерпретатора Tcl:
exec — выполняет заданную в кавычках команду из набора IOS CLI priveleged EXEC.
sw(tcl)#exec "show int fa0"
выдаст:
ios-config — выполняет команду из global configuration mode. За ней в отдельных парных кавычках указываются все последующие команды sub-configuration. Например:
sw(tcl)#ios_config "int fa0" "ip address 192.168.0.1 255.255.255.0" "no shut"
эквивалентно серии команд IOS:
sw#conf te
sw(config)#int fa0
sw(conf-int)#ip address 192.168.0.1 255.255.255.0
sw(conf-int)#no shut
Тикль не поддерживает типизацию, это надо помнить, оперируя с переменными:
Вложенный оператор [expr {..}]
вычислит значение выражения, заданного в фигурных скобках ($a + $b) и выполнит подстановку этого значения вместо квадратных скобок.
Теперь перейдем к решению практической задачи. Перед нами 48-ми портовый Cat2950S «из коробки». Скрипт, приведенный ниже
- запрашивает с консоли порядковый номер свича sw_num
- задает для него hostname вида switch_<sw_num>
- запрашивает и устанавливает пароль на консоль priveleged EXEC
- настраивает в соответствии с введенным номером свича адрес на его интерфейсе управления Fa0 (192.168.0.х) и интерфейсе Vlan1 (10.0.х.254)
- создает port-based DHCP reservation и пул из 48 адресов, в котором за каждым клиентом зарезервирован один IP-адрес, младший октет которого равен порядковому номеру порта, через который это клиент подключен.
puts "Enter Switch number:"
set sw_num [gets stdin]
ios_config "hostname switch_$sw_num"
puts "Enter password (secret):"
set pass [gets stdin]
ios_config "enable secret 0 $pass"
ios_config "line 0 16" "password 0 $pass" "login"
ios_config "int fa0" "ip address 192.168.0.$sw_num 255.255.255.0" "no shut"
ios_config "int vlan1" "ip address 10.0.$sw_num.254 255.0.0.0" "no shut"
ios_config "ip dhcp use subscriber-id client-id"
ios_config "ip dhcp subscriber-id interface-name"
#перебираем в цикле все 48 портов и для каждого задаем опцию subscriber-id
for {set i 1} {$i <= 48} {incr i} {ios_config "int Gi1/0/$i" "ip dhcp server use subscriber-id client-id"}
ios_config "ip dhcp pool POOL1" "network 10.0.0.0 255.0.0.0" "reserved-only" "default-router 10.10.0.254"
# записываем в пул 48 зарезервированных IP-адресов, привязанных к соотв. порту
for {set i 1} {$i <= 48} {incr i} {ios_config "ip dhcp pool POOL1" "address 10.0.$sw_num.$i client-id Gi1/0/$i ascii"}
#
Примечание 1. В этом скрипте есть небольшая логическая ошибка. Попробуйте её найти.
Примечание 2. Некоторые текстовые редакторы любят помещать в конце файла непечатаемый символ EoF. Его можно увидеть в консоли IOS, выведя содержимое файла командой cat или more. Наткнувшись на EoF, интерпретатор Tcl выдаст ошибку и проигнорирует всю строку. Поэтому я оставил в конце скрипта экранирующий знак комментария.
Возникает вопрос: а как же записать скрипт в память коммутатора с ненастроенным IP работая только через консольный порт? Не набирать же скрипт руками! Неужели каждый раз вручную настраивать Management Interface и пользоваться FTP? Нет, можно проще. Cisco IOS умеет копировать файлы прямо через последовательный порт консоли по протоколу Xmodem и сохранять их на флеш. Для этого вам понадобится эмулятор терминала с поддержкой Xmodem, например, ZOC или Tera Term (а вот популярный бесплатный Putty, увы, не подойдет!). Копирование выполняется командой IOS copy xmodem: flash:filename , после чего нужно выполнить File Transfer в меню эмулятора терминала:
Также это можно сделать находясь в ROMmon (например, если вы «сносите» конфиг коммутатора, не имея пароля на priveleged EXEC). А вот обратное копирование файлов (с флэш-памяти коммутатора на ПК) не поддерживается.
На этом краткий экскурс в возможности языка Tcl на платформе Cisco IOS завершен, изучить вопрос более подробно вы можете в документе «Cisco IOS Scripting with TCL Configuration Guide» доступном на сайте Cisco.
Комментариев нет:
Отправить комментарий