How can I lookup properties in a slurped file? - ansible

According to the ansible documentation, I can use slurp to read a remote file.
I have a java properties file on a remote host that I want to slurp so I did:
- name slurp xyz properties
slurp:
src: /some/path/on/the/remote/my.properties
register: myprops
- debug:
msg: "{{ myprops['content'] | b64decode }}"
If I do that I get the content.
Now I want to use that conent in ansible. E.g. through a lookup. Something like this:
{{lookup('somePropertyInPropertiesFile', myprops['content'])}}
But this doesn't work since the lookup module only allows lookup in files.
How can I pass the slurped file to the lookup?
I'm using ansible 2.9.9

Given ansible lookups work on the control host, you can also get a file from remote to local using fetch module. Then use ini lookup to read a specific property from the properties file.
I couldn't test the code but something like below should work.
- name: Fetch my properties
fetch:
src: /some/path/on/the/remote/my.properties
dest: /tmp/
flat: yes
- debug:
msg: "content is {{ lookup('ini', 'content type=properties file=/tmp/my.properties') }}"
flat: yes will copy the file under /tmp without creating a dir with hostname in the given destination dir which is the default behavior. This might be useful if you have a single host or do not care if the file gets overwritten.

The answer of Moon is correct, but I want to add more details about java property files.
It seems that ansible can only hanlde simple java property files like:
user.name=robert
user.pass=somerandompassword
But the java properties file format also allowes values to span serveral lines, e.g.
targetCities=\
Detroit,\
Chicago,\
Los Angeles
When you have entries like this, ansible doesn't parse them correctly. Ansible's result is:
ok: [..............] => {
"msg": "content is \\\nDetroit,\\\nChicago,\\\nLos Angeles"
}
But the java Properties documentation say:
Properties are processed in terms of lines. There are two kinds of line, natural lines and logical lines. A natural line is defined as a line of characters that is terminated either by a set of line terminator characters (\n or \r or \r\n) or by the end of the stream. A natural line may be either a blank line, a comment line, or hold all or some of a key-element pair. A logical line holds all the data of a key-element pair, which may be spread out across several adjacent natural lines by escaping the line terminator sequence with a backslash character .
Thus
targetCities=\
Detroit,\
Chicago,\
Los Angeles
should be equivalent to
targetCities=Detroit,Chicago,Los Angeles
which is not the case as explained above.
EDIT
Sadly some property files, like tomcat's catalina.properties, can not be parsed at all.
fatal: [..............]: FAILED! => {"msg": "An unhandled exception occurred while running
the lookup plugin 'ini'. Error was a <class 'ConfigParser.ParsingError'>, original
message: File contains parsing errors: <???>\n\t[line 35]: u'org.apache.jasper.,org.apache.naming.,org.apache.tomcat.\\r\\n'\n\t[line 110]:
...

Related

Rename file using ansible playbook on windows [duplicate]

This question already has answers here:
How to rename/move a file on a remote windows host with ansible?
(4 answers)
Closed last month.
Looking at rename file using ansible playbook on windows with below option, but is leading to below error.
Tried few mix match with " and ' but no luck in getting it sorted.
Kindly suggest correct way of handling on windows machine.
- name: Rename foo.bar
win_command: 'cmd.exe /c rename 'C:\windows\some\path\foo.bar' foo.zzz'
Error its leading to is per below :
^ here This one looks easy to fix. There seems to be an extra unquoted colon in the line and this is confusing the parser. It was only expecting to find one free colon. The solution is just add some quotes around the colon, or quote the entire line after the first colon.
For instance, if the original line was:
copy: src=file.txt dest=/path/filename:with_colon.txt
It can be written as:
copy: src=file.txt dest='/path/filename:with_colon.txt'
Or:
copy: 'src=file.txt dest=/path/filename:with_colon.txt'
Looks like there is no viable option with copy on local machine using win_command.
Ended up implementing same with copy to different file name with win_copy & removing original file with win_file to achieve effective result of renaming file!
- name: Rename foo.bar
win_copy:
src: C:\windows\some\path\foo.bar
dest: C:\windows\some\path\foo.zzz
remote_src: yes
- win_file:
path: C:\windows\some\path\foo.bar
state: absent

How can I parse part of a URL from an variable?

I'm trying to write a playbook that will go and download the version of ombi I supply on the command line as a variable, then parse part of it so I can rename the file and keep a local copy of it. Then gunzip then untar then stop the service overwrite the existing app, then restart the service.
I've written several other playbooks but parsing this part out has me stumped.
So if say this was the URL
https://github.com/Ombi-app/Ombi/releases/download/v4.32.0/linux-x64.tar.gz
I want to extract the 4.32.0 out of that url. So my playbook run line might be something like:
ansible-playbook updateombi.yml --extra-vars "ombi_release=https://github.com/Ombi-app/Ombi/releases/download/v4.32.0/linux-x64.tar.gz"
I'm assuming I would declare a var like:
ombi_version: "{{ ombi_release | urlsplit('path') }}"
but the urlsplit is what's got me stumped. Anyone able to throw me a bone?
I'm trying to write a playbook that will go and download the version of Ombi I supply on the command line as a variable ...
To do so you could simply provide the version number only
ansible-playbook updateombi.yml --extra-vars "ombi_release=4.32.0"
and construct the URL and filename afterwards within your playbook
url: "https://github.com/Ombi-app/Ombi/releases/download/v{{ ombi_release }}/linux-x64.tar.gz"
dest: /tmp/linux-x64-v{{ ombi_release }}.tar.gz
since they don't have a variable part except the version number. By doing this there would be no need for
... then parse part of it so I can rename the file ...

How to make ansible with_fileglob work recursively for all subdirectories or alternative?

I am using Ansible and have a directory structure like the example below:
configs
something
files
1.conf
2.conf
// and so on
Those files are templates and I am using Ansible to parse these templates and create them automatically in the destination server.
My problem is that with_fileglob is working only of first level directory and cannot seem to enable some recursive mode.
I have
- name: "Apply templates"
template:
src: "{{ item }}"
dest: "{{ item | replace('.j2', '') }}"
with_fileglob:
- "{{ user_configs_path }}/*"
by the way user_configs_path=configs exists and all good here.
The above does nothing.
If I add something under configs, example configs/blabla.j2 and re-run the playbook it is parsed and copied fine.
So seems somehow that the directories are not searched recursively.
I am not limited to only use the fileglob solution so feel free to suggest anything I can learn to reach my goal.
Basically I want to recursively iterate all directories for files only, and in a loop apply the template module to them and create them in remote server
Thank you
Regarding
My problem is that with_fileglob is working only of first level directory and cannot seem to enable some recursive mode.
and according the documentation fileglob
Matches all files in a single directory, non-recursively, that match a pattern. It calls Python’s “glob” library.
for
How to make Ansible with_fileglob work recursively for all subdirectories
one would need to enhance the module code.
Regarding
Basically I want to recursively iterate all directories for files only, and in a loop apply the template module to them and create them in remote server
as solution and depending on your requirements and what you try to achieve, you could use just
find module – Return a list of files based on specific criteria, in example .conf files. It works with parameter recursive: true and will you provide with a list of full path(s) over which you can loop after.
shell module – Execute shell commands on targets like find and register: result
Similar Q&A
Ansible playbook to find out specific files in sub directories
Ansible: How to find latest files from a directory recursively?
How to search for files containing a particular text with Ansible?

ansible_wait_for a file containing a name pattern

How can I use ansible wait_for module and search regex to wait for a file containing a certain naming format. For instance, a file can have the number within its name change from time to time as in "waitfor1234.txt" or "waitfor5678.txt". I would like to know how I can implement a solution like "waitfor*.txt" in ansible wait_for module. Thanks
#Below code doesn't work
name: Wait for file matching waitfor*.txt is present
wait_for:
path: /tmp/foo/waitfor*.txt

How do I use an encrypted variable (ansible_ssh_pass) in an INI file?

I am reading this page and if I drop the following text in an file in the Inventory folder :
[vyos:vars]
ansible_connection=network_cli
ansible_network_os=vyos
ansible_user=my_vyos_user
ansible_ssh_pass= !vault |
$ANSIBLE_VAULT;1.2;AES256;my_user
66386134653765386232383236303063623663343437643766386435663632343266393064373933
3661666132363339303639353538316662616638356631650a316338316663666439383138353032
63393934343937373637306162366265383461316334383132626462656463363630613832313562
3837646266663835640a313164343535316666653031353763613037656362613535633538386539
65656439626166666363323435613131643066353762333232326232323565376635
I am getting this error message
[WARNING]: * Failed to parse /home/myuser/Ansible/Inventory/pwdtest
with ini plugin: /home/cristi/Ansible/Inventory/pwdtest:9: Expected
key=value, got: $ANSIBLE_VAULT;1.2;AES256;my_user
I think the issue comes down to assigning a multiline string to a variable in an INI file
Does anybody have any idea how I can use this?
I can use the above in a YAML file format but I would like to keep consistency and use YAML everywhere
How do I use an encrypted variable (ansible_ssh_pass) in an INI file?
You can't.
The documentation page you linked to, seems to be blatantly wrong.
For a start, !vault tag and | character in the output of ansible-vault belong to YAML syntax and there is no way they could ever work in an INI-format inventory.
It seems also, that the function AnsibleVaultEncryptedUnicode, which decrypts the value, is called only from the YAML parser, so there is no way to modify the value (like single line, no tag) in the INI-format inventory.
You can either:
write your inventory in YAML, whole or a part of it, if you use a directory and split the inventory into multiple files
create a directory group_vars in the same directory as your inventory file and put a file vyos.yml inside with the following content:
ansible_connection: network_cli
ansible_network_os: vyos
ansible_user: my_vyos_user
ansible_ssh_pass: !vault |
$ANSIBLE_VAULT;1.2;AES256;my_user
66386134653765386232383236303063623663343437643766386435663632343266393064373933
3661666132363339303639353538316662616638356631650a316338316663666439383138353032
63393934343937373637306162366265383461316334383132626462656463363630613832313562
3837646266663835640a313164343535316666653031353763613037656362613535633538386539
65656439626166666363323435613131643066353762333232326232323565376635

Resources