Doing YANG Wrong: Part 4 - Config stores

Part 4: Config stores

As we head down this rabbit hole, we start to get ever closer to something useful, but ever more deep into the weeds of NETCONF/YANG. For the uninitiated, config stores are a place where you can put config chunks either singularly, or in aggregate over a series of netconf pushes, to generate a new config that you will apply in one hit. In the SP world you might want to setup some interfaces, some BGP and then some overlay like an MPLS service. You may not want to do all this in one script since you might not need all of those things in one script. better to make a script per thing, and then call the ones your CMDB thinks it needs, place them all in a candidate config, validate that as a whole and then push that in one go. If anything fails, you can then throw it all away and not touch the operational running config. At this point juniper folks are shrugging their shoulders - this is very old hat to them, but for enterprise people, particularly the type who lived on the CLI for years, this is unimaginable.

[Read more]

Doing YANG Wrong: Part 3 - Using the python bindings

Part 3: Using the python bindings to push a config

Given we generated that python file locally in a machine, we assume here that you are still in that subdirectory.

The below code was stolen fully from the YANG Book. Much love and all credit to them for their work.

from interface_setup import openconfig_interfaces
from pyangbind.lib.serialise import pybindIETFXMLEncoder
from ncclient import manager

# device settings
username = 'yangconf'
password = 'my_good_password.'
device_ip = '192.168.70.21'

# config settings 
inside_interface = 'GigabitEthernet4'
inside_ip_addr = '109.109.109.2'
inside_ip_prefix = 24


def send_to_device(**kwargs):
    rpc_body = '<config>' + pybindIETFXMLEncoder.serialise(kwargs['py_obj']) + '</config>'
    with manager.connect_ssh(host-kwargs['dev'], port=830, username=kwargs['user'], password=kwargs['password'], hostkey_verify=False) as m:
        try:
            m.edit_config(target='running', config=rpc_body)
            print('Successfully configured IP on {}'.format(kwargs['dev']))
        except Exception as e:
            print('Failed to configure interface: {}'.format(e))


if __name__ == '__main__':
    # instanciate the openconfig model
    ocintmodel = openconfig_interfaces()

    # create an instance of the interfaces
    ocinterfaces = ocintmodel.interfaces

    # create a new interface instance in that parent object
    inside_if = ocinterfaces.interface.add(inside_interface)

    # even a routed interface required a subinterface, its just at index 0
    inside_if.subinterfaces.subinterface.add(0)

    # create an instance of that subinterface object to edit
    inside_sub_if = inside_if.subinterfaces.subinterface[0]

    # apply an IP to that object
    inside_sub_if.ipv4.addresses.address.add(inside_ip_addr)
    
    # read that ip object into an ip object
    ip = inside_sub_if.ipv4.addresses.address[inside_ip_addr]

    # set the IP and the subnet mask properly

    ip.config.ip = inside_ip_addr
    ip.config.prefix_length = inside_ip_prefix
    send_to_device(dev=device_ip, user=username, password=password, py_obj=ocinterfaces)

When I run this, it fails.

[Read more]

Doing YANG Wrong: Part 2 - Python Bindings

Part 2: Python bindings for models

Having a model is one thing. Using it requires you to ingest that model somewhere, apply values to its elements (leaves) as necessary/appropriate and then submit that completed model to the appliance for application to the config.

I’m a python guy, you might like Go, or ruby or whatever. thats up to you, but I use python right now, which means I use pyangbind and pyang to create pythonic modules I can import into a script, and then interact with the model attributes like I would any other object in python. We can then push that out to a device from that script.

[Read more]

Doing YANG Wrong - Part 1: Getting started

This is more of a discovery post than anything particularly useful. It charts my adventure from a problem statement, through discovery of a solution, to a dead end. I post it here to help people see the logic I followed, and why, against all wisdom, it didn’t work.

Note that if you are familiar with YANG, I know why this is NOT the right way to do this, but I only know that having done this as shown here. Please don’t waste your time in the comments with nerdsplaining that to me. This is to show people a process and to help people who feel stupid when this stuff doesnt work, to see that they’re not alone. I learn by making mistakes.

[Read more]

Network Automation: from spreadsheets to YANG and everything between

Over the last few years I have spent a significant amount of time in YAML and Ansible. I’m not an expert by any means, but I can probably get anything I need done in maybe a few days worth of tinker time. I’m what you would call a fair weather scripter.

One thing I learned from building about 30,000 lines of YAML whilst orchestrating ACI, was that Ansible is a square peg, and everything networking is a round hole. Sometimes it fits, sometimes it doesn’t, but it is never perfect. Never.

[Read more]