How to handle multi-line prompts with expect module?

Per https://groups.google.com/forum/#!topic/ansible-project/AXEPsAqxmNE I’m using the expect module, and have it working when the prompt is single line. How do I make it work when the prompt is multi-line? I’m not talking about multi-prompts.

Let me explain.

ansible v2.4.0.0

I’m trying to automate JKS (Java Keystore) and CSR file generation via the keytool command (the java_cert module doesn’t do this, IIUC).The command, and the first 3 prompts are the following. Note that the third prompt is multi-lined.

$ keytool -genkey -alias tomcat -keyalg RSA -sigalg SHA1withRSA -keysize 2048 -keystore keystore.jks Enter keystore password: Re-enter new password: What is your first and last name? [Unknown]:

I have

`

Expect is just looking a a stream of bytes, when it sees a string it will "type" the response.
So in this case you only need to check for the string [Unknown]:
Since is special character in regex you need to escape them

   "\[Unknown\]: ": "myserver.domain.com"

You could also leave out the quotes, the colon and the space, this will also work

   \[Unknown\]: myserver.domain.com

This helped some, but brought up the next issue.

The keytool command has multiple multi-lined prompts, with “[Unknown]” as the second line, so if I do this

`
tasks:

  • name: Test expect
    expect:
    timeout: 5
    echo: yes
    command: keytool -genkey -alias tomcat -keyalg RSA -sigalg SHA1withRSA -keysize 2048 -keystore keystore.jks
    responses:
    “Enter keystore password”: “changeit”
    “Re-enter new password”: “changeit”
    [Unknown]: “{{ cname }}”
    [Unknown]: “EngIT”
    [Unknown]: “{{ company }}”
    [Unknown]: “RTP”
    [Unknown]: “NC”
    [Unknown]: “US”

`

I now get

[WARNING]: While constructing a mapping from /home/scscm_builder/copy- expect.yml, line 20, column 9, found a duplicate dict key (\[Unknown\]). Using last defined value only.

I need to somehow include part of each prompt in the regex?

Thanks Kai. Your comment “Expect is just looking a a stream of bytes” gave me the idea to just look for a “string of bytes” that’s present in each prompt. The following now works.

`

  • name: Test expect
    expect:
    timeout: 5
    echo: yes
    command: keytool -genkey -alias tomcat -keyalg RSA -sigalg SHA1withRSA -keysize 2048 -keystore keystore.jks
    responses:
    “Enter keystore password”: “{{ keystore_pw }}”
    “Re-enter new password”: “{{ keystore_pw }}”
    “last name”: “{{ cname }}”
    “organizational unit”: “EngIT”
    “organization”: “{{ company }}”
    “Locality”: “RTP”
    “Province” : “NC”
    “country”: “US”
    [no]: “yes”
    “Enter key password” : “{{ keystore_pw }}”

`

Interestingly enough, the following gives a syntax error

"\[no\]"

but corrected with this

\[no\]

I saw you did make it work, but to answer this for the future.

The responses is often call question and answers, you can only have one uniq question but many answer, and the answers must be in a list like so

   - name: Test expect
     expect:
       timeout: 5
       echo: yes
       command: keytool -genkey -alias tomcat -keyalg RSA -sigalg SHA1withRSA -keysize 2048 -keystore keystore.jks
       responses:
         "Enter keystore password": "changeit"
         "Re-enter new password": "changeit"
         \[Unknown\]:
           - "{{ cname }}"
           - "EngIT"
           - "{{ company }}"
           - "RTP"
           - "NC"
           - "US"