forked from StreisandEffect/streisand
-
Notifications
You must be signed in to change notification settings - Fork 0
/
streisand
executable file
·215 lines (186 loc) · 7.05 KB
/
streisand
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/usr/bin/env bash
# Streisand provisioning script
# Set errexit option to exit immediately on any non-zero status return
set -e
echo -e "\n\033[38;5;255m\033[48;5;234m\033[1m S T R E I S A N D \033[0m\n"
# This is where Ansible looks for local modules. Disable it, in the
# interests of consistency between installs.
export ANSIBLE_LIBRARY=
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
DEFAULT_SITE_VARS="$SCRIPT_DIR/global_vars/default-site.yml"
GLOBAL_VARS="$SCRIPT_DIR/global_vars/globals.yml"
HOME_DIR="$HOME/.streisand"
SITE_VARS="$HOME_DIR/site.yml"
# Include the check_ansible function from ansible_check.sh
source util/ansible_check.sh
function init_homedir() {
if [ ! -d "$HOME_DIR" ]; then
mkdir "$HOME_DIR"
echo "Created new Streisand home directory: $HOME_DIR"
fi
if [ ! -f "$SITE_VARS" ]; then
cp "$DEFAULT_SITE_VARS" "$SITE_VARS"
echo "Created new Streisand site vars file: $SITE_VARS"
fi
}
# check_python checks whether the 'python' interpreter is Python 2 or Python 3.
# If it is Python 2 then the inventory file is updated to set the
# ansible_interpretter host var explicitly
# function check_python() {
# return 0
# local PYTHON_VERSION
# PYTHON_VERSION="$(python --version 2>/dev/null)"
#
# if [[ -n $PYTHON_VERSION && ! $PYTHON_VERSION =~ ^Python\ 3\..* ]]; then
# local INVENTORY_DIR="$SCRIPT_DIR/inventories/"
# for INV_FILE in "$INVENTORY_DIR"/*; do
# sed "s|=python\$|=$(type python)|" "$INV_FILE" > "$INV_FILE.new"
# mv "$INV_FILE.new" "$INV_FILE"
# git -C "$INVENTORY_DIR" update-index --assume-unchanged "$INV_FILE" 2>/dev/null || true
# done
# fi
# }
# validate runs the validation role to check the consistency of the Streisand
# service vars (e.g. that at least one service is enabled after customization of
# $SITE_VARS).
function validate() {
local NEW_SERVER_PROVISIONING=$1
if [ -z "${NEW_SERVER_PROVISIONING}" ]; then
NEW_SERVER_PROVISIONING=true
fi
echo; echo; ansible-playbook \
--extra-vars="@$GLOBAL_VARS" \
--extra-vars="@$DEFAULT_SITE_VARS" \
--extra-vars="@$SITE_VARS" \
--extra-vars="streisand_new_server_provisioning=$NEW_SERVER_PROVISIONING" \
playbooks/validate.yml
}
# customize prompts the user to decide if they want to customize the Streisand
# installation. If the user wishes, the playbooks/customize.yml role is used to
# change the base installation by rewriting the $SITE_VARS file.
function customize() {
read -r -p "
Do you wish to customize which services Streisand will install?
By saying 'no' Streisand will use the settings configured in $SITE_VARS
Press enter to customize your installation: " confirm
case "$confirm" in
no) echo; echo "Installing Streisand services specified in $SITE_VARS";;
*) echo; echo "Confirmed. Customizing Streisand services.";
# NOTE(@cpu): We don't pass the other `--extra-vars` here because the
# customize `vars_prompt` will only happen if the vars aren't already
# set. If you pass the site/defaults in no prompting will happen.
echo; echo; ansible-playbook \
--extra-vars="@$GLOBAL_VARS" \
playbooks/customize.yml;;
esac
}
# run_genesis invokes the genesis playbook file specified by the first argument
# to the function, or `streisand.yml` if none is provided. It uses the second
# argument to the function as the inventory or `inventories/inventory` if none
# is provided.
function run_genesis() {
local GENESIS_PLAYBOOK=$1
local ASK_BECOME=""
if [ -z "${GENESIS_PLAYBOOK}" ]; then
GENESIS_PLAYBOOK=streisand.yml
fi
local GENESIS_INVENTORY=$2
if [ -z "${GENESIS_INVENTORY}" ]; then
GENESIS_INVENTORY=inventories/inventory
fi
# Customize the Streisand services that will be installed
customize
# Ensure that the customization hasn't resulted in something inconsistent
# NEW_SERVER_PROVISIONING can be False or True (0 or 1), tests if we need
# to check existence of SSH public key
if [ "$GENESIS_PLAYBOOK" != "existing-server.yml" ] && [ "$GENESIS_PLAYBOOK" != "localhost.yml" ]; then
validate true
else
validate false
fi
if [ -n "${SSH_USER}" ] && [ "$SSH_USER" != "root" ]; then
ASK_BECOME="--ask-become-pass"
fi
# Run the specified genesis playbook with the specified Ansible inventory
echo; echo; ansible-playbook \
-i $GENESIS_INVENTORY \
--extra-vars="@$GLOBAL_VARS" \
--extra-vars="@$DEFAULT_SITE_VARS" \
--extra-vars="@$SITE_VARS" \
$ASK_BECOME \
"playbooks/$GENESIS_PLAYBOOK"
}
# be_careful_friend asks you to pay attention because you're about to do
# something that might be impossible to undo!
function be_careful_friend() {
read -r -p "$1" confirm
case "$confirm" in
streisand) echo; echo "Confirmed. Continuing";;
*) echo; echo "Cancelling & exiting."; exit 1;;
esac
}
# local_provision handles provisioning the same machine as is running the
# Streisand script/Ansible. It performs an additional "ARE YOU SURE" step before
# invoking ansible-playbook. It uses the `inventory-local-provision` inventory
# file from the inventories directory as the Ansible inventory.
function local_provision() {
be_careful_friend "
LOCAL PROVISIONING WILL OVERWRITE CONFIGURATION ON **THIS** MACHINE.
THE MACHINE YOU ARE CURRENTLY EXECUTING THIS SHELL SCRIPT ON.
ARE YOU 100% SURE THAT YOU WISH TO CONTINUE?
Please enter the word 'streisand' to continue: "
run_genesis localhost.yml inventories/inventory-local-provision
}
function existing_server() {
read -r -p "What is the IP of the existing server: " SERVER_IP
be_careful_friend "
THIS WILL OVERWRITE CONFIGURATION ON THE EXISTING SERVER.
STREISAND ASSUMES $SERVER_IP IS A BRAND NEW UBUNTU INSTANCE AND WILL
NOT PRESERVE EXISTING CONFIGURATION OR DATA.
ARE YOU 100% SURE THAT YOU WISH TO CONTINUE?
Please enter the word 'streisand' to continue: "
# If ANSIBLE_SSH_USER is empty, default to root
if [ -z "${ANSIBLE_SSH_USER}" ]; then
SSH_USER='root'
# Otherwise, use whatever ANSIBLE_SSH_USER is set to as the SSH_USER
else
SSH_USER=${ANSIBLE_SSH_USER}
fi
# Create an inventory file string on the fly
read -r -d '' TEMPL << EOF || true
[localhost]
localhost ansible_connection=local ansible_python_interpreter=python3
[streisand-host]
$SERVER_IP ansible_user=$SSH_USER
EOF
# Create the inventory file
echo "$TEMPL" > inventories/inventory-existing
# Invoke the Streisand playbook on the existing server inventory
run_genesis existing-server.yml inventories/inventory-existing
}
# Make sure the system is ready for the Streisand playbooks
init_homedir
# check_python
check_ansible
# Figure out which genesis role to invoke
read -r -p "Which provider are you using?
1. Amazon
2. Azure
3. DigitalOcean
4. Google
5. Linode
6. Rackspace
7. localhost (Advanced)
8. Existing Server (Advanced)
: " reply
case "$reply" in
1) run_genesis amazon.yml;;
2) run_genesis azure.yml;;
3) run_genesis digitalocean.yml;;
4) run_genesis google.yml;;
5) run_genesis linode.yml;;
6) run_genesis rackspace.yml;;
7) local_provision;;
8) existing_server;;
*) echo; echo "Invalid provider selected."; exit 1;;
esac