Added a new network connection type to handle PPPoE connections

* Added a new choice to main selectbox for adding Network Connections (network.py)
* Added a new form which asks for name, interface, firewall zone, username and password (forms.py, urls.py)
* Added new helper functions to create PPPoE based connection object (network.py)
This commit is contained in:
Daniel Steglich 2015-08-09 22:48:17 +02:00 committed by Sunil Mohan Adapa
parent 2879c9cedb
commit 286caf8917
4 changed files with 131 additions and 4 deletions

View File

@ -73,6 +73,29 @@ available over this interfaces. Select Internal only for trusted networks.'),
self.fields['interface'].choices = choices self.fields['interface'].choices = choices
class AddPPPoEForm(forms.Form):
"""Form to create a new pppoe connection."""
name = forms.CharField(label=_('Connection Name'))
interface = forms.ChoiceField(
label=_('Physical Interface'),
choices=(),
help_text=_('The network device that this connection should be bound '
'to.'))
zone = forms.ChoiceField(
label=_('Firewall Zone'),
help_text=_('The firewall zone will control which services are \
available over this interfaces. Select Internal only for trusted networks.'),
choices=[('external', 'External'), ('internal', 'Internal')])
username = forms.CharField(label=_('Username'))
password = forms.CharField(label=_('Password'))
def __init__(self, *args, **kwargs):
"""Initialize the form, populate interface choices."""
super(AddPPPoEForm, self).__init__(*args, **kwargs)
choices = _get_interface_choices(nm.DeviceType.ETHERNET)
self.fields['interface'].choices = choices
class AddWifiForm(forms.Form): class AddWifiForm(forms.Form):
"""Form to create a new wifi connection.""" """Form to create a new wifi connection."""
name = forms.CharField(label=_('Connection Name')) name = forms.CharField(label=_('Connection Name'))

View File

@ -23,6 +23,7 @@ from gettext import gettext as _
from logging import Logger from logging import Logger
from .forms import ConnectionTypeSelectForm, AddEthernetForm, AddWifiForm from .forms import ConnectionTypeSelectForm, AddEthernetForm, AddWifiForm
from .forms import AddPPPoEForm
from plinth import cfg from plinth import cfg
from plinth import network from plinth import network
from plinth import package from plinth import package
@ -70,8 +71,10 @@ def edit(request, uuid):
if request.method == 'POST': if request.method == 'POST':
if connection.get_connection_type() == '802-11-wireless': if connection.get_connection_type() == '802-11-wireless':
form = AddWifiForm(request.POST) form = AddWifiForm(request.POST)
else: elif connection.get_connection_type() == '802-3-ethernet':
form = AddEthernetForm(request.POST) form = AddEthernetForm(request.POST)
elif connection.get_connection_type() == 'pppoe':
form = AddPPPoEForm(request.POST)
if form.is_valid(): if form.is_valid():
name = form.cleaned_data['name'] name = form.cleaned_data['name']
@ -79,6 +82,8 @@ def edit(request, uuid):
zone = form.cleaned_data['zone'] zone = form.cleaned_data['zone']
ipv4_method = form.cleaned_data['ipv4_method'] ipv4_method = form.cleaned_data['ipv4_method']
ipv4_address = form.cleaned_data['ipv4_address'] ipv4_address = form.cleaned_data['ipv4_address']
username = form.cleaned_data['username']
password = form.cleaned_data['password']
if connection.get_connection_type() == '802-3-ethernet': if connection.get_connection_type() == '802-3-ethernet':
network.edit_ethernet_connection( network.edit_ethernet_connection(
@ -93,6 +98,9 @@ def edit(request, uuid):
network.edit_wifi_connection( network.edit_wifi_connection(
connection, name, interface, zone, ssid, mode, auth_mode, connection, name, interface, zone, ssid, mode, auth_mode,
passphrase, ipv4_method, ipv4_address) passphrase, ipv4_method, ipv4_address)
elif connection.get_connection_type() == 'pppoe':
network.edit_pppoe_connection(
connection, name, interface, zone, username, password)
return redirect(reverse_lazy('networks:index')) return redirect(reverse_lazy('networks:index'))
else: else:
@ -103,6 +111,7 @@ def edit(request, uuid):
else: else:
settings_connection = connection.get_setting_connection() settings_connection = connection.get_setting_connection()
settings_ipv4 = connection.get_setting_ip4_config() settings_ipv4 = connection.get_setting_ip4_config()
settings_pppoe = connection.get_setting_pppoe()
form_data['interface'] = connection.get_interface_name() form_data['interface'] = connection.get_interface_name()
try: try:
form_data['zone'] = settings_connection.get_zone() form_data['zone'] = settings_connection.get_zone()
@ -110,6 +119,12 @@ def edit(request, uuid):
form_data['zone'] = 'external' form_data['zone'] = 'external'
form_data['ipv4_method'] = settings_ipv4.get_method() form_data['ipv4_method'] = settings_ipv4.get_method()
if not settings_pppoe:
form_data['username'] = ''
form_data['password'] = ''
else:
form_data['username'] = settings_pppoe.get_username()
form_data['password'] = settings_pppoe.get_password()
if settings_ipv4.get_num_addresses(): if settings_ipv4.get_num_addresses():
# XXX: Plinth crashes here. Possibly because a double free bug # XXX: Plinth crashes here. Possibly because a double free bug
@ -136,8 +151,10 @@ def edit(request, uuid):
form_data['auth_mode'] = 'open' form_data['auth_mode'] = 'open'
form = AddWifiForm(form_data) form = AddWifiForm(form_data)
else: elif settings_connection.get_connection_type() == '802-3-ethernet':
form = AddEthernetForm(form_data) form = AddEthernetForm(form_data)
elif settings_connection.get_connection_type() == 'pppoe':
form = AddPPPoEForm(form_data)
return TemplateResponse(request, 'connections_edit.html', return TemplateResponse(request, 'connections_edit.html',
{'title': _('Edit Connection'), {'title': _('Edit Connection'),
@ -196,6 +213,8 @@ def add(request):
return redirect(reverse_lazy('networks:add_ethernet')) return redirect(reverse_lazy('networks:add_ethernet'))
elif connection_type == '802-11-wireless': elif connection_type == '802-11-wireless':
return redirect(reverse_lazy('networks:add_wifi')) return redirect(reverse_lazy('networks:add_wifi'))
elif connection_type == 'pppoe':
return redirect(reverse_lazy('networks:add_pppoe'))
else: else:
form = ConnectionTypeSelectForm() form = ConnectionTypeSelectForm()
return TemplateResponse(request, 'connections_type_select.html', return TemplateResponse(request, 'connections_type_select.html',
@ -229,6 +248,31 @@ def add_ethernet(request):
'form': form}) 'form': form})
def add_pppoe(request):
"""Serve pppoe connection create form."""
form = None
if request.method == 'POST':
form = AddPPPoEForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
interface = form.cleaned_data['interface']
zone = form.cleaned_data['zone']
username = form.cleaned_data['username']
password = form.cleaned_data['password']
network.add_pppoe_connection(
name, interface, zone, username, password)
return redirect(reverse_lazy('networks:index'))
else:
form = AddPPPoEForm()
return TemplateResponse(request, 'connections_create.html',
{'title': _('Adding New PPPoE Connection'),
'subsubmenu': subsubmenu,
'form': form})
def add_wifi(request, ssid=None): def add_wifi(request, ssid=None):
"""Serve wifi connection create form.""" """Serve wifi connection create form."""
form = None form = None

View File

@ -34,6 +34,7 @@ urlpatterns = patterns(
url(r'^sys/networks/scan/$', 'scan', name='scan'), url(r'^sys/networks/scan/$', 'scan', name='scan'),
url(r'^sys/networks/add/$', 'add', name='add'), url(r'^sys/networks/add/$', 'add', name='add'),
url(r'^sys/networks/add/ethernet/$', 'add_ethernet', name='add_ethernet'), url(r'^sys/networks/add/ethernet/$', 'add_ethernet', name='add_ethernet'),
url(r'^sys/networks/add/pppoe/$', 'add_pppoe', name='add_pppoe'),
url(r'^sys/networks/add/wifi/(?:(?P<ssid>[^/]+)/)?$', 'add_wifi', url(r'^sys/networks/add/wifi/(?:(?P<ssid>[^/]+)/)?$', 'add_wifi',
name='add_wifi'), name='add_wifi'),
url(r'^sys/networks/(?P<uuid>[\w.@+-]+)/delete/$', url(r'^sys/networks/(?P<uuid>[\w.@+-]+)/delete/$',

View File

@ -32,6 +32,7 @@ logger = logging.getLogger(__name__)
CONNECTION_TYPE_NAMES = { CONNECTION_TYPE_NAMES = {
'802-3-ethernet': 'Ethernet', '802-3-ethernet': 'Ethernet',
'802-11-wireless': 'Wi-Fi', '802-11-wireless': 'Wi-Fi',
'pppoe': 'PPPoE',
} }
@ -127,8 +128,8 @@ def get_active_connection(connection_uuid):
raise ConnectionNotFound(connection_uuid) raise ConnectionNotFound(connection_uuid)
def _update_common_settings(connection, connection_uuid, name, type_, interface, def _update_common_settings(connection, connection_uuid, name, type_,
zone, ipv4_method, ipv4_address): interface, zone, ipv4_method, ipv4_address):
"""Create/edit basic settings for network manager connections.""" """Create/edit basic settings for network manager connections."""
if not connection: if not connection:
connection = nm.SimpleConnection.new() connection = nm.SimpleConnection.new()
@ -184,6 +185,59 @@ def _update_ethernet_settings(connection, connection_uuid, name, interface,
return connection return connection
def _update_pppoe_settings(connection, connection_uuid, name, interface, zone,
username, password):
"""Create/edit ethernet settings for network manager connections."""
type_ = 'pppoe'
connection = _update_common_settings(connection, connection_uuid, name,
type_, interface, zone, 'auto',
'0.0.0.0')
#pppoe
settings = connection.get_setting_pppoe()
if not settings:
settings = nm.SettingPppoe.new()
settings.set_property(nm.SETTING_PPPOE_USERNAME, username)
settings.set_property(nm.SETTING_PPPOE_PASSWORD, password)
connection.add_setting(settings)
settings = connection.get_setting_ppp()
if not settings:
settings = nm.SettingPpp.new()
#ToDo: make this configurable?
#ToDo: apt-get install ppp pppoe
settings.set_property(nm.SETTING_PPP_LCP_ECHO_FAILURE, 5)
settings.set_property(nm.SETTING_PPP_LCP_ECHO_INTERVAL, 30)
connection.add_setting(settings)
return connection
def add_pppoe_connection(name, interface, zone, username, password):
"""Add an automatic pppoe connection in network manager.
Return the UUID for the connection.
"""
connection_uuid = str(uuid.uuid4())
connection = _update_pppoe_settings(
None, connection_uuid, name, interface, zone, username, password)
client = nm.Client.new(None)
client.add_connection_async(connection, True, None, _callback, None)
return connection_uuid
def edit_pppoe_connection(connection, name, interface, zone, username,
password):
"""Edit an existing pppoe connection in network manager."""
_update_pppoe_settings(
connection, connection.get_uuid(), name, interface, zone, username,
password)
connection.commit_changes(True)
def add_ethernet_connection(name, interface, zone, ipv4_method, ipv4_address): def add_ethernet_connection(name, interface, zone, ipv4_method, ipv4_address):
"""Add an automatic ethernet connection in network manager. """Add an automatic ethernet connection in network manager.
@ -272,6 +326,11 @@ def activate_connection(connection_uuid):
# Find the connection # Find the connection
connection = get_connection(connection_uuid) connection = get_connection(connection_uuid)
# ToDo: is the following code still needed? Because the connections
# are bound to an interface and for this reason, the device name should
# be available within connection object. So simply use:
# connection.get_interface_name() ??
# Find a suitable device # Find a suitable device
client = nm.Client.new(None) client = nm.Client.new(None)
connection_type = connection.get_connection_type() connection_type = connection.get_connection_type()