Curl request to ansible playbook - json

Sample curl request.
curl -X POST \
--data '"test connection"' \
-H 'Content-type: application/json' \
-H 'Authorization: Basic asdfasdf' \
dns.com/end
Now, I'd like to send exactly the same message using curl ansible playbook.
---
- name: "Send test"
hosts: localhost
tasks:
- name: Send test
uri:
url: dns.com/end
method: POST
src: '"test connection"'
body_format: json
headers:
Content-type: "application/json"
Authorization: "Basic asdfasdf"
I'm getting an error.

You should be using the body parameter instead of src. Also, the header should be Content-Type instead of Content-type.

Just to add src is used when you want to submit the data from a file.
Solution will look something like
tasks:
- name: Send test
uri:
url: dns.com/end
method: POST
body: "test connection"
headers:
Content-Type: "application/json"
Authorization: "Basic asdfasdf"

You have mentioned body format as json and you are not passing any body to it.
You body.json file should contain something like this:
{
"name": "test connection"
}
and also you can mention status_code=201 for POST method.

Related

How to trigger Github Action's workflow dispatch event through curl with string input in json format

I have a workflow in Github Actions with a workflow_dispatch event trigger. I expect a string input in json format. The workflow's yml looks something like this:
name: Json parse test
on:
workflow_dispatch:
inputs:
parameters_json:
type: string
required: true
jobs:
build_and_deploy:
name: Json parse test
runs-on: ubuntu-latest
steps:
- name: Parse json input
id: json
run: |
echo ${{ fromJson(github.event.inputs.parameters_json).targetPlatform }}
I want to trigger this workflow through a request with curl the way it is described here
When i run the workflow manually through Github's web page it runs fine.
My problem is when I try to trigger the workflow through a curl request with
curl -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer <my token>" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/\<owner>/<my repo>/actions/workflows/json_parse_test.yml/dispatches -d '{"ref":"dev","inputs":{"parameters_json":"{"targetPlatform":"asd","param":45}"}}'
it throws the following error and the workflow does not run
{
"message": "Problems parsing JSON",
"documentation_url": "https://docs.github.com/rest/reference/actions#create-a-workflow-dispatch-event"
}
If I pass a normal string (without json format, e.g "something") as input, the workflows gets triggered as expected, i.e. there is no problem with the curl code.
So, my question is: is there any syntax to send a string input with json format to get around this parsing issue?
Thanks in advance.
Credits to #Azeem who answered this in the question's comments.
To solve this issue you should escape the double quotes in the nested json input.
"inputs":{"parameters_json":"{\"targetPlatform\":\"asd\",\"param\":45}"
Resulting in the curl code:
curl -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer <my token>" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/<owner>/<my repo>/actions/workflows/json_parse_test.yml/dispatches -d '{"ref":"dev","inputs":{"parameters_json":"{\"targetPlatform\":\"asd\",\"param\":45}"}}'

Getting bad request error with alamofire JSON request

I have been converting this curl syntax
curl -L -X POST 'https://driver-vehicle-licensing.api.gov.uk/vehicleenquiry/v1/vehicles' \-H 'x-api-key: REPLACE WITH YOUR API KEY' \-H 'Content-Type: application/json' \-d '{"registrationNumber": "TE57VRN"}'
into Swift with Alamofire and have got this syntax
guard let url = URL(string: "https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles") else { return }
let headers : HTTPHeaders = [
"x-api-key": "mykey",
"Content-Type": "application/json"
]
let params: Parameters = [
"registrationNumber" : "myreg"
]
AF.request(url, method: .post, parameters: params, encoding: URLEncoding(destination: .httpBody), headers: headers).responseJSON(completionHandler: { response in
print(response)
})
However, I have got the output
success({
errors = (
{
code = ENQ103;
detail = "Invalid format for field - vehicle registration number";
status = 400;
title = "Bad Request";
}
);
Please could someone explain what I have done wrong. Thanks
The API expects the parameters to be sent as JSON, but you are sending as URL encoded.
Try using JSONParameterEncoder.default as the encoder instead of URL encoding.
Check Usage from the docs: POST request with JSON Parameters
let parameters: Parameters = [
"registrationNumber" : "myreg"
]
AF.request(url, method: .post, parameters: parameters, encoder: JSONParameterEncoder.default)
You have a working curl command, small (or big) tip: AlamoFire can print the request as a curl command!
In "one step":
AF.request(url, method: .post,
parameters: params,
encoding: URLEncoding(destination: .httpBody),
headers: headers)
.cURLDescription(calling: { curlCommand in
print("curlCommand1: \(curlCommand)")
}).responseJSON(completionHandler: { response in
print(response)
})
In "two steps", if you prefer to separate your calls and not chain them all:
let request = AF.request(url, method: .post,
parameters: params,
encoding: URLEncoding(destination: .httpBody),
headers: headers)
request.cURLDescription { curlCommand in
print("curlCommand2: \(curlCommand)")
}
request.responseJSON(completionHandler: { response in
print(response)
})
And you should have output:
curl -v \
-X POST \
-H "Accept-Encoding: br;q=1.0, gzip;q=0.9, deflate;q=0.8" \
-H "User-Agent: Alamofired/1.0 (...; build:1; iOS 14.5.0) Alamofire/5.4.0" \
-H "Accept-Language: en;q=1.0, fr-US;q=0.9" \
-H "Content-Type: application/json" \
-H "x-api-key: mykey" \
-d "registrationNumber=myreg" \
"https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles"
Now, if we compare with yours:
curl \
-L \
-X POST \
'https://driver-vehicle-licensing.api.gov.uk/vehicleenquiry/v1/vehicles' \
-H 'x-api-key: REPLACE WITH YOUR API KEY' \
-H 'Content-Type: application/json' \
-d '{"registrationNumber": "TE57VRN"}'
I added some \ to make it sill valid...
We shouldn't care about the order, the "Accept-Language", "User-Agent", "Accept-Encoding" headers that are added with Alamofire shouldn't be an issue.
Try your command with no -L parameter maybe to check if it's "important" (if it's --location).
And then, the difference is with the data paramater (-d). Once is JSON, the other is URL encoded.
Then, let's see your code, and URLEncoding(destination: .httpBody)
might be the culprit. Using JSONEncoding.default instead will work.
Now, if you didn't have had the curl command, just by seeing your code, I spotted it. If you think about it:
You are saying there that you will provide the parameter in body following the JSON protocol.
let headers : HTTPHeaders = ["Content-Type": "application/json"]
And later, you used URL Encoding protocol.
URLEncoding(destination: .httpBody)
Doesn't make sense, right? You're contradicting yourself.

How to format a JSON array in the request body of a multipart/form-data request with OpenAPI 3?

I'm trying to write the OpenAPI 3 specs for an existing endpoint. The endpoint uses Content-Type of multipart/form-data and one of the parameters accepts a JSON array string. The following curl shows an example of this endpoint working correctly:
curl -X 'POST' \
'https://testing.org/test/' \
-H 'accept: */*' \
-H 'Content-Type: multipart/form-data' \
-F 'simple=abc' \
-F 'complex=[{"key": "string", "size": 0}"]'
My OpenAPI 3 specs currently look like the following:
openapi: 3.0.3
info:
title: Simple
description: Testing
version: '1.0'
servers:
- url: 'https://testing.org'
paths:
/test/:
post:
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
simple:
type: string
complex:
type: array
items:
type: object
properties:
key:
type: string
size:
type: integer
encoding:
complex:
contentType: application/json
responses:
'200':
description: OK
However, using the "test it out" functionality in swagger editor results in a request that looks like this:
curl -X 'POST' \
'https://testing.org/test/' \
-H 'accept: */*' \
-H 'Content-Type: multipart/form-data' \
-F 'simple=abc' \
-F 'complex=["{\n \"key\": \"string\",\n \"size\": 0\n}"]'
with the complex parameter not formatted correctly. If I removed the encoding portion of the specs, this is what the request looks like:
curl -X 'POST' \
'https://testing.org/test/' \
-H 'accept: */*' \
-H 'Content-Type: multipart/form-data' \
-F 'simple=abc' \
-F 'complex={
"key": "string",
"size": 0
}'
which is a JSON object but not a JSON array.
Any advice on how to format the OpenAPI 3 specs so that complex form parameter is formatted as a simple JSON array [{"key": "string", "size": 0}"]? Thank you!
Your API definition is correct. It should even work without encoding because the Content-Type for objects and arrays of objects is application/json by default.
The problem is that Swagger UI and Swagger Editor do not properly support JSON in multipart bodies yet. Here are the related issues you can track:
Encoding attribute is not respected on the request
Generated CURL seems wrong for mime/multipart uploads that have JSON parts - missing 'type=' option, wrong quotes
multipart/form-data should support custom content-type selection

How to retrieve values from json response of a CURL request when using ansible command module?

I am using Ansible to test some APIs. Instead of using get_url or uri module of ansible, i am using Curl requests with command/shell module.
I would need to extract a particular value from the json response of a curl api call, so that i can use that value in next curl request.
For example,
- name: Run a curl request to login and get jwt token
command: curl -k -X POST -H "Content-Type:application/json" --data '{"user":"{{username}}","password":"{{password}}"}' https://localhost:8001/api/v1/login
register: login_response
- name: Print the jwt response
debug:
var: login_response.stdout
- name: Run a curl request to get service token
command: curl -k -X GET -H "Accept:application/json" -H "Authorization:Bearer {{login_response.stdout.jwt}}" https://localhost:8001/api/v1/servicetoken/issue
register: service_token
- name: Print service token
debug:
var: service_token.stdout
The above ansible playbook will fail at third task because it cannot find a variable like:
login_response.stdout.jwt
Normally the variable in second task, ie, login_response.stdout will print something like this:
ok: [localhost] => {
"login_response.stdout": {
"jwt": "eyJhbGciOiJIUzUxMiIsImtpZCI6ImFiNmU0ZDg2LWE4YzgtNDU4OS04MmRiLWIxZTg1YzQwNDNlZiJ9.eyJleHAiOjE2MDU2MTIxODAuNjA5MTI1NCwiaWF0IjoxNjA1NjExODgwLjYwOTEyMC42MDkxMjU0fQ.ZC4a3H3j03ZmzDkjGj11cvxSls2qXZmVOGuIvKp8LHVpYOUyEJlWJJOTArHxKhxne3DsuqWoGpslR6KxuUOBFg",
"roles": [
{
"name": "Admin"
}
]
}
}
What i want is to extract that jwt token from the above response and use it in third task.
How can i achieve this?
I found the answer!
This can be achieved using from_json filter in order to make ansible able to access the json fields.
Now the working playbook should be like:
- name: Run a curl request to login and get jwt token
command: curl -k -X POST -H "Content-Type:application/json" --data '{"user":"{{username}}","password":"{{password}}"}' https://localhost:8001/api/v1/login
register: login_response
- name: Print the jwt token
debug:
var: (login_response.stdout|from_json).jwt
- name: Run a curl request to get service token
command: curl -k -X GET -H "Accept:application/json" -H "Authorization:Bearer {{(login_response.stdout|from_json).jwt}}" https://localhost:8001/api/v1/servicetoken/issue
register: service_token
- name: Print service token
debug:
var: (service_token.stdout|from_json).token
I refered here to get the idea: https://medium.com/#justinhennessy/parsing-json-with-ansible-bcbb8d4b6a54

Grails - JSON param request not passing to controller

I would like to pass a JSON to my requete.
But not possible to find the JSON.
#Secured(['ROLE_STUDENT'])
def validate() {
println params
println request.JSON
}
Result :
[controller:student, action:validate, id:2345444]
[:]
URL :
curl -i -H "Content-Type: application/json" -X POST -d '{"studentScores":[{"id":"2","score":"17"}],"comment":"good"}' 'http://localhost:8080/myapp/studient/2345444/validate' -H 'Cookie: JSESSIONID=3CCDC701553A2208428BB7135DDA5546'
I tried with GET and POST, and with à JQuery
$.ajax({
url: urlSubmit,
type: 'POST',
data: JSON.stringify(student),
contentType:"application/json; charset=utf-8",
dataType: "json"
});
Grails 2.4.4
Java 8 (compliance level java 7)
Tomcat 8
Some plugins :
spring-security-core:2.0-RC4
spring-security-facebook:0.16.2
spring-security-oauth2-provider:2.0-RC2
Need your help
See this: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html (9.3 GET).
The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI
Request-URI being the important part here. There is no concept of body data in a GET requests.
So, change to POST and your request should work.
For first u have an error in your url in curl :)
http://localhost:8080/myapp/STUDIENT/2345444/validate
try this code
def json = JSON.stringify(params)
but I don't sure.