'Get the CN out of certificates information

I am trying to do a nice print out of the data from Ansible but have no idea on how to manipulate it.
This is what I have in the debug — I am trying to somehow manipulate the data so that it only gives me a CN= (without the CN=) value, and not the whole subject string:

[
        {
            "certkey": "Verisign_ca3_cer",
            "daystoexpiration": 0,
            "status": "Expired",
            "subject": " C=US,O=VeriSign, Inc.,OU=VeriSign Trust Network,OU=Terms of use at https://www.verisign.com/rpa (c)06,CN=VeriSign Class 3 Extended Validation SSL SGC CA"
        },
        {
            "certkey": "Verisign_ca5_cer",
            "daystoexpiration": 0,
            "status": "Expired",
            "subject": " C=US,O=VeriSign, Inc.,OU=VeriSign Trust Network,OU=Terms of use at https://www.verisign.com/rpa (c)10,CN=VeriSign Class 3 International Server CA - G3"
        }
]

I wanted output similar to this:

[
        {
            "certkey": "Verisign_ca3_cer",
            "daystoexpiration": 0,
            "status": "Expired",
            "subject": "CN=VeriSign Class 3 Extended Validation SSL SGC CA"
        },
        {
            "certkey": "Verisign_ca5_cer",
            "daystoexpiration": 0,
            "status": "Expired",
            "subject": "CN=VeriSign Class 3 International Server CA - G3"
        }
]


Solution 1:[1]

Q: "Select 'CN' from 'subject'."

A: Let's assume your data is a list of dictionaries, e.g.

    certs:
      - {"certkey": "Verisign_ca3_cer",
         "daystoexpiration": 0,
         "status": "Expired",
         "subject": " C=US,O=VeriSign, ...

Create the list of the parsed subjects, e.g.

    - set_fact:
        subjs: "{{ subjs|d([]) + [_subj] }}"
      loop: "{{ certs|map(attribute='subject')|list }}"
      vars:
        _subj: "{{ dict(item.split(',')|
                        select('match', '.*=.*')|
                        map('trim')|
                        map('split', '=')|
                        list) }}"

gives

  subjs:
  - C: US
    CN: VeriSign Class 3 Extended Validation SSL SGC CA
    O: VeriSign
    OU: Terms of use at https://www.verisign.com/rpa (c)06
  - C: US
    CN: VeriSign Class 3 International Server CA - G3
    O: VeriSign
    OU: Terms of use at https://www.verisign.com/rpa (c)10

and select the attribute 'CN'

    - set_fact:
        CN: "{{ subjs|map(attribute='CN')|list }}"

gives

  CN:
  - VeriSign Class 3 Extended Validation SSL SGC CA
  - VeriSign Class 3 International Server CA - G3

Combine the certificates with the updated attribute subject, e.g.

    - set_fact:
        cert_cn: "{{ cert_cn|d([]) + 
                     [item.0|combine({'subject': 'CN=' ~ item.1.CN})] }}"
      loop: "{{ certs|zip(subjs) }}"

gives the output you want

  cert_cn:
  - certkey: Verisign_ca3_cer
    daystoexpiration: 0
    status: Expired
    subject: CN=VeriSign Class 3 Extended Validation SSL SGC CA
  - certkey: Verisign_ca5_cer
    daystoexpiration: 0
    status: Expired
    subject: CN=VeriSign Class 3 International Server CA - G3

Solution 2:[2]

I just went the regex_replace way

msg: '{{ result.json.sslcertkey | regex_replace(" C=.*?CN=", "")   }}'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Sergey Fox