Can't import dashboard via API - value must be an object

I exported a dashboard to export.json using web UI.

Am trying to import via API:

curl -XPOST 'http://localhost:5601/api/kibana/dashboards/import' -H 'kbn-xsrf:true' -H 'Content-type:application/json' --data @export.json

Get error message:

{"statusCode":400,"error":"Bad Request","message":""value" must be an object","validation":{"source":"payload","keys":["value"]}}

Kibana 6.4.2

Any suggestions?

Something is wrong with the way you're using curl. That is a curl error... are you sure you have the path right for that file? I will also redirect you to the docs here- may be that could help ? https://www.elastic.co/guide/en/kibana/current/dashboard-import-api.html

Could you also comment on what you changed/ how you made it work once you fix it , for future reference if someone else hits the same problems ?

Thanks
Rashmi

Thank you for the link. It was not a curl error directly. The link has a button "Copy as curl" which then worked for me on command line.

A key difference is that the export.json file is a set of objects:

[
{
"_id": "a27618c0-d080-11e8-a11c-696815073ccd",
"_type": "dashboard",
:
etc
]

Whereas the example API call wraps that:

{"objects":

[
{
"_id": "a27618c0-d080-11e8-a11c-696815073ccd",
"_type": "dashboard",
etc...
]

}

Also, I noted "http://localhost:5601/api/kibana/dashboards/import?exclude=some-pattern" - specifying without the excluded seemed to give an error.

In fact the json is subtly different as far as field names etc - e.g. the use of "_id" - you need to use "id".

I got the curl export api working and that produces the right format of json which can then be reloaded. But why oh why is API and the web UI producing different results?

Surely this is just a recipe for confusion??

So here is my script which create things (this is run as part of docker-compose set so assumes blank Kibana app).

#!/bin/bash
# Initialise Kibana dashboard - first waiting until it responds
# Primary usage of script is as part of Dockerfile

# Hostname for kibana - could be localhost
KIBANA_HOST=${1:-kibana}
# Default port
KIBANA_PORT=${2:-5601}
# JSON file - see below for how to create
DASHBOARD_JSON=${3:-/p4/api_dashboard.json}

until nc -zw 1 $KIBANA_HOST $KIBANA_PORT; do sleep 1; done

# Please note that the following file MUST have been created using the API.
# https://www.elastic.co/guide/en/kibana/current/dashboard-import-api-export.html
# 
# curl -X GET "http://localhost:5601/api/kibana/dashboards/export?dashboard=942dcef0-b2cd-11e8-ad8e-85441f0c2e5c" -H 'kbn-xsrf: true'
#
# Obviously substitute appropriate UUID - which turns out not to be so easy to find via API.
#
# If you attempt to use a file that was exported using the web UI it will not work since
# Elastic in their wisdom have made the formats close but not the same!!

URL="http://$KIBANA_HOST:$KIBANA_PORT"

# In the below it might say "?exclude=index-pattern" but we explicitly want the index
# created.

curl -X POST -H "Content-Type: application/json" -H "kbn-xsrf: true" "$URL/api/kibana/dashboards/import?exclude=some-pattern" -d @${DASHBOARD_JSON}

# Finally having imported dashboard we extract index pattern it contained and set it to be default
index_id=$(grep -B1 "index-pattern" $DASHBOARD_JSON | grep '"id"' | sed -e 's/.*: "//' -e 's/",//')

curl -X POST -H "Content-Type: application/json" -H "kbn-xsrf: true" "$URL/api/kibana/settings/defaultIndex" -d '{"value": "$index_id"}' 

Also have a python version:

import os
import requests
import json
import sys

json_file = "api_dashboard.json"
kibana_url = "localhost:5601/api"
headers = {'Content-Type': 'application/json', 'kbn-xsrf': 'true'}

# Please note that the following file MUST have been created using the API.
# https://www.elastic.co/guide/en/kibana/current/dashboard-import-api-export.html
# 
# curl -X GET "http://localhost:5601/api/kibana/dashboards/export?dashboard=942dcef0-b2cd-11e8-ad8e-85441f0c2e5c" -H 'kbn-xsrf: true'
# Obviously substitute appropriate UUID - which turns out to be hard to get at from API.
#
# If you attempt to use a file that was exported using the web UI it will not work since
# Elastic in their wisdom have made the formats close but not the same!!

with open(json_file, 'r') as f:
    data = f.read()

dashboard_json = json.loads(data)

id_default_index = ""
for o in dashboard_json['objects']:
    if o['type'] == 'index-pattern':
        id_default_index = o['id']

# Note that we don't exclude the index-pattern because we want that imported too!
url = 'http://%s/kibana/dashboards/import?exclude=some-pattern' % kibana_url

print("Posting to '%s'" % url)
r = requests.post(url, headers=headers, json=dashboard_json)
print(str(r))
print(str(r.text))

# Set default index pattern - for reasons not yet known doesn't take effect for a while
url = 'http://%s/kibana/settings/defaultIndex' % (kibana_url)
data = {"value": id_default_index}

r = requests.post(url, headers=headers, json=data)
print(str(r))
print(str(r.text))

The fact that the json exported by Web UI and by API are different raises concerns in my mind about consistency in the internals - am I missing something or being unfair?

Comments welcome...

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.