generated from onedr0p/cluster-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
configure
executable file
·226 lines (205 loc) · 7.69 KB
/
configure
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
#!/usr/bin/env bash
set -o errexit
set -o pipefail
# shellcheck disable=SC2155
export PROJECT_DIR=$(git rev-parse --show-toplevel)
# shellcheck disable=SC2155
export SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt
# shellcheck disable=SC1091
source "${PROJECT_DIR}/.config.env"
show_help() {
cat << EOF
Usage: $(basename "$0") <options>
-h, --help Display help
--verify Verify .config.env settings
EOF
}
main() {
local verify=
parse_command_line "$@"
if [[ "${verify}" == 1 ]]; then
verify_start
verify_binaries
verify_age
verify_git_repository
verify_success
else
# generate sops configuration file
envsubst < "${PROJECT_DIR}/tmpl/.sops.yaml" \
> "${PROJECT_DIR}/.sops.yaml"
# generate cluster settings
envsubst < "${PROJECT_DIR}/tmpl/kubernetes/flux/cluster-settings.yaml" \
> "${PROJECT_DIR}/kubernetes/flux/vars/cluster-settings.yaml"
envsubst < "${PROJECT_DIR}/tmpl/kubernetes/flux/cluster.yaml" \
> "${PROJECT_DIR}/kubernetes/flux/config/cluster.yaml"
# generate secrets
envsubst < "${PROJECT_DIR}/tmpl/kubernetes/cluster-secrets.sops.yaml" \
> "${PROJECT_DIR}/kubernetes/flux/vars/cluster-secrets.sops.yaml"
sops --encrypt --in-place "${PROJECT_DIR}/kubernetes/flux/vars/cluster-secrets.sops.yaml"
envsubst < "${PROJECT_DIR}/tmpl/kubernetes/cert-manager-secret.sops.yaml" \
> "${PROJECT_DIR}/kubernetes/apps/cert-manager/cert-manager/issuers/secret.sops.yaml"
sops --encrypt --in-place "${PROJECT_DIR}/kubernetes/apps/cert-manager/cert-manager/issuers/secret.sops.yaml"
envsubst < "${PROJECT_DIR}/tmpl/kubernetes/external-dns-secret.sops.yaml" \
> "${PROJECT_DIR}/kubernetes/apps/networking/external-dns/app/secret.sops.yaml"
sops --encrypt --in-place "${PROJECT_DIR}/kubernetes/apps/networking/external-dns/app/secret.sops.yaml"
setup_github_webhook
setup_weave_gitops
success
fi
}
parse_command_line() {
while :; do
case "${1:-}" in
-h|--help)
show_help
exit
;;
--verify)
verify=1
;;
*)
break
;;
esac
shift
done
if [[ -z "$verify" ]]; then
verify=0
fi
}
_has_binary() {
command -v "${1}" >/dev/null 2>&1 || {
_log "ERROR(${FUNCNAME[0]})" "${1} is not installed or not found in \$PATH"
exit 1
}
_log "INFO(${FUNCNAME[0]})" "Found CLI tool ${1} and it is in \$PATH"
}
_has_optional_envar() {
local option="${1}"
# shellcheck disable=SC2015
[[ "${!option}" == "" ]] && {
_log "WARN" "Unset optional variable ${option}"
} || {
_log "INFO(${FUNCNAME[0]})" "Found variable '${option}' with value '${!option}'"
}
}
_has_envar() {
local option="${1}"
local secret="${2:-false}"
local value=
# shellcheck disable=SC2015
if [[ "${!option}" == "" ]]; then
_log "ERROR(${FUNCNAME[0]})" "Unset variable ${option}"
exit 1
fi
value="${!option}"
if [[ $secret == "true" ]]; then
value="***"
fi
_log "INFO(${FUNCNAME[0]})" "Found variable '${option}' with value '${value}'"
}
_has_valid_ip() {
local ip="${1}"
local variable_name="${2}"
if ! ipcalc "${ip}" | awk 'BEGIN{FS=":"; is_invalid=0} /^INVALID/ {is_invalid=1; print $1} END{exit is_invalid}' >/dev/null 2>&1; then
_log "INFO(${FUNCNAME[0]})" "Variable '${variable_name}' has an invalid IP address '${ip}'"
exit 1
else
_log "INFO(${FUNCNAME[0]})" "Variable '${variable_name}' has a valid IP address '${ip}'"
fi
}
verify_age() {
_has_envar "BOOTSTRAP_AGE_PUBLIC_KEY"
_has_envar "SOPS_AGE_KEY_FILE"
if [[ ! "$BOOTSTRAP_AGE_PUBLIC_KEY" =~ ^age.* ]]; then
_log "ERROR(${FUNCNAME[0]})" "BOOTSTRAP_AGE_PUBLIC_KEY does not start with age"
exit 1
else
_log "INFO(${FUNCNAME[0]})" "Age public key is in the correct format"
fi
if [[ ! -f ~/.config/sops/age/keys.txt ]]; then
_log "ERROR(${FUNCNAME[0]})" "Unable to find Age file keys.txt in ~/.config/sops/age"
exit 1
else
_log "INFO(${FUNCNAME[0]})" "Found Age public key '${BOOTSTRAP_AGE_PUBLIC_KEY}'"
fi
}
verify_binaries() {
_has_binary "age"
_has_binary "envsubst"
_has_binary "flux"
_has_binary "git"
_has_binary "gitops"
_has_binary "ipcalc"
_has_binary "jq"
_has_binary "pip3"
_has_binary "sops"
_has_binary "ssh"
_has_binary "go-task"
_has_binary "terraform"
_has_binary "yq"
if ! [[ "$(sops --version)" =~ 3\.[0-9]+\.[0-9]+ ]]; then
_log "ERROR(${FUNCNAME[0]})" "Incompatible sops version, make sure you are using the latest release of github.com/mozilla/sops"
exit 1
fi
if ! [[ "$(yq --version)" =~ 3\.[0-9]+\.[0-9]+ ]]; then
_log "ERROR(${FUNCNAME[0]})" "Incompatible yq version, make sure you are using the latest release of github.com/mikefarah/yq"
exit 1
fi
}
verify_git_repository() {
_has_envar "BOOTSTRAP_GIT_REPOSITORY"
export GIT_TERMINAL_PROMPT=0
pushd "$(mktemp -d)" >/dev/null 2>&1
[ "$(git ls-remote "${BOOTSTRAP_GIT_REPOSITORY}" 2> /dev/null)" ] || {
_log "ERROR(${FUNCNAME[0]})" "Unable to find the remote Git repository '${BOOTSTRAP_GIT_REPOSITORY}'"
exit 1
}
popd >/dev/null 2>&1
export GIT_TERMINAL_PROMPT=1
}
verify_start() {
_log "INFO(${FUNCNAME[0]})" "Starting verification of .config.env, please wait..."
}
verify_success() {
_log "INFO(${FUNCNAME[0]})" "All checks passed!"
_log "INFO(${FUNCNAME[0]})" "Run the script without --verify to template all the files out"
exit 0
}
setup_github_webhook() {
_has_envar "BOOTSTRAP_FLUX_GITHUB_WEBHOOK_SECRET"
WEBHOOK_SECRET="${BOOTSTRAP_FLUX_GITHUB_WEBHOOK_SECRET}"
if [[ "${WEBHOOK_SECRET}" == "generated" ]]; then
WEBHOOK_SECRET="$(openssl rand -base64 30)"
fi
export BOOTSTRAP_FLUX_GITHUB_WEBHOOK_SECRET="${WEBHOOK_SECRET}"
_log "INFO(${FUNCNAME[0]})" "Using GitHub Token '${WEBHOOK_SECRET}' for Flux"
envsubst < "${PROJECT_DIR}/tmpl/kubernetes/github-webhook-token-secret.sops.yaml" \
> "${PROJECT_DIR}/kubernetes/apps/flux-system/addons/webhooks/github/secret.sops.yaml"
sops --encrypt --in-place "${PROJECT_DIR}/kubernetes/apps/flux-system/addons/webhooks/github/secret.sops.yaml"
}
setup_weave_gitops() {
_has_envar "BOOTSTRAP_WEAVE_GITOPS_ADMIN_PASSWORD"
WEAVE_GITOPS_ADMIN_PASSWORD="${BOOTSTRAP_WEAVE_GITOPS_ADMIN_PASSWORD}"
if [[ "${WEAVE_GITOPS_ADMIN_PASSWORD}" == "generated" ]]; then
WEAVE_GITOPS_ADMIN_PASSWORD="$(openssl rand -base64 30)"
fi
export BOOTSTRAP_WEAVE_GITOPS_ADMIN_PASSWORD="${WEAVE_GITOPS_ADMIN_PASSWORD}"
_log "INFO(${FUNCNAME[0]})" "Using admin password '${WEAVE_GITOPS_ADMIN_PASSWORD}' for Weave Gitops"
# Convert password to bcrypt hash
# shellcheck disable=SC2155
export BOOTSTRAP_WEAVE_GITOPS_ADMIN_PASSWORD="$(echo -n "${BOOTSTRAP_WEAVE_GITOPS_ADMIN_PASSWORD}" | gitops get bcrypt-hash)"
envsubst < "${PROJECT_DIR}/tmpl/kubernetes/weave-gitops-secret.sops.yaml" \
> "${PROJECT_DIR}/kubernetes/apps/flux-system/weave-gitops/app/secret.sops.yaml"
sops --encrypt --in-place "${PROJECT_DIR}/kubernetes/apps/flux-system/weave-gitops/app/secret.sops.yaml"
}
success() {
_log "INFO(${FUNCNAME[0]})" "All files have been templated, proceed to the next steps outlined in the README"
exit 0
}
_log() {
local type="${1}"
local msg="${2}"
printf 'timestamp="%s" type="%s" message="%s"\n' "$(date)" "${type}" "${msg}"
}
main "$@"