将 cURL 命令转换为 ansible

Rik*_*son 2 curl ansible devops

我有两个 cURL 命令,我试图将它们转换为 Ansible。它们看起来像这样:

curl -v -ik --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"}}' "https://localhost:8443/path/to/url/that/I/need"


curl -v -ik --header "Content-Type: application/json" --header "X-Application-Username: my_username" --header "X-Application-Password: my_password" --request PUT --data '{"enabled":"True","persisted" : true,"concurrentExecution" : false, "type" : "cron","schedule" : "0/10 * * * * ?","invokeService" : "provisioner","invokeContext" : { "action" : "someAction","source" : "path/to/resource"}}' "https://localhost:8443/path/to/url/that/I/need"
Run Code Online (Sandbox Code Playgroud)

我试图转换为 ansible,但它不起作用。到目前为止我想出的是:

- name: Run cURL commands
  hosts: role_app_server[1]
  vars:
    endpoint: "https://localhost:8443/path/to/url/that/I/need"
    cron_schedule: "0/10 * * * * ?"
    invocation_context:
      action: "someAction"
      source: "path/to/resource"
  tasks:
    - name: First task
      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
    - name: 2nd task
      uri:
        url: "{{ endpoint }}"
        headers:
          Content-Type: "application/json"
          X-Application-Username: "my_username"
          X-Application-Password: "my_password"
        method: PUT
        body:
          enabled: "True"
          persisted: "true"
          concurrentExecution: "false"
          type: "cron"
          schedule: "{{ cron_schedule }}"
          invokeService: "provisioner"
          invokeContext: "{{ invocation_context | to_json }}"
        validate_certs: no
        body_format: json
Run Code Online (Sandbox Code Playgroud)

谁能发现我做错了什么?

lar*_*sks 7

我们可以使用像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
Run Code Online (Sandbox Code Playgroud)

您可以手动检查结果,但如果我们结合jqdiff突出差异可能会更容易:

$ 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"
 }
Run Code Online (Sandbox Code Playgroud)

这突出了一些差异。最大的似乎是invokeContext属性的内容。使用时curl,该属性的值是一个 JSON 对象:

$ jq -r .data output-curl1.json | jq .invokeContext
{
  "action": "someAction",
  "source": "path/to/resource"
}
Run Code Online (Sandbox Code Playgroud)

但是在使用uri模块时,的值invokeContext是一个字符串:

$ jq -r .data output-task1.json | jq .invokeContext
"{\"action\": \"someAction\", \"source\": \"path/to/resource\"}"
Run Code Online (Sandbox Code Playgroud)

发生这种情况是因为您invocation_context通过to_json过滤器传递变量的值:

invokeContext: "{{ invocation_context | to_json }}"
Run Code Online (Sandbox Code Playgroud)

这意味着当body您的任务中的数据结构被序列化为 JSON 时,invokeContext已经转换为 JSON 字符串的 JSON 会被双重转换。你要这个:

invokeContext: "{{ invocation_context }}"
Run Code Online (Sandbox Code Playgroud)

您也有一些布尔值与字符串冲突。

使用时,curl您将persisted属性设置为 boolean true,但在 Ansible 任务中,您将其设置为字符串 value "true"。代替:

persisted: "true"
Run Code Online (Sandbox Code Playgroud)

你要:

persisted: true
Run Code Online (Sandbox Code Playgroud)

最后,concurrentExecution属性也有同样的问题,应该是:

concurrentExecution: false
Run Code Online (Sandbox Code Playgroud)

随着所有这些变化,第一个任务变成:

- 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
Run Code Online (Sandbox Code Playgroud)

如果我们重复我们先前的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
Run Code Online (Sandbox Code Playgroud)