apiVersion: v1
kind: ConfigMap
metadata:
  name: gitlab-shared-secrets
  namespace: public-service
  labels:
    app: gitlab
    component: shared-secrets
  annotations:
    "helm.sh/hook": pre-install,pre-upgrade
    "helm.sh/hook-weight": "-3"
    "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation
data:
  generate-secrets: |
    namespace=public-service
    env=production
    pushd $(mktemp -d)

    function gen_random(){
      head -c 4096 /dev/urandom | LC_CTYPE=C tr -cd $1 | head -c $2
    }
    
    function fetch_rails_value(){
      local value=$(yq read $1 "${2}")

      if [ "${value}" != "null" ]; then echo "${value}"; fi
    }
    
    function label_secret(){
      local secret_name=$1

      kubectl --namespace=$namespace label \
        secret $secret_name $(echo 'app.kubernetes.io/name=mygitlab' | sed -E 's/=[^ ]*/-/g')               #helm渲染时指定名称为mygitlab，mygitlab不要修改为gitlab，否则postgresql无法使用secrets
    
      kubectl --namespace=$namespace label \
        --overwrite \
        secret $secret_name app=gitlab component=shared-secrets
    }
    
    function generate_secret_if_needed(){
      local secret_args=( "${@:2}")
      local secret_name=$1
      if ! $(kubectl --namespace=$namespace get secret $secret_name > /dev/null 2>&1); then
        kubectl --namespace=$namespace create secret generic $secret_name ${secret_args[@]}
      else
        echo "secret \"$secret_name\" already exists"
      fi;
      label_secret $secret_name
    }
    
    generate_secret_if_needed "gitlab-initial-root-password" --from-literal="password"=$(gen_random 'a-zA-Z0-9' 64)
    
    generate_secret_if_needed "gitlab-redis-secret" --from-literal="secret"=$(gen_random 'a-zA-Z0-9' 64)
    
    generate_secret_if_needed "gitlab-postgresql-password" --from-literal=postgresql-password=$(gen_random 'a-zA-Z0-9' 64) --from-literal=postgresql-postgres-password=$(gen_random 'a-zA-Z0-9' 64)
    
    generate_secret_if_needed "gitlab-shell-secret" --from-literal="secret"=$(gen_random 'a-zA-Z0-9' 64)
    
    generate_secret_if_needed "gitlab-gitaly-secret" --from-literal="token"=$(gen_random 'a-zA-Z0-9' 64)
    
    generate_secret_if_needed "gitlab-minio-secret" --from-literal=accesskey=$(gen_random 'a-zA-Z0-9' 64) --from-literal=secretkey=$(gen_random 'a-zA-Z0-9' 64)
    
    generate_secret_if_needed "gitlab-runner-secret" --from-literal=runner-registration-token=$(gen_random 'a-zA-Z0-9' 64) --from-literal=runner-token=""
    
    mkdir -p certs
    openssl req -new -newkey rsa:4096 -subj "/CN=gitlab-issuer" -nodes -x509 -keyout certs/registry-example-com.key -out certs/registry-example-com.crt -days 3650
    generate_secret_if_needed "gitlab-registry-secret" --from-file=registry-auth.key=certs/registry-example-com.key --from-file=registry-auth.crt=certs/registry-example-com.crt
    
    if [ -n "$env" ]; then
      rails_secret="gitlab-rails-secret"

      if $(kubectl --namespace=$namespace get secret $rails_secret > /dev/null 2>&1); then
        kubectl --namespace=$namespace get secret $rails_secret -o jsonpath="{.data.secrets\.yml}" | base64 --decode > secrets.yml
        secret_key_base=$(fetch_rails_value secrets.yml "${env}.secret_key_base")
        otp_key_base=$(fetch_rails_value secrets.yml "${env}.otp_key_base")
        db_key_base=$(fetch_rails_value secrets.yml "${env}.db_key_base")
        openid_connect_signing_key=$(fetch_rails_value secrets.yml "${env}.openid_connect_signing_key")
        ci_jwt_signing_key=$(fetch_rails_value secrets.yml "${env}.ci_jwt_signing_key")
      fi;
    
      secret_key_base="${secret_key_base:-$(gen_random 'a-f0-9' 128)}" # equavilent to secureRandom.hex(64)
      otp_key_base="${otp_key_base:-$(gen_random 'a-f0-9' 128)}" # equavilent to secureRandom.hex(64)
      db_key_base="${db_key_base:-$(gen_random 'a-f0-9' 128)}" # equavilent to secureRandom.hex(64)
      openid_connect_signing_key="${openid_connect_signing_key:-$(openssl genrsa 2048)}"
      ci_jwt_signing_key="${ci_jwt_signing_key:-$(openssl genrsa 2048)}"
    
      cat << EOF > rails-secrets.yml
    apiVersion: v1
    kind: Secret
    metadata:
      name: $rails_secret
    type: Opaque
    stringData:
      secrets.yml: |-
        $env:
          secret_key_base: $secret_key_base
          otp_key_base: $otp_key_base
          db_key_base: $db_key_base
          openid_connect_signing_key: |
    $(echo "${openid_connect_signing_key}" | awk '{print "        " $0}')
          ci_jwt_signing_key: |
    $(echo "${ci_jwt_signing_key}" | awk '{print "        " $0}')
    EOF
      kubectl --validate=false --namespace=$namespace apply -f rails-secrets.yml
      label_secret $rails_secret
    fi
    
    ssh-keygen -A
    mkdir -p host_keys
    cp /etc/ssh/ssh_host_* host_keys/
    generate_secret_if_needed "gitlab-shell-host-keys" --from-file host_keys
    
    generate_secret_if_needed "gitlab-workhorse-secret" --from-literal="shared_secret"=$(gen_random 'a-zA-Z0-9' 32 | base64)
    
    generate_secret_if_needed "gitlab-registry-httpsecret" --from-literal="secret"=$(gen_random 'a-z0-9' 128 | base64 -w 0)
