I merged the new backward conversion feature and released it in 
netjsonconfig 0.6.1: https://github.com/openwisp/netjsonconfig/pull/83

In the near future we will be able to collect the whole device 
configuration and store it in openwisp2, which will make management easier.
A bit more work and building blocks are needed to get there, but the 
hardest part is done! FINALLY.

Federico


On Wednesday, May 31, 2017 at 12:55:13 PM UTC+2, Federico Capoano wrote:
>
> Hi everyone,
>
> recently I started introducing some important changes in netjsonconfig 
> <https://github.com/openwisp/netjsonconfig>, the library used to generate 
> configuration of routers.
>
> This change should not affect openwisp2 users negatively, I'm already 
> testing the current master on 3 instances and already fixed a few bugs.
>
> Nevertheless, the change is affecting negatively the 2 GSoC students who 
> have started to work on the AirOS and Raspbian backends, so I will try to 
> explain why this change is needed.
>
> *Backward conversion*
>
> One of the features that is missing in OpenWISP 2 is the possibility to 
> easily store the full configuration of devices in the controller.
>
> Since OpenWRT/LEDE allows merging a remote configuration with the local 
> one, that's the default mode we are using now in OpenWISP 2 (it was also 
> the only mode available in OpenWISP 1).
>
> This method has its own disadvantages:
>
>    - operators have to remember what is in their local configuration, in 
>    order to write a remote configuration that works well with the local one
>    - some packages use anonymous UCI blocks by default, which are 
>    impossible for openwisp to override in the merge mode, hence creating 
>    duplicate configurations
>
> These disadvantages are holding down OpenWISP 2 from becoming easier to 
> use. OpenWISP 2 is very powerful, but hard to use properly. Which is a 
> shame, because it means many people will give up and use some kind of home 
> baked solution with its own class of bugs, reinventing the wheel: no good 
> framework and ecosystem of tools for low cost open source networks can 
> emerge for such a situation.
>
> That's why we need to add a way to store the full configuration of routers 
> in the controller and this needs to happen automatically: here where 
> backward conversion in netjsonconfig comes into play.
>
> Without the backward conversion, we cannot even use the AirOS or Raspbian 
> backends because those don't have a way to easily merge different 
> configurations like OpenWRT/LEDE (uci import --merge), users would need to 
> manually enter the full configuration of their devices in openwisp2: that 
> will never happen!
>
> *The new implementation*
>
> I've been designing and planning this feature since at least a year, but 
> never got the time to implement because there were more urgent matters. Now 
> is the right time to introduce it because it's very much needed.
>
> The new implementation adds a few new concepts in the codebase:
>
>    - intermediate data structure
>    - converters
>    - parsers
>
> Everything revolves around the data structures: the *NetJSON 
> <http://netjson.org/> configuration dictionary* and the *intermediate 
> data structures*.
>
> Remember what *Linux Torvalds* said?
> *"Bad programmers worry about the code. Good programmers worry about data 
> structures and their relationships."*
>
> This intermediate data structure represents the native configuration of 
> the backend in a python data structure (lists and dictionaries).
>
> This data structure is a convenient way to simplify conversion in both 
> direction, parsing and rendering, and will be different for each backend.
>
> Take a look at this diagram:
> [image: netjsonconfig backward conversion.jpg]
> *Converter* classes take care of converting between NetJSON and 
> intermediate data structure (and vice versa):
>
>    - to_intermediate converts the NetJSON configuration dictionary to the 
>    intermediate data structure
>    - to_netjson (not pushed to the repository yet) converts the 
>    intermediate data structure to NetJSON configuration dictionary
>
> These two main methods can then call helper methods in order to split 
> complex logic in smaller methods that are easier for the human mind to 
> grasp.
>
> *Renderers* take care of rendering the intermediate data structure to the 
> native format.
>
> *Parsers* perform the opposite operation of Renderers: they take care of 
> parsing native format and build the intermediate data structure.
>
> In case of OpenWRT and AirOS, we can get away with just 1 renderer (with 
> just 1 jinja2 tempate) and 1 parser. In the case of Raspbian, we may need 
> to have a render and a template for each format that needs to be rendered 
> (eg: /etc/network/interfaces, ini files, dnsmasq, iptables, ecc).
>
> *Advantages*
>
>    - Cleaner, well defined workflow - also easier to document and learn
>    - Less boilerplate code in those cases where the native configuration 
>    of the router is centralized in one format (OpenWRT / AirOS / PfSense / 
>    vyos), because most of the logic goes in converters while there can be 
> only 
>    1 renderer and 1 parser
>    - Last but not least, makes it possible to implement backward 
>    conversion without going crazy with messy spaghetti code. Our sanity is 
>    very important not only for our work but for our life!
>
> *Disadvantages*
>
> Developers using lower level features of netjsonconfig in their programs 
> and GSOC students working on the netjsonconfig backends will have to 
> rewrite part of their code. A bit of more work needed, but in my opinion a 
> worthy price to pay for a cleaner and more robust implementation.
>
> *How to upgrade your code*
>
> Proceed as follows:
>
>    - the logic that before was contained in the renderers, should most 
>    probably go into the converters
>    - design an intermediate data structure with the following features:
>       - closely represents your native configuration format (or formats)
>       - can be easily rendered with jinja2
>       - can be easily built when parsing the native format (or formats)
>    - simplify your renderers so that you have 1 renderer and 1 template 
>    for each format supported
>
> *Conclusion*
>
> That's it. Sorry for the length. I hope the explanation is clear enough.
>
> Federico
>

-- 
You received this message because you are subscribed to the Google Groups 
"OpenWISP" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to openwisp+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to