1+ #! /usr/bin/env bash
2+ # shellcheck disable=SC2087
3+ set -Eeo pipefail
4+
5+ # Read values from environment variables with defaults
6+ BASE_DIR=" /wire-server-deploy"
7+ TARGET_SYSTEM=" example.dev"
8+ CERT_MASTER_EMAIL=" certmaster@${TARGET_SYSTEM} "
9+
10+ # this IP should match the DNS A record value for TARGET_SYSTEM
11+ # assuming it to be the public address used by clients to reach public Address
12+ HOST_IP=" "
13+ if [ -z " $HOST_IP " ]; then
14+ HOST_IP=$( wget -qO- https://api.ipify.org)
15+ fi
16+
17+ # picking a node for calling traffic (3rd kube worker node)
18+ CALLING_NODE=$( kubectl get nodes --no-headers | tail -n 1 | awk ' {print $1}' )
19+ if [[ -z " $CALLING_NODE " ]]; then
20+ echo " Error: could not determine the last kube worker node via kubectl"
21+ exit 1
22+ fi
23+
24+ # Creates values.yaml from prod-values.example.yaml and secrets.yaml from prod-secrets.example.yaml
25+ # Works on all chart directories in $BASE_DIR/values/
26+ process_values () {
27+
28+ ENV=$1
29+ TYPE=$2
30+ charts=(fake-aws demo-smtp rabbitmq databases-ephemeral reaper wire-server webapp account-pages team-settings smallstep-accomp ingress-nginx-controller nginx-ingress-services coturn sftd cert-manager)
31+
32+ if [[ " $ENV " != " prod" ]] || [[ -z " $TYPE " ]] ; then
33+ echo " Error: This function only supports prod deployments with TYPE as values or secrets. ENV must be 'prod', got: '$ENV ' and '$TYPE '"
34+ exit 1
35+ fi
36+ timestp=$( date +" %Y%m%d_%H%M%S" )
37+
38+ for chart in " ${charts[@]} " ; do
39+ chart_dir=" $BASE_DIR /values/$chart "
40+ if [[ -d " $chart_dir " ]]; then
41+ if [[ -f " $chart_dir /${ENV} -${TYPE} .example.yaml" ]]; then
42+ if [[ ! -f " $chart_dir /${TYPE} .yaml" ]]; then
43+ cp " $chart_dir /${ENV} -${TYPE} .example.yaml" " $chart_dir /${TYPE} .yaml"
44+ echo " Used template ${ENV} -${TYPE} .example.yaml to create $chart_dir /${TYPE} .yaml"
45+ else
46+ echo " $chart_dir /${TYPE} .yaml already exists, archiving it and creating a new one."
47+ mv " $chart_dir /${TYPE} .yaml" " $chart_dir /${TYPE} .yaml.bak.$timestp "
48+ cp " $chart_dir /${ENV} -${TYPE} .example.yaml" " $chart_dir /${TYPE} .yaml"
49+ fi
50+ fi
51+ fi
52+ done
53+ }
54+
55+ # selectively setting values of following charts which requires additional values
56+ # wire-server, webapp, team-settings, account-pages, nginx-ingress-services, sftd and coturn
57+ configure_values () {
58+
59+ TEMP_DIR=$( mktemp -d)
60+ trap ' rm -rf $TEMP_DIR' EXIT
61+
62+ # to find IP address of calling NODE
63+ CALLING_NODE_IP=$( kubectl get node " $CALLING_NODE " -o jsonpath=' {.status.addresses[?(@.type=="InternalIP")].address}' )
64+
65+ # Fixing the hosts with TARGET_SYSTEM and setting the turn server
66+ sed -e " s/example.com/$TARGET_SYSTEM /g" \
67+ " $BASE_DIR /values/wire-server/values.yaml" > " $TEMP_DIR /wire-server-values.yaml"
68+
69+ # fixing the turnStatic values
70+ yq eval -i " .brig.turnStatic.v2 = [\" turn:$HOST_IP :3478\" , \" turn:$HOST_IP :3478?transport=tcp\" ]" " $TEMP_DIR /wire-server-values.yaml"
71+
72+ # Fixing the hosts in webapp team-settings and account-pages charts
73+ for chart in webapp team-settings account-pages; do
74+ sed " s/example.com/$TARGET_SYSTEM /g" " $BASE_DIR /values/$chart /values.yaml" > " $TEMP_DIR /$chart -values.yaml"
75+ done
76+
77+ # Setting certManager and DNS records
78+ sed -e ' s/useCertManager: false/useCertManager: true/g' \
79+ -e " /certmasterEmail:$/s/certmasterEmail:/certmasterEmail: $CERT_MASTER_EMAIL /" \
80+ -e " s/example.com/$TARGET_SYSTEM /" \
81+ " $BASE_DIR /values/nginx-ingress-services/values.yaml" > " $TEMP_DIR /nginx-ingress-services-values.yaml"
82+
83+ # Fixing SFTD hosts and setting the cert-manager to http01
84+ sed -e " s/webapp.example.com/webapp.$TARGET_SYSTEM /" \
85+ -e " s/sftd.example.com/sftd.$TARGET_SYSTEM /" \
86+ -e ' s/name: letsencrypt-prod/name: letsencrypt-http01/' \
87+ " $BASE_DIR /values/sftd/values.yaml" > " $TEMP_DIR /sftd-values.yaml"
88+
89+ # Setting coturn node IP values
90+ yq eval -i " .coturnTurnListenIP = \" $CALLING_NODE_IP \" " " $BASE_DIR /values/coturn/values.yaml"
91+ yq eval -i " .coturnTurnRelayIP = \" $CALLING_NODE_IP \" " " $BASE_DIR /values/coturn/values.yaml"
92+ yq eval -i " .coturnTurnExternalIP = \" $HOST_IP \" " " $BASE_DIR /values/coturn/values.yaml"
93+
94+ # Compare and copy files if different
95+ for file in wire-server-values.yaml webapp-values.yaml team-settings-values.yaml account-pages-values.yaml \
96+ nginx-ingress-services-values.yaml sftd-values.yaml; do
97+ if ! cmp -s " $TEMP_DIR /$file " " $BASE_DIR /values/${file% -values.yaml} /values.yaml" ; then
98+ cp " $TEMP_DIR /$file " " $BASE_DIR /values/${file% -values.yaml} /values.yaml"
99+ echo " Updating $BASE_DIR /values/${file% -values.yaml} /values.yaml"
100+ fi
101+ done
102+
103+ }
104+
105+ deploy_charts () {
106+
107+ local charts=(" $@ " )
108+ echo " Following charts will be deployed: ${charts[*]} "
109+
110+ for chart in " ${charts[@]} " ; do
111+ chart_dir=" $BASE_DIR /charts/$chart "
112+ values_file=" $BASE_DIR /values/$chart /values.yaml"
113+ secrets_file=" $BASE_DIR /values/$chart /secrets.yaml"
114+
115+ if [[ ! -d " $chart_dir " ]]; then
116+ echo " Error: Chart directory $chart_dir does not exist. Exiting fix the charts"
117+ exit 1
118+ fi
119+
120+ if [[ ! -f " $values_file " ]]; then
121+ echo " Warning: Values file $values_file does not exist. Deploying without values."
122+ values_file=" "
123+ fi
124+
125+ if [[ ! -f " $secrets_file " ]]; then
126+ secrets_file=" "
127+ fi
128+
129+ helm_command=" helm upgrade --install --wait --timeout=15m0s $chart $chart_dir "
130+
131+ if [[ -n " $values_file " ]]; then
132+ helm_command+=" --values $values_file "
133+ fi
134+
135+ if [[ -n " $secrets_file " ]]; then
136+ helm_command+=" --values $secrets_file "
137+ fi
138+
139+ echo " Deploying $chart as $helm_command "
140+ eval " $helm_command "
141+ done
142+
143+ # display running pods post deploying all helm charts in default namespace
144+ kubectl get pods --sort-by=.metadata.creationTimestamp
145+ }
146+
147+ deploy_cert_manager () {
148+
149+ kubectl get namespace cert-manager-ns || kubectl create namespace cert-manager-ns
150+ helm upgrade --install -n cert-manager-ns cert-manager " $BASE_DIR /charts/cert-manager" --values " $BASE_DIR /values/cert-manager/values.yaml"
151+
152+ # display running pods
153+ kubectl get pods --sort-by=.metadata.creationTimestamp -n cert-manager-ns
154+ }
155+
156+ deploy_calling_services () {
157+
158+ echo " Deploying sftd and coturn"
159+ # select the node to deploy sftd
160+ kubectl annotate node " $CALLING_NODE " wire.com/external-ip=" $HOST_IP " --overwrite
161+ helm upgrade --install sftd " $BASE_DIR /charts/sftd" --set " nodeSelector.kubernetes\\ .io/hostname=$CALLING_NODE " --values " $BASE_DIR /values/sftd/values.yaml"
162+
163+ kubectl annotate node " $CALLING_NODE " wire.com/external-ip=" $HOST_IP " --overwrite
164+ helm upgrade --install coturn " $BASE_DIR /charts/coturn" --set " nodeSelector.kubernetes\\ .io/hostname=$CALLING_NODE " --values " $BASE_DIR /values/coturn/values.yaml" --values " $BASE_DIR /values/coturn/secrets.yaml"
165+ }
166+
167+ main () {
168+ # Create prod-values.example.yaml to values.yaml and take backup
169+ process_values " prod" " values"
170+ # Create prod-secrets.example.yaml to secrets.yaml and take backup
171+ process_values " prod" " secrets"
172+
173+ # configure chart specific variables for each chart in values.yaml file
174+ configure_values
175+
176+ # deploying with external datastores, useful for prod setup
177+ deploy_charts cassandra-external elasticsearch-external minio-external fake-aws demo-smtp rabbitmq databases-ephemeral reaper wire-server webapp account-pages team-settings smallstep-accomp ingress-nginx-controller
178+
179+ # deploying cert manager to issue certs, by default letsencrypt-http01 issuer is configured
180+ deploy_cert_manager
181+
182+ # nginx-ingress-services chart needs cert-manager to be deployed
183+ deploy_charts nginx-ingress-services
184+
185+ # deploying sft and coturn services
186+ # not implemented yet
187+ deploy_calling_services
188+
189+ # print status of certs
190+ kubectl get certificate
191+ }
192+
193+ main
0 commit comments