Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Junos-style configs searchable #17

Closed
mpenning opened this issue Jan 26, 2015 · 5 comments
Closed

Make Junos-style configs searchable #17

mpenning opened this issue Jan 26, 2015 · 5 comments
Assignees

Comments

@mpenning
Copy link
Owner

Some people want ciscoconfparse to search Junos configurations... this bug tracks implementation of the feature request.

@mpenning mpenning self-assigned this Jan 26, 2015
@mpenning
Copy link
Owner Author

We now parse Junos configurations into Cisco IOS-style (I already hear the distant cries of "heretic")... nevertheless, if you want to see it in action, here's how I parse configs/sample_01.junos:

>>> from ciscoconfparse import CiscoConfParse
>>> parse = CiscoConfParse('configs/sample_01.junos', syntax='junos', comment='#!')
>>> for line in parse.ioscfg:
...     print line
... 
!# Last commit: 2015-06-28 13:00:59 CST by mpenning
system 
    host-name TEST01_EX
    domain-name pennington.net
    domain-search [ pennington.net lab.pennington.net ]
    location 
        country-code 001
        building HQ_005
        floor 1
    root-authentication 
        encrypted-password "$1$y7ArHxKU$zUbdeLfBirgkCsKiOJ5Qa0"
    name-server 
        172.16.3.222
    login 
        announcement "Test Lab Switch"
            class super-user
            authentication 
                encrypted-password "$1$y7ArHxKU$zUbdeLfBirgkCsKiOJ5Qa0"
    services 
        ssh 
            root-login allow
        telnet
        web-management 
            http
    syslog 
        user * 
            any emergency
        file messages 
            any notice
            authorization info
        file interactive-commands 
            interactive-commands any
    ntp 
        boot-server time.apple.com
        server 172.16.8.3
vlans 
    Management 
        vlan-id 1
        interface 
            ge-0/0/0.0
            ge-0/0/1.0
            ge-0/0/2.0
            ge-0/0/3.0
    VLAN_FOO 
        vlan-id 5
    vlan1 
        vlan-id 1
        l3-interface vlan.1
    vlan800 
        vlan-id 800
ethernet-switching-options 
    storm-control 
        interface all
interfaces 
    ge-0/0/0 
        unit 0 
            family ethernet-switching 
                port-mode access
                vlan 
                    members VLAN_FOO
    ge-0/0/1 
        unit 0 
            family ethernet-switching 
                port-mode trunk
                vlan 
                    members all
                native-vlan-id 1
    vlan 
        unit 0 
            family inet 
                address 172.16.15.5/22
routing-options 
    static 
        route 0.0.0.0/0 next-hop 172.16.12.1
        route 192.168.36.0/25 next-hop 172.16.12.1

This is a hack, to be sure... so I'm leaving the enhancement open until I get a few more details nailed down... in the mean time, if people want to experiment with searching Junos as IOS, it is here :-)

mpenning added a commit that referenced this issue Jan 26, 2015
@mpenning
Copy link
Owner Author

mpenning commented Jan 26, 2015

Junos Searches with find_object_branches()

Recommended: Use the find_object_branches() method as illustrated below._

Junos Searches with find_objects_w_*()

Not Recommended: Juniper configurations are quite hierarchical... To get the interface object for a Junos interface such as ge-0/0/1, you'd need to use something like parse.find_objects_w_parents(r'^\s*interface', r'^\s+ge-0/0/1'), which returns the object for ge-0/0/1 in a list. Then you can iterate through for children of ge-0/0/1 as you like.

However, if you don't require the interface object itself, you can still enforce Junos interface configuration policies in python via parse.find_objects_w_child(r'^\s+ge-0/0/1', r'port-mode\saccess'); that policy checks whether ge-0/0/1 is port-mode access.

@kthned
Copy link

kthned commented Aug 1, 2017

Hi Mike

I am trying to parse the F5 Networks configurations. Do you have a syntax ready for bigIP or any timeplan :)
currently i am getting following error on at

line 263, in __init__
    config = self.convert_braces_to_ios(rgx.split(text))
line 389, in convert_braces_to_ios
    line, line_offset = line_level(tmp.strip())
line 383, in line_level
    raise ValueError("Could not parse: '{0}'".format(input))
ValueError: Could not parse: '} else {'

Running the code like

from ciscoconfparse import CiscoConfParse
parse = CiscoConfParse("/Users/python/lbj.junos", syntax='junos', comment='#')
for line in parse.ioscfg:
    print (line)

@mpenning
Copy link
Owner Author

@kthned, "} else {" should parse correctly in the latest versions... please let me know if you run into problems

@mpenning
Copy link
Owner Author

mpenning commented Oct 28, 2020

Another junos-parsing example using find_object_branches()

Suppose you want to associate junos interface names with their IP addresses from this example config...

config = r"""
interfaces {                                                 
    xe-0/0/0 {                                               
        unit 0 {                                             
            family inet {                                    
                address 1.1.1.6/31;                     
            }                                                
            family inet6 {                                   
                address FD00:DEAD:CAFE:6000::4/127;         
            }                                                
        }                                                    
    }                                                        
    xe-0/0/1 {                                               
        unit 0 {                                             
            family inet {                                    
                address 2.2.2.10/31;                    
            }                                                
            family inet6 {                                   
                address FD00:DEAD:CAFE:7903::2/64;             
            }                                                
        }                                                    
    }                                                        
    xe-0/0/2 {                                               
        mtu 9192;                                            
        unit 0 {                                             
            family inet {                                    
                address 3.3.3.14/31;                    
            }                                                
            family inet6 {                                   
                address FD00:DEAD:CAFE:6000::26/127;        
            }                                                
        }                                                    
    }                                                        
}
""".splitlines()
from ciscoconfparse import CiscoConfParse

parse = CiscoConfParse(config, syntax='junos', comment='#')
branchspec = (
    r'interfaces',
    r'^\s+\S+',   # Detect any intf name...
    r'^\s+unit',
    r'^\s+family',
    r'^\s+address',
)
for params in parse.find_object_branches(branchspec):

    # Select the params with the corresponding index of the regex specified in branchspec, above... 
    intf_obj, intf_family_obj, addr_obj = params[1], params[3], params[4]

    intf_name = intf_obj.re_match_typed('^\s+(\S+)')
    intf_family = intf_family_obj.re_match_typed('\s+family\s+(inet\S*)')
    addr = addr_obj.re_match_typed('^\s+address\s+(\S+)')

    print("{} {} {}".format(intf_name, intf_family, addr))

When you run the script above, you will get this as output...

xe-0/0/0 inet 1.1.1.6/31
xe-0/0/0 inet6 FD00:DEAD:CAFE:6000::4/127
xe-0/0/1 inet 2.2.2.10/31
xe-0/0/1 inet6 FD00:DEAD:CAFE:7903::2/64
xe-0/0/2 inet 3.3.3.14/31
xe-0/0/2 inet6 FD00:DEAD:CAFE:6000::26/127

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants