-
Notifications
You must be signed in to change notification settings - Fork 0
/
ansible-by-proxy
executable file
·180 lines (135 loc) · 4.43 KB
/
ansible-by-proxy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/usr/bin/env bash
set -e
HERE=$(dirname "$0")
HOST=$(basename "$0")
INVENTORY=${HERE}/ansible/inventory
function usage() {
cat <<EOF >&2
Usage: ${HOST} [-n|--dry-run] {ansible-module} {arguments} -- [arguments]
or
Usage: ${HOST} [-n|--dry-run] [-r|--retry] {ansible-playbook} -- [arguments]
In the first form, the invocation expands to the following shell invocation:
ansible -i ${INVENTORY} ${HOST} -m {ansible-module} -a {arguments} \
[arguments]
In the second form, the invocation expands to:
ansible-playbook -i ${INVENTORY} -l ${HOST} {ansible-playbook}
The {ansible-playbook} can be specified either as a filename relative to
${HERE}/ansible/ or as a full path or as the basename excluding the .yml
extension that refers to a file named ${HERE}/ansible/{ansible-playbook}.yml.
The second form also allows specifying a -r or --retry option that will further
limit the host selection based on a {ansible-playbook}.retry file that the
script expects to find adjacent to the playbook.
In both forms, the -n or --dry-run options cause the command to be printed
without executing.
The list of ansible playbooks that are available for use are:
EOF
for pb in ${HERE}/ansible/*.yml ; do
echo " $(basename $pb)"
done
exit 1
}
if [[ "${HOST}" == "ansible-by-proxy" ]]; then
cat <<EOF >&2
This script isn't meant to be invoked as-is. Instead create a symlink to this
script as follows:
$ ln -s ansible-by-proxy groupname
... where "groupname" is a group defined in ${INVENTORY}.
EOF
exit 1
fi
POSITIONAL=()
REST=()
while [[ $# -gt 0 ]]; do
ARG=$1
case $ARG in
-h | --help )
usage
;;
-n | --dry-run | --dryrun )
ANSIBLEPREFIX=echo
shift
;;
-r | --retry )
RETRY=1
shift
;;
-- )
shift
REST=$@
shift $#
;;
-* )
echo "Unrecognized option ${ARG}" >&2
usage
;;
* )
if [[ ${#POSITIONAL[@]} -ge 2 ]]; then
REST="$@"
shift $#
else
POSITIONAL+=("$ARG")
shift
fi
;;
esac
done
# Use pipelining instead of copying a script into the target VM. This saves us
# one SSH session.
export ANSIBLE_SSH_PIPELINING=True
# Free scheduling means that tasks are run on each host indepdently. The
# default is for all hosts to complete each step for the playbook to proceed to
# the next step.
export ANSIBLE_STRATEGY=free
# Improve readability of ansible output. The default is to spit out unformatted
# JSON.
# To get a list of callback plugins, use: ansible-doc -t callback -l
export ANSIBLE_STDOUT_CALLBACK=unixy
# Enable use of callback plugins for ad-hoc commands.
export ANSIBLE_LOAD_CALLBACK_PLUGINS=1
# Don't spam syslog.
export ANSIBLE_DEFAULT_NO_TARGET_SYSLOG=1
log_dir=${HOME}/log
log_name_suffix=$(date +%Y-%m-%d-%H-%M-%S)
if [[ ! -d ${log_dir} ]]; then
mkdir -p ${log_dir}
fi
if [[ ${#POSITIONAL[@]} -eq 0 ]]; then
usage
fi
if [[ ${#POSITIONAL[@]} -eq 2 ]]; then
${ANSIBLEPREFIX} ansible -i "${INVENTORY}" ${HOST} -m "${POSITIONAL[0]}" -a "${POSITIONAL[1]}" "${REST[@]}"
else
MODULE=${POSITIONAL[0]}
function prep_logging() {
module_name=$(basename -s .yml ${MODULE})
latest_log_name=${log_dir}/${module_name}-latest.log
export ANSIBLE_LOG_PATH=${log_dir}/${module_name}-${log_name_suffix}.log
if [[ -f ${latest_log_name} ]]; then
rm ${latest_log_name}
fi
ln -s ${ANSIBLE_LOG_PATH} ${latest_log_name}
}
if [[ -n "$RETRY" ]]; then
LIMIT="--limit @${HERE}/ansible/${MODULE}.retry"
fi
# If the second argument is a playbook specified either as a relative path,
# or as just a playbook name, then we invoke the playbook and constrain the
# host selection to $HOST.
if [[ -f "${MODULE}" ]]; then
prep_logging
${ANSIBLEPREFIX} ansible-playbook -i ${INVENTORY} --limit ${HOST} ${LIMIT} "${MODULE}" "${REST[@]}"
echo Log written to ${ANSIBLE_LOG_PATH}
elif [[ -f "${HERE}/ansible/${MODULE}.yml" ]]; then
prep_logging
${ANSIBLEPREFIX} ansible-playbook -i ${INVENTORY} --limit ${HOST} ${LIMIT} "${HERE}/ansible/${MODULE}.yml" "${REST[@]}"
echo Log written to ${ANSIBLE_LOG_PATH}
# Otherwise, we treat it as an ad hoc command. MODULE now refers to an
# ansible module, and the next non-switch parameter is the argument for that
# module.
else
${ANSIBLEPREFIX} ansible -i ${INVENTORY} ${HOST} -m ${MODULE} "${REST[@]}"
fi
fi
if [[ "$(type -t alert)" == "function" ]]; then
alert "Completed ${MODULE}"
fi