Hello ansible community,
We are working with an Ansible project in which we would like to call a API-put request for FME (a GIS-etl-tool). The machine that gets the request is a windows machine. Therefore we quickly found the win_uri module. However we do a multipart request in which a file is uploaded to the application. This would be easier if it were a linux-machine. then we could use the uri module. The win_uri module does not support form-multipart as a variable in the body.
After some struggles the only solution that works so far is calling a python script deducted from postman, making the original API request.
-The python-script is created based on the environment variables,
-The python-script is run by ansible
-The output is tested to see if it was succesful
I are curious if there is an easier way to achieve the same result. The code we have now is:
---
- name: Write Python script
win_copy:
content: "{{ python_script_content }}"
dest: "{{ destination_path }}/script.py"
force: yes
- name: Run the Python script
win_shell: |
python "{{ destination_path }}/script.py"
register: upload_result
- name: Check upload success status
debug:
msg: "Upload succeeded with response code 204!"
when: upload_result.rc == 0
- name: Upload failed or unexpected response
debug:
msg: "Upload failed or returned status code other than 204. Return code: {{ upload_result.rc }}"
when: upload_result.rc != 0
and in the main the python script that is written to the machine and run via ansible:
python_script_content: |
import requests
import base64
# Your credentials
credentials = "{{ user }}:{{ password }}"
# Encode credentials in base64
b64_credentials = base64.b64encode(credentials.encode('utf-8')).decode('utf-8')
# Set headers with the encoded token
headers = {
'Authorization': f'Basic {b64_credentials}'
}
url = "https://{{ fqdn }}/fmeapiv4/configuration/encryption/keyfile"
payload = {}
file_path = "{{ share[env] }}/key/fme_{{ env }}.jceks"
with open(file_path, 'rb') as f:
files = [('file', ('fme_{{ env }}.jceks', f, 'application/octet-stream'))]
response = requests.put(url, headers=headers, data=payload, files=files, verify=False)
print(response.text)
Other options we tested but not the optimal solution or working at all:
-Powershell script run via Ansible with win_shell/ win_script
-Use CURL in some way
-Somehow use the win_uri incorporating multipart as header
Is there an option to achieve the same goal more easily?