confgraph

Juniper JunOS Parser Support Documentation

Overview

The JunOS parser (confgraph.parsers.junos_parser.JunOSParser) parses Juniper JunOS device configurations. Unlike all other parsers, it does not use CiscoConfParse — JunOS uses a brace-delimited hierarchical config format that is fundamentally incompatible with indentation-based parsing. Instead it uses a custom recursive tokenizer (confgraph.parsers.junos_hierarchy) to convert the config into a nested dict that the parser navigates.

Both brace-style (hierarchical) and set-style config formats exist in JunOS. This parser handles brace-style only. Set-style output (lines beginning with set) can be converted to brace-style using show configuration | display set vs show configuration on the device.

Class: confgraph.parsers.junos_parser.JunOSParser Inherits from: BaseParser Tokenizer: confgraph.parsers.junos_hierarchy.parse_junos_config OSType: OSType.JUNOS (“junos”)


Key Syntax Differences from IOS

Feature IOS JunOS
Config format Line-by-line, indentation-based Brace-delimited hierarchy
VRF definition vrf definition NAME routing-instances NAME { instance-type vrf; }
VRF membership vrf forwarding NAME on interface interface NAME; inside routing-instances NAME
Interface IP ip address X MASK family inet { address X/LEN; } inside unit N
Interface ACL ip access-group NAME in\|out family inet { filter { input\|output NAME; } }
Subinterfaces Named subinterfaces (Gi0/0.100) Units (ge-0/0/0 { unit 100 { } })
Route-maps route-map NAME permit N policy-statement NAME { term T { } }
Prefix-lists ip prefix-list NAME seq N permit PREFIX prefix-list NAME { PREFIX; } (no permit/deny)
AS-path lists ip as-path access-list NAME permit REGEX as-path NAME "REGEX"; (flat statement)
Community lists ip community-list NAME permit VALUE community NAME members VALUE; (flat statement)
BGP neighbors Flat: neighbor IP remote-as N Group-centric: group NAME { neighbor IP { } }
BGP peer templates neighbor IP peer-group NAME group NAME { } (groups ARE the templates)
BGP import/export neighbor IP route-map NAME in\|out neighbor IP { import NAME; export NAME; }
ACLs ip access-list NAME firewall { filter NAME { term T { } } }
Static routes ip route PREFIX MASK NEXTHOP routing-options { static { route P/L next-hop N; } }
OSPF interface ip ospf PROC area AREA on interface area A { interface NAME; } inside OSPF block
ASN router bgp ASN routing-options { autonomous-system ASN; }
Router-ID router-id X inside router bgp routing-options { router-id X; }

Configuration Syntax Support

1. VRF Configuration (routing-instances)

Syntax:

routing-instances {
    CUST-A {
        instance-type vrf;
        interface ge-0/0/2.0;
        route-distinguisher 65000:100;
        vrf-target target:65000:100;
        vrf-table-label;
    }
}

JunOS-Specific Differences:

Supported Attributes:

Cross-referencing: Interface vrf field is populated by cross-referencing routing-instance interface members during parse_vrfs(), which runs before parse_interfaces().

Parsing Status: ✅ Implemented — parse_vrfs() handles routing-instances with vrf-target/vrf-import/vrf-export and populates _vrf_of_intf for interface cross-referencing


2. Interface Configuration

Syntax:

interfaces {
    ge-0/0/0 {
        description "Uplink to ISP";
        unit 0 {
            family inet {
                address 203.0.113.1/30;
                filter {
                    input INBOUND-FILTER;
                    output OUTBOUND-FILTER;
                }
            }
            family inet6 {
                address 2001:db8::1/64;
            }
        }
    }
    lo0 {
        unit 0 {
            family inet {
                address 192.0.2.1/32;
            }
        }
    }
}

JunOS-Specific Differences:

Supported Attributes:

Interface type classification:

Prefix InterfaceType
lo LOOPBACK
fxp, em, me, re MANAGEMENT
ae PORTCHANNEL
irb, vlan SVI
gr-, ip-, st0, lt-, mt- TUNNEL
All others (ge-, xe-, et-, fe-) PHYSICAL

Parsing Status: ✅ Implemented — parse_interfaces() handles brace-style unit blocks with family inet/inet6 and filter { input/output }


3. BGP Configuration

Syntax:

routing-options {
    autonomous-system 65000;
    router-id 192.0.2.1;
}

protocols {
    bgp {
        group IBGP-PEERS {
            type internal;
            local-address 192.0.2.1;
            neighbor 192.0.2.2 {
                description "CORE-02 iBGP";
                import IBGP-IMPORT;
                export IBGP-EXPORT;
            }
        }
        group EBGP-ISP {
            type external;
            peer-as 64512;
            neighbor 203.0.113.2 {
                description "ISP Uplink";
                import ISP-IMPORT;
                export ISP-EXPORT;
            }
        }
    }
}

VRF BGP (inside routing-instance):

routing-instances {
    CUST-A {
        protocols {
            bgp {
                group CUST-A-CE {
                    type external;
                    peer-as 65001;
                    neighbor 10.10.10.2 {
                        import CUST-A-IMPORT;
                        export CUST-A-EXPORT;
                    }
                }
            }
        }
    }
}

JunOS-Specific Differences:

Supported Attributes:

Parsing Status:


4. OSPF Configuration

Syntax:

protocols {
    ospf {
        area 0.0.0.0 {
            interface lo0.0 {
                passive;
            }
            interface ge-0/0/1.0 {
                interface-type p2p;
            }
        }
    }
}

JunOS-Specific Differences:

Supported Attributes:

Parsing Status: ✅ Implemented — parse_ospf() handles area-nested interface blocks


5. Route-Maps (Policy-Statements)

Syntax:

policy-options {
    policy-statement ISP-IMPORT {
        term REJECT-DEFAULT {
            from {
                prefix-list DEFAULT-ROUTE;
            }
            then reject;
        }
        term ACCEPT-REST {
            then accept;
        }
    }
}

JunOS-Specific Differences:

Supported Attributes:

Note: JunOS policy-statement language is more expressive than IOS route-maps. The parser performs best-effort extraction sufficient for dependency graph analysis (identifying referenced prefix-lists, communities, AS-paths). Full policy semantics are not evaluated.

Parsing Status: ✅ Implemented — parse_route_maps() maps policy-statement/term blocks to RouteMapConfig


6. Prefix-Lists (prefix-list in policy-options)

Syntax:

policy-options {
    prefix-list DEFAULT-ROUTE {
        0.0.0.0/0;
    }
    prefix-list RFC1918 {
        10.0.0.0/8;
        172.16.0.0/12;
        192.168.0.0/16;
    }
}

JunOS-Specific Differences:

Supported Attributes:

Parsing Status: ✅ Implemented — parse_prefix_lists() handles prefix-list/end-set style entries


7. AS-Path Lists (as-path in policy-options)

Syntax:

policy-options {
    as-path CUSTOMER-AS "^65001$";
    as-path UPSTREAM-AS "^64512_";
}

JunOS-Specific Differences:

Parsing Status: ✅ Implemented — parse_as_path_lists() parses both flat-statement and block forms


8. Community Lists (community in policy-options)

Syntax:

policy-options {
    community NO-EXPORT members no-export;
    community LOCAL-PREF-100 members 65000:100;
}

JunOS-Specific Differences:

Parsing Status: ✅ Implemented — parse_community_lists() parses both flat-statement and block forms


9. ACLs (firewall filters)

Syntax:

firewall {
    filter INBOUND-FILTER {
        term BLOCK-RFC1918 {
            from {
                source-prefix-list RFC1918;
            }
            then {
                discard;
            }
        }
        term ALLOW-ESTABLISHED {
            from {
                tcp-established;
            }
            then accept;
        }
        term DEFAULT-DENY {
            then {
                discard;
            }
        }
    }
}

JunOS-Specific Differences:

Supported Attributes:

Parsing Status: ✅ Implemented — parse_acls() handles firewall { filter NAME { term T { } } }


10. Static Routes

Syntax:

routing-options {
    static {
        route 0.0.0.0/0 next-hop 203.0.113.2;
        route 192.168.0.0/16 discard;
    }
}

routing-instances {
    CUST-A {
        routing-options {
            static {
                route 0.0.0.0/0 next-hop 10.0.0.1;
            }
        }
    }
}

JunOS-Specific Differences:

Supported Attributes:

Parsing Status: ✅ Implemented — parse_static_routes() handles global and per-VRF routing-options static blocks


11. Management Protocols (Inherited from system block)

JunOS management configuration lives under the top-level system { } block rather than at the global config level.

NTP:

system {
    ntp {
        server 10.0.0.10;
        server 10.0.0.11;
    }
}

Parsing Status: ✅ Implemented — parse_ntp() handles system.ntp.server

SNMP:

system {
    snmp {
        community public {
            authorization read-only;
        }
    }
}

Parsing Status: ✅ Implemented — parse_snmp() handles system.snmp.community with authorization

Syslog:

system {
    syslog {
        host 10.0.0.20 {
            any any;
        }
    }
}

Parsing Status: ✅ Implemented — parse_syslog() handles system.syslog.host entries


Tokenizer Architecture

Unlike IOS-style parsers that rely on CiscoConfParse, the JunOS parser uses a two-layer approach:

Config text
    │
    ▼
junos_hierarchy.parse_junos_config()
    ├── _tokenize()         Strip comments, emit tokens ({, }, ;, [, ], words, quoted strings)
    └── _parse_block()      Recursive descent → nested dict
    │
    ▼
dict[str, Any]              Navigated by JunOSParser parse methods
    │
    ▼
ParsedConfig                Standard model used by all OS types

Key tokenizer behaviors:

Input Stored as
keyword value; {keyword: "value"}
keyword name { … } {keyword: {name: {…}}}
keyword { … } {keyword: {…}}
keyword [ a b c ]; {keyword: "a b c"}
Duplicate keys First block merged; leaves become list
/* … */ and # … Stripped before tokenizing

Implemented Methods Summary

Method What it handles
_extract_hostname() system { host-name X; }
_collect_unrecognized_blocks() Returns [] — CiscoConfParse not used
parse_vrfs() routing-instances NAME { instance-type vrf; … } with interface cross-reference
parse_interfaces() interfaces { NAME { unit N { family inet { } } } }
_make_interface() Constructs InterfaceConfig from parsed unit data
_junos_interface_type() Classifies interface name → InterfaceType
parse_bgp() protocols bgp { group G { neighbor IP { } } } + VRF BGP
_parse_bgp_block() Shared group/neighbor parser for global and VRF BGP
parse_ospf() protocols ospf { area A { interface I { } } }
parse_route_maps() policy-options policy-statement NAME { term T { from/then } }
parse_prefix_lists() policy-options prefix-list NAME { PREFIX; }
parse_community_lists() policy-options community NAME members VALUE;
parse_as_path_lists() policy-options as-path NAME "regex";
parse_acls() firewall filter NAME { term T { from/then } }
parse_static_routes() routing-options static { route P next-hop N; } (global + VRF)
parse_ntp() system ntp { server IP; }
parse_snmp() system snmp { community NAME { authorization ro/rw; } }
parse_syslog() system syslog { host IP { } }

Parser Limitations

  1. Set-style config not supported — Only brace-style (hierarchical) config is parsed. Convert with show configuration (not show configuration | display set) before using confgraph.
  2. IS-IS — Detected in protocols isis block but parsed as a stub (no IS-IS model populated).
  3. MPLS / LDP / RSVP / Segment Routing — Not parsed.
  4. EVPN / VXLAN — Not parsed.
  5. Policy-statement full semantics — Complex if/then/else constructs and apply-path are best-effort; only prefix-list, community, as-path references in from blocks are extracted.
  6. Firewall filter match conditions — Only the action (accept/discard) is captured; source/destination address match conditions in filter terms are not parsed into ACLEntry fields.
  7. IPv6 routing protocols — Limited coverage.
  8. Multi-chassis / Virtual Chassis — Not parsed.

Testing and Validation

Sample Configuration: samples/junos_test.cfg

Validated output (confgraph info samples/junos_test.cfg --os junos):

Hostname : JUNOS-CORE-01
OS       : junos
Interfaces         3
VRFs               1
BGP instances      2
OSPF instances     1
Route-maps         6
Prefix-lists       2
ACLs               2
Community-lists    2
AS-path-lists      2
Static routes      3
NTP                1
SNMP               1

Auto-detection signals (used when --os is not provided):

Signal Example
system { Top-level system block
interfaces { Top-level interfaces block
protocols { Top-level protocols block
routing-options { Top-level routing-options block
set system host-name Set-style prefix (detected but not parsed)

Quick Reference

from confgraph.parsers.junos_parser import JunOSParser

parser = JunOSParser(config_text)
parsed = parser.parse()
# os_type = OSType.JUNOS  # "junos"
confgraph info samples/junos_test.cfg --os junos
confgraph map  samples/junos_test.cfg --os junos --lint

Last Updated: 2026-04-14 Parser Version: 1.0.0