Ansible - User input - ansible

If a user is prompted for some input and in this case they don't input anything and just press enter a " '' " value is put into the variable:
Example of the question:
- name: "vs_rule"
prompt: "enter the associated rule [Press enter to skip or enter in the following format: rule1 rule2]"
private: no
I'd like to use something similar to the below code but I don't want to pass the quotes onto the LTM (''), since the user will see the following error: "std exception: (basic_string::substr), exiting..."
Is there a way to filter the '' after the else and just send nothing to the LTM?
- "{{ 'tmsh list ltm rule ' + vs_rule + '' if vs_rule else '' |default([]) }}"

According to the vars_prompt documentation (here), you can add a default value for your variable, in the case the user does not enter any content.
On your case you could pass an empty string:
- name: "vs_rule"
prompt: "enter the associated rule [Press enter to skip or enter in the following format: rule1 rule2]"
private: no
default: ""
and the remaining "code" will work

Related

Ansible expect responses were feed twice

My Ansible code:
- expect:
command: virsh console myguest
responses:
'Escape character is': ''
'login:': 'root'
'root#:~ #': 'cli'
'root>': 'show version'
register: myreg
- debug: msg="{{ myreg.stdout_lines }}"
Execution of the code above showed each of my responses were feed twice. See sample outputs below:
"login: root",
"Last login: Mon May 10 03:57:15 on ttyu0",
"",
"root#:~ # root",
"",
"root: Command not found.",
"root#:~ # cli",
"",
"cli",
"root> cli",
" ^",
"unknown command.",
"",
"root> show version ",
......
Although the wrong feedings were not recognized so the results were still usable, but what might be wrong that caused the double feeds?
You have an ambiguous regex:
"Last login: Mon May 10 03:57:15 on ttyu0",
for sure matches login: just with a Last prefix
You likely want:
...
responses:
'^login:': 'root'
'^root#:~ #': 'cli'
since in your examples those strings occur at the leading edge of the output.
The rest of the malformity you're encourtering may straighten itself out once you and expect are on the same page

Jenkins Job Builder tries to expand parameter in a text field

I'm having some issues with a Jenkins Job Builder YAML file which contains an attribute (message-content) with "{}" characters in it:
- job-template:
id: senderjob
name: '{job-prefix}{id}'
command: 'echo "executed with $PARAMETER"'
type: freestyle
properties:
- ownership:
enabled: true
owner: user1
- build-discarder:
num-to-keep: 100
parameters:
- string:
name: PARAMETER
default: 'param'
description: 'default parameter for message.'
# template settings
builders:
- shell: '{command}'
publishers:
- ci-publisher:
override-topic: VirtualTopic.abcd.message
message-type: 'Custom'
message-properties: |
release-name=$PARAMETER
PARAMETER=$PARAMETER
message-content: '{"release-name" : "1.0"}'
The error reported is:
jenkins_jobs.errors.JenkinsJobsException: release-name parameter missing to format {release-name : 1.0}
So it looks like it's trying to expand "release-name" with a parameter.
So I have added it as parameter:
- string:
name: release-name
default: '1.0'
description: 'default parameter for release.'
It still reports the same error. Should I include the parameter somewhere else or escape it ? I couldn't find any YAML escape for "{}" characters though.
Any idea?
You should add the following to the configuration file
[job_builder]
allow_empty_variables = True
Link: https://jenkins-job-builder.readthedocs.io/en/latest/definition.html#job-template-1

Empty string in Ansible responses

I am developing RouterOS network module for Ansible 2.5.
RouterOS shell can print a few messages that should be detected in on_open_shell() event and either skipped or dismissed automatically. These are Do you want to see the software license? [Y/n]: and a few others, all of which are well documented here in the MikroTik Wiki.
Here is how I'm doing this:
def on_open_shell(self):
try:
if not prompt.strip().endswith(b'>'):
self._exec_cli_command(b' ')
except AnsibleConnectionFailure:
raise AnsibleConnectionFailure('unable to bypass license prompt')
It indeed does bypass the license prompt. However it seems that the \n response from the RouterOS device counts as a reply for the actual commands that follow. So, if I have two tasks in my playbook like this:
---
- hosts: routeros
gather_facts: no
connection: network_cli
tasks:
- routeros_command:
commands:
- /system resource print
- /system routerboard print
register: result
- name: Print result
debug: var=result.stdout_lines
This is the output I get:
ok: [example] => {
"result.stdout_lines": [
[
""
],
[
"uptime: 12h33m29s",
" version: 6.42.1 (stable)",
" build-time: Apr/23/2018 10:46:55",
" free-memory: 231.0MiB",
" total-memory: 249.5MiB",
" cpu: Intel(R)",
" cpu-count: 1",
" cpu-frequency: 2700MHz",
" cpu-load: 2%",
" free-hdd-space: 943.8MiB",
" total-hdd-space: 984.3MiB",
" write-sect-since-reboot: 7048",
" write-sect-total: 7048",
" architecture-name: x86",
" board-name: x86",
" platform: MikroTik"
]
]
}
As you can see, the output seems to be offset by 1. What should I do to correct this?
It turns out that the problem was in the regular expression that defined the shell prompt. I had it defined like this:
terminal_stdout_re = [
re.compile(br"\[\w+\#[\w\-\.]+\] ?>"),
# other cases
]
It did not match the end of prompt which caused Ansible to think that there was a newline before the actual command output. Here is the correct regexp:
terminal_stdout_re = [
re.compile(br"\[\w+\#[\w\-\.]+\] ?> ?$"),
# other cases
]

Chef - How to check if a bash block ran successfully and to ignore at the second instances

I am having a chef recipe with the following bash block -
bash "run_bash" do
user node[:value1][:user]
group node[:value1][:group]
cwd node[:value1][:install_dir] + '/tools/bin'
code <<-EOH
export MW_HOME=#{node[:value1][:mw_install_dir]}
export JAVA_HOME=#{node[:value1][:install_dir]}
export ORACLE_HOME=#{node[:value1][:install_dir]}
/usr/bin/expect -c 'spawn ./idmConfigTool.sh -configOAM input_file=#{Chef::Config[:file_cache_path]}/config.props
expect "Enter ID Store Bind DN password : "
send "#{OrcladminPassword}\r"
expect "Enter User Password for IDSTORE_PWD_SOFTWAREUSER: "
send "#{LDAPPassword }\r"
expect "Confirm User Password for IDSTORE_PWD_APPSOFTWAREUSER: "
send "#{AppLDAPPassword }\r"
expect "Enter User Password for IDSTORE_PWD_APP2ADMINUSER: "
send "#{App2AdminPassword }\r"
expect "Confirm User Password for IDSTORE_PWD_APP3ADMINUSER: "
send "#{App3AdminPassword}\r"
sleep 240
expect eof'
EOH
I am trying to run this recipe with chef-solo.So redundantly this recipe will run.
I need a solution to make this bash block to be idempotent. There are guard statements like not_if,only_if etc. But i could not find a way to implement those guards here.
I thought of one solution which is,Once this bash block ran successful , i can find the time stamp and compare it with the current time stamp when the next run is happening. If those didn't match i can ignore running it.This is just a brute force work a round i can think.
Kindly provide a better optimal solution for this scenario.
I'd go with a template an using notifications:
your_cookbook/templates/default/script.erb:
#!/bin/bash
export MW_HOME=<%= node[:value1][:mw_install_dir] %>
export JAVA_HOME=<%= node[:value1][:install_dir] %>
export ORACLE_HOME=<%= node[:value1][:install_dir]}
/usr/bin/expect -c 'spawn ./idmConfigTool.sh -configOAM input_file=<%=
Chef::Config[:file_cache_path] %>/config.props
expect "Enter ID Store Bind DN password : "
send "<%= #OrcladminPassword %>\r"
expect "Enter User Password for IDSTORE_PWD_SOFTWAREUSER: "
send "<%= #LDAPPassword %>\r"
expect "Confirm User Password for IDSTORE_PWD_APPSOFTWAREUSER: "
send "<%= #AppLDAPPassword %>\r"
expect "Enter User Password for IDSTORE_PWD_APP2ADMINUSER: "
send "<%= #App2AdminPassword %>\r"
expect "Confirm User Password for IDSTORE_PWD_APP3ADMINUSER: "
send "<%= #App3AdminPassword %>\r"
sleep 240
expect eof
you_cookbook/recipes/default.rb:
execute 'my_installer' do
command '/usr/local/bin/my_script'
action :noting # For it not to run on each converge by default
end
template '/usr/local/bin/my_script' do
source 'script.erb'
mode '0600'
variables(
'OrcladminPassword' => <how you set the value>,
'LDAPPassword' => <...>,
'AppLDAPPassword' => <...>,
'App2AdminPassword' => <...>,
'App3AdminPassword' => <...>
)
notifies :run,execute[my_installer]
end
You may add a , :immediately at the end of the notifies line to trigger the execution just have the template have been rendered.
This way chef will trigger the execute resource only when the template change.
This doesn't take in account cases where your install may not work and chef won't retry it in this case, the installation will stay failed.
All in all I would work with the product editor to have a kind of package to avoid this kind of brittle install.

Using Heat template parameter value in bash script

In a bash script in a Heat template, is it possible to use a parameter value from that template?
Yes, according to the Heat Orchestration Template specification, you can accomplish this with the str_replace function. They give an example that uses str_replace, together with get_param, to use a parameter value DBRootPassword in a bash script:
parameters:
DBRootPassword:
type: string
label: Database Password
description: Root password for MySQL
hidden: true
resources:
my_instance:
type: OS::Nova::Server
properties:
# general properties ...
user_data:
str_replace:
template: |
#!/bin/bash
echo "Hello world"
echo "Setting MySQL root password"
mysqladmin -u root password $db_rootpassword
# do more things ...
params:
$db_rootpassword: { get_param: DBRootPassword }
Each key in params is replaced in template with its value. Since $db_rootpassword's value is set to the result of get_param, that means the parameter is passed into the bash script wherever $db_rootpassword is used.

Resources