Remove symbols from ansible stdout_lines in file with Ansible - ansible

A have the line in file acounts.list
['# name prueba7#prueba7.com', 'zimbraIsDelegatedAdminAccount: TRUE']
I would like to remove ['# name, all ' and '] What would the result be prueba7#prueba7.com, zimbraIsDelegatedAdminAccount: TRUE
I tried to create task to remove first ['# name
- lineinfile:
dest: /home/acounts.list
state: absent
regexp: "^\[\'\#\sname\s"
... but i got error. Could you please help with solution? Thank you.

use replace instead:
- name: replace
ansible.builtin.replace:
path: /home/acounts.list
regexp: "['\\[\\]]|# *name *"
replace: ''
you could write too: regexp: '[''\[\]]|# *name *'
['\\[\\]] means replace all ' or [ or ] (or == [])
so as [ and ] are special char, you ahve to protect by \ with " you have to protect \ too by another \ (not needed when surrounded by ')
| means or and the other expression is # *name * * means zero or more space

Related

json_query filter with bug?

I have a situation.
When I try to use json_query filter in ansible-playbook return this error:
{"msg": "Error in jmespath.search in json_query filter plugin:\ninvalid literal for int() with base 10: '-'"}
I solve this with replace ('-','_') filter.
Have I other way to solve this?
complete code here:
---
# tasks file for mpls-lsp
- name: Colete informações do protocolo osfp
junipernetworks.junos.junos_rpc:
rpc: get-ospf-neighbor-information
output: json
register:
_data
- name: Aplica as configurações padrão em RT-BRAS.*
ansible.builtin.debug:
var: item
loop: "{{ _data2 | json_query('ospf_neighbor_information[0].ospf_neighbor[*].neighbor_address[0].data') }}"
vars:
_data2: "{{ _data.output | replace ('-','_') }}"
when: "'device_roles_bras' in {{ group_names }}"
TL;DR
"ospf-neighbor-information"[0]."ospf-neighbor"[*]."neighbor-address"[0].data
Full Story
I solve this with replace ('-','_') filter.
This is actually quite dangerous as this replaces dashes for underscores absolutely everywhere in the input, identifiers and values. But if we now look at your resulting jmespath expression
json_query('ospf_neighbor_information[0].ospf_neighbor[*].neighbor_address[0].data')
we can infer that all your identifiers where previously using - as a separator
In the above expression, you are using unquoted identifiers. If you look at jmespath specification for identifiers, you will see that unquoted ones cannot contain dashes.
identifier = unquoted-string / quoted-string
unquoted-string = (%x41-5A / %x61-7A / %x5F) *( ; A-Za-z_
%x30-39 / ; 0-9
%x41-5A / ; A-Z
%x5F / ; _
%x61-7A) ; a-z
quoted-string = quote 1*(unescaped-char / escaped-char) quote
unescaped-char = %x20-21 / %x23-5B / %x5D-10FFFF
escape = %x5C ; Back slash: \
quote = %x22 ; Double quote: '"'
escaped-char = escape (
%x22 / ; " quotation mark U+0022
%x5C / ; \ reverse solidus U+005C
%x2F / ; / solidus U+002F
%x62 / ; b backspace U+0008
%x66 / ; f form feed U+000C
%x6E / ; n line feed U+000A
%x72 / ; r carriage return U+000D
%x74 / ; t tab U+0009
%x75 4HEXDIG ) ; uXXXX U+XXXX
So if your identifiers contain dashes, you must quote them (and note that quoting identifiers is made with double-quotes)
You can transform your json_query task as below to make it work on your original data (you might have to adapt as I didn't have your original structure and had to guess a bit...)
- name: Aplica as configurações padrão em RT-BRAS.*
ansible.builtin.debug:
var: item
loop: "{{ _data.output | json_query(query) }}"
vars:
query: >-
"ospf-neighbor-information"[0]."ospf-neighbor"[*]."neighbor-address"[0].data
when: "'device_roles_bras' in {{ group_names }}"

lineinfile/regexp/line: why line at the end of file?

I don't understand how lineinfile works, I use:
- name: "configure"
lineinfile:
path: /etc/apt/apt.conf.d/50unattended-upgrades
regexp: '^\/\/ "\${distro_id}:\${distro_codename}-updates";'
line: ' "${distro_id}:${distro_codename}-updates";'
state: present
And I expect that line in file will be uncommented:
// "${distro_id}:${distro_codename}-updates";
instead of this, this line stay as it is, but at the end of file,
I see:
"${distro_id}:${distro_codename}-updates";
so "match" happens, but why there is new line at the end of file instead of replace?
Your regexp does not escape all of the special symbols and therefore there is no match which causes the addition of the new line instead of the replacement. Curly braces should be escaped, according to Python's re module documentation.
This task works as expected on my Ubuntu 18.04 server.
- name: "configure"
lineinfile:
path: /etc/apt/apt.conf.d/50unattended-upgrades
regexp: '^//\s+"\$\{distro_id\}:\$\{distro_codename\}-updates";'
line: ' "${distro_id}:${distro_codename}-updates";'
state: present
Diff
-// "${distro_id}:${distro_codename}-updates";
+ "${distro_id}:${distro_codename}-updates";
There must be other problem. The code works as expexted
shell> diff 50unattended-upgrades 50unattended-upgrades.orig
1c1
< "${distro_id}:${distro_codename}-updates";
---
> // "${distro_id}:${distro_codename}-updates";

Test a substring with special character in a list

I have a list with some application landscape names and I have to look for an specific application with special characters in Jinja2
landscape_list: ["cmdb:app1 landscape", "cmdb:app2 (ex app3) landscape",
"cmdb:app4 landscape"]
app_to_look: "app2 (ex app3)"
I'm trying to use this code to test the list:
{{landscape_list | select('search',land_key) | list | count > 0}}
But I'm always getting 0 when I tried to test "app2 (ex app3)".
I think this problem is related with special characters like ().
Is it possible to look into a list for that specific application in jinja2?
Thanks
Q: "This problem is related to special characters like ()."
A: Yes. The parenthesis must be escaped in the regex. For example
- set_fact:
land_key: 'app2 \(ex app3\)'
- debug:
msg: "{{ landscape_list|select('search', land_key)|list }}"
- debug:
msg: "{{ landscape_list|select('search', land_key)|list|length }}"
- debug:
msg: One or more items match the searched pattern.
when: landscape_list|select('search', land_key)|list|length > 0
give
"msg": [
"cmdb:app2 (ex app3) landscape"
]
"msg": "1"
"msg": "One or more items match the searched pattern."
I end up using a similar method. Instead of using search, I used contains as a search method
{{completed_list | select('contains',solution_search) | list | count > 0}}
solution_search contains the full name of what I'm looking.
{%-set solution_search = env_key ~' '~env_server_key ~' TEST'-%}
Where env_key is the application name that can contain special characters and env_server_key is the application environment.

Jenkins Job Builder tries to expand parameter in a text field

I'm having some issues with a Jenkins Job Builder YAML file which contains an attribute (message-content) with "{}" characters in it:
- job-template:
id: senderjob
name: '{job-prefix}{id}'
command: 'echo "executed with $PARAMETER"'
type: freestyle
properties:
- ownership:
enabled: true
owner: user1
- build-discarder:
num-to-keep: 100
parameters:
- string:
name: PARAMETER
default: 'param'
description: 'default parameter for message.'
# template settings
builders:
- shell: '{command}'
publishers:
- ci-publisher:
override-topic: VirtualTopic.abcd.message
message-type: 'Custom'
message-properties: |
release-name=$PARAMETER
PARAMETER=$PARAMETER
message-content: '{"release-name" : "1.0"}'
The error reported is:
jenkins_jobs.errors.JenkinsJobsException: release-name parameter missing to format {release-name : 1.0}
So it looks like it's trying to expand "release-name" with a parameter.
So I have added it as parameter:
- string:
name: release-name
default: '1.0'
description: 'default parameter for release.'
It still reports the same error. Should I include the parameter somewhere else or escape it ? I couldn't find any YAML escape for "{}" characters though.
Any idea?
You should add the following to the configuration file
[job_builder]
allow_empty_variables = True
Link: https://jenkins-job-builder.readthedocs.io/en/latest/definition.html#job-template-1

yaml multi line syntax without newline to space conversion

I have something like this dictionary:
env: qat
target_host: >
{%if env in ['prd'] %}one
{%elif env in ['qat','stg'] %}two
{%else%}three
{%endif%}
when I print it I get:
ok: [localhost] => {
"var": {
"target_host": "two "
} }
So it is converting the \n at the end of the line to a space. Which is exactly what it is supposed to do. However in this case I am just trying to spread out the lines to make the structure of the if/else more readable and I don't want the extra space. It works as expected if I put it all on one line without the > but I would like to be able to make it multiline just so its easier to read.
I found this question
Is there a way to represent a long string that doesnt have any whitespace on multiple lines in a YAML document?
So I could do:
env: qat
target_host: "{%if env in ['prd'] %}one\
{%elif env in ['qat','stg'] %}two\
{%else%}three\
{%endif%}"
And that gives the desired result.
Is there anyway to accomplish this without cluttering it up even more?
In Jinja* you can strip whitespaces/newlines by adding a minus sign to the start/end of a block. This should do the trick:
env: qat
target_host: >
{%if env in ['prd'] -%}one
{%- elif env in ['qat','stg'] -%}two
{%- else -%}three
{%- endif%}
* Jinja 2 is the templating engine used by Ansible.
Maybe what you need is the | literal?
env: qat
target_host: |
{%if env in ['prd'] %}one
{%elif env in ['qat','stg'] %}two
{%else%}three
{%endif%}
This will not 'fold' newlines into spaces, as oposed to >

Resources