ttp
ttp copied to clipboard
ttp not working inside a function
Hi there, I'm having an issue with ttp as it's working fine when the Netmiko call is in the main body, but when I move all the code, including the Netmiko call, inside a function the dictionary returned is empty. Or even if I move ttp code to a function, and keep Netmiko call on the amin one, sending data through a function. BUT, if instead using Netmiko to get the data I use plain text as data input, it works either way inside or outside a function.
Script with Netmiko and no Function returns proper dict:
from ttp import ttp
from netmiko import ConnectHandler
import json
emea_cred = 'admin'
emea_psw = 'Password0'
device = {"device_type":"cisco_ios","ip":"10.1.1.1","username":emea_cred,"password":emea_psw,"fast_cli":"False"}
with ConnectHandler(**device) as net_connect:
wlc_hostname = net_connect.find_prompt()[:-1]
data = net_connect.send_command('show run | inc (^wlan.+)_([0-9]+)_([A-Za-z0-9]+)$')
print (data)
template = """
<template name="wlan_profile_summ">
<group name="{{ wlan_profile }}">
wlan {{ wlan_profile | _start_ }} {{ wlan_id }} {{ ssid }}
</group>
</template>
"""
parser2 = ttp(data, template)
parser2.parse()
cisco_wlanTemplates2 = parser2.result(structure="flat_list")
print(json.dumps(cisco_wlanTemplates2, sort_keys=True, indent=5, separators=(',', ': ')))
Script with Netmiko inside Function returns empty dict:
from ttp import ttp
from netmiko import ConnectHandler
import json
def parse_cisco_wlans():
emea_cred = 'admin'
emea_psw = 'Password0'
device = {"device_type":"cisco_ios","ip":"10.1.1.1","username":emea_cred,"password":emea_psw,"fast_cli":"False"}
with ConnectHandler(**device) as net_connect:
wlc_hostname = net_connect.find_prompt()[:-1]
data1 = net_connect.send_command('show run | inc (^wlan.+)_([0-9]+)_([A-Za-z0-9]+)$')
template = """
<template name="wlan_profile_summ">
<group name="{{ wlan_profile }}">
wlan {{ wlan_profile | _start_ }} {{ wlan_id }} {{ ssid }}
</group>
</template>
"""
print (data1)
parser2 = ttp(data1, template)
parser2.parse()
cisco_wlanTemplates2 = parser2.result(structure="flat_list")
print(json.dumps(cisco_wlanTemplates2, sort_keys=True, indent=5, separators=(',', ': ')))
def main():
parse_cisco_wlans()
if __name__ == "__main__":
main()
Script with plain data and no Function returns proper dict:
from ttp import ttp
import json
data = """
wlan IOT_psk 61 IoTNet
wlan CORP_wpa2 29 CorpNet
wlan CORP_wpa3 23 CorpNet
wlan IOT_dot1x 62 IoTNet
wlan CORP_wpa23 21 CorpNet
wlan GUEST_local 49 GuestNet
wlan XRNET_dot1x 79 XRNet
wlan VOICE_psk_ft 59 VoiceNet
wlan GUEST_central 48 GuestNet
wlan BYOD_wpa2_local 39 DeviceNet
wlan BYOD_wpa23_local 31 DeviceNet
wlan CORP_wpa2_24only 28 CorpNet
wlan BYOD_wpa2_central 38 DeviceNet
wlan GUEST_wpa23_local 41 GuestNet
wlan BYOD_wpa23_central 32 DeviceNet
wlan GUEST_wpa23_central 42 GuestNet
"""
template = """
<template name="wlan_profile_summ">
<group name="{{ wlan_profile }}">
wlan {{ wlan_profile | _start_ }} {{ wlan_id }} {{ ssid }}
</group>
</template>
"""
parser2 = ttp(data, template)
parser2.parse()
cisco_wlanTemplates2 = parser2.result(structure="flat_list")
print(json.dumps(cisco_wlanTemplates2, sort_keys=True, indent=5, separators=(',', ': ')))
Script with plain data inside Function returns proper dict:
from ttp import ttp
import json
def parse_cisco_wlans():
data = """
wlan IOT_psk 61 IoTNet
wlan CORP_wpa2 29 CorpNet
wlan CORP_wpa3 23 CorpNet
wlan IOT_dot1x 62 IoTNet
wlan CORP_wpa23 21 CorpNet
wlan GUEST_local 49 GuestNet
wlan XRNET_dot1x 79 XRNet
wlan VOICE_psk_ft 59 VoiceNet
wlan GUEST_central 48 GuestNet
wlan BYOD_wpa2_local 39 DeviceNet
wlan BYOD_wpa23_local 31 DeviceNet
wlan CORP_wpa2_24only 28 CorpNet
wlan BYOD_wpa2_central 38 DeviceNet
wlan GUEST_wpa23_local 41 GuestNet
wlan BYOD_wpa23_central 32 DeviceNet
wlan GUEST_wpa23_central 42 GuestNet
"""
template = """
<template name="wlan_profile_summ">
<group name="{{ wlan_profile }}">
wlan {{ wlan_profile | _start_ }} {{ wlan_id }} {{ ssid }}
</group>
</template>
"""
print (data)
parser = ttp(data, template)
parser.parse()
cisco_wlanTemplates = parser.result(structure="flat_list")
print(json.dumps(cisco_wlanTemplates, sort_keys=True, indent=5, separators=(',', ': ')))
def main():
parse_cisco_wlans()
if __name__ == "__main__":
main()
I finaly got this working. It was only moving the "template" variable out of the function and from main, and then simply call it:
import json
template = """
<template name="wlan_profile_summ">
<group name="{{ wlan_profile }}">
wlan {{ wlan_profile | _start_ }} {{ wlan_id | DIGIT }} {{ ssid }}
</group>
</template>
"""
def parse_cisco_wlans(wlcList,ssid,newPsk):
for device in wlcList:
try:
with ConnectHandler(**device) as net_connect:
wlc_hostname = net_connect.find_prompt()[:-1]
print ('=========> Connecting to ',wlc_hostname)
data = net_connect.send_command('show run | inc (^wlan.+)_([0-9]+)_([A-Za-z0-9]+)$')
parser = ttp(data, template)
parser.parse()
cisco_wlanTemplates = parser.result(structure="flat_list")
(...)
when you moved the template variable in the function you accidentaly indented all the strings, thats why it was not matching anything. If you want to move the template back in the function write something like this:
template = """
<template name="wlan_profile_summ">
<group name="{{ wlan_profile }}">
wlan {{ wlan_profile | _start_ }} {{ wlan_id }} {{ ssid }}
</group>
</template>
"""