Мы можем диагностировать эту проблему, используя конечную точку отладки, такую как https://httpbin.org,, которую вы можете использовать для точного просмотра данных, отправляемых вашими запросами.
Используя следующую книгу, мы сначала делаем запрос сcurl
, а затем с модулем uri
, в каждом случае сохраняя ответ от httpbin
, чтобы мы могли сравнить их:
---
- name: Run cURL commands
hosts: localhost
gather_facts: false
vars:
endpoint: "https://httpbin.org/put"
cron_schedule: "0/10 * * * * ?"
invocation_context:
action: "someAction"
source: "path/to/resource"
tasks:
- name: First task (curl)
command: >-
curl -k -o output-curl1.json
--header "Content-Type: application/json"
--header "X-Application-Username: my_username"
--header "X-Application-Password: my_password"
--request PUT
--data '{"enabled":"False","persisted" : true,"concurrentExecution" : false, "type" : "cron","schedule" : "0/10 * * * * ?","invokeService" : "provisioner","invokeContext" : { "action" : "someAction","source" : "path/to/resource"}}'
"{{ endpoint }}"
- name: First task (uri)
uri:
url: "{{ endpoint }}"
headers:
Content-Type: "application/json"
X-Application-Username: "my_username"
X-Application-Password: "my_password"
method: PUT
body:
enabled: "False"
persisted: "true"
concurrentExecution: "false"
type: "cron"
schedule: "{{ cron_schedule }}"
invokeService: "provisioner"
invokeContext: "{{ invocation_context | to_json }}"
body_format: json
validate_certs: no
return_content: true
register: output1
- copy:
content: "{{ output1.content }}"
dest: ./output-task1.json
Вы можете просто проверить результаты вручную, но это, вероятно, прощеесли мы объединяем jq
и diff
, чтобы выделить различия:
$ diff -u <(jq -Sr .data output-curl1.json | jq -S .) <(jq -Sr .data output-task1.json | jq -S .)
--- /dev/fd/63 2019-04-07 18:00:46.597729568 -0400
+++ /dev/fd/62 2019-04-07 18:00:46.599729606 -0400
@@ -1,12 +1,9 @@
{
- "concurrentExecution": false,
+ "concurrentExecution": "false",
"enabled": "False",
- "invokeContext": {
- "action": "someAction",
- "source": "path/to/resource"
- },
+ "invokeContext": "{\"action\": \"someAction\", \"source\": \"path/to/resource\"}",
"invokeService": "provisioner",
- "persisted": true,
+ "persisted": "true",
"schedule": "0/10 * * * * ?",
"type": "cron"
}
Это подчеркивает некоторые различия.Самым большим из них является содержимое атрибута invokeContext
.При использовании curl
значением этого атрибута является объект JSON:
$ jq -r .data output-curl1.json | jq .invokeContext
{
"action": "someAction",
"source": "path/to/resource"
}
Но при использовании модуля uri
значение invokeContext
представляет собой строку:
$ jq -r .data output-task1.json | jq .invokeContext
"{\"action\": \"someAction\", \"source\": \"path/to/resource\"}"
Это происходит потому, что вы передаете значение переменной invocation_context
через фильтр to_json
:
invokeContext: "{{ invocation_context | to_json }}"
Это означает, что структура данных body
в вашей задаче сериализуется вJSON, invokeContext
- который уже уже преобразован в строку JSON - получает двойное преобразование.Вы хотите это:
invokeContext: "{{ invocation_context }}"
У вас также есть некоторые логические и строковые конфликты.
При использовании curl
вы устанавливаете атрибут persisted
в логическое true
, нов вашей задаче Ansible вы устанавливаете значение строки "true"
.Вместо:
persisted: "true"
Вы хотите:
persisted: true
И, наконец, у вас та же проблема с атрибутом concurrentExecution
, который должен быть:
concurrentExecution: false
Со всеми этими изменениями первая задача становится:
- name: First task (uri)
uri:
url: "{{ endpoint }}"
headers:
Content-Type: "application/json"
X-Application-Username: "my_username"
X-Application-Password: "my_password"
method: PUT
body:
enabled: "False"
persisted: true
concurrentExecution: false
type: "cron"
schedule: "{{ cron_schedule }}"
invokeService: "provisioner"
invokeContext: "{{ invocation_context }}"
body_format: json
validate_certs: no
return_content: true
register: output1
И если мы повторим нашу более раннюю команду diff
, мы увидим, что данные, отправленные curl
и модулем uri
идентично:
$ diff -u <(jq -Sr .data output-curl1.json | jq -S .) <(jq -Sr .data output-task1.json | jq -S .)
$ # no output from the previous command