В момент появления поддержки тега {% pyhotn %}, тут была блогозапись как этим пользоваться, но очень слабый пример, только поверхностно затронута мощь этого инструмента. На сколько я понимаю определение сниппета, это механизм позволяющий с помощью шаблона выполнять автоматически однообразные действия. Для меня это настройка клиентских портов под интернет, очень много однотипных действий, поэтому взялся написать сниппет это автоматизирующий. Собственно хочу его представить

{% load python %}
{% var cmd internal %}
{% var Client str %}
{% var po str %}
{% var id str %}
{% var speed str %}
{% python %}
from noc.inv.models import *
from noc.sa.models import *
from noc.ip.models import *
from noc.lib.ip import IP
from noc.lib.text import split_alnum

i = Interface.objects.filter(managed_object=context["object"].id, type="physical")
free_interface=""
for interface in sorted(i, key=lambda x: split_alnum(x.name)):
    if interface.description==None or interface.description.split(" ")[0]=="was":
        free_interface=interface.name
        iface=interface
        break

if free_interface=="":
    raise Exception('No free interface found')

p = Prefix.objects.filter(vrf=12, Prefix_group="Clients-p2p", afi=4)
free = []
for pref in p:
    for free_preffix in pref.iter_free():
        free += {free_preffix}  
    try:
        if free[0]:
            break
    except:
        pass

ip_prefix = str(free[0]).split('/')[0].split('.')
ip_gw = str(ip_prefix[0]) + "." + str(ip_prefix[1]) + "." + str(ip_prefix[2]) + "." + str(int(ip_prefix[3])+1)
new_prefix=str(free[0]).split('/')[0]+"/30"
domain_name=context["object"].name + "-" + "-".join("-".join(free_interface.split("/")).split(" ")) + ".a.ru"
iface.description=context["Client"]

iface.profile=InterfaceProfile.objects.get(name="UNI").id 
Prefix(prefix=new_prefix, vrf=VRF.objects.get(id=12), description=context["Client"], Project=int(context["po"]), Channel_ID=int(context["id"])).save()
Address(address=ip_gw, fqdn=domain_name, vrf=VRF.objects.get(id=12)).save()
iface.save()

context["cmd"]="configure terminal\n"
context["cmd"]+="interface " + free_interface + "\n"
context["cmd"]+=" description " + context["Client"] + " po-" + context["po"] + " id-" + context["id"] + "\n"
context["cmd"]+=" no switchport\n no shutdown\n"
context["cmd"]+=" ip access-group fromclient in\n"
context["cmd"]+=" ip address " + ip_gw + " 255.255.255.252\n"
context["cmd"]+=" no snmp trap link-status\n"
if not " " in context["speed"]:
    context["cmd"]+=" service-policy input " + context["speed"] + "-in\n"
    context["cmd"]+=" service-policy output " + context["speed"] + "-out\n"
context["cmd"]+="end\n"
context["cmd"]+="write\n"
context["cmd"]+="show running-config interface " + free_interface
{% endpython %}
{{cmd}}

Получилось полсотни строк.

Некоторые пояснения.

14 - 20 строки ищем свободный интерфейс. то есть сначала загружаем в i все интерфейсы у выбранного МО, потом идем в цикле в поисках первого где  дескрипшен будет пустой или начинаться со слова "was" (у нас это значит что какой-то клиент раньше был на этом порту но уже отключился), как только нашли интерфейс, то записываем его и прекращаем это безобразие.

25 - 34 - задачка посложнее была, но тоже решилось, здесь мы ищем свободный префикс /30. У меня все большие сети откуда выдаются клиентам адреса помещены в группу Clients-p2p (это мой custom field), хотел фильтровать по тегу, но что-то не заработало. а дальше с помощью iter_free ищем что у нас не занято. Работает несколько неоптимально, можно было бы выходить из цикла когда нашел первый свободный, а не продолжать выбирать все из префикса, но я не захотел ломать то что уже заработало.

дальше идут некоторые преобразования чтобы получить нужные параметры

ip_prefix - это сам найденый свободный префикс без маски, приведенный к списку октетов (этого наверное не стоило делать, 
да и вообще тут большое поле для оптимизаций)
ip_gw - ip который мы настраиваем на интерфейсе

new_prefix - тут дело вот в чем, свободные префиксы ищутся с максимально короткой маской, поэтому найденую маску приходится срезать и жестко приделывать /30

domain_name - ипользуется для сохранения в ипам адреса который мы настроили

Далее сохраняем все в БД, прописываем дескрипшен для интерфейса в инвентори, чтобы не занять интерфейс второй раз и не ждать пока сработает дискавери, сохраняем префикс в ипам (думаю не надо объяснять зачем мы это делаем), и собственно адрес, адрес я сохраняю потому, что дискавери и fqdn_template очень страшно генерят fqdn. Неудобство есть небольшое, запись в БД происходит в момент выполнения питона и если где-то произошла опечатка, то даже если еще не подтвердил выполнение команд на железе, данные в ИПАМ и Инвентори уже попали

И собственно формируем список команд которые надо выполнить, вообще их можно было перечислить вне тега питона и просто передать в них нужные переменные, но тогда мне не удастся исключать резалку скорости, когда ограничения не требуется (пользователь ставит просто пробел в поле для ввода переменной speed).

Собственно вся концепция на лицо, есть правда поле для исправлений и дополнений, например надо сделать исключение чтобы он не пытался занимать management интерфейсы, или поправить баг, почему-то он пытается занять 2 порта, хотя вроде на тестовом каталисте все работает нормально (это надо еще помедитировать).