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