napalm-automation / napalm-yang

Bindings for napalm based on YANG models
Apache License 2.0
54 stars 44 forks source link

parse_config returns nothing for network_instance model in Junos #137

Closed elkinaguas closed 6 years ago

elkinaguas commented 6 years ago

Hello, I'll put you in context, I'm trying to populate a model with the BGP configuration from a Junos (JUNOS 12.1X47-D15.4) router that I set up with Vagrant and Virtualbox, here the tutorial. To populate the model I parse the configuration from the device using the network_instance model but this is only returning an empty set of curly brackets: {}.

I tried populating the interfaces model by the same method and it works just fine. At the beginning I thought that the network_instance profile was not yet implemented for Junos, but I checked here and I saw that some parts are implemented, e.g. the part for the getting the as-number, and the router-id.

I tried populating the model the same way but with an EOS router, also implemented with Vagrant and Virtualbox, and in both cases, with the interfaces and the network_instance model, it worked perfectly. I compared the network_instance profiles for EOS and Junos and noticed that for both the same parts were implemented, which brings me to my question, why is the parse_config function returning no information for the network_instance model in Junos if the profile is already implemented?

Maybe I'm forgetting or not noticing something and this is not really a problem, but I don't know what else to do to make this work or if this is not supposed to work yet. I hope some one can take a look at it.

Thanks for reading, Elkin


MORE CONTEXT 1. Here the code I'm using:

from napalm_base import get_network_driver
import napalm_yang, salt.client, ast

import json

def use_real_devices():
    junos_configuration = {
        'hostname': '127.0.0.1',
        'username': 'root',
        'password': 'Juniper',
        'optional_args': {'port': 2231}
    }

    eos_configuration = {
        'hostname': '127.0.0.1',
        'username': 'vagrant',
        'password': 'vagrant',
        'optional_args': {'port': 12443}
    }

    junos = get_network_driver("junos")
    junos_device = junos(**junos_configuration)

    eos = get_network_driver("eos")
    eos_device = eos(**eos_configuration)
    return junos_device, eos_device

def pretty_print(dictionary):
    print(json.dumps(dictionary, sort_keys=True, indent=4))

junos_device, eos_device = use_real_devices()

#__________________________________________________________________________________

with junos_device as d:
    candidate = napalm_yang.base.Root()
    candidate.add_model(napalm_yang.models.openconfig_network_instance)
    candidate.parse_config(device=d)
    pretty_print(candidate.get(filter=True))

2. Router Config:

## Last commit: 2018-06-15 08:14:10 UTC by root
version 12.1X47-D15.4;
system {
    host-name r1;
    root-authentication {
        encrypted-password "$1$nq.N1UsY$JxA/ESAj3Ku"; ## SECRET-DATA
        ssh-rsa "ssh-rsa AAAAB3...
    }
    login {
        user vagrant {
            uid 2000;
            class super-user;
            authentication {
                ssh-rsa "ssh-rsa AAAAB3...
            }                           
        }                               
    }                                   
    services {                          
        ssh {                           
            root-login allow;           
        }                               
        netconf {                       
            ssh;                        
        }                               
        web-management {                
            http {                      
                interface ge-0/0/0.0;   
            }                           
        }                               
    }                                   
    syslog {                            
        user * {                        
            any emergency;              
        }                               
        file messages {                 
            any any;                    
            authorization info;         
        }                               
        file interactive-commands {     
            interactive-commands any;   
        }                               
    }                                   
    license {                           
        autoupdate {                    
            url https://ae1.juniper.net/junos/key_retrieval;
        }                               
    }                                   
}                                       
interfaces {                            
    ge-0/0/0 {                          
        unit 0 {                        
            family inet {               
                dhcp;                   
            }                           
        }                               
    }                                   
    ge-0/0/1 {                          
        unit 0 {                        
            family inet {               
                address 192.168.1.1/24; 
            }                           
        }                               
    }                                   
    ge-0/0/2 {                          
        unit 0 {                        
            family inet {               
                address 192.168.2.1/24; 
            }                           
        }                               
    }                                   
    lo0 {                               
        unit 0 {                        
            family inet {               
                address 1.1.1.1/32;     
            }                           
        }                               
    }                                   
}                                       
routing-options {                       
    autonomous-system 100;              
}                                       
protocols {                             
    bgp {                               
        group external-peers {          
            type external;              
            export send-direct;         
            neighbor 192.168.1.2 {      
                peer-as 200;            
            }                           
            neighbor 192.168.2.3 {      
                peer-as 300;            
            }                           
        }                               
    }                                   
}                                       
policy-options {                        
    policy-statement send-direct {      
        term 1 {                        
            from protocol direct;       
            then accept;                
        }                               
    }                                   
}                                       
security {                              
    forwarding-options {                
        family {                        
            inet6 {                     
                mode packet-based;      
            }                           
            mpls {                      
                mode packet-based;      
            }                           
        }                               
    }                                   
} 
dbarrosop commented 6 years ago

I think you hit a bug in the profile. I suspect the problem is here:

https://github.com/napalm-automation/napalm-yang/blob/develop/napalm_yang/mappings/junos/parsers/config/openconfig-network-instance/network-instances.yaml#L10-L12

As you don't have a routing instance I suspect that's returning nothing and not processing the rules for "network-instance". Would you mind trying to create a dummy routing instance and checking if the problem goes away? In that case we will have to fix that. I think the following should work:

network-instances:
    _process:
        - path: "configuration"
          from: root_network-instances.0
    network-instance:
        _process:
            - key: "{{ 'global' }}"
            - path: "routing-instances.instance"
              key: name

Please, give it a go if you can and let me know (or send a PR if it works or if you have any other suggestion)

cspeidel commented 6 years ago

fwiw I replicated the issue from @elkinaguas (napalm-yang returned {}), and implemented @dbarrosop suggestion and it looks like it worked: test.py:

running_config = napalm_yang.base.Root()
running_config.add_model(napalm_yang.models.openconfig_network_instance)
running_config.parse_config(native=[config], profile=["junos"])

pretty_print(running_config.get(filter=True))

Before @dbarrosop's suggestion:

[user@net01 napalm-yang]$ ./test.py 
{}

After @dbarrosop's suggestion:

[user@net01 napalm-yang]$ ./test.py 
{
    "network_instances": {
        "network-instance": {
            "global": {
                "config": {
                    "enabled": True, 
                    "type": "DEFAULT_INSTANCE"
                }, 
                "name": "global", 
                "protocols": {
                    "protocol": {
                        "bgp bgp": {
                            "bgp": {
                                "global": {
                                    "config": {
                                        "as": 65000, 
                                        "router-id": "192.168.9.9"
                                    }
                                }, 
                                "neighbors": {
                                    "neighbor": {
                                        "192.168.11.11": {
                                            "config": {
                                                "local-as": 65000, 
                                                "neighbor-address": "192.168.11.11", 
                                                "peer-group": "ibgp"
                                            }, 
                                            "neighbor-address": "192.168.11.11"
                                        }, 
                                        "192.168.22.22": {
                                            "config": {
                                                "local-as": 65000, 
                                                "neighbor-address": "192.168.22.22", 
                                                "peer-group": "ibgp"
                                            }, 
                                            "neighbor-address": "192.168.22.22"
                                        }
                                    }
                                }
                            }, 
                            "identifier": "bgp", 
                            "name": "bgp"
                        }, 
                        "lldp lldp": {
                            "identifier": "lldp", 
                            "name": "lldp"
                        }, 
                        "ospf ospf": {
                            "identifier": "ospf", 
                            "name": "ospf"
                        }, 
                        "pim pim": {
                            "identifier": "pim", 
                            "name": "pim"
                        }, 
                        "static static": {
                            "identifier": "static", 
                            "name": "static", 
                            "static-routes": {
                                "static": {
                                    "0.0.0.0/0": {
                                        "config": {
                                            "prefix": "0.0.0.0/0"
                                        }, 
                                        "prefix": "0.0.0.0/0"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

The translator is a different story :)

dbarrosop commented 6 years ago

Glad to see it worked :) feel free to send a PR if you have the energy, otherwise I will try to find some time and PR it myself (my backlog keeps growing :( )

Is the translator also misbehaving? That's odd. Would you mind sharing your tests and findings there?

elkinaguas commented 6 years ago

Thanks @dbarrosop and @cspeidel for your fast response, I made the change and I confirm that now it works. Very helpful now that I'm still understanding napalm-yang. I will make the PR.

dbarrosop commented 6 years ago

Glad to hear, I will close this issue, feel free to reopen though if there is anything else to address.