-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdeploy.sh
executable file
·234 lines (188 loc) · 6.36 KB
/
deploy.sh
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#!/usr/bin/env bash
set -e
SITE="${1}"
TYPE="${2}"
DATA="${3}"
if [ "${SITE}" == '' ] || [ "${SITE}" == '-h' ] || [ "${SITE}" == '--help' ]; then
echo "USAGE: ${0} SITE (devices|render|infra|clean) [EXTRA_DATA]"
echo "Eg #1: ${0} global infra"
echo "Eg #2: ${0} indigo devices dal-indigo-fw-0"
echo "Eg #3: ${0} indigo render dal-indigo-wap-0"
echo "Eg #4: ${0} indigo clean"
exit 0
fi
echo "INFO: Site: ${SITE}"
echo "INFO: Type: ${TYPE}"
if [ "${DATA}" != '' ]; then
echo "INFO: Data: ${DATA}"
fi
if [ "${TYPE}" == "render" ]; then
TYPE='devices'
RENDER='true'
else
RENDER='false'
fi
SITE_FOLDER="sites/${SITE}"
TYPE_FOLDER="${SITE_FOLDER}/${TYPE}"
if [ ! -d "${SITE_FOLDER}" ]; then
echo "ERROR: Site '${SITE}' folder is missing (${SITE_FOLDER})"
exit 1
fi
if [ "${TYPE}" != 'clean' ] && [ ! -d "${TYPE_FOLDER}" ]; then
echo "ERROR: Type '${TYPE}' folder is missing (${TYPE_FOLDER})"
exit 1
fi
if [ -f 'secrets.yaml' ]; then
ROOT_SECRETS_FILE='secrets.yaml'
fi
if [ -f "${SITE_FOLDER}/secrets.yaml" ]; then
SITE_SECRETS_FILE="${SITE_FOLDER}/secrets.yaml"
fi
SITE_NETWORK_FILE="${SITE_FOLDER}/networks.yaml"
if [ ! -f "${SITE_NETWORK_FILE}" ]; then
echo "WARN: ${SITE_NETWORK_FILE} is missing"
fi
echo 'WARN: Deploying in 5s'
sleep 5
if [ "${TYPE}" == 'devices' ]; then
if [ "${DATA}" == 'global' ]; then
echo 'ERROR: Global has no networks'
exit 1
fi
# Ensure the rendered folder exists
mkdir -p "${TYPE_FOLDER}/rendered"
# Figure out if the device config is in parts
DEVICE_ARRAY=(${DATA//_/ })
DEVICE_NAME="${DEVICE_ARRAY[0]}"
DEVICE_PART="${DEVICE_ARRAY[1]}"
if [ "${DEVICE_PART}" == '' ] || [ "${DEVICE_PART}" == 'part1' ]; then
INITIAL_CONFIG='y'
echo 'INFO: Detected initial config'
else
INITIAL_CONFIG='n'
echo 'INFO: Detected additional config'
fi
# Deploy RouterOS config
CONFIG_FILE="${TYPE_FOLDER}/rendered/${DATA}.rsc"
TEMPLATE_FILE="${TYPE_FOLDER}/${DATA}.rsc.tmpl"
if [ ! -f "${TEMPLATE_FILE}" ]; then
echo "ERROR: Device template file missing: ${TEMPLATE_FILE}"
exit 1
fi
if [ "${DEVICE_UPGRADE}" != 'false' ]; then
DEVICE_UPGRADE='true'
fi
if [ "${REQUIRES_FLASH}" != 'true' ]; then
REQUIRES_FLASH='false'
fi
if [ "${USE_HTTP}" != 'true' ]; then
USE_HTTP='false'
fi
TMP_CONFIG_FILE=$(mktemp)
echo "{\"site\":\"${SITE}\", \"device\":\"${DATA}\", \"device_upgrade\": ${DEVICE_UPGRADE}}" > ${TMP_CONFIG_FILE}
yq \
--output-format json \
eval-all \
'. as $item ireduce ({}; . * $item )' \
${TMP_CONFIG_FILE} \
${ROOT_SECRETS_FILE} \
${SITE_SECRETS_FILE} \
"${SITE_NETWORK_FILE}" \
| \
tera \
--template "${TEMPLATE_FILE}" \
--out "${CONFIG_FILE}" \
--stdin
rm "${TMP_CONFIG_FILE}"
if [ ! -f "${CONFIG_FILE}" ]; then
echo "ERROR: Failed to render: ${CONFIG_FILE}"
exit 1
fi
if [ "${RENDER}" == 'true' ]; then
echo "INFO: Rendering done, exiting cleanly"
exit 0
fi
# Find the IP of the device from networks.yaml
DEVICE_IP=$(yq ".networks.MANAGEMENT.subranges.static.allocations | with_entries(select(.value == \"${DEVICE_NAME}\")) | keys | .[0]" "${SITE_NETWORK_FILE}")
if [ "${DEVICE_IP}" == '' ]; then
echo "ERROR: Couldn't extract device IP for '${DATA}' from '${SITE_NETWORK_FILE}'"
exit 1
fi
echo "INFO: Deploying ${CONFIG_FILE} => ${DEVICE_IP} (aka ${DATA})"
if [ "${MY_IP}" == '' ]; then
# Just give it go and fail if not
# This is usually the default interface on a Mac
MY_IP=$(ipconfig getifaddr en0)
if [ "${MY_IP}" == '' ]; then
echo "ERROR: Unable to determine your LAN IP, please set MY_IP"
exit 1
fi
fi
if [ "${ROUTEROS_USERNAME}" == '' ] || [ "${ROUTEROS_PASSWORD}" == '' ]; then
echo "ERROR: Missing 'ROUTEROS_USERNAME' or 'ROUTEROS_PASSWORD' env vars"
exit 1
fi
echo "INFO: Client IP: ${MY_IP}"
echo "INFO: About to apply device config in 2s"
sleep 2
# Upload our device config into the router
python3 -m http.server --bind 0.0.0.0 --directory "${TYPE_FOLDER}" 8000 &
PYTHON_PID=$!
sleep 2
if [ "${REQUIRES_FLASH}" == 'true' ]; then
DST_PATH=',"dst-path":"flash/"'
RUN_PATH='flash/'
else
DST_PATH=''
RUN_PATH=''
fi
if [ "${USE_HTTP}" == 'true' ]; then
SCHEME='http'
else
SCHEME='https'
fi
echo "INFO: Downloading 'rendered/${DATA}.rsc' onto device (via ${SCHEME})"
curl \
--insecure \
--user "${ROUTEROS_USERNAME}:${ROUTEROS_PASSWORD}" \
-X POST \
--header 'content-type: application/json' \
--data "{\"mode\":\"http\",\"url\":\"http://${MY_IP}:8000/rendered/${DATA}.rsc\"${DST_PATH}}" \
"${SCHEME}://${DEVICE_IP}/rest/tool/fetch"
echo ''
kill "${PYTHON_PID}"
if [ "${INITIAL_CONFIG}" == 'y' ]; then
echo "INFO: First Config - Resetting Device"
curl \
--insecure \
--user "${ROUTEROS_USERNAME}:${ROUTEROS_PASSWORD}" \
-X POST \
--header 'content-type: application/json' \
--data "{\"keep-users\":\"yes\",\"no-defaults\":\"yes\",\"run-after-reset\":\"${RUN_PATH}${DATA}.rsc\"}" \
"${SCHEME}://${DEVICE_IP}/rest/system/reset-configuration"
echo ''
echo 'INFO: Reset, wait for the reboot and double check'
else
echo "INFO: Further Config - Applying directly"
curl \
--insecure \
--user "${ROUTEROS_USERNAME}:${ROUTEROS_PASSWORD}" \
-X POST \
--header 'content-type: application/json' \
--data "{\"file-name\":\"${RUN_PATH}${DATA}.rsc\"}" \
"${SCHEME}://${DEVICE_IP}/rest/import"
echo ''
echo 'INFO: Applied, please check'
fi
elif [ "${TYPE}" == 'infra' ]; then
if [ "${AWS_PROFILE}" == '' ]; then
echo 'ERROR: Missing AWS_PROFILE env var'
exit 1
fi
rm -rf "${TYPE_FOLDER}/.terraform"
tofu -chdir="${TYPE_FOLDER}" init -upgrade
tofu -chdir="${TYPE_FOLDER}" apply
elif [ "${TYPE}" == 'clean' ]; then
rm -rf "${SITE_FOLDER}"/devices/*.rsc
rm -rf "${SITE_FOLDER}"/terraform/.terraform
fi