pythonnetwork-programmingansibleciscopython-textfsm

Is there a way to Continue with the same line in State changes in TextFSM?


I know that I can't combine state transitions with a continue statement.

I'm trying to parse network configuration with ansible where the only clear end of row its the beginning of the next one.

For example I want to parse configs like follows:

line vty 0 4
 exec-timeout 30 0
 authorization exec MIRADIUS
 accounting connection MIRADIUS
 accounting exec MIRADIUS
 login authentication MIRADIUS
line vty 5 16
 access-class 95 in vrf-also
 exec-timeout 30 0
 authorization exec MIRADIUS
 accounting connection MIRADIUS
 accounting exec MIRADIUS
 login authentication MIRADIUS
 history size 25
 transport input ssh
line vty 15 116
 access-class 95 in
 exec-timeout 30 0
 authorization exec MIRADIUS
 accounting connection MIRADIUS
 accounting exec MIRADIUS
 login authentication MIRADIUS
 history size 25

Template I'm using:

Value Required LINE (\d+\s+\d+)
Value vtyAcl (\d+|\w+)
Value aclDir (\w+)
Value vrfAlso (\w+-\w+)

Start
  ^\s+access-class\s+${vtyAcl}\s+${aclDir}\s+${vrfAlso}.*$$
  ^\s+access-class\s+${vtyAcl}\s+${aclDir}.*$$
  ^line vty ${LINE}.*$$ -> Continue.Record

So the only certain way I have to know I'm done with the vty 0 4 for example is that the vty 5 16 starts.

so, it is possible to keep continue with the line in order to save the new vty? Currently my template is saving the config of previous row in the nextone. I have no way to know the which will be the lasts lines possibilities.

Current result:
[
    {
        "LINE": "0 4",
        "aclDir": "",
        "vrfAlso": "",
        "vtyAcl": ""
    },
    {
        "LINE": "5 16",
        "aclDir": "",
        "vrfAlso": "",
        "vtyAcl": ""
    },
    {
        "LINE": "15 116",
        "aclDir": "in",
        "vrfAlso": "vrf-also",
        "vtyAcl": "95"
    }
]

Desired Result:
[
    {
        "LINE": "0 4",
        "aclDir": "",
        "vrfAlso": "",
        "vtyAcl": ""
    },
    {
        "LINE": "5 16",
        "aclDir": "in",
        "vrfAlso": "vrf-also",
        "vtyAcl": "95"
    },
    {
        "LINE": "15 116",
        "aclDir": "in",
        "vrfAlso": "",
        "vtyAcl": "95"
    }
]

UPDATE: Here the update with solution for this particular issue. Thanks.

Value Required LINE (\d+\s+\d+)
Value vtyAcl (\d+|\w+)
Value aclDir (\w+)
Value vrfAlso (\w+-\w+)

Start
  ^line vty -> Continue.Record
  ^\s+access-class\s+${vtyAcl}\s+${aclDir}\s+${vrfAlso}.*$$
  ^\s+access-class\s+${vtyAcl}\s+${aclDir}.*$$
  ^line vty ${LINE}.*$$ 

Solution

  • I have been looking an answer for the same question but have not found it (found just your question :)). AFAIK:

    1. TextFSM does NOT support Lookahead/Lookbehind regex features.
    2. As you already wrote, TextFSM does NOT support Record+Continue (state change) as it is stated in their docs: "Note that the Continue action does not accept a state transition. This ensures that state machines are loop free."
    3. If there was an empty string (or any other delimiter for information blocks) BEFORE the line "line vty X Y" we could use TextFSM's states.

    What workaround I'm using now - I'm using several templates consequently, a template extract VTY-number and ONE parameter for this line. Then combine the results together.

    BUT in your case you have only ONE "interesting" line per "line vty X Y" block and this line is NOT the last line in the "line vty X Y" block, so you may use just the right REGEX (I slightly correct your template - vrfAlso "may be" or "may be not" exist) and a little TextFSM trick. :)

    Value Required LINE (\d+\s+\d+)
    Value vtyAcl (\d+|\w+)
    Value aclDir (\w+)
    Value vrfAlso (\w+-\w+)
    
    Start
      ^line vty ${LINE}.*$$
      ^\s+access-class\s+${vtyAcl}\s+${aclDir}\s*(${vrfAlso})?.*$$ -> Record
      ^.* -> Record
    
    EOF
    

    Here, we are using "^.* -> Record" in order to Record the lines that do NOT have "interesting" string.

    And you will get your desired result (I presume):

    LINE    vtyAcl    aclDir    vrfAlso
    ------  --------  --------  ---------
    0 4
    5 16    95        in        vrf-also
    15 116  95        in
    

    Unfortunately, in my case, I have multiple "interesting" strings and they may be the last in a block, so it will not work for me. :(

    UPDATE: I accidentally found a TextFSM's way of looking ahead. It gave me an idea how to find a solution for my task and the main idea is described here: https://github.com/google/textfsm/issues/22