Remote configuration via NETCONFΒΆ

It is possible to remotely configure the equipement using the NETCONF protocol.

We will use ncclient as a NETCONF client. On another machine that will configure the router, install ncclient dependencies.

root@local# pip install xmltodict ncclient

Create a netconf.py file with this content. This script will use the following NETCONF operations:

  • lock, unlock

  • get

  • edit-config

  • validate

  • commit

It will configure the hostname twice, and it will check whether the system state has properly changed after each change.

#!/usr/bin/env python
# pip install xmltodict ncclient

import json
from ncclient import manager
import time
import xmltodict

def connect(host, user, password):
    conn = manager.connect(host=host,
                           username=user,
                           password=password,
                           timeout=10,
                           hostkey_verify=False)

    state = """
<nc:filter type="xpath"
   xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
   xmlns:vrouter="urn:6wind:vrouter"
   xmlns:vrouter-system="urn:6wind:vrouter/system"
   select="%s" />
"""

    conf = """
<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <config xmlns="urn:6wind:vrouter">
    <system xmlns="urn:6wind:vrouter/system">
      <hostname>router</hostname>
    </system>
  </config>
</config>
"""

    new_hostname_conf = """
<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <config xmlns="urn:6wind:vrouter">
    <system xmlns="urn:6wind:vrouter/system">
      <hostname>myhostname</hostname>
    </system>
  </config>
</config>
"""

    conn.lock()

    get_state = conn.get(state % '/vrouter:state/vrouter-system:system/hostname')
    print "***************** hostname before configuration ****************"
    print json.dumps(xmltodict.parse(get_state.data_xml), indent=2)

    print "***************** set hostname to 'myhostname' ****************"
    send_config = conn.edit_config(target='running', config=new_hostname_conf, default_operation='merge')

    check_config = conn.validate()

    conn.commit()

    get_state = conn.get(state % '/vrouter:state/vrouter-system:system/hostname')
    print "***************** hostname is now 'myhostname' ****************"
    print json.dumps(xmltodict.parse(get_state.data_xml), indent=2)

    print "***************** revert to 'router' ****************"
    send_config = conn.edit_config(target='running', config=conf, default_operation='merge')

    conn.commit()
    get_state = conn.get(state % '/vrouter:state/vrouter-system:system/hostname')
    print "***************** hostname is now 'router' ****************"
    print json.dumps(xmltodict.parse(get_state.data_xml), indent=2)

    conn.unlock()
    conn.close_session()

if __name__ == '__main__':
    connect('<myip>', 'root', '<rootpass>')

Update the connect line to put the router IP, and the root password of the router, and launch the script. The following output is displayed.

# python netconf.py
***************** hostname before configuration ****************
{
  "data": {
    "@xmlns": "urn:ietf:params:xml:ns:netconf:base:1.0",
    "@xmlns:nc": "urn:ietf:params:xml:ns:netconf:base:1.0",
    "state": {
      "@xmlns": "urn:6wind:vrouter",
      "system": {
        "@xmlns": "urn:6wind:vrouter/system",
        "hostname": "router"
      }
    }
  }
}
***************** set hostname to 'myhostname' ****************
***************** hostname is now 'myhostname' ****************
{
  "data": {
    "@xmlns": "urn:ietf:params:xml:ns:netconf:base:1.0",
    "@xmlns:nc": "urn:ietf:params:xml:ns:netconf:base:1.0",
    "state": {
      "@xmlns": "urn:6wind:vrouter",
      "system": {
        "@xmlns": "urn:6wind:vrouter/system",
        "hostname": "myhostname"
      }
    }
  }
}
***************** revert to 'router' ****************
***************** hostname is now 'router' ****************
{
  "data": {
    "@xmlns": "urn:ietf:params:xml:ns:netconf:base:1.0",
    "@xmlns:nc": "urn:ietf:params:xml:ns:netconf:base:1.0",
    "state": {
      "@xmlns": "urn:6wind:vrouter",
      "system": {
        "@xmlns": "urn:6wind:vrouter/system",
        "hostname": "router"
      }
    }
  }
}