Thanks for that info! It works pretty much how I need it. Now I need to figure out how to loop through all users in our IPA server, get the password expiration, do the calculations, and then disable where needed. The IPA user_find API method doesn't return the krbpasswordexpiration. So I may need to do the user find and pull out the user names into a fact, then traverse that using the user_show IPA API method to get the krbpasswordexpiration value, then go from there. Still planning that part out, but this calculation method is a huge step, and I appreciate everyone's time and effort to help.
Thanks, Harry On Wednesday, November 17, 2021 at 11:28:44 PM UTC-5 [email protected] wrote: > If you really want to do it with math (which requires lots of casts to > integers) instead of strings, here's a version that does it that way. > --- > - name: KrbPasswordExpiration date/time demo III > hosts: localhost > vars: > cutoff_days: 180 > > user_show: > json: > result: > result: > krbpasswordexpiration: [ > { "__datetime__": "20210107191401Z" }, > ] > tasks: > - name: Save expiration date as seconds in the epoch > set_fact: > exp_epoch: '{{ > (user_show.json.result.result.krbpasswordexpiration[0][''__datetime__''] | > to_datetime(''%Y%m%d%H%M%SZ'')).strftime(''%s'') }}' > - name: Save the number of days since this password expired > set_fact: > age: "{{ (ansible_date_time.epoch|int - exp_epoch|int) / ( 60 * 60 > * 24 ) }}" # negative values are in the future. > > - name: Disable accounts of users with old passwords. > debug: > msg: | > Cutoff KRB days: {{ cutoff_days }}; age: {{ age }} > {% if age|int >= cutoff_days %} > !!! Disable account; (pw exp: {{ > user_show.json.result.result.krbpasswordexpiration[0]['__datetime__'] }}). > {% else %} > --- Retain account; (pw exp: {{ > user_show.json.result.result.krbpasswordexpiration[0]['__datetime__'] }}). > {% endif %} > > and here's the output: > > TASK [Save expiration date as seconds in the epoch] > **************************** > > ok: [localhost] => changed=false > ansible_facts: > exp_epoch: '1610064841' > > TASK [Save the number of days since this password expired] > ********************* > > ok: [localhost] => changed=false > ansible_facts: > age: '314.17319444444445' > > > TASK [Disable accounts of users with old passwords.] > *************************** > ok: [localhost] => > msg: |- > Cutoff KRB days: 180; age: 314.17319444444445 > !!! Disable account; (pw exp: 20210107191401Z). > > On Wednesday, November 17, 2021 at 10:13:53 PM UTC-5 Todd Lewis wrote: > >> Both utc and today are strings (a.k.a. "AnsibleUnsafeText"), so you >> can't subtract one from the other. If they were both Python datetime >> objects, then you could get a difference like that (or something similar). >> >> I'm evidently not communicating clearly, but please know that I have a >> lot of sympathy for the frustration you're encountering with data >> manipulation in Ansible. Been there; got some scorched t-shirts out of it. >> I see what you're trying to do, and, while you're not wrong, and you can >> make Ansible do it that way, it involves a lot more "code" than is >> necessary to solve your problem. >> >> I say that because you don't need "today" or "age". Nor do you need to >> manipulate any of the kerberos password "__datetime__" values, or >> convert anything to datetime objects or take their differences. The only >> new piece of data you need is a string representing the date that was 180 >> days ago. >> >> Here's another shot at demonstrating what I'm suggesting. >> >> --- >> - name: KrbPasswordExpiration date/time demo II >> >> hosts: localhost >> vars: >> user_show: >> json: >> result: >> result: >> krbpasswordexpiration: [ >> { "__datetime__": "20210107191401Z", "id": "user1" }, >> { "__datetime__": "20210213123102Z", "id": "user2" }, >> { "__datetime__": "20210327062203Z", "id": "user3" }, >> { "__datetime__": "20210411130904Z", "id": "user4" }, >> { "__datetime__": "20210519124605Z", "id": "user5" }, >> { "__datetime__": "20210604225106Z", "id": "user6" }, >> { "__datetime__": "20210711531407Z", "id": "user7" }, >> { "__datetime__": "20210818191408Z", "id": "user8" }, >> ] >> tasks: >> >> - name: Save "now - 180 days" in krbpasswordexpiration format >> set_fact: >> krbpassworddeadline: '{{ lookup(''pipe'', >> ''date -u --date="now - 180 days" >> +%Y%m%d000000Z'') }}' >> - name: Disable accounts of users with old passwords. >> debug: >> msg: | >> Cutoff KRB date: {{ krbpassworddeadline }} >> {% for item in >> user_show.json.result.result.krbpasswordexpiration %} >> {% if krbpassworddeadline > item["__datetime__"] %} >> !!! Disable account for "{{ item['id'] }}" (pw exp: {{ >> item["__datetime__"] }}). >> {% else %} >> --- Retain account for "{{ item['id'] }}" (pw exp: {{ >> item["__datetime__"] }}). >> {% endif %} >> {% endfor %} >> >> That produces the following output (given that this was run on >> 2021-11-17): >> >> TASK [Save "now - 180 days" in krbpasswordexpiration format] >> ******************* >> ok: [localhost] => changed=false >> ansible_facts: >> krbpassworddeadline: 20210522000000Z >> >> TASK [Disable accounts of users with old passwords.] >> *************************** >> >> ok: [localhost] => >> msg: |- >> Cutoff KRB date: 20210522000000Z >> !!! Disable account for "user1" (pw exp: 20210107191401Z). >> !!! Disable account for "user2" (pw exp: 20210213123102Z). >> !!! Disable account for "user3" (pw exp: 20210327062203Z). >> !!! Disable account for "user4" (pw exp: 20210411130904Z). >> !!! Disable account for "user5" (pw exp: 20210519124605Z). >> --- Retain account for "user6" (pw exp: 20210604225106Z). >> --- Retain account for "user7" (pw exp: 20210711531407Z). >> --- Retain account for "user8" (pw exp: 20210818191408Z). >> >> On Wednesday, November 17, 2021 at 3:22:26 PM UTC-5 [email protected] >> wrote: >> >>> Let me further clarify what I'm looking to do and show where I'm at. We >>> have some bash scripts that check our IPA server user's and determines >>> their password age. Any user who has not changed their password in 180 >>> days gets automatically disabled. So that expiration date will be in >>> past. In bash we found an "abs" function to make a negative date >>> calculation a positive value. For example, if a person's account has been >>> expired since May 19, 2021, that is 182 days ago and should be expired. >>> I'm trying to do something similar with Ansible. But I'm working on the >>> date calculations now before expanding. >>> >>> So I'm able to get the user's password expiration date using the IPA >>> APIs, and can set the fact for it as assisted above in this thread. I can >>> also get today's date using the Ansible facts. What I am having an issue >>> with now is trying to use the facts previously calculated to determine the >>> age, and its not working: >>> >>> - name: Set facts >>> set_fact: >>> utc: '{{ lookup(''pipe'', >>> ''date -u --date="'' + >>> >>> (user_show.json.result.result.krbpasswordexpiration[0][''__datetime__'']| >>> >>> regex_replace(''^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z'',''\1-\2-\3 >>> \4:\5:\6 UTC'')) + ''" "+%Y-%m-%d"'') }}' >>> today: "{{ (ansible_date_time.date | >>> to_datetime('%Y-%m-%d')).date() }}" >>> age: "{{ ((utc) - (today)).days }}" >>> >>> FAILED! => {"msg": "Unexpected templating type error occurred on ({{ >>> ((utc) - (today)).days }}): unsupported operand type(s) for -: >>> 'AnsibleUnsafeText' and 'AnsibleUnsafeText'"} >>> >>> Any ideas on how to reference the "utc" and "today" facts in the "age" >>> fact? >>> >>> Thanks, >>> Harry >>> >>> >>> On Wednesday, November 17, 2021 at 12:10:18 PM UTC-5 [email protected] >>> wrote: >>> >>>> You don't need a datetime object. You just need to know if the string >>>> you have sorts before or after this string: >>>> '{{ lookup(''pipe'', ''date -u --date="now - 180 days" >>>> +%Y%m%d000000Z'') }}' >>>> I would argue "now - 180 days" is going to be a lot easier to >>>> understand next year than whatever "pure Ansible" contortions you come up >>>> with to do the same thing. >>>> >>>> On Wednesday, November 17, 2021 at 8:11:28 AM UTC-5 [email protected] >>>> wrote: >>>> >>>>> Thanks for that! I can now reference the __datetime__ member, but now >>>>> I'm trying to convert that to a datetime object in the format of YYmmdd, >>>>> but I get an error. Here's how I'm setting the fact now: >>>>> >>>>> - name: Set facts >>>>> set_fact: >>>>> user_expires: "{{ >>>>> user_show.json.result.result.krbpasswordexpiration[0]['__datetime__'] | >>>>> to_datetime('%Y%m%d') }}" >>>>> >>>>> - name: print results >>>>> debug: >>>>> msg: "{{ user_expires }} / {{ ansible_date_time.year }}{{ >>>>> ansible_date_time.month }}{{ ansible_date_time.day }}" >>>>> >>>>> When I run the playbook, it gives me the following error in the >>>>> set_fact play: >>>>> >>>>> FAILED! => {"msg": "the field 'args' has an invalid value >>>>> ({u'user_expires': u\"{{ >>>>> user_show.json.result.result.krbpasswordexpiration[0]['__datetime__'] | >>>>> to_datetime('%Y%m%d') }}\"}), and could not be converted to an dict.The >>>>> error was: unconverted data remains: 191401Z\n\n >>>>> >>>>> Any ideas? >>>>> >>>>> Thanks, >>>>> Harry >>>>> >>>>> On Tuesday, November 16, 2021 at 11:15:15 PM UTC-5 [email protected] >>>>> wrote: >>>>> >>>>>> - name: KrbPasswordExpiration date/time demo >>>>>> hosts: localhost >>>>>> vars: >>>>>> user_show: >>>>>> json: >>>>>> result: >>>>>> result: >>>>>> krbpasswordexpiration: [ >>>>>> { >>>>>> "__datetime__": "20220207191401Z" >>>>>> } >>>>>> ] >>>>>> tasks: >>>>>> - name: Read and manipulate the krb password expiration date/time. >>>>>> set_fact: >>>>>> utc: '{{ lookup(''pipe'', >>>>>> ''date -u --date="'' + >>>>>> >>>>>> (user_show.json.result.result.krbpasswordexpiration[0][''__datetime__'']| >>>>>> >>>>>> regex_replace(''^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z'',''\1-\2-\3 >>>>>> \4:\5:\6 UTC'')) + >>>>>> ''" "+%Y-%m-%d %H:%M:%S %z"'') }}' >>>>>> >>>>>> - name: Do you have the time? >>>>>> debug: >>>>>> msg: >>>>>> - "Before: {{ >>>>>> user_show.json.result.result.krbpasswordexpiration[0]['__datetime__'] }}" >>>>>> - "After: {{ utc }}" >>>>>> >>>>>> # > What I'm ultimately trying to do is grab a user's expiration >>>>>> date, and compare it to >>>>>> # > the current date. If the date is greater than or equal to >>>>>> 180, I need to disable the >>>>>> # > account. >>>>>> # That's a different problem. Behold: >>>>>> >>>>>> - name: Save "now - 180 days" in krbpasswordexpiration format >>>>>> set_fact: >>>>>> krbpassworddeadline: '{{ lookup(''pipe'', >>>>>> ''date -u --date="now - 180 >>>>>> days" +%Y%m%d000000Z'') }}' >>>>>> - name: Show the deadline >>>>>> debug: >>>>>> msg: "krbpassworddeadline: {{ krbpassworddeadline }}" >>>>>> >>>>>> - name: Expire user >>>>>> debug: >>>>>> msg: >>>>>> - "This is where you'd expire the user IFF the following >>>>>> were True:" >>>>>> - "when: krbpassworddeadline > >>>>>> user_show.json.result.result.krbpasswordexpiration[0]['__datetime__']" >>>>>> - "i.e. when: {{ krbpassworddeadline }} > {{ >>>>>> user_show.json.result.result.krbpasswordexpiration[0]['__datetime__'] }}" >>>>>> >>>>>> This produces the following output: >>>>>> >>>>>> TASK [Ansible setup date-time in UTC] >>>>>> ******************************************************************** >>>>>> task path: /home/utoddl/ansible/date-utc2.yml:29 >>>>>> ok: [localhost] => changed=false >>>>>> ansible_facts: >>>>>> utc: 2022-02-07 19:14:01 +0000 >>>>>> >>>>>> TASK [Do you have the time?] >>>>>> ***************************************************************************** >>>>>> task path: /home/utoddl/ansible/date-utc2.yml:40 >>>>>> ok: [localhost] => >>>>>> msg: >>>>>> - 'Before: 20220207191401Z' >>>>>> - 'After: 2022-02-07 19:14:01 +0000' >>>>>> >>>>>> TASK [Save "now - 180 days" in krbpasswordexpiration format] >>>>>> ********************************************* >>>>>> task path: /home/utoddl/ansible/date-utc2.yml:51 >>>>>> ok: [localhost] => changed=false >>>>>> ansible_facts: >>>>>> krbpassworddeadline: 20210521000000Z >>>>>> >>>>>> TASK [Show the deadline] >>>>>> ********************************************************************************* >>>>>> task path: /home/utoddl/ansible/date-utc2.yml:55 >>>>>> ok: [localhost] => >>>>>> msg: 'krbpassworddeadline: 20210521000000Z' >>>>>> >>>>>> TASK [Expire user] >>>>>> *************************************************************************************** >>>>>> task path: /home/utoddl/ansible/date-utc2.yml:59 >>>>>> ok: [localhost] => >>>>>> msg: >>>>>> - 'This is where you''d expire the user IFF the following were >>>>>> True:' >>>>>> - 'when: krbpassworddeadline > >>>>>> user_show.json.result.result.krbpasswordexpiration[0][''__datetime__'']' >>>>>> - 'i.e. when: 20210521000000Z > 20220207191401Z' >>>>>> META: ran handlers >>>>>> META: ran handlers >>>>>> >>>>>> PLAY RECAP >>>>>> *********************************************************************************************** >>>>>> localhost : ok=6 changed=0 unreachable=0 >>>>>> failed=0 skipped=0 rescued=0 ignored=0 >>>>>> >>>>>> On Tuesday, November 16, 2021 at 12:16:46 PM UTC-5 [email protected] >>>>>> wrote: >>>>>> >>>>>>> I'm using the freeipa APIs in a playbook to get a user's LDAP >>>>>>> information. I can get the krbpasswordexpiration fine: >>>>>>> >>>>>>> "krbpasswordexpiration": [ >>>>>>> { >>>>>>> "__datetime__": "20220207191401Z" >>>>>>> } >>>>>>> >>>>>>> But I can't figure out how to access the date string to convert it >>>>>>> to a date object. I need it in the form of YYMMDD. If I try to set a >>>>>>> fact >>>>>>> as follows: >>>>>>> >>>>>>> user_show.json.result.result.krbpasswordexpiration >>>>>>> >>>>>>> I get an error about the fact being a list and not a string. How do >>>>>>> I pull out the date string so I can turn it into a date? >>>>>>> >>>>>>> What I'm ultimately trying to do is grab a user's expiration date, >>>>>>> and compare it to the current date. If the date is greater than or >>>>>>> equal >>>>>>> to 180, I need to disable the account. >>>>>>> >>>>>>> Thanks! >>>>>>> Harry >>>>>>> >>>>>>> -- You received this message because you are subscribed to the Google Groups "Ansible Project" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/49c23a4f-e322-453a-a765-9744b7dcd54fn%40googlegroups.com.
