Creating Genie Parsers – Part 4

Stage Three – Creating the Parser Schema

The final piece on this to finish is the schema. As I mentioned I like to do this last but you may want to do this first. If you get comfortable with the schemas then you can always do these first but as I mentioned I tend to stay in the pdb when doing these scripts so that they don’t crash because the schema is wrong.

What is the schema?

The schema is an exact representation of how the dictionary should be presented and has to match. It’s mandatory that the dictionary returned and the schema match or the parser will not work. This is intentional to ensure that the correct results are always parsed. If there is deviation then something must be wrong.

Lets have a look at our show ip nbar example:

{
    'interface': {        <------ Key
        'GigabitEthernet1': {   <------ Key
            'protocol': {  <------ Key
                'unknown': {
                    'IN Packet Count': 110, <------ Key
                    'OUT Packet Count': 8, <------ Key
                    'IN Byte Count': 3000, <------ Key
                    'OUT Byte Count': 0,<------ Key
                    'IN 5min Bit Rate (bps)': 3000, <------ Key
                    'OUT 5min Bit Rate (bps)': 0, <------ Key
                    'IN 5min Max Bit Rate (bps)': 3000,<------ Key
                    'OUT 5min Max Bit Rate (bps)': 0 <------ Key
                },

It may be obvious but these are the keys in the dictionary. Now see the mappings required in the schema.

    schema = {
        'interface': {
            Any(): {
                'protocol': {
                    Any(): {
                        'IN Packet Count': int,
                        'OUT Packet Count': int,
                        'IN Byte Count': int,
                        'OUT Byte Count': int,
                        'IN 5min Bit Rate (bps)': int,
                        'OUT 5min Bit Rate (bps)': int,
                        'IN 5min Max Bit Rate (bps)': int,
                        'OUT 5min Max Bit Rate (bps)': int,
                    }
                }
            }
        }
    }

Instead of ‘GigabitEthernet1’ we have Any() to represent any value for that key.

Instead of ‘unknown’ which is a protocol type we also have Any() to represent any value for that key.

The remaining keys should be instantly recognizable from the dictionary.

What we are doing is making sure that anything captured is always an integer and let’s say a word, float or something else ended up in there then it means the parser is not capturing the right data. Therefore think of it as a safety catch to ensure the integrity of the data. Since these keys are all digits then we are enforcing integers in the schema but if that was a string then we could use str instead. However, whilst using str would work here as well it would not be enforcing that data type as it’s too loose. I believe boolean is also a valid datatype but that’s not applicable to our scenario.

The next question you may ask is how do you do the indention on the schema to make it look neat like above. When you print a dictionary it can look almost unreadable. I was given a top tip by Daniel and Thomas in the pyATS team at Cisco that the Code Beautify site is great for making these neat.

https://codebeautify.org/python-formatter-beautifier

Once the schema is complete then you have completed the parser and can remove the debug and see it working in action.

There are some other things like Optional() which means that field is not always present in the data which is useful when there are variations in what is returned by the parser.

https://pubhub.devnetcloud.com/media/pyats-development-guide/docs/writeparser/writeparser.html

The link above contains more information but as a suggestion have a look through some existing parser schemas to see what is required for your use case. The important thing is remembering that the dictionary output and the schema must match. What I did for this one is initially used loose values like strings in the parser script before locking these down to integers in both the script and the schema.

In the last part (Part 5) we will go through the unit test and submission process on Github to make your parser officially part of the library of parsers. At the moment you can use your parser only on your local repository until it is formally submitted.

Published by gwoodwa1

IP Network Design and coding hobbyist

One thought on “Creating Genie Parsers – Part 4

Leave a comment

Design a site like this with WordPress.com
Get started