From d248e6561fcd8965839c5834d7f440ed0cb2a54b Mon Sep 17 00:00:00 2001 From: rhinoau <78184917+rhinoau@users.noreply.github.com> Date: Fri, 29 Jul 2022 00:38:46 +0800 Subject: [PATCH] Standardize device and device group maintenance API (#14153) * Standardise device and devicegroup maintenance API * styleci fixes --- doc/API/DeviceGroups.md | 51 +++++++++++++++++++++++++---- doc/API/Devices.md | 48 ++++++++++++++++++++++++--- includes/html/api_functions.inc.php | 39 ++++++++++++++++------ 3 files changed, 116 insertions(+), 22 deletions(-) diff --git a/doc/API/DeviceGroups.md b/doc/API/DeviceGroups.md index 5459504575..95a6593784 100644 --- a/doc/API/DeviceGroups.md +++ b/doc/API/DeviceGroups.md @@ -150,15 +150,28 @@ 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 +- `title`: *optional* - Some title for the Maintenance + Will be replaced with device group name if omitted +- `notes`: *optional* - Some description for the Maintenance +- `start`: *optional* - start time of Maintenance in full format `Y-m-d H:i:00` + eg: 2022-08-01 22:45:00 + Current system time `now()` will be used if omitted +- `duration`: *required* - Duration of Maintenance in format `H:i` / `Hrs:Mins` + eg: 02:00 -Example: +Example with start time: ```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 +curl -H 'X-Auth-Token: YOURAPITOKENHERE' \ + -X POST https://librenms.org/api/v0/devicegroups/Cisco%20switches/maintenance/ \ + --data-raw ' +{ + "title":"Device group Maintenance", + "notes":"A 2 hour Maintenance triggered via API with start time", + "start":"2022-08-01 08:00:00", + "duration":"2:00" +} +' ``` Output: @@ -166,6 +179,30 @@ Output: ```json { "status": "ok", - "message": "Device group Cisco switches (2) will begin maintenance mode at 5:00 for 2:00 h" + "message": "Device group Cisco switches (2) will begin maintenance mode at 2022-08-01 22:45:00 for 2:00h" } ``` + +Example with no start time: + +```curl +curl -H 'X-Auth-Token: YOURAPITOKENHERE' \ + -X POST https://librenms.org/api/v0/devicegroups/Cisco%20switches/maintenance/ \ + --data-raw ' +{ + "title":"Device group Maintenance", + "notes":"A 2 hour Maintenance triggered via API with no start time", + "duration":"2:00" +} +' +``` + +Output: + +```json +{ + "status": "ok", + "message": "Device group Cisco switches (2) moved into maintenance mode for 2:00h" +} +``` + diff --git a/doc/API/Devices.md b/doc/API/Devices.md index e8cb2cab5d..ead46d37f4 100644 --- a/doc/API/Devices.md +++ b/doc/API/Devices.md @@ -1109,13 +1109,28 @@ Route: `/api/v0/devices/:hostname/maintenance` Input (JSON): -- notes: Some description for the Maintenance -- duration: Duration of Maintenance in format H:m +- `title`: *optional* - Some title for the Maintenance + Will be replaced with hostname if omitted +- `notes`: *optional* - Some description for the Maintenance + Will also be added to device notes if user prefs "Add schedule notes to devices notes" is set +- `start`: *optional* - start time of Maintenance in full format `Y-m-d H:i:00` + eg: 2022-08-01 22:45:00 + Current system time `now()` will be used if omitted +- `duration`: *required* - Duration of Maintenance in format `H:i` / `Hrs:Mins` + eg: 02:00 -Example: +Example with start time: ```curl -curl -X POST -d '{"notes":"A 2 hour Maintenance triggered via API","duration":"2:00"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/localhost/maintenance +curl -H 'X-Auth-Token: YOURAPITOKENHERE' \ + -X POST https://librenms.org/api/v0/devices/localhost/maintenance/ \ + --data-raw ' + "title":"Device Maintenance", + "notes":"A 2 hour Maintenance triggered via API with start time", + "start":"2022-08-01 08:00:00", + "duration":"2:00" +} +' ``` Output: @@ -1123,10 +1138,33 @@ Output: ```json { "status": "ok", - "message": "Device localhost.localdomain (57) moved into maintenance mode for 2:00 h" + "message": "Device localhost (1) will begin maintenance mode at 2022-08-01 22:45:00 for 2:00h" } ``` +Example with no start time: + +```curl +curl -H 'X-Auth-Token: YOURAPITOKENHERE' \ + -X POST https://librenms.org/api/v0/devices/localhost/maintenance/ \ + --data-raw ' + "title":"Device Maintenance", + "notes":"A 2 hour Maintenance triggered via API with no start time", + "duration":"2:00" +} +' +``` + +Output: + +```json +{ + "status": "ok", + "message": "Device localhost (1) moved into maintenance mode for 2:00h" +} +``` + + ### `add_device` Add a new device. Most fields are optional. You may omit snmp diff --git a/includes/html/api_functions.inc.php b/includes/html/api_functions.inc.php index 7029943704..2e6e78265e 100644 --- a/includes/html/api_functions.inc.php +++ b/includes/html/api_functions.inc.php @@ -457,28 +457,35 @@ function maintenance_device(Illuminate\Http\Request $request) return api_error(400, 'No information has been provided to set this device into maintenance'); } - // This will add a device using the data passed encoded with json $hostname = $request->route('hostname'); // use hostname as device_id if it's all digits - $device = ctype_digit($hostname) ? DeviceCache::get($hostname) : DeviceCache::getByHostname($hostname); + $device = ctype_digit($hostname) ? Device::find($hostname) : Device::findByHostname($hostname); - if (! $device) { - return api_error(404, "Device $hostname does not exist"); + if (is_null($device)) { + return api_error(404, "Device $hostname not found"); + } + + if (! $request->json('duration')) { + return api_error(400, 'Duration not provided'); } $notes = $request->json('notes'); + $title = $request->json('title') ?? $device->displayName(); $alert_schedule = new \App\Models\AlertSchedule([ - 'title' => $device->displayName(), + 'title' => $title, 'notes' => $notes, 'recurring' => 0, - 'start' => date('Y-m-d H:i:s'), ]); + $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::now() + $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'); } @@ -491,7 +498,11 @@ function maintenance_device(Illuminate\Http\Request $request) $device->save(); } - return api_success_noresult(201, "Device {$device->hostname} ({$device->device_id}) moved into maintenance mode" . ($duration ? " for {$duration}h" : '')); + if ($request->json('start')) { + return api_success_noresult(201, "Device {$device->hostname} ({$device->device_id}) will begin maintenance mode at $start" . ($duration ? " for {$duration}h" : '')); + } else { + return api_success_noresult(201, "Device {$device->hostname} ({$device->device_id}) moved into maintenance mode" . ($duration ? " for {$duration}h" : '')); + } } function device_availability(Illuminate\Http\Request $request) @@ -2143,7 +2154,11 @@ function maintenance_devicegroup(Illuminate\Http\Request $request) $device_group = ctype_digit($name) ? DeviceGroup::find($name) : DeviceGroup::where('name', $name)->first(); if (! $device_group) { - return api_error(404, 'Device group not found'); + return api_error(404, "Device group $name not found"); + } + + if (! $request->json('duration')) { + return api_error(400, 'Duration not provided'); } $notes = $request->json('notes'); @@ -2170,7 +2185,11 @@ function maintenance_devicegroup(Illuminate\Http\Request $request) $alert_schedule->save(); $alert_schedule->deviceGroups()->attach($device_group); - return api_success_noresult(201, "Device group {$device_group->name} ({$device_group->id}) will begin maintenance mode at $start" . ($duration ? " for {$duration}h" : '')); + if ($request->json('start')) { + return api_success_noresult(201, "Device group {$device_group->name} ({$device_group->id}) will begin maintenance mode at $start" . ($duration ? " for {$duration}h" : '')); + } else { + return api_success_noresult(201, "Device group {$device_group->name} ({$device_group->id}) moved into maintenance mode" . ($duration ? " for {$duration}h" : '')); + } } function get_devices_by_group(Illuminate\Http\Request $request)