Skip to content

Commit

Permalink
bugfix/247 Improve Zerotier Start/Stop Behaviour
Browse files Browse the repository at this point in the history
#247

This commit improves upon the way that Zerotier starts and stops and how
networks are added/removed and activated/deactivated. There is now a "Global"
tab on the Zerotier page that enables or disables the service which is
honoured between reboots. Additionally, the service needs to be active in
order for networks to be added and removed. If the service is not active, then
the tab "Networks" will be disabled and the user will not be able to
add/remove or activate/deactivate Zerotier networks.

This should fix the observed problems raised in the issue.

The "Global" tab will be extended later to include further information and
actions, especially when Zerotier API usage is developed.

-=david=-
  • Loading branch information
dharrigan authored and fichtner committed Sep 11, 2017
1 parent a2f3413 commit 3fdca05
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 69 deletions.
2 changes: 1 addition & 1 deletion net/zerotier/Makefile
@@ -1,5 +1,5 @@
PLUGIN_NAME= zerotier
PLUGIN_VERSION= 1.0
PLUGIN_VERSION= 1.1.0
PLUGIN_COMMENT= Virtual Networks That Just Work
PLUGIN_DEPENDS= zerotier
PLUGIN_MAINTAINER= dharrigan@gmail.com
Expand Down
11 changes: 2 additions & 9 deletions net/zerotier/src/etc/inc/plugins.inc.d/zerotier.inc
Expand Up @@ -29,15 +29,8 @@

function zerotier_enabled()
{
$mdl = new \OPNsense\Zerotier\Zerotier();

foreach ($mdl->networks->network->__items as $network) {
if ($network->enabled == '1') {
return true;
}
}

return false;
$zerotier = new \OPNsense\Zerotier\Zerotier();
return (string)$zerotier->enabled == '1';
}

function zerotier_services()
Expand Down
Expand Up @@ -45,12 +45,26 @@ public function getAction()
{
$result = array();
if ($this->request->isGet()) {
$mdlZerotier = new Zerotier();
$mdlZerotier = $this->getModel();
$result['zerotier'] = $mdlZerotier->getNodes();
}
return $result;
}

public function setAction()
{
$result = array("result" => "failed");
if($this->request->isPost()) {
$mdlZerotier = $this->getModel();
$mdlZerotier->setNodes($this->request->getPost("zerotier"));
$mdlZerotier->serializeToConfig();
Config::getInstance()->save();
$enabled = $this->isEnabled($mdlZerotier);
$result["result"] = $this->toggleZerotierService($enabled);
}
return $result;
}

public function searchNetworkAction()
{
$this->sessionClose();
Expand Down Expand Up @@ -129,8 +143,12 @@ public function delNetworkAction($uuid = null)
if ($this->request->isPost()) {
$mdlZerotier = $this->getModel();
if ($uuid != null) {
if (!$this->isEnabled($mdlZerotier)) {
$result["result"] = "service_not_enabled";
return $result;
}
$node = $mdlZerotier->getNodeByReference('networks.network.' . $uuid);
if ($node->enabled->__toString() == "1") {
if ($this->isEnabled($node)) {
# Ensure we remove the interface before deleting the network
$this->toggleZerotierNetwork($node->networkId, 0);
}
Expand All @@ -139,7 +157,7 @@ public function delNetworkAction($uuid = null)
Config::getInstance()->save();
$result["result"] = "deleted";
} else {
$result["result"] = "not found";
$result["result"] = "not_found";
}
}
}
Expand All @@ -152,10 +170,14 @@ public function toggleNetworkAction($uuid)
if ($this->request->isPost()) {
$mdlZerotier = $this->getModel();
if ($uuid != null) {
if (!$this->isEnabled($mdlZerotier)) {
$result["result"] = "service_not_enabled";
return $result;
}
$node = $mdlZerotier->getNodeByReference('networks.network.' . $uuid);
if ($node != null) {
$networkId = $node->networkId;
if ($node->enabled->__toString() == "1") {
if ($this->isEnabled($node)) {
$node->enabled = "0";
$result['result'] = $this->toggleZerotierNetwork($networkId, 0);
} else {
Expand All @@ -170,34 +192,13 @@ public function toggleNetworkAction($uuid)
return $result;
}

public function reconfigureZerotierAction()
{
if ($this->request->isPost()) {
$this->sessionClose();
$backend = new Backend();
$backend->configdRun("template reload OPNsense/zerotier");
$mdlZerotier = $this->getModel();
$action = 'stop';
foreach ($mdlZerotier->networks->network->__items as $network) {
if ($network->enabled == '1') {
$action = 'restart';
break;
}
}
$result = trim($backend->configdRun("zerotier $action"));
return array("status" => $result);
} else {
return array("status" => "failed");
}
}

public function statusAction()
{
$mdlZerotier = $this->getModel();
$enabled = false;

foreach ($mdlZerotier->networks->network->__items as $network) {
if ($network->enabled == '1') {
if ($this->isEnabled($network)) {
$enabled = true;
break;
}
Expand All @@ -220,7 +221,7 @@ public function statusAction()
$status = "unknown";
}

return array("status" => $status);
return array("result" => $status);
}

private function toggleZerotierNetwork($networkId, $enabled)
Expand All @@ -229,4 +230,18 @@ private function toggleZerotierNetwork($networkId, $enabled)
$action = $enabled ? 'join' : 'leave';
return trim($backend->configdRun("zerotier $action $networkId"));
}

private function toggleZerotierService($enabled)
{
$backend = new Backend();
$backend->configdRun("template reload OPNsense/zerotier");
$action = $enabled ? "start" : "stop";
return trim($backend->configdRun("zerotier $action"));
}

private function isEnabled($node)
{
return $node->enabled->__toString() == "1";
}

}
Expand Up @@ -35,6 +35,7 @@ public function indexAction()
{
$this->view->title = "VPN: Zerotier";
$this->view->pick('OPNsense/Zerotier/index');
$this->view->formDialogNetwork = $this->getForm("dialogNetwork");
$this->view->globalForm = $this->getForm("global");
$this->view->dialogNetworkForm = $this->getForm("dialogNetwork");
}
}
@@ -0,0 +1,8 @@
<form>
<field>
<id>zerotier.enabled</id>
<label>Enable the Zerotier Service</label>
<type>checkbox</type>
<help>This will activate the Zerotier service</help>
</field>
</form>
Expand Up @@ -3,7 +3,12 @@
<description>
Zerotier - Virtual Networks That Just Work.
</description>
<version>1.1.0</version>
<items>
<enabled type="BooleanField">
<default>0</default>
<Required>Y</Required>
</enabled>
<networks>
<network type="ArrayField">
<enabled type="BooleanField">
Expand Down
Expand Up @@ -31,6 +31,13 @@ POSSIBILITY OF SUCH DAMAGE.

$(document).ready(function() {

var zerotierSettings = {'global': '/api/zerotier/zerotier/get'};

mapDataToFormUI(zerotierSettings).done(function(data) {
formatTokenizersUI();
$('select').selectpicker('refresh');
});

$("#grid-networks").UIBootgrid(
{
search: '/api/zerotier/zerotier/searchNetwork',
Expand All @@ -42,37 +49,55 @@ POSSIBILITY OF SUCH DAMAGE.
}
);

ajaxCall(url="/api/zerotier/zerotier/status", sendData={}, callback=function(data,status) {
updateServiceStatusUI(data['status']);
ajaxCall(url="/api/zerotier/zerotier/status", sendData={}, callback=function(data, status) {
updateServiceStatusUI(data['result']);
toggleNetworksTab(data['result']);
});

$("#reconfigureZerotier").click(function() {
$("#reconfigureZerotierProgress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url="/api/zerotier/zerotier/reconfigureZerotier", sendData={}, callback=function(data, status) {
ajaxCall(url="/api/zerotier/zerotier/status", sendData={}, callback=function(data,status) {
updateServiceStatusUI(data['status']);
$("#save").click(function() {
$("#saveProgress").addClass("fa fa-spinner fa-pulse");
saveFormToEndpoint(url="/api/zerotier/zerotier/set", formid="global", callback_ok=function(data, status) {
ajaxCall(url="/api/zerotier/zerotier/status", sendData={}, callback=function(data, status) {
updateServiceStatusUI(data['result']);
toggleNetworksTab(data['result']);
});
$("#reconfigureZerotierProgress").removeClass("fa fa-spinner fa-pulse");
if (status != "success" || data['status'] != 'OK') {
BootstrapDialog.show({
type: BootstrapDialog.TYPE_WARNING,
title: "{{ lang._('Error reconfiguring Zerotier') }}",
message: data['status'],
draggable: true
});
}
$("#saveProgress").removeClass("fa fa-spinner fa-pulse");
});
});

function toggleNetworksTab(status) {
switch(status) {
case "disabled":
case "service_not_enabled":
$('#ztNetworks').addClass("disabled");
$('#ztNetworksLink').removeAttr("data-toggle");
break;
default:
$('#ztNetworks').removeClass("disabled");
$('#ztNetworksLink').attr("data-toggle", "tab");
}
};

});

</script>

<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
<li class="active"><a data-toggle="tab" href="#networks">{{ lang._('Networks') }}</a></li>
<li id="ztGlobal" class="active"><a data-toggle="tab" href="#global">{{ lang._('Global') }}</a></li>
<li id="ztNetworks"><a id="ztNetworksLink" data-toggle="tab" href="#networks">{{ lang._('Networks') }}</a></li>
</ul>

<div class="tab-content content-box tab-content">
<div id="networks" class="tab-pane fade in active">
<div id="global" class="tab-pane fade in active">
<div class="content-box" style="padding-bottom: 1.5em;">
{{ partial("layout_partials/base_form", ['fields': globalForm, 'id': 'global']) }}
<hr/>
<div class="col-md-12">
<button class="btn btn-primary" id="save" type="button"><b>{{ lang._('Save') }}</b> <i id="saveProgress" class=""></i></button>
</div>
</div>
</div>
<div id="networks" class="tab-pane fade in">
<table id="grid-networks" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="dialogNetwork">
<thead>
<tr>
Expand All @@ -95,11 +120,6 @@ POSSIBILITY OF SUCH DAMAGE.
</tfoot>
</table>
</div>
<div class="col-md-12">
<hr/>
<button class="btn btn-primary" id="reconfigureZerotier" type="button"><b>{{ lang._('Apply') }}</b> <i id="reconfigureZerotierProgress" class=""></i></button>
<br/><br/>
</div>
</div>

{{ partial("layout_partials/base_dialog",['fields':formDialogNetwork,'id':'dialogNetwork','label':lang._('Edit Zerotier Network')]) }}
{{ partial("layout_partials/base_dialog", ['fields': dialogNetworkForm, 'id': 'dialogNetwork', 'label': lang._('Edit Zerotier Network')]) }}
@@ -1,10 +1,4 @@
{% set networks = [] %}
{% for network in helpers.toList('OPNsense.zerotier.networks.network') %}
{% if network.enabled == '1' %}
{% do networks.append(network) %}
{% endif %}
{% endfor %}
{% if networks|length > 0 %}
{% if helpers.exists('OPNsense.zerotier.enabled') and OPNsense.zerotier.enabled == '1' %}
zerotier_enable="YES"
{% else %}
zerotier_enable="NO"
Expand Down

0 comments on commit 3fdca05

Please sign in to comment.