A month or so back I wrote about reviving my old provisioning system project, Viconf. I have not had so much time to work on it, but I've come a long way already. I have more or less the entire base functionality implemented, so I'm ready to talk about what I have. Especially, I'm interested in any feedback on whether this tool could be useful to you.
So what was it again?
The concept was quite simple: Start with a configuration template, and turn it in to a form. Use this form to produce configuration that can be pushed to network devices in whatever way you prefer.
It uses rather simple templates without too much logic, based on an older templating system called Mustache.
This template system is rather devoid of logic, which makes it perfect to this system. I'd rather avoid having to provide input for various list types and advanced data structures. In its simplest form, a template should have a direct relationship between a variable and the input.
In the past, I had overcomplicated things drastically by creating custom inventory systems, reimplementing spreadsheets and database overlays. In this new and improved version, there is no such complications.
However, to achieve some usefulness, templates can be grouped in two levels, enabling you to define services that are not limited to one node.
What do I have so far?
So right now I have a working backend and a really nice frontend. The front-end is not polished, but works reasonably intuitively.
I've taken a number of screenshots, as this is easier to explain from.
Routers and groups
You can define nodes and groups. Groups are something I haven't quite figured out what to use for, but they so far store authentication information for the nodes. This is a remnant of the old version that had support for pushing configuration to the network. I may remove this model in a future version, and have just nodes, with some additional fields that I find myself defining quite often.
Templates are the heart of the system.
When you create new templates, you get access to writing your own variables, or use some special built in variables.
I've included some special tags that allow for template nesting. Something that came handy when I tested writing templates for Nokia SROS.
The service hierarchy, as you may recall, is defined as such:
In addition to
defaults in the ResourceService object, it
is possible to define whether a variable should be configurable at
all. This allows you to create services e.g. on specific interfaces
that are not to be overwritten.
This service uses three templates. Using the same variable names across templates makes the form field shared between these.
In this template there is no node defined. When provisioned, the user is prompted to select node. Otherwise, the node is hardcoded.
It is posible to create multiple ResourceServices with different nodes set. This is how you configure services that span the network.
You can also define a mix where all but one has a fixed node. Defining multiple ResourceServices without a node assumes that these all end up on the same node for now.
The Resource Services are tied together in a Service object, in the frontend called Network Service.
These just contain the previously defined ResourceServices.
Once you have a Network Service defined, you can provision your first service. The provisioned service will be available as a Service Order afterwards. First you fill in a few basic information about the order, and select your service.
Then you get the form for the template. Note that you can tie various types of validation to the variables. These are currently validated both in the frontend and in the backend.
Getting the config
After filling in the form, you can see the servce in the list of Service Orders. From this list you can generate the configuration.
The configuration is actually not stored anywhere, only the variables and their values. This allows you to change the template and get a new configuration. This should probably be done with care, as adding new variables will break existing configuration.
I'm intending this system to be rather use-case agnostic. The frontend is an API client to the backend, so it is entirely possible to create another API client that fetches the provisioned services and their configuration, in order to push them to the network. This could be ansible, salt, nornir, or whatever you prefer.
The frontend is intended to be super simple to use. It's just a matter of filling in a form, and with the simple validation I've made, it should be relatively safe as well. For machine provisioning, you can just use the REST API to send the service as JSON instead.
I consider the features I have implemented so far to be feature complete for the base version. They still need a lot of polish, but this is the functionality that I've been looking to build. However, I have some other things I'm going to look at. These include:
Currently, every user in the system is admin. I'm planning to create at least one level that only has access to fill out templates, and perhaps also a read-only group.
I'd also like to build some sort of plugin system that can be used from templates and get access to the variable scope somehow. This is tricky, as I don't want to overcomplicate the template system. My first use case for this plugin system, is something that generates route filters for BGP. The mustache template system does support lists, so it is possible to inject something from a plugin that can be iterated. I just have to be extremely mindful of the potential complications that this may provide.
I'm extremely interested in hearing your thoughts! Are you a network engineer who are looking for some simple automation where this could be valuable? Is it stupid and not worth spending time on? Every kind of feedback is welcomed.