I think I got it.  I set the fact like so:

  - name: Find users who's password will expire in the next {{ warning_days 
}} days
    ansible.builtin.set_fact:
      pwd_expire_soon: "{{ user_show.results | 
json_query('[*].json.result.result.{uid: uid[0], pwdchg: 
krblastpwdchange[0].__datetime__}') | selectattr('pwdchg', '!=', None) | 
selectattr('pwdchg', '<', expire_date) | list }}"


And that returns those 3 that did not have null for krblastpwdchange.  Now, 
those 3 had values that were within the last 30/60 days, but I think I may 
be looking at the wrong attribute at this point.  But that's something that 
I'll work on next.

Thank you very much for your help and time!  I always appreciate you guys!
Harry

On Monday, February 26, 2024 at 2:50:03 PM UTC-5 Todd Lewis wrote:

> Assuming what you posted is the result of:
>
>   - name: Show user info
>       debug:
>         msg: "{{ user_show.results | json_query('[*].json.result.result.{uid: 
> uid[0], pwdchg: krblastpwdchange[0].__datetime__}') }}"
>
> Then throw this onto the end:
>
>   | selectattr("pwdchg", "!=", None)
>
> You could put that new expression in a set_fact for use later on.
> --
> Todd
>
>
> On 2/26/24 2:27 PM, [email protected] wrote:
>
> I totally understand where you're coming from.  You guys have always been 
> great and extremely helpful, and I appreciate that.  I have adjusted the 
> playbook to look at the first 5 users, and the anonymized output is below. 
>
> Thanks,
> Harry
>
> TASK [Show user info] 
> **************************************************************************************************************************************************************************************
> ok: [localhost] => {
>     "msg": [
>         {
>             "pwdchg": null,
>             "uid": "user1"
>         },
>         {
>             "pwdchg": "20240124144409Z",
>             "uid": "user2"
>         },
>         {
>             "pwdchg": "20231212115535Z",
>             "uid": "user3"
>         },
>         {
>             "pwdchg": null,
>             "uid": "user4"
>         },
>         {
>             "pwdchg": "20240115133407Z",
>             "uid": "user5"
>         }
>     ]
> }
>
> On Monday, February 26, 2024 at 2:14:15 PM UTC-5 Todd Lewis wrote:
>
>> Normally I would change
>>
>> krblastpwdchange[0].__datetime__
>>
>> to
>>
>> krblastpwdchange[0].__datetime__ | default('0')
>>
>> but your expression is part of json_query(). Perhaps there's an 
>> equivalent of Jinja's default() in json_query(); I just don't know.
>>
>> Without standing up an IPA instance and experimenting, I don't see a way 
>> to derive what your user_show data looks like. (I did that a year or two 
>> ago to answer a similar question, but I'm a bit swamped at the moment.) 
>> Perhaps if you could give us the first couple of records from your 
>> registered user_show data — the first one that's throwing the error and 
>> another one or two that has what you expect, anonymized as appropriate of 
>> course — that would give us enough information about your data's structure 
>> to suggest some expressions to try.
>>
>> Including the playbook helps a whole lot; alas, without sample data or an 
>> IPA instance to play with it's not sufficient to give you a definitive 
>> answer. Well, at least I can't.
>>
>> I know this sort of problem can be extremely frustrating, and you've been 
>> patient in asking. We really do want to help, honestly. But the IPA thing 
>> is one level of niche, and very few people are versed in json_query() so 
>> that adds yet another level of niche. But if you can provide the sample 
>> data I mentioned before I think we can make some progress.
>> --
>> Todd
>>
>>
>> On 2/26/24 9:43 AM, [email protected] wrote:
>>
>> I'm including the playbook below.  I'm still unable to find a way to 
>> ignore any user that does not have the krblastpwdchange property set.  When 
>> I run the playbook, I still get the following error: 
>>
>> TASK [Find users who's password will expire in the next 10 days] 
>> *******************************************************************************************************************************************
>> fatal: [localhost]: FAILED! => {"msg": "Unexpected templating type error 
>> occurred on ({{ user_show.results | 
>> json_query('[*].json.result.result.{uid: uid[0], pwdchg: 
>> krblastpwdchange[0].__datetime__}') | selectattr('pwdchg', 'defined') | 
>> selectattr('pwdchg', '<', expire_date) | list }}): '<' not supported 
>> between instances of 'NoneType' and 'AnsibleUnsafeText'. '<' not supported 
>> between instances of 'NoneType' and 'AnsibleUnsafeText'"}
>>
>> Playbook:
>>
>> ---
>> - name: Gather User Password Expiration information from IDM server
>>   hosts: localhost
>>   gather_facts: no
>>
>>   pre_tasks:
>>     - setup:
>>         filter: 'ansible_date_time'
>>
>>   vars_files:
>>     - /etc/ansible/vault.yml
>>
>>   vars:
>>     idmfqdn: idmserver
>>     binduser: 'admin'
>>     bindpasswd: '{{ secure_ipa_pass }}'
>>     warning_days: 10
>>
>>   tasks:
>>
>>   - name: Set list of users to ignore
>>     ansible.builtin.set_fact:
>>       ignore_users:
>>         - "root" 
>>         - "some.user" 
>>         - "some.c-ctr.user" 
>>         - "test.redhat" 
>>         - "admin"
>>
>>   - name: Login to IDM use returned cookie to access the API in later 
>> tasks
>>     ansible.builtin.uri:
>>       url: "https://{{idmfqdn}}/ipa/session/login_password"; 
>> <https://%7B%7Bidmfqdn%7D%7D/ipa/session/login_password>
>>       method: POST
>>       headers:
>>         Referer: "https://{{idmfqdn}}/ipa"; 
>> <https://%7B%7Bidmfqdn%7D%7D/ipa>
>>         Content-Type: "application/x-www-form-urlencoded"
>>         Accept: "text/plain"
>>       body_format: form-urlencoded
>>       body:
>>         user: "{{binduser}}"
>>         password: "{{bindpasswd}}"
>>       status_code: 200
>>       follow_redirects: all
>>     register: login
>>
>>   - name: Get IDM API version using previously stored session cookie
>>     ansible.builtin.uri:
>>       url: "https://{{idmfqdn}}/ipa/session/json"; 
>> <https://%7B%7Bidmfqdn%7D%7D/ipa/session/json>
>>       method: POST
>>       headers:
>>         Cookie: "{{ login.set_cookie }}"
>>         Referer: "https://{{idmfqdn}}/ipa"; 
>> <https://%7B%7Bidmfqdn%7D%7D/ipa>
>>         Content-Type: "application/json"
>>         Accept: "application/json"
>>       body_format: json
>>       body: '{"method": "ping","params": [[],{}]}'
>>     register: api_vers_out
>>
>>   - name: Set fact for api version
>>     ansible.builtin.set_fact:
>>       api_vers: "{{ 
>> api_vers_out.json.result.messages|json_query('[*].data.server_version')|join()
>>  
>> }}"
>>
>>   - name: Run user_find from IDM API using previously stored session 
>> cookie
>>     ansible.builtin.uri:
>>       url: "https://{{idmfqdn}}/ipa/session/json"; 
>> <https://%7B%7Bidmfqdn%7D%7D/ipa/session/json>
>>       method: POST
>>       headers:
>>         Cookie: "{{ login.set_cookie }}"
>>         Referer: "https://{{idmfqdn}}/ipa"; 
>> <https://%7B%7Bidmfqdn%7D%7D/ipa>
>>         Content-Type: "application/json"
>>         Accept: "application/json"
>>       body_format: json
>>       body: "{\"method\": \"user_find/1\",\"params\": [[],{\"version\": 
>> \"{{ api_vers }}\"}]}"
>>     no_log: true
>>     register: user_find
>>
>>   - name: Set users fact
>>     ansible.builtin.set_fact:
>>       uid: "{{ 
>> user_find.json.result.result|map(attribute='uid')|flatten|difference(ignore_users)
>>  
>> }}"
>>
>>   - name: Run user_show from IDM API using previously stored session 
>> cookie
>>     ansible.builtin.uri:
>>       url: "https://{{idmfqdn}}/ipa/session/json"; 
>> <https://%7B%7Bidmfqdn%7D%7D/ipa/session/json>
>>       method: POST
>>       headers:
>>         Cookie: "{{ login.set_cookie }}"
>>         Referer: "https://{{idmfqdn}}/ipa"; 
>> <https://%7B%7Bidmfqdn%7D%7D/ipa>
>>         Content-Type: "application/json"
>>         Accept: "application/json"
>>       body_format: json
>>       body: "{\"method\": \"user_show\",\"params\": [[ \"{{ item 
>> }}\"],{\"all\": true,\"version\": \"{{ api_vers }}\"}]}"
>>     register: user_show
>>     loop: "{{ uid | json_query('[:1]') }}"
>>
>>
>>   - name: Set expire date
>>     ansible.builtin.set_fact:
>>       expire_date: '{{ lookup(''pipe'', ''date -u --date="today + {{ 
>> warning_days }} days" +%Y%m%d000000Z'') }}'
>>
>>   - name: Show expire date
>>     ansible.builtin.debug:
>>       msg: "{{ expire_date }}"
>>
>>   - name: Show user info
>>     debug:
>>       msg: "{{ user_show.results | 
>> json_query('[*].json.result.result.{uid: uid[0], pwdchg: 
>> krblastpwdchange[0].__datetime__}') }}"
>>
>>   - name: Find users who's password will expire in the next {{ 
>> warning_days }} days
>>     ansible.builtin.set_fact:
>>       pwd_expire_soon: "{{ user_show.results | 
>> json_query('[*].json.result.result.{uid: uid[0], pwdchg: 
>> krblastpwdchange[0].__datetime__}') | selectattr('pwdchg', 'defined') | 
>> selectattr('pwdchg', '<', expire_date) | list }}"
>>
>>   - name: Show accounts that are due to expire in the next {{ 
>> warning_days }} days
>>     ansible.builtin.debug:
>>       msg: "{{ pwd_expire_soon }}"
>>
>> Thanks,
>> Harry
>> On Friday, February 23, 2024 at 2:54:06 PM UTC-5 [email protected] wrote:
>>
>>> So it looks like the VERY 1st user in our system has never logged in, so 
>>> the krblaspwdchange property has never gotten set.  Is there a way to 
>>> ignore when that field doesn't exist or is null? 
>>>
>>> Thanks,
>>> Harry
>>>
>>> On Friday, February 23, 2024 at 2:46:07 PM UTC-5 Todd Lewis wrote:
>>>
>>>> The original problem is you're comparing 'NoneType' and 'str'. So, for 
>>>> at least one of your principals there's no krblastpwdchange. You need to 
>>>> work on the subset of data relevant to the comparison.
>>>>
>>>>
>>>> On 2/23/24 2:09 PM, [email protected] wrote:
>>>>
>>>> I'm not including the entire playbook, but the URI module call where 
>>>> user_show gets registered, then the debug statements: 
>>>>
>>>>   - name: Run user_show from IDM API using previously stored session 
>>>> cookie
>>>>     ansible.builtin.uri:
>>>>       url: "https://{{idmfqdn}}/ipa/session/json"; 
>>>> <https://%7B%7Bidmfqdn%7D%7D/ipa/session/json>
>>>>       method: POST
>>>>       headers:
>>>>         Cookie: "{{ login.set_cookie }}"
>>>>         Referer: "https://{{idmfqdn}}/ipa"; 
>>>> <https://%7B%7Bidmfqdn%7D%7D/ipa>
>>>>         Content-Type: "application/json"
>>>>         Accept: "application/json"
>>>>       body_format: json
>>>>       body: "{\"method\": \"user_show\",\"params\": [[ \"{{ item 
>>>> }}\"],{\"all\": true,\"version\": \"{{ api_vers }}\"}]}"
>>>>     register: user_show
>>>>     loop: "{{ uid | json_query('[:10]') }}"
>>>>
>>>>
>>>>   - name: Set expire date
>>>>     ansible.builtin.set_fact:
>>>>       expire_date: '{{ lookup(''pipe'', ''date -u --date="today + 10 
>>>> days" +%Y%m%d000000Z'') }}'
>>>>
>>>>   - name: Show expire date
>>>>     ansible.builtin.debug:
>>>>       msg: "{{ expire_date }}"
>>>>
>>>>   - name: Show user info
>>>>     debug:
>>>>       msg: "{{ user_show.results | 
>>>> json_query('[*].json.result.result.{uid: uid[0], pwdchg: 
>>>> krblastpwdchange[0].__datetime__}') }}"
>>>>
>>>> Thanks,
>>>> Harry
>>>> On Friday, February 23, 2024 at 1:58:04 PM UTC-5 Todd Lewis wrote:
>>>>
>>>>> Without showing us the expression you used in your debug's "msg:", 
>>>>> this doesn't tell us anything.
>>>>>
>>>>>
>>>>> On 2/23/24 1:05 PM, [email protected] wrote:
>>>>>
>>>>> Looks OK to me: 
>>>>>
>>>>> TASK [Show user info] 
>>>>> **************************************************************************************************************************************************************************************
>>>>> ok: [localhost] => {
>>>>>     "msg": [
>>>>>         {
>>>>>             "pwdchg": "20210416141027Z",
>>>>>             "uid": "user1"
>>>>>         }
>>>>>     ]
>>>>> }
>>>>>
>>>>>
>>>>> Thanks,
>>>>> Harry
>>>>> On Friday, February 23, 2024 at 12:13:07 PM UTC-5 Rowe, Walter P. 
>>>>> (Fed) wrote:
>>>>>
>>>>>> {{ user_show.results | json_query('[*].json.result.result.{uid: 
>>>>>> uid[0], pwdchg: krblastpwdchange[0].__datetime__}') }}
>>>>>>
>>>>>> I would display this info in a debug to see what the resulting data 
>>>>>> stream looks like. Maybe the selectattr('pwdchg') is in inaccurate 
>>>>>> reference to pwdchg?
>>>>>>
>>>>>>
>>>>>> Walter
>>>>>> --
>>>>>> Walter Rowe, Division Chief
>>>>>> Infrastructure Services Division
>>>>>> Mobile: 202.355.4123 <(202)%20355-4123> 
>>>>>>
>>>>>> On Feb 23, 2024, at 12:09 PM, [email protected] <[email protected]> 
>>>>>> wrote:
>>>>>>
>>>>>> Just pull out those fields from the returned user information.  I use 
>>>>>> that in 2 or 3 other playbooks so I know that it works. 
>>>>>>
>>>>>> Thanks,
>>>>>> Harry
>>>>>>
>>>>>> On Friday, February 23, 2024 at 11:53:04 AM UTC-5 Rowe, Walter P. 
>>>>>> (Fed) wrote:
>>>>>>
>>>>>>> pwd_expire_soon: "{{ user_show.results | 
>>>>>>> json_query('[*].json.result.result.{uid: uid[0], pwdchg: 
>>>>>>> krblastpwdchange[0].__datetime__}') | selectattr('pwdchg', 
>>>>>>> 'lessthan', 'expire_date') | list }}"
>>>>>>>
>>>>>>> What are you expecting this red portion to do? I don't think it is 
>>>>>>> valid in json_query.
>>>>>>>
>>>>>>> Walter
>>>>>>> --
>>>>>>> Walter Rowe, Division Chief
>>>>>>> Infrastructure Services Division
>>>>>>> Mobile: 202.355.4123 <(202)%20355-4123> 
>>>>>>>
>>>>>>> On Feb 23, 2024, at 11:30 AM, [email protected] <[email protected]> 
>>>>>>> wrote:
>>>>>>>
>>>>>>> I am trying to determine when user's password's are going to expire 
>>>>>>> in the next 10 days.  After I traverse my FreeIPA users and store those 
>>>>>>> users into a variable, I try to set a fact like so: 
>>>>>>>   - name: Find users who's password will expire in the next 10 days
>>>>>>>     set_fact:
>>>>>>>       pwd_expire_soon: "{{ user_show.results | 
>>>>>>> json_query('[*].json.result.result.{uid: uid[0], pwdchg: 
>>>>>>> krblastpwdchange[0].__datetime__}') | selectattr('pwdchg', 'lessthan', 
>>>>>>> 'expire_date') | list }}"
>>>>>>>
>>>>>>> When I run my playbook, I get the following error:
>>>>>>>
>>>>>>> fatal: [localhost]: FAILED! => {"msg": "Unexpected templating type 
>>>>>>> error occurred on ({{ user_show.results | 
>>>>>>> json_query('[*].json.result.result.{uid: uid[0], pwdchg: 
>>>>>>> krblastpwdchange[0].__datetime__}') | selectattr('pwdchg', 'lessthan', 
>>>>>>> 'expire_date') | list }}): '<' not supported between instances of 
>>>>>>> 'NoneType' and 'str'. '<' not supported between instances of 'NoneType' 
>>>>>>> and 
>>>>>>> 'str'"}
>>>>>>>
>>>>>>> I can't seem to find what the issue is.  I originally  had '<' 
>>>>>>> instead of 'lessthan' but got the same error.  Any ideas?
>>>>>>>
>>>>>>> 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/a1131cb0-bc23-46bb-afbf-ca9ad6f4ce34n%40googlegroups.com
>>>>>>>  
>>>>>>> <https://groups.google.com/d/msgid/ansible-project/a1131cb0-bc23-46bb-afbf-ca9ad6f4ce34n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>>> .
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> -- 
>>>>>> 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/c0b4de3d-50e2-4fff-85b1-0437076137dcn%40googlegroups.com
>>>>>>  
>>>>>> <https://groups.google.com/d/msgid/ansible-project/c0b4de3d-50e2-4fff-85b1-0437076137dcn%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>> .
>>>>>>
>>>>>>
>>>>>> -- 
>>>>> 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/f76c158f-1107-4d10-8977-12638128d056n%40googlegroups.com
>>>>>  
>>>>> <https://groups.google.com/d/msgid/ansible-project/f76c158f-1107-4d10-8977-12638128d056n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>>
>>>>>

-- 
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/1f325f23-ae03-4c88-9c32-37de2890467en%40googlegroups.com.

Reply via email to