Skip to content

Commit

Permalink
Merge ecfb31c into 11cfed1
Browse files Browse the repository at this point in the history
  • Loading branch information
edoput committed Jun 1, 2018
2 parents 11cfed1 + ecfb31c commit 95c348c
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 9 deletions.
13 changes: 5 additions & 8 deletions bin/netjsonconfig
@@ -1,9 +1,11 @@
#!/usr/bin/env python

import argparse
import os
import sys

import six
import argparse

import netjsonconfig

description = """
Expand Down Expand Up @@ -56,7 +58,7 @@ output = parser.add_argument_group('output')

output.add_argument('--backend', '-b',
required=True,
choices=['openwrt', 'openwisp', 'openvpn'],
choices=netjsonconfig.get_backends().keys(),
action='store',
type=str,
help='Configuration backend')
Expand Down Expand Up @@ -166,13 +168,8 @@ context = dict(os.environ)
method = args.method
method_arguments = parse_method_arguments(args.args)

backends = {
'openwrt': netjsonconfig.OpenWrt,
'openwisp': netjsonconfig.OpenWisp,
'openvpn': netjsonconfig.OpenVpn
}

backend_class = backends[args.backend]
backend_class = netjsonconfig.get_backends()[args.backend]
try:
options = dict(templates=templates, context=context)
if args.config:
Expand Down
96 changes: 96 additions & 0 deletions docs/source/backends/create_your_backend.rst
@@ -0,0 +1,96 @@

===================
Create your backend
===================

.. include:: ../_github.rst

Every backend is based on the common ground of some elements provided by the
netjsonconfig library. The `BaseBackend`, `BaseConverter`, `BaseParser` and
`BaseRenderer` are a battle proven set of tools that can be extended when
creating you backend.

But the netjsonconfig package is not a playground to experiment, your contributions
to a new backend should start elsewhere, a different package, where you are in control
and can make errors and experiment more.

Netjsonconfig can now discover packages that provides a custom backend using
a feature available in the Python packaging ecosystem which is called `entry_points`.

To create a new backend start from scratch with a new folder and add this file to your
project root directory.

.. code-block:: python
# setup.py
from setuptools import setup, find_packages
setup(
name='example_backend',
version='0.0.0',
description='an example to illustrate a netjsonconfig backend as an external module',
packages=find_packages(),
entry_points={
'netjsonconfig.backends': [
'example=example_backend.__init__:ExampleBackend',
]
}
)
this file can be used to create a package that can be installed using pip or other tools
in the python ecosystem. You can find more information about Python packaging
`at packaging.python.org <https://packaging.python.org/>`_
and `at the hitchhikers guide to packaging <https://the-hitchhikers-guide-to-packaging.readthedocs.io/en/latest/>`_.

The most important part is to give your package a good name, a well thought description and
to add the `entry_points` keyword argument with the following code

.. code-block:: python
{
# this is used by netjsonconfig
# to find your backend
'netjsonconfig.backends': [
...
]
}
Now your package will be in the list of backends that netjsonconfig can use!

But we still have to give us a name to be unique! Netjsonconfig already
defined the names `openwisp`, `openwrt` and `openvpn` but you can choose
whatever you like most.

The name `netjsonconfig.backends` will be associated with a list of classes
from your package that will be presented to netjconfig at runtime. To specify
which classes you want to expose write the triple `name`, `path` and `class_name`
using the format `name=path:class_name` as in the example below.

The `path` part is simply the path to the file that contains the class
you want to expose and the `class_name` is the name of the class.

.. code-block:: python
{
'netjsonconfig.backends': [
# name=path:class_name
'example=example_backend.__init__:ExampleBackend',
]
}
The previous example can be used with the following class definition

.. code-block:: python
# example_backend/__init__.py
from netjsonconfig.backends.base.backend import BaseBackend
from netjsonconfig.backends.base.renderer import BaseRenderer
from netjsonconfig.backends.base.parser import BaseParser
from netjsonconfig.schema import schema as default_schema
class ExampleBackend(BaseBackend):
schema = default_schema
converter = []
parser = BaseParser
renderer = BaseRenderer
1 change: 1 addition & 0 deletions docs/source/index.rst
Expand Up @@ -55,6 +55,7 @@ Contents:
/backends/openwrt
/backends/openwisp
/backends/openvpn
/backends/create_your_backend
/general/commandline_utility
/general/running_tests
/general/contributing
Expand Down
19 changes: 19 additions & 0 deletions netjsonconfig/__init__.py
@@ -1,5 +1,24 @@
from pkg_resources import iter_entry_points
import logging

from .version import VERSION, __version__, get_version # noqa

from .backends.openwrt.openwrt import OpenWrt # noqa
from .backends.openwisp.openwisp import OpenWisp # noqa
from .backends.openvpn.openvpn import OpenVpn # noqa


def get_backends():
default = {
'openwrt': OpenWrt,
'openwisp': OpenWisp,
'openvpn': OpenVpn,
}
logger = logging.getLogger(__name__)

for entry_point in iter_entry_points('netjsonconfig.backends'):
try:
default.update({entry_point.name.lower(): entry_point.load()})
except ImportError as e:
logger.error("Error loading backend {}".format(entry_point.name.lower()))
return default
1 change: 0 additions & 1 deletion netjsonconfig/backends/openwrt/schema.py
Expand Up @@ -6,7 +6,6 @@
from ..openvpn.schema import base_openvpn_schema
from .timezones import timezones


default_radio_driver = "mac80211"


Expand Down

0 comments on commit 95c348c

Please sign in to comment.