

DATA="/data"
KES_DATA="${DATA}/kes"
VAULT_DATA="${DATA}/vault"
MINIO_DATA="${DATA}/minio"
KES_YML=${KES_DATA}/kes.yml
VAULT_CONFIG="${VAULT_DATA}/config/config.json"
VAULT_HCL="${VAULT_DATA}/config/kes-policy.hcl"
KES_SERV_KEY="${KES_DATA}/certs/kes-server.key"
KES_SERV_CERT="${KES_DATA}/certs/kes-server.cert"
MINIO_SERV_KEY="${KES_DATA}/certs/minio.key"
MINIO_SERV_CERT="${KES_DATA}/certs/minio.cert"
KES_INIT="${KES_DATA}/init_kes.sh"
VAULT_INIT="${VAULT_DATA}/config/init_vault.sh"
DIRS=("${KES_DATA}" "${VAULT_DATA}" "${VAULT_DATA}/config" "${KES_DATA}/certs" "${KES_DATA}/config" "${VAULT_DATA}/certs"  "${MINIO_DATA}/certs")
# Create necessary directories if they don't exist
for DIR in "${DIRS[@]}"; do
  if [ ! -d "$DIR" ]; then
#    log "Directory $DIR does not exist. Creating..."
    mkdir -p "$DIR"
  fi
done

#openssl ecparam -genkey -name prime256v1 | openssl ec -out ${KES_SERV_KEY} &&
#openssl req -new -x509 -days 365 -key ${KES_SERV_KEY} -out ${KES_SERV_CERT} -subj '/C=US/ST=California/L=foggieV/O=foggie/CN=fogworks.io' -addext 'subjectAltName=DNS:kes'
#
#openssl ecparam -genkey -name prime256v1 | openssl ec -out ${MINIO_SERV_KEY} &&
#openssl req -new -x509 -days 365 -key ${MINIO_SERV_KEY} -out ${MINIO_SERV_CERT} -subj '/C=US/ST=California/L=foggieV/O=foggie/CN=fogworks.io' -addext 'subjectAltName=DNS:kes'


cat > ${VAULT_HCL} <<'EOF'
path "kv/*" {
     capabilities = [ "create", "read", "delete" ]
}
EOF
cat > ${VAULT_CONFIG} << 'EOF'
{
    "listener":  {
      "tcp":  {
        "address":  "0.0.0.0:8200",
        "tls_disable":  true
      }
    },
    "backend": {
      "file": {
        "path": "/data/vault/data"
      }
    },
    "api_addr": "http://127.0.0.1:8200",
    "ui": true
  }
EOF

KES_SERV_KEY=${KES_DATA}/kes-server.key
KES_SERV_CERT=${KES_DATA}/kes-server.cert


cat >${VAULT_INIT} << 'EOF'
#!/bin/sh

USE_CN_MIRROR={{ use_cn_mirror }}

if [ "$USE_CN_MIRROR" = "true" ]; then
    echo "https://mirrors.aliyun.com/alpine/v3.18/main" > /etc/apk/repositories
    echo "https://mirrors.aliyun.com/alpine/v3.18/community" >> /etc/apk/repositories
    echo "https://mirrors.163.com/alpine/v3.18/main" >> /etc/apk/repositories
    echo "https://mirrors.163.com/alpine/v3.18/community" >> /etc/apk/repositories
    echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.18/main" >> /etc/apk/repositories
    echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.18/community" >> /etc/apk/repositories
fi


apk update
apk upgrade
apk add jq




  # 等待 Vault 服务完全启动
  echo "Waiting for Vault to start..."
  sleep 5
  count=0
  while [ $count -lt 30 ]; do
      status=$(vault status)
      echo $status
      echo $count

      # 检查状态输出中的关键字，例如"Sealed"或"Initialized"
      if echo "$status" | grep -q "Sealed"; then
          echo "Vault is sealed. Sleeping for 10 seconds..."
    break
          #sleep 10
      elif echo "$status" | grep -q "Initialized"; then
          echo "Vault is initialized but unsealed. Sleeping for 10 seconds..."
          #sleep 10
    break
      else
          echo "Vault is unsealed and active. Proceeding with the rest of the script."
          break
      fi

      # 如果超过5分钟还未成功启动，退出脚本
      if [ $count -eq 29 ]; then
          echo "Vault failed to start within 5 minutes. Exiting..."
          exit 1
      fi

      # 增加计数器并等待10秒
      count=$((count+1))
      sleep 10
  done

# Check if the init_done file exists
if [ ! -f /data/vault/data/.init_done ]; then

  # 初始化 Vault 并保存输出到一个文件
  vault operator init -format=json > /data/vault/config/init-output.json
fi

  # 解析 JSON 输出以获取 root token 和解封密钥
  root_token=$(jq -r .root_token /data/vault/config/init-output.json)
  unseal_key_1=$(jq -r ".unseal_keys_b64[0]" /data/vault/config/init-output.json)
  unseal_key_2=$(jq -r ".unseal_keys_b64[1]" /data/vault/config/init-output.json)
  unseal_key_3=$(jq -r ".unseal_keys_b64[2]" /data/vault/config/init-output.json)
  # 解封 Vault
  vault operator unseal "$unseal_key_1"
  vault operator unseal "$unseal_key_2"
  vault operator unseal "$unseal_key_3" 

  # 使用 root token 登录到 Vault
  vault login "$root_token"

if  [ ! -f /data/vault/data/.init_done ]; then
  # 启用 AppRole 认证
  vault secrets enable kv
  vault auth enable approle

  vault policy write kes-policy /data/vault/config/kes-policy.hcl
  # 创建一个新的 AppRole
  vault write auth/approle/role/kes-role token_num_uses=0 secret_id_num_uses=0 period=5m
  vault write    auth/approle/role/kes-role policies=kes-policy
  touch /data/vault/data/.init_done
fi
  vault read -field=role_id auth/approle/role/kes-role/role-id > /data/kes/config/role_id.txt
  vault write -f -field=secret_id auth/approle/role/kes-role/secret-id > /data/kes/config/secret_id.txt



EOF
chmod +x ${VAULT_INIT}
cat >${KES_INIT} << 'EOF'
#!/bin/bash

auth_approle_login_url="http://127.0.0.1:8200/v1/auth/approle/login"
while true; do
  response=$(curl -i -X PUT "$auth_approle_login_url")
  status_code=$(echo "$response" | awk '/HTTP/ {print $2}')

  if [ "$status_code" = "503" ]; then
    echo "Authentication endpoint is not accessible. Retrying..."
    sleep 1
  else
    # The endpoint is accessible, break out of the loop
    echo "Authentication endpoint is accessible. Proceeding with the script."
    break
  fi
done


USE_CN_MIRROR={{ use_cn_mirror }}

if [ "$USE_CN_MIRROR" = "true" ]; then
    echo "https://mirrors.aliyun.com/alpine/v3.18/main" > /etc/apk/repositories
    echo "https://mirrors.aliyun.com/alpine/v3.18/community" >> /etc/apk/repositories
    echo "https://mirrors.163.com/alpine/v3.18/main" >> /etc/apk/repositories
    echo "https://mirrors.163.com/alpine/v3.18/community" >> /etc/apk/repositories
    echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.18/main" >> /etc/apk/repositories
    echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.18/community" >> /etc/apk/repositories
fi



apk update
apk upgrade
apk add libcap sudo


if [ ! -f /data/kes/certs/kes-server.key ] ; then
  kes identity new kes_server --key=/data/kes/certs/kes-server.key --cert=/data/kes/certs/kes-server.cert --ip "127.0.0.1" --dns kes
  kes identity new minio_server --key=/data/minio/certs/minio-kes.key --cert=/data/minio/certs/minio-kes.cert --ip "127.0.0.1" --dns minio;
  cp /data/minio/certs/minio-kes.cert /usr/local/share/ca-certificates/minio-kes.crt ;
  cp /data/kes/certs/kes-server.cert /usr/local/share/ca-certificates/kes-server.crt  ;
  update-ca-certificates ;
fi


while true; do
    if [ -f /data/kes/config/role_id.txt ]; then
        export KES_APPROLE_ID=$(cat /data/kes/config/role_id.txt)
        break
    else
        echo "File role_id.txt does not exist, waiting..."
        sleep 5
    fi
done

while true; do
    if [ -f /data/kes/config/secret_id.txt ]; then
        export KES_APPROLE_SECRET=$(cat /data/kes/config/secret_id.txt)
        break
    else
        echo "File secret_id.txt does not exist, waiting..."
        sleep 5
    fi
done
export MINIO_IDENTITY=$(kes identity of /data/minio/certs/minio-kes.cert)
# Start the KES server in the background
envsubst < /etc/kes/kes-server.yml > /etc/kes/kes-server_m.yml
cat /etc/kes/kes-server_m.yml
sudo setcap cap_ipc_lock=+ep $(readlink -f $(which kes))
kes server --config=/etc/kes/kes-server_m.yml --auth=off &
# Wait for KES to start
while ! curl -k -i  --key /data/minio/certs/minio-kes.key --cert /data/minio/certs/minio-kes.cert https://127.0.0.1:7373; do
  sleep 1
done

# Create the key


max_retries=3
retry_interval=5  

command="kes key create my-minio-key"

retries=0
while [ $retries -lt $max_retries ]; do
    echo "Trying to execute command: $command (Attempt: $((retries + 1)))"
    
    $command
    exit_code=$?

    if [ $exit_code -eq 0 ]; then
        echo "Command executed successfully"
        break
    else
        echo "Command failed with exit code $exit_code. Retrying in $retry_interval seconds..."
        sleep $retry_interval
        retries=$((retries + 1))
    fi
done

#if [ $retries -eq $max_retries ]; then
#    echo "Maximum retries reached. Exiting script."
#    exit 1
#fi


tail -f /dev/null
EOF

