I have a simple Ansible playbook that reads a HEX value (epoch time) from a log file then I would like to get the readable format using strftime
but I can't get it to work.
Playbook example:
- debug:
msg:
- "Time = {{ '%Y-%m-%d %H:%M:%S' | strftime( item ) }}"
with_lines: cat /tmp/log.file
I found that the returned value is defined as AnsibleUnsafeText
, I tried to convert it to an integer but, still, it doesn't work.
Ansible version: 2.9
From your description I understand that you like to convert strings like 626698A0
into seconds. Lets assume there is hex.log
file with Unix HEX timestamps
626698A0
626698B0
626698C0
626698D0
626698E0
626698F0
and a test playbook like
---
- hosts: localhost
become: false
gather_facts: true
vars:
HEX: 0x626698A0
HEX_STRING: '626698A0'
tasks:
- name: Show vars type
debug:
msg:
- "{{ HEX }} is {{ HEX | type_debug }} and HEX {{ '%#X' % HEX }}"
- "{{ HEX_STRING }} is {{ HEX_STRING | type_debug }}"
- name: Show values type
debug:
msg: "{{ item }} is {{ item | type_debug }}"
with_lines: cat hex.log
then it would result into an output of
TASK [Show vars type] ******************
ok: [localhost] =>
msg:
- 1650890912 is int and HEX 0X626698A0
- 626698A0 is AnsibleUnicode
TASK [Show values type] *************
ok: [localhost] => (item=626698A0) =>
msg: 626698A0 is AnsibleUnsafeText
ok: [localhost] => (item=626698B0) =>
msg: 626698B0 is AnsibleUnsafeText
ok: [localhost] => (item=626698C0) =>
msg: 626698C0 is AnsibleUnsafeText
ok: [localhost] => (item=626698D0) =>
msg: 626698D0 is AnsibleUnsafeText
ok: [localhost] => (item=626698E0) =>
msg: 626698E0 is AnsibleUnsafeText
ok: [localhost] => (item=626698F0) =>
msg: 626698F0 is AnsibleUnsafeText
As of Ansible v2.10 it should be possible to use
"{{ HEX_STRING | int(base=16) }}"
whereby in Ansible v2.9 one would get an error
TASK [Show values type] ************************************************************************************
fatal: [localhost]: FAILED! =>
msg: 'Unexpected templating type error occurred ...: do_int() got an unexpected keyword argument ''base'''
Further Documentation and Q&A
Regarding "Is there a way to convert the values coming from the log file from AnsibleUnsafeText
to int
?" and as a workaround in Ansible v2.9, it might be possible write an own filter plugin similar to other solutions here, in example version_sort. It would just be necessary to use an approach like in Convert HEX string to int in Python instead.
After a short test with a hex2int.py
filter plugin
#!/usr/bin/python
class FilterModule(object):
def filters(self):
return {
'hex2int': self.hex2int,
}
def hex2int(self, hexString):
intValue = int(hexString, 16)
return intValue
which one need to place under the path specified in ansible.cfg
and filter_plugins =
, I found it working
- name: Show int values and type
debug:
msg: "{{ item | hex2int }} is {{ item | hex2int | type_debug }}"
with_lines: cat hex.log
and resulting into an output of
TASK [Show int values and type] *************
ok: [localhost] => (item=626698A0) =>
msg: 1650890912 is int
ok: [localhost] => (item=626698B0) =>
msg: 1650890928 is int
ok: [localhost] => (item=626698C0) =>
msg: 1650890944 is int
ok: [localhost] => (item=626698D0) =>
msg: 1650890960 is int
ok: [localhost] => (item=626698E0) =>
msg: 1650890976 is int
ok: [localhost] => (item=626698F0) =>
msg: 1650890992 is int