Marged
Marged

Reputation: 10953

Using url module with jinja2 templates

I know how to process jinja2 templates files and let them create files. I also know how to POST to webservices using the url module. For now I use some code like this, which successfully posts hardcoded JSON to my remote service:

  tasks:
    - name: GSA app definition
      uri:
        url: "http://localhost:8764/api/apps?relatedObjects=false"
        method: POST
        force_basic_auth: yes
        user: "{{ admin_name }}"
        password: "{{ admin_pass }}"
        body_format: json
        body: "{\"name\":\"My new app\", \"description\":\"A really great new app\" }"
        follow_redirects: all
        status_code: 200
        timeout: 15
      register: app_gsa_cfg

But the JSON is static, how can I process a jinja2 template and POST its content ? I would prefer not having to create temporary files on disk and POST them, what I am looking for is a direct connection or perhaps an approach that puts the template processing result into a string.

For starters a jinja2 template could look like this, later I will add variables too:

{#
This file creates the basic GSA app in Fusion. See https://doc.lucidworks.com/fusion-server/4.2/reference-guides/api/apps-api.html#create-a-new-app for details
#}

{
  "name": "GSA",
  "description": "Contains all configuration specific to the migrated GSA legacy searches"
}

(I know that this has little advantage over a static json included into the playbook. But is is easier to edit and offers me the opportunity to have (jinja style) comments in Json, which is normally not possible)

Upvotes: 0

Views: 2472

Answers (1)

imjoseangel
imjoseangel

Reputation: 3926

In my case, what I do is the following:

I have an API, so I do the following:

- name: Change API Status
  uri:
    url: "{{ enpoint }}/v1/requests/{{ whatever }}"
    method: PATCH
    user: "{{ tokenid }}"
    password: x
    headers:
      X-4me-Account: "myaccount"
    body: '{ "status":"{{ reqstatus }}" }'
    body_format: json
    status_code:
      - 201
      - 200
    force_basic_auth: true
    validate_certs: false
    return_content: true

Then your reqstatus var will change.

Even you can add your whole text as yaml, import into a variable and convert with filters {{ some_variable | to_json }}

Note: Have a look to the formatting without escaping quotes. That will help.

It makes no sense creating a file with jinja2 if you are not going to copy it remotely. Ansible supports jinja natively but its strength is the possibility to have plugins for better maintainability. There is no difference between template (or win_template) modules unless (as said) you copy the file somewhere. Look this example:

---
- name: Adhoc Jinja
  hosts: localhost
  connection: local
  gather_facts: false

  vars:
    mytemplate:
      - name: "GSA"
        description: "Contains all configuration specific to the migrated GSA legacy searches"
      - name: "Another Name"
        description: "Contains Another Var"

  tasks:
    - name: Read Vars Loop
      debug:
        msg: "{{ item | to_json }}"
      with_items: "{{ mytemplate }}"

    - name: Include Vars
      include_vars: adhocjinja2.yml

    - name: Read Vars Loop
      debug:
        msg: "{{ item | to_json }}"
      with_items: "{{ mytemplate }}"

And adhocjinja2.yml:

mytemplate:
  - name: "GSA2"
    description: "Contains all configuration specific to the migrated GSA legacy searches"
  - name: "Another Name 2"
    description: "Contains Another Var"

The output is:

TASK [Read Vars Loop] **************************************************************************************
ok: [localhost] => (item={'name': 'GSA', 'description': 'Contains all configuration specific to the migrated GSA legacy searches'}) => {
    "msg": "{\"name\": \"GSA\", \"description\": \"Contains all configuration specific to the migrated GSA legacy searches\"}"
}
ok: [localhost] => (item={'name': 'Another Name', 'description': 'Contains Another Var'}) => {
    "msg": "{\"name\": \"Another Name\", \"description\": \"Contains Another Var\"}"
}

TASK [Include Vars] ****************************************************************************************
ok: [localhost]

TASK [Read Vars Loop] **************************************************************************************
ok: [localhost] => (item={'name': 'GSA2', 'description': 'Contains all configuration specific to the migrated GSA legacy searches'}) => {
    "msg": "{\"name\": \"GSA2\", \"description\": \"Contains all configuration specific to the migrated GSA legacy searches\"}"
}
ok: [localhost] => (item={'name': 'Another Name 2', 'description': 'Contains Another Var'}) => {
    "msg": "{\"name\": \"Another Name 2\", \"description\": \"Contains Another Var\"}"
}

You can manage your variables as you want and create your json on the fly as Ansible has jinja and json it its heart.

Upvotes: 0

Related Questions