mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
net/haproxy: add user/group management, refs #300
This commit is contained in:
+261
@@ -1103,4 +1103,265 @@ class SettingsController extends ApiControllerBase
|
||||
"name"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve group settings or return defaults
|
||||
* @param $uuid item unique id
|
||||
* @return array
|
||||
*/
|
||||
public function getGroupAction($uuid = null)
|
||||
{
|
||||
$mdlCP = new HAProxy();
|
||||
if ($uuid != null) {
|
||||
$node = $mdlCP->getNodeByReference('groups.group.'.$uuid);
|
||||
if ($node != null) {
|
||||
// return node
|
||||
return array("group" => $node->getNodes());
|
||||
}
|
||||
} else {
|
||||
// generate new node, but don't save to disc
|
||||
$node = $mdlCP->groups->group->add();
|
||||
return array("group" => $node->getNodes());
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* update group with given properties
|
||||
* @param $uuid item unique id
|
||||
* @return array
|
||||
*/
|
||||
public function setGroupAction($uuid)
|
||||
{
|
||||
if ($this->request->isPost() && $this->request->hasPost("group")) {
|
||||
$mdlCP = new HAProxy();
|
||||
if ($uuid != null) {
|
||||
$node = $mdlCP->getNodeByReference('groups.group.'.$uuid);
|
||||
if ($node != null) {
|
||||
$node->setNodes($this->request->getPost("group"));
|
||||
return $this->save($mdlCP, $node, "group");
|
||||
}
|
||||
}
|
||||
}
|
||||
return array("result"=>"failed");
|
||||
}
|
||||
|
||||
/**
|
||||
* add new group and set with attributes from post
|
||||
* @return array
|
||||
*/
|
||||
public function addGroupAction()
|
||||
{
|
||||
$result = array("result"=>"failed");
|
||||
if ($this->request->isPost() && $this->request->hasPost("group")) {
|
||||
$mdlCP = new HAProxy();
|
||||
$node = $mdlCP->groups->group->Add();
|
||||
$node->setNodes($this->request->getPost("group"));
|
||||
return $this->save($mdlCP, $node, "group");
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete group by uuid
|
||||
* @param $uuid item unique id
|
||||
* @return array status
|
||||
*/
|
||||
public function delGroupAction($uuid)
|
||||
{
|
||||
$result = array("result"=>"failed");
|
||||
if ($this->request->isPost()) {
|
||||
$mdlCP = new HAProxy();
|
||||
if ($uuid != null) {
|
||||
if ($mdlCP->groups->group->del($uuid)) {
|
||||
// if item is removed, serialize to config and save
|
||||
$mdlCP->serializeToConfig();
|
||||
Config::getInstance()->save();
|
||||
$result['result'] = 'deleted';
|
||||
} else {
|
||||
$result['result'] = 'not found';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle group by uuid (enable/disable)
|
||||
* @param $uuid item unique id
|
||||
* @param $enabled desired state enabled(1)/disabled(0), leave empty for toggle
|
||||
* @return array status
|
||||
*/
|
||||
public function toggleGroupAction($uuid, $enabled = null)
|
||||
{
|
||||
|
||||
$result = array("result" => "failed");
|
||||
if ($this->request->isPost()) {
|
||||
$mdlCP = new HAProxy();
|
||||
if ($uuid != null) {
|
||||
$node = $mdlCP->getNodeByReference('groups.group.' . $uuid);
|
||||
if ($node != null) {
|
||||
if ($enabled == "0" || $enabled == "1") {
|
||||
$node->enabled = (string)$enabled;
|
||||
} elseif ((string)$node->enabled == "1") {
|
||||
$node->enabled = "0";
|
||||
} else {
|
||||
$node->enabled = "1";
|
||||
}
|
||||
$result['result'] = $node->enabled;
|
||||
// if item has toggled, serialize to config and save
|
||||
$mdlCP->serializeToConfig();
|
||||
Config::getInstance()->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* search groups
|
||||
* @return array
|
||||
*/
|
||||
public function searchGroupsAction()
|
||||
{
|
||||
$this->sessionClose();
|
||||
$mdlCP = new HAProxy();
|
||||
$grid = new UIModelGrid($mdlCP->groups->group);
|
||||
return $grid->fetchBindRequest(
|
||||
$this->request,
|
||||
array("enabled", "name", "description"),
|
||||
"name"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve user settings or return defaults
|
||||
* @param $uuid item unique id
|
||||
* @return array
|
||||
*/
|
||||
public function getUserAction($uuid = null)
|
||||
{
|
||||
$mdlCP = new HAProxy();
|
||||
if ($uuid != null) {
|
||||
$node = $mdlCP->getNodeByReference('users.user.'.$uuid);
|
||||
if ($node != null) {
|
||||
// return node
|
||||
return array("user" => $node->getNodes());
|
||||
}
|
||||
} else {
|
||||
// generate new node, but don't save to disc
|
||||
$node = $mdlCP->users->user->add();
|
||||
return array("user" => $node->getNodes());
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* update user with given properties
|
||||
* @param $uuid item unique id
|
||||
* @return array
|
||||
*/
|
||||
public function setUserAction($uuid)
|
||||
{
|
||||
if ($this->request->isPost() && $this->request->hasPost("user")) {
|
||||
$mdlCP = new HAProxy();
|
||||
if ($uuid != null) {
|
||||
$node = $mdlCP->getNodeByReference('users.user.'.$uuid);
|
||||
if ($node != null) {
|
||||
$node->setNodes($this->request->getPost("user"));
|
||||
return $this->save($mdlCP, $node, "user");
|
||||
}
|
||||
}
|
||||
}
|
||||
return array("result"=>"failed");
|
||||
}
|
||||
|
||||
/**
|
||||
* add new user and set with attributes from post
|
||||
* @return array
|
||||
*/
|
||||
public function addUserAction()
|
||||
{
|
||||
$result = array("result"=>"failed");
|
||||
if ($this->request->isPost() && $this->request->hasPost("user")) {
|
||||
$mdlCP = new HAProxy();
|
||||
$node = $mdlCP->users->user->Add();
|
||||
$node->setNodes($this->request->getPost("user"));
|
||||
return $this->save($mdlCP, $node, "user");
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete user by uuid
|
||||
* @param $uuid item unique id
|
||||
* @return array status
|
||||
*/
|
||||
public function delUserAction($uuid)
|
||||
{
|
||||
$result = array("result"=>"failed");
|
||||
if ($this->request->isPost()) {
|
||||
$mdlCP = new HAProxy();
|
||||
if ($uuid != null) {
|
||||
if ($mdlCP->users->user->del($uuid)) {
|
||||
// if item is removed, serialize to config and save
|
||||
$mdlCP->serializeToConfig();
|
||||
Config::getInstance()->save();
|
||||
$result['result'] = 'deleted';
|
||||
} else {
|
||||
$result['result'] = 'not found';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle user by uuid (enable/disable)
|
||||
* @param $uuid item unique id
|
||||
* @param $enabled desired state enabled(1)/disabled(0), leave empty for toggle
|
||||
* @return array status
|
||||
*/
|
||||
public function toggleUserAction($uuid, $enabled = null)
|
||||
{
|
||||
|
||||
$result = array("result" => "failed");
|
||||
if ($this->request->isPost()) {
|
||||
$mdlCP = new HAProxy();
|
||||
if ($uuid != null) {
|
||||
$node = $mdlCP->getNodeByReference('users.user.' . $uuid);
|
||||
if ($node != null) {
|
||||
if ($enabled == "0" || $enabled == "1") {
|
||||
$node->enabled = (string)$enabled;
|
||||
} elseif ((string)$node->enabled == "1") {
|
||||
$node->enabled = "0";
|
||||
} else {
|
||||
$node->enabled = "1";
|
||||
}
|
||||
$result['result'] = $node->enabled;
|
||||
// if item has toggled, serialize to config and save
|
||||
$mdlCP->serializeToConfig();
|
||||
Config::getInstance()->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* search users
|
||||
* @return array
|
||||
*/
|
||||
public function searchUsersAction()
|
||||
{
|
||||
$this->sessionClose();
|
||||
$mdlCP = new HAProxy();
|
||||
$grid = new UIModelGrid($mdlCP->users->user);
|
||||
return $grid->fetchBindRequest(
|
||||
$this->request,
|
||||
array("enabled", "name", "description"),
|
||||
"name"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ class IndexController extends \OPNsense\Base\IndexController
|
||||
$this->view->formDialogHealthcheck = $this->getForm("dialogHealthcheck");
|
||||
$this->view->formDialogAction = $this->getForm("dialogAction");
|
||||
$this->view->formDialogAcl = $this->getForm("dialogAcl");
|
||||
$this->view->formDialogUser = $this->getForm("dialogUser");
|
||||
$this->view->formDialogGroup = $this->getForm("dialogGroup");
|
||||
$this->view->formDialogLua = $this->getForm("dialogLua");
|
||||
$this->view->formDialogErrorfile = $this->getForm("dialogErrorfile");
|
||||
$this->view->formDialogMapfile = $this->getForm("dialogMapfile");
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>group.enabled</id>
|
||||
<label>Enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable this group.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>group.name</id>
|
||||
<label>Name</label>
|
||||
<type>text</type>
|
||||
<help>Name to identify this group.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>group.description</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
<help>Description for this group.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>group.members</id>
|
||||
<label>Members</label>
|
||||
<type>select_multiple</type>
|
||||
<allownew>true</allownew>
|
||||
<hint>Type username or choose from list.</hint>
|
||||
</field>
|
||||
</form>
|
||||
@@ -0,0 +1,26 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>user.enabled</id>
|
||||
<label>Enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable this user.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.name</id>
|
||||
<label>Name</label>
|
||||
<type>text</type>
|
||||
<help>Name to identify this user.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.description</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
<help>Description for this user.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.password</id>
|
||||
<label>Password</label>
|
||||
<type>password</type>
|
||||
<help><![CDATA[Both secure (encrypted) and insecure (unencrypted) passwords can be used. Most systems support MD5, SHA-256, SHA-512, and, of course, the classic DES-based method of encrypting passwords.<br/><div class="text-info"><b>NOTE:</b> Avoid using unencrypted passwords that start with a $-sign, because this indicates an encrypted password and will make it impossible to authenticate.</div>]]></help>
|
||||
</field>
|
||||
</form>
|
||||
@@ -1,6 +1,6 @@
|
||||
<model>
|
||||
<mount>//OPNsense/HAProxy</mount>
|
||||
<version>2.5.0</version>
|
||||
<version>2.6.0</version>
|
||||
<description>the HAProxy load balancer</description>
|
||||
<items>
|
||||
<general>
|
||||
@@ -1921,5 +1921,64 @@
|
||||
</content>
|
||||
</mapfile>
|
||||
</mapfiles>
|
||||
<groups>
|
||||
<group type="ArrayField">
|
||||
<id type="UniqueIdField">
|
||||
<Required>Y</Required>
|
||||
</id>
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
<name type="TextField">
|
||||
<mask>/^[^\t^,^;^\.^\[^\]^\{^\}]{1,255}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 255 characters.</ValidationMessage>
|
||||
<Required>Y</Required>
|
||||
</name>
|
||||
<description type="TextField">
|
||||
<mask>/^.{1,255}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 255 characters.</ValidationMessage>
|
||||
<Required>N</Required>
|
||||
</description>
|
||||
<members type="ModelRelationField">
|
||||
<Model>
|
||||
<template>
|
||||
<source>OPNsense.HAProxy.HAProxy</source>
|
||||
<items>users.user</items>
|
||||
<display>name</display>
|
||||
</template>
|
||||
</Model>
|
||||
<ValidationMessage>Related user not found</ValidationMessage>
|
||||
<Multiple>Y</Multiple>
|
||||
<Required>N</Required>
|
||||
</members>
|
||||
</group>
|
||||
</groups>
|
||||
<users>
|
||||
<user type="ArrayField">
|
||||
<id type="UniqueIdField">
|
||||
<Required>Y</Required>
|
||||
</id>
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
<name type="TextField">
|
||||
<mask>/^[^\t^,^;^\.^\[^\]^\{^\}]{1,255}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 255 characters.</ValidationMessage>
|
||||
<Required>Y</Required>
|
||||
</name>
|
||||
<description type="TextField">
|
||||
<mask>/^.{1,255}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 255 characters.</ValidationMessage>
|
||||
<Required>N</Required>
|
||||
</description>
|
||||
<password type="TextField">
|
||||
<mask>/^.{1,512}$/u</mask>
|
||||
<ValidationMessage>Should be a string between 1 and 512 characters.</ValidationMessage>
|
||||
<Required>Y</Required>
|
||||
</password>
|
||||
</user>
|
||||
</users>
|
||||
</items>
|
||||
</model>
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
<HealthChecks VisibleName="Health Checks" url="/ui/haproxy#healthchecks"/>
|
||||
<Actions VisibleName="Actions" url="/ui/haproxy#actions"/>
|
||||
<Acls VisibleName="ACLs" url="/ui/haproxy#acls"/>
|
||||
<Users VisibleName="Users" url="/ui/haproxy#users"/>
|
||||
<Groups VisibleName="Groups" url="/ui/haproxy#groups"/>
|
||||
<Luas VisibleName="Lua Scripts" url="/ui/haproxy#luas"/>
|
||||
<Errorfiles VisibleName="Error Files" url="/ui/haproxy#errorfiles"/>
|
||||
<Mapfiles VisibleName="Map Files" url="/ui/haproxy#mapfiles"/>
|
||||
|
||||
@@ -121,6 +121,32 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
}
|
||||
);
|
||||
|
||||
$("#grid-users").UIBootgrid(
|
||||
{ search:'/api/haproxy/settings/searchUsers',
|
||||
get:'/api/haproxy/settings/getUser/',
|
||||
set:'/api/haproxy/settings/setUser/',
|
||||
add:'/api/haproxy/settings/addUser/',
|
||||
del:'/api/haproxy/settings/delUser/',
|
||||
toggle:'/api/haproxy/settings/toggleUser/',
|
||||
options: {
|
||||
rowCount:[10,25,50,100,500,1000]
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$("#grid-groups").UIBootgrid(
|
||||
{ search:'/api/haproxy/settings/searchGroups',
|
||||
get:'/api/haproxy/settings/getGroup/',
|
||||
set:'/api/haproxy/settings/setGroup/',
|
||||
add:'/api/haproxy/settings/addGroup/',
|
||||
del:'/api/haproxy/settings/delGroup/',
|
||||
toggle:'/api/haproxy/settings/toggleGroup/',
|
||||
options: {
|
||||
rowCount:[10,25,50,100,500,1000]
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$("#grid-luas").UIBootgrid(
|
||||
{ search:'/api/haproxy/settings/searchLuas',
|
||||
get:'/api/haproxy/settings/getLua/',
|
||||
@@ -439,6 +465,20 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li role="presentation" class="dropdown">
|
||||
<a data-toggle="dropdown" href="#" class="dropdown-toggle pull-right visible-lg-inline-block visible-md-inline-block visible-xs-inline-block visible-sm-inline-block" role="button">
|
||||
<b><span class="caret"></span></b>
|
||||
</a>
|
||||
<a data-toggle="tab" onclick="$('#{% if showIntro|default('0')=='1' %}user-management-introduction{% else %}users-tab{% endif %}').click();" class="visible-lg-inline-block visible-md-inline-block visible-xs-inline-block visible-sm-inline-block" style="border-right:0px;"><b>{{ lang._('User Management') }}</b></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
{% if showIntro|default('0')=='1' %}
|
||||
<li><a data-toggle="tab" id="user-management-introduction" href="#subtab_haproxy-user-management-introduction">{{ lang._('Introduction') }}</a></li>
|
||||
{% endif %}
|
||||
<li><a data-toggle="tab" id="users-tab" href="#users">{{ lang._('Users') }}</a></li>
|
||||
<li><a data-toggle="tab" href="#groups">{{ lang._('Groups') }}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
{# add automatically generated tabs #}
|
||||
{% for tab in mainForm['tabs']|default([]) %}
|
||||
{% if tab['subtabs']|default(false) %}
|
||||
@@ -541,6 +581,20 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="subtab_haproxy-user-management-introduction" class="tab-pane fade">
|
||||
<div class="col-md-12">
|
||||
<h1>{{ lang._('User Management') }}</h1>
|
||||
<p>{{ lang._("Optionally HAProxy manages an internal list of users and groups, which can be used for HTTP Basic Authentication as well as access to HAProxy's internal statistic pages.") }}</p>
|
||||
<ul>
|
||||
<li>{{ lang._('%sUser:%s A username/password combination. Both secure (encrypted) and insecure (unencrypted) passwords can be used.') | format('<b>', '</b>') }}</li>
|
||||
<li>{{ lang._('%sGroup:%s A optional list containing one or more users. Groups usually make it easier to manage permissions for a large number of users') | format('<b>', '</b>') }}</li>
|
||||
</ul>
|
||||
<p>{{ lang._('Note that users and groups must be selected from the Backend Pool or Public Service configuration in order to be used for authentication.') }}</p>
|
||||
<p>{{ lang._("For more information on HAProxy's %suser/group management%s see the %sofficial documentation%s.") | format('<b>', '</b>', '<a href="http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#3.4" target="_blank">', '</a>') }}</p>
|
||||
<br/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="subtab_haproxy-advanced-introduction" class="tab-pane fade">
|
||||
<div class="col-md-12">
|
||||
<h1>{{ lang._('Advanced Features') }}</h1>
|
||||
@@ -780,6 +834,76 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="users" class="tab-pane fade">
|
||||
<!-- tab page "users" -->
|
||||
<table id="grid-users" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogUser">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="enabled" data-width="6em" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
|
||||
<th data-column-id="userid" data-type="number" data-visible="false">{{ lang._('User ID') }}</th>
|
||||
<th data-column-id="name" data-type="string">{{ lang._('Username') }}</th>
|
||||
<th data-column-id="description" data-type="string">{{ lang._('Description') }}</th>
|
||||
<th data-column-id="commands" data-width="7em" data-formatter="commands" 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>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
|
||||
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<!-- apply button -->
|
||||
<div class="col-md-12">
|
||||
<hr/>
|
||||
<button class="btn btn-primary" id="reconfigureAct-users" type="button"><b>{{ lang._('Apply') }}</b><i id="reconfigureAct_progress" class=""></i></button>
|
||||
<button class="btn btn-primary" id="configtestAct-users" type="button"><b>{{ lang._('Test syntax') }}</b><i id="configtestAct_progress" class=""></i></button>
|
||||
<br/>
|
||||
<br/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="groups" class="tab-pane fade">
|
||||
<!-- tab page "groups" -->
|
||||
<table id="grid-groups" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogGroup">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="enabled" data-width="6em" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
|
||||
<th data-column-id="groupid" data-type="number" data-visible="false">{{ lang._('Group ID') }}</th>
|
||||
<th data-column-id="name" data-type="string">{{ lang._('Group') }}</th>
|
||||
<th data-column-id="description" data-type="string">{{ lang._('Description') }}</th>
|
||||
<th data-column-id="commands" data-width="7em" data-formatter="commands" 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>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
|
||||
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<!-- apply button -->
|
||||
<div class="col-md-12">
|
||||
<hr/>
|
||||
<button class="btn btn-primary" id="reconfigureAct-groups" type="button"><b>{{ lang._('Apply') }}</b><i id="reconfigureAct_progress" class=""></i></button>
|
||||
<button class="btn btn-primary" id="configtestAct-groups" type="button"><b>{{ lang._('Test syntax') }}</b><i id="configtestAct_progress" class=""></i></button>
|
||||
<br/>
|
||||
<br/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="luas" class="tab-pane fade">
|
||||
<!-- tab page "luas" -->
|
||||
<table id="grid-luas" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogLua">
|
||||
@@ -891,6 +1015,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogHealthcheck,'id':'DialogHealthcheck','label':lang._('Edit Health Monitor')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogAction,'id':'DialogAction','label':lang._('Edit Rule')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogAcl,'id':'DialogAcl','label':lang._('Edit Condition')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogUser,'id':'DialogUser','label':lang._('Edit User')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogGroup,'id':'DialogGroup','label':lang._('Edit Group')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogLua,'id':'DialogLua','label':lang._('Edit Lua Script')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogErrorfile,'id':'DialogErrorfile','label':lang._('Edit Error Message')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogMapfile,'id':'DialogMapfile','label':lang._('Edit Map File')])}}
|
||||
|
||||
Reference in New Issue
Block a user