0

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

U880D
  • 8,601
  • 6
  • 24
  • 40
  • 2
    Please read the [how to ask](https://stackoverflow.com/help/how-to-ask) page, and pay especial attention to the [MCVE](https://stackoverflow.com/help/mcve) section. Ban the use of the phrase "it doesn't work" when asking for help, because it obviously didn't work or you wouldn't be asking for help -- what **did** happen versus what you **wanted** to happen? What debugging steps have you already tried to help yourself, and what was their outcome? – mdaniel Apr 24 '22 at 23:24
  • 3
    Can you furthermore provide some loglines from your `/tmp/log.file`? – U880D Apr 25 '22 at 05:40
  • 3
    To follow-up on @mdaniel comment, an other resource to help you [edit](/posts/71992457/edit) your question: ["Doesn't work is not helpful"](https://idownvotedbecau.se/itsnotworking/) – Zeitounator Apr 25 '22 at 07:42

1 Answers1

0

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
U880D
  • 8,601
  • 6
  • 24
  • 40
  • 1
    That is exactly what happened with my PB. If I declare the hex values manually like: vars: HEX: 0x626698A0 It works but I need to get the values from the log file which is very similar to your example. I can't use int(base=16) due to the old version of Jinja2 in my system. Is there a way to convert the values coming from the log file from AnsibleUnsafeText to int? Thanks, – user10761553 Apr 25 '22 at 14:45
  • @user10761553, regarding "_Is there a way to convert the values coming from the log file from `AnsibleUnsafeText` to `int`?_", I was already looking such in Ansible v2.9 but haven't find a direct solution yet. Except of updating Ansible or using `shell` module and call Python, using external Python scripts or [writing an own filter plugin](https://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html). Whereby writing an own [filter_plugin](https://stackoverflow.com/a/54026844/6771046) might be a quick and easy workaround. – U880D Apr 25 '22 at 14:52
  • @user10761553, as an example I've added a working filter plugins sample. – U880D Apr 25 '22 at 15:23