I am using a script module to run a script on some hosts. I have an array ansible variable, that I want to pass the script as space separated arguments. Passing the array variable directly as argument does not help. Suggestions ?
You can join your list with jinja filter and pass it as a variable, like this:
ansible -m script -a "myscript.sh {{ test_list|join(' ') }}" localhost -e "{"test_list": [1,2,3]}"
If myscript.sh is:
#!/bin/bash
echo Args are: ${#}, 1st: $1 2nd: $2, 3d: $3
The output will be:
localhost | SUCCESS => {
"changed": true,
"failed": false,
"rc": 0,
"stderr": "",
"stdout": "Args are: 1 2 3, 1st: 1 2nd: 2, 3d: 3\n",
"stdout_lines": [
"Args are: 1 2 3, 1st: 1 2nd: 2, 3d: 3"
]
}
Related
I cannot find any doc for Fish Shell regarding using Command Substitution more than once.
I'm trying to assign the state, city from the JSON result set (jq parser) piped from a curl API query of LocationIQ. 2 Command Substitution 1:(curl) and 2:(jq). I don't need the location variable assignment if I can get the address variable assignment
Purpose of Function:
#Take 2 arguments (Latitude, Longitude) and return 2 variables $State, $City
The JSON:
{
"address": {
"city": "Aurora",
"country": "United States of America",
"country_code": "us",
"county": "Kane County",
"postcode": "60504",
"road": "Ridge Road",
"state": "Illinois"
},
"boundingbox": [
"41.729347",
"41.730247",
"-88.264466",
"-88.261979"
],
"display_name": "Ridge Road, Aurora, Kane County, Illinois, 60504, USA",
"importance": 0.2,
"lat": "41.729476",
"licence": "https://locationiq.com/attribution",
"lon": "-88.263423",
"place_id": "333878957973"
}
My Function:
function getLocation
set key 'hidden'
set exifLat $argv[1]
set exifLon $argv[2]
set location (curl -s "https://us1.locationiq.com/v1/reverse.phpkey=$key&lat=$exifLat&lon=$exifLon&format=json" | set address (jq --raw-output '.address.state,.address.city') )
echo "Location: $location
echo "state: $address[1]"
echo "city: $address[2]"
end
Error: fish Command substitution not allowed
Works fine using only the curl Command substitution ->removing the: set address & parens for jq.
set location (curl -s "https://us1.locationiq.com/v1/reverse.phpkey=$key&lat=$exifLat&lon=$exifLon&format=json" | jq --raw-output '.address.state,.address.city')
I'm still pretty novice - maybe there is a better way to achieve my desired result: Assign the JSON State to a variable and City to a variable?
I originally tried (slicing the location[17] - City, location[19] - State) and getting inconsistent results as the fields seem to be dynamic and affecting how many results which affects the ordering.
Any help appreciated!
I find the nested set confusing. Did you intend to do use $location to hold the downloaded JSON data, and $address to hold the results of jq? If yes, split them out into separate statements
set url "https://us1.locationiq.com/v1/reverse.phpkey=$key&lat=$exifLat&lon=$exifLon&format=json"
set location (curl -s $url)
set address (echo $location | jq --raw-output '.address.state,.address.city')
Here is my feature file , which just loads the json file and wants to iterate over the same
Background:
* def kittens = read('../json/test.json')
Scenario Outline: cat name: <name>
* print <name>
Examples:
| name |
| kittens |
Here is the output
[
{
"name": "Bob"
},
{
"name": "Wild"
},
{
"name": "Nyan"
},
{
"name": "Keyboard"
},
{
"name": "LOL"
},
{
"name": "Ceiling"
}
]
As per my understanding this should run 7 times and give me individual variable values , But its running only once and giving me full json as output .
Let me know if I am missing anything.
You are passing the list/array with a variable name in it, it will run only once as it interprets your entire json data as single variable name.
you could have noted it printed the entire data in your test.json
once, as it acted as normal scenario outline.
You should pass the array directly as below to make it as dynamic scenario outline.
Feature: Dynamic Scenario Outline
Background:
* def kittens = read('../json/test.json')
Scenario Outline: cat name: <name>
* print <name>
Examples:
| kittens |
For dynamic scenario outline, the variables <name> will actually derived from your json, if there is key in your json as "name". Not as the header of the list in Examples:.
Karate docs- Dynamic Scenario Outline
#Babu Sekaran. It was not priting cat names as used as above.
It was iterating number of times but not printing anything. Then i used * print '' means included quotes. then it started printing cat names.
Feature: Dynamic Scenario Outline
Background:
* def kittens = read('test.json')
Scenario Outline: cat name: <name>
* print '<name>'
Examples:
| kittens |
I am trying to shrink several chunks of similar code which looks like:
- ... multiple things is going here
register: list_register
- name: Generating list
set_fact: my_list="{{ list_register.results | map(attribute='ansible_facts.list_item') | list }}"
# the same code repeats...
The only difference between them is list name instead of my_list.
In fact, I want to do this:
set_fact:
"{{ some var }}" : "{{ some value }}"
I came across this post but didn't find any answer here.
Is it possible to do so or is there any workaround?
take a look at this sample playbook:
---
- hosts: localhost
vars:
iter:
- key: abc
val: xyz
- key: efg
val: uvw
tasks:
- set_fact: {"{{ item.key }}":"{{ item.val }}"}
with_items: "{{iter}}"
- debug: msg="key={{item.key}}, hostvar={{hostvars['localhost'][item.key]}}"
with_items: "{{iter}}"
The above does not work for me. What finally works is
- set_fact:
example_dict: "{'{{ some var }}':'{{ some other var }}'}"
Which is in the end obvious. You construct a string (the outer double quotes) which is then interpreted as a hash. In hashes key and value must be single quotes (the inner single quotes around the variable replacements). And finally you just place your variable replacements as in any other string.
Stefan
As of 2018, using ansible v2.7.1, the syntax you suggest in your post works perfectly well.
At least in my case, I have this in role "a" :
- name: Set fact
set_fact:
"{{ variable_name }}": "{{ variable_value }}"
And that in role "b" :
- debug:
msg: "variable_name = {{ variable_name }}"
And execution goes :
TASK [role a : Set fact] *******************************************************
ok: [host_name] => {
"ansible_facts": {
"variable_name": "actual value"
},
"changed": false
}
...
TASK [role b : debug] **********************************************************
ok: [host_name] => {}
MSG:
variable_name = actual value
- set_fact: '{{ some_var }}={{ some_value }}'
It creates a string of inline module parameter expression by concatenating value of some_var (fact name), separator = and value of some_value (fact value).
- set_fact:
var1={"{{variable_name}}":"{{ some value }}"}
This will create a variable "var1" with your dynamic variable key and value.
Example: I used this for creating dynamic tags in AWS Autoscaling group for creating kubernetes tags for the instances like this:
- name: Dynamic clustertag
set_fact:
clustertag={"kubernetes.io/cluster/{{ clustername }}":"owned"}
- name: Create the auto scale group
ec2_asg:
.
.
.
tags:
- "{{ clustertag }}"
Beware of a change in 2.9 – the behaviour changed rendering all the answers invalid. https://github.com/ansible/ansible/issues/64169
I have an array:
[
{
"AssetId": 14462955,
"Name": "Cultural Item"
},
{
"AssetId": 114385498,
"Name": "Redspybot"
},
{
"AssetId": 29715011,
"Name": "American Cowboy"
},
{
"AssetId": 98253651,
"Name": "Mahem"
}
]
I would like to loop through each object in this array, and pick out the value of each key called AssetId and output it.
How would I do this using jq for the command line?
The command-line tool jq writes to STDOUT and/or STDERR. If you want to write the .AssetId information to STDOUT, then one possibility would be as follows:
jq -r ".[] | .AssetId" input.json
Output:
14462955
114385498
29715011
98253651
A more robust incantation would be: .[] | .AssetId? but your choice will depend on what you want if there is no key named "AssetId".
You can also do it via this command.
jq ".[].AssetId" input.json
if array like be that which is in my case
{
"resultCode":0,
"resultMsg":"SUCCESS",
"uniqueRefNo":"111222333",
"list":[
{
"cardType":"CREDIT CARD",
"isBusinessCard":"N",
"memberName":"Bank A",
"memberNo":10,
"prefixNo":404591
},
{
"cardType":"DEBIT CARD",
"isBusinessCard":"N",
"memberName":"Bank A",
"memberNo":10,
"prefixNo":407814
},
{
"cardType":"CREDIT CARD",
"isBusinessCard":"N",
"memberName":"Bank A",
"memberNo":10,
"prefixNo":413226
}
]
}
you can get the prefixNo with below jq command.
jq ".list[].prefixNo" input.json
For more specific case on array iterating on jq you can check this blogpost
you have a couple of choices to do the loop itself. you can apply peak's awesome answer and wrap a shell loop around it. replace echo with the script you want to run.
via xargs
$ jq -r ".[] | .AssetId" input.json | xargs -n1 echo # this would print
14462955
114385498
29715011
98253651
via raw loop
$ for i in $(jq -r ".[] | .AssetId" input.json)
do
echo $i
done
14462955
114385498
29715011
98253651
An alternative using map:
jq "map ( .AssetId ) | .[]"
For your case jq -r '.[].AssetId' should work
You can also use online JQ Parser : https://jqplay.org/
If you want to loop through the each value then can use below :
for i in $(echo $api_response | jq -r ".[].AssetId")
do
echo echo $i
done
I'm using the Instagram API to get the number of people who follow a given account as follows.
$follow_info = file_get_contents('https://api.instagram.com/v1/users/477644454/followed-by?access_token=ACESS_TOKEN&count=-1');
$follow_info = #json_decode($follow_info, true);
This returns a set of 50 results. They do have a next_url key in the array, but it becomes time consuming to keep on going to the next page of followers when dealing with tens of thousands.
I read on StackOverflow that setting the count parameter to -1 would return the entire set. But, it doesn't seem to...
Instagram limits the number of results returned in their API for all sorts of endpoints, and they change these limits arbitrarily, without warning, presumably to handle server load.
Several similar threads exist:
Instagram API not fufilling count parameter
Displaying more than 20 photos in instagram API
Instagram API: How to get all user media? (see comments on answer too, -1 returns 1 less result).
350 Request Limit for Instagram API
Instagram API: How to get all user media?
In short, you won't be able to increase the maximum returned rows, and you'll be stuck paginating.
$follow_info = file_get_contents('https://api.instagram.com/v1/users/USER_ID?access_token=ACCES_TOKEN');
$follow_info = json_decode($follow_info);
print_r($follow_info->data);
And:
return
{
"meta": {
"code": 200
},
"data": {
"username": "i_errorw",
"bio": "A Casa do Júlio é um espaço para quem gosta da ideia de cuidar da saúde com uma alimentação saudável e saborosa.",
"website": "",
"profile_picture": "",
"full_name": "",
"counts": {
"media": 5,
"followed_by": 10,
"follows": 120000
},
"id": "1066376857"
}
}
if the APIs are optional
using the mobile version of twitter you can extract a full list of a followers for a designed target using a very simple bash script
the sleep time must me chosen carefully to avoid temporary ip block
the script can be executed by :
./scriptname.sh targetusername
content
#!/bin/bash
counter=1
wget --load-cookies ./twitter.cookies -O - "https://mobile.twitter.com/$1/followers?" > page
until [ $counter = 0 ]; do
cat page | grep -i "#" | grep -vi "fullname" | grep -vi "$1" | awk -F">" '{print $5}' | awk -F"<" '{print $1}' >> userlist
nextpage=$(cat page | grep -i "cursor" | awk -F'"' '{print $4}')
wget --load-cookies twitter.cookies -O - "https://mobile.twitter.com/$nextpage" > page
if [ -z $nextpage ]; then
exit 0
fi
sleep 5
done
it creates a file "userlist" including all usernames that follows the designed target one by line
PS: a cookies file filled with your credentials is necessary to wget to authenticate the requests
I personally suggest to use Wizboost for instagram automation. And the reason is that I have used this tool and my experience is amazing. It gave me a lot of followers. Now you don’t need to invest time in competing with other Instagram accounts as Wizboost has got your back for this, in fact for everything. You don’t need to do anything you can just relax and Wizboost will get you followers, likes and comments. And you can also schedule your posts too. So easy to use and still got lots of potential. I just love Wizboost for all the services it has.
$follow_info = file_get_contents('https://api.instagram.com/v1/users/USER_ID?access_token=ACCES_TOKEN');
$follow_info = json_decode($follow_info);
print_r($follow_info->data);
return
{
"meta": {
"code": 200
},
"data": {
"username": "casadojulio",
"bio": "A Casa do Júlio é um espaço para quem gosta da ideia de cuidar da saúde com uma alimentação saudável e saborosa.",
"website": "",
"profile_picture": "",
"full_name": "",
"counts": {
"media": 5,
"followed_by": 25,
"follows": 12
},
"id": "1066376857"
}
}