Cisco MPLS forwarding table example
Here the Cisco IOS-XR MPLS table output is:
Sat Oct 6 09:34:54.543 UTC
Local Outgoing Prefix Outgoing Next Hop Bytes
Label Label or ID Interface Switched
------ ----------- ------------------ ------------ --------------- ------------
123011 123011 Ac accept (im 4) BE1 10.123.123.1 1234567890
123011 Ac accept (im 4) BE123 10.234.234.22 0 (!)
Here three template examples are illustrated. First a naive version, but this leaves spaces on the end of hte “prefix_or_id” fields:
m> {{ cisco_iosxr_cmd_dt }}
m> Local Outgoing Prefix Outgoing Next Hop Bytes
m> Label Label or ID Interface Switched
m> ------ ----------- ------------------ ------------ --------------- ------------
m*> {{ local_label = re("(?:\d+|)") }}{{ ws }}{{ outgoing_label = non_ws }}{{ ws }}{{ prefix_or_id = re(".{18}") }}{{ ws }}{{ outgoing_ifname = non_ws }}{{ ws }}{{ next_hop = ipaddr }}{{ ws }}{{ bytes_switched = integer }}{{ ws }}{{ flags = re("(?:\S+|)") }}
Or, using the fixedwidth function:
m> {{ cisco_iosxr_cmd_dt }}
m> Local Outgoing Prefix Outgoing Next Hop Bytes
m> Label Label or ID Interface Switched
m> ------ ----------- ------------------ ------------ --------------- ------------
m*> {{ local_label = fixedwidth(6) }}{{ ws }}{{ outgoing_label = fixedwidth(11) }}{{ ws }}{{ prefix_or_id = fixedwidth(18) }}{{ ws }}{{ outgoing_ifname = fixedwidth(12) }}{{ ws }}{{ next_hop = fixedwidth(15) }}{{ ws }}{{ int bytes_switched = fixedwidth(12) }}{{ flags = string | lstrip() }}
Or this would be fixed width column parsing without the fixedwidth column, which leaves a lot of extra trailing white space on all columns, though you could tidy this up with the lstrip function:
m> {{ cisco_iosxr_cmd_dt }}
m> Local Outgoing Prefix Outgoing Next Hop Bytes
m> Label Label or ID Interface Switched
m> ------ ----------- ------------------ ------------ --------------- ------------
m*> {{ local_label = re(".{6}") }}{{ ws }}{{ outgoing_label = re(".{11}") }}{{ ws }}{{ prefix_or_id = re(".{18}") }}{{ ws }}{{ outgoing_ifname = re(".{12}") }}{{ ws }}{{ next_hop = re(".{15}") }}{{ ws }}{{ int bytes_switched = re(".{12}") }}{{ flags = string }}
Here’s the naive template demonstrated working:
>>> import sttp
>>>
>>> in_template = '''m> {{ cisco_iosxr_cmd_dt }}
... m> Local Outgoing Prefix Outgoing Next Hop Bytes
... m> Label Label or ID Interface Switched
... m> ------ ----------- ------------------ ------------ --------------- ------------
... m*> {{ local_label = re("(?:\d+|)") }}{{ ws }}{{ outgoing_label = non_ws }}{{ ws }}{{ prefix_or_id = re(".{18}") }}{{ ws }}{{ outgoing_ifname = non_ws }}{{ ws }}{{ next_hop = ipaddr }}{{ ws }}{{ bytes_switched = integer }}{{ ws }}{{ flags = re("(?:\S+|)") }}
... '''
>>>
>>> in_text = '''Sat Oct 6 09:34:54.543 UTC
... Local Outgoing Prefix Outgoing Next Hop Bytes
... Label Label or ID Interface Switched
... ------ ----------- ------------------ ------------ --------------- ------------
... 123011 123011 Ac accept (im 4) BE1 10.123.123.1 1234567890
... 123011 Ac accept (im 4) BE123 10.234.234.22 0 (!)
... '''
>>>
>>> parser = sttp.Parser(template = in_template)
>>> out_struct = parser.parse(in_text)
>>>
>>> assert out_struct == [{
... 'local_label': '123011',
... 'outgoing_label': '123011',
... 'prefix_or_id': 'Ac accept (im 4) ',
... 'next_hop': '10.123.123.1',
... 'outgoing_ifname': 'BE1',
... 'bytes_switched': 1234567890,
... 'flags': '',
... }, {
... 'local_label': '',
... 'outgoing_label': '123011',
... 'prefix_or_id': 'Ac accept (im 4) ',
... 'next_hop': '10.234.234.22',
... 'outgoing_ifname': 'BE123',
... 'bytes_switched': 0,
... 'flags': '(!)',
... }], out_struct
Here’s the fixedwidth template demonstrated working:
>>> import sttp
>>>
>>> in_template = '''m> {{ cisco_iosxr_cmd_dt }}
... m> Local Outgoing Prefix Outgoing Next Hop Bytes
... m> Label Label or ID Interface Switched
... m> ------ ----------- ------------------ ------------ --------------- ------------
... m*> {{ local_label = fixedwidth(6) }}{{ ws }}{{ outgoing_label = fixedwidth(11) }}{{ ws }}{{ prefix_or_id = fixedwidth(18) }}{{ ws }}{{ outgoing_ifname = fixedwidth(12) }}{{ ws }}{{ next_hop = fixedwidth(15) }}{{ ws }}{{ int bytes_switched = fixedwidth(12) }}{{ flags = string | lstrip() }}
... '''
>>>
>>> in_text = '''Sat Oct 6 09:34:54.543 UTC
... Local Outgoing Prefix Outgoing Next Hop Bytes
... Label Label or ID Interface Switched
... ------ ----------- ------------------ ------------ --------------- ------------
... 123011 123011 Ac accept (im 4) BE1 10.123.123.1 1234567890
... 123011 Ac accept (im 4) BE123 10.234.234.22 0 (!)
... '''
>>>
>>> parser = sttp.Parser(template = in_template)
>>> out_struct = parser.parse(in_text)
>>>
>>> assert out_struct == [{
... 'local_label': '123011',
... 'outgoing_label': '123011',
... 'prefix_or_id': 'Ac accept (im 4)',
... 'next_hop': '10.123.123.1',
... 'outgoing_ifname': 'BE1',
... 'bytes_switched': 1234567890,
... 'flags': '',
... }, {
... 'local_label': '',
... 'outgoing_label': '123011',
... 'prefix_or_id': 'Ac accept (im 4)',
... 'next_hop': '10.234.234.22',
... 'outgoing_ifname': 'BE123',
... 'bytes_switched': 0,
... 'flags': '(!)',
... }], out_struct
Here’s the DIY fixed width column template demonstrated working:
>>> import sttp
>>>
>>> in_template = '''m> {{ cisco_iosxr_cmd_dt }}
... m> Local Outgoing Prefix Outgoing Next Hop Bytes
... m> Label Label or ID Interface Switched
... m> ------ ----------- ------------------ ------------ --------------- ------------
... m*> {{ local_label = re(".{6}") }}{{ ws }}{{ outgoing_label = re(".{11}") }}{{ ws }}{{ prefix_or_id = re(".{18}") }}{{ ws }}{{ outgoing_ifname = re(".{12}") }}{{ ws }}{{ next_hop = re(".{15}") }}{{ ws }}{{ int bytes_switched = re(".{12}") }}{{ flags = string }}
... '''
>>>
>>> in_text = '''Sat Oct 6 09:34:54.543 UTC
... Local Outgoing Prefix Outgoing Next Hop Bytes
... Label Label or ID Interface Switched
... ------ ----------- ------------------ ------------ --------------- ------------
... 123011 123011 Ac accept (im 4) BE1 10.123.123.1 1234567890
... 123011 Ac accept (im 4) BE123 10.234.234.22 0 (!)
... '''
>>>
>>> parser = sttp.Parser(template = in_template)
>>> out_struct = parser.parse(in_text)
>>>
>>> assert out_struct == [{
... 'local_label': '123011',
... 'outgoing_label': '123011 ',
... 'prefix_or_id': 'Ac accept (im 4) ',
... 'next_hop': '10.123.123.1 ',
... 'outgoing_ifname': 'BE1 ',
... 'bytes_switched': 1234567890,
... 'flags': '',
... }, {
... 'local_label': ' ',
... 'outgoing_label': '123011 ',
... 'prefix_or_id': 'Ac accept (im 4) ',
... 'next_hop': '10.234.234.22 ',
... 'outgoing_ifname': 'BE123 ',
... 'bytes_switched': 0,
... 'flags': ' (!)',
... }], out_struct