Using NETCONF to apply configuration changes
As you might expect, NETCONF isn't limited to querying the JUNOS OS device operational status using RPCs. It can also influence the operating state of the device by applying configuration changes. In contrast to other management models like SNMP however, one doesn't manipulate individual data atoms to effect change. Instead, JUNOS OS makes use of the concept of a candidate configuration which is applied to the various software daemons when the candidate is committed. In this respect, NETCONF and the traditional user-based CLI are consistent.
In this recipe, we'll look at the NETCONF directives necessary to make configuration changes. We'll make a simple interface description change, and we'll also look at how to delete configuration stanzas.
Getting ready
Make sure you've got access to a JUNOS OS platform that you can make changes on. Make sure that you've got a working NETCONF-over-SSH capability with the JUNOS OS platform as per the first recipe in this chapter, JUNOS NETCONF-over-SSH setup.
How to do it...
The steps for the recipe are as follows:
- Familiarize yourself with the XML format used within JUNOS OS to represent configuration data. Generally speaking, the XML representation follows the same hierarchy as the configuration format itself. JUNOS OS itself can help you here. Issue the
show configuration | display xml
command in order to see a portion of the configuration expressed in XML:
adamc@router> show configuration interfaces em0.0 | display xml
<rpc-reply xmlns:JUNOS="http://xml.juniper.net/JUNOS/
15.1F6/JUNOS">
<configuration JUNOS:commit-seconds="3780" JUNOS:commit-
localtime="1970-01-01 01:03:00 UTC" JUNOS:commit-user="adamc">
<interfaces>
<interface>
<name>em0</name>
<unit>
<name>0</name>
<family>
<inet>
<address>
<name>10.0.201.201/24</name>
</address>
</inet>
</family>
</unit>
</interface>
</interfaces>
</configuration>
- Connect to the NETCONF-over-SSH server in the usual manner:
unix$ ssh -i JUNOS_auto_id_rsa [email protected] netconf
- Use the NETCONF-standard
edit-config
operation to submit a configuration change to the NETCONF server. In this example, we update the description on theem0.0
interface to something trivial:
<rpc> <edit-config> <target> <candidate/> </target> <config> <configuration> <interfaces> <interface> <name>em0</name> <unit> <name>0</name> <description>Management interface</description> </unit> </interface> </interfaces> </configuration> </config> </edit-config> </rpc>
- Verify that the operation was successful. The
<ok/>
RPC reply is what we want to see here. - Commit the configuration by issuing the
commit
NETCONF primitive and checking for the<ok/>
RPC reply again:
<rpc><commit/></rpc>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS">
<ok/>
</rpc-reply>
]]>]]>
- Apply the same configuration, but delete the description attribute by including the special
operation="delete"
XML attribute decoration:
<rpc> <edit-config> <target> <candidate/> </target> <default-operation>none</default-operation> <config> <configuration> <interfaces> <interface> <name>em0</name> <unit> <name>0</name> <description operation="delete"/> </unit> </interface> </interfaces> </configuration> </config> </edit-config> </rpc>
- Commit the candidate configuration again, and analyze the configuration and system commit log by hand to verify what happened:
<rpc><commit/></rpc>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS">
<ok/>
</rpc-reply>
]]>]]>
How it works...
In step 1, we need to work out what our configuration change looks like in the XML representation that JUNOS OS requires. We can use the CLI to help us with that process.
In step 2, we connect to the NETCONF-over-SSH server in the usual manner.
In step 3, we submit the configuration change that we need, represented in XML, and then in step 4 we look for the server's response. If it isn't the standard <ok/>
response, there are a couple of reasons why that might be:
- The configuration submission contained an error:
<rpc-error> <error-type>protocol</error-type> <error-tag>operation-failed</error-tag> <error-severity>error</error-severity> <error-message>syntax error</error-message> <error-info> <bad-element>unti</bad-element> </error-info> </rpc-error>
- The JUNOS OS configuration database is currently locked by another user:
<rpc-error> <error-type>protocol</error-type> <error-tag>lock-denied</error-tag> <error-severity>error</error-severity> <error-message> configuration database locked by: adamc terminal pts/0 (pid 19893) on since 1970-01-01 01:09:14 UTC, idle 00:03:11 exclusive [edit] </error-message> <error-info> <session-id>19893</session-id> </error-info> </rpc-error>
Note
The Junos OS provides several ways to manipulate the configuration. Generally speaking a user modifies the configuration by taking a copy of the current configuration. This is called the candidate. The user manipulates the candidate using set
and delete
commands, and when ready commits the configuration to make it live. The default behaviour is for all users to manipulate a shared candidate configuration, but there are also two other methods of operations. Configuring with private
mode provides the user with his own private candidate. The changes he makes are guaranteed to be his own, and when he commits, the system will apply his differences to the current configuration (even if the configuration has changed since he checked out his basis for a candidate). exclusive
mode requests that the user lock the configuration, thereby preventing access by other individuals until the user relinquishes the lock.
If all is okay, we proceed to the commit
operation in step 5. This is the part of the process where the new configuration actually gets applied. JUNOS OS produces the individual instructions for each of the software processes from the configuration file, and then signals each process to re-read the configuration and implement the change to the new state.
This phase can also have errors if the new configuration causes a runtime error. It's really important to deal with this situation because the configuration change will not be removed, so it has the potential to block up future commit
operations as well.
Here's the RPC response that we get, for example, if we try to commit
an Ethernet sub-interface with zero-host portion:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS"> <rpc-error> <error-type>protocol</error-type> <error-tag>operation-failed</error-tag> <error-severity>error</error-severity> <source-daemon> dcd </source-daemon> <error-path> [edit interfaces em0 unit 10 family inet] </error-path> <error-info> <bad-element> address 1.0.10.0/24 </bad-element> </error-info> <error-message> Cannot assign address 0 on subnet </error-message> </rpc-error>
In order to ensure that we undo the failed configuration attempt, we can use the discard-changes
RPC from NETCONF standard. This will cause the JUNOS OS device to discard any changes in the global candidate configuration that we are working on.
<rpc><discard-changes/></rpc>
In steps 6 and 7, we undo the change by submitting a new configuration with a delete directive and then committing to that. Configuration deletions are quite simple, but it's important to understand them. There are two notable differences from the configuration addition:
- The
default-operation
RPC property is set toNone
. This property controls how JUNOS OS applies the supplied configuration with respect to the existing candidate configuration. By default, JUNOS OS merges configuration items, which is typically what we want when we're adding or changing values. But when we're deleting configuration items, we don't want JUNOS OS to accidentally create unnecessary configuration hierarchies. - The
operation
property for the item to be deleted is set toDelete
. This tells JUNOS OS that this particular element should be removed from the configuration.