I am trying to use http filter plugin to make POST requests to third party API while processing evens in logstash.
This API requires requests to be json-encoded in following format:
{
"type": "alert",
"source": "elasticsearch",
"title": "default title",
"description": "default description",
"sourceRef": "default_id",
"artifacts": [
{
"data": "8.8.8.8",
"message": "not empty",
"dataType": "ip"
},
{
"data": "11.11.11.11",
"message": "not empty",
"dataType": "ip"
}
]
}
In my logstash config I use following filter configuration:
http {
body_format => "json"
follow_redirects => false
body => {
"title" => "%{[title]}"
"description" => "%{[description]}"
"type" => "%{[type]}"
"source" => "%{[source]}"
"sourceRef" => "%{[sourceRef]}"
"artifacts" => "%{[array_of_objects]}"
}
url => "http://${HIVE_IP}/api/alert"
verb => "POST"
headers => [ "Authorization", "Bearer ${HIVE_API_KEY}" ]
target_body => "[@metadata][hive_response]"
target_headers => "[@metadata][hive_headers]"
}
All required data is prepared in right format in previous sections of the filter.
The problem I am now fasing is that I do not understand, how to pass an array of objects to "artifacts" field of http body. I tried "%{[array_of_objects]}" and ["%{[array_of_objects]}"], but it seems that using %{[field]} is leading to content of the field becoming a string.
Here is what I got in response (using "artifacts" => ["%{[array_of_objects]}"] syntax):
[DEBUG] 2019-07-19 10:32:13.769 [[main]>worker0] http - processing request {:body=>" {\"title\":\"default title\",\"description\":\"default description\",\"type\":\"alert\",\"source\":\"elasticsearch\",\"sourceRef\":\"default_id\",\"artifacts\":[\"{message=not empty, data=8.8.8.8, dataType=ip},{message=not empty, data=11.11.11.11, dataType=ip}\"]}", :url=>"http://<<IP>>/api/alert", :headers=>{"Authorization"=>"Bearer <<KEY>>", "content-type"=>"application/json"}}
[ERROR] 2019-07-19 10:32:14.238 [[main]>worker0] http - error during HTTP request {:url=>"http://<<IP>>/api/alert", :code=>400, :response=>"{\"tableName\":\"alert\",\"type\":\"AttributeCheckingError\",\"errors\":[{\"name\":\"alert.artifacts\",\"format\":\"nested\",\"type\":\"InvalidFormatAttributeError\",\"message\":\"Invalid format for alert.artifacts: JsonInputValue(\\\"{message=not empty, data=8.8.8.8, dataType=ip},{message=not empty, data=11.11.11.11, dataType=ip}\\\"), expected nested\",\"value\":{\"type\":\"JsonInputValue\",\"value\":\"{message=not empty, data=8.8.8.8, dataType=ip},{message=not empty, data=11.11.11.11, dataType=ip}\"}}]}"}
Here is what I got in response (using "artifacts" => "%{[array_of_objects]}" syntax):
[DEBUG] 2019-07-19 10:38:09.743 [[main]>worker2] http - processing request {:body=>{\"title\":\"default title\",\"description\":\"default description\",\"type\":\"alert\",\"source\":\"elasticsearch\",\"sourceRef\":\"default_id\",\"artifacts\":\"{data=8.8.8.8, message=not empty, dataType=ip},{data=11.11.11.11, message=not empty, dataType=ip}\"}", :url=>"http://<<IP>>/api/alert", :headers=>{"Authorization"=>"Bearer <<KEY>>", "content-type"=>"application/json"}}
[ERROR] 2019-07-19 10:38:10.233 [[main]>worker2] http - error during HTTP request {:url=>"http://<<IP>>/api/alert", :code=>400, :response=>"{\"type\":\"ConflictError\",\"message\":\"[alert][2dda1ae3dc11f5810504ca683c915dbb]: version conflict, document already exists (current version [2])\",\"object\":{\"type\":\"alert\",\"customFields\":{},\"sourceRef\":\"default_id\",\"date\":1563521890175,\"lastSyncDate\":1563521890175,\"description\":\"default description\",\"follow\":true,\"createdBy\":\"siem\",\"artifacts\":[ ],\"status\":\"New\",\"_id\":\"2dda1ae3dc11f5810504ca683c915dbb\",\"source\":\"elasticsearch\",\"severity\":2,\"title\":\"default title\",\"tlp\":2,\"createdAt\":1563521890153}}"}
Any advice?