This repository has no description
1#!/usr/bin/env bash
2
3# This script can display our client certificates in a human readable format
4# It does so by setting up a custom git diff driver but only for the files matching the target pattern.
5# See the Git documentation for more details: https://git-scm.com/docs/gitattributes#_performing_text_diffs_of_binary_files
6
7TARGET_PATTERN='01/clients/certificates/*.enc.yaml'
8DIFF_DRIVER=client-certificate
9ROOT=$(git rev-parse --show-toplevel)
10
11RED='\e[31m'
12GREEN='\e[32m'
13ENDCOLOR='\e[0m'
14
15APPEND_DEFAULT_OPTION="-a"
16SYNOPSIS="Usage: $0 [$APPEND_DEFAULT_OPTION|--append-original] <client-cert-file> | [$APPEND_DEFAULT_OPTION|--append-original] init | clean | purge | test"
17
18if [ "$#" -eq 0 ]; then
19 echo "$SYNOPSIS" >&2
20 exit 1
21fi
22
23purge() {
24 echo Deleting cache...
25 git update-ref -d refs/notes/textconv/$DIFF_DRIVER
26 echo -e "Cache deleted \u2714"
27}
28
29clean() {
30 purge
31 echo Cleaning any existing config...
32 git config --unset diff.$DIFF_DRIVER.textconv
33 git config --unset diff.$DIFF_DRIVER.cachetextconv
34 sed -i "/diff=$DIFF_DRIVER/d" "$ROOT"/.git/info/attributes
35 echo -e "Done \u2714"
36}
37
38prepare() {
39 append_original_file=$1
40 echo Updating local git config...
41 git config diff.$DIFF_DRIVER.textconv "./tools/$(basename "$0") $append_original_file"
42 git config diff.$DIFF_DRIVER.cachetextconv true
43 echo -e "Done \u2714"
44
45 echo Updating local git attributes...
46 mkdir -p "$ROOT"/.git/info/
47 echo "$TARGET_PATTERN diff=$DIFF_DRIVER" >> "$ROOT"/.git/info/attributes
48 echo -e "Done \u2714"
49}
50
51exit_setup_status(){
52 status=$1
53 [ "$status" -eq 0 ] && echo -e "\n${GREEN}Setup ready \u2714$ENDCOLOR\n" \
54 || echo -e "\n${RED}\u2718 Something went wrong$ENDCOLOR\n"
55
56 exit "$status"
57}
58
59check_params() {
60 append_option=$1
61 path=$2
62
63 if [ "$append_option" != true ] && [ "$append_option" != false ]; then
64 echo "Wrong option: $append_option" >&2
65 echo "$SYNOPSIS" >&2
66 exit 1
67 fi
68
69 if [ ! -f "$path" ]; then
70 echo "File not found: $path" >&2
71 echo "$SYNOPSIS" >&2
72 exit 1
73 fi
74}
75
76prepare_for_diff_of() {
77 append_original_file=$1
78 original_file=$2
79
80 check_params "$append_original_file" "$original_file"
81
82 sops_decrypted=$(sops -d --config /dev/null "$original_file" 2>/dev/null)
83 is_sops_decrypted=$?
84
85 if [ "$is_sops_decrypted" -ne 0 ]; then
86 cat "$original_file"
87 exit 0
88 fi
89
90 sops_last_modified=$(yq '.sops.lastmodified' "$original_file")
91
92 certs=$(echo "$sops_decrypted" | yq '.proxy-in.certificates | with_entries(select(.key | test("\.crt$|\.pem$"))) | to_entries')
93 private_keys=$(echo "$sops_decrypted" | yq '.proxy-in.certificates | with_entries(select(.key == "*.key")) | to_entries')
94
95 certs_len=$(echo "$certs" | yq length)
96
97cat <<END
98 __________ ______ ______
99 / ___/ _ \\\____ \/ ___/
100 \___ ( <_> ) |_> >___ \\
101 /____ >____/| __/____ >
102 \/ |__| \/
103sops:
104 lastmodified: $sops_last_modified
105END
106
107
108 for((i=0;i<certs_len;i++)); do
109 ct="$((i + 1))/$certs_len"
110 cert_name=$(echo "$certs" | yq ".[$i].key")
111 cert="$(echo "$certs" | yq ".[$i].value" | base64 -d)"
112
113 cert_md5=$(echo "$cert" | openssl x509 -pubkey -noout | openssl md5)
114 cert_len="${#cert}"
115 cert_metadata=$(echo "$cert" | openssl x509 -ext subjectAltName -dates -issuer -noout | tail -n4 | awk '{$1=$1};1' | sed "s/^/ - /" )
116
117 privkey_name=$(echo "$private_keys" | yq ".[$i].key")
118 privkey="$(echo "$private_keys" | yq ".[$i].value" | base64 -d)"
119
120 privkey_md5=$(echo "$privkey" | openssl pkey -pubout | openssl md5)
121 privkey_len="${#privkey}"
122
123cat << END
124 __
125 ____ ____________/ |_
126 _/ ___\/ __ \_ __ \ __\\
127 \ \__\ ___/| | \/| |
128 \___ >___ >__| |__| $ct
129 \/ \/
130$cert_name:
131 metadata:
132$cert_metadata
133 md5: $cert_md5
134 length: $cert_len
135 __
136 | | __ ____ ___.__.
137 | |/ // __ < | |
138 | <\ ___/\___ |
139 |__|_ \\\___ > ____|
140 \/ \/\/
141$privkey_name:
142 md5: $privkey_md5
143 length: $privkey_len
144END
145 done
146
147
148 if [[ $append_original_file == true ]]; then
149cat <<END
150 .__ .__ .__
151 ___________|__| ____ |__| ____ _____ | |
152 / _ \_ __ \ |/ ___\| |/ \\\__ \ | |
153( <_> ) | \/ / /_/ > | | \/ __ \| |__
154 \____/|__| |__\___ /|__|___| (____ /____/
155 /_____/ \/ \/
156original_file:
157 $(< "$original_file")
158END
159 fi
160}
161
162case $1 in
163 -h|--help)
164 echo "$SYNOPSIS"
165 exit 0
166 ;;
167 # Manual: cleans up the diff driver and the git attribute, purges the cache
168 clean)
169 clean
170 exit $?
171 ;;
172 # Manual: sets up the diff driver and the git attribute, doesn't append the original file on diffs
173 init)
174 clean
175 prepare
176 status=$?
177 exit_setup_status "$status"
178 ;;
179 init-ci)
180 prepare
181 ;;
182 # Manual: purges the cache
183 purge)
184 purge
185 exit $?
186 ;;
187 # Manual: runs the test suite
188 test)
189 tests
190 ;;
191 "$APPEND_DEFAULT_OPTION"|--append-original)
192 case $2 in
193 # Manual: sets up the diff driver to append the original file on diffs
194 init)
195 clean
196 prepare $APPEND_DEFAULT_OPTION
197 status=$?
198 exit_setup_status "$status"
199 ;;
200 # Git: the target used by Git when it calls this script with the append option
201 # Manual: displays a single converted file with the original file appended
202 *)
203 append_original_file=true
204 original_file=$2
205 prepare_for_diff_of "$append_original_file" "$original_file"
206 ;;
207 esac
208 ;;
209 # Git: the target used by Git when it calls this script WITHOUT the append option
210 # Manual: displays a single converted file WITHOUT the original file appended
211 *)
212 append_original_file=false
213 original_file=$1
214 prepare_for_diff_of "$append_original_file" "$original_file"
215 ;;
216esac