From 5a085f79e507f27411041c7767446e7766ad0eab Mon Sep 17 00:00:00 2001 From: "Chris A. Evans" Date: Fri, 27 May 2022 10:38:47 -0500 Subject: [PATCH] Feature: Add support to REST API for creating Maintenance Schedules for Device Groups (#13985) * Add support to REST API for creating Maintenance Schedules for Device Groups * Update documentation to include the maintenance_devicegroup API endpoint * Fix quotes * Fix whitespace Co-authored-by: Tony Murray --- app/Models/DeviceGroup.php | 6 ++++ doc/API/DeviceGroups.md | 28 +++++++++++++++++++ includes/html/api_functions.inc.php | 43 +++++++++++++++++++++++++++++ routes/api.php | 4 +++ 4 files changed, 81 insertions(+) diff --git a/app/Models/DeviceGroup.php b/app/Models/DeviceGroup.php index 8a8b65bc70..e932dffb51 100644 --- a/app/Models/DeviceGroup.php +++ b/app/Models/DeviceGroup.php @@ -26,6 +26,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Relations\BelongsToMany; +use Illuminate\Database\Eloquent\Relations\MorphToMany; use LibreNMS\Alerting\QueryBuilderFluentParser; use Permissions; @@ -116,6 +117,11 @@ class DeviceGroup extends BaseModel // ---- Define Relationships ---- + public function alertSchedules(): MorphToMany + { + return $this->morphToMany(\App\Models\AlertSchedule::class, 'alert_schedulable', 'alert_schedulables', 'schedule_id', 'schedule_id'); + } + public function devices(): BelongsToMany { return $this->belongsToMany(\App\Models\Device::class, 'device_group_device', 'device_group_id', 'device_id'); diff --git a/doc/API/DeviceGroups.md b/doc/API/DeviceGroups.md index 41b8616ac1..45253939b6 100644 --- a/doc/API/DeviceGroups.md +++ b/doc/API/DeviceGroups.md @@ -138,3 +138,31 @@ Output: } ] ``` + +### `maintenance_devicegroup` + +Set a device group into maintenance mode. + +Route: `/api/v0/devicesgroups/:name/maintenance` + +Input (JSON): + +- title: Some title for the Maintenance +- notes: Some description for the Maintenance +- start: Start time of Maintenance in format H:m +- duration: Duration of Maintenance in format H:m + +Example: + +```curl +curl -X POST -d '{"title":"Device group Maintenance","notes":"A 2 hour Maintenance triggered via API","start":"04:30","duration":"2:00"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/localhost/maintenance +``` + +Output: + +```json +{ + "status": "ok", + "message": "Device group Cisco switches (2) will begin maintenance mode at 5:00 for 2:00 h" +} +``` diff --git a/includes/html/api_functions.inc.php b/includes/html/api_functions.inc.php index 0216cd0bed..6006599ac4 100644 --- a/includes/html/api_functions.inc.php +++ b/includes/html/api_functions.inc.php @@ -2128,6 +2128,49 @@ function get_device_groups(Illuminate\Http\Request $request) return api_success($groups->makeHidden('pivot')->toArray(), 'groups', 'Found ' . $groups->count() . ' device groups'); } +function maintenance_devicegroup(Illuminate\Http\Request $request) +{ + if (empty($request->json())) { + return api_error(400, 'No information has been provided to set this device into maintenance'); + } + + $name = $request->route('name'); + if (! $name) { + return api_error(400, 'No device group name provided'); + } + + $device_group = ctype_digit($name) ? DeviceGroup::find($name) : DeviceGroup::where('name', $name)->first(); + + if (! $device_group) { + return api_error(404, 'Device group not found'); + } + + $notes = $request->json('notes'); + $title = $request->json('title') ?? $device_group->name; + + $alert_schedule = new \App\Models\AlertSchedule([ + 'title' => $title, + 'notes' => $notes, + 'recurring' => 0, + ]); + + $start = $request->json('start') ?? \Carbon\Carbon::now()->format('Y-m-d H:i:00'); + $alert_schedule->start = $start; + + $duration = $request->json('duration'); + + if (Str::contains($duration, ':')) { + [$duration_hour, $duration_min] = explode(':', $duration); + $alert_schedule->end = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $start) + ->addHours($duration_hour)->addMinutes($duration_min) + ->format('Y-m-d H:i:00'); + } + + $device_group->alertSchedules()->save($alert_schedule); + + return api_success_noresult(201, "Device group {$device_group->name} ({$device_group->id}) will begin maintenance mode at $start" . ($duration ? " for {$duration}h" : '')); +} + function get_devices_by_group(Illuminate\Http\Request $request) { $name = $request->route('name'); diff --git a/routes/api.php b/routes/api.php index 3b5e3e219d..0ed692e680 100644 --- a/routes/api.php +++ b/routes/api.php @@ -67,6 +67,10 @@ Route::group(['prefix' => 'v0', 'namespace' => '\App\Api\Controllers'], function Route::post('{hostname}/maintenance', 'LegacyApiController@maintenance_device')->name('maintenance_device'); }); + Route::group(['prefix' => 'devicegroups'], function () { + Route::post('{name}/maintenance', 'LegacyApiController@maintenance_devicegroup')->name('maintenance_devicegroup'); + }); + Route::post('bills', 'LegacyApiController@create_edit_bill')->name('create_bill'); Route::delete('bills/{bill_id}', 'LegacyApiController@delete_bill')->name('delete_bill'); Route::put('alerts/{id}', 'LegacyApiController@ack_alert')->name('ack_alert');