Technical Forum
Ask questions. Discover Answers.
cancel
Showing results for 
Search instead for 
Did you mean: 
Custom Alert Banner

Any python experts out there? - parsing tmsh list

Hi,

For a documation exercise i'm trying to parse the output of "tmsh list" - it's been suggested that this is a good output to identify the config of the f5.

I've choosen to use python as its native on my server i run other things on.
What i am trying to do is firstly. Split the string at the first { and then using space limitation separate this so i can see the config being identifed.
Where i am struggling is how to split up the contents of the {}  brackets and split this up into key:value pairs so i can then use this infomation in the documenation.

Has anyone ever done this? Or can lend me any advise please? I'm not really a coder, more of a hacker when it comes to programming!

ltm virtual virtualServer { creation-time 2022-06-23:11:02:34 destination 172.16.100.102:http ip-protocol tcp last-modified-time 2022-06-23:11:11:50 mask 255.255.255.255 pool SiteA-Pool profiles { http { } tcp { } } serverssl-use-sni disabled source 0.0.0.0/0 source-address-translation { type automap } translate-address enabled translate-port enabled vs-index 6 }

7 REPLIES 7

Hello PSFletchTheTek,

Have you tried with f5-sdk?
https://f5-sdk.readthedocs.io/en/latest/

It's an easy way to collect the config of "tmsh list" in a parsed way.

 

Regards,
Dario.

So iwas going to use ansbile to run the tmsh list command and pipe its output into a file via ansible then run some python to parse it.

So i could use the sdk instead if that gives me more useable parameters.
Any suggestions on how to cleanly navigate?
I'm trying to pull together build documentation, so any parameters you can suggest you be awesome!

Fletch

Annoyingly,

My collegue has just pointed out, i can't use the SDK in our environment as i'm not allowed to install anything on the customers environment. (forgot that part, i got all existed about the SDK)

So i'm back to processing the tmsh list one-line output.

So if anyone can help me with the parsing that would be awesome!

Fletch

Well, all the libraries used in the F5 SDK are open source, so, you can replicate the same code to your own repository. If you install it in your home lab, you will see all the files involved. I recommend you to give it a try.

Take into account that the python philosophy is to reuse the already created libraries and only create something when the current existing library doesn't solve what you are searching for. If this already exists, it doesn't make sense to create the same again. Just my POV.

 

Regards,
Dario.

I do agree with you whole heartedly.
But the SDK runs off of the REST API from what i can work out. 
Unfortunately i need something i can run offline, with minial tools on the custmer environment.
The concept of the SDK from inside works brillantly, but i don't have control the environment i am working in.

So running tmsh list > /var/temp/list_output.txt for example and getting one of the sys admins send it to me works very nicely. 

Meant to add, if there is any other way i can get this offline and get the sdk to process that file that would be awesome. It's the offline bit that i think is the struggle here

nsmcan
Nimbostratus
Nimbostratus

Here is a piece of code I created recently, which works well for my needs. It might be updated with more 'declarative' words, where a word is a key and its omitted value is 'True':

declarative_keys = ['disabled', 'internal', 'ip-forward', 'vlans-enabled']


def parse_tmsh_one_line_output(out):
    """
    Parses output of a tmsh command produced in machine-readable format with the 'one-line' option
    @param out: Command output
    @return: Parsed dictionary
    """
    def parse_layer(tokens):
        """
        Parses one dictionary layer from the tokens
        @param list tokens: string tokens
        @return: parsed dictionary, leftover tokens
        """
        result = {}
        is_key = True  # The first token will be a key
        key = None
        while tokens:
            token = tokens.pop(0)
            if is_key:
                key = token
                if key in declarative_keys:
                    result[key] = True
                    continue
                if key == '}':
                    break
                is_key = False

            else:
                value = token
                is_key = True
                if value == '{':
                    result[key], tokens = parse_layer(tokens)
                    continue
                if value.startswith('"'):
                    tokens.insert(0, value[1:])
                    parts = []
                    while tokens:
                        token = tokens.pop(0)
                        if token.endswith('"') and not token.endswith('\\"'):
                            parts.append(token[:-1])
                            break
                        parts.append(token)
                    value = ' '.join(parts)
                result[key] = value.replace('\\"', '"')
        # end while
        return result, tokens

    _tokens = out.split(' ')
    parsed, _ = parse_layer(_tokens)
    return parsed