0

I'm trying to import a Template to my Zabbix server with Zabbix API, i used this:

fileJSON=\""$(cat template_file)"\"

curl  -s -X POST -H 'Content-Type: application/json-rpc' -d '{
    "jsonrpc": "2.0",
    "method": "configuration.import",
    "params": {
        "format": "json",
        "rules": {
            "templates": {
                "createMissing": true,
                "updateExisting": true
            }
        },
        "source": $fileJSON
    },
    "auth": "6a977cd94b26b6156698459ac4d0f769",
    "id": 1
}' 'http://127.0.0.1/zabbix/api_jsonrpc.php' | jq '.'

Here is the output:

{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error","data":"Invalid JSON. An error occurred on the server while parsing the JSON text."},"id":null}

I just don't see any error… i tried to use an online parser website but he Don't see any error. This var is directly filled with the export method of Zabbix (in JSON). Here is the content of the file:

{
  "jsonrpc": "2.0",
  "result": "{\"zabbix_export\":{\"version\":\"4.4\",\"date\":\"2020-02-18T08:47:31Z\",\"groups\":[{\"name\":\"System\"}],\"templates\":[{\"template\":\"Template Systeme\",\"name\":\"Template Systeme\",\"groups\":[{\"name\":\"System\"}],\"discovery_rules\":[{\"name\":\"D\\u00e9couverte des services\",\"key\":\"service.discovery\",\"delay\":\"30s\"}]}]}}",
  "id": 1
}

I think that the error is the format of the fileJSON, how to encode this variable in JSON format ?

BlueStraax
  • 103
  • 3
  • 11
  • As a suggestion, why don't you create the JSON before you put it in Curl so you can check its validity? – vogomatix Feb 18 '20 at 10:24

3 Answers3

2

you're submitting your JSON using single quotes '{...}' which do not result in the interpolation of your $fileJSON - hence you receive that error.

Use double quotations instead:

curl  -s -X POST -H 'Content-Type: application/json-rpc' -d "{
...

you would need then quote the inner quotation marks of your JSON too.

There's also an easier way to interpolate $fileJSON, use it like this:

curl  -s -X POST -H 'Content-Type: application/json-rpc' -d '{
    "jsonrpc": "2.0",
    "method": "configuration.import",
    "params": {
        "format": "json",
        "rules": {
            "templates": {
                "createMissing": true,
                "updateExisting": true
            }
        },
        "source": '"$fileJSON"'
    },
    "auth": "6a977cd94b26b6156698459ac4d0f769",
    "id": 1
}' ...

that way will spare you a hassle quoting inner quotation marks

Dmitry
  • 1,275
  • 1
  • 5
  • 14
  • No, single quotes is the proper way to send JSON data with cURL. See this SO [post](https://stackoverflow.com/questions/7172784/how-do-i-post-json-data-with-curl) – Lucas Feb 18 '20 at 10:30
  • 2
    shell interpolation occurs before argument is passed to the command and single quotes prevent it. `curl` simply would not know that `$fileJSON` requires an interpolation – Dmitry Feb 18 '20 at 10:37
  • Right. The single quotes around the argument to `-d` mean that the data being passed to `curl` contains the literal 9-character sequence `$fileJSON`; nowhere in there is the contents of the file you loaded into a shell variable _named_ `$fileJSON`. – Mark Reed Feb 18 '20 at 10:55
  • Thank for your answer but that Don't solve the problem… – BlueStraax Feb 18 '20 at 13:06
  • @BlueStraax what's the returned error in that case? I suspect that interpolation of `$fileJSON` does not go well. do you mind sharing the content of that variable? – Dmitry Feb 18 '20 at 13:08
  • @Dmitry when i type this: ``` '"$fileJSON"' ``` i have the same error as usual, the content of the variable is exactly the same as the content of the file with double quote at the start and at the end. You can see the content in my question. – BlueStraax Feb 18 '20 at 13:24
  • 1
    @BlueStraax: ah, I missed that part. In this case the interpolation fails because your template_file contains double quotation marks (it's a `JSON`) and thus require _stringification_ before interpolation. Try setting `fileJSON` like this: `fileJSON="$( – Dmitry Feb 18 '20 at 13:29
  • @Dmitry, still the same error… Here is an echo of the variable: "{\"jsonrpc\":\"2.0\",\"result\":\"{\\\"zabbix_export\\\":{\\\"version\\\":\\\"4.4\\\",\\\"date\\\":\\\"2020-02-18T08:47:31Z\\\",\\\"groups\\\":[{\\\"name\\\":\\\"System\\\"}],\\\"templates\\\":[{\\\"template\\\":\\\"Template_System\\\",\\\"name\\\":\\\"Template_System\\\",\\\"groups\\\":[{\\\"name\\\":\\\"System\\\"}],\\\"discovery_rules\\\":[{\\\"name\\\":\\\"D\\\\u00e9couverte des services\\\",\\\"key\\\":\\\"service.discovery\\\",\\\"delay\\\":\\\"30s\\\"}]}]}}\",\"id\":1}" – BlueStraax Feb 18 '20 at 13:38
  • @BlueStraax - that's the properly stringified JSON. I don't know the API requirement to supply your JSON, but if that fails, I may assume that API expect a constructed JSON rather than a stringified source. In such case try this way: `fileJSON="$(cat template_file)"` – Dmitry Feb 18 '20 at 13:51
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/208054/discussion-between-bluestraax-and-dmitry). – BlueStraax Feb 18 '20 at 14:01
1

From the API documentation:

source (required) - string - Serialized string containing the configuration data.

You can find an XML source example:

"source": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><zabbix_export><version> [cut]

You are sending as source the full output of a configuration.export call:

{
  "jsonrpc": "2.0",
  "result": "{\"zabbix_export\":{\"version\":\"4.4\",\"date\":\"2020-02-18T08:47:31Z\",\"groups\":[{\"name\":\"System\"}],\"templates\":[{\"template\":\"Template Systeme\",\"name\":\"Template Systeme\",\"groups\":[{\"name\":\"System\"}],\"discovery_rules\":[{\"name\":\"D\\u00e9couverte des services\",\"key\":\"service.discovery\",\"delay\":\"30s\"}]}]}}",
  "id": 1
}

while you have to send only the serialized string, which should be the value of the "result" field of your fileJSON:

"source": "{\"zabbix_export\":{\"  [cut]
Simone Zabberoni
  • 2,024
  • 1
  • 10
  • 15
  • Thank you for answer me, i think you right but that Don't solved the problem… Always the same error with or without the backslash… any idea ? – BlueStraax Feb 18 '20 at 13:04
  • Try without the external file, use a static source inside your curl data. But a better idea is to avoid manual "curling": use an API implementation that takes care of escaping, authentication etc... I use pyzabbix, but it's a personal taste decision. – Simone Zabberoni Feb 18 '20 at 13:29
  • 1
    Always the same error i think i will use xml format or pyzabbix. thanks – BlueStraax Feb 18 '20 at 13:39
0

From the look of the template_file output, the result key is not JSON but JSON string. Have you tried without JSON dumping it?

Lucas
  • 1,833
  • 1
  • 18
  • 19
  • i didin't dump it, it's by default like that. I Don't really know what's the difference between JSON and JSON string, that why my request was how to transform it in JSON format – BlueStraax Feb 18 '20 at 13:11