Продолжаю нашу тему фреймворков для тестирования инфраструктры. Сегодня мой пост является беглым отчетом по выполнению работы "7.6.3 Lab - Automated Testing Using pyATS and Genie" из Cisco DevNet.
Знакомтесь - pyATS (https://developer.cisco.com/pyats/). Это экосистема сквозного тестирования, изначально разработанная компанией Cisco и ставшая открытой в конце 2017 года. Ранее библиотека pyATS называлась Genie; эти названия используются в одном и том же контексте. Ввиду своего происхождения этот фреймворк целиком и полностью ориентирован на тестирование сетей.
Фреймворк доступен в PyPI:
(venv) $ pip install pyats[full]
Для начала рассмотрим некоторые демонстрационные сценарии из GitHub-репозитория:
git clone https://github.com/CiscoTestAutomation/examples
Мы сходу можем прогнать тест-пустышку чтобы оценить как все происходит:
pyats run job examples/basic/basic_example_job.py
Следом можно охватить отчетность по всем проведенным PyATS-тестам в формате HTML:
pyats logs view
P.S.: имейте ввиду - порт web-сервера отчетов динамический.
Ок, реальные тесты начинаются с создания файла испытательной модели (testbed) в формате YAML. Создадим простой testbed-файл testbed-pyats.yml для нашего устройства CSR1000v. Он похож на файл реестра hosts, знакомый нам от Ansible:
testbed:
name: pyATS
credentials:
default:
username: admin
password: super
enable:
password: super
devices:
CSR:
alias: CSR
type: iosxe
connections:
defaults:
class: unicon.Unicon
vty:
ip: 192.168.1.19
protocol: ssh -o KexAlgorithms=diffie-hellman-group14-sha1
В нашем первом сценарии, pyats_1.py, мы загрузим testbed-файл, подключимся к устройству, выполним команду show version и затем отключимся от устройства:
from pyats.topology import loader
# load testbed
testbed = loader.load('yaml/testbed-pyats.yml')
# access the device
testbed.devices
ios_1 = testbed.devices['CSR']
# establish connectivity
ios_1.connect()
# issue command
print(ios_1.execute('show version'))
# disconnect
ios_1.disconnect()
Запустив этот сценарий, мы увидим смесь из сообщений о подготовке pyATS и вывода самого устройства. Это похоже на сценарии Paramiko, которые мы видели ранее, но в данном случае соединение устанавливает pyATS:
(venv) $ python pyats_1.py
[2019-11-10 08:11:55,901] +++ CSR logfile /tmp/ CSR-default-
20191110T081155900.log +++
[2019-11-10 08:11:55,901] +++ Unicon plugin generic +++
<опущено>
[2019-11-10 08:11:56,249] +++ connection to spawn: ssh -l cisco
172.16.1.20, id: 140357742103464 +++
[2019-11-10 08:11:56,250] connection to CSR
[2019-11-10 08:11:56,314] +++ initializing handle +++
[2019-11-10 08:11:56,315] +++ CSR: executing command 'term length 0' +++
term length 0 CSR#
[2019-11-10 08:11:56,354] +++ CSR: executing command 'term width 0' +++
term width 0 CSR#
[2019-11-10 08:11:56,386] +++ CSR: executing command 'show version' +++
show version
<опущено>
Второй пример более развернутый. Он включает настройку и установку соединения, сами тесты и последующее отключение от устройства. В сценарии pyats_2.py используются различные декораторы из модуля aetest, входящего в состав pyATS. Помимо методов подготовки и очистки, в классе PingTestCase имеется тест ping:
from pyats import aetest
import re
class CommonSetup(aetest.CommonSetup):
@aetest.subsection
def establish_test(self, testbed, iosv1_name = 'CSR'):
ios1 = testbed.devices[iosv1_name]
self.parent.parameters.update(ios1 = ios1)
@aetest.subsection
def establish_connections(self, steps, ios1):
with steps.start('Connecting to %s' % ios1.name):
ios1.connect()
@aetest.loop(device = ('ios1',))
class PingTestcase(aetest.Testcase):
@aetest.test.loop(destination = ('192.168.1.180','192.168.1.3'))
def ping(self, device, destination):
try:
result = self.parameters[device].ping(destination)
except Exception as e:
self.failed('Ping {} from device {} failed with error: {}'.format(
destination,
device,
str(e),
),
goto = ['exit'])
else:
match = re.search(r'Success rate is (?P<rate>\d+) percent', result)
success_rate = match.group('rate')
class CommonCleanup(aetest.CommonCleanup):
@aetest.subsection
def disconnect(self, steps, ios1):
with steps.start('Disconnecting from %s' % ios1.name):
ios1.disconnect()
if __name__ == '__main__':
import argparse
from pyats.topology import loader
parser = argparse.ArgumentParser()
parser.add_argument('--testbed', dest = 'testbed', type = loader.load)
args, unknown = parser.parse_known_args()
aetest.main(**vars(args))
На практике предпочтительнее передавать testbed-файл как аргумент командной строки:
(venv) $ python pyats_2.py --testbed testbed_pyats.yml
Вывод этого сценария похож на тот, что мы видели в предыдущем примере, если не считать дополнительных разделов STEPS Report и Detailed Results в каждом тесте. В выводе также указано имя журнального файла, сохраненного в каталоге /tmp:
Фреймворк pyATS отлично подходит для автоматизированного тестирования. Но, учитывая его происхождение, ему не хватает поддержки других производителей, окромя Cisco.
Мы еще можем использовать фреймворк Genie которая позволяет парсить вывод IOS в формате JSON. Если вы ставили PyATS то Genie у вас уже присутствует. Также Genie позволяет зашифровать пароли в testbed. Первое что мы сделаем это создадим новый testbed в диалоговом режиме:
genie create testbed interactive --output yaml/testbed.yml --encode-password
где
- Device hostname - имя нашего подопытного устройства, мое CSR
- IP address - его IPv4 address
- Username - local username used for ssh
- Default password - local password used for ssh
- Enable password - у меня совпадает с default
- Protocol - указываю SSH
- OS - указываю iosxe.
Мы получим в итоге файлик yaml/testbed.yml такого содержания:
devices:
CSR:
connections:
cli:
ip: 192.168.1.19
protocol: ssh -o KexAlgorithms=diffie-hellman-group14-sha1
credentials:
default:
password: '%ENC{w53DmsOUw6jDmMOR}'
username: admin
enable:
password: '%ENC{w53DmsOUw6jDmMOR}'
os: iosxe
type: iosxe
Далее можем запросить что угодно с CSR. Собственно вы можете видеть что Genie пересылает
наши команды устройству и читает ответы на них:
genie parse "show ip interface brief" --testbed-file yaml/testbed.yml --devices CSR
или
genie parse "show version" --testbed-file yaml/testbed.yml --devices CSR
Еще одна полезная возможность это сравнивать конфигурации До и После. Переведем вывод запроса в файл:
genie parse "show ipv6 interface gig 1" --testbed-file yaml/testbed.yml --devices CSR --output verify-ipv6-1
Что-то поменяем в ipv6 и выполним запрос еще раз:
genie parse "show ipv6 interface gig 1" --testbed-file yaml/testbed.yml --devices CSR --output verify-ipv6-2
А теперь смотрим разницу:
genie diff verify-ipv6-1 verify-ipv6-2
На десерт - существует еще один открытый инструмент для проверки сетей Batfish от IntentionNet (https://github.com/batfish/batfish). Его прямое назначение - проверка изменений в конфигурации перед развертыванием. И он может цепляться не только к Cіsco!)
Вот собственно и все. Пользуйтесь и удачи.
genie validate testbed testbed.yml
ReplyDelete