superloopnetworks
superloopnetworks

Reputation: 514

sync_diff() unable to keep F5 config sequencing/order

Ultimately, I'm trying to diff out curly brace notation. Similar to a "show | compare" output in Junos. Unfortunately setting the syntax to 'junos' does not keep the curly braces in the output. However, setting it to 'ios' does. It seems to have done most of the work done when syntax is set to 'ios' on a F5 code, however, it's still complaining there is a diff on certain parts where it shouldn't be.

from ciscoconfparse import CiscoConfParse

BASELINE = """ltm virtual ACME {
    destination 192.168.1.191:http
    ip-protocol tcp
    mask 255.255.255.255
    pool pool1
    profiles {
        http { }
        tcp { }
    }
    rules {
        MOBILE
    }
    source 0.0.0.0/0
    source-address-translation {
        type automap
    }
    translate-address enabled
    translate-port enabled
    vs-index 17
}""".splitlines()

REQUIRED = """ltm virtual ACME {
    destination 192.168.2.191:http
    ip-protocol tcp
    mask 255.255.255.255
    pool pool2
    profiles {
        http { }
        tcp { }
    }
    rules {
        BLAH
    }
    source 0.0.0.0/0
    source-address-translation {
        type automap
    }
    translate-address enabled
    translate-port enabled
    vs-index 17
}""".splitlines()

parse = CiscoConfParse(BASELINE, syntax='ios')
print('\n'.join(parse.sync_diff(REQUIRED, ''))) 

Produces this:

ltm virtual ACME {
    no }
    no rules {
    no destination 192.168.1.191:http
    no pool pool1
        no MOBILE
ltm virtual ACME {
    destination 192.168.2.191:http
    pool pool2
    rules {
        BLAH
    }

Notice the second and third line from the output.

no }
no rules {

The order is different from the required code and I think, therefore it throws a 'diff'. Is there a way to ensure sequencing is kept in place?

Expected output:

ltm virtual ACME {
    no destination 192.168.1.191:http
    no pool pool1
    rules {
        no MOBILE
    }
ltm virtual ACME {
    destination 192.168.2.191:http
    pool pool2
    rules {
        BLAH
    }

Upvotes: 1

Views: 80

Answers (1)

Mike Pennington
Mike Pennington

Reputation: 43077

This will be close to what you want...

import os
from ciscoconfparse2 import CiscoConfParse, Diff

BASELINE = """ltm virtual ACME {
    destination 192.168.1.191:http
    ip-protocol tcp
    mask 255.255.255.255
    pool pool1
    profiles {
        http { }
        tcp { }
    }
    rules {
        MOBILE
    }
    source 0.0.0.0/0
    source-address-translation {
        type automap
    }
    translate-address enabled
    translate-port enabled
    vs-index 17
}""".splitlines()

REQUIRED = """ltm virtual ACME {
    destination 192.168.2.191:http
    ip-protocol tcp
    mask 255.255.255.255
    pool pool2
    profiles {
        http { }
        tcp { }
    }
    rules {
        BLAH
    }
    source 0.0.0.0/0
    source-address-translation {
        type automap
    }
    translate-address enabled
    translate-port enabled
    vs-index 17
}""".splitlines()

baseline = CiscoConfParse(BASELINE, syntax='ios').get_text()
required = CiscoConfParse(REQUIRED, syntax='ios').get_text()

diff = Diff(baseline, required)
print(os.linesep.join(diff.get_diff()))

Which produces:

ltm virtual ACME {
  no destination 192.168.1.191:http
  no pool pool1
  destination 192.168.2.191:http
  pool pool2
  rules {
    no MOBILE
    BLAH
  • Note that ciscoconfparse2 has a much better diff algorithm than the original ciscoconfparse; however, at this time it still won't close the braces for you.
  • Also, there's no need to repeat ltm virtual ACME { blocks. All this can be contained in one block
  • Finally, note that because we use syntax='ios', proper F5 configuration indentation is required even those this F5 configuration is brace-delimited.

Upvotes: 0

Related Questions