Forum Discussion

PSFletchTheTek's avatar
Jul 01, 2022

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 }

    • PSFletchTheTek's avatar
      PSFletchTheTek
      Icon for MVP rankMVP

      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

    • PSFletchTheTek's avatar
      PSFletchTheTek
      Icon for MVP rankMVP

      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

      • Dario_Garrido's avatar
        Dario_Garrido
        Icon for MVP rankMVP

        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.

         

  • nsmcan's avatar
    nsmcan
    Icon for Nimbostratus rankNimbostratus

    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