006f550ecede1ecce402b50077f10480da9ea2b0
[icn.git] / deploy / site / common.sh
1 #!/usr/bin/env bash
2 set -eu -o pipefail
3
4 SITE_NAMESPACE="${SITE_NAMESPACE:-metal3}"
5
6 function _gpg_key_fp {
7     gpg --with-colons --list-secret-keys $1 | awk -F: '/fpr/ {print $10;exit}'
8 }
9
10 function create_gpg_key {
11     local -r key_name=$1
12
13     # Create an rsa4096 key that does not expire
14     gpg --batch --full-generate-key <<EOF
15 %no-protection
16 Key-Type: 1
17 Key-Length: 4096
18 Subkey-Type: 1
19 Subkey-Length: 4096
20 Expire-Date: 0
21 Name-Real: ${key_name}
22 EOF
23 }
24
25 function export_gpg_private_key {
26     gpg --export-secret-keys --armor "$(_gpg_key_fp $1)"
27 }
28
29 function sops_encrypt {
30     local -r yaml=$1
31     local -r yaml_dir=$(dirname ${yaml})
32
33     local -r key_name=$2
34     local -r key_fp=$(_gpg_key_fp ${key_name})
35
36     local site_dir=${yaml_dir}
37     if [[ $# -eq 3 ]]; then
38         site_dir=$3
39     fi
40
41     # Commit the public key to the repository so that team members who
42     # clone the repo can encrypt new files
43     echo "Creating ${yaml_dir}/sops.pub.asc with public key used to encrypt secrets"
44     gpg --export --armor "${key_fp}" >${site_dir}/sops.pub.asc
45
46     # Add .sops.yaml so users won't have to worry about specifying the
47     # proper key for the target cluster or namespace
48     echo "Creating ${site_dir}/.sops.yaml SOPS configuration file"
49     encrypted_regex="(bmcPassword|ca-key.pem|decryptionSecret|hashedPassword|emcoPassword|rootPassword)"
50     cat <<EOF > ${site_dir}/.sops.yaml
51 creation_rules:
52   - path_regex: .*.yaml
53     encrypted_regex: ^${encrypted_regex}$
54     pgp: ${key_fp}
55 EOF
56
57     if [[ $(grep -c $(echo ${encrypted_regex} | sed -e 's/(/\\(/g' -e 's/|/\\|/g' -e 's/)/\\)/') ${yaml}) -ne 0 ]]; then
58         sops --encrypt --in-place --config=${site_dir}/.sops.yaml ${yaml}
59     fi
60 }
61
62 function sops_decrypt {
63     local -r yaml=$1
64     local -r yaml_dir=$(dirname ${yaml})
65     local site_dir=${yaml_dir}
66     if [[ $# -eq 2 ]]; then
67         site_dir=$2
68     fi
69
70     if [[ $(grep -c "^sops:" ${yaml}) -ne 0 ]]; then
71         sops --decrypt --in-place --config=${site_dir}/.sops.yaml ${yaml}
72     fi
73 }
74
75 function flux_site_source_name {
76     local -r url=$1
77     local -r branch=$2
78     echo $(basename ${url})-${branch}
79 }
80
81 function flux_site_kustomization_name {
82     local -r url=$1
83     local -r branch=$2
84     local -r path=$3
85     echo $(flux_site_source_name ${url} ${branch})-site-$(basename ${path})
86 }
87
88 function flux_create_site {
89     local -r url=$1
90     local -r branch=$2
91     local -r path=$3
92     local -r key_name=$4
93
94     local -r source_name=$(flux_site_source_name ${url} ${branch})
95     local -r kustomization_name=$(flux_site_kustomization_name ${url} ${branch} ${path})
96     local -r key_fp=$(gpg --with-colons --list-secret-keys ${key_name} | awk -F: '/fpr/ {print $10;exit}')
97     local -r secret_name="${key_name}-sops-gpg"
98
99     flux create source git ${source_name} --url=${url} --branch=${branch}
100     gpg --export-secret-keys --armor "$(_gpg_key_fp ${key_name})" |
101         kubectl -n flux-system create secret generic ${secret_name} --from-file=sops.asc=/dev/stdin --dry-run=client -o yaml |
102         kubectl apply -f -
103     kubectl create namespace ${SITE_NAMESPACE} --dry-run=client -o yaml | kubectl apply -f -
104     flux create kustomization ${kustomization_name} --target-namespace=${SITE_NAMESPACE} --path=${path} --source=GitRepository/${source_name} --prune=true \
105          --decryption-provider=sops --decryption-secret=${secret_name}
106 }