mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
net/zerotier: Add Basic API Functionality (#320)
This commit brings basic API functionality to the Zerotier plugin. It allows the user to retrieve "Global" Zerotier information, peers that are talking with this node and details on configured (and enabled) networks. This version of the plugin provides a space for the Zerotier API key to be input and saved, but it is not used for Basic API functionality. The zerotier-cli client is used directly to query for global, peers and network information. If the API functionality is extended to allow for creating and modifying Zerotier information from this plugin, then the API key will be required at that point. It is introduced here for the sake of convenience for later down the line. Various other small changes include general code cleanups, renaming of some UI facing labels and improved layout design. -=david=- Fixes: #260
This commit is contained in:
committed by
Franco Fichtner
parent
fda078dd4d
commit
5060f5c95c
@@ -1,5 +1,5 @@
|
||||
PLUGIN_NAME= zerotier
|
||||
PLUGIN_VERSION= 1.2.0
|
||||
PLUGIN_VERSION= 1.3.0
|
||||
PLUGIN_COMMENT= Virtual Networks That Just Work
|
||||
PLUGIN_DEPENDS= zerotier
|
||||
PLUGIN_MAINTAINER= dharrigan@gmail.com
|
||||
|
||||
@@ -29,8 +29,13 @@
|
||||
|
||||
function zerotier_enabled()
|
||||
{
|
||||
$zerotier = new \OPNsense\Zerotier\Zerotier();
|
||||
return (string)$zerotier->enabled == '1';
|
||||
$mdlZerotier = new \OPNsense\Zerotier\Zerotier();
|
||||
return isEnabled($mdlZerotier);
|
||||
}
|
||||
|
||||
function isEnabled($node)
|
||||
{
|
||||
return $node->enabled->__toString() == "1";
|
||||
}
|
||||
|
||||
function zerotier_services()
|
||||
|
||||
+68
-95
@@ -29,43 +29,21 @@
|
||||
|
||||
namespace OPNsense\Zerotier\Api;
|
||||
|
||||
require_once 'plugins.inc.d/zerotier.inc';
|
||||
|
||||
use \OPNsense\Base\ApiMutableModelControllerBase;
|
||||
use \OPNsense\Base\UIModelGrid;
|
||||
use \OPNsense\Core\Backend;
|
||||
use \OPNsense\Core\Config;
|
||||
use \OPNsense\Zerotier\Zerotier;
|
||||
|
||||
class ZerotierController extends ApiMutableModelControllerBase
|
||||
class NetworkController extends ApiMutableModelControllerBase
|
||||
{
|
||||
|
||||
static protected $internalModelName = 'Zerotier';
|
||||
static protected $internalModelClass = '\OPNsense\Zerotier\Zerotier';
|
||||
|
||||
public function getAction()
|
||||
{
|
||||
$result = array();
|
||||
if ($this->request->isGet()) {
|
||||
$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()
|
||||
public function searchAction()
|
||||
{
|
||||
$this->sessionClose();
|
||||
$mdlZerotier = $this->getModel();
|
||||
@@ -76,7 +54,7 @@ class ZerotierController extends ApiMutableModelControllerBase
|
||||
);
|
||||
}
|
||||
|
||||
public function getNetworkAction($uuid = null)
|
||||
public function getAction($uuid = null)
|
||||
{
|
||||
$mdlZerotier = $this->getModel();
|
||||
if ($uuid != null) {
|
||||
@@ -91,30 +69,52 @@ class ZerotierController extends ApiMutableModelControllerBase
|
||||
return array();
|
||||
}
|
||||
|
||||
public function setNetworkAction()
|
||||
public function infoAction($uuid = null)
|
||||
{
|
||||
$mdlZerotier = $this->getModel();
|
||||
if ($uuid != null) {
|
||||
$network = $mdlZerotier->getNodeByReference('networks.network.' . $uuid);
|
||||
if ($network != null) {
|
||||
$networkId = $network->networkId->__toString();
|
||||
return array
|
||||
(
|
||||
"title" => gettext("Information on network") . " " . $networkId,
|
||||
"message" => $this->listZerotierNetwork($networkId)
|
||||
);
|
||||
}
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public function setAction($uuid = null)
|
||||
{
|
||||
$result = array("result" => "failed");
|
||||
if ($this->request->isPost()) {
|
||||
$mdlZerotier = new Zerotier();
|
||||
$mdlZerotier->setNodes($this->request->getPost("network"));
|
||||
$validationMessages = $mdlZerotier->performValidation();
|
||||
foreach ($validationMessages as $field => $msg) {
|
||||
if (!array_key_exists("validation", $result)) {
|
||||
$result["validations"] = array();
|
||||
if ($this->request->isPost() && $this->request->hasPost("network")) {
|
||||
if($uuid != null) {
|
||||
$mdlZerotier = $this->getModel();
|
||||
$network = $mdlZerotier->getNodeByReference('networks.network.' . $uuid);
|
||||
if($network != null) {
|
||||
$network->setNodes($this->request->getPost("network"));
|
||||
$validationMessages = $mdlZerotier->performValidation();
|
||||
foreach ($validationMessages as $field => $msg) {
|
||||
if (!array_key_exists("validation", $result)) {
|
||||
$result["validations"] = array();
|
||||
}
|
||||
$result["validation"]["network.".$msg->getField()] = $msg->getMessage();
|
||||
}
|
||||
if ($validationMessages->count() == 0) {
|
||||
unset($result["validations"]);
|
||||
$mdlZerotier->serializeToConfig();
|
||||
Config::getInstance()->save();
|
||||
$result["result"] = "saved";
|
||||
}
|
||||
}
|
||||
$result["validation"]["network.".$msg->getField()] = $msg->getMessage();
|
||||
}
|
||||
if ($validationMessages->count() == 0) {
|
||||
unset($result["validations"]);
|
||||
$mdlZerotier->serializeToConfig();
|
||||
Config::getInstance()->save();
|
||||
$result["result"] = "saved";
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function addNetworkAction()
|
||||
public function addAction()
|
||||
{
|
||||
$result = array("result" => "failed");
|
||||
if ($this->request->isPost() && $this->request->hasPost("network")) {
|
||||
@@ -137,20 +137,20 @@ class ZerotierController extends ApiMutableModelControllerBase
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function delNetworkAction($uuid = null)
|
||||
public function delAction($uuid = null)
|
||||
{
|
||||
$result = array("result" => "failed");
|
||||
if ($this->request->isPost()) {
|
||||
$mdlZerotier = $this->getModel();
|
||||
if ($uuid != null) {
|
||||
if (!$this->isEnabled($mdlZerotier)) {
|
||||
$mdlZerotier = $this->getModel();
|
||||
if (!isEnabled($mdlZerotier)) {
|
||||
$result["result"] = "service_not_enabled";
|
||||
return $result;
|
||||
}
|
||||
$node = $mdlZerotier->getNodeByReference('networks.network.' . $uuid);
|
||||
if ($this->isEnabled($node)) {
|
||||
$network = $mdlZerotier->getNodeByReference('networks.network.' . $uuid);
|
||||
if (isEnabled($network)) {
|
||||
# Ensure we remove the interface before deleting the network
|
||||
$this->toggleZerotierNetwork($node->networkId, 0);
|
||||
$this->toggleZerotierNetwork($network->networkId, 0);
|
||||
}
|
||||
if ($mdlZerotier->networks->network->del($uuid)) {
|
||||
$mdlZerotier->serializeToConfig();
|
||||
@@ -164,24 +164,24 @@ class ZerotierController extends ApiMutableModelControllerBase
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function toggleNetworkAction($uuid)
|
||||
public function toggleAction($uuid = null)
|
||||
{
|
||||
$result = array("result" => "failed");
|
||||
if ($this->request->isPost()) {
|
||||
$mdlZerotier = $this->getModel();
|
||||
if ($uuid != null) {
|
||||
if (!$this->isEnabled($mdlZerotier)) {
|
||||
$mdlZerotier = $this->getModel();
|
||||
if (!isEnabled($mdlZerotier)) {
|
||||
$result["result"] = "service_not_enabled";
|
||||
return $result;
|
||||
}
|
||||
$node = $mdlZerotier->getNodeByReference('networks.network.' . $uuid);
|
||||
if ($node != null) {
|
||||
$networkId = $node->networkId;
|
||||
if ($this->isEnabled($node)) {
|
||||
$node->enabled = "0";
|
||||
$network = $mdlZerotier->getNodeByReference('networks.network.' . $uuid);
|
||||
if ($network != null) {
|
||||
$networkId = $network->networkId;
|
||||
if (isEnabled($network)) {
|
||||
$network->enabled = "0";
|
||||
$result['result'] = $this->toggleZerotierNetwork($networkId, 0);
|
||||
} else {
|
||||
$node->enabled = "1";
|
||||
$network->enabled = "1";
|
||||
$result['result'] = $this->toggleZerotierNetwork($networkId, 1);
|
||||
}
|
||||
$mdlZerotier->serializeToConfig();
|
||||
@@ -192,49 +192,22 @@ class ZerotierController extends ApiMutableModelControllerBase
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function statusAction()
|
||||
{
|
||||
$mdlZerotier = $this->getModel();
|
||||
$enabled = (string)$mdlZerotier->enabled == '1';
|
||||
|
||||
$backend = new Backend();
|
||||
$response = $backend->configdRun('zerotier status');
|
||||
|
||||
if (strpos($response, "not running") > 0) {
|
||||
if ($enabled) {
|
||||
$status = "stopped";
|
||||
} else {
|
||||
$status = "disabled";
|
||||
}
|
||||
} elseif (strpos($response, "is running") > 0) {
|
||||
$status = "running";
|
||||
} elseif (!$enabled) {
|
||||
$status = "disabled";
|
||||
} else {
|
||||
$status = "unknown";
|
||||
}
|
||||
|
||||
return array("result" => $status);
|
||||
}
|
||||
|
||||
private function toggleZerotierNetwork($networkId, $enabled)
|
||||
{
|
||||
$backend = new Backend();
|
||||
$action = $enabled ? 'join' : 'leave';
|
||||
return trim($backend->configdRun("zerotier $action $networkId"));
|
||||
return trim((new Backend())->configdRun("zerotier $action $networkId"));
|
||||
}
|
||||
|
||||
private function toggleZerotierService($enabled)
|
||||
private function listZerotierNetwork($networkId)
|
||||
{
|
||||
$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";
|
||||
$zerotierNetworks = trim((new Backend())->configdRun("zerotier listnetworks"));
|
||||
$zerotierNetworks = explode("200 listnetworks", $zerotierNetworks);
|
||||
foreach($zerotierNetworks as $zerotierNetwork) {
|
||||
if(strpos($zerotierNetwork, $networkId) !== false) {
|
||||
return $zerotierNetwork;
|
||||
}
|
||||
}
|
||||
return gettext("Unable to obtain Zerotier information for network") . " " . $networkId . "! " . gettext("Is the network enabled?");
|
||||
}
|
||||
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 David Harrigan
|
||||
* Copyright (C) 2017 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Zerotier\Api;
|
||||
|
||||
require_once 'plugins.inc.d/zerotier.inc';
|
||||
|
||||
use \OPNsense\Base\ApiMutableModelControllerBase;
|
||||
use \OPNsense\Base\UIModelGrid;
|
||||
use \OPNsense\Core\Backend;
|
||||
use \OPNsense\Core\Config;
|
||||
use \OPNsense\Zerotier\Zerotier;
|
||||
|
||||
class SettingsController extends ApiMutableModelControllerBase
|
||||
{
|
||||
|
||||
static protected $internalModelName = 'Zerotier';
|
||||
static protected $internalModelClass = '\OPNsense\Zerotier\Zerotier';
|
||||
|
||||
public function getAction()
|
||||
{
|
||||
$result = array();
|
||||
if ($this->request->isGet()) {
|
||||
$mdlZerotier = $this->getModel();
|
||||
$result = array("zerotier" => $mdlZerotier->getNodes());
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function setAction()
|
||||
{
|
||||
$result = array("result" => "failed");
|
||||
if($this->request->isPost() && $this->request->hasPost("zerotier")) {
|
||||
$mdlZerotier = $this->getModel();
|
||||
$mdlZerotier->setNodes($this->request->getPost("zerotier"));
|
||||
$mdlZerotier->serializeToConfig();
|
||||
Config::getInstance()->save();
|
||||
$enabled = isEnabled($mdlZerotier);
|
||||
$result["result"] = $this->toggleZerotierService($enabled);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function statusAction()
|
||||
{
|
||||
$mdlZerotier = $this->getModel();
|
||||
$enabled = isEnabled($mdlZerotier);
|
||||
|
||||
$response = trim((new Backend())->configdRun('zerotier status'));
|
||||
|
||||
if (strpos($response, "not running") > 0) {
|
||||
if (isEnabled($mdlZerotier)) {
|
||||
$status = "stopped";
|
||||
} else {
|
||||
$status = "disabled";
|
||||
}
|
||||
} elseif (strpos($response, "is running") > 0) {
|
||||
$status = "running";
|
||||
} elseif (!$enabled) {
|
||||
$status = "disabled";
|
||||
} else {
|
||||
$status = "unknown";
|
||||
}
|
||||
|
||||
return array("result" => $status);
|
||||
}
|
||||
|
||||
private function toggleZerotierService($enabled)
|
||||
{
|
||||
$backend = new Backend();
|
||||
$backend->configdRun("template reload OPNsense/zerotier");
|
||||
$action = $enabled ? "start" : "stop";
|
||||
return trim($backend->configdRun("zerotier $action"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,9 +33,9 @@ class IndexController extends \OPNsense\Base\IndexController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->title = "VPN: Zerotier";
|
||||
$this->view->title = gettext("VPN : Zerotier : Settings");
|
||||
$this->view->pick('OPNsense/Zerotier/index');
|
||||
$this->view->globalForm = $this->getForm("global");
|
||||
$this->view->settingsForm = $this->getForm("settings");
|
||||
$this->view->dialogNetworkForm = $this->getForm("dialogNetwork");
|
||||
}
|
||||
}
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2017 David Harrigan
|
||||
* Copyright (C) 2017 Deciso B.V.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
namespace OPNsense\Zerotier;
|
||||
|
||||
require_once 'plugins.inc.d/zerotier.inc';
|
||||
|
||||
use \OPNsense\Core\Backend;
|
||||
|
||||
class OverviewController extends \OPNsense\Base\IndexController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->title = gettext("VPN : Zerotier : Overview");
|
||||
$this->view->pick('OPNsense/Zerotier/overview');
|
||||
$this->view->information = $this->information();
|
||||
$this->view->networks = $this->listNetworks();
|
||||
$this->view->peers = $this->listPeers();
|
||||
}
|
||||
|
||||
private function information()
|
||||
{
|
||||
return $this->invokeConfigdRun("info_json");
|
||||
}
|
||||
|
||||
private function listNetworks()
|
||||
{
|
||||
return $this->invokeConfigdRun("listnetworks_json");
|
||||
}
|
||||
|
||||
private function listPeers()
|
||||
{
|
||||
return $this->invokeConfigdRun("listpeers_json");
|
||||
}
|
||||
|
||||
private function invokeConfigdRun($action)
|
||||
{
|
||||
if(!zerotier_enabled()) {
|
||||
return (object)[];
|
||||
}
|
||||
$result = json_decode(trim((new Backend())->configdRun("zerotier $action")), true);
|
||||
return $result !== null ? $result : (object)[];
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -7,8 +7,8 @@
|
||||
</field>
|
||||
<field>
|
||||
<id>network.description</id>
|
||||
<label>Description</label>
|
||||
<label>Local Description</label>
|
||||
<type>text</type>
|
||||
<help>Description to help identify this network</help>
|
||||
<help>Local Description to help identify this network</help>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
+7
-2
@@ -5,12 +5,17 @@
|
||||
<type>checkbox</type>
|
||||
<help>This will activate the Zerotier service</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>zerotier.apiAccessToken</id>
|
||||
<label>API Access Token</label>
|
||||
<type>text</type>
|
||||
<help>Access Token used for the Zerotier API service</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>zerotier.localconf</id>
|
||||
<label>local.conf settings</label>
|
||||
<type>textbox</type>
|
||||
<height>10</height>
|
||||
<help>Contains configuration options that apply to the local node</help>
|
||||
<help>A JSON document containing configuration options that apply to the local node</help>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<menu>
|
||||
<VPN>
|
||||
<Zerotier order="30" VisibleName="Zerotier" cssClass="fa fa-lock fa-fw" url="/ui/zerotier/"/>
|
||||
<Zerotier order="30" VisibleName="Zerotier" cssClass="fa fa-lock fa-fw">
|
||||
<Settings order="40" VisibleName="Settings" url="/ui/zerotier/"/>
|
||||
<Overview order="50" VisibleName="Overview" url="/ui/zerotier/overview/"/>
|
||||
</Zerotier>
|
||||
</VPN>
|
||||
</menu>
|
||||
|
||||
@@ -3,12 +3,16 @@
|
||||
<description>
|
||||
Zerotier - Virtual Networks That Just Work.
|
||||
</description>
|
||||
<version>1.2.0</version>
|
||||
<version>1.3.0</version>
|
||||
<items>
|
||||
<enabled type="BooleanField">
|
||||
<default>0</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
<apiAccessToken type="TextField">
|
||||
<default></default>
|
||||
<Required>N</Required>
|
||||
</apiAccessToken>
|
||||
<localconf type="TextField">
|
||||
<Required>N</Required>
|
||||
</localconf>
|
||||
|
||||
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
var zerotierSettings = {'global': '/api/zerotier/zerotier/get'};
|
||||
var zerotierSettings = {'settings': '/api/zerotier/settings/get'};
|
||||
|
||||
mapDataToFormUI(zerotierSettings).done(function(data) {
|
||||
formatTokenizersUI();
|
||||
@@ -40,28 +40,29 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
$("#grid-networks").UIBootgrid(
|
||||
{
|
||||
search: '/api/zerotier/zerotier/searchNetwork',
|
||||
get:'/api/zerotier/zerotier/getNetwork/',
|
||||
set:'/api/zerotier/zerotier/setNetwork/',
|
||||
add:'/api/zerotier/zerotier/addNetwork/',
|
||||
del:'/api/zerotier/zerotier/delNetwork/',
|
||||
toggle:'/api/zerotier/zerotier/toggleNetwork/'
|
||||
search: '/api/zerotier/network/search',
|
||||
get:'/api/zerotier/network/get/',
|
||||
set:'/api/zerotier/network/set/',
|
||||
add:'/api/zerotier/network/add/',
|
||||
del:'/api/zerotier/network/del/',
|
||||
info:'/api/zerotier/network/info/',
|
||||
toggle:'/api/zerotier/network/toggle/'
|
||||
}
|
||||
);
|
||||
|
||||
ajaxCall(url="/api/zerotier/zerotier/status", sendData={}, callback=function(data, status) {
|
||||
ajaxGet(url="/api/zerotier/settings/status", sendData={}, callback=function(data, status) {
|
||||
updateServiceStatusUI(data['result']);
|
||||
toggleNetworksTab(data['result']);
|
||||
});
|
||||
|
||||
$("#btn_save_global").click(function() {
|
||||
$("#global_progress").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) {
|
||||
$("#btn_save_settings").click(function() {
|
||||
$("#settings_progress").addClass("fa fa-spinner fa-pulse");
|
||||
saveFormToEndpoint(url="/api/zerotier/settings/set", formid="settings", callback_ok=function(data, status) {
|
||||
ajaxGet(url="/api/zerotier/settings/status", sendData={}, callback=function(data, status) {
|
||||
updateServiceStatusUI(data['result']);
|
||||
toggleNetworksTab(data['result']);
|
||||
});
|
||||
$("#global_progress").removeClass("fa fa-spinner fa-pulse");
|
||||
$("#settings_progress").removeClass("fa fa-spinner fa-pulse");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -83,14 +84,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
</script>
|
||||
|
||||
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
|
||||
<li id="ztGlobal" class="active"><a data-toggle="tab" href="#global">{{ lang._('Global') }}</a></li>
|
||||
<li id="ztSettings" class="active"><a data-toggle="tab" href="#settings">{{ lang._('Settings') }}</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="global" class="tab-pane fade in active">
|
||||
<div id="settings" class="tab-pane fade in active">
|
||||
<div class="content-box">
|
||||
{{ partial("layout_partials/base_form", ['fields': globalForm, 'id': 'global', 'apply_btn_id': 'btn_save_global']) }}
|
||||
{{ partial("layout_partials/base_form", ['fields': settingsForm, 'id': 'settings', 'apply_btn_id': 'btn_save_settings']) }}
|
||||
</div>
|
||||
</div>
|
||||
<div id="networks" class="tab-pane fade in">
|
||||
@@ -98,8 +99,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="enabled" data-width="6em" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
|
||||
<th data-column-id="networkId" data-type="string" data-visible="true">{{ lang._('Network Id') }}</th>
|
||||
<th data-column-id="description" data-width="7em" data-type="string" data-visible="true">{{ lang._('Description') }}</th>
|
||||
<th data-column-id="networkId" data-width="20em" data-type="string" data-visible="true">{{ lang._('Network Id') }}</th>
|
||||
<th data-column-id="description" data-width="30em" data-type="string" data-visible="true">{{ lang._('Local Description') }}</th>
|
||||
<th data-column-id="commands" data-formatter="commandsWithInfo" data-visible="true" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
{#
|
||||
|
||||
OPNsense® is Copyright © 2014 – 2017 by Deciso B.V.
|
||||
Copyright (C) 2017 David Harrigan
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#}
|
||||
|
||||
{% set networksFirstRow = true, peersFirstRow = true %}
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$("#network_details_collapse_all").click(function() {
|
||||
$(".network_details").collapse('toggle');
|
||||
});
|
||||
});
|
||||
$(document).ready(function() {
|
||||
$("#peer_details_collapse_all").click(function() {
|
||||
$(".peer_details").collapse('toggle');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
|
||||
<li id="ztInformation" class="active"><a data-toggle="tab" href="#information">{{ lang._('Information') }}</a></li>
|
||||
<li id="ztNetworks"><a data-toggle="tab" href="#networks">{{ lang._('Networks') }}</a></li>
|
||||
<li id="ztPeers"><a data-toggle="tab" href="#peers">{{ lang._('Peers') }}</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content content-box tab-content">
|
||||
<div id="information" class="tab-pane fade in active">
|
||||
<table class="table table-striped">
|
||||
<tbody>
|
||||
{% for key, value in information %}
|
||||
{% set value = value | default('null') %}
|
||||
<tr>
|
||||
<td width="22%">{{ key | e }}</td>
|
||||
{% if value is type ('boolean') %}
|
||||
<td width="78%">{{ value ? 'true' : 'false' }}</td>
|
||||
{% elseif key == "config" %}
|
||||
{% set config = value %}
|
||||
{% set settings = config["settings"] %}
|
||||
<td width="78%">
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td><b>{{ lang._("physical") }}</b></td>
|
||||
<td colspan="4">{{ config["physical"] ? 'true' : 'false' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>{{ lang._("settings") }}</b></td>
|
||||
<td><b>{{ lang._("portMappingEnabled") }}</b></td>
|
||||
<td><b>{{ lang._("primaryPort") }}</b></td>
|
||||
<td><b>{{ lang._("softwareUpdate") }}</b></td>
|
||||
<td><b>{{ lang._("softwareUpdateChannel") }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>{{ settings["portMappingEnabled"] ? 'true' : 'false' }}</td>
|
||||
<td>{{ settings["primaryPort"] | default('null') | e }}</td>
|
||||
<td>{{ settings["softwareUpdate"] | default('null') | e }}</td>
|
||||
<td>{{ settings["softwareUpdateChannel"] | default('null') | e }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
{% else %}
|
||||
<td width="78%">{{ value | e}}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% elsefor %}
|
||||
<tr><td>{{ lang._("Unable to retrieve Zerotier information. Is the service enabled and is there internet connectivity?") }}</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="networks" class="tab-pane fade in">
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<section class="col-xs-12">
|
||||
{% for network in networks %}
|
||||
<div class="tab-content content-box col-xs-12 __mb">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<i class="fa fa-chevron-down" style="cursor: pointer;" data-toggle="collapse" data-target="#{{ network['nwid'] | e }}"></i>
|
||||
{{ lang._("Network Id") }} : {{ network['nwid'] | e }} ({{ network['name'] | e }})
|
||||
{% if networksFirstRow == true %}
|
||||
{% set networksFirstRow = false %}
|
||||
<div class="pull-right">
|
||||
<i class="fa fa-expand" id="network_details_collapse_all" style="cursor: pointer;" data-toggle="tooltip" title="{{ lang._("collapse/expand all") }}"></i>
|
||||
</div>
|
||||
{% endif %}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<div class="network_details collapse table-responsive" id="{{ network['nwid'] | e }}">
|
||||
<table class="table table-striped">
|
||||
<tbody>
|
||||
{% for key, value in network %}
|
||||
{% set value = value | default('null') %}
|
||||
<tr>
|
||||
<td width="22%">{{ key | e }}</td>
|
||||
{% if value is type('boolean') %}
|
||||
<td width="78%">{{ value == true ? 'true' : 'false' }}</td>
|
||||
{% elseif value is iterable %}
|
||||
<td width="78%">
|
||||
<table class="table">
|
||||
{% if key == "assignedAddresses" %}
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{{ lang._("Addresses") }}</td
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if value|length > 0 %}
|
||||
{% for index in 0..value|length - 1 %}
|
||||
<tr>
|
||||
<td>{{ value[index] | e }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td>{{ lang._("No addresses currently defined.") }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tbody>
|
||||
{% elseif key == "routes" %}
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{{ lang._("target") }}</td>
|
||||
<td>{{ lang._("via") }}</td>
|
||||
<td>{{ lang._("metric") }}</td>
|
||||
<td>{{ lang._("flags") }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if value|length > 0 %}
|
||||
{% for index in 0..value|length - 1 %}
|
||||
{% set route = value[index] %}
|
||||
<tr>
|
||||
<td>{{ route["target"] | e }}</td>
|
||||
<td>{{ route["via"] | e }}</td>
|
||||
<td>{{ route["metric"] | e }}</td>
|
||||
<td>{{ route["flags"] | e }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr><td colspan="4">{{ lang._("No routes currently defined.") }}</td></tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
{% endif %}
|
||||
</table>
|
||||
</td>
|
||||
{% else %}
|
||||
<td width="78%">{{ value | e }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% elsefor %}
|
||||
{{ lang._("Unable to retrieve Zerotier network information. Is the service enabled, do you have enabled networks and is there internet connectivity?") }}
|
||||
{% endfor %}
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div id="peers" class="tab-pane fade in">
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<section class="col-xs-12">
|
||||
{% for peer in peers %}
|
||||
<div class="tab-content content-box col-xs-12 __mb">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<i class="fa fa-chevron-down" style="cursor: pointer;" data-toggle="collapse" data-target="#{{ peer['address'] | e }}"></i>
|
||||
{{ lang._("Peer") }} : {{ peer['address'] | e }} ({{ peer['role'] | e }})
|
||||
{% if peersFirstRow == true %}
|
||||
{% set peersFirstRow = false %}
|
||||
<div class="pull-right">
|
||||
<i class="fa fa-expand" id="peer_details_collapse_all" style="cursor: pointer;" data-toggle="tooltip" title="{{ lang._("collapse/expand all") }}"></i>
|
||||
</div>
|
||||
{% endif %}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<div class="peer_details collapse table-responsive" id="{{ peer['address'] | e }}">
|
||||
<table class="table table-striped">
|
||||
<tbody>
|
||||
{% for key, value in peer %}
|
||||
{% set value = value | default('null') %}
|
||||
<tr>
|
||||
<td width="22%">{{ key | e }}</td>
|
||||
{% if value is type('boolean') %}
|
||||
<td width="78%">{{ value == true ? 'true' : 'false' }}</td>
|
||||
{% elseif value is iterable %}
|
||||
<td width="78%">
|
||||
<table class="table">
|
||||
{% if key == "paths" %}
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{{ lang._("active") }}</td>
|
||||
<td>{{ lang._("address") }}</td>
|
||||
<td>{{ lang._("expired") }}</td>
|
||||
<td>{{ lang._("lastReceive") }}</td>
|
||||
<td>{{ lang._("lastSend") }}</td>
|
||||
<td>{{ lang._("linkQuality") }}</td>
|
||||
<td>{{ lang._("preferred") }}</td>
|
||||
<td>{{ lang._("trustedPathId") }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if value|length > 0 %}
|
||||
{% for index in 0..value|length - 1 %}
|
||||
{% set path = value[index] %}
|
||||
<tr>
|
||||
<td>{{ path["active"] | e }}</td>
|
||||
<td>{{ path["address"] | e }}</td>
|
||||
<td>{{ path["expired"] ? 'true' : 'false' }}</td>
|
||||
<td>{{ path["lastReceive"] | e }}</td>
|
||||
<td>{{ path["lastSend"] | e }}</td>
|
||||
<td>{{ path["linkQuality"] | e }}</td>
|
||||
<td>{{ path["preferred"] | e }}</td>
|
||||
<td>{{ path["trustedPathId"] | e }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="4">{{ lang._("No routes currently defined.") }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
{% endif %}
|
||||
</table>
|
||||
</td>
|
||||
{% else %}
|
||||
<td width="78%">{{ value | e }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% elsefor %}
|
||||
{{ lang._("Unable to retrieve Zerotier peer information. Is the service enabled and is there internet connectivity?") }}
|
||||
{% endfor %}
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,3 +33,39 @@ command:/usr/local/bin/zerotier-cli
|
||||
parameters: leave %s
|
||||
type:script_output
|
||||
message:Leaving Zerotier Network
|
||||
|
||||
[info]
|
||||
command:/usr/local/bin/zerotier-cli info
|
||||
parameters:
|
||||
type:script_output
|
||||
message:Listing Zerotier Info
|
||||
|
||||
[listnetworks]
|
||||
command:/usr/local/bin/zerotier-cli listnetworks
|
||||
parameters:
|
||||
type:script_output
|
||||
message:Listing Zerotier Networks
|
||||
|
||||
[listpeers]
|
||||
command:/usr/local/bin/zerotier-cli listpeers
|
||||
parameters:
|
||||
type:script_output
|
||||
message:Listing Zerotier Peers
|
||||
|
||||
[info_json]
|
||||
command:/usr/local/bin/zerotier-cli -j info
|
||||
parameters:
|
||||
type:script_output
|
||||
message:Listing Zerotier Info (as JSON)
|
||||
|
||||
[listnetworks_json]
|
||||
command:/usr/local/bin/zerotier-cli -j listnetworks
|
||||
parameters:
|
||||
type:script_output
|
||||
message:Listing Zerotier Networks (as JSON)
|
||||
|
||||
[listpeers_json]
|
||||
command:/usr/local/bin/zerotier-cli -j listpeers
|
||||
parameters:
|
||||
type:script_output
|
||||
message:Listing Zerotier Peers (as JSON)
|
||||
|
||||
Reference in New Issue
Block a user