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, lift...@gmail.com 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, lift...@gmail.com 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
    lift...@gmail.com 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, lift...@gmail.com 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, lift...@gmail.com 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 <tel:(202)%20355-4123>
                    On Feb 23, 2024, at 12:09 PM,
                    lift...@gmail.com <lift...@gmail.com> 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 <tel:(202)%20355-4123>

                        On Feb 23, 2024, at 11:30 AM,
                        lift...@gmail.com <lift...@gmail.com> 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 ansible-proje...@googlegroups.com.
                        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
                    ansible-proje...@googlegroups.com.
                    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
                ansible-proje...@googlegroups.com.
                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 ansible-project+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ansible-project/ec2d24d8-aef1-4a1c-a6ef-50a896374add%40gmail.com.

Reply via email to