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

POC for adding OC support to napalm #28

Closed
wants to merge 2 commits into
base: master
from

Conversation

Projects
None yet
3 participants
@dbarrosop
Member

dbarrosop commented May 7, 2016

This is an idea I recently discussed with Rob Shakir. After he put some code for me as an example I was able to integrate his example into napalm.

The idea of this feature is to provide a load_openconfig method that gets a model and an instance of the model. NAPALM should be able to:

  1. Merge the new configuration by translating OC into regular commands if the model is not supported natively.
  2. Merge the new configuration by using the native mechanism (gRCP, NETCONF, etc) if it's supported.

Here is an example (so far only translation is supported):

>>> from napalm_base import get_network_driver
>>> driver = get_network_driver('eos')
>>> optional_args = {'port': 12443,}
>>>
>>> d = driver('localhost', 'vagrant', 'vagrant', optional_args=optional_args)
>>> d.open()
>>>
>>> with open('bgp_global.json', 'r') as f:
...     data = f.read()
...
>>> print(data)
{
    "openconfig-bgp:bgp": {
        "neighbors": {
            "neighbor": [
                {
                    "ebgp-multihop": {
                        "config": {
                            "enabled": true,
                            "multihop-ttl": 255
                        }
                    },
                    "neighbor-address": "2001:db8::1",
                    "config": {
                        "neighbor-address": "2001:db8::1",
                        "peer-as": 6643,
                        "description": ":a=6643:d=Jive:"
                    },
                    "afi-safis": {
                        "afi-safi": [
                            {
                                "config": {
                                    "enabled": true,
                                    "afi-safi-name": "openconfig-bgp-types:IPV6_UNICAST"
                                },
                                "afi-safi-name": "IPV6_UNICAST"
                            }
                        ]
                    }
                },
                {
                    "neighbor-address": "192.0.2.2",
                    "config": {
                        "neighbor-address": "192.0.2.2",
                        "peer-as": 54113,
                        "description": ":a=54413:d=Fastly:"
                    },
                    "afi-safis": {
                        "afi-safi": [
                            {
                                "config": {
                                    "enabled": true,
                                    "afi-safi-name": "openconfig-bgp-types:IPV6_UNICAST"
                                },
                                "afi-safi-name": "IPV6_UNICAST"
                            },
                            {
                                "config": {
                                    "enabled": true,
                                    "afi-safi-name": "openconfig-bgp-types:IPV4_UNICAST"
                                },
                                "afi-safi-name": "IPV4_UNICAST"
                            }
                        ]
                    }
                }
            ]
        },
        "global": {
            "config": {
                "as": 6643,
                "router-id": "192.0.2.1"
            },
            "afi-safis": {
                "afi-safi": [
                    {
                        "use-multiple-paths": {
                            "ebgp": {
                                "config": {
                                    "maximum-paths": 8
                                }
                            }
                        },
                        "config": {
                            "enabled": true,
                            "afi-safi-name": "openconfig-bgp-types:IPV6_UNICAST"
                        },
                        "afi-safi-name": "IPV6_UNICAST"
                    },
                    {
                        "use-multiple-paths": {
                            "ebgp": {
                                "config": {
                                    "maximum-paths": 8
                                }
                            }
                        },
                        "config": {
                            "enabled": true,
                            "afi-safi-name": "openconfig-bgp-types:IPV4_UNICAST"
                        },
                        "afi-safi-name": "IPV4_UNICAST"
                    }
                ]
            }
        }
    }
}

>>> d.load_openconfig(model='openconfig_bgp', data=data)
>>> print d.compare_config()
@@ -26,7 +26,20 @@
 !
 no ip routing
 !
-router bgp 123
+router bgp 6643
+   maximum-paths 8
+   neighbor 192.0.2.2 remote-as 54113
+   neighbor 192.0.2.2 description :a=54413:d=Fastly:
+   neighbor 192.0.2.2 maximum-routes 12000
+   neighbor 2001:db8::1 remote-as 6643
+   neighbor 2001:db8::1 description :a=6643:d=Jive:
+   neighbor 2001:db8::1 maximum-routes 12000
+   address-family ipv4
+      neighbor 192.0.2.2 activate
+   !
+   address-family ipv6
+      neighbor 192.0.2.2 activate
+      neighbor 2001:db8::1 activate
 !
 management api http-commands
    no shutdown
>>> d.commit_config()
>>> d.load_openconfig(model='openconfig_bgp', data=data)
>>> print d.compare_config()
''
>>>

Thanks to Rob Shakir for his help putting this together and for pyangbind.

@ktbyers

This comment has been minimized.

Show comment
Hide comment
@ktbyers

ktbyers May 7, 2016

Contributor

@dbarrosop Nice!

Contributor

ktbyers commented May 7, 2016

@dbarrosop Nice!

@dbarrosop

This comment has been minimized.

Show comment
Hide comment
@dbarrosop

dbarrosop May 7, 2016

Member

Btw, most of the code is autogenerated by pyangbind. The only new parts were added on the commit 7f3f2ba

Member

dbarrosop commented May 7, 2016

Btw, most of the code is autogenerated by pyangbind. The only new parts were added on the commit 7f3f2ba

@mirceaulinic

This comment has been minimized.

Show comment
Hide comment
@mirceaulinic

mirceaulinic May 7, 2016

Member

This is fantastic! Do you think we'll be able to integrate OpenConfig in the getters too, in order to collect data from the device?

Member

mirceaulinic commented May 7, 2016

This is fantastic! Do you think we'll be able to integrate OpenConfig in the getters too, in order to collect data from the device?

@dbarrosop

This comment has been minimized.

Show comment
Hide comment
@dbarrosop

dbarrosop May 7, 2016

Member

Should be as unpleasant as the current getters we have. We just have to return a different format. I will try to mock a get_oc_bgp in the next few weeks.

Member

dbarrosop commented May 7, 2016

Should be as unpleasant as the current getters we have. We just have to return a different format. I will try to mock a get_oc_bgp in the next few weeks.

@dbarrosop

This comment has been minimized.

Show comment
Hide comment
@dbarrosop

dbarrosop May 8, 2016

Member

BTW, @mirceaulinic you probably noticed but I added a mechanism to pass custom filters to jinja2 templates.

Member

dbarrosop commented May 8, 2016

BTW, @mirceaulinic you probably noticed but I added a mechanism to pass custom filters to jinja2 templates.

@mirceaulinic

This comment has been minimized.

Show comment
Hide comment
@mirceaulinic

mirceaulinic May 8, 2016

Member

Yes, I've noticed, that's yet another nice feature for load_template! :)

Member

mirceaulinic commented May 8, 2016

Yes, I've noticed, that's yet another nice feature for load_template! :)

@dbarrosop dbarrosop closed this May 11, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment