Курс от Наташки: Интересные задачи и их решение

Курс от Наташки: Интересные задачи и их решение

 
"""
Задание 20.5a
Создать функцию configure_vpn, которая использует
шаблоны из задания 20.5 для настройки VPN на маршрутизаторах
на основе данных в словаре data.
Параметры функции:
* src_device_params - словарь с параметрами подключения к устройству 1
* dst_device_params - словарь с параметрами подключения к устройству 2
* src_template - имя файла с шаблоном, который создает конфигурацию для строны 1
* dst_template - имя файла с шаблоном, который создает конфигурацию для строны 2
* vpn_data_dict - словарь со значениями, которые надо подставить в шаблоны
Функция должна настроить VPN на основе шаблонов
и данных на каждом устройстве с помощью netmiko.
Функция возвращает кортеж с выводом команд с двух
маршрутизаторов (вывод, которые возвращает метод netmiko send_config_set).
Первый элемент кортежа - вывод с первого устройства (строка),
второй элемент кортежа - вывод со второго устройства.
При этом, в словаре data не указан номер интерфейса Tunnel,
который надо использовать.
Номер надо определить самостоятельно на основе информации с оборудования.
Если на маршрутизаторе нет интерфейсов Tunnel,
взять номер 0, если есть взять ближайший свободный номер,
но одинаковый для двух маршрутизаторов.
Например, если на маршрутизаторе src такие интерфейсы: Tunnel1, Tunnel4.
А на маршрутизаторе dest такие: Tunnel2, Tunnel3, Tunnel8.
Первый свободный номер одинаковый для двух маршрутизаторов будет 5.
И надо будет настроить интерфейс Tunnel 5.
Для этого задания тест проверяет работу функции на первых двух устройствах
из файла devices.yaml. И проверяет, что в выводе есть команды настройки
интерфейсов, но при этом не проверяет настроенные номера тунелей и другие команды.
Они должны быть, но тест упрощен, чтобы было больше свободы выполнения.
"""
import yaml
from jinja2 import Environment, FileSystemLoader
import os
from netmiko import ConnectHandler
import re
data = {
    "tun_num": None,
    "wan_ip_1": "192.168.100.1",
    "wan_ip_2": "192.168.100.2",
    "tun_ip_1": "10.0.1.1 255.255.255.252",
    "tun_ip_2": "10.0.1.2 255.255.255.252",
}
def create_vpn_config(template1, template2, data_dict):
    tmpl = [template1, template2]
    out = []
    for i in tmpl:
        template_dir, template_file = os.path.split(i)
        env = Environment(
            loader=FileSystemLoader(template_dir),
            trim_blocks=True, lstrip_blocks=True)
        template = env.get_template(template_file)
        output = template.render(data_dict)
        out.append(output)
    return out
def check_tun_intf(check_output1, check_output2):
    check_output = [check_output1, check_output2]
    # print('check_output = ', check_output)
    regex = r"Tunnel(\d+)"
    tunn_list = []
    for i in check_output:
        tn = re.findall(regex, i)
        if tn:
            [tunn_list.append(int(j)) for j in tn]
        else:
            # Tunnel interface not found
            tunn_list.append(0)
    tunn_list = list(set(tunn_list))
    for n in range(len(tunn_list) - 1):
        if tunn_list[n + 1] - tunn_list[n] > 1:
            tunn_number = tunn_list[n] + 1
            break
    # print('tunn_number = ', tunn_number)
    return tunn_number
def configure_vpn(src_device_params, dst_device_params,
                  src_template, dst_template, vpn_data_dict):
    test_cmd = "show ip interface brief"
    with ConnectHandler(**src_device_params) as src_dev, \
            ConnectHandler(**dst_device_params) as dst_dev:
        src_dev.enable()
        dst_dev.enable()
        test_out1 = src_dev.send_command(test_cmd)
        test_out2 = dst_dev.send_command(test_cmd)
        vpn_data_dict['tun_num'] = str(check_tun_intf(test_out1, test_out2))
        # print(vpn_data_dict)
        dev_tmpl = create_vpn_config(src_template, dst_template, vpn_data_dict)
        # print(dev_tmpl)
        src_cmd = dev_tmpl[0].split('\n')
        dev_cmd = dev_tmpl[1].split('\n')
        src_dev_out = src_dev.send_config_set(src_cmd)
        dst_dev_out = dst_dev.send_config_set(dev_cmd)
        # print(src_dev_out, dst_dev_out)
    return src_dev_out, dst_dev_out
if __name__ == "__main__":
    template1 = "templates/gre_ipsec_vpn_1.txt"
    template2 = "templates/gre_ipsec_vpn_2.txt"
    data_dict = data
    with open("devices.yaml") as f:
        devices = yaml.safe_load(f)
    src_device_params = devices[0]
    dst_device_params = devices[1]
    # print(configure_vpn(src_device_params, dst_device_params, template1, template2, data_dict))
    configure_vpn(src_device_params, dst_device_params, template1, template2, data_dict)

 

#### devices.yaml
- device_type: cisco_ios
  host: 192.168.122.10
  username: cisco
  password: cisco
  secret: cisco
  timeout: 10
  #fast_cli: true
- device_type: cisco_ios
  host: 192.168.122.11
  username: cisco
  password: cisco
  secret: cisco
  timeout: 10
  #fast_cli: true
- device_type: cisco_ios
  host: 192.168.122.12
  username: cisco
  password: cisco
  secret: cisco
  timeout: 10
  #fast_cli: true