Formatting date in Ansible

In another thread, I was explaining how I’m getting a user’s information from our IPA server. I believe that the password expiration is already in a datetime format. I’d like to display it to the user via email in a more standard format.

For example, let’s say that the user’s password expiration date/value is 20210715141027Z. In the email I send out to them, I’d like to show 07/15/2021. Then, I’d like to calculate the date where their account will be automatically disabled, which should be 90 days after the expiration date. But I can’t figure out how to add 90 days to the expiration date.

Here’s part of my playbook for reference:

  • name: Set Disabled Users fact
    set_fact:
    disabled_users: “{{ user_show.results | json_query(‘[*].json.result.result.{uid: uid[0], mail: mail[0], nsaccountlock: nsaccountlock, pwdexp: krbpasswordexpiration[0].datetime}’) | selectattr(‘pwdexp’,‘<’,cutoff_date) | selectattr(‘nsaccountlock’, ‘equalto’, False) | list }}”

  • name: Print disabled users
    debug:
    msg: “{{ item.uid }} / {{ item.mail }} / {{ item.pwdexp.format(‘%m/%d/%Y’) }}”
    loop: “{{ disabled_users }}”

Thanks,
Harry

For example

    - debug:
        var: _date90
      vars:
        _date: "{{ pwdexp[0:4] }}-{{ pwdexp[4:6] }}-{{ pwdexp[6:8] }}"
        _sec: "{{ (_date|to_datetime('%Y-%m-%d')).strftime('%s')|int
                  + 90 * 24 * 60 * 60 }}"
        _date90: "{{ '%Y-%m-%d'|strftime(_sec) }}"

gives

  _date90: '2021-10-13'

This can be simplified

        _sec: "{{ (pwdexp[0:8]|
                   to_datetime('%Y%m%d')).strftime('%s')|
                   int + 90 * 24 * 60 * 60 }}"
        _date90: "{{ '%Y-%m-%d'|strftime(_sec) }}"

So I’m trying this:

  • name: Print warning list users
    debug:
    msg: “{{ item.uid }} / {{ item.mail }} / {{ item.pwdexp }} / {{ (item.pwdexp[0:8]|to_datetime(‘%Y%m%d’)).strftime(‘%s’)|int + 90 * 24 * 60 * 60 }}”
    loop: “{{ warning_users }}”

And I’m getting this:

TASK [Print warning list users] ***********************************************************************************
ok: [ipaserver.example.comt] => (item={u’pwdexp’: u’20210715141027Z’, u’mail’: u’test.user1@example.com’, u’uid’: u’test.user1’, u’nsaccountlock’: False}) => {
“msg”: “test.user1 / test.user1@example.com / 20210715141027Z / 1634097600”
}

Any ideas?
Harry

So, you're starting from 15th July 2021 and adding 90 days, which comes to
13th October.

strftime('%s') will give you the Unix Epoch time, in this case 1634097600,
which is indeed the 13th October 2021.

Antony.

I get that, but I want to show it as 10/13/2021. How do I do that???

Thanks,
Harry

I would try strftime('%m/%d/%Y') provided you are happy with dates in the first
12 days of each month being highly ambiguous for an international audience.

Antony.

So I just tried this:

  • name: Print warning list users
    debug:
    msg: “{{ item.uid }} / {{ item.mail }} / {{ item.pwdexp }} / {{ (item.pwdexp[0:8]|to_datetime(‘%Y%m%d’)).strftime(‘%m/%d/%Y’)|int + 90 * 24 * 60 * 60 }}”
    loop: “{{ warning_users }}”

And it gives me this:

“msg”: “test.user1 / test.user1@example.com / 20210715141027Z / 7776000”

Thanks,
Harry

I suggest you change the format to year, month then day. This format sorts naturally when you use ls(1).
(The command in vi(1) is :!cp -p % %.211216 (or whatever is the current date).)

Mike

For example

- hosts: localhost
  vars:
    warning_users:
      - {uid: user1, mail: user1@example.com, pwdexp: 20210715141027Z}
      - {uid: user2, mail: user2@example.com, pwdexp: 20210716141027Z}
      - {uid: user3, mail: user3@example.com, pwdexp: 20210717141027Z}
  tasks:
    - debug:
        msg: "{{ item.uid }} /
              {{ item.mail }} /
              {{ item.pwdexp }} /
              {{ _date90 }}"
      loop: "{{ warning_users }}"
      vars:
        _sec: "{{ (item.pwdexp[0:8]|
                   to_datetime('%Y%m%d')).strftime('%s')|int
                  + 90 * 24 * 60 * 60 }}"
        _date90: "{{ '%Y-%m-%d'|strftime(_sec) }}"

gives

  msg: user1 / user1@example.com / 20210715141027Z / 2021-10-13
  msg: user2 / user2@example.com / 20210716141027Z / 2021-10-14
  msg: user3 / user3@example.com / 20210717141027Z / 2021-10-15

YYYY-MM-DD is the very useful European standard, and is also followed
by various useful RFC's, such as RFC 3339.Might I encourage ansible
users to follow that standard as closely as possibl?

    $ date --rfc-3339=seconds
    2021-12-16 10:58:09-05:00

It also preserves the offset from GMT, which the typical casually
drummed up bit of python scripting will not.

Thanks Vladimir! That worked as I needed it to. I appreciate everyone’s input!

Thanks,
Harry