Ansible: 'regex_replace' removing every character starting with "#" - ansible

I have following registered variable with stdout and I want to remove every character starting with "#".
ok: [localhost] => {
"msg": [
"wazuh#4.3.10-4311"
]
}
Example: wazuh#4.3.10-4311 should become wazuh.

remove every character after "#"
---
- hosts: localhost
gather_facts: false
vars:
my_string: wazuh#4.3.10-4311
tasks:
- debug:
msg: "{{ my_string | regex_replace('#.*', '') }}"
Provides:
wazuh

One could also look at the use case as just interested in the left part of the #
delimitered string.
---
- hosts: localhost
gather_facts: false
vars:
my_string: wazuh#4.3.10-4311
tasks:
# For Ansible v2.9 and later
- name: Use of Python string method
debug:
msg: "{{ my_string.split('#') | first }}"
So not removing the part behind but only deliver the part before.
# For Ansible v2.10 and later
- name: Show left part with filter
debug:
msg: "{{ my_string | split('#') | first }}"

Also this solution it's working:
regex_replace('#.*$','')

Related

Jinja2 expression for split , replace and join

In Ansible playbooks, We have the variable 'dns_name: xyz.abc.pqr.*.com' where as we have one template file called es_config.yml there the value of cname should be (cname: .abc.pqr..com)
How can we write jinja2 expression for this ?
dns_name: xyz.abc.com (Or) xyz.abc.pqr.***.com
cname: *.abc.com (Or) .abc.pqr.**.com (We have to use variable of dns_name)
Playbook
- hosts: elastic-search-servers
gather_facts: true
vars:
es_admin_hostname: test.develop123.com
tasks:
- name: split string
set_fact:
cname: "{{ es_admin_hostname.split('.') }} | first | replace('*')"
- name: debug
debug:
msg: "{{ cname[1:] }} is dns name"
Required Output
*.develop123.com
just change your split by regex_replaces:
- name: split string
set_fact:
cname: "{{ es_admin_hostname| regex_replace('^[^\\.]+', '*') }}"
- name: debug
debug:
msg: "{{ cname }} is dns name"
result:
ok: [localhost] => {
"msg": "*.develop123.com is dns name"
}
'^[^\\.]+' means trap all chars from beginning of string until i meet a dot and replace them by * (the \\ is needed because . is special char)

finding and setting new var from ansible_net_config

I'm trying to come up with a way to find a piece of text in a very long string. I'm using the ios_facts module to grab a Cisco config. I'm looking for the text below and want to set it as a new var. The 'ip nbar protocol-pack' portion will never change but the value after that will vary from node to node.
{{ ansible_net_config }} =
o ip source-route\n!\n!\nip nbar protocol-pack bootflash:pp-adv-isr4000-169.1-34-47.0.0.pack \n!\n!\n!\n!\nip nb
the value of ansible_net_config is much longer. I trimmed it down for sanity sake.
This is what I want the var set to:
ip nbar protocol-pack bootflash:pp-adv-isr4000-169.1-34-47.0.0.pack
Here is the code I'm working with. I don't know if I should keep trying regex_search or try json_query or something I'm not yet aware of.
---
- name: Cisco NBAR Test
connection: ansible.netcommon.network_cli
hosts: all
tasks:
- name: collect facts
cisco.ios.ios_facts:
gather_subset:
- config
- name: set vars
set_fact: config={{ ansible_net_config | regex_search('ip nbar protocol-pack') }}
#set_fact: config={{ ansible_net_config | community.general.json_query('*') }}
- name: show output
debug:
var: config
Any idea on how to do this?
Thanks,
I'd write the regexp like this:
set_fact: config="{{ ansible_net_config | regex_search('.*ip nbar protocol-pack.*') | trim }}"
- name: test
hosts: localhost
tasks:
- name: set vars
set_fact: config="o ip source-route\n!\n!\nip nbar protocol-pack bootflash:pp-adv-isr4000-169.1-34-47.0.0.pack \n!\n!\n!\n!\nip nb"
- name: regex vars
set_fact: result="{{ config | regex_search('.*ip nbar protocol-pack.*') | trim }}"
- name: show
debug:
var: result
result:
TASK [show] ***********************************************************************************************************************************************************************
ok: [localhost] => {
"result": "ip nbar protocol-pack bootflash:pp-adv-isr4000-169.1-34-47.0.0.pack"
}

using ansible variable in task conditonal

When I use an Ansible variable in the failed_when conditional, Ansible complains and fails by telling me that I cannot use Jinja2 expressions with failed_when.
Below snippet does not work:
vars:
var1: "var"
tasks:
- name: "sth"
raw: "anothersth"
register: status
failed_when: var1 in status.stdout
I want to use a regex in the above example and use variable var1 within a regex. This also fails.
I want to fail the task if var1 is repeated in the beginning and at the end of the stdout_lines. I was thinking something like this:
failed_when: regex("^{{var1}}/.*/{{var1}}$") in status.stdout
I wonder whether there is a way to achieve what I intend to do?
===============================================================
Exact play and the description:
Let me explain what I am trying to do:
run a command with "raw" module and register the stdout_lines.
iterate over a list of items, where list is a fact of current ansible host
use failed_when to search a pattern in the registered stdout and fail the task if it is not found
peers_underlay is a list defined in the host file:
peers_underlay:
- ip: "172.16.1.2"
- ip: "172.16.1.6"
This is the play:
- hosts: leaf-2, spine-1
gather_facts: no
tags: [ verify ]
vars:
bgp_underlay: "show ip bgp summary"
tasks:
- name: "underlay bgp test"
raw: "{{ bgp_underlay }}"
register: underlay_status
with_items: "{{ peers_underlay }}"
failed_when: not regex(".*/{{ item['ip'] }}/.*/Estab/.*") in underlay_status.stdout_lines
Q: "Fail the task if var1 is repeated in the beginning and at the end."
A: It's possible to test strings. For example, use regex
- hosts: localhost
vars:
my_stdout1: 'ABC dlkjfsldkfjsldkfj ABC'
my_stdout2: 'alkdjflaksdjflakdjflaksjdflaksdjflasj'
var1: 'ABC'
my_regex: '^{{ var1 }}(.*){{ var1 }}$'
tasks:
- debug:
msg: my_regex match my_stdout1
when: my_stdout1 is regex(my_regex)
- debug:
msg: my_regex match my_stdout2
when: my_stdout2 is regex(my_regex)
gives
"msg": "my_regex match my_stdout1"
The particular task sequence would be
vars:
var1: "var"
my_regex: '^{{ var1 }}(.*){{ var1 }}$'
tasks:
- name: "sth"
raw: "anothersth"
register: status
failed_when: status.stdout is regex(my_regex)

ansible vars_files and extra_vars to read input

looking to pass the dict to read a set of key value pairs based on the location. When values are hardcoded to the playbook, it works fine but calling through extra_vars giving an error message. Not sure even if it supports. appreciate, your thoughts and inputs.
ansible-playbook play3.yml -e '{"var1":"loc2"}' -vv
play3.yml
---
- name: testing
hosts: localhost
connection: local
gather_facts: no
vars_files:
- var_file.yml
tasks:
- debug:
msg: "{{ var1['first'] }}"
var_file.yml
---
loc1:
first: name1
last: name2
loc2:
first: python
last: perl
...
"Anything's possible in an animated cartoon." -Bugs Bunny
This playook:
---
- name: testing
hosts: localhost
connection: local
gather_facts: no
vars_files:
- var_file.yml
tasks:
- debug:
var: "{{ item }}.first"
with_items: "{{ var1 }}"
Gave me this output:
TASK [debug] **********************************************************************************************************************************
task path: /home/jack/Ansible/CANES/PLAYBOOKS/play3.yml:9
ok: [localhost] => (item=None) => {
"loc2.first": "python"
}

Splitting a debug msg to extract a certain part of the msg in ansible

So I need to take a particular part of my debug msg that I have in my playbook that goes like
---
- name: extract
shell: grep "ScriptAlias /.*/" /etc/httpd/conf/httpd.conf
register: st
- debug:
msg: "{{ st.stdout_lines | map('trim') | list }}"
and that playbook prints out when ran
ok: [52.61.71.178] => {
"msg": [
"ScriptAlias /cgi-bin/ \"/var/www/cgi-bin/\""
]
}
So what I need to do is put that msg "ScriptAlias /cgi-bin/ \"/var/www/cgi-bin/\""in an array and extract the last element in that which is the "/var/www/cgi-bin/"
What is the best approach in extracting the last element in my msg to where it can get only the "/var/www/cgi-bin/"?
Try as below. Only added regex_replace (Answer From Valdimir) to get exactly what you want.
- hosts: localhost
vars:
lines:
- "ScriptAlias /cgi-bin/ \"/var/www/cgi-bin/\""
tasks:
- debug:
msg: "{{ item.split(' ')[2] | regex_replace('\"', '') }}"
loop: "{{ lines }}"
Output should be exactly as ::
"msg": "/var/www/cgi-bin/"
The split method works fine. Output is abridged.
> ansible-playbook split_test.yml
"msg": "\"/var/www/cgi-bin/\""
split_test.yml
- hosts: localhost
vars:
lines:
- "ScriptAlias /cgi-bin/ \"/var/www/cgi-bin/\""
tasks:
- debug:
msg: "{{ item.split(' ')[2] }}"
loop: "{{ lines }}"

Resources