All I Want For Christmas Is ... RESTCONF?

As somebody not lucky enough to have a nice clicky interface with which to manage and automate all my equipment, I have to develop my own tools to do so. One aspect of developing those tools that drives me up the wall is the variety of mechanisms I have to support to communicate with the various devices deployed in the network. Why can’t we have one, consistent way to manage the devices?

SHHH About SSH

I can already hear voices saying “But we have SSH. SSH is available on almost all devices. Is that not the consistency you desire?” No, it isn’t. In terms of configuring network devices, SSH is just a(n encrypted) transport mechanism and provides no help whatsoever with configuring the devices. Once I’ve connected using SSH, I have to develop the appropriate customized code to screen-scrape the particular operating system I connect to. Anybody who has done this will testify that this is not particularly straightforward and, worse, the reward for doing so is to be able to issue commands and receive, in return, wads of unstructured data (i.e., command output) which can change between code versions, making parsing a nightmare.

So here’s my first requirement: structured data.

Structured Data

Typical command line output blurts out the requested information in such a way that the surrounding label text and the position of a piece of text impart the information necessary to infer what the text itself represents. Decoding data in this format usually means developing regular expressions to identify and pull apart the text so that the constituent data can be processed. Identification of data is implicit, based on contextual clues. Unstructured data is nice (or a least tolerable) for a human to look at and make sense of, but is frequently very difficult to interpret in code.

Structured data, on the other hand, follows a specific set of rules to present the data points such that they are explicitly and unambiguously identified and labeled for consumption by code. Structured data usually presents data in a way that mimics programmatic hierarchical data structures, which lends itself to easy integration into code.

Junos has historically favored XML for structured data, but — subjectively — I would argue that XML is ugly and can get complex very quickly, especially where multiple namespaces are being used. Personally I have a soft spot for JSON, and I know other people like YAML, but ultimately I’m at the point where I’d say “I don’t care, just pick one and stick with it,” so that I can focus my time and effort on handling the one format.

So here’s my second requirement: consistent encoding.

What Gets Encoded?

Once we have a way to encode the data in structured format, we then need to be more consistent about what’s being encoded. Again, this may point at a project like OpenConfig, but failing that, perhaps it might be worth it if everything could be described using YANG. By default, YANG maps to XML, but RFC7951 (JSON Encoding of Data Modeled With YANG) helpfully shows how my pet preference JSON can be used instead.

The point here is that if YANG is used, the mapping to JSON or XML is almost a side issue, so long as the data is modeled in YANG to start with; both XML and JSON fans can translate from YANG to their favorite encoding and—and this is the key part—so can the devices, so clients can request the encoding of their choice.

One Transport To Rule Them All

So now that I’ve determined that we need YANG models with support for both JSON and XML encoding, optionally following a common OpenConfig data model, let’s address how we communicate with the devices.

I don’t want to have to figure out what kind of device I’m connecting to, then based on that information, decide what connection transport I should be using (e.g., HTTP, HTTPS, SSH possibly on a non-standard TCP port). What I want to be able to do is to connect to the device in a standard way on a standard port. I don’t mind reconnecting to a non-standard port, but I want to be told about that port after I connect to the standard port.

That’s my third requirement: one transport for all.

OpenConfig takes this approach, by having a “well-known” URL on the device to report back information about the device and connection details in a standard format. I’d like to take it a step further, though.

REST API or Bust

Let’s use a REST API for all this communication. REST APIs are ubiquitous now; every programming language has the ability to send and receive requests over HTTP(S) and to decode the XML/JSON responses. It makes things easy!

My last requirement: access via REST API.

Wait a moment, let me check again:

  • Structured data: YES
  • Consistent encoding: YES
  • One transport: YES
  • RESTAPI: YES

I believe I’ve accidentally just defined RESTCONF (RFC8040), whose introductory paragraph reads:

“[...] an HTTP-based protocol that provides a programmatic interface for accessing data defined in YANG, using the datastore concepts defined in the Network Configuration Protocol (NETCONF).”

I am not a huge fan of NETCONF/XML over SSH, but NETCONF/JSON over HTTP? Count me in!

My Thoughts

Automating the infrastructure is hard enough without battling against multiple protocols. How about we just all agreed that RESTCONF is a good compromise and start supporting it across all devices?

For what it’s worth, there is some level of RESTCONF support in more recent software releases, including:

  • Cisco IOS XE
  • Cisco IOS XR
  • Cisco NXOS
  • Juniper Junos OS
  • Arista EOS
  • Extreme XOS
  • DellEMC OS10
  • and more...

But here’s the problem: when did you last hear of anybody trying to automate with RESTCONF?

That’s what I’d like to see. What about you?

  • The issue of "lowest common denominator" versus "vendor-specific requirements" is one of the main areas that OpenConfig was trying to address, by creating a standardized framework for the LCD stuff while also allowing vendors to extend the model to permit the vendor-specific configurations to be incorporated. Choosing a protocol and transport through which to connect to a device doesn't impact what the device can do, nor does it dictate the model that has to be used; however, it would be nice to think that 80% of the configurations could be approached in the same away across all my devices, even if I still had to write vendor-specific code for the remaining 20%.

    Additionally, having a standards-based API for programmatic access does not remove the ability to have a CLI and, indeed, any other configuration mechanisms. The idea isn't necessarily that you have to be a coder in order to configure a device; far from it. However, if you do want to configure (or query) a device using code, then wouldn't it be nice to have a common underlying mechanism by which to do it?

  • Don't make it easy.  They everyone will be able to do it.

  • Hmm...  I'm all for standardizing things, getting a more consistent transport mechanism and such, but I think many of the current approaches are forgetting something critical.   The diversity we have in technology and vendors promotes a diversity in the hardware and such too.   For stock traders and others concerned with nanoseconds, ultra low latency has evolved, for others large buffer spaces are important, and so on...    We can't accept a standard that generalizes all this and gives us only the mechanisms to control the things that are common among devices, but we need to be able to control the things that make things special from device to device too.   If you go into a box and customize something, you can't be worrying about whether it might be wiped the next time a standard config is deployed.    Nor do I want to see vendors only supporting the minimum necessary.  

    From what I've seen from these approaches, they are much more complex than what we have now, from XML to JSON formats or ansible and such.  Some entity, whether it be an NMS or standards board, needs to figure out a way to actually make this simpler, not more complex.  Where coding isn't a requirement to understand things.

  • Security should be paramount regardless of the transport / protocol, just like it is today with VTY access.

Thwack - Symbolize TM, R, and C