NVP
NVP

Reputation: 113

pexpect module responses in Ansible based on condition

I am creating an ansible script to install splunk Universal Forwarder. If management port 8089 is not free, splunk service start doesnot work. It asks for user input:

{
  "stdout_lines": [
    "", 
    "This appears to be your first time running this version of Splunk.", 
    "", 
    "Splunk software must create an administrator account during startup. Otherwise, you cannot log in.", 
    "Create credentials for the administrator account.",
    "Characters do not appear on the screen when you type in credentials.", 
    "", 
    "Please enter an administrator username: admin", 
    "Password must contain at least:", 
    "   * 8 total printable ASCII character(s).", 
    "Please enter a new password: ", "Please confirm new password: ", 
    "", 
    "Splunk> Needle. Haystack. Found.", 
    "", 
    "Checking prerequisites...", 
    "\tChecking mgmt port [8089]: not available", 
    "ERROR: mgmt port [8089] - port is already bound.  Splunk needs to use this port.", 
    "Would you like to change ports? [y/n]: "
  ]
}

I am using the pexpect module this way for username and password :

- name: Start splunk forwarder service
  expect:
    command:  /opt/splunkforwarder/bin/splunk start  --accept-license --answer-yes
    responses:
       (.*)Please enter an administrator username(.*): "{{ Username }}"
       (.*)Please enter a new password(.*): "{{ Password }}"
       (.*)Please confirm new password(.*): "{{ Password }}"

I want to add under pexpect responses - Would you like to change ports? [y/n] :. This should be executed only when below prompts for user.

execution stops with "ERROR: mgmt port [8089] - port is already bound.  Splunk needs to use this port." 

Please let me know how I can achieve this?

Upvotes: 1

Views: 235

Answers (1)

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39304

The fact that Ansible responds to a question or not is already why the keys of the responses dictionary are regex.

So you can feed your string in the response regex, like you have for the other question.

You will just have to escape all characters having a meaning in a regex, so ., [ and ].

- name: Start splunk forwarder service
  expect:
    command: >-
      /opt/splunkforwarder/bin/splunk start  
        --accept-license 
        --answer-yes
    responses:
      (.*)Please enter an administrator username(.*): "{{ Username }}"
      (.*)Please enter a new password(.*): "{{ Password }}"
      (.*)Please confirm new password(.*): "{{ Password }}"
      ? "(.*)ERROR: mgmt port \\[8089\\] - port is already bound\\.
        (.*)Splunk needs to use this port\\.\
        (.*)Would you like to change ports(.*)"
      : y

Note: for readability, I used a multiline YAML key here.


With this demo script:

#!/usr/bin/env sh

echo "Please enter an administrator username: admin"
read
echo "Your username is ${REPLY}"
echo "Password must contain at least:"
echo "   * 8 total printable ASCII character(s)."
echo "Please enter a new password: "
read
echo "Your password is ${REPLY}"
echo "Please confirm new password: "
read
echo "Your password confirmation is ${REPLY}"
echo -n "ERROR: mgmt port [8089] - port is already bound.  "
echo "Splunk needs to use this port."
echo "Would you like to change ports? [y/n]: "
read
echo "Your answer is ${REPLY}"

The two taks:

- expect:
    command: >-
      ./splunk start  
        --accept-license 
        --answer-yes
    responses:
      (.*)Please enter an administrator username(.*): "{{ Username }}"
      (.*)Please enter a new password(.*): "{{ Password }}"
      (.*)Please confirm new password(.*): "{{ Password }}"
      ? "(.*)ERROR: mgmt port \\[8089\\] - port is already bound\\.
        (.*)Splunk needs to use this port\\.\
        (.*)Would you like to change ports(.*)"
      : y
    timeout: 2
  vars:
    Username: b.enoit.be
    Password: foobar
  register: splunk
  
- debug:
    var: splunk.stdout

Would yield:

TASK [expect] **********************************************************
changed: [localhost]

TASK [debug] ***********************************************************
ok: [localhost] => 
  splunk.stdout: |-
    Please enter an administrator username: admin
    Your username is b.enoit.be
    Password must contain at least:
       * 8 total printable ASCII character(s).
    Please enter a new password:
    Your password is foobar
    Please confirm new password:
    Your password confirmation is foobar
    ERROR: mgmt port [8089] - port is already bound.  Splunk needs to use this port.
    Would you like to change ports? [y/n]:
    Your answer is y

Upvotes: 3

Related Questions