Ansible string split - ansible

I have a split function in ansible based on a delimiter. But only want to get the first occurance of the delimiter string and the rest as the second string.
string: "hello=abcd=def=asd"
string1= string.split("=")[0]
string2= string.split("=)[1..n] (This is what i missing)
How can i achieve this in ansible with string.split?

Q: "Get the first occurrence of the delimiter string and the rest as the second string."
A: Join the rest of the string again
arr: "{{ string.split('=') }}"
string1: "{{ arr[0] }}"
string2: "{{ arr[1:]|join('=') }}"
Optionally, set the maxsplit parameter to 1
arr: "{{ string.split('=', 1) }}"
string1: "{{ arr.0 }}"
string2: "{{ arr.1 }}"
Both options give the same result
string1: hello
string2: abcd=def=asd

Related

Ansible : loop on several set_fact with condition on current value of the loop

I would like to loop on hash of arrays and assign keys to 2 variables values depending on the current value of current element of array of the hash element, here is the code which is not accepted :
- name : put keys in var1 and var2 corresponding to their value
set_fact:
var1: "{{ item[0].key }}"
when: var1 == item[1]
set_fact:
var2: "{{ item[0].key }}"
when: var2 == item[1]
with_subelements:
- "{{ my_hash | dict2items }}"
- value
I wonder if I don't have to put a one-line condition after var1: and var2: with some %if but I don't know where this syntax come from.

Create a string from dictionary

I want to generate a string "key=value key=value ..." from this dictionary
command:
chain: dstnat
action: dst-nat
to-addresses: blaah
How can I achieve something like that in Ansible?
string = ""
for key, value in dict.items:
string += f'{key}={value} '
For example
- debug:
msg: "{{ string }}"
vars:
command:
chain: dstnat
action: dst-nat
to-addresses: blaah
string: "{{ command.keys()|list|
zip(command.values()|list)|
map('join', '=')|
join(' ') }}"
gives
msg: chain=dstnat action=dst-nat to-addresses=blaah

Json_query filter in Ansible

I cannot manage to make json_query work, even with the simplest examples.
I have a fact old_new_nodes like:
ok: [localhost] => {
"msg": [
{
"id_new": 2430,
"id_old": 2263
},
{
"id_new": 2431,
"id_old": 2283
}
]
}
I want to save the id_new parameter whenever the id_old is equal to a certain value.
I do:
- name: Get id of the new node
set_fact:
new_node_id: "{{ (old_new_nodes | first) |json_query('[?id_old==original_node.id].id_new') }}"
I have checked that original_node.id is 2263 so the expected result is 2430.
Moreover, I have tried without the first and I still get [] as a result
A literal in JMESPath expression must be quoted. See Grammar
list-filter-expr = expression comparator expression
comparator = "<" / "<=" / "==" / ">=" / ">" / "!="
expression =/ "*" / multi-select-list / multi-select-hash / literal
literal = "`" json-value "`"
Unquoted literal causes the error bellow
- debug:
msg: "{{ old_new_nodes|json_query('[?id_old == 2263].id_new') }}"
msg: |-
JMESPathError in json_query filter plugin:
invalid token: Parse error at column 12, token "2263" (NUMBER), for expression:
"[?id_old == 2263].id_new"
^
The query works as expected if you quote the literal
- debug:
msg: "{{ old_new_nodes|json_query('[?id_old == `2263`].id_new') }}"
gives
msg:
- 2430
If you want to put the searched value into a variable simplify the quotation of the query and put it into a variable too. The task below gives the same result
- debug:
msg: "{{ old_new_nodes|json_query(query) }}"
vars:
id: 2263
query: '[?id_old == `{{ id }}`].id_new'
It's possible to iterate the list, e.g.
- debug:
msg: "{{ old_new_nodes|json_query(query) }}"
loop: "{{ old_new_nodes|map(attribute='id_old')|list }}"
vars:
query: '[?id_old == `{{ item }}`].id_new'
gives
msg:
- 2430
msg:
- 2431
It'd be better to convert the list to a dictionary if you have to search it repeatedly, e.g.
- set_fact:
old_new: "{{ old_new_nodes|
items2dict(key_name='id_old', value_name='id_new') }}"
gives
old_new:
2263: 2430
2283: 2431
This would make the searching both trivial and fast.

ansible how to get last 2 digit of number

I have question about how to convert a digit to string and then get last 2 number using filter
For string, it's easy to use like:
vars:
string_1: 'abcd'
number_1: 1234
For string, it's easy:
"{{ string_1[-2:] }}"
But for number then i have to convert to string first but it failed while templating.
"{{ number_1 | string | [-2:] }}
How can I achieve this in single line code?
Close the conversion in parenthesis. The index has higher precedence compared to the filter. (And index can't be used as a filter, of course).
msg: "{{ (number_1|string)[-2:] }}"
The only difference is that modulus % returns an integer. The tasks
- debug:
msg: "{{ (number_1 % 100)|type_debug }}"
- debug:
msg: "{{ (number_1|string)[-2:]|type_debug }}"
give
"msg": "int"
"msg": "str"
You may use a modulus trick here:
{{ number_1 % 100 }}
The modulus dividing by 100 should yield the final two digits of any number input.

Splitting a values as list from a string using ansible filter

How to convert the above string to the list of comma separated strings using ansible filter.I need like this var2 , so that i can loop it and use those values.
Expected:
var2: [arn:aws:sds:ABCDEFGHI123456, arn:aws:sds:HRTYUIOPE89012345]"
Input:
var1:"arn:aws:sds:ABCDEFGHI123456arn:aws:sds:HRTYUIOPE89012345"
thansk!!!
Something like this should work:
- name: play1
hosts: all
vars:
x: "arn:aws:sds:ABCDEFGHI123456arn:aws:sds:HRTYUIOPE89012345"
tasks:
- name: task1
debug:
msg: "arn:{{ item }}"
with_items: "{{ x.split('arn:') }}"

Resources