Add Service Templates (#12107)
* service templates - move to blade - jellyfrog fixes - revert get to find and fix discovery lookup * service templates - move to blade - wip * service templates - move to blade - wip * service templates - move to blade - deprecate delete_service_template * service templates - move to blade - deprecate delete_service_template * service templates - move to blade - deprecate remove_service_template * service templates - move to blade - deprecate remove_service_template * service templates - move to blade - fix permisson lookup * service templates - move to blade - fix remove route * service templates - move to blade - fix remove route * service templates - move to blade - fix permisson lookup * service templates - move to blade - fix permisson lookup * service templates - move to blade - fix permisson lookup * service templates - move to blade - fix permisson lookup * service templates - move to blade - fixs * service templates - move to blade - fixes * service templates - move to blade - fixes * service templates - move to blade - fixes * service templates - move to blade - nullable input? * service templates - move to blade - nullable input? * service templates - move to blade - nullable input? * service templates - move to blade - add selected for device group id and type * service templates - move to blade - add selected for device group id and type * service templates - move to blade - add selected for device group id and type * service templates - move to blade - fix discovery response * service templates - move to blade - fix device group index display * service templates - move to blade - add delete to discover_service_template * service templates - move to blade - add discover all button - function foobar * service templates - move to blade - add discover all button - function foobar * service templates - move to blade - add discover all button - function foobar * service templates - move to blade - fixes * service templates - move to blade - fixes * service templates - move to blade - fixes * service templates - move to blade - button fixes * service templates - move to blade - button fixes * service templates - move to blade - button fixes * service templates - move to blade - attempt route fix * service templates - move to blade - attempt route fix * service templates - move to blade - attempt route fix * service templates - move to blade - attempt route fix * service templates - move to blade - fix discovery function * service templates - move to blade - fix discovery function * service templates - move to blade - fix return values - thanks SourceDoctor * service templates - move to blade - attempt route fix * service templates - move to blade - button variable fix * service templates - move to blade - button variable fix * service templates - move to blade - button variable fix * service templates - move to blade - function fix * service templates - move to blade - permissions fix * service templates - move to blade - permissions fix * service templates - move to blade - permissions fix * service templates - move to blade - permissions fix * service templates - move to blade - permissions fix * service templates - move to blade - permissions fix * service templates - move to blade - permissions fix * service templates - move to blade - permissions fix * service templates - move to blade - permissions fix * service templates - add initial api - and model permissions fix * service templates - add initial api - discovery too * service templates - add initial api - discovery too * service templates - merge fix * service templates - api fixes * service templates - api fixes * service templates - remove bad fixe * service templates - discover null? :) * service templates - Policy requires Facade? * service templates - Policy requires Facade? * service templates - REVERT Policy requires Facade? * service templates - REVERT Policy requires Facade? * Revert "service templates - REVERT Policy requires Facade?" This reverts commit7752b3e4e5
. * service templates - clean up discover api call * service templates - clean up discover api call * service templates - clean up discover api call * service templates - clean up discover api call * service templates - clean up discover api call * service templates - attempt route fix * Revert "service templates - attempt route fix" This reverts commitb48970351e
. * service templates - jellyfrog fixes - DeviceGroup relates to Service Template * service templates - jellyfrog fixes - DeviceGroup relates to Service Template * service templates - jellyfrog fixes - DeviceGroup relates to Service Template * service templates - jellyfrog fixes - DeviceGroup relates to Service Template * service templates - jellyfrog fixes - DeviceGroup relates to Service Template * service templates - jellyfrog fixes - DeviceGroup relates to Service Template * service templates - jellyfrog fixes - dbchanged - DeviceGroup relates to Service Template * service templates - jellyfrog fixes - dbchanged - DeviceGroup relates to Service Template * service templates - jellyfrog fixes - dbchanged - DeviceGroup relates to Service Template * service templates - jellyfrog fixes - dbchanged - DeviceGroup relates to Service Template * Revert "service templates - jellyfrog fixes - dbchanged - DeviceGroup relates to Service Template" This reverts commitef93315db5
. * Revert "service templates - jellyfrog fixes - dbchanged - DeviceGroup relates to Service Template" This reverts commit73af819a60
. * Revert "service templates - jellyfrog fixes - dbchanged - DeviceGroup relates to Service Template" This reverts commitdd019c3105
. * Revert "service templates - jellyfrog fixes - dbchanged - DeviceGroup relates to Service Template" This reverts commit94aaaf7976
. * service templates - jellyfrog fixes - DeviceGroup relates to Service Template * service templates - fix permissions * service templates - db service_templates_perms * service templates - fix permissions * service templates - fix permissions * service templates - fix permissions * service templates - fix permissions * service templates - fix permissions * service templates - fix edit.blade missing parameters - still 403 :( * service templates - jellyfrog -fix route and construct * service templates - jellyfrog -fix route and construct * service templates - jellyfrog -fix route and construct * Revert "service templates - jellyfrog -fix route and construct" This reverts commitec1eea7a99
. * service templates - jellyfrog -fix routes * service templates - jellyfrog -fix services lookup * service templates - edit blade fixes * service templates - edit blade fixes - service or services or template or serviceTemplate or service_template good luck * service templates - edit blade fixes * service templates - index blade fixes * service templates - discover return fix * service templates - remove return fix * service templates - fix discovery api returns * service templates - fix discovery api returns * service templates - fix discovery api returns * service templates - fix discovery - test * service templates - fix discovery * service templates - fix checkbox integer * service templates - fix checkbox integer * service templates - fix checkbox integer * service templates - fix checkbox integer * service templates - fix checkbox integer * service templates - fix discover all * service templates - fix discover all * service templates - fix discover all * service templates - fix discover all * service templates - fix discover all * service templates - fix discover all * service templates - fix discover all * service templates - fix discover * service templates - fix discover * service templates - fix discover * service templates - fix discover * service templates - fix discover * service templates - move discover/apply to blade - last of the old functions - wip * service templates - move discover/apply to blade - last of the old functions - wip * service templates - move discover/apply to blade - last of the old functions - wip * service templates - change all relevant to template for sanity * service templates - inspection fixes * service templates - inspection fixes * service templates - inspection fixes * service templates - murrant fixes - use createOrUpdate - add obervers - fix function call * service templates - murrant fixes - add ServiceController store - not used * service templates - murrant fixes - add Observers file) * service templates - murrant fixes - correct ServiceController * service templates - murrant fixes - fix observers load * service templates - observer fix * service templates - schedule discovery function call fix, cheeky, is this allowed? * service templates - attempt route fix. * service templates - attempt route fix 2 * service templates - blade route applyall missing url - ie the route lol * service templates - blade route applyall missing url - ie the route lol * service templates - fix routes - bingo! * service templates - fix routes - bingo! * service templates - fix blade missing quote * service templates - jellyfrog fix - remove pluck * service templates - missing template id on service update * service templates - jellyfrog fix - add get * service templates - fix service db defaults / null * service templates - fix service update * service templates - fix service update * service templates - fix service update * service templates - fix service devicegroup change - obsoletes service_template_change in servicesdb * service templates - fix service devicegroup change - obsoletes service_template_change in servicesdb * Add service templates - phpcs fixes - and attemp whereNotIn scope * Add service templates - styleci * Add service templates - styleci * Add service templates - fix notindevicegroup scope * Add service templates - removed service service_template_changed - not required for delete or update * Add service templates - removed service service_template_changed - not required for delete or update * Add service templates - murrant fixes - add protected casts - fix checkbox * Add service templates - fix checkbox - attempt2 * Add service templates - fix checkbox - attempt3 * Add service templates - fix checkbox - attempt3 * Add service templates - fix checkbox - attempt4 * Add service templates - fix delete row selection * Revert "Add service templates - fix delete row selection" This reverts commit4d9e4990f2
. * Add service templates - fix delete row selection * Add service templates - fix automatic discovery * Add service templates - fix automatic discovery * Add service templates - checkbox - add hidden input * Add service templates - checkbox - add old value back? * Add service templates - checkbox - fix disabled * Add service templates - checkbox - fix disabled * Add service templates - service fixes - styleci * Add service templates - make devicegroup required * Add service templates - let Disable text wrap * Add service templates - dont allow device group to be deleted when service templates exist * Add service templates - dont allow device group to be deleted when service templates exist * Add service templates - enable multiple device groups - wip * Add service templates - enable multiple device groups - wip * Add service templates - enable multiple device groups - wip * Add service templates - enable multiple device groups - dbschema - wip * Add service templates - enable multiple device groups - db migration - wip * Add service templates - enable multiple device groups - db migration - wip * Add service templates - enable multiple device groups - wip * Add service templates - enable multiple device groups - wip * Add service templates - enable service template Groups - relationships to device AND device groups * Add service templates - styleci fixes * Add service templates - styleci fixes * Add service templates - fixes * Add service templates - fixes * Add service templates - fixes * Add service templates - fixes * Add service templates - fixes * Add service templates - fixes * Add service templates - fixes * Add service templates - fixes * Add service templates - db - primarykey issues * Add service templates - fix migrations * Add service templates - fix migrations * Add service templates - fix migrations * Add service templates - fix migrations * Add service templates - fix migrations * Add service templates - fix migrations * Add service templates - fix migrations * Add service templates - fix migrations * Add service templates - fix migrations * Add service templates - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - blade view - fixes * Add service templates - misc update for travis build trigger * Add service templates - restrict view to only show device/groups that have templates applied * Add service templates - fix devicegroup update * remove permissions table stuff * Fix schema rollback * fix style * Update ServiceTemplateController.php Co-authored-by: Tony Murray <murraytony@gmail.com>
This commit is contained in:
parent
89cbf152f6
commit
5388a20c09
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
/*
|
||||
* Services.php
|
||||
*
|
||||
* Nagios services helper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package LibreNMS
|
||||
* @link http://librenms.org
|
||||
* @copyright 2020 Tony Murray
|
||||
* @author Tony Murray <murraytony@gmail.com>
|
||||
*/
|
||||
|
||||
namespace LibreNMS;
|
||||
|
||||
class Services
|
||||
{
|
||||
/**
|
||||
* List all available services from nagios plugins directory
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function list()
|
||||
{
|
||||
$services = [];
|
||||
if (is_dir(Config::get('nagios_plugins'))) {
|
||||
foreach (scandir(Config::get('nagios_plugins')) as $file) {
|
||||
if (substr($file, 0, 6) === 'check_') {
|
||||
$services[] = substr($file, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
}
|
|
@ -175,6 +175,11 @@ class DeviceGroupController extends Controller
|
|||
*/
|
||||
public function destroy(DeviceGroup $deviceGroup)
|
||||
{
|
||||
if ($deviceGroup->serviceTemplates()->exists()) {
|
||||
$msg = __('Device Group :name still has Service Templates associated with it. Please remove or update the Service Template accordingly', ['name' => $deviceGroup->name]);
|
||||
|
||||
return response($msg, 200);
|
||||
}
|
||||
$deviceGroup->delete();
|
||||
|
||||
$msg = __('Device Group :name deleted', ['name' => $deviceGroup->name]);
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
/**
|
||||
* ServiceTemplateController.php
|
||||
*
|
||||
* -Description-
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @link http://librenms.org
|
||||
* @copyright 2020 Anthony F McInerney <bofh80>
|
||||
* @author Anthony F McInerney <afm404@gmail.com>
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Select;
|
||||
|
||||
use App\Models\ServiceTemplate;
|
||||
|
||||
class ServiceTemplateController extends SelectController
|
||||
{
|
||||
protected function searchFields($request)
|
||||
{
|
||||
return ['name'];
|
||||
}
|
||||
|
||||
protected function baseQuery($request)
|
||||
{
|
||||
return ServiceTemplate::hasAccess($request->user())->select('id', 'name');
|
||||
}
|
||||
|
||||
public function formatItem($template)
|
||||
{
|
||||
return [
|
||||
'id' => $template->id,
|
||||
'text' => $template->name,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Service;
|
||||
use Illuminate\Http\Request;
|
||||
use Toastr;
|
||||
|
||||
class ServiceController extends Controller
|
||||
{
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request = [
|
||||
'service_name' => 'required|string|unique:service',
|
||||
'device_id' => 'integer',
|
||||
'service_type' => 'string',
|
||||
'service_param' => 'nullable|string',
|
||||
'service_ip' => 'nullable|string',
|
||||
'service_desc' => 'nullable|string',
|
||||
'service_changed' => 'integer',
|
||||
'service_disabled' => 'integer',
|
||||
'service_ignore' => 'integer',
|
||||
];
|
||||
|
||||
$service = Service::make(
|
||||
$request->only(
|
||||
[
|
||||
'service_name',
|
||||
'device_id',
|
||||
'service_type',
|
||||
'service_param',
|
||||
'service_ip',
|
||||
'service_desc',
|
||||
'service_changed',
|
||||
'service_disabled',
|
||||
'service_ignore',
|
||||
]
|
||||
)
|
||||
);
|
||||
$service->save();
|
||||
|
||||
Toastr::success(__('Service :name created', ['name' => $service->service_name]));
|
||||
|
||||
return redirect()->route('services.templates.index');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,378 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Device;
|
||||
use App\Models\DeviceGroup;
|
||||
use App\Models\Service;
|
||||
use App\Models\ServiceTemplate;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
use LibreNMS\Alerting\QueryBuilderFilter;
|
||||
use LibreNMS\Services;
|
||||
use Toastr;
|
||||
|
||||
class ServiceTemplateController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(ServiceTemplate::class, 'template');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//$this->authorize('manage', ServiceTemplate::class);
|
||||
|
||||
return view(
|
||||
'service-template.index', [
|
||||
'service_templates' => ServiceTemplate::orderBy('name')->withCount('devices')->withCount('groups')->get(),
|
||||
'groups' => DeviceGroup::orderBy('name')->has('serviceTemplates')->get(),
|
||||
'devices' => Device::orderBy('hostname')->has('serviceTemplates')->get(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view(
|
||||
'service-template.create', [
|
||||
'template' => new ServiceTemplate(),
|
||||
'service_templates' => ServiceTemplate::orderBy('name')->get(),
|
||||
'services' => Services::list(),
|
||||
'filters' => json_encode(new QueryBuilderFilter('group')),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->validate(
|
||||
$request, [
|
||||
'name' => 'required|string|unique:service_templates',
|
||||
'groups' => 'array',
|
||||
'groups.*' => 'integer',
|
||||
'devices' => 'array',
|
||||
'devices.*' => 'integer',
|
||||
'type' => 'string',
|
||||
'dtype' => 'required|in:dynamic,static',
|
||||
'dgtype' => 'required|in:dynamic,static',
|
||||
'drules' => 'json|required_if:dtype,dynamic',
|
||||
'dgrules' => 'json|required_if:dgtype,dynamic',
|
||||
'param' => 'nullable|string',
|
||||
'ip' => 'nullable|string',
|
||||
'desc' => 'nullable|string',
|
||||
'changed' => 'integer',
|
||||
'disabled' => 'integer',
|
||||
'ignore' => 'integer',
|
||||
]
|
||||
);
|
||||
|
||||
$template = ServiceTemplate::make(
|
||||
$request->only(
|
||||
[
|
||||
'name',
|
||||
'type',
|
||||
'dtype',
|
||||
'dgtype',
|
||||
'drules',
|
||||
'dgrules',
|
||||
'param',
|
||||
'ip',
|
||||
'desc',
|
||||
'changed',
|
||||
'disabled',
|
||||
'ignore',
|
||||
]
|
||||
)
|
||||
);
|
||||
$template->drules = json_decode($request->drules);
|
||||
$template->dgrules = json_decode($request->dgrules);
|
||||
$template->save();
|
||||
|
||||
if ($request->dtype == 'static') {
|
||||
$template->devices()->sync($request->devices);
|
||||
}
|
||||
if ($request->dgtype == 'static') {
|
||||
$template->groups()->sync($request->groups);
|
||||
}
|
||||
Toastr::success(__('Service Template :name created', ['name' => $template->name]));
|
||||
|
||||
return redirect()->route('services.templates.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function show(ServiceTemplate $template)
|
||||
{
|
||||
return redirect(url('/services/templates/' . $template->id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return \Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function edit(ServiceTemplate $template)
|
||||
{
|
||||
return view(
|
||||
'service-template.edit', [
|
||||
'template' => $template,
|
||||
'filters' => json_encode(new QueryBuilderFilter('group')),
|
||||
'services' => Services::list(),
|
||||
]
|
||||
//
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function update(Request $request, ServiceTemplate $template)
|
||||
{
|
||||
$this->validate(
|
||||
$request, [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
Rule::unique('service_templates')->where(
|
||||
function ($query) use ($template) {
|
||||
$query->where('id', '!=', $template->id);
|
||||
}
|
||||
),
|
||||
],
|
||||
'dtype' => 'required|in:dynamic,static',
|
||||
'drules' => 'json|required_if:dtype,dynamic',
|
||||
'devices' => 'array',
|
||||
'devices.*' => 'integer',
|
||||
'dgtype' => 'required|in:dynamic,static',
|
||||
'dgrules' => 'json|required_if:dgtype,dynamic',
|
||||
'groups' => 'array',
|
||||
'groups.*' => 'integer',
|
||||
'type' => 'string',
|
||||
'param' => 'nullable|string',
|
||||
'ip' => 'nullable|string',
|
||||
'desc' => 'nullable|string',
|
||||
'changed' => 'integer',
|
||||
'disabled' => 'integer',
|
||||
'ignore' => 'integer',
|
||||
]
|
||||
);
|
||||
|
||||
$template->fill(
|
||||
$request->only(
|
||||
[
|
||||
'name',
|
||||
'type',
|
||||
'dtype',
|
||||
'dgtype',
|
||||
'drules',
|
||||
'dgrules',
|
||||
'param',
|
||||
'ip',
|
||||
'desc',
|
||||
'changed',
|
||||
'ignore',
|
||||
'disabled',
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
$devices_updated = false;
|
||||
if ($template->dtype == 'static') {
|
||||
// sync device_ids from input
|
||||
$updated = $template->devices()->sync($request->get('devices', []));
|
||||
// check for attached/detached/updated
|
||||
$devices_updated = array_sum(array_map(function ($device_ids) {
|
||||
return count($device_ids);
|
||||
}, $updated)) > 0;
|
||||
} else {
|
||||
$template->drules = json_decode($request->drules);
|
||||
}
|
||||
|
||||
$device_groups_updated = false;
|
||||
if ($template->dgtype == 'static') {
|
||||
// sync device_group_ids from input
|
||||
$updated = $template->groups()->sync($request->get('groups', []));
|
||||
// check for attached/detached/updated
|
||||
$device_groups_updated = array_sum(array_map(function ($device_group_ids) {
|
||||
return count($device_group_ids);
|
||||
}, $updated)) > 0;
|
||||
} else {
|
||||
$template->dgrules = json_decode($request->dgrules);
|
||||
}
|
||||
|
||||
if ($template->isDirty() || $devices_updated || $device_groups_updated) {
|
||||
try {
|
||||
if ($template->save() || $devices_updated || $device_groups_updated) {
|
||||
Toastr::success(__('Service Template :name updated', ['name' => $template->name]));
|
||||
} else {
|
||||
Toastr::error(__('Failed to save'));
|
||||
|
||||
return redirect()->back()->withInput();
|
||||
}
|
||||
} catch (\Illuminate\Database\QueryException $e) {
|
||||
return redirect()->back()->withInput()->withErrors([
|
||||
'drules' => __('Rules resulted in invalid query: ') . $e->getMessage(),
|
||||
'dgrules' => __('Rules resulted in invalid query: ') . $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
Toastr::info(__('No changes made'));
|
||||
}
|
||||
|
||||
return redirect()->route('services.templates.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply specified Service Template to Device Groups.
|
||||
*
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function applyDeviceGroups(ServiceTemplate $template)
|
||||
{
|
||||
foreach (DeviceGroup::inServiceTemplate($template->id)->get() as $device_group) {
|
||||
foreach (Device::inDeviceGroup($device_group->id)->get() as $device) {
|
||||
$device->services()->updateOrCreate(
|
||||
[
|
||||
'service_template_id' => $template->id,
|
||||
],
|
||||
[
|
||||
'service_name' => $template->name,
|
||||
'service_type' => $template->type,
|
||||
'service_template_id' => $template->id,
|
||||
'service_param' => $template->param,
|
||||
'service_ip' => $template->ip,
|
||||
'service_desc' => $template->desc,
|
||||
'service_disabled' => $template->disabled,
|
||||
'service_ignore' => $template->ignore,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
$msg = __('Services for Template :name have been updated', ['name' => $template->name]);
|
||||
|
||||
return response($msg, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply specified Service Template to Devices.
|
||||
*
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function applyDevices(ServiceTemplate $template)
|
||||
{
|
||||
foreach (Device::inServiceTemplate($template->id)->get() as $device) {
|
||||
$device->services()->updateOrCreate(
|
||||
[
|
||||
'service_template_id' => $template->id,
|
||||
],
|
||||
[
|
||||
'service_name' => $template->name,
|
||||
'service_type' => $template->type,
|
||||
'service_template_id' => $template->id,
|
||||
'service_param' => $template->param,
|
||||
'service_ip' => $template->ip,
|
||||
'service_desc' => $template->desc,
|
||||
'service_disabled' => $template->disabled,
|
||||
'service_ignore' => $template->ignore,
|
||||
]
|
||||
);
|
||||
}
|
||||
$msg = __('Services for Template :name have been updated', ['name' => $template->name]);
|
||||
|
||||
return response($msg, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply all Service Templates.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function applyAll()
|
||||
{
|
||||
foreach (ServiceTemplate::all() as $template) {
|
||||
ServiceTemplateController::apply($template);
|
||||
}
|
||||
$msg = __('All Service Templates have been applied');
|
||||
|
||||
return response($msg, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply specified Service Template.
|
||||
*
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function apply(ServiceTemplate $template)
|
||||
{
|
||||
ServiceTemplateController::applyDevices($template);
|
||||
ServiceTemplateController::applyDeviceGroups($template);
|
||||
|
||||
// remove any remaining services no longer in the correct device group
|
||||
foreach (Device::notInServiceTemplate($template->id)->notInDeviceGroup($template->groups)->get() as $device) {
|
||||
Service::where('device_id', $device->device_id)->where('service_template_id', $template->id)->delete();
|
||||
}
|
||||
$msg = __('All Service Templates have been applied');
|
||||
|
||||
return response($msg, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove specified Service Template.
|
||||
*
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function remove(ServiceTemplate $template)
|
||||
{
|
||||
Service::where('service_template_id', $template->id)->delete();
|
||||
|
||||
$msg = __('All Service Templates have been applied');
|
||||
|
||||
return response($msg, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\View\View
|
||||
*/
|
||||
public function destroy(ServiceTemplate $template)
|
||||
{
|
||||
Service::where('service_template_id', $template->id)->delete();
|
||||
$template->delete();
|
||||
|
||||
$msg = __('Service Template :name deleted, Services removed', ['name' => $template->name]);
|
||||
|
||||
return response($msg, 200);
|
||||
}
|
||||
}
|
|
@ -456,11 +456,46 @@ class Device extends BaseModel
|
|||
|
||||
public function scopeInDeviceGroup($query, $deviceGroup)
|
||||
{
|
||||
return $query->whereIn($query->qualifyColumn('device_id'), function ($query) use ($deviceGroup) {
|
||||
$query->select('device_id')
|
||||
->from('device_group_device')
|
||||
->where('device_group_id', $deviceGroup);
|
||||
});
|
||||
return $query->whereIn(
|
||||
$query->qualifyColumn('device_id'), function ($query) use ($deviceGroup) {
|
||||
$query->select('device_id')
|
||||
->from('device_group_device')
|
||||
->where('device_group_id', $deviceGroup);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function scopeNotInDeviceGroup($query, $deviceGroup)
|
||||
{
|
||||
return $query->whereNotIn(
|
||||
$query->qualifyColumn('device_id'), function ($query) use ($deviceGroup) {
|
||||
$query->select('device_id')
|
||||
->from('device_group_device')
|
||||
->where('device_group_id', $deviceGroup);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function scopeInServiceTemplate($query, $serviceTemplate)
|
||||
{
|
||||
return $query->whereIn(
|
||||
$query->qualifyColumn('device_id'), function ($query) use ($serviceTemplate) {
|
||||
$query->select('device_id')
|
||||
->from('service_templates_device')
|
||||
->where('service_template_id', $serviceTemplate);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function scopeNotInServiceTemplate($query, $serviceTemplate)
|
||||
{
|
||||
return $query->whereNotIn(
|
||||
$query->qualifyColumn('device_id'), function ($query) use ($serviceTemplate) {
|
||||
$query->select('device_id')
|
||||
->from('service_templates_device')
|
||||
->where('service_template_id', $serviceTemplate);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// ---- Define Relationships ----
|
||||
|
@ -635,6 +670,11 @@ class Device extends BaseModel
|
|||
return $this->hasMany(\App\Models\Sensor::class, 'device_id');
|
||||
}
|
||||
|
||||
public function serviceTemplates()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\ServiceTemplate::class, 'service_templates_device', 'device_id', 'service_template_id');
|
||||
}
|
||||
|
||||
public function services()
|
||||
{
|
||||
return $this->hasMany(\App\Models\Service::class, 'device_id');
|
||||
|
|
|
@ -138,6 +138,28 @@ class DeviceGroup extends BaseModel
|
|||
return $query->whereIn('id', Permissions::deviceGroupsForUser($user));
|
||||
}
|
||||
|
||||
public function scopeInServiceTemplate($query, $serviceTemplate)
|
||||
{
|
||||
return $query->whereIn(
|
||||
$query->qualifyColumn('id'), function ($query) use ($serviceTemplate) {
|
||||
$query->select('device_group_id')
|
||||
->from('service_templates_device_group')
|
||||
->where('service_template_id', $serviceTemplate);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function scopeNotInServiceTemplate($query, $serviceTemplate)
|
||||
{
|
||||
return $query->whereNotIn(
|
||||
$query->qualifyColumn('id'), function ($query) use ($serviceTemplate) {
|
||||
$query->select('device_group_id')
|
||||
->from('service_templates_device_group')
|
||||
->where('service_template_id', $serviceTemplate);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// ---- Define Relationships ----
|
||||
|
||||
public function devices()
|
||||
|
@ -154,4 +176,9 @@ class DeviceGroup extends BaseModel
|
|||
{
|
||||
return $this->belongsToMany(\App\Models\User::class, 'devices_group_perms', 'device_group_id', 'user_id');
|
||||
}
|
||||
|
||||
public function serviceTemplates()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\ServiceTemplate::class, 'service_templates_device_group', 'device_group_id', 'service_template_id');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,22 @@ class Service extends DeviceRelatedModel
|
|||
{
|
||||
public $timestamps = false;
|
||||
protected $primaryKey = 'service_id';
|
||||
protected $fillable = [
|
||||
'service_id',
|
||||
'device_id',
|
||||
'service_ip',
|
||||
'service_type',
|
||||
'service_desc',
|
||||
'service_param',
|
||||
'service_ignore',
|
||||
'service_status',
|
||||
'service_changed',
|
||||
'service_message',
|
||||
'service_disabled',
|
||||
'service_ds',
|
||||
'service_template_id',
|
||||
'service_name',
|
||||
];
|
||||
|
||||
// ---- Query Scopes ----
|
||||
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ServiceTemplate.php
|
||||
*
|
||||
* Service Templates with Dynamic groups of devices
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @link http://librenms.org
|
||||
* @copyright 2020 Anthony F McInerney <bofh80>
|
||||
* @author Anthony F McInerney <afm404@gmail.com>
|
||||
*/
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use LibreNMS\Alerting\QueryBuilderFluentParser;
|
||||
use Log;
|
||||
|
||||
class ServiceTemplate extends BaseModel
|
||||
{
|
||||
public $timestamps = false;
|
||||
protected $primaryKey = 'id';
|
||||
protected $fillable = [
|
||||
'id',
|
||||
'ip',
|
||||
'type',
|
||||
'dtype',
|
||||
'dgtype',
|
||||
'drules',
|
||||
'dgrules',
|
||||
'desc',
|
||||
'param',
|
||||
'ignore',
|
||||
'status',
|
||||
'changed',
|
||||
'disabled',
|
||||
'name',
|
||||
];
|
||||
|
||||
protected $attributes = [ // default values
|
||||
'ignore' => '0',
|
||||
'disabled' => '0',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'ignore' => 'integer',
|
||||
'disabled' => 'integer',
|
||||
'drules' => 'array',
|
||||
'dgrules' => 'array',
|
||||
];
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::deleting(function (ServiceTemplate $template) {
|
||||
$template->devices()->detach();
|
||||
$template->groups()->detach();
|
||||
});
|
||||
|
||||
static::saving(function (ServiceTemplate $template) {
|
||||
if ($template->isDirty('drules')) {
|
||||
$template->drules = $template->getDeviceParser()->generateJoins()->toArray();
|
||||
}
|
||||
if ($template->isDirty('dgrules')) {
|
||||
$template->dgrules = $template->getDeviceGroupParser()->generateJoins()->toArray();
|
||||
}
|
||||
});
|
||||
|
||||
static::saved(function (ServiceTemplate $template) {
|
||||
if ($template->isDirty('drules')) {
|
||||
$template->updateDevices();
|
||||
}
|
||||
if ($template->isDirty('dgrules')) {
|
||||
$template->updateGroups();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ---- Helper Functions ----
|
||||
|
||||
/**
|
||||
* Update devices included in this template (dynamic only)
|
||||
*/
|
||||
public function updateDevices()
|
||||
{
|
||||
if ($this->dtype == 'dynamic') {
|
||||
$this->devices()->sync(QueryBuilderFluentParser::fromJSON($this->rules)->toQuery()
|
||||
->distinct()->pluck('devices.device_id'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update device groups included in this template (dynamic only)
|
||||
*/
|
||||
public function updateGroups()
|
||||
{
|
||||
if ($this->dgtype == 'dynamic') {
|
||||
$this->groups()->sync(QueryBuilderFluentParser::fromJSON($this->rules)->toQuery()
|
||||
->distinct()->pluck('device_groups.id'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the device template groups for the given device or device_id
|
||||
*
|
||||
* @param Device|int $device
|
||||
* @return array
|
||||
*/
|
||||
public static function updateServiceTemplatesForDevice($device)
|
||||
{
|
||||
$device = ($device instanceof Device ? $device : Device::find($device));
|
||||
if (! $device instanceof Device) {
|
||||
// could not load device
|
||||
return [
|
||||
'attached' => [],
|
||||
'detached' => [],
|
||||
'updated' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$template_ids = static::query()
|
||||
->with(['devices' => function ($query) {
|
||||
$query->select('devices.device_id');
|
||||
}])
|
||||
->get()
|
||||
->filter(function ($template) use ($device) {
|
||||
/** @var ServiceTemplate $template */
|
||||
if ($template->dtype == 'dynamic') {
|
||||
try {
|
||||
return $template->getDeviceParser()
|
||||
->toQuery()
|
||||
->where('devices.device_id', $device->device_id)
|
||||
->exists();
|
||||
} catch (\Illuminate\Database\QueryException $e) {
|
||||
Log::error("Service Template '$template->name' generates invalid query: " . $e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// for static, if this device is include, keep it.
|
||||
return $template->devices
|
||||
->where('device_id', $device->device_id)
|
||||
->isNotEmpty();
|
||||
})->pluck('id');
|
||||
|
||||
return $device->serviceTemplates()->sync($template_ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the device template groups for the given device group or device_group_id
|
||||
*
|
||||
* @param DeviceGroup|int $deviceGroup
|
||||
* @return array
|
||||
*/
|
||||
public static function updateServiceTemplatesForDeviceGroup($deviceGroup)
|
||||
{
|
||||
$deviceGroup = ($deviceGroup instanceof DeviceGroup ? $deviceGroup : DeviceGroup::find($deviceGroup));
|
||||
if (! $deviceGroup instanceof DeviceGroup) {
|
||||
// could not load device
|
||||
return [
|
||||
'attached' => [],
|
||||
'detached' => [],
|
||||
'updated' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$template_ids = static::query()
|
||||
->with(['device_groups' => function ($query) {
|
||||
$query->select('device_groups.id');
|
||||
}])
|
||||
->get()
|
||||
->filter(function ($template) use ($deviceGroup) {
|
||||
/** @var ServiceTemplate $template */
|
||||
if ($template->dgtype == 'dynamic') {
|
||||
try {
|
||||
return $template->getDeviceGroupParser()
|
||||
->toQuery()
|
||||
->where('device_groups.id', $deviceGroup->id)
|
||||
->exists();
|
||||
} catch (\Illuminate\Database\QueryException $e) {
|
||||
Log::error("Service Template '$template->name' generates invalid query: " . $e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// for static, if this device group is include, keep it.
|
||||
return $template->groups
|
||||
->where('device_group_id', $deviceGroup->id)
|
||||
->isNotEmpty();
|
||||
})->pluck('id');
|
||||
|
||||
return $deviceGroup->serviceTemplates()->sync($template_ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a query builder parser instance from this Service Template device rule
|
||||
*
|
||||
* @return QueryBuilderFluentParser
|
||||
*/
|
||||
public function getDeviceParser()
|
||||
{
|
||||
return QueryBuilderFluentParser::fromJson($this->drules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a query builder parser instance from this Service Template device group rule
|
||||
*
|
||||
* @return QueryBuilderFluentParser
|
||||
*/
|
||||
public function getDeviceGroupParser()
|
||||
{
|
||||
return QueryBuilderFluentParser::fromJson($this->dgrules);
|
||||
}
|
||||
|
||||
// ---- Query Scopes ----
|
||||
|
||||
/**
|
||||
* @param Builder $query
|
||||
* @return Builder
|
||||
*/
|
||||
public function scopeIsDisabled($query)
|
||||
{
|
||||
return $query->where('disabled', 1);
|
||||
}
|
||||
|
||||
// ---- Define Relationships ----
|
||||
|
||||
public function devices()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\Device::class, 'service_templates_device', 'service_template_id', 'device_id');
|
||||
}
|
||||
|
||||
public function services()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\Service::class, 'service_templates_device', 'service_template_id', 'device_id');
|
||||
}
|
||||
|
||||
public function groups()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\DeviceGroup::class, 'service_templates_device_group', 'service_template_id', 'device_group_id');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Models\Service;
|
||||
|
||||
class ServiceObserver
|
||||
{
|
||||
/**
|
||||
* Handle the service "created" event.
|
||||
*
|
||||
* @param \App\Models\Service $service
|
||||
* @return void
|
||||
*/
|
||||
public function created(Service $service)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the service "updated" event.
|
||||
*
|
||||
* @param \App\Models\Service $service
|
||||
* @return void
|
||||
*/
|
||||
public function updated(Service $service)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the service "deleted" event.
|
||||
*
|
||||
* @param \App\Models\Service $service
|
||||
* @return void
|
||||
*/
|
||||
public function deleted(Service $service)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the service "restored" event.
|
||||
*
|
||||
* @param \App\Models\Service $service
|
||||
* @return void
|
||||
*/
|
||||
public function restored(Service $service)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the service "force deleted" event.
|
||||
*
|
||||
* @param \App\Models\Service $service
|
||||
* @return void
|
||||
*/
|
||||
public function forceDeleted(Service $service)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\ServiceTemplate;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class ServiceTemplatePolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any service templates.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function viewAny(User $user)
|
||||
{
|
||||
return $user->hasGlobalRead();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the service template.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return mixed
|
||||
*/
|
||||
public function view(User $user, ServiceTemplate $template)
|
||||
{
|
||||
return $this->viewAny($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create service templates.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function create(User $user)
|
||||
{
|
||||
return $user->hasGlobalAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the service template.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(User $user, ServiceTemplate $template)
|
||||
{
|
||||
return $user->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the service template.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete(User $user, ServiceTemplate $template)
|
||||
{
|
||||
return $user->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the service template.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return mixed
|
||||
*/
|
||||
public function restore(User $user, ServiceTemplate $template)
|
||||
{
|
||||
return $user->hasGlobalAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the service template.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return mixed
|
||||
*/
|
||||
public function forceDelete(User $user, ServiceTemplate $template)
|
||||
{
|
||||
return $user->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the stored configuration of the service template
|
||||
* from Oxidized or Rancid
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return mixed
|
||||
*/
|
||||
public function showConfig(User $user, ServiceTemplate $template)
|
||||
{
|
||||
return $user->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update service template notes.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\ServiceTemplate $template
|
||||
* @return mixed
|
||||
*/
|
||||
public function updateNotes(User $user, ServiceTemplate $template)
|
||||
{
|
||||
return $user->isAdmin();
|
||||
}
|
||||
}
|
|
@ -130,6 +130,7 @@ class AppServiceProvider extends ServiceProvider
|
|||
private function bootObservers()
|
||||
{
|
||||
\App\Models\Device::observe(\App\Observers\DeviceObserver::class);
|
||||
\App\Models\Service::observe(\App\Observers\ServiceObserver::class);
|
||||
}
|
||||
|
||||
private function bootCustomValidators()
|
||||
|
|
|
@ -20,6 +20,7 @@ class AuthServiceProvider extends ServiceProvider
|
|||
\App\Models\DeviceGroup::class => \App\Policies\DeviceGroupPolicy::class,
|
||||
\App\Models\PollerCluster::class => \App\Policies\PollerClusterPolicy::class,
|
||||
\App\Models\Port::class => \App\Policies\PortPolicy::class,
|
||||
\App\Models\ServiceTemplate::class => \App\Policies\ServiceTemplatePolicy::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class CreateServiceTemplatesDeviceGroupTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('service_templates_device_group', function (Blueprint $table) {
|
||||
$table->unsignedInteger('service_template_id')->unsigned()->index();
|
||||
$table->unsignedInteger('device_group_id')->unsigned()->index();
|
||||
|
||||
$table->primary(['service_template_id', 'device_group_id'], 'service_templates_device_group_relationship_primary');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('service_templates_device_group');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class CreateServiceTemplatesDeviceTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('service_templates_device', function (Blueprint $table) {
|
||||
$table->unsignedInteger('service_template_id')->unsigned()->index();
|
||||
$table->unsignedInteger('device_id')->unsigned()->index();
|
||||
|
||||
$table->primary(['service_template_id', 'device_id'], 'service_templates_device_relationship_primary');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('service_templates_device');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class CreateServiceTemplatesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('service_templates', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->text('ip')->nullable()->default(null);
|
||||
$table->string('type');
|
||||
$table->string('dtype', 16)->default('static');
|
||||
$table->string('dgtype', 16)->default('static');
|
||||
$table->text('drules')->nullable();
|
||||
$table->text('dgrules')->nullable();
|
||||
$table->text('desc')->nullable()->default(null);
|
||||
$table->text('param')->nullable()->default(null);
|
||||
$table->boolean('ignore')->default(0);
|
||||
if (\LibreNMS\DB\Eloquent::getDriver() == 'mysql') {
|
||||
$table->timestamp('changed')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'));
|
||||
} else {
|
||||
$table->timestamp('changed')->useCurrent();
|
||||
}
|
||||
$table->boolean('disabled')->default(0);
|
||||
$table->string('name');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('service_templates');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class ExtendServicesTableForServiceTemplatesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('services', function (Blueprint $table) {
|
||||
$table->unsignedInteger('service_template_id')->default(0);
|
||||
$table->string('service_name')->nullable()->default(null);
|
||||
$table->text('service_desc')->nullable()->default(null)->change();
|
||||
$table->text('service_param')->nullable()->default(null)->change();
|
||||
$table->boolean('service_ignore')->default(0)->change();
|
||||
$table->text('service_ip')->nullable()->default(null)->change();
|
||||
$table->text('service_ds')->nullable()->default(null)->change();
|
||||
$table->text('service_message')->nullable()->default(null)->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('services', function (Blueprint $table) {
|
||||
$table->dropColumn([
|
||||
'service_template_id',
|
||||
'service_name',
|
||||
]);
|
||||
$table->text('service_desc')->change();
|
||||
$table->text('service_param')->change();
|
||||
$table->boolean('service_ignore')->change();
|
||||
$table->text('service_ip')->change();
|
||||
$table->text('service_ds')->change();
|
||||
$table->text('service_message')->change();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class AddForeignKeysToServiceTemplatesDeviceGroupTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('service_templates_device_group', function (Blueprint $table) {
|
||||
$table->foreign('service_template_id')->references('id')->on('service_templates')->onUpdate('RESTRICT')->onDelete('CASCADE');
|
||||
$table->foreign('device_group_id')->references('id')->on('device_groups')->onUpdate('RESTRICT')->onDelete('CASCADE');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
if (\LibreNMS\DB\Eloquent::getDriver() !== 'sqlite') {
|
||||
Schema::table('service_templates_device_group', function (Blueprint $table) {
|
||||
$table->dropForeign('service_templates_device_group_service_template_id_foreign');
|
||||
$table->dropForeign('service_templates_device_group_device_group_id_foreign');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class AddForeignKeysToServiceTemplatesDeviceTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('service_templates_device', function (Blueprint $table) {
|
||||
$table->foreign('service_template_id')->references('id')->on('service_templates')->onUpdate('RESTRICT')->onDelete('CASCADE');
|
||||
$table->foreign('device_id')->references('device_id')->on('devices')->onUpdate('RESTRICT')->onDelete('CASCADE');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
if (\LibreNMS\DB\Eloquent::getDriver() !== 'sqlite') {
|
||||
Schema::table('service_templates_device', function (Blueprint $table) {
|
||||
$table->dropForeign('service_templates_device_service_template_id_foreign');
|
||||
$table->dropForeign('service_templates_device_device_id_foreign');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,54 @@ Note: Plugins will only load if they are prefixed with `check_`.
|
|||
The `check_` prefix is stripped out when displaying in the "Add Service"
|
||||
GUI "Type" dropdown list.
|
||||
|
||||
## Service Templates
|
||||
|
||||
Service Templates within LibreNMS provides the same ability as Nagios
|
||||
does with Host Groups. Known as Device Groups in LibreNMS.
|
||||
They are applied devices that belong to the specified Device Group.
|
||||
|
||||
Use the Apply buttons to manually create or update Services for the Service
|
||||
Template.
|
||||
Use the Remove buttons to manually remove Services for the Service Template.
|
||||
|
||||
After you Edit a Service Template, and then use Apply, all relevant changes are
|
||||
pushed to existing Services previously created.
|
||||
|
||||
You can also enable Service Templates Auto Discovery to have Services
|
||||
added / removed / updated on regular discover intervals.
|
||||
|
||||
When a Device is a member of multiple Device Groups, templates from
|
||||
all of those Device Groups are applied.
|
||||
|
||||
If a Device is added or removed from a Device Group, when the Apply button
|
||||
is used or Auto Discovery runs Services will be added / removed as
|
||||
appropriate.
|
||||
|
||||
**Service Templates are tied into Device Groups, you need at least
|
||||
one Device Group to be able to add Service Templates - You can define a
|
||||
dummy one. The Device Group does not need members to add Service Templates.**
|
||||
|
||||
## Service Auto Discovery
|
||||
|
||||
To automatically create services for devices with available checks.
|
||||
|
||||
You need to enable the discover services within config.php with the following:
|
||||
|
||||
```php
|
||||
$config['discover_services'] = true;
|
||||
```
|
||||
|
||||
## Service Templates Auto Discovery
|
||||
|
||||
To automatically create services for devices with configured
|
||||
Service Templates.
|
||||
|
||||
You need to enable the discover services within config.php with the following:
|
||||
|
||||
```php
|
||||
$config['discover_services_templates'] = true;
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
Service checks are now distributable if you run a distributed
|
||||
|
@ -157,6 +205,42 @@ then you can run the following command to help troubleshoot services.
|
|||
./check-services.php -d
|
||||
```
|
||||
|
||||
## Related Polling / Discovery Options
|
||||
|
||||
These settings are related and should be investigated and set accordingly.
|
||||
The below values are not defaults or recommended.
|
||||
|
||||
```php
|
||||
$config['service_poller_enabled'] = true;
|
||||
```
|
||||
```php
|
||||
$config['service_poller_workers'] = 16;
|
||||
```
|
||||
```php
|
||||
$config['service_poller_frequency'] = 300;
|
||||
```
|
||||
```php
|
||||
$config['service_poller_down_retry'] = 5;
|
||||
```
|
||||
```php
|
||||
$config['service_discovery_enabled'] = true;
|
||||
```
|
||||
```php
|
||||
$config['service_discovery_workers'] = 16;
|
||||
```
|
||||
```php
|
||||
$config['service_discovery_frequency'] = 3600;
|
||||
```
|
||||
```php
|
||||
$config['service_services_enabled'] = true;
|
||||
```
|
||||
```php
|
||||
$config['service_services_workers'] = 16;
|
||||
```
|
||||
```php
|
||||
$config['service_services_frequency'] = 60;
|
||||
```
|
||||
|
||||
## Service checks polling logic
|
||||
|
||||
Service check is skipped when the associated device is not pingable,
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<?php
|
||||
|
||||
use App\Http\Controllers\ServiceTemplateController;
|
||||
use LibreNMS\Config;
|
||||
|
||||
if (Config::get('discover_services_templates')) {
|
||||
ServiceTemplateController::applyAll();
|
||||
}
|
||||
if (Config::get('discover_services')) {
|
||||
// FIXME: use /etc/services?
|
||||
$known_services = [
|
||||
|
|
|
@ -18,6 +18,7 @@ use App\Models\DeviceGroup;
|
|||
use App\Models\DeviceOutage;
|
||||
use App\Models\PortsFdb;
|
||||
use App\Models\Sensor;
|
||||
use App\Models\ServiceTemplate;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\Arr;
|
||||
|
@ -2328,6 +2329,57 @@ function missing_fields($required_fields, $data)
|
|||
return false;
|
||||
}
|
||||
|
||||
function add_service_template_for_device_group(Illuminate\Http\Request $request)
|
||||
{
|
||||
$data = json_decode($request->getContent(), true);
|
||||
if (json_last_error() || ! is_array($data)) {
|
||||
return api_error(400, "We couldn't parse the provided json. " . json_last_error_msg());
|
||||
}
|
||||
|
||||
$rules = [
|
||||
'name' => 'required|string|unique:service_templates',
|
||||
'device_group_id' => 'integer',
|
||||
'type' => 'string',
|
||||
'param' => 'nullable|string',
|
||||
'ip' => 'nullable|string',
|
||||
'desc' => 'nullable|string',
|
||||
'changed' => 'integer',
|
||||
'disabled' => 'integer',
|
||||
'ignore' => 'integer',
|
||||
];
|
||||
|
||||
$v = Validator::make($data, $rules);
|
||||
if ($v->fails()) {
|
||||
return api_error(422, $v->messages());
|
||||
}
|
||||
|
||||
// Only use the rules if they are able to be parsed by the QueryBuilder
|
||||
$query = QueryBuilderParser::fromJson($data['rules'])->toSql();
|
||||
if (empty($query)) {
|
||||
return api_error(500, "We couldn't parse your rule");
|
||||
}
|
||||
|
||||
$serviceTemplate = ServiceTemplate::make(['name' => $data['name'], 'device_group_id' => $data['device_group_id'], 'type' => $data['type'], 'param' => $data['param'], 'ip' => $data['ip'], 'desc' => $data['desc'], 'changed' => $data['changed'], 'disabled' => $data['disabled'], 'ignore' => $data['ignore']]);
|
||||
$serviceTemplate->save();
|
||||
|
||||
return api_success($serviceTemplate->id, 'id', 'Service Template ' . $serviceTemplate->name . ' created', 201);
|
||||
}
|
||||
|
||||
function get_service_templates(Illuminate\Http\Request $request)
|
||||
{
|
||||
if ($request->user()->cannot('viewAny', ServiceTemplate::class)) {
|
||||
return api_error(403, 'Insufficient permissions to access service templates');
|
||||
}
|
||||
|
||||
$templates = ServiceTemplate::query()->orderBy('name')->get();
|
||||
|
||||
if ($templates->isEmpty()) {
|
||||
return api_error(404, 'No service templates found');
|
||||
}
|
||||
|
||||
return api_success($templates->makeHidden('pivot')->toArray(), 'templates', 'Found ' . $templates->count() . ' service templates');
|
||||
}
|
||||
|
||||
function add_service_for_host(Illuminate\Http\Request $request)
|
||||
{
|
||||
$hostname = $request->route('hostname');
|
||||
|
@ -2344,7 +2396,9 @@ function add_service_for_host(Illuminate\Http\Request $request)
|
|||
$service_desc = $data['desc'] ? $data['desc'] : '';
|
||||
$service_param = $data['param'] ? $data['param'] : '';
|
||||
$service_ignore = $data['ignore'] ? true : false; // Default false
|
||||
$service_id = add_service($device_id, $service_type, $service_desc, $service_ip, $service_param, (int) $service_ignore);
|
||||
$service_disable = $data['disable'] ? true : false; // Default false
|
||||
$service_name = $data['name'];
|
||||
$service_id = add_service($device_id, $service_type, $service_desc, $service_ip, $service_param, (int) $service_ignore, (int) $service_disable, 0, $service_name);
|
||||
if ($service_id != false) {
|
||||
return api_success_noresult(201, "Service $service_type has been added to device $hostname (#$service_id)");
|
||||
}
|
||||
|
|
|
@ -24,10 +24,12 @@ $param = $vars['param'];
|
|||
$ignore = isset($vars['ignore']) ? 1 : 0;
|
||||
$disabled = isset($vars['disabled']) ? 1 : 0;
|
||||
$device_id = $vars['device_id'];
|
||||
$template_id = $vars['template_id'];
|
||||
$name = $vars['name'];
|
||||
|
||||
if (is_numeric($service_id) && $service_id > 0) {
|
||||
// Need to edit.
|
||||
$update = ['service_desc' => $desc, 'service_ip' => $ip, 'service_param' => $param, 'service_ignore' => $ignore, 'service_disabled' => $disabled];
|
||||
$update = ['service_desc' => $desc, 'service_ip' => $ip, 'service_param' => $param, 'service_ignore' => $ignore, 'service_disabled' => $disabled, 'service_template_id' => $template_id, 'service_name' => $name];
|
||||
if (is_numeric(edit_service($update, $service_id))) {
|
||||
$status = ['status' =>0, 'message' => 'Modified Service: <i>' . $service_id . ': ' . $type . '</i>'];
|
||||
} else {
|
||||
|
@ -35,7 +37,7 @@ if (is_numeric($service_id) && $service_id > 0) {
|
|||
}
|
||||
} else {
|
||||
// Need to add.
|
||||
$service_id = add_service($device_id, $type, $desc, $ip, $param, $ignore, $disabled);
|
||||
$service_id = add_service($device_id, $type, $desc, $ip, $param, $ignore, $disabled, 0, $name);
|
||||
if ($service_id == false) {
|
||||
$status = ['status' =>1, 'message' => 'ERROR: Failed to add Service: <i>' . $type . '</i>'];
|
||||
} else {
|
||||
|
|
|
@ -27,7 +27,9 @@ if (is_numeric($service_id) && $service_id > 0) {
|
|||
'desc' => $service[0]['service_desc'],
|
||||
'param' => $service[0]['service_param'],
|
||||
'ignore' => $service[0]['service_ignore'],
|
||||
'disabled' => $service[0]['service_disabled'],
|
||||
'disabled' => $service[0]['service_disabled'],
|
||||
'template_id' => $service[0]['service_template_id'],
|
||||
'name' => $service[0]['service_name'],
|
||||
];
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
|
|
@ -30,64 +30,88 @@ if (Auth::user()->hasGlobalAdmin()) {
|
|||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h5 class="modal-title" id="Create">Services</h5>
|
||||
<h2 class="modal-title" id="Create">Add / Edit Service</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="post" role="form" id="service" class="form-horizontal service-form">
|
||||
<?php echo csrf_field() ?>
|
||||
<input type="hidden" name="service_id" id="service_id" value="">
|
||||
<input type="hidden" name="device_id" id="device_id" value="<?php echo $device['device_id']?>">
|
||||
<input type="hidden" name="type" id="type" value="create-service">
|
||||
<div class="form-service">
|
||||
<div class="col-sm-12">
|
||||
<span id="ajax_response"> </span>
|
||||
<div class='alert alert-info'>Service will modified for the specified Device.</div>
|
||||
<div class='well well-lg'>
|
||||
<div class="modal-body">
|
||||
<form method="post" role="form" id="service" class="form-horizontal service-form">
|
||||
<?php echo csrf_field() ?>
|
||||
<input type="hidden" name="service_id" id="service_id" value="">
|
||||
<input type="hidden" name="service_template_id" id="service_template_id" value="">
|
||||
<input type="hidden" name="device_id" id="device_id" value="<?php echo $device['device_id']?>">
|
||||
<input type="hidden" name="type" id="type" value="create-service">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<span id="ajax_response"> </span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-service row">
|
||||
<label for='stype' class='col-sm-3 control-label'>Type: </label>
|
||||
<div class="col-sm-9">
|
||||
<select id='stype' name='stype' placeholder='type' class='form-control has-feedback'>
|
||||
<?php echo $stype?>
|
||||
</select>
|
||||
<div class="form-group row">
|
||||
<label for='name' class='col-sm-3 control-label'>Name: </label>
|
||||
<div class="col-sm-9">
|
||||
<input type='text' id='name' name='name' class='form-control input-sm' placeholder=''/>
|
||||
</div>
|
||||
<div class='col-sm-9'>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='form-service row'>
|
||||
<label for='desc' class='col-sm-3 control-label'>Description: </label>
|
||||
<div class='col-sm-9'>
|
||||
<textarea id='desc' name='desc' class='form-control'></textarea>
|
||||
<div class="form-group row">
|
||||
<label for='stype' class='col-sm-3 control-label'>Check Type: </label>
|
||||
<div class="col-sm-9">
|
||||
<select id='stype' name='stype' placeholder='type' class='form-control has-feedback'>
|
||||
<?php echo $stype?>
|
||||
</select>
|
||||
</div>
|
||||
<div class='col-sm-9'>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-service row">
|
||||
<label for='ip' class='col-sm-3 control-label'>IP Address: </label>
|
||||
<div class="col-sm-9">
|
||||
<input type='text' id='ip' name='ip' class='form-control has-feedback' placeholder='<?php echo $device['hostname']?>'/>
|
||||
<div class='form-group row'>
|
||||
<label for='desc' class='col-sm-3 control-label'>Description: </label>
|
||||
<div class='col-sm-9'>
|
||||
<textarea id='desc' name='desc' class='form-control' rows='5'></textarea>
|
||||
</div>
|
||||
<div class='col-sm-9'>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-service row">
|
||||
<label for='param' class='col-sm-3 control-label'>Parameters: </label>
|
||||
<div class="col-sm-9">
|
||||
<input type='text' id='param' name='param' class='form-control has-feedback' placeholder=''/>
|
||||
<div class="form-group row">
|
||||
<label for='ip' class='col-sm-3 control-label'>Remote Host: </label>
|
||||
<div class="col-sm-9">
|
||||
<input type='text' id='ip' name='ip' class='form-control has-feedback' placeholder='IP Address or Hostname'/>
|
||||
</div>
|
||||
<div class='col-sm-9'>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-service row">
|
||||
<label for='ignore' class='col-sm-3 control-label'>Ignore alert tag: </label>
|
||||
<div class="col-sm-9">
|
||||
<input type='checkbox' id='ignore' name='ignore'>
|
||||
<div class="form-group row">
|
||||
<label for='param' class='col-sm-3 control-label'>Parameters: </label>
|
||||
<div class="col-sm-9">
|
||||
<input type='text' id='param' name='param' class='form-control has-feedback' placeholder=''/>
|
||||
</div>
|
||||
<div class='col-sm-9'>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-service row">
|
||||
<label for='disabled' class='col-sm-3 control-label'>Disable polling and alerting: </label>
|
||||
<div class="col-sm-9">
|
||||
<input type='checkbox' id='disabled' name='disabled'>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12 alert alert-info">
|
||||
<label class='control-label text-left input-sm'>Parameters may be required and will be different depending on the service check.</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-service row">
|
||||
<div class="col-sm-offset-3 col-sm-9">
|
||||
<button class="btn btn-success btn-sm" type="submit" name="service-submit" id="service-submit" value="save">Save Service</button>
|
||||
<div class="form-group row">
|
||||
<label for='ignore' class='col-sm-3 control-label'>Ignore alert tag: </label>
|
||||
<div class="col-sm-9">
|
||||
<input type='checkbox' id='ignore' name='ignore'>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
<div class="form-group row">
|
||||
<label for='disabled' class='col-sm-3 control-label'>Disable polling and alerting: </label>
|
||||
<div class="col-sm-9">
|
||||
<input type='checkbox' id='disabled' name='disabled'>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-group row">
|
||||
<center><button class="btn btn-default btn-sm" type="submit" name="service-submit" id="service-submit" value="save">Save Service</button></center>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -104,6 +128,9 @@ $('#create-service').on('hide.bs.modal', function (event) {
|
|||
$('#param').val('');
|
||||
$('#ignore').val('');
|
||||
$('#disabled').val('');
|
||||
$('#service_template_id').val('');
|
||||
$('#name').val('');
|
||||
$('#service_template_name').val('');
|
||||
});
|
||||
|
||||
// on-load
|
||||
|
@ -131,6 +158,8 @@ $('#create-service').on('show.bs.modal', function (e) {
|
|||
if ($('#disabled').attr('value') == 1) {
|
||||
$('#disabled').prop("checked", true);
|
||||
}
|
||||
$('#service_template_id').val(output['service_template_id']);
|
||||
$('#name').val(output['name']);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ if (! Auth::user()->hasGlobalAdmin()) {
|
|||
if (Auth::user()->hasGlobalAdmin()) {
|
||||
$updated = '1';
|
||||
|
||||
$service_id = add_service($vars['device'], $vars['type'], $vars['descr'], $vars['ip'], $vars['params'], 0);
|
||||
$service_id = add_service($vars['device'], $vars['type'], $vars['descr'], $vars['ip'], $vars['params'], $vars['ignore'], $vars['disabled'], 0, $vars['name']);
|
||||
if ($service_id) {
|
||||
$message .= $message_break . 'Service added (' . $service_id . ')!';
|
||||
$message_break .= '<br />';
|
||||
|
@ -31,6 +31,8 @@ if (! Auth::user()->hasGlobalAdmin()) {
|
|||
$pagetitle[] = 'Add service';
|
||||
|
||||
echo "<div class='row'>
|
||||
<div class='col-sm-3'>
|
||||
</div>
|
||||
<div class='col-sm-6'>";
|
||||
|
||||
include_once 'includes/html/print-service-add.inc.php';
|
||||
|
|
|
@ -5,7 +5,7 @@ if (Auth::user()->hasGlobalRead()) {
|
|||
if (Auth::user()->hasGlobalAdmin()) {
|
||||
$updated = '1';
|
||||
|
||||
$service_id = add_service($vars['device'], $vars['type'], $vars['descr'], $vars['ip'], $vars['params'], 0);
|
||||
$service_id = add_service($vars['device'], $vars['type'], $vars['descr'], $vars['ip'], $vars['params'], $vars['ignore'], $vars['disabled'], 0, $vars['name']);
|
||||
if ($service_id) {
|
||||
$message .= $message_break . 'Service added (' . $service_id . ')!';
|
||||
$message_break .= '<br />';
|
||||
|
|
|
@ -173,10 +173,14 @@ require_once 'includes/html/modal/delete_service.inc.php';
|
|||
echo '<table class="table table-hover table-condensed">';
|
||||
echo '<thead>';
|
||||
echo '<th style="width:1%;max-width:1%;"></th>';
|
||||
echo '<th style="width:10%;max-width: 10%;">Service</th>';
|
||||
echo '<th style="width:15%;max-width: 15%;">Last Changed</th>';
|
||||
echo '<th style="width:15%;max-width: 15%;">Description</th>';
|
||||
echo '<th style="width:10%;max-width: 10%;">Name</th>';
|
||||
echo '<th style="width:10%;max-width: 10%;">Check Type</th>';
|
||||
echo '<th style="width:10%;max-width: 15%;">Remote Host</th>';
|
||||
echo '<th >Message</th>';
|
||||
echo '<th style="width:15%;max-width: 15%;">Description</th>';
|
||||
echo '<th style="width:15%;max-width: 15%;">Last Changed</th>';
|
||||
echo '<th style="width:5%;max-width: 5%;">Ignored</th>';
|
||||
echo '<th style="width:5%;max-width: 5%;">Disabled</th>';
|
||||
echo '<th style="width:5%;max-width:5%;"></th>';
|
||||
echo '</thead>';
|
||||
}
|
||||
|
@ -185,10 +189,14 @@ require_once 'includes/html/modal/delete_service.inc.php';
|
|||
|
||||
echo '<tr id="row_' . $service['service_id'] . '">';
|
||||
echo '<td><span data-toggle="tooltip" title="' . $title . '" class="alert-status ' . $label . '"></span></td>';
|
||||
echo '<td>' . nl2br(display($service['service_name'])) . '</td>';
|
||||
echo '<td>' . nl2br(display($service['service_type'])) . '</td>';
|
||||
echo '<td>' . formatUptime(time() - $service['service_changed']) . '</td>';
|
||||
echo '<td>' . nl2br(display($service['service_desc'])) . '</td>';
|
||||
echo '<td>' . nl2br(display($service['service_ip'])) . '</td>';
|
||||
echo '<td>' . nl2br(display($service['service_message'])) . '</td>';
|
||||
echo '<td>' . nl2br(display($service['service_desc'])) . '</td>';
|
||||
echo '<td>' . formatUptime(time() - $service['service_changed']) . '</td>';
|
||||
echo '<td>' . nl2br(display($service['service_ignore'])) . '</td>';
|
||||
echo '<td>' . nl2br(display($service['service_disabled'])) . '</td>';
|
||||
|
||||
if (Auth::user()->hasGlobalAdmin()) {
|
||||
echo "<td>
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
<?php
|
||||
|
||||
echo "
|
||||
<h3><span class='label label-success threeqtr-width'>Add Service</span></h3>
|
||||
<form id='addsrv' name='addsrv' method='post' action='' class='form-horizontal' role='form'>
|
||||
" . csrf_field() . "
|
||||
<div><h2>Add Service</h2></div>
|
||||
<div class='alert alert-info'>Service will created for the specified Device.</div>
|
||||
<div class='well well-lg'>
|
||||
<div class='form-group'>
|
||||
<label for='name' class='col-sm-2 control-label'>Name:</label>
|
||||
<div class='col-sm-5'>
|
||||
<input name='name' id='name' class='form-control input-sm'>
|
||||
</div>
|
||||
<div class='col-sm-5'>
|
||||
</div>
|
||||
</div>
|
||||
<div class='form-group'>
|
||||
<input type='hidden' name='addsrv' value='yes'>
|
||||
<label for='device' class='col-sm-2 control-label'>Device</label>
|
||||
<label for='device' class='col-sm-2 control-label'>Device:</label>
|
||||
<div class='col-sm-5'>
|
||||
<select name='device' class='form-control input-sm'>
|
||||
$devicesform
|
||||
|
@ -17,7 +26,7 @@ echo "
|
|||
</div>
|
||||
</div>
|
||||
<div class='form-group'>
|
||||
<label for='type' class='col-sm-2 control-label'>Type</label>
|
||||
<label for='type' class='col-sm-2 control-label'>Check Type:</label>
|
||||
<div class='col-sm-5'>
|
||||
<select name='type' id='type' class='form-control input-sm'>
|
||||
$servicesform
|
||||
|
@ -27,7 +36,7 @@ echo "
|
|||
</div>
|
||||
</div>
|
||||
<div class='form-group'>
|
||||
<label for='descr' class='col-sm-2 control-label'>Description</label>
|
||||
<label for='descr' class='col-sm-2 control-label'>Description:</label>
|
||||
<div class='col-sm-5'>
|
||||
<textarea name='descr' id='descr' class='form-control input-sm' rows='5'></textarea>
|
||||
</div>
|
||||
|
@ -35,22 +44,37 @@ echo "
|
|||
</div>
|
||||
</div>
|
||||
<div class='form-group'>
|
||||
<label for='ip' class='col-sm-2 control-label'>IP Address</label>
|
||||
<label for='ip' class='col-sm-2 control-label'>Remote Host:</label>
|
||||
<div class='col-sm-5'>
|
||||
<input name='ip' id='ip' class='form-control input-sm' placeholder='IP Address'>
|
||||
<input name='ip' id='ip' class='form-control input-sm' placeholder='IP Address or Hostname'>
|
||||
</div>
|
||||
<div class='col-sm-5'>
|
||||
</div>
|
||||
</div>
|
||||
<div class='form-group'>
|
||||
<label for='params' class='col-sm-2 control-label'>Parameters</label>
|
||||
<label for='params' class='col-sm-2 control-label'>Parameters:</label>
|
||||
<div class='col-sm-5'>
|
||||
<input name='params' id='params' class='form-control input-sm'>
|
||||
</div>
|
||||
<div class='col-sm-5'>
|
||||
This may be required based on the service check.
|
||||
</div>
|
||||
<div class='form-group'>
|
||||
<div class='col-sm-12 alert alert-info'>
|
||||
<label class='control-label text-left input-sm'>Parameters may be required and will be different depending on the service check.</label>
|
||||
</div>
|
||||
</div>
|
||||
<button type='submit' name='Submit' class='btn btn-success input-sm'>Add Service</button>
|
||||
<div class='form-group'>
|
||||
<label for='ignore' class='col-sm-2 control-label'>Ignore Alert Tag:</label>
|
||||
<div class='col-sm-5'>
|
||||
<input name='ignore' id='ignore' type='checkbox'>
|
||||
</div>
|
||||
</div>
|
||||
<div class='form-group'>
|
||||
<label for='disabled' class='col-sm-2 control-label'>Disable Polling and Alerting: </label>
|
||||
<div class='col-sm-5'>
|
||||
<input name='disabled' id='disabled' type='checkbox'>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<center><button type='submit' name='Submit' class='btn btn-default input-sm'>Add Service</button></center>
|
||||
</div>
|
||||
</form>";
|
||||
|
|
|
@ -36,7 +36,7 @@ function get_service_status($device = null)
|
|||
return $service_count;
|
||||
}
|
||||
|
||||
function add_service($device, $type, $desc, $ip = '', $param = '', $ignore = 0, $disabled = 0)
|
||||
function add_service($device, $type, $desc, $ip = '', $param = '', $ignore = 0, $disabled = 0, $template_id = '', $name)
|
||||
{
|
||||
if (! is_array($device)) {
|
||||
$device = device_by_id_cache($device);
|
||||
|
@ -46,14 +46,14 @@ function add_service($device, $type, $desc, $ip = '', $param = '', $ignore = 0,
|
|||
$ip = Device::pollerTarget($device['hostname']);
|
||||
}
|
||||
|
||||
$insert = ['device_id' => $device['device_id'], 'service_ip' => $ip, 'service_type' => $type, 'service_changed' => ['UNIX_TIMESTAMP(NOW())'], 'service_desc' => $desc, 'service_param' => $param, 'service_ignore' => $ignore, 'service_status' => 3, 'service_message' => 'Service not yet checked', 'service_ds' => '{}', 'service_disabled' => $disabled];
|
||||
$insert = ['device_id' => $device['device_id'], 'service_ip' => $ip, 'service_type' => $type, 'service_changed' => ['UNIX_TIMESTAMP(NOW())'], 'service_desc' => $desc, 'service_param' => $param, 'service_ignore' => $ignore, 'service_status' => 3, 'service_message' => 'Service not yet checked', 'service_ds' => '{}', 'service_disabled' => $disabled, 'service_template_id' => $template_id, 'service_name' => $name];
|
||||
|
||||
return dbInsert($insert, 'services');
|
||||
}
|
||||
|
||||
function service_get($device = null, $service = null)
|
||||
{
|
||||
$sql_query = 'SELECT `service_id`,`device_id`,`service_ip`,`service_type`,`service_desc`,`service_param`,`service_ignore`,`service_status`,`service_changed`,`service_message`,`service_disabled`,`service_ds` FROM `services` WHERE';
|
||||
$sql_query = 'SELECT `service_id`,`device_id`,`service_ip`,`service_type`,`service_desc`,`service_param`,`service_ignore`,`service_status`,`service_changed`,`service_message`,`service_disabled`,`service_ds`,`service_template_id`,`service_name` FROM `services` WHERE';
|
||||
$sql_param = [];
|
||||
$add = 0;
|
||||
|
||||
|
@ -108,7 +108,7 @@ function delete_service($service = null)
|
|||
function discover_service($device, $service)
|
||||
{
|
||||
if (! dbFetchCell('SELECT COUNT(service_id) FROM `services` WHERE `service_type`= ? AND `device_id` = ?', [$service, $device['device_id']])) {
|
||||
add_service($device, $service, "(Auto discovered) $service");
|
||||
add_service($device, $service, "$service Monitoring (Auto Discovered)", null, null, 0, 0, 0, "AUTO: $service");
|
||||
log_event('Autodiscovered service: type ' . mres($service), $device, 'service', 2);
|
||||
echo '+';
|
||||
}
|
||||
|
@ -326,12 +326,5 @@ function check_service($command)
|
|||
*/
|
||||
function list_available_services()
|
||||
{
|
||||
$services = [];
|
||||
foreach (scandir(Config::get('nagios_plugins')) as $file) {
|
||||
if (substr($file, 0, 6) === 'check_') {
|
||||
$services[] = substr($file, 6);
|
||||
}
|
||||
}
|
||||
|
||||
return $services;
|
||||
return \LibreNMS\Services::list();
|
||||
}
|
||||
|
|
|
@ -947,6 +947,10 @@
|
|||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"discover_services_templates": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"discovery_by_ip": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
|
|
|
@ -1755,19 +1755,60 @@ services:
|
|||
Columns:
|
||||
- { Field: service_id, Type: 'int unsigned', 'Null': false, Extra: auto_increment }
|
||||
- { Field: device_id, Type: 'int unsigned', 'Null': false, Extra: '' }
|
||||
- { Field: service_ip, Type: text, 'Null': false, Extra: '' }
|
||||
- { Field: service_ip, Type: text, 'Null': true, Extra: '' }
|
||||
- { Field: service_type, Type: varchar(255), 'Null': false, Extra: '' }
|
||||
- { Field: service_desc, Type: text, 'Null': false, Extra: '' }
|
||||
- { Field: service_param, Type: text, 'Null': false, Extra: '' }
|
||||
- { Field: service_ignore, Type: tinyint, 'Null': false, Extra: '' }
|
||||
- { Field: service_desc, Type: text, 'Null': true, Extra: '' }
|
||||
- { Field: service_param, Type: text, 'Null': true, Extra: '' }
|
||||
- { Field: service_ignore, Type: tinyint, 'Null': false, Extra: '', Default: '0' }
|
||||
- { Field: service_status, Type: tinyint, 'Null': false, Extra: '', Default: '0' }
|
||||
- { Field: service_changed, Type: 'int unsigned', 'Null': false, Extra: '', Default: '0' }
|
||||
- { Field: service_message, Type: text, 'Null': false, Extra: '' }
|
||||
- { Field: service_message, Type: text, 'Null': true, Extra: '' }
|
||||
- { Field: service_disabled, Type: tinyint, 'Null': false, Extra: '', Default: '0' }
|
||||
- { Field: service_ds, Type: text, 'Null': false, Extra: '' }
|
||||
- { Field: service_ds, Type: text, 'Null': true, Extra: '' }
|
||||
- { Field: service_template_id, Type: 'int unsigned', 'Null': false, Extra: '', Default: '0' }
|
||||
- { Field: service_name, Type: varchar(255), 'Null': true, Extra: '' }
|
||||
Indexes:
|
||||
PRIMARY: { Name: PRIMARY, Columns: [service_id], Unique: true, Type: BTREE }
|
||||
services_device_id_index: { Name: services_device_id_index, Columns: [device_id], Unique: false, Type: BTREE }
|
||||
service_templates:
|
||||
Columns:
|
||||
- { Field: id, Type: 'int unsigned', 'Null': false, Extra: auto_increment }
|
||||
- { Field: ip, Type: text, 'Null': true, Extra: '' }
|
||||
- { Field: type, Type: varchar(255), 'Null': false, Extra: '' }
|
||||
- { Field: dtype, Type: varchar(16), 'Null': false, Extra: '', Default: static }
|
||||
- { Field: dgtype, Type: varchar(16), 'Null': false, Extra: '', Default: static }
|
||||
- { Field: drules, Type: text, 'Null': true, Extra: '' }
|
||||
- { Field: dgrules, Type: text, 'Null': true, Extra: '' }
|
||||
- { Field: desc, Type: text, 'Null': true, Extra: '' }
|
||||
- { Field: param, Type: text, 'Null': true, Extra: '' }
|
||||
- { Field: ignore, Type: tinyint, 'Null': false, Extra: '', Default: '0' }
|
||||
- { Field: changed, Type: 'timestamp', 'Null': false, , Extra: 'on update CURRENT_TIMESTAMP', Default: CURRENT_TIMESTAMP }
|
||||
- { Field: disabled, Type: tinyint, 'Null': false, Extra: '', Default: '0' }
|
||||
- { Field: name, Type: varchar(255), 'Null': false, Extra: '' }
|
||||
Indexes:
|
||||
PRIMARY: { Name: PRIMARY, Columns: [id], Unique: true, Type: BTREE }
|
||||
service_templates_device:
|
||||
Columns:
|
||||
- { Field: service_template_id, Type: 'int unsigned', 'Null': false, Extra: '' }
|
||||
- { Field: device_id, Type: 'int unsigned', 'Null': false, Extra: '' }
|
||||
Indexes:
|
||||
PRIMARY: { Name: PRIMARY, Columns: [service_template_id, device_id], Unique: true, Type: BTREE }
|
||||
service_templates_device_service_template_id_index: { Name: service_templates_device_service_template_id_index, Columns: [service_template_id], Unique: false, Type: BTREE }
|
||||
service_templates_device_device_id_index: { Name: service_templates_device_device_id_index, Columns: [device_id], Unique: false, Type: BTREE }
|
||||
Constraints:
|
||||
service_templates_device_service_template_id_foreign: { name: service_templates_device_service_template_id_foreign, foreign_key: service_template_id, table: service_templates, key: id, extra: 'ON DELETE CASCADE' }
|
||||
service_templates_device_device_id_foreign: { name: service_templates_device_device_id_foreign, foreign_key: device_id, table: devices, key: device_id, extra: 'ON DELETE CASCADE' }
|
||||
service_templates_device_group:
|
||||
Columns:
|
||||
- { Field: service_template_id, Type: 'int unsigned', 'Null': false, Extra: '' }
|
||||
- { Field: device_group_id, Type: 'int unsigned', 'Null': false, Extra: '' }
|
||||
Indexes:
|
||||
PRIMARY: { Name: PRIMARY, Columns: [service_template_id, device_group_id], Unique: true, Type: BTREE }
|
||||
service_templates_device_group_service_template_id_index: { Name: service_templates_device_group_service_template_id_index, Columns: [service_template_id], Unique: false, Type: BTREE }
|
||||
service_templates_device_group_device_group_id_index: { Name: service_templates_device_group_device_group_id_index, Columns: [device_group_id], Unique: false, Type: BTREE }
|
||||
Constraints:
|
||||
service_templates_device_group_service_template_id_foreign: { name: service_templates_device_group_service_template_id_foreign, foreign_key: service_template_id, table: service_templates, key: id, extra: 'ON DELETE CASCADE' }
|
||||
service_templates_device_group_device_group_id_foreign: { name: service_templates_device_group_device_group_id_foreign, foreign_key: device_group_id, table: device_groups, key: id, extra: 'ON DELETE CASCADE' }
|
||||
session:
|
||||
Columns:
|
||||
- { Field: session_id, Type: 'int unsigned', 'Null': false, Extra: auto_increment }
|
||||
|
|
|
@ -234,8 +234,12 @@
|
|||
aria-hidden="true"></i> <span
|
||||
class="hidden-sm">@lang('Services')</span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{ url('services') }}"><i class="fa fa-cogs fa-fw fa-lg"
|
||||
aria-hidden="true"></i> @lang('All Services')</a>
|
||||
<li><a href="{{ url('services') }}"><i class="fa fa-cogs fa-fw fa-lg" aria-hidden="true"></i> @lang('All Services')</a>
|
||||
</li>
|
||||
<li><a href="{{ route('services.templates.index') }}"><span class="fa-stack" aria-hidden="true" style="font-size: 12px">
|
||||
<i class="fa fa-square fa-stack-2x"></i>
|
||||
<i class="fa fa-cogs fa-stack-1x fa-inverse"></i>
|
||||
</span> @lang('Services Templates')</a>
|
||||
</li>
|
||||
@if($service_counts['warning'] || $service_counts['critical'])
|
||||
<li role="presentation" class="divider"></li>
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
@extends('layouts.librenmsv1')
|
||||
|
||||
@section('title', __('Create Service Template'))
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<form action="{{ route('services.templates.store') }}" method="POST" role="form"
|
||||
class="form-horizontal services-templates-form col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2 col-sm-12">
|
||||
<legend><h2>@lang('Create Service Template')</h2></legend>
|
||||
<div class='alert alert-info'>Service Template will created for the specified Device Group.</div>
|
||||
@csrf
|
||||
<div class='well well-lg'>
|
||||
@include('service-template.form')
|
||||
<div class="form-group">
|
||||
<hr>
|
||||
<center><button type="submit" class="btn btn-primary">@lang('Save')</button>
|
||||
<a type="button" class="btn btn-danger"
|
||||
href="{{ route('services.templates.index') }}">@lang('Cancel')</a>
|
||||
</center>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('javascript')
|
||||
<script src="{{ asset('js/sql-parser.min.js') }}"></script>
|
||||
<script src="{{ asset('js/query-builder.standalone.min.js') }}"></script>
|
||||
@endsection
|
|
@ -0,0 +1,32 @@
|
|||
@extends('layouts.librenmsv1')
|
||||
|
||||
@section('title', __('Edit Service Template'))
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<form action="{{ route('services.templates.update', $template->id) }}" method="POST" role="form"
|
||||
class="form-horizontal services-templates-form col-md-10 col-md-offset-1 col-sm-12">
|
||||
<legend><h2>@lang('Edit Service Template'): {{ $template->name }}</h2></legend>
|
||||
<div class='alert alert-info'>Service Template will edited for the specified Device Group.</div>
|
||||
{{ method_field('PUT') }}
|
||||
@csrf
|
||||
<div class='well well-lg'>
|
||||
@include('service-template.form')
|
||||
<div class="form-group">
|
||||
<center><div class="col-sm-9 col-sm-offset-3 col-md-10 col-sm-offset-2">
|
||||
<button type="submit" class="btn btn-primary">@lang('Save')</button>
|
||||
<a type="button" class="btn btn-danger"
|
||||
href="{{ route('services.templates.index') }}">@lang('Cancel')</a>
|
||||
</div></center>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('javascript')
|
||||
<script src="{{ asset('js/sql-parser.min.js') }}"></script>
|
||||
<script src="{{ asset('js/query-builder.standalone.min.js') }}"></script>
|
||||
@endsection
|
|
@ -0,0 +1,288 @@
|
|||
<div class="form-group @if($errors->has('name')) has-error @endif">
|
||||
<label for="name" class="control-label col-sm-3 col-md-2 text-nowrap">@lang('Name')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<input type="text" class="form-control" id="name" name="name" value="{{ old('name', $template->name) }}">
|
||||
<span class="help-block">{{ $errors->first('name') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group @if($errors->has('dtype')) has-error @endif">
|
||||
<label for="dtype" class="control-label col-sm-3 col-md-2">@lang('Device Type')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<select class="form-control" id="dtype" name="dtype" onchange="change_st_dtype(this)">
|
||||
<option value="static"
|
||||
@if(old('dtype', $template->dtype) == 'static') selected @endif>@lang('Static')</option>
|
||||
<option value="dynamic"
|
||||
@if(old('dtype', $template->dtype) == 'dynamic') selected @endif>@lang('Dynamic')</option>
|
||||
</select>
|
||||
<span class="help-block">{{ $errors->first('dtype') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="dynamic-st-d-form" class="form-group @if($errors->has('drules')) has-error @endif">
|
||||
<label for="drules" class="control-label col-sm-3 col-md-2 text-wrap">@lang('Define Device Rules')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<div id="builder"></div>
|
||||
<span class="help-block">{{ $errors->first('drules') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="static-st-d-form" class="form-group @if($errors->has('devices')) has-error @endif" style="display: none">
|
||||
<label for="devices" class="control-label col-sm-3 col-md-2 text-nowrap">@lang('Select Devices')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<select class="form-control" id="devices" name="devices[]" multiple>
|
||||
@foreach($template->devices as $device)
|
||||
<option value="{{ $device->device_id }}" selected>{{ $device->displayName() }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<span class="help-block">{{ $errors->first('devices') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group @if($errors->has('dgtype')) has-error @endif">
|
||||
<label for="dgtype" class="control-label col-sm-3 col-md-2">@lang('Device Group Type')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<select class="form-control" id="dgtype" name="dgtype" onchange="change_st_dgtype(this)">
|
||||
<option value="static"
|
||||
@if(old('dgtype', $template->dgtype) == 'static') selected @endif>@lang('Static')</option>
|
||||
<option value="dynamic"
|
||||
@if(old('dgtype', $template->dgtype) == 'dynamic') selected @endif>@lang('Dynamic')</option>
|
||||
</select>
|
||||
<span class="help-block">{{ $errors->first('dgtype') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="dynamic-st-dg-form" class="form-group @if($errors->has('dgrules')) has-error @endif">
|
||||
<label for="dgrules" class="control-label col-sm-3 col-md-2 text-wrap">@lang('Device Group Rules')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<div id="builder2"></div>
|
||||
<span class="help-block">{{ $errors->first('dgrules') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="static-st-dg-form" class="form-group @if($errors->has('groups')) has-error @endif" style="display: none">
|
||||
<label for="groups" class="control-label col-sm-3 col-md-2 text-wrap">@lang('Device Groups')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<select class="form-control" id="groups" name="groups[]" multiple>
|
||||
@foreach($template->groups as $group)
|
||||
<option value="{{ $group->id }}" selected>{{ $group->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<span class="help-block">{{ $errors->first('groups') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group @if($errors->has('type')) has-error @endif">
|
||||
<label for="type" class="control-label col-sm-3 col-md-2">@lang('Check Type')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<select class="form-control" id="type" name="type">
|
||||
@foreach($services as $current_service)
|
||||
<option value="{{ $current_service }}" @if($current_service == $template->type) selected @endif>{{ $current_service }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<span class="help-block">{{ $errors->first('type') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group @if($errors->has('desc')) has-error @endif">
|
||||
<label for="desc" class="control-label col-sm-3 col-md-2 text-nowrap">@lang('Description')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<input type="text" class="form-control" id="desc" name="desc" value="{{ old('desc', $template->desc) }}">
|
||||
<span class="help-block">{{ $errors->first('desc') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group @if($errors->has('ip')) has-error @endif">
|
||||
<label for="ip" class="control-label col-sm-3 col-md-2 text-nowrap">@lang('Remote Host')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<input type="text" class="form-control" id="ip" name="ip" value="{{ old('ip', $template->ip) }}">
|
||||
<span class="help-block">{{ $errors->first('ip') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group @if($errors->has('param')) has-error @endif">
|
||||
<label for="param" class="control-label col-sm-3 col-md-2 text-nowrap">@lang('Parameters')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<input type="text" class="form-control" id="param" name="param" value="{{ old('param', $template->param) }}">
|
||||
<span class="help-block">{{ $errors->first('param') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12 alert alert-info">
|
||||
<label class='control-label text-left input-sm'>Parameters may be required and will be different depending on the service check.</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group @if($errors->has('ignore')) has-error @endif">
|
||||
<label for="ignore" class="control-label col-sm-3 col-md-2 text-nowrap">@lang('Ignore alert tag')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<input type="hidden" value="0" name="ignore">
|
||||
<input type="checkbox" class="form-control" id="ignore" name="ignore" data-size="small" value="{{ old('ignore', $template->ignore) }}"@if(old('ignore', $template->ignore) == 1) checked @endif>
|
||||
<span class="help-block">{{ $errors->first('ignore') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group @if($errors->has('disabled')) has-error @endif">
|
||||
<label for="disabled" class="control-label col-sm-3 col-md-2 text-wrap">@lang('Disable polling and alerting')</label>
|
||||
<div class="col-sm-9 col-md-10">
|
||||
<input type="hidden" value="0" name="disabled">
|
||||
<input type="checkbox" class="form-control" id="disabled" name="disabled" data-size="small" value="{{ old('disabled', $template->disabled) }}"@if(old('disabled', $template->disabled) == 1) checked @endif>
|
||||
<span class="help-block">{{ $errors->first('disabled') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$("[type='checkbox']").bootstrapSwitch('offColor','danger');
|
||||
$("#ignore").on( 'switchChange.bootstrapSwitch', function (e, state) {
|
||||
var value = $(this).is(':checked') ? "1": "0";
|
||||
$('#ignore').val(value);
|
||||
});
|
||||
$("#disabled").on( 'switchChange.bootstrapSwitch', function (e, state) {
|
||||
var value = $(this).is(':checked') ? "1": "0";
|
||||
$('#disabled').val(value);
|
||||
});
|
||||
function change_st_dtype(select) {
|
||||
var dtype = select.options[select.selectedIndex].value;
|
||||
document.getElementById("dynamic-st-d-form").style.display = (dtype === 'dynamic' ? 'block' : 'none');
|
||||
document.getElementById("static-st-d-form").style.display = (dtype === 'dynamic' ? 'none' : 'block');
|
||||
}
|
||||
|
||||
change_st_dtype(document.getElementById('dtype'));
|
||||
|
||||
function change_st_dgtype(select) {
|
||||
var dgtype = select.options[select.selectedIndex].value;
|
||||
document.getElementById("dynamic-st-dg-form").style.display = (dgtype === 'dynamic' ? 'block' : 'none');
|
||||
document.getElementById("static-st-dg-form").style.display = (dgtype === 'dynamic' ? 'none' : 'block');
|
||||
}
|
||||
|
||||
change_st_dgtype(document.getElementById('dgtype'));
|
||||
|
||||
init_select2('#devices', 'device', {multiple: true});
|
||||
init_select2('#groups', 'device-group', {multiple: true});
|
||||
var builder = $('#builder').on('afterApplyRuleFlags.queryBuilder afterCreateRuleFilters.queryBuilder', function () {
|
||||
$("[name$='_filter']").each(function () {
|
||||
$(this).select2({
|
||||
dropdownAutoWidth: true,
|
||||
width: 'auto'
|
||||
});
|
||||
});
|
||||
}).on('ruleToSQL.queryBuilder.filter', function (e, rule) {
|
||||
if (rule.operator === 'regexp') {
|
||||
e.value += ' \'' + rule.value + '\'';
|
||||
}
|
||||
}).queryBuilder({
|
||||
plugins: [
|
||||
'bt-tooltip-errors'
|
||||
// 'not-group'
|
||||
],
|
||||
|
||||
filters: {!! $filters !!},
|
||||
operators: [
|
||||
'equal', 'not_equal', 'between', 'not_between', 'begins_with', 'not_begins_with', 'contains', 'not_contains', 'ends_with', 'not_ends_with', 'is_empty', 'is_not_empty', 'is_null', 'is_not_null', 'in', 'not_in',
|
||||
{type: 'less', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime']},
|
||||
{type: 'less_or_equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime']},
|
||||
{type: 'greater', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime']},
|
||||
{type: 'greater_or_equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime']},
|
||||
{type: 'regex', nb_inputs: 1, multiple: false, apply_to: ['string', 'number']},
|
||||
{type: 'not_regex', nb_inputs: 1, multiple: false, apply_to: ['string', 'number']}
|
||||
],
|
||||
lang: {
|
||||
operators: {
|
||||
regexp: 'regex',
|
||||
not_regex: 'not regex'
|
||||
}
|
||||
},
|
||||
sqlOperators: {
|
||||
regexp: {op: 'REGEXP'},
|
||||
not_regexp: {op: 'NOT REGEXP'}
|
||||
},
|
||||
sqlRuleOperator: {
|
||||
'REGEXP': function (v) {
|
||||
return {val: v, op: 'regexp'};
|
||||
},
|
||||
'NOT REGEXP': function (v) {
|
||||
return {val: v, op: 'not_regexp'};
|
||||
}
|
||||
}
|
||||
});
|
||||
var builder2 = $('#builder2').on('afterApplyRuleFlags.queryBuilder afterCreateRuleFilters.queryBuilder', function () {
|
||||
$("[name$='_filter']").each(function () {
|
||||
$(this).select2({
|
||||
dropdownAutoWidth: true,
|
||||
width: 'auto'
|
||||
});
|
||||
});
|
||||
}).on('ruleToSQL.queryBuilder.filter', function (e, rule) {
|
||||
if (rule.operator === 'regexp') {
|
||||
e.value += ' \'' + rule.value + '\'';
|
||||
}
|
||||
}).queryBuilder({
|
||||
plugins: [
|
||||
'bt-tooltip-errors'
|
||||
// 'not-group'
|
||||
],
|
||||
|
||||
filters: {!! $filters !!},
|
||||
operators: [
|
||||
'equal', 'not_equal', 'between', 'not_between', 'begins_with', 'not_begins_with', 'contains', 'not_contains', 'ends_with', 'not_ends_with', 'is_empty', 'is_not_empty', 'is_null', 'is_not_null', 'in', 'not_in',
|
||||
{type: 'less', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime']},
|
||||
{type: 'less_or_equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime']},
|
||||
{type: 'greater', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime']},
|
||||
{type: 'greater_or_equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime']},
|
||||
{type: 'regex', nb_inputs: 1, multiple: false, apply_to: ['string', 'number']},
|
||||
{type: 'not_regex', nb_inputs: 1, multiple: false, apply_to: ['string', 'number']}
|
||||
],
|
||||
lang: {
|
||||
operators: {
|
||||
regexp: 'regex',
|
||||
not_regex: 'not regex'
|
||||
}
|
||||
},
|
||||
sqlOperators: {
|
||||
regexp: {op: 'REGEXP'},
|
||||
not_regexp: {op: 'NOT REGEXP'}
|
||||
},
|
||||
sqlRuleOperator: {
|
||||
'REGEXP': function (v) {
|
||||
return {val: v, op: 'regexp'};
|
||||
},
|
||||
'NOT REGEXP': function (v) {
|
||||
return {val: v, op: 'not_regexp'};
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.service-template-form').submit(function (eventObj) {
|
||||
if ($('#dtype').val() === 'static') {
|
||||
return true;
|
||||
} else {
|
||||
$('<input type="hidden" name="drules" />')
|
||||
.attr('value', JSON.stringify(builder.queryBuilder('getRules')))
|
||||
.appendTo(this);
|
||||
if (!builder.queryBuilder('validate')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ($('#dgtype').val() === 'static') {
|
||||
return true;
|
||||
} else {
|
||||
$('<input type="hidden" name="dgrules" />')
|
||||
.attr('value', JSON.stringify(builder2.queryBuilder('getRules')))
|
||||
.appendTo(this);
|
||||
if (!builder2.queryBuilder('validate')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
var drules = {!! json_encode(old('drules') ? json_decode(old('drules')) : $template->drules) !!};
|
||||
if (drules) {
|
||||
builder.queryBuilder('setRules', drules);
|
||||
}
|
||||
var dgrules = {!! json_encode(old('dgrules') ? json_decode(old('dgrules')) : $template->dgrules) !!};
|
||||
if (dgrules) {
|
||||
builder2.queryBuilder('setRules', dgrules);
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,229 @@
|
|||
@extends('layouts.librenmsv1')
|
||||
|
||||
@section('title', __('Services Templates'))
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid">
|
||||
<x-panel id="manage-services-templates-panel">
|
||||
<x-slot name="title">
|
||||
<span class="fa-stack" aria-hidden="true">
|
||||
<i class="fa fa-square fa-stack-2x"></i>
|
||||
<i class="fa fa-cogs fa-stack-1x fa-inverse"></i>
|
||||
</span> @lang('Services Templates')
|
||||
</x-slot>
|
||||
<div class="row" style="padding-bottom: 16px;">
|
||||
<div class="col-md-12">
|
||||
<a type="button" class="btn btn-primary" href="{{ route('services.templates.create') }}">
|
||||
<i class="fa fa-plus"></i> @lang('New Service Template')
|
||||
</a>
|
||||
<button type="button" title="@lang('Apply Service Templates')" class="btn btn-success" aria-label="@lang('Apply Service Templates')"
|
||||
onclick="applyAll_st(this, '{{ route('services.templates.applyAll') }}')">
|
||||
<i
|
||||
class="fa fa-refresh" aria-hidden="true"></i> @lang('Apply Service Templates')</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table id="manage-services-templates-table" class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>@lang('Name')</th>
|
||||
<th>@lang('Description')</th>
|
||||
<th>@lang('Devices')</th>
|
||||
<th>@lang('Device Groups')</th>
|
||||
<th>@lang('Device Type')</th>
|
||||
<th>@lang('Device Group Type')</th>
|
||||
<th>@lang('Device Rules')</th>
|
||||
<th>@lang('Device Group Rules')</th>
|
||||
<th>@lang('Actions')</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($service_templates as $template)
|
||||
<tr id="row_{{ $template->id }}">
|
||||
<td>{{ $template->name }}</td>
|
||||
<td>{{ $template->desc }}</td>
|
||||
<td>
|
||||
<a href="{{ url("/devices/serviceTemplates=$template->id") }}">{{ $template->devices_count }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url("/device-groups/serviceTemplates=$template->id") }}">{{ $template->groups_count }}</a>
|
||||
</td>
|
||||
<td>{{ __(ucfirst($template->dtype)) }}</td>
|
||||
<td>{{ __(ucfirst($template->dgtype)) }}</td>
|
||||
<td>{{ $template->dtype == 'dynamic' ? $template->getDeviceParser()->toSql(false) : '' }}</td>
|
||||
<td>{{ $template->dgtype == 'dynamic' ? $template->getDeviceGroupParser()->toSql(false) : '' }}</td>
|
||||
<td>
|
||||
<button type="button" title="@lang('Apply Services for this Service Template')" class="btn btn-success btn-sm" aria-label="@lang('Apply')"
|
||||
onclick="apply_st(this, '{{ $template->name }}', '{{ $template->id }}', '{{ route('services.templates.apply', $template->id) }}')">
|
||||
<i class="fa fa-refresh" aria-hidden="true"></i></button>
|
||||
<button type="button" title="@lang('Remove Services for this Service Template')" class="btn btn-warning btn-sm" aria-label="@lang('Remove')"
|
||||
onclick="remove_st(this, '{{ $template->name }}', '{{ $template->id }}', '{{ route('services.templates.remove', $template->id) }}')">
|
||||
<i class="fa fa-ban" aria-hidden="true"></i></button>
|
||||
<a type="button" title="@lang('Edit Service Template')" class="btn btn-primary btn-sm" aria-label="@lang('Edit')"
|
||||
href="{{ route('services.templates.edit', $template->id) }}">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i></a>
|
||||
<button type="button" class="btn btn-danger btn-sm" title="@lang('Delete Service Template')" aria-label="@lang('Delete')"
|
||||
onclick="delete_st(this, '{{ $template->name }}', '{{ $template->id }}', '{{ route('services.templates.destroy', $template->id) }}')">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@foreach($groups as $group)
|
||||
<x-panel id="manage-services-templates-panel-dg">
|
||||
<x-slot name="title">
|
||||
<i class="fa fa-th fa-fw fa-lg" aria-hidden="true"></i> @lang($group->name)
|
||||
</x-slot>
|
||||
<div class="table-responsive">
|
||||
<table id="manage-services-templates-table-dg-{{ $group->id }}" class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>@lang('Name')</th>
|
||||
<th>@lang('Check Type')</th>
|
||||
<th>@lang('Parameters')</th>
|
||||
<th>@lang('Remote Host')</th>
|
||||
<th>@lang('Description')</th>
|
||||
<th>@lang('Modified')</th>
|
||||
<th>@lang('Ignored')</th>
|
||||
<th>@lang('Disabled')</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($group->serviceTemplates as $template)
|
||||
<tr id="row_{{ $template->id }}">
|
||||
<td>{{ $template->name }}</td>
|
||||
<td>{{ $template->type }}</td>
|
||||
<td>{{ $template->param }}</td>
|
||||
<td>{{ $template->ip }}</td>
|
||||
<td>{{ $template->desc }}</td>
|
||||
<td>{{ $template->changed }}</td>
|
||||
<td>{{ $template->ignore }}</td>
|
||||
<td>{{ $template->disabled }}</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</x-panel>
|
||||
@endforeach
|
||||
@foreach($devices as $device)
|
||||
<x-panel id="manage-services-templates-panel-d">
|
||||
<x-slot name="title">
|
||||
<i class="fa fa-server fa-fw fa-lg" aria-hidden="true"></i> @lang($device->hostname)
|
||||
</x-slot>
|
||||
<div class="table-responsive">
|
||||
<table id="manage-services-templates-table-d-{{ $device->id }}" class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>@lang('Name')</th>
|
||||
<th>@lang('Check Type')</th>
|
||||
<th>@lang('Parameters')</th>
|
||||
<th>@lang('Remote Host')</th>
|
||||
<th>@lang('Description')</th>
|
||||
<th>@lang('Modified')</th>
|
||||
<th>@lang('Ignored')</th>
|
||||
<th>@lang('Disabled')</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($device->serviceTemplates as $template)
|
||||
<tr id="row_{{ $template->id }}">
|
||||
<td>{{ $template->name }}</td>
|
||||
<td>{{ $template->type }}</td>
|
||||
<td>{{ $template->param }}</td>
|
||||
<td>{{ $template->ip }}</td>
|
||||
<td>{{ $template->desc }}</td>
|
||||
<td>{{ $template->changed }}</td>
|
||||
<td>{{ $template->ignore }}</td>
|
||||
<td>{{ $template->disabled }}</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</x-panel>
|
||||
@endforeach
|
||||
</x-panel>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
<script>
|
||||
function apply_st(button, name, id, url) {
|
||||
if (confirm('@lang('Are you sure you want to create Services for ')' + name + '?')) {
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
success: function (msg) {
|
||||
toastr.success(msg);
|
||||
},
|
||||
error:function(){
|
||||
toastr.error('No Services were updated when Applying this Service Template');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
function applyAll_st(button, url) {
|
||||
if (confirm('@lang('Are you sure you want to Apply All Service Templates?')')) {
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
success: function (msg) {
|
||||
toastr.success(msg);
|
||||
},
|
||||
error:function(){
|
||||
toastr.error('No Services were updated');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
function remove_st(button, name, id, url) {
|
||||
if (confirm('@lang('Are you sure you want to remove all Services created by ')' + name + '?')) {
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
success: function (msg) {
|
||||
toastr.success(msg);
|
||||
},
|
||||
error: function () {
|
||||
toastr.error('@lang('No Services for this Service Template were removed')');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
function delete_st(button, name, id, url) {
|
||||
var index = button.parentNode.parentNode.rowIndex;
|
||||
if (confirm('@lang('Are you sure you want to delete AND remove all Services created by ')' + name + '?')) {
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'DELETE',
|
||||
success: function (msg) {
|
||||
document.getElementById("manage-services-templates-table").deleteRow(index);
|
||||
toastr.success(msg);
|
||||
},
|
||||
error: function () {
|
||||
toastr.error('@lang('The Service Template could not be deleted')');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
@endsection
|
||||
|
||||
@section('css')
|
||||
<style>
|
||||
.table-responsive {
|
||||
padding-top: 16px
|
||||
}
|
||||
</style>
|
||||
@endsection
|
|
@ -27,6 +27,12 @@ Route::group(['middleware' => ['auth'], 'guard' => 'auth'], function () {
|
|||
Route::get('performance', 'PollerController@performanceTab')->name('poller.performance');
|
||||
Route::resource('{id}/settings', 'PollerSettingsController', ['as' => 'poller'])->only(['update', 'destroy']);
|
||||
});
|
||||
Route::prefix('services')->name('services.')->group(function () {
|
||||
Route::resource('templates', 'ServiceTemplateController');
|
||||
Route::post('templates/applyAll', 'ServiceTemplateController@applyAll')->name('templates.applyAll');
|
||||
Route::post('templates/apply/{template}', 'ServiceTemplateController@apply')->name('templates.apply');
|
||||
Route::post('templates/remove/{template}', 'ServiceTemplateController@remove')->name('templates.remove');
|
||||
});
|
||||
Route::get('locations', 'LocationController@index');
|
||||
Route::resource('preferences', 'UserPreferencesController', ['only' => ['index', 'store']]);
|
||||
Route::resource('users', 'UserController');
|
||||
|
@ -109,6 +115,7 @@ Route::group(['middleware' => ['auth'], 'guard' => 'auth'], function () {
|
|||
Route::get('location', 'LocationController');
|
||||
Route::get('munin', 'MuninPluginController');
|
||||
Route::get('service', 'ServiceController');
|
||||
Route::get('template', 'ServiceTemplateController');
|
||||
Route::get('port', 'PortController');
|
||||
Route::get('port-field', 'PortFieldController');
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue