Update a Device
Last updated on 29 June, 2022You can use LogicMonitor’s REST API to update the devices in your account.
As with all of our API calls, authentication is required.
There are two ways to update a device:
- PUT: A PUT request enables you to replace an entire device definition (and update fields in the process). You should use PUT to update a device if you want to provide an updated JSON definition for the device. Note that consistent with REST standards, any properties not specified in a PUT request will revert back to their default values.
- PATCH: A PATCH request enables you to replace only certain fields for a device. You should use PATCH if you don’t have the JSON definition for the device and you only want to update a few fields.
PUT
Note that consistent with REST standards, any properties not specified in a PUT request will revert back to their default values. As such, you’ll want to be sure to include any custom device configuration and/or properties in the request. One easy way to accomplish this is to first make a GET request for the desired device, manipulate the device’s JSON definition, and then use that JSON in a PUT request to update the device (see Example 2 for an example). Passing an obfuscated property value as eight stars will preserve it’s value in LogicMonitor. Note that we do plan to publish a PATCH method to make this process easier (as HTTP PATCH does not require that you include every parameter in the request).
HTTP Method: PUT
URI: /device/devices/{id}
Request Parameters:
Property |
Description |
Required? |
Type |
Example |
name | The host name or IP address of the device | Yes | String | “name”:”10.36.11.240″ |
displayName | The display name of the device | Yes | String | “displayName”:”ProdServer24″ |
preferredCollectorId | The Id of the preferred collector assigned to monitor the device | Yes | Integer | “preferredCollectorId”:85 |
hostGroupIds | The Id(s) of the groups the device is in, where multiple group ids should be comma separated | No. Defaults to “1” (root group). | String | “hostGroupIds”:”2,34″ |
description | The device description | No | String | “description”:”A server in the LA Datacenter” |
disableAlerting | Indicates whether alerting is disabled (true) or enabled (false) for this device | No. Defaults to false. | Boolean | “disableAlerting”:false |
link | The URL link associated with the device | No | String | “link”:”https://status.aws.amazon.com” |
enableNetflow | Indicates whether Netflow is enabled (true) or disabled (false) for the device | No. Defaults to false. | Boolean | “enableNetflow”:false |
netflowCollectorId | The Id of the netflow collector associated with the device | If enableNetflow=true | Integer | “netflowCollectorId”:125 |
customProperties | Define custom properties for this device. Each property needs to have a name and a value. | No | JSON object | “customProperties”:[{“name”:”snmp.version”,”value”:”v3″},{“name”:”location”,”value”:”Santa Barbara, CA”}] |
Example 1: Python PUT
The following Python script updates the device with id 253.
#!/bin/env python
import requests
import json
import hashlib
import base64
import time
import hmac
#Account Info
AccessId ='48v2wRzfK94y53sq5EuF'
AccessKey ='H_D9i(f5~B^U36^K6i42=^nS~e75gy382Bf6{)P+'
Company = 'api'
#Request Info
httpVerb ='PUT'
resourcePath = '/device/devices/253'
data = '{"name":"10.36.11.240","displayName":"ProdServer24","preferredCollectorId":90,"hostGroupIds":"2","description":"a server in the LA datacenter"}'
#Construct URL
url = 'https://'+ Company +'.logicmonitor.com/santaba/rest' + resourcePath
#Get current time in milliseconds
epoch = str(int(time.time() * 1000))
#Concatenate Request details
requestVars = httpVerb + epoch + data + resourcePath
#Construct signature
hmac1 = hmac.new(AccessKey.encode(),msg=requestVars.encode(),digestmod=hashlib.sha256).hexdigest()
signature = base64.b64encode(hmac1.encode())
#Construct headers
auth = 'LMv1 ' + AccessId + ':' + signature.decode() + ':' + epoch
headers = {'Content-Type':'application/json','Authorization':auth}
#Make request
response = requests.put(url, data=data, headers=headers)
#Print status and body of response
print('Response Status:',response.status_code)
print('Response Body:',response.content)
The following is an example response for the request above:
Response Status: 200
Response Body: {
"status" : 200,
"errmsg" : "OK",
"data" : {
"id" : 253,
"name" : "10.36.11.240",
"displayName" : "ProdServer24",
"deviceType" : 0,
"relatedDeviceId" : -1,
"currentCollectorId" : 90,
"preferredCollectorId" : 90,
"preferredCollectorGroupId" : 1,
"preferredCollectorGroupName" : "@default",
"description" : "a server in the LA datacenter",
"createdOn" : 1458754984,
"updatedOn" : 1470715583,
"disableAlerting" : false,
"autoPropsAssignedOn" : 0,
"autoPropsUpdatedOn" : 0,
"scanConfigId" : 0,
"link" : "",
"enableNetflow" : false,
"netflowCollectorId" : 0,
"netflowCollectorGroupId" : 0,
"netflowCollectorGroupName" : null,
"lastDataTime" : 0,
"lastRawdataTime" : 0,
"hostGroupIds" : "2",
"sdtStatus" : "none-none-none",
"userPermission" : "write",
"hostStatus" : "normal",
"alertStatus" : "confirmed-warn-none",
"alertStatusPriority" : 1100,
"awsState" : 1,
"alertDisableStatus" : "none-none-none",
"alertingDisabledOn" : null,
"collectorDescription" : "ip-374-32-37-182.us-west-1.compute.internal",
"netflowCollectorDescription" : null,
"customProperties" : [ {
"name" : "system.categories",
"value" : ""
} ],
"upTimeInSeconds" : 0,
"deletedTimeInMs" : 0,
"toDeleteTimeInMs" : 0,
"hasDisabledSubResource" : false,
"manualDiscoveryFlags" : {
"winprocess" : false,
"linuxprocess" : false,
"winservice" : false
}
}
}
Example 2: Groovy PUT
The following Groovy script first makes a GET request to get the JSON definition for device 257, changes the device’s preferredCollectorId, and then makes a PUT request with the updated JSON:
import org.apache.http.HttpEntity
import org.apache.http.client.methods.CloseableHttpResponse
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.methods.HttpPut
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients
import org.apache.http.util.EntityUtils
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
import groovy.json.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
//define credentials and url
def accessId = 'YQQ75w6Mxx9zWIeAMq5H';
def accessKey = 'f)!Z}%spR=6en+4^s2$t32r-3=NpdQ]2T{-deI)8';
def account = 'apiAccount';
def resourcePath = "/device/devices/257"
def url = "https://" + account + ".logicmonitor.com" + "/santaba/rest" + resourcePath;
//get current time
epoch = System.currentTimeMillis();
//calculate signature
requestVars = "GET" + epoch + resourcePath;
hmac = Mac.getInstance("HmacSHA256");
secret = new SecretKeySpec(accessKey.getBytes(), "HmacSHA256");
hmac.init(secret);
hmac_signed = Hex.encodeHexString(hmac.doFinal(requestVars.getBytes()));
signature = hmac_signed.bytes.encodeBase64();
// HTTP GET
CloseableHttpClient httpclient = HttpClients.createDefault();
httpGet = new HttpGet(url);
httpGet.addHeader("Authorization" , "LMv1 " + accessId + ":" + signature + ":" + epoch);
response = httpclient.execute(httpGet);
responseBody = EntityUtils.toString(response.getEntity());
code = response.getStatusLine().getStatusCode();
response = new JsonSlurper().parseText(responseBody.toString());
device = response.data;
device.preferredCollectorId = 90;
device = JsonOutput.toJson(device)
StringEntity params = new StringEntity(device,ContentType.APPLICATION_JSON);
epoch = System.currentTimeMillis(); //get current time
requestVars = "PUT" + epoch + device + resourcePath;
// construct signature
hmac = Mac.getInstance("HmacSHA256");
secret = new SecretKeySpec(accessKey.getBytes(), "HmacSHA256");
hmac.init(secret);
hmac_signed = Hex.encodeHexString(hmac.doFinal(requestVars.getBytes()));
signature = hmac_signed.bytes.encodeBase64();
// HTTP PUT
httpPut = new HttpPut(url);
httpPut.addHeader("Authorization" , "LMv1 " + accessId + ":" + signature + ":" + epoch);
httpPut.setHeader("Accept", "application/json");
httpPut.setHeader("Content-type", "application/json");
httpPut.setEntity(params);
responsePut = httpclient.execute(httpPut);
responseBodyPut = EntityUtils.toString(responsePut.getEntity());
codePut = responsePut.getStatusLine().getStatusCode();
// Print Response
println "Status:" + codePut;
println "Response body:" + responseBodyPut;
httpclient.close();
PATCH
HTTP Method: PATCH
URI: /device/devices/{id}
Request Parameters:
With every PATCH request you must include a query parameter patchFields that indicates which fields should be updated, where multiple fields should be comma separated. If a field is identified in the patchFields parameter and included in the payload of the request, its value will be updated. All other field values will remain the same. E.g. to update a device’s name, the URI + query parameter would be /santaba/rest/device/devices/{id}?patchFields=Name. The name field would also need to be included in the request payload. The following fields can be updated via PATCH:
Property |
Description |
Type |
Example |
name | The host name or IP address of the device | String | “name”:”10.36.11.240″ |
displayName | The display name of the device | String | “displayName”:”ProdServer24″ |
preferredCollectorId | The Id of the preferred collector assigned to monitor the device | Integer | “preferredCollectorId”:85 |
hostGroupIds | The Id(s) of the groups the device is in, where multiple group ids should be comma separated | String | “hostGroupIds”:”2,34″ |
description | The device description | String | “description”:”A server in the LA Datacenter” |
disableAlerting | Indicates whether alerting is disabled (true) or enabled (false) for this device | Boolean | “disableAlerting”:false |
link | The URL link associated with the device | String | “link”:”https://status.aws.amazon.com” |
enableNetflow | Indicates whether Netflow is enabled (true) or disabled (false) for the device | Boolean | “enableNetflow”:false |
netflowCollectorId | The Id of the netflow collector associated with the device | Integer | “netflowCollectorId”:125 |
customProperties | Define custom properties for this device. Each property needs to have a name and a value. To add or update just one or a few device properties in the customProperties object, but not all of them, you’ll need to additionally use the opType query parameter. The opType query parameter can be set to add, refresh or replace. opType=add indicates that the properties included in the payload will be added, but all existing properties will remain the same. opType=replace indicates that the properties included in the request payload will be added if they don’t already exist, or updated if they do already exist, but all other existing properties will remain the same. opType=refresh indicates that the properties will be replaced with those included in the request payload. | JSON object | “customProperties”:[{“name”:”snmp.version”,”value”:”v3″},{“name”:”location”,”value”:”Santa Barbara, CA”}] |
Example 1: Python PATCH
The following python script enables Netflow and sets a Netflow Collector for device 435, but leaves all other device fields as is:
import requests
import json
import hashlib
import base64
import time
import hmac
#Account Info
AccessId ='48v2wRzfK94y53sq5EuF'
AccessKey ='H_D9i(f5~B^U36^K6i42=^nS~e75gy382Bf6{)P+'
Company = 'api'
#Request Info
httpVerb ='PATCH'
resourcePath = '/device/devices/435'
queryParams = '?patchFields=enableNetflow,netflowCollectorId'
data = '{"enableNetflow":true,"netflowCollectorId":85}'
#Construct URL
url = 'https://'+ Company +'.logicmonitor.com/santaba/rest' + resourcePath +queryParams
#Get current time in milliseconds
epoch = str(int(time.time() * 1000))
#Concatenate Request details
requestVars = httpVerb + epoch + data + resourcePath
#Construct signature
hmac1 = hmac.new(AccessKey.encode(),msg=requestVars.encode(),digestmod=hashlib.sha256).hexdigest()
signature = base64.b64encode(hmac1.encode())
#Construct headers
auth = 'LMv1 ' + AccessId + ':' + signature.decode() + ':' + epoch
headers = {'Content-Type':'application/json','Authorization':auth}
#Make request
response = requests.patch(url, data=data, headers=headers)
#Print status and body of response
print('Response Status:',response.status_code)
print('Response Body:',response.content)
Example 2: Python PATCH
The following python script enables adds a property for device 435, but leaves all other device fields as is:
import requests
import json
import hashlib
import base64
import time
import hmac
#Account Info
AccessId ='48v2wRzfK94y53sq5EuF'
AccessKey ='H_D9i(f5~B^U36^K6i42=^nS~e75gy382Bf6{)P+'
Company = 'api'
#Request Info
httpVerb ='PATCH'
resourcePath = '/device/devices/435'
queryParams = '?patchFields=customProperties&opType=add'
data = '{"customProperties":[{"name":"snmp.version","value":"v2c"}]}'
#Construct URL
url = 'https://'+ Company +'.logicmonitor.com/santaba/rest' + resourcePath +queryParams
#Get current time in milliseconds
epoch = str(int(time.time() * 1000))
#Concatenate Request details
requestVars = httpVerb + epoch + data + resourcePath
#Construct signature
hmac1 = hmac.new(AccessKey.encode(),msg=requestVars.encode(),digestmod=hashlib.sha256).hexdigest()
signature = base64.b64encode(hmac1.encode())
#Construct headers
auth = 'LMv1 ' + AccessId + ':' + signature.decode() + ':' + epoch
headers = {'Content-Type':'application/json','Authorization':auth}
#Make request
response = requests.patch(url, data=data, headers=headers)
#Print status and body of response
print('Response Status:',response.status_code)
print('Response Body:',response.content)
Example 3: Python PATCH
The following python script updates the Collector id for all devices that have ‘prod’ in the display name, and leaves all other fields for the devices as is:
#!/bin/env python
import requests
import json
import hashlib
import base64
import time
import hmac
#Account Info
AccessId ='48v2wRzfK94y53sq5EuF'
AccessKey ='H_D9i(f5~B^U36^K6i42=^nS~e75gy382Bf6{)P+'
Company = 'api'
#Request Info
httpVerb ='GET'
resourcePath = '/device/devices'
queryParam = '?filter=displayName~prod'
#Construct URL
url = 'https://'+ Company +'.logicmonitor.com/santaba/rest' + resourcePath + queryParam
#Get current time in milliseconds
epoch = str(int(time.time() * 1000))
#Concatenate Request details
requestVars = httpVerb + epoch + resourcePath
#Construct signature
hmac1 = hmac.new(AccessKey.encode(),msg=requestVars.encode(),digestmod=hashlib.sha256).hexdigest()
signature = base64.b64encode(hmac1.encode())
#Construct headers
auth = 'LMv1 ' + AccessId + ':' + signature.decode() + ':' + epoch
headers = {'Content-Type':'application/json','Authorization':auth}
#Make request
response = requests.get(url, headers=headers)
#Parse response
jsonResponse = json.loads(response.content)
#Loop through each device & update Collector Id
for i in jsonResponse['data']['items']:
deviceId = str(i['id'])
#Request Info
httpVerb ='PATCH'
resourcePath = '/device/devices/'+deviceId
queryParams ='?patchFields=preferredCollectorId'
data = '{"preferredCollectorId":85}'
#Construct URL
url = 'https://'+ Company +'.logicmonitor.com/santaba/rest' + resourcePath +queryParams
#Get current time in milliseconds
epoch = str(int(time.time() * 1000))
#Concatenate Request details
requestVars = httpVerb + epoch + data + resourcePath
#Construct signature
hmac1 = hmac.new(AccessKey.encode(),msg=requestVars.encode(),digestmod=hashlib.sha256).hexdigest()
signature = base64.b64encode(hmac1.encode())
#Construct headers
auth = 'LMv1 ' + AccessId + ':' + signature.decode() + ':' + epoch
headers = {'Content-Type':'application/json','Authorization':auth}
#Make request
response = requests.patch(url, data=data, headers=headers)