RNC
RNC

Reputation: 107

Getting an item from a list as a string in Ansible

I'm trying to get an RSA key from a Keycloak installation via Ansible. My variable returned from the Keycloak API is:

"msg": {
    "cache_control": "no-cache",
    "changed": false,
    "connection": "close",
    "content_length": "2011",
    "content_type": "application/json",
    "cookies": {},
    "cookies_string": "",
    "date": "Sun, 05 Jul 2020 13:32:42 GMT",
    "elapsed": 0,
    "failed": false,
    "json": {
        "active": {
            "AES": "redactedredactedredacted-redacted-redacted",
            "HS256": "redactedredactedredacted-redacted-redacted",
            "RS256": "redactedredactedredacted-redacted-redacted"
        },
        "keys": [
            {
                "algorithm": "HS256",
                "kid": "redactedredactedredacted-redacted-redacted",
                "providerId": "redactedredactedredacted-redacted-redacted",
                "providerPriority": 100,
                "status": "ACTIVE",
                "type": "OCT"
            },
            {
                "algorithm": "AES",
                "kid": "redactedredactedredacted-redacted-redacted",
                "providerId": "redactedredactedredacted-redacted-redacted",
                "providerPriority": 100,
                "status": "ACTIVE",
                "type": "OCT"
            },
            {
                "algorithm": "RS256",
                "certificate": "redactedredactedredacted-redacted-redactedredactedredactedredacted-redacted-redactedredactedredactedredacted-redacted-redactedredactedredactedredacted-redacted-redactedredactedredactedredacted-redacted-redactedredactedredactedredacted-redacted-redactedredactedredactedredacted-redacted-redactedredactedredactedredacted-redacted-redactedredactedredactedredacted-redacted-redactedredactedredactedredacted-redacted-redactedredactedredactedredacted-redacted-redactedredactedredactedredacted-redacted-redacted=",
                "kid": "redactedredactedredacted-redacted-redacted",
                "providerId": "redactedredactedredacted-redacted-redacted",
                "providerPriority": 100,
                "publicKey": "thisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEY",
                "status": "ACTIVE",
                "type": "RSA"
            }
        ]
    },
    "msg": "OK (2011 bytes)",
    "redirected": false,
    "status": 200,
    "strict_transport_security": "max-age=31536000; includeSubDomains",
    "url": "http://localhost:8080/auth/admin/realms/master/keys",
    "x_content_type_options": "nosniff",
    "x_frame_options": "SAMEORIGIN",
    "x_xss_protection": "1; mode=block"
}

}

... from which I want the publicKey to generate a JWK. Lets say I'm using the variable kc_keys from the API response object.

"{{ kc_keys.json['keys'] | map(attribute='publicKey') }}"

... returns "msg": "<generator object do_map at 0x7f9c6b3014d0>".

Okay, it's an object. I can convert it to a list by "{{ kc_keys.json['keys'] | map(attribute='publicKey') | list }}" which returns...

"msg": "[AnsibleUndefined, AnsibleUndefined, 'thisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEY']"

From here the documentation isn't clear on how I would simply extract my thisISApublicKEY... as a string. How do I grab the last element in the list as a string from the last step above?

Upvotes: 1

Views: 631

Answers (2)

RNC
RNC

Reputation: 107

Found the answer here:

https://stackoverflow.com/a/62314142/7488096

|last was the filter I was missing. So based on the accepted answer....

"{{ kc_keys.json['keys'] | selectattr('publicKey', 'defined') | map(attribute='publicKey') | list | last | to_json }}" returns an escaped json string as desired, and | list | last | string converts the output to a string successfully as well if you prefer:

"msg": "\"thisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEYthisISApublicKEY\"" }

Upvotes: 0

Moon
Moon

Reputation: 3037

If you are just looking for the publicKey this simple json_query filter should do.

- debug:
    msg: "{{ kc_keys.json | json_query('*[].publicKey') }}"

An alternative

- debug:
    msg: "{{ kc_keys.json['keys'] | selectattr('publicKey', 'defined') | map(attribute='publicKey') | list }}"

Upvotes: 1

Related Questions