#!/usr/bin/env bash

#VARIABLES
export SCRIPT_FULL_PATH=$(dirname "$0")

##FUNCTIONS
# https://stackoverflow.com/questions/1527049/how-can-i-join-elements-of-an-array-in-bash
join_by() {
  local d=${1-} f=${2-}
  if shift 2; then
    printf %s "$f" "${@/#/$d}"
  fi
}

mkstring() {
	local start=$1
	local separator=$2
	local end=$3
	shift 3

	if [ $# -gt 0 ]; then
    printf $start
    join_by $separator $*
    printf $end
  fi
}

md5all() {
    all_hash=$(mktemp)
    for name in $*; do
        find $name -type f -exec cat {} \; | md5sum | cut -f1 -d ' ' >> $all_hash
    done;
    cat $all_hash | md5sum | cut -f1 -d ' '
}

log() {
  echo "$*" >&2
}
#!/usr/bin/env bash

check_args() {
  if [ -z $2 ] || [ "$1" != "$2" ]; then
    echo >&2 "missing argument $1"
    return 1
  fi
}

check_env_vars() {
  ArgsCount=$1 && shift
  for ((i = 0; i < $ArgsCount; i++)); do
    if [[ -z "${!1}" ]]; then
      echo >&2 "missing ENV $1"
      return 1
    fi
    shift
  done
}

extract_arg() {
  name=$1
  passed=$2
  value=$3
  if [ "--$name" != "$passed" ]; then
    echo "missing argument $name"
    exit 1
  fi
  eval $name='$value'
}

extract_args() {
  declare -a Array_Args
  ArgsCount=$1 && shift
  for ((i = 0; i < $ArgsCount; i++)); do
    Array_Args[i]=$1 && shift
  done
  for ArgName in "${Array_Args[@]}"; do
    extract_arg "$ArgName" $* && shift 2
  done
}

#!/usr/bin/env bash

aws_ecr_login() {
  PATH=/root/.local/bin:$PATH

  aws ecr get-login-password \
    | docker login --username AWS --password-stdin 949316342391.dkr.ecr.eu-west-1.amazonaws.com \
    || (echo "you should update to AWS CLI version 2 https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-mac.html " $(aws ecr get-login --region=eu-west-1 --no-include-email) )
}

aws_ecr_token() {
  aws ecr get-authorization-token --region=eu-west-1 --output text --query 'authorizationData[].authorizationToken'
}


#!/usr/bin/env bash

# If gitlab is down or pipeline are stuck, hotfixes need to be available
# This script will publish docker images to ECR using your current git HEAD, then deploy them to a given environment.
# Some local files (git-commit.conf and sentry.properties) will be updated, take caution.
# No trace of this will appear on Gitlab (no releases, no pipelines, no tags).
# create_hotfix_scala $ENVIRONMENT $CHART_NAME [ $MODULE_NAME $MODULE_PATH $DEPLOYMENT ]
# create_hotfix_scala testing crm main modules/3-executables/main crm
# create_hotfix_scala testing notification \
#   main-http modules/3-executables/main-http notification-http \
#   main-consumer modules/3-executables/main-consumer notification-consumer

create_hotfix_scala() {

  ENVIRONMENT=$1
  CHART_NAME=$2
  shift 2

  SHORT_SHA=$(git rev-parse --short HEAD)
  HOTFIX_TAG="hotfix-$SHORT_SHA"

  gum confirm "Preparing $HOTFIX_TAG for $CHART_NAME ?" || exit
  prepare_hotfix_scala $HOTFIX_TAG

  gum confirm "Building $HOTFIX_TAG for $CHART_NAME ?" || exit
  while [[ $# -gt 2 ]] ; do
    build_hotfix_scala $HOTFIX_TAG "$1" "$2" "$3"
    shift 3
  done

  gum confirm "Deploying $HOTFIX_TAG for $CHART_NAME ?" || exit
  deploy_hotfix $CHART_NAME $ENVIRONMENT $HOTFIX_TAG
}

# Update local git-commit.conf and sentry.properties files using git short sha
prepare_hotfix_scala() {
  HOTFIX_TAG=$1

  git secret reveal -f
  aws_ecr_login

  COMMIT_CONF_FILES=$(find . -name "git-commit.conf")
  SENTRY_PROPERTIES_FILES=$(find . -name "sentry.properties")

  for file in $(echo "$COMMIT_CONF_FILES\n$SENTRY_PROPERTIES_FILES"); do
      sed -i '' -e 's&GIT_COMMIT&'"$HOTFIX_TAG&" $file
  done

}

# Build docker images locally and publish them to AWS ECR.
build_hotfix_scala() {

  HOTFIX_TAG=$1
  SBT_MODULE=$2
  DOCKER_PATH=$3
  DEPLOYMENT=$4

  DOCKER_REGISTRY_ID="949316342391"
  DOCKER_REGISTRY="$DOCKER_REGISTRY_ID.dkr.ecr.eu-west-1.amazonaws.com"
  DOCKER_IMAGE=$DOCKER_REGISTRY/$DEPLOYMENT
  HOTFIX_IMAGE=$DOCKER_IMAGE:$HOTFIX_TAG

  #Build
  sbt "project $SBT_MODULE" "Docker / stage"

  #Publish
  docker build --platform "linux/amd64" -t $HOTFIX_IMAGE --cache-from $DOCKER_IMAGE "$DOCKER_PATH/target/docker/stage"
  docker push $HOTFIX_IMAGE

  echo "Created hotfix $HOTFIX_IMAGE"
}

# Deploy the project in the given environment
deploy_hotfix() {
  source $colisweb_scripts/ci/helm.sh

  CHART_NAME=$1
  ENVIRONMENT=$2
  HOTFIX_TAG=$3

  CONFIG_PATH=deploy
  CHART_PATH=$CONFIG_PATH/$CHART_NAME
  ROOT_PATH=$(pwd)

  # Unset Kubectl configuration made via the KUBECONFIG env variable
  #  it would override the config made by configure_kubectl_for
  #  for example, using Gitlab runners in Kubernetes sets this variable and causes conflict
  unset KUBECONFIG

  # Configure Kubectl
  configure_kubectl_for $ENVIRONMENT

  # Avoiding "no local-index.yaml" or "empty local-index.yaml" error
  cat > $HOME/Library/Caches/helm/repository/local-index.yaml <<EOT
apiVersion: v1
entries:
  cronjob:
EOT

  # helm stable repo have changed and must be updated manually, in versions < v2.17.0
  helm repo add colisweb s3://colisweb-helm-charts/colisweb  --force-update
  helm repo add stable https://charts.helm.sh/stable --force-update
  helm repo update
  helm dependency update ${ROOT_PATH}/${CHART_PATH}

  # Gather values/*.yaml files
  VALUES_PATH="${ROOT_PATH}/${CHART_NAME}/values"
  VALUES_FILES=''
  [ -d $VALUES_PATH ] && VALUES_FILES=$(find $VALUES_PATH -type f -maxdepth 1 -name "*.yaml" | sed 's/^/ -f /' | tr -d \\n | sed 's/%//')

  # Deploy
  helm upgrade --install \
    --namespace ${ENVIRONMENT} \
    ${VALUES_FILES} \
    -f ${ROOT_PATH}/${CONFIG_PATH}/common.yaml \
    -f ${ROOT_PATH}/${CONFIG_PATH}/${ENVIRONMENT}.yaml \
    -f ${ROOT_PATH}/${CONFIG_PATH}/${ENVIRONMENT}-secrets.yaml \
    --set global.version=$HOTFIX_TAG \
    ${CHART_NAME} ${ROOT_PATH}/${CHART_PATH}


  verify_deployments -t 10m $ENVIRONMENT $CHART_NAME

}

#!/usr/bin/env bash

image_exists() {
  set -e

  REGISTRY=$1
  REPOSITORY=$2
  IMAGE=$3

  TAGGED_IMAGE="$REGISTRY/$REPOSITORY:$IMAGE"

  aws ecr describe-images --registry-id $REGISTRY --repository-name $REPOSITORY --image-ids "imageTag=$IMAGE"

  if [ $? -eq 0 ]
  then
    echo "Image $TAGGED_IMAGE already present in distant repo"
    return 0
  else
    echo "Image $TAGGED_IMAGE NOT present in distant repo"
    return 1
  fi
}
#!/usr/bin/env bash

gmm() {
  git checkout $1
  git pull
  git checkout $2
  git pull
  git merge $1
  git push
}

git_damn_merge() {
  git checkout $1
  git pull
  git checkout $2
  git dammit
  git merge $1
  git push
}

git_prune_local_branches() {
  git branch -r |
    awk '{print $1}' |
    egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) |
    awk '{print $1}' |
    xargs git branch -d
}

gum_checkout() {
  git branch -a | cut -f3- -d "/" | gum filter | xargs git checkout
}

# useful option :
#  export GIT_SUBLINE_MERGE_NON_INTERACTIVE_MODE=TRUE
# see https://github.com/paulaltin/git-subline-merge
setup_subline_merge() {
  location=${1:-"--local"}

  case $location in
  --local)
    if [ -d ".git" ]; then
      echo "* merge=subline" >>.git/info/attributes
    else
      echo "Cannot use local option, not in a git repository"
      return 1
    fi
    ;;
  --global)
    echo "* merge=subline" >>~/.gitattributes
    ;;
  *)
    echo "unknown argument $location"
    return 2
    ;;
  esac

  git config $location merge.conflictStyle diff3
  git config $location merge.subline.driver "$colisweb_scripts/shell-session/shell/dev/git-subline-merge %O %A %B %L %P"
  git config $location merge.subline.recursive binary
}

rebase_from_ancestor() {
  set -x
  branch=$1
  tip=$(git rev-parse HEAD)
  ancestor=$(git merge-base $branch $tip)
  commits=$(git log $ancestor..$tip)
  git reset --hard $ancestor
  git merge --squash $tip
  git commit -m "squashed commmits $commits" || echo "nothing committed"
  git rebase $branch -Xtheirs
}

#!/usr/bin/env bash

import_all_pgp_keys() {
  echo "importing all PGP keys"
  gpg --import $SCRIPT_FULL_PATH/pgp_keys/*.key
}

remove_all_persons_from_secrets() {
    echo "cleanup git secret"
    WHO_KNOWS=($(git secret whoknows))
    git secret removeperson $WHO_KNOWS
    echo "Removed secrets access for $WHO_KNOWS"
}

all_pgp_emails() {
  gpg --show-key $SCRIPT_FULL_PATH/pgp_keys/*.key | sed -rn "s/.*<(.*)>/\1/p"
}

set_all_secret_keys() {

  import_all_pgp_keys

  git secret reveal -f

  remove_all_persons_from_secrets

  if [ $# -eq 0 ]; then
    echo "No emails supplied, using dev-tools pgp keys as source"
    IN_THE_KNOW=($(gum choose --no-limit $(all_pgp_emails)))
  else
    IN_THE_KNOW=($*)
  fi

  git secret tell $IN_THE_KNOW
  git secret hide
  git secret whoknows

  echo "all secrets updated, you'll need to commit the changes"
}

#!/usr/bin/env bash

start_ssh_bastion() {
  ENV=$1
  SSH_LOCAL_PORT=$2
  POD_NAME=ssh-bastion-$USERNAME
  CONFIG_MAP_NAME=ssh-bastion-$USERNAME
  configure_kubectl_for $ENV
  kubectl get pods -o name | grep pod/$POD_NAME
  if [ $? -eq 0 ]; then
    echo "$POD_NAME is already running"
  else
  	#configmap
    kubectl get configmap $CONFIG_MAP_NAME && kubectl delete configmap $CONFIG_MAP_NAME
    tempdir=$(mktemp -d)
    cat <<EOF  > $tempdir/sshd_config
AllowTcpForwarding yes
Port 2222
PermitRootLogin yes
AuthorizedKeysFile /etc/ssh/authorized_keys
EOF
	cp ~/.ssh/id_rsa.pub $tempdir/authorized_keys
    kubectl create configmap $CONFIG_MAP_NAME --from-file=$tempdir

	#pod
    kubectl get pod  $POD_NAME && kubectl delete pod $POD_NAME
    cat <<EOF | kubectl create -f -

    apiVersion: v1
    kind: Pod
    metadata:
      name: $POD_NAME
    spec:
      containers:
      - name: $POD_NAME
        image: sickp/alpine-sshd:7.4
        ports:
        - containerPort: 2222
        volumeMounts:
        - mountPath: /etc/ssh/sshd_config
          name: ssh-config
          subPath: sshd_config
        - mountPath: /etc/ssh/authorized_keys
          name: ssh-config
          subPath: authorized_keys
      volumes:
      - name: ssh-config
        configMap:
          name: $CONFIG_MAP_NAME
EOF

  fi

  # You need a recent kubectl for wait to work (1.15 works), install or upgrade
  # with brew :
  # brew install kubernetes-cli
  # brew upgrade kubernetes-cli
  kubectl wait --for=condition=Ready pod/$POD_NAME

  # kube port-forward
  lsof -ti  tcp:$SSH_LOCAL_PORT | xargs kill
  kubectl port-forward $POD_NAME $SSH_LOCAL_PORT:2222 &
  while ! nc -z 127.0.0.1 $SSH_LOCAL_PORT; do
    sleep 1
  done
  echo "forwarding ssh via local port $SSH_LOCAL_PORT"
  echo "remember to terminate the bastion with 'stop_ssh_bastion'"
}

stop_ssh_bastion() {
  POD_NAME=ssh-bastion-$USERNAME
  kubectl delete pod $POD_NAME
}

#!/usr/bin/env bash

configure_kubectl_for() {
  local infra_env="$1"
  local valid_envs="[testing][staging][production][performance][tests][recette]"
  echo "$valid_envs" | grep -q "\[$infra_env\]"

  if [ $? -ne 0 ]; then
    echo "Cannot configure kubectl for invalid env : $infra_env"
    echo "choose one of $valid_envs"
    return 1
  fi

  aws eks update-kubeconfig --name "toutatis-$infra_env-eks" >&2
}

#!/usr/bin/env bash

# WARNING : never try to do a dump directly from the database_production_ca
# this could cause lot of lock database issues.
# always use database_production_read_replica_ca instead
database_k8s() {
  MODE=$1
  case $MODE in
  	 "tests") SSH_LOCAL_PORT=2224;PG_LOCAL_PORT=24440;CA_LOCAL_PORT=25430;ENV="tests";;
	   "testing") SSH_LOCAL_PORT=2225;PG_LOCAL_PORT=24441;CA_LOCAL_PORT=25431;ENV="testing";;
	   "staging") SSH_LOCAL_PORT=2226;PG_LOCAL_PORT=24442;CA_LOCAL_PORT=25432;ENV="staging";;
	   "production") SSH_LOCAL_PORT=2227;PG_LOCAL_PORT=24443;CA_LOCAL_PORT=25433;ENV="production";;
	   "production_rw") SSH_LOCAL_PORT=2227;PG_LOCAL_PORT=24444;CA_LOCAL_PORT=25434;ENV="production";;
	   "recette") SSH_LOCAL_PORT=2228;PG_LOCAL_PORT=24446;CA_LOCAL_PORT=25436;ENV="recette";;
	   *) echo "Unsupported ENV : $MODE"; return 1 ;;
  esac

  start_ssh_bastion $ENV $SSH_LOCAL_PORT

  lsof -ti  tcp:$PG_LOCAL_PORT | xargs kill

  bastion_config=$(mktemp)
  cat > "$bastion_config" <<EOF
	  UserKnownHostsFile /dev/null
	  StrictHostKeyChecking no
	  User root
	  Host bastion_tests
    HostName 127.0.0.1
    Port 2224
    LocalForward 24440 toutatis-tests-db.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:5432
	  Host bastion_testing
		HostName 127.0.0.1
		Port 2225
		LocalForward 24441 toutatis-testing-db.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:5432
		LocalForward 25431 toutatis-testing-mysql-db.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:3306
		LocalForward 25531 testapirds.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:3306
	  Host bastion_staging
		HostName 127.0.0.1
		Port 2226
		LocalForward 24442 toutatis-staging-db.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:5432
		LocalForward 25432 toutatis-staging-mysql-db.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:3306
    Host bastion_recette
		HostName 127.0.0.1
		Port 2228
		LocalForward 24446 toutatis-recette-db.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:5432
		LocalForward 25436 toutatis-recette-mysql-db.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:3306
		LocalForward 25536 testapirds.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:3306
	  Host bastion_production
		HostName 127.0.0.1
		Port 2227
    LocalForward 24443 toutatis-production-db-replica.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:5432
    LocalForward 25433 toutatis-production-mysql-db-replica.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:3306
EOF
  if [ "$MODE" = "production_rw" ] ; then
    cat >> "$bastion_config" <<EOF
      LocalForward 24444 toutatis-production-db.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:5432
      LocalForward 25434 toutatis-production-mysql-db.ca0rjdmnxf1x.eu-west-1.rds.amazonaws.com:3306
EOF
  fi

  ssh -f -N \
  	-F "$bastion_config" \
  	"bastion_$ENV"

  echo "sample command : 'psql postgres://postgres@127.0.0.1:$PG_LOCAL_PORT'"
  echo "sample command : 'mysql -u colisweb -h 127.0.0.1 -P $CA_LOCAL_PORT -p db_name'"

  echo "run 'kubectl delete pod $POD_NAME' when you have finished"
}

psql_on_k8() {
  NAMESPACE=$1
  SERVICE=$2
  CONNECTION=$3
  shift 3

  kubectl -n $NAMESPACE run ${SERVICE}-postgres-init \
    --image jbergknoff/postgresql-client \
    --restart=Never \
    --attach --rm \
    -- \
    postgresql://${CONNECTION} \
    "$*"
}

mysql_on_k8() {
  local namespace=$1
  local service=$2
  local db_host=$3
  local db_port=$4
  local db_init_username=$5
  local db_init_password=$6
  local query=$7

  kubectl -n ${namespace} run ${service}-mysql-init \
    --image arey/mysql-client \
    --restart=Never \
    --attach --rm \
    -- \
    mysql --host=$db_host --user=$db_init_username --password=$db_init_password --port=$db_port --execute="$query"
}
#!/usr/bin/env bash

kube_init_database_once() {

  extract_args 8 namespace db_host db_port db_init_username db_init_password db_database db_username db_password $*

  echo "======================="
  echo " Initializing Database '$db_database' for namespace $namespace"
  echo "======================="

  echo "Checking if Database '$db_database' exists"
  set +e
  psql_on_k8 $namespace once "$db_init_username:$db_init_password@$db_host:$db_port" -lqtA | cut -d\| -f1 | grep "^$db_database$"
  return_code=$?
  set -e

  if [ ${return_code} -eq 0 ]; then
    echo "Database $db_database already exists - nothing to do"
  else
    echo "Database $db_database does not exist - initializing"

    psql_on_k8 $namespace once "$db_init_username:$db_init_password@$db_host:$db_port" -c 'CREATE DATABASE '"$db_database"';'
    echo "DB created $db_database"

    psql_on_k8 $namespace once "$db_init_username:$db_init_password@$db_host:$db_port" -c 'CREATE USER '"$db_username"' WITH ENCRYPTED PASSWORD '"'$db_password'"';'
    echo "USER created $db_username"

    psql_on_k8 $namespace once "$db_init_username:$db_init_password@$db_host:$db_port" -c 'GRANT ALL PRIVILEGES ON DATABASE '"$db_database"' TO '"$db_username"';'
    echo "Granted all privileges for $db_username on $db_database"
  fi

  echo "======================="
  echo " Database '$db_database' Initialization complete for namespace $namespace"
  echo "======================="
}

kube_init_database_readonly_account() {

  extract_args 6 namespace service db_connection db_database db_readonly_username db_readonly_password $*

  echo "======================="
  echo " Initializing Readonly Account '$db_readonly_username' for '$db_database' for namespace $namespace"
  echo "======================="

  # Print commands before execution, except echo
  trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG

  echo "Checking if Readonly account '$db_readonly_username' for '$db_database' exists"
  set +e
  psql_on_k8 $namespace $service $db_connection -qtAc 'SELECT rolname FROM pg_roles;' | grep "^$db_readonly_username$"
  return_code=$?
  set -e

  if [ ${return_code} -eq 0 ]; then
    echo "Account $db_readonly_username already exists - nothing to do"
  else
    echo "Account $db_readonly_username does not exist - creating"

    psql_on_k8 $namespace $service $db_connection -c 'CREATE USER '"$db_readonly_username"' WITH ENCRYPTED PASSWORD '"'$db_readonly_password'"';'
    psql_on_k8 $namespace $service $db_connection -c 'GRANT CONNECT ON DATABASE '"$db_database"' TO '"$db_readonly_username"';'
    psql_on_k8 $namespace $service $db_connection -c 'GRANT USAGE ON SCHEMA public TO '"$db_readonly_username"';'
    psql_on_k8 $namespace $service $db_connection -c 'GRANT SELECT ON ALL TABLES IN SCHEMA public TO '"$db_readonly_username"';'
    psql_on_k8 $namespace $service $db_connection -c 'ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO '"$db_readonly_username"';'

    echo "Created user with read-only permissions for $db_readonly_username on $db_database (schema public)"
  fi
}

kube_init_datadog_in_database() {
  extract_args 8 namespace db_host db_port db_init_username db_init_password db_datadog_username db_datadog_password db_datadog_schema $*

  echo "======================="
  echo " Initializing Datadog Agent Requirement for namespace $namespace"
  echo "======================="

  echo "Checking if User  '$db_datadog_username' exists"
  local service="datadog"
  found_db_users=$(mysql_on_k8 $namespace $service $db_host $db_port $db_init_username $db_init_password 'SELECT user FROM mysql.user;')
  set +e
  echo "$found_db_users" | grep "^$db_datadog_username$"
  return_code=$?
  set -e

  if [ ${return_code} -eq 0 ]; then
    echo "User $db_datadog_username already exists - nothing to do"
  else
    echo "User $db_datadog_username does not exist - initializing"

    # All the query come from this docs : https://docs.datadoghq.com/fr/database_monitoring/setup_mysql/selfhosted/?tab=mysql56

    mysql_on_k8 $namespace $service $db_host $db_port $db_init_username $db_init_password 'CREATE USER '"$db_datadog_username"'@"%" IDENTIFIED BY '"'$db_datadog_password'"';'
    echo "USER created $db_datadog_username"

    mysql_on_k8 $namespace $service $db_host $db_port $db_init_username $db_init_password 'GRANT REPLICATION CLIENT ON *.* TO datadog@"%" WITH MAX_USER_CONNECTIONS 5;'
    echo "ALTER USER $db_datadog_username"

    mysql_on_k8 $namespace $service $db_host $db_port $db_init_username $db_init_password 'GRANT PROCESS ON *.* TO '"$db_datadog_username"'@"%";'
    echo "Granted PROCESS for $db_datadog_username"

    mysql_on_k8 $namespace $service $db_host $db_port $db_init_username $db_init_password 'GRANT SELECT ON performance_schema.* TO '"$db_datadog_username"'@"%";'
    echo "Granted SELECT on performance_schema for $db_datadog_username"

    mysql_on_k8 $namespace $service $db_host $db_port $db_init_username $db_init_password 'CREATE SCHEMA IF NOT EXISTS datadog;'
    echo "CREATE SCHEMA datadog"

    mysql_on_k8 $namespace $service $db_host $db_port $db_init_username $db_init_password 'GRANT EXECUTE ON datadog.* to '"$db_datadog_username"'@"%";'
    echo "Granted 'GRANT EXECUTE for $db_datadog_username on datadog"

    mysql_on_k8 $namespace $service $db_host $db_port $db_init_username $db_init_password 'GRANT CREATE TEMPORARY TABLES ON datadog.* TO '"$db_datadog_username"'@"%";'
    echo "Granted  CREATE TEMPORARY TABLES for $db_datadog_username"


    mysql_on_k8 $namespace $service $db_host $db_port $db_init_username $db_init_password 'DROP PROCEDURE IF EXISTS datadog.explain_statement;
                  DELIMITER $$
                  CREATE PROCEDURE datadog.explain_statement(IN query TEXT)
                      SQL SECURITY DEFINER
                  BEGIN
                      SET @explain := CONCAT("EXPLAIN FORMAT=json ", query);
                      PREPARE stmt FROM @explain;
                      EXECUTE stmt;
                      DEALLOCATE PREPARE stmt;
                  END $$
                  DELIMITER ;'
   echo "CREATE PROCEDURE PROCEDURE datadog.explain_statement"

    mysql_on_k8 $namespace $service $db_host $db_port $db_init_username $db_init_password 'DROP PROCEDURE IF EXISTS '"$db_datadog_username"'.explain_statement;
                    DELIMITER $$
                    CREATE PROCEDURE '"$db_datadog_username"'.explain_statement(IN query TEXT)
                        SQL SECURITY DEFINER
                    BEGIN
                        SET @explain := CONCAT("EXPLAIN FORMAT=json ", query);
                        PREPARE stmt FROM @explain;
                        EXECUTE stmt;
                        DEALLOCATE PREPARE stmt;
                    END $$
                    DELIMITER ;
                    GRANT EXECUTE ON PROCEDURE '"$db_datadog_username"'.explain_statement TO datadog@"%";'
    echo "CREATE PROCEDURE on SCHEMA $db_datadog_schema for $db_datadog_username"

    mysql_on_k8 $namespace $service $db_host $db_port $db_init_username $db_init_password 'DROP PROCEDURE IF EXISTS datadog.enable_events_statements_consumers;
                  DELIMITER $$
                  CREATE PROCEDURE datadog.enable_events_statements_consumers()
                      SQL SECURITY DEFINER
                  BEGIN
                      UPDATE performance_schema.setup_consumers SET enabled="YES" WHERE name LIKE "events_statements_%";
                  END $$
                  DELIMITER ;
                  GRANT EXECUTE ON PROCEDURE datadog.enable_events_statements_consumers TO datadog@"%";'

    echo "CREATE PROCEDURE on datadog.enable_events_statements_consumers"
  fi

  echo "======================="
  echo " Database '$db_datadog_schema' Initialization complete for namespace $namespace"
  echo "======================="
}

kube_init_datadog_in_postgres_database() {
  extract_args 7 namespace db_host db_port db_init_username db_init_password db_datadog_username db_datadog_password $*

  local service="datadog"
  local db_connection="$db_init_username:$db_init_password@$db_host:$db_port"

  echo "======================="
  echo " Initializing $service Agent On PostgresSQL Database Requirement for namespace $namespace"
  echo "======================="

  echo "Checking if User  '$db_datadog_username' exists"

  set +e
  if psql_on_k8 $namespace $service $db_connection -qtAc 'SELECT usename FROM pg_catalog.pg_user;' | grep "^$db_datadog_username$";
  then
    echo "User $db_datadog_username already exists - nothing to do"
  else
    echo "User $db_datadog_username does not exist - initializing"

    set -e
    psql_on_k8 $namespace $service $db_connection -qc 'CREATE USER '"$db_datadog_username"' WITH password '"'$db_datadog_password'"';'
    echo "User created $db_datadog_username"

    psql_on_k8 $namespace $service $db_connection -qc 'CREATE SCHEMA datadog;'
    echo "Schema datadog created"

    psql_on_k8 $namespace $service $db_connection -qc 'GRANT USAGE ON SCHEMA datadog TO datadog;'
    echo "Granted usage for datadog schema to datadog"

    psql_on_k8 $namespace $service $db_connection -qc 'GRANT USAGE ON SCHEMA public TO datadog;'
    echo "Granted usage for public schema to datadog"

    psql_on_k8 $namespace $service $db_connection -qc 'GRANT pg_monitor TO datadog;'
    echo "Granted pg_monitor to datadog"

    psql_on_k8 $namespace $service $db_connection -qc 'CREATE EXTENSION IF NOT EXISTS pg_stat_statements schema public;'
    echo "Extension pg_stat_statements created"

    local datadog_function_path="/tmp/datatog-explain-statement-function.sql"
    local datadog_function="CREATE OR REPLACE FUNCTION datadog.explain_statement(
         l_query TEXT,
         OUT explain JSON
      )
      RETURNS SETOF JSON AS
      \\$\\$
      DECLARE
      curs REFCURSOR;
      plan JSON;

      BEGIN
         OPEN curs FOR EXECUTE pg_catalog.concat('EXPLAIN (FORMAT JSON) ', l_query);
         FETCH curs INTO plan;
         CLOSE curs;
         RETURN QUERY SELECT plan;
      END;
      \\$\\$
      LANGUAGE 'plpgsql'
      RETURNS NULL ON NULL INPUT
      SECURITY DEFINER;"

    kubectl -n $namespace run $service-postgres-init \
      --image jbergknoff/postgresql-client \
      --restart=Never \
      --attach --rm \
      --command \
      -- \
      /bin/sh -c "echo -e \"$datadog_function\" > $datadog_function_path; psql postgresql://$db_connection -qf $datadog_function_path"

    echo "Function datadog.explain_statement created"
  fi

  echo "======================="
  echo " Database $service Initialization complete for namespace $namespace"
  echo "======================="
}

kube_init_service_database() {

  extract_args 9 namespace service db_host db_port db_init_username db_init_password db_database db_username db_password $*

  local db_connection="$db_init_username:$db_init_password@$db_host:$db_port"

  echo "Checking if Database '$db_database' exists"
  set +e
  psql_on_k8 $namespace $service $db_connection -lqtA | cut -d\| -f1 | grep "^$db_database$"
  return_code=$?
  set -e

  if [ ${return_code} -eq 0 ]; then
    echo "Database $db_database already exists - nothing to do"
  else
    echo "Database $db_database does not exist - initializing"

    psql_on_k8 $namespace $service $db_connection -c 'CREATE DATABASE '"$db_database"';'
    echo "DB created $db_database"

    psql_on_k8 $namespace $service $db_connection -c 'CREATE USER '"$db_username"' WITH ENCRYPTED PASSWORD '"'$db_password'"';'
    echo "USER created $db_username"

    psql_on_k8 $namespace $service $db_connection -c 'GRANT ALL PRIVILEGES ON DATABASE '"$db_database"' TO '"$db_username"';'
    echo "Granted all privileges for $db_username on $db_database"
  fi

  echo "======================="
  echo " Database '$db_database' Initialization complete for  namespace $namespace"
  echo "======================="
}

#!/usr/bin/env bash

# Allow to use JMX connection to retrieve data and metrics from the pods within kubernetes
# You will need visualVM to use this tool https://visualvm.github.io/
# ex: bind_jmx testing notification
bind_jmx() {

  local ENV=$1
  local SERVICE_NAME=$2
  local PORT=2242

  start_ssh_bastion $ENV $PORT

  echo "root" | ssh -f -N -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no -D 7777 root@127.0.0.1 -p 2242
  local PODS=$(kubectl -n $ENV get pods -o wide | grep $SERVICE_NAME | grep -Eo '^[^ ]+')

  echo "Choose one of the following pod to get metrics from..."
  local POD_NAME=$(gum choose $PODS)
  local POD_IP=$(
    kubectl -n $ENV get pods -o jsonpath='{range .items[*]}{.metadata.name}{" "}{.status.podIP}{"\n"}{end}' |
    grep $POD_NAME |
    cut -d' ' -f2 |
    head -1
  )

  jconsole -J-DsocksProxyHost=localhost \
    -J-DsocksProxyPort=7777 \
    service:jmx:rmi:///jndi/rmi://$POD_IP:7199/jmxrmi \
    -J-DsocksNonProxyHosts= &

  cat << EOF
  Now start VisualVM
  Preferences > Network > Manual Proxy Settings
  SOCKS Proxy Line: Set 'localhost' and Port '7777'
  File > Add JMX Connection
  Set $POD_IP:7199, check 'do not require an SSL connection'
  Remember to kill you bastion afterward using 'stop_ssh_bastion'
EOF
}
#!/usr/bin/env bash

function kstatus() {
  if [ -z "$3" ]
    then
    configure_kubectl_for $1 && watch -n 1 "kubectl -n $1 get $2"
  else
    configure_kubectl_for $1 && watch -n 1 "kubectl -n $1 get $2 | grep $3"
  fi
}

#!/usr/bin/env bash

k8_nodes_stats() {
kubectl get nodes -o name  |
  xargs kubectl describe |
  grep "^Name\|workType\|cpu  \|memory  "  |
  sed -r 's/[ :=]+/\t/g' |
  sed 's/\tworkType\t//g' |
  sed -r 's/^Name/---\nName/g' |
  grep --color "Name\|web\|workers\|cpu\|memory\|---"
}

#!/usr/bin/env bash

# Port forward on the first matching pod
# Ex :
# pod_forward testing notification-http
# pod_forward testing colisweb-api-web 3333 3000
pod_forward() {
  ENV=$1
  POD_FILTER=$2
  LOCAL_PORT=${3:-8080}
  POD_PORT=${4:-8080}

  if PID=$(lsof -ti tcp:$LOCAL_PORT); then
    echo "killing process $PID which uses port $LOCAL_PORT"
    kill $PID
  fi

  configure_kubectl_for $ENV

  POD=`pick_pod $ENV $POD_FILTER`

  echo "setting up forwarding to $POD"
  kubectl -n $ENV port-forward $POD $LOCAL_PORT:$POD_PORT &
  PID=$!

  while ! echo exit | nc localhost $LOCAL_PORT > /dev/null; do
    sleep 1
    echo "waiting for port $LOCAL_PORT to be open locally"
  done
  echo "port $LOCAL_PORT is now available on localhost, forwarding to $ENV $POD:$POD_PORT"
  echo 'you can terminate it with "kill '$PID'" or "kill $(lsof -ti tcp:'$LOCAL_PORT')"'
}

# prompts to pick a pod and run a command like bash inside
# pod_exec testing
# pod_exec testing bash
# pod_exec testing bash colisweb-api
pod_exec() {
  ENV=$1
  COMMAND=${2:-bash}
  configure_kubectl_for $ENV
  POD_FILTER=$3
  POD=`pick_pod $ENV $POD_FILTER`
  echo "running $COMMAND inside $POD"
  kubectl -n $ENV exec -ti $POD -- $COMMAND
}

# prompts to pick a pod and copy from a local file to the pod
# pod_copy_to testing localfile remotefile
# pod_copy_to testing localfile remotefile colisweb-api
pod_copy_to() {
  ENV=$1
  LOCAL_FILE=$2
  REMOTE_FILE=$3
  configure_kubectl_for $ENV
  POD_FILTER=$4
  POD=`pick_pod $ENV $POD_FILTER`
  kubectl cp $LOCAL_FILE $ENV/$POD:$REMOTE_FILE
}


pick_pod() {
  ENV=$1
  POD_FILTER="pod/$2"
  configure_kubectl_for $ENV

  if [ -z "$2" ] ; then
    kubectl -n $ENV get pods | gum filter | cut -f1 -d" "
  else
      if PODS=$(kubectl -n $ENV get pods -o=name | grep "$POD_FILTER"); then
        echo $PODS | head -1 | sed -e 's/pod\///'
      else
        echo "no pods found on $ENV matching $POD_FILTER" >&2
      fi
  fi
}

# pods_settings $ENV
# Will output a CSV (;) of all deployments on this environment with cpu and memory request and limits
# Errors and null outputs are ignored and won't be in the output.
pods_resources() {
  ENV=$1
  configure_kubectl_for $ENV
  DEPLOYMENTS=(
    $(kubectl -n $ENV get deployments | grep -Eo '^[^ ]+' | grep -v 'NAME')
  )
  echo "deployment; request_cpu; request_memory; limits_cpu;limits_memory"
  for D in "${DEPLOYMENTS[@]}"; do
      info=$(kubectl -n $ENV get deployment -o yaml $D |
        yq '.spec.template.spec.containers[].resources' |
        yq '.L = .requests.cpu + "; " + .requests.memory + "; " + .limits.cpu + "; " + .limits.memory' |
        yq ".L") 2&>/dev/null
      if ! [ "$info" = "null" ]; then
        echo "$D; $info"
      fi
  done
}

pods_strategies() {
  ENV=$1
  configure_kubectl_for $ENV
  DEPLOYMENTS=(
    $(kubectl -n $ENV get deployments | grep -Eo '^[^ ]+' | grep -v 'NAME')
  )
  echo "deployment; max_surge; max_unavailable"
  for D in "${DEPLOYMENTS[@]}"; do
      info=$(kubectl -n $ENV get deployment -o yaml $D |
        yq '.spec.strategy' |
        yq '.L = .rollingUpdate.maxSurge + "; " + .rollingUpdate.maxUnavailable' |
        yq ".L") 2&>/dev/null
      if ! [ "$info" = "null" ]; then
        echo "$D; $info"
      fi
  done
}

#!/usr/bin/env bash

bastion_config_for_redis_ca() {
  ssh_config xufte6.0001.euw1.cache.amazonaws.com redis 2223 63789 tests testing recette-001 sandbox prod > $1
}

bastion_config_for_redis_toutatis() {
  ssh_config xufte6.0001.euw1.cache.amazonaws.com toutatis 2223 63789 tests testing recette staging production > $1
}

ssh_config() {
  host=$1
  host_prefix=$2
  port0=$3
  forward0=$4
  shift 4
  instance_names=("$@") # /!\ indices start at 1 with zsh
  ssh_header

  environments=(tests testing recette staging production)

  length=${#environments[@]}
  for (( i=1; i<=${length}; i++ ));
  do
    bastion_block bastion_${environments[$i]} $(($port0 + $i)) $(($forward0 + $i)) ${host_prefix}-${instance_names[$i]}.$host
  done
}

ssh_header() {
  cat  <<EOF
    UserKnownHostsFile /dev/null
    StrictHostKeyChecking no
    User root
EOF
}

bastion_block() {
  cat <<EOF
    Host $1
      HostName 127.0.0.1
      Port $2
      LocalForward $3 $4:6379
EOF
}

redis_k8s() {
  MODE=$1
  REDIS_INSTANCE=${2:-ca}
  case $MODE in
	   "tests") SSH_LOCAL_PORT=2224;REDIS_LOCAL_PORT=63790;ENV="tests";;
	   "testing") SSH_LOCAL_PORT=2225;REDIS_LOCAL_PORT=63791;ENV="testing";;
	   "recette") SSH_LOCAL_PORT=2226;REDIS_LOCAL_PORT=63792;ENV="recette";;
	   "staging") SSH_LOCAL_PORT=2227;REDIS_LOCAL_PORT=63793;ENV="staging";;
	   "production") SSH_LOCAL_PORT=2228;REDIS_LOCAL_PORT=63794;ENV="production";;
	   *) echo "Unsupported ENV : $MODE"; return 1 ;;
  esac

  start_ssh_bastion $ENV $SSH_LOCAL_PORT

  lsof -ti  tcp:$REDIS_LOCAL_PORT | xargs kill

  bastion_config=$(mktemp)
  case $REDIS_INSTANCE in
    "ca") bastion_config_for_redis_ca "$bastion_config";;
    "toutatis") bastion_config_for_redis_toutatis "$bastion_config";;
    *) echo "Unsupported redis instance (ca or toutatis available) : $REDIS_INSTANCE"; return 1;;
  esac

  ssh -f -N \
  	-F "$bastion_config" \
  	"bastion_$ENV"

  echo "sample command : 'redis-cli -p $REDIS_LOCAL_PORT'"
  echo "run 'kubectl delete pod $POD_NAME' when you have finished"

  redis-cli -p $REDIS_LOCAL_PORT
}

#!/usr/bin/env bash

#Create a k8s cron jobs that will be run regularly
#See run_cron_job_k8s -h for more details

run_cron_job_k8s() {

  #default values
  local namespace="testing"
  local name="$USERNAME"
  local SCHEDULE="00 05 * * *"
  local secret=""
  local amm_folder=""
  local amm_script=""

  while getopts ":e:c:p:f:s:t:h" opt; do
    case $opt in
      e)
        namespace="$OPTARG" >&2
        ;;
      t)
        SCHEDULE="$OPTARG" >&2
        ;;
      p)
        name="$OPTARG" >&2
        ;;
      c)
        secret="$OPTARG" >&2
        ;;
      f)
        amm_folder="$OPTARG" >&2
        ;;
      s)
        amm_script="$OPTARG" >&2
        ;;
      h)
        show_help_cron_job
        return 0
        ;;
      :)
        echo "Option -$OPTARG requires an argument. Run run_cron_job_k8s -h for help" >&2
        return 0
        ;;
      \?)
        echo "Invalid option: -$OPTARG. Run run_cron_job_k8s -h for help" >&2
        return 0
        ;;
    esac
  done

  if [ -z "$amm_script" ]; then
          echo 'Missing -s. Run run_cron_job_k8s -h for help' >&2
          return 0
  fi

  shift "$((OPTIND-1))"

  local script_args=$(
    if [ "$#" -gt 0 ] ; then
      printf '"'
      join_by '", "' $*
      printf '"'
    fi
  )

  local IMAGE="lolhens/ammonite:2.5.4"
  local CRONJOB_NAME="cronjob-ammonite-$name"


  configure_kubectl_for $namespace

    if [[ ! -r "$amm_script" ]]; then
      echo "ammonite script not found $amm_script"
      return 2
    else
      local CONFIG_MAP="config-$CRONJOB_NAME"
      local SECRET_MAP="secret-$CRONJOB_NAME"
      local CONFIG_MAP_DIR="$(mktemp -d)"

      if [[ ! -z $amm_folder && -d $amm_folder ]] ; then
        cp -r "$amm_folder/" "$CONFIG_MAP_DIR"
      fi
      cp "$amm_script" "$CONFIG_MAP_DIR/script.sc"

      kubectl -n $namespace get configmap $CONFIG_MAP && kubectl -n $namespace delete configmap $CONFIG_MAP
      kubectl -n $namespace create configmap $CONFIG_MAP --from-file="$CONFIG_MAP_DIR"

      kubectl -n $namespace get secret $SECRET_MAP && kubectl -n $namespace delete secret $SECRET_MAP
      kubectl -n $namespace create secret generic $SECRET_MAP --from-file="$secret"

      kubectl -n $namespace get cronjob $CRONJOB_NAME && kubectl -n $namespace delete cronjob $CRONJOB_NAME

      echo "starting $CRONJOB_NAME with $IMAGE"

JOB_DEFINITION='
apiVersion: batch/v1
kind: CronJob
metadata:
  name: '$CRONJOB_NAME'
  namespace: '$namespace'
spec:
  schedule: "'$SCHEDULE'"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      backoffLimit: 0
      template:
        spec:
          nodeSelector:
            workType: "workers"
          restartPolicy: Never
          volumes:
          - name: config
            configMap:
              name: '$CONFIG_MAP'
          - name: secret
            secret:
              secretName: '$SECRET_MAP'
          containers:
             - name: '$CRONJOB_NAME'
               command: ["amm", "/code/script.sc"]
               image: '$IMAGE'
               imagePullPolicy: IfNotPresent
               args: ['$script_args']
               env:
                - name: POD_NAME
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.name
                - name: POD_NAMESPACE
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.namespace
                - name: HOST_IP
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: status.hostIP
               volumeMounts:
                - name: config
                  mountPath: /code
                - name: secret
                  mountPath: /conf
                  readOnly: true
               resources:
                 requests:
                   cpu: 500m
                   memory: 256Mi
                 limits:
                   cpu: 4000m
                   memory: 512Mi
               envFrom:
                 - configMapRef:
                     name: '$CONFIG_MAP'
                 - secretRef:
                     name: '$SECRET_MAP'
'

    echo $JOB_DEFINITION > /tmp/job.yaml

    kubectl -n $namespace  apply -f /tmp/job.yaml

  fi
}

# Usage info
show_help_cron_job() {
  #p:f:s
local help="""Usage: run_cron_job_k8s -s SCRIPT [-t TIME] [-e ENV] [-c CONFIG] [-p POD] [-f FOLDER] [ARGS]
Create a k8s cron job that will be run a script regularly

    -h          display this help and exit
    -s SCRIPT   run script SCRIPT on a pod (SCRIPT must be a .sc file)
    -t TIME     opt. time when the job will be launched. TIME should be in CRON syntax (default to 00 05 * * *, ie 5AM UTC)
    -e ENV      opt. set execution environment (default to testing)
    -c CONFIG   opt. secret file needed for the script (must be a .sc file, not a .secret file)
    -p POD      opt. name of the pod to create (default to $USERNAME)
    -f FOLDER   opt. name of the folder containing the scripts to execute (if SCRIPT needs other files)
    ARGS        opt. additional arguments for SCRIPT
"""
echo "$help"
}

#!/usr/bin/env bash

# Usage info
show_help_job() {
  local help="""Usage: run_job_k8s -s SCRIPT [-e ENV] [-c CONFIG] [-p POD] [-f FOLDER] [ARGS]
  Create a k8s job executing a script

      -h          display this help and exit
      -s SCRIPT   run script SCRIPT on a pod (SCRIPT must be a .sc file)
      -e ENV      opt. set execution environment (default to testing)
      -c CONFIG   opt. secret file needed for the script (must be a .sc file, not a .secret file)
      -p POD      opt. name of the pod to create (default to $USERNAME)
      -f FOLDER   opt. name of the folder containing the scripts to execute (if SCRIPT needs other files)
      ARGS        opt. additional arguments for SCRIPT

  The organisation of the files must be the same locally as on the pod :
    - /code containing the script to execute (arg -s) and the other needed files (if the arg -f is used, it must reference this directory)
    - /conf containing the secret file (arg -c if used)
  E.g. in the script \"/code/script.sc\", to use a secret file \"/conf/secret.sc\", the import should look like \"import \$file.^.conf.secret.sc\"
  """
  echo "$help"
}

run_job_k8s() {

  #default values
  local namespace="testing"
  local name="$USERNAME"
  local secret=""
  local amm_folder=""
  local amm_script=""

  while getopts ":e:c:p:f:s:h" opt; do
    case $opt in
      e)
        namespace="$OPTARG" >&2
        ;;
      p)
        name="$OPTARG" >&2
        ;;
      c)
        secret="$OPTARG" >&2
        ;;
      f)
        amm_folder="$OPTARG" >&2
        ;;
      s)
        amm_script="$OPTARG" >&2
        ;;
      h)
        show_help_job
        return 0
        ;;
      :)
        echo "Option -$OPTARG requires an argument. Run run_cron_job_k8s -h for help" >&2
        return 0
        ;;
      \?)
        echo "Invalid option: -$OPTARG. Run run_cron_job_k8s -h for help" >&2
        return 0
        ;;
    esac
  done

  if [ -z "$amm_script" ]; then
          echo 'Missing -s. Run run_job_k8s -h for help' >&2
          return 0
  fi

  shift "$((OPTIND-1))"

  local script_args=$(
      if [ "$#" -gt 0 ] ; then
        printf '"'
        join_by '", "' $*
        printf '"'
      fi
    )

  local IMAGE="lolhens/ammonite:2.5.4"
  local JOB_NAME="job-ammonite-$name"

    if [[ ! -r "$amm_script" ]]; then
      echo "ammonite script not found $amm_script"
      return 2
    else
      local CONFIG_MAP="config-$JOB_NAME"
      local CONFIG_MAP_DIR="$(mktemp -d)"
      local SECRET_MAP="secret-$JOB_NAME"

      configure_kubectl_for $namespace

      if [[ ! -z $amm_folder && -d $amm_folder ]] ; then
        cp -r "$amm_folder/" "$CONFIG_MAP_DIR"
      fi
      cp "$amm_script" "$CONFIG_MAP_DIR/script.sc"

      kubectl -n $namespace get configmap $CONFIG_MAP && kubectl -n $namespace delete configmap $CONFIG_MAP
      kubectl -n $namespace create configmap $CONFIG_MAP --from-file="$CONFIG_MAP_DIR"

      kubectl -n $namespace get secret $SECRET_MAP && kubectl -n $namespace delete secret $SECRET_MAP
      kubectl -n $namespace create secret generic $SECRET_MAP --from-file="$secret"

      kubectl -n $namespace get job $JOB_NAME && kubectl -n $namespace delete job $JOB_NAME

      echo "starting $JOB_NAME with $IMAGE"
    fi

      JOB_DEFINITION='
apiVersion: batch/v1
kind: Job
metadata:
  name: '$JOB_NAME'
  namespace: '$namespace'
spec:
  template:
    spec:
      containers:
      - name: '$JOB_NAME'
        command: ["amm", "/code/script.sc"]
        image: '$IMAGE'
        args: ['$script_args']
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        - name: HOST_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.hostIP
        volumeMounts:
        - name: config
          mountPath: /code
        - name: secret
          mountPath: /conf
          readOnly: true
        resources:
          requests:
            cpu: 500m
            memory: 256Mi
          limits:
            cpu: 4000m
            memory: 1Gi
      nodeSelector:
        workType: workers
      restartPolicy: Never
      volumes:
      - name: config
        configMap:
          name: '$CONFIG_MAP'
      - name: secret
        secret:
          secretName: '$SECRET_MAP'
     '


     echo $JOB_DEFINITION > /tmp/job.yaml

      kubectl -n $namespace  apply -f /tmp/job.yaml

}


#!/usr/bin/env bash

run_task() {
  set -e

  check_args "--namespace" $1
  shift
  NAMESPACE=$1
  shift
  check_args "--image" $1
  shift
  IMAGE=$1
  shift
  check_args "--name" $1
  shift
  NAME=$1
  shift

  set -x

  kubectl -n ${NAMESPACE} run ${NAME} \
    --image ${IMAGE} \
    --restart=Never \
    --attach --rm \
    $*
}
geocode_address() {
  ADDRESS=$(sed -e 's: :%20:g' <(echo "$*"))
  URL="https://maps.googleapis.com/maps/api/geocode/json?address=${ADDRESS}&key=${GOOGLE_API_KEY}"
  curl $URL
}

search_business() {
  SIREN=$1
  shift
  QUERY=$(sed -e 's: :+:g' <(echo "$*"))
  URL="https://data.opendatasoft.com/api/records/1.0/search/?dataset=sirene_v3%40public&q=${QUERY}&sort=datederniertraitementetablissement&facet=trancheeffectifsetablissement&facet=libellecommuneetablissement&facet=departementetablissementi&refine.siren=${SIREN}"
  curl $URL
}

#!/bin/bash

# source tolls.sh ; tolls antoine.thomas@colisweb.com
function tolls() {
  USER=${1:-first.last@colisweb.com}
  FROM_DATE=${2:-"2023-02-01"}
  TO_DATE=${3:-"2023-02-28"}

  USER=$(gum input --prompt "username : " --value $USER)
  TOKEN=$(./tour_details.sc login --user $USER --password $(gum input --password --placeholder password))
  [ "$TOKEN" != "" ] && echo "connected" || return 1

  FROM_DATE=$(gum input --prompt "Date start : " --value $FROM_DATE)
  TO_DATE=$(gum input --prompt "Date end : " --value $TO_DATE)
  FILENAME="tours-${FROM_DATE}-TO-${TO_DATE}.json"
  curl --cookie "session=$TOKEN" "https://api.production.colisweb.com/api/v6/routes-plans/external?from=${FROM_DATE}&to=${TO_DATE}" > ~/Downloads/$FILENAME
  echo "Tournées téléchargées"

  projectIds=$(./tour_details.sc allProjects --file ~/Downloads/$FILENAME | gum choose --no-limit | cut -d "," -f 2)
  echo "projets sélectionnés : $projectIds"
  tourIds=$(./tour_details.sc allTours --file ~/Downloads/$FILENAME --projectIds "$projectIds")
  echo "tournées sélectionnées : $tourIds"

  TARGET="${FROM_DATE}-TO-${TO_DATE}.csv"
  echo "appels à HERE, écriture dans $TARGET"
  ./tour_details.sc allToursDetails --token $TOKEN --hereApiKey $HERE_API_KEY --routeIds "$tourIds" > "$TARGET"

  echo "terminé"
}

#!/usr/bin/env bash

# possible syntax:
# login
# login testing
# login testing userid
login() {
  ENV=${1:-`gum choose testing staging production recette`} && \
  USER=${2:-`gum input --placeholder username`} && \
  PASSWORD=`gum input --password --placeholder password` && \
  TOKEN=`$SCRIPT_FULL_PATH/scala/auth.sc login --env $ENV --user $USER --password $PASSWORD` && \
  export TOKEN_$ENV=$TOKEN && \
  echo "login success for $USER on $ENV" >&2
}

# you need to call login first (see above)
# possible syntax:
# recompute_tour
# recompute_tour testing
# recompute_tour testing draft
# recompute_tour testing draft 28bf9967-b5f3-4294-8855-cfd2fa36ec09
# recompute_tour testing draft 28bf9967-b5f3-4294-8855-cfd2fa36ec09 TODAY
# recompute_tour testing draft 28bf9967-b5f3-4294-8855-cfd2fa36ec09 FRIDAY
recompute_tour() {
  ENV=${1:-`gum choose testing staging production recette`}
  MODE=${2:-`gum choose draft definitive`}
  PROJECT_ID=${3:-`pick_project $ENV`}
  DAY=${4:-`gum choose TODAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY SUNDAY`}
  jwt_token $ENV
  scala/tour_config.sc $MODE -t $TOKEN -p $PROJECT_ID -d $DAY
}

pick_project() {
  ENV=${1:-`gum choose testing staging production recette`}
  jwt_token $ENV
  scala/tour_config.sc list -t $TOKEN -e $ENV | gum filter | cut -f1
}

jwt_token() {
  ENV=${1:-`gum choose testing staging production recette`}
  eval 'TOKEN=$TOKEN_'$ENV
  if ! $SCRIPT_FULL_PATH/scala/auth.sc check -t $TOKEN -e $ENV ; then
    login $ENV
  fi
}

#!/bin/bash

SCRIPT_PATH=$(dirname $(readlink -f $0))
PATH="$PATH:$SCRIPT_PATH/script"

function get_token {
    local ENV=$1
    local LOGINFILE="$HOME/scriptlogin"

   if [ ! -f "$LOGINFILE" ]; then
    cat > "$LOGINFILE" <<-'EOF'
    #!/bin/bash
    case $ENV in 
        "testing")
            local USERLOGIN=""
            local PASSWORD=""
        ;;
        "recette")
            local USERLOGIN=""
            local PASSWORD=""
        ;;
        "staging")
            local USERLOGIN=""
            local PASSWORD=""
        ;;
        *)
            local USERLOGIN=""
            local PASSWORD=""
            echo "ENV ${ENV} inconue"
            return
        ;;
    esac
EOF
    fi

    source "${LOGINFILE}"

    if [ -z "$PASSWORD" ] || [ -z "$USERLOGIN" ]
    then
        echo éditer le ficher "$LOGINFILE"
        return 1
    fi

    curl -o /dev/null -D - "https://api.$ENV.colisweb.com/api/v6/authent/external/session" \
        --data-raw '{"username":"'"${USERLOGIN}"'","password":"'"${PASSWORD/\"/\\\"}"'"}' \
        --compressed 2> /dev/null  | grep set-cook | sed -e 's/.*session=//g;s/;.*//g'
}

function bash_array_to_json {
    function join { 
        local IFS="$1"
        shift
        echo "$*"
    }

    echo '["'"$(join , $*| sed -e 's/,/","/g' )"'"]' | jq
}

function get_random_street {
    if [ ! -f "rue.lst" ]; then
        curl --output tmp1.gz https://adresse.data.gouv.fr/data/ban/adresses/latest/csv/adresses-59.csv.gz
        gzip -d tmp1.gz
        cut -d\; -f3,5,6,8 tmp1 | sed '/;Lille/!d' > rue.lst
        rm tmp
    fi

    sort -R rue.lst | head -n 1
}

function rand_slot {
    DATE="$1"

    USAGE=$(cat <<-EOF
        {"start":"${DATE}T06:00:00.000Z", "end":"${DATE}T08:00:00.000Z" }
        {"start":"${DATE}T08:00:00.000Z", "end":"${DATE}T10:00:00.000Z" }
        {"start":"${DATE}T10:00:00.000Z", "end":"${DATE}T12:00:00.000Z" }
        {"start":"${DATE}T16:00:00.000Z", "end":"${DATE}T18:00:00.000Z" }
        {"start":"${DATE}T18:00:00.000Z", "end":"${DATE}T20:00:00.000Z" }
EOF
        ) 
        
    echo "$USAGE" |  sort -u -R | head -n 1 
}

function call_create_sfh_order {
    local ENV=$1 
    local TOKEN=$2
    source "$3"
    local POS=$4
    local BARECODES="$5"
    local PACKAGES=$(echo "$BARECODES" | jq '[{
                "barcode": .[],
                "length": 10.5,
                "height": 9.0,
                "width": 9.0,
                "weight": 10.11,
                "description": "test parel",
                "options": [],
                "productTypology": "Classical",
                "packageType": "Parcel"
            }
        ]')

    IFS=";" read -r nu rue code_postal ville < <(get_random_street)
    JSON='{
        "primaryOrderReference": "'"${PRIMARY_REF}${POS}"'",
        "secondaryOrderReference": null,
        "stages": [
            {
                "type": "Pickup",
                "packageBarcodes": '"$BARECODES"',
                "location": {
                    "type": "Warehouse",
                    "warehouseCode": "'"$PICKUP_WAREHOUSE_CODE"'"
                }
            },
            {
                "type": "Dropoff",
                "packageBarcodes": '"$BARECODES"',
                "location": {	
                    "type": "Address",
                    "address": {
                        "address1": "'"$nu $rue"'",
                        "postalCode": "'"$code_postal"'",
                        "city": "'"$ville"'",
                        "country": "France",
                        "floor": 0,
                        "lift": "with_lift"
                    },
                    "contact": {
                        "name": "John Doe",
                        "primaryPhone": "+33606060606"
                    }
                }
            }
        ],
        "packages": '"$PACKAGES"',
        "owner": {
            "accountIdentifier": "'$ACCOUNTIDENTIFIER'"
        },
        "deliveryOptions": [],
        "ecommerceValidationDate": "'"${DATE}"'"
    }'

    curl -X POST https://api.$ENV.colisweb.com/api/v6/order/external/warehouse/orders -H 'content-type: application/json'  --cookie session="$TOKEN" --data-raw "$JSON" 
}


function call_scan {
    local ENV=$1 
    local TOKEN=$2
    source "$3"
    local BARECODES="$4"
    local SCAN=$(echo "$BARECODES" | jq '[{"barcode" :.[], "context": "shuttle"}]')

    IFS=";" read -r nu rue code_postal ville < <(get_random_street)
    JSON='{"scans":'$SCAN'}'

    curl -X POST https://api.$ENV.colisweb.com/api/v6/parcel/external/units/scans/bulk -H 'content-type: application/json'  --cookie session="$TOKEN" --data-raw "$JSON" 
}


function call_register_delivery {
    local ENV=$1 
    local TOKEN=$2

    SCENARIO=$3
    source "$SCENARIO"

    local ORDERID=$4    
    local BARECODES="$5"
    
    curl -X POST https://api.$ENV.colisweb.com/api/v6/order/external/warehouse/orders/"$ORDERID"/deliveries \
        --cookie session="$TOKEN" --data-raw '{
            "slot": '"$(rand_slot ${DELIVERY_DATE})"',
            "storeIdOwner":"'"$STOREIDOWNER"'",
            "pickup":{"type":"hub","code":"'"$HUB"'"},
            "barcodes":'"$BARECODES"',
            "price":{"origin":"auto","amount":25.9},
            "allowCustomerSlotUpdate":false
        }'
}



function _create_scenario_file_if_not_exist () {
if [ ! -f "$SCENARIO" ] 
    then
        cat > "$SCENARIO" <<-'EOF'
    DELIVERY_DATE=$(date -v+7d '+%Y-%m-%d')
    ENV="testing"
    # ENV="staging"
    # ENV="recette"

    ACCOUNTIDENTIFIER="102"
    HUB="duck"
    STOREIDOWNER="184"

    PICKUP_WAREHOUSE_CODE="422"

    BARECODES_COUNT=5
    PREF="aaaa"


    DATE=$(date '+%Y-%m-%d')
    RAND=$(date +%y%m%d%H%M%S)
    BARECODE_PART=0000$RAND
    PRIMARY_REF=$PREF$RAND
EOF
echo "éditer le fichier $SCENARIO"
return 1
fi
}

#!/usr/bin/env bash

cleanup_merged_mr() {
  COLISWEB_IDL_GROUP=3054234

  BEFORE=${1:- $(date -I -v -2y)}

  for (( COUNTER=1; COUNTER<=12; COUNTER+=2 )); do
    cleanup_grouped_merged_mr $COLISWEB_IDL_GROUP $BEFORE $COUNTER &
  done

}

cleanup_grouped_merged_mr() {
  GROUP=$1
  BEFORE=$2
  PAGE_COUNT=$3
  MERGED_MRS=($(curl --header "PRIVATE-TOKEN: $GITLAB_PAT" \
                    --url "https://gitlab.com/api/v4/groups/$GROUP/merge_requests?updated_before=${BEFORE}T08:00:00Z&status=merged&per_page=50&page=$PAGE_COUNT" |
                     jq -r '.[] | {iid: .iid|tostring, pid:.project_id|tostring} | (.pid + "/merge_requests/" + .iid)'))

  for MR in ${MERGED_MRS[@]}; do
    echo "https://gitlab.com/api/v4/projects/$MR"
    curl --request DELETE \
      --header "PRIVATE-TOKEN: $GITLAB_PAT" \
      --url "https://gitlab.com/api/v4/projects/$MR"
  done
}
# FIXME
# image index (docker manifest) does not have tags and images are tagged but not marked as related to the index.
# Should be fixed using more complex procedure to relate index and images.
# you will need jq to use these commands. You can install it using "brew install jq"
# cleanup_ecr_images colisweb_api 8
# will delete images older than 8 weeks
cleanup_ecr_images() {

  REPO=$1
  WEEKS=${2:-16}

  WEEKS_AGO=$(date -v-${WEEKS}w +%F)

  #Get all ecr images
  IMAGES=$(aws ecr describe-images --repository-name $REPO --output json)

  #Filter unnecessary values and map `imagePushedAt` to EPOCH
  NON_LATEST_IMAGES=$(echo $IMAGES | jq '[.imageDetails[] | select(.imageTags | any(endswith("latest")) | not)]')

  #Filter on EPOCH
  OLD_IMAGES=$(echo $NON_LATEST_IMAGES | jq --arg date $WEEKS_AGO '.[] | select(.imagePushedAt[0:10] < $date).imageDigest')
  while IFS= read -r IMAGE; do
    if [ "$IMAGE" != "" ]; then
      echo "Deleting $IMAGE from $REPO"
      AWS_PAGER="" aws  ecr batch-delete-image --repository-name $REPO --image-ids imageDigest=$IMAGE
    fi
  done <<< "$OLD_IMAGES"
}

# cleanup_all_ecr_images 12
# will delete images in all repositories older than 12 weeks
cleanup_all_ecr_images() {
  REPOSITORIES=$(aws ecr describe-repositories --output json | jq -r '.[]|.[].repositoryName')

  while IFS= read -r REPO; do
    echo "processing ECR repository $REPO"
    cleanup_ecr_images $REPO $1
  done <<< "$REPOSITORIES"
}

cleanup_ci_cache() {
  DATE=${1:-$(date -v-1m +%F)}
  CACHE_BUCKET=${2:-"s3://gitlab-colisweb-distributed-cache/project/"}

  echo "deleting from cache $CACHE_BUCKET all older than $DATE"

  aws_ecr_login

  while read -r line; do
    datum=$(echo $line | cut -c1-10)
    if [[ "$datum" < "$DATE" ]] ; then
      # Shell Parameter Expansion: ${parameter##word}
      # Allow to return the result from "word" to the end of "parameters"
      # Here we need the end of the string after "project/" (corresponding to the S3 gitlab project id and filename)
      TO_DELETE="$CACHE_BUCKET${line##* project/}"
      echo $TO_DELETE
      aws s3 rm $TO_DELETE
    fi
  done < <(aws s3 ls $CACHE_BUCKET  --recursive)
}

#!/usr/bin/env bash

ftp_ikea_k8s() {
  SSH_LOCAL_PORT=2230
  FTP_LOCAL_PORT=25500
  start_ssh_bastion testing $SSH_LOCAL_PORT

  lsof -ti  tcp:$FTP_LOCAL_PORT | xargs kill

  bastion_config=$(mktemp)
  cat > "$bastion_config" <<EOF
	  UserKnownHostsFile /dev/null
	  StrictHostKeyChecking no
	  User root
	  Host bastion_ftp
		HostName 127.0.0.1
		Port 2230
		LocalForward 25500 ft.centiro.ikea.com:22
EOF

  ssh -f -N \
  	-F "$bastion_config" \
  	"bastion_ftp"

  sftp -P $FTP_LOCAL_PORT colisweb.fr@127.0.0.1
}

#!/usr/bin/env bash

# usage:
# jconsole_k8s testing colisweb-api-web

jconsole_k8s() {
  ENV=$1
  NAME=$2

  start_ssh_bastion $ENV 2242
  POD_IP=$( \
    kubectl -n $ENV get pods -o jsonpath='{range .items[*]}{.metadata.name}{" "}{.status.podIP}{"\n"}{end}' \
    | grep "$NAME" | cut -d' ' -f2 | head -1 \
  )
  echo "selected POD with ip $POD_IP"
  echo "use 'root' as password"
  ssh -f -N -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no -D 7777 root@127.0.0.1 -p 2242

  jconsole \
    -J-DsocksProxyHost=localhost \
    -J-DsocksProxyPort=7777 \
    -J-DsocksNonProxyHosts= \
    service:jmx:rmi:///jndi/rmi://$POD_IP:7199/jmxrmi \
    &

  echo "remember to stop with 'stop_ssh_bastion'"

}

#!/usr/bin/env bash

# Interactive console on an new pod. See also run_ruby_k8s
# Ex :
# railsc_k8s production
# railsc_k8s production "User.where(email:'toni@colisweb.com')"
railsc_k8s() {
  ENV=$1
  COMMAND=$2
  [[ $ENV = "production" || $ENV = "staging" ]] && default_tag="master-latest" || default_tag="${ENV}-latest"
  local image_tag=${5:-$default_tag}
  local IMAGE="949316342391.dkr.ecr.eu-west-1.amazonaws.com/colisweb-api:$image_tag"
  local POD_NAME="colisweb-api-rails-console-$image_tag-$USERNAME"

  kubectl -n $ENV get pod $POD_NAME && kubectl -n $ENV delete pod $POD_NAME

  configure_kubectl_for $ENV
  echo "starting with $IMAGE"

  kubectl -n $ENV run $POD_NAME \
       --image $IMAGE \
       --restart=Never \
       --overrides='{
       "spec":{
          "nodeSelector":{
            "workType": "workers"
          },
          "containers":[
             {
                "name":"'$POD_NAME'",
                "image":"'$IMAGE'",
                "imagePullPolicy":"Always",
                "command":[
                  "sleep",
                  "infinity"
                ],
                "resources":{
                  "limits":{
                    "memory": "2048Mi"
                  }
                },
                "envFrom": [ {
                     "configMapRef": {
                         "name": "colisweb-api"
                     }
                   }, {
                     "secretRef": {
                         "name": "colisweb-api"
                     }
                   }
                ]
             }
          ]
       }
    }
    '

  sleep 5
  KUBERAILS="kubectl -n $ENV exec -ti $POD_NAME -- /usr/src/app/bin/rails c"
  [ -z "$COMMAND" ] && eval $KUBERAILS || echo $COMMAND | eval $KUBERAILS

  print "End of $POD_NAME "
  kubectl -n $ENV delete pods $POD_NAME
}

# Ex :
# create_user testing claire.lien@colisweb.com super_admin clairemdp
create_user() {
  ENV=$1
  EMAIL=$2
  ROLE=$3
  PASSWORD=$4
  railsc_k8s $ENV "User.where(email:'$EMAIL', role:'$ROLE').first_or_create.update_attributes!(password: '$PASSWORD')"
}

# Ex :
# delete_user testing claire.lien@colisweb.com 
delete_user() {
  ENV=$1
  EMAIL=$2
  railsc_k8s $ENV "User.find_by(email:'$EMAIL').destroy"
}

# NON Interactive console on an new pod, for long-running tasks (a few minutes)
# See also railsc_k8s
# file.txt will be available from /conf/data.txt in the ruby code
# examples :
# run_ruby_k8s testing demo <(echo "pp JSON.parse(File.read('/conf/data.txt'))")  <(echo '{ "content": 123 }')
# run_ruby_k8s testing demo ~/.oh-my-zsh/custom/dev-tools/shell-session/ruby/demo.rb  <(echo '{ "content": 123 }')
run_ruby_k8s() {
  if [ $# -lt 4 ]; then
    echo "usage : run_ruby_k8s production name-for-pod script.rb file.txt"
    return 1
  fi
  local namespace=$1
  local name=$2
  local ruby_script=$3
  local input_data=$4
  [[ $namespace = "production" || $namespace = "staging" ]] && default_tag="master-latest" || default_tag="${namespace}-latest"
  local image_tag=${5:-$default_tag}

  if [ ! -r "$ruby_script" ]; then
    echo "ruby script not found $ruby_script"
    return 2
  fi

  if [ ! -r "$input_data" ]; then
    echo "data not found $input_data"
    return 3
  fi


  local IMAGE="949316342391.dkr.ecr.eu-west-1.amazonaws.com/colisweb-api:$image_tag"
  local POD_NAME="colisweb-api-script-$name"
  local CONFIG_MAP="config-$POD_NAME"
  local CONFIG_MAP_DIR="$(mktemp -d)"


  configure_kubectl_for $namespace


  cp "$ruby_script" "$CONFIG_MAP_DIR/script.rb"
  cp "$input_data" "$CONFIG_MAP_DIR/data.txt"

  kubectl -n $namespace get configmap $CONFIG_MAP && kubectl -n $namespace delete configmap $CONFIG_MAP
  kubectl -n $namespace create configmap $CONFIG_MAP --from-file="$CONFIG_MAP_DIR"

  kubectl -n $namespace get pod $POD_NAME && kubectl -n $namespace delete pod $POD_NAME

  echo "starting with $IMAGE"
  kubectl -n $namespace run $POD_NAME \
     --image $IMAGE \
     -ti \
     --restart=Never \
     --attach \
     --rm \
     --overrides='{
     "spec":{
        "nodeSelector":{
          "workType": "workers"
        },
        "containers":[
           {
              "name":"'$POD_NAME'",
              "image":"'$IMAGE'",
              "imagePullPolicy":"Always",
              "command":[
                "/usr/src/app/bin/rails",
                "r",
                "/conf/script.rb"
              ],
              "resources":{
                "limits":{
                  "memory": "4096Mi"
                }
              },
              "volumeMounts":[
                 {
                    "name":"conf",
                    "mountPath":"/conf"
                 }
              ],
              "envFrom": [ {
                   "configMapRef": {
                       "name": "colisweb-api"
                   }
                 }, {
                   "secretRef": {
                       "name": "colisweb-api"
                   }
                 }
              ]
           }
        ],
          "volumes":[
           {
              "name":"conf",
              "configMap":{ "name":"'$CONFIG_MAP'" }
           }
        ]
     }
  }
  '

  kubectl -n $namespace delete configmap $CONFIG_MAP
}

# example:
# update_pickup_cp testing <( echo '{"wrong_cp": "59123", "corrected_cp": "59223", "delivery_ids": ["4192421", "4192425"]}' )
update_pickup_cp() {
	run_ruby_k8s $1 update-pickup-cp "$SCRIPT_FULL_PATH/ruby/update_pickup_cp.rb" $2
}



update_all_prices() {
  local namespace=$1
  local json_prices=$2

  local json_size=$(wc -c < "$json_prices")

  if ((json_size > 940000)); then
	command -v jq || (echo "jq not found (use brew install jq)" && return 1)
    local max_lines=3000
    local total_lines=$(jq '. | length' $json_prices)
    local iterations=$((total_lines / max_lines + 1))
    echo "$json_prices is too big, I'll split it for you in blocks of $max_lines lines. It will take $iterations runs"
    for (( i = 0 ; i < iterations ; i++ )) ; do
      local start=$((i * max_lines))
      local end=$(( (i + 1) * max_lines))
      local split_file=$(mktemp)
      jq -c ".[$start:$end]" $json_prices > $split_file
      local split_lines=$(jq '. | length' $split_file)
      echo "starting iteration $i from $start to $end with $split_file command -v has $split_lines lines"
      run_ruby_k8s $namespace "update-prices-$i" "$SCRIPT_FULL_PATH/ruby/update_prices.rb" $split_file
    done
  else
  	run_ruby_k8s $namespace "update-prices" "$SCRIPT_FULL_PATH/ruby/update_prices.rb" $json_prices
  fi
}


update_surveys() {
  local namespace=$1
  local csv_surveys=$2

  local csv_size=$(wc -c < "$csv_surveys")


  if ((csv_size > 940000)); then
    local max_lines=400
    local total_lines=$(wc -l < $csv_surveys)
    local iterations=$((total_lines / max_lines + 1))
    echo "$csv_surveys is too big, I'll split it for you in blocks of $max_lines lines. It will take $iterations runs"
    for (( i = 0 ; i < iterations ; i++ )) ; do
      local start=$((i * max_lines + 2))
      local end=$(( (i + 1) * max_lines + 1))
      local split_file=$(mktemp)
      head -1 $csv_surveys > $split_file
      sed -n ''"$start,${end}p" $csv_surveys >> $split_file


      local split_lines=$(wc -l < $split_file)
      echo "starting iteration $i from $start to $end with $split_file command -v has $split_lines lines"
      run_ruby_k8s $namespace "reimport-surveys-$i" "$SCRIPT_FULL_PATH/ruby/feedback_kpi_reuploader.rb" $split_file
    done
  else
  	run_ruby_k8s $namespace "reimport-surveys" "$SCRIPT_FULL_PATH/ruby/feedback_kpi_reuploader.rb" $csv_surveys
  fi
}

#!/usr/bin/env bash

configure_gitlab_ssh() {
  tmp_dir=$(mktemp -d)
  ssh-keyscan gitlab.com > $tmp_dir/known_hosts
  echo "$SSH_PRIVATE_KEY" > $tmp_dir/id_rsa
  chmod 600 $tmp_dir/id_rsa
  ssh -i $tmp_dir/id_rsa -T git@gitlab.com
  rm -Rf $tmp_dir
}


configure_gitlab_ssh_home() {
  mkdir ~/.ssh
  ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
  echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
  chmod 600 ~/.ssh/id_rsa
  ssh -T git@gitlab.com
}
#!/usr/bin/env bash

datadog_schedule_downtime() {
  SERVICES=$1
  DOWNTIME_MINUTES=${2:-30}

  if [[ "$ENVIRONMENT" == "production" ]] ; then
    log "scheduling downtime for $SERVICES in $ENVIRONMENT"
  else
    return 0
  fi

  for SERVICE in $SERVICES ; do
    datadog_schedule_downtime_single $SERVICE $DOWNTIME_MINUTES
  done
}

datadog_schedule_downtime_single() {
  local SERVICE=$1
  local DOWNTIME_MINUTES=$2

  START=$(date +%s)
  END=$((START + 60 * DOWNTIME_MINUTES))

  log "scheduling a downtime on datadog for $SERVICE ($DOWNTIME_MINUTES minutes)"
  curl -X POST "https://api.datadoghq.com/api/v1/downtime" \
    -H "Content-Type: application/json" \
    -H "DD-API-KEY: ${DD_API_KEY}" \
    -H "DD-APPLICATION-KEY: ${DD_APP_KEY}" \
    -d '
      {
        "active": true,
          "downtime_type": 0,
          "start": '$START',
          "end": '$END',
          "message": "CA Deployment - performance for '$SERVICE' may be lower for next '$DOWNTIME_MINUTES' min",
          "monitor_tags": [
            "service:'$SERVICE'",
            "performance"
          ],
          "scope": [
            "env:production"
          ],
          "timezone": "Europe/Paris"
      }
      '
}

#!/usr/bin/env bash

docker_build_push() {
  read -r -a BUILD_ARGS <<< "$1"
  DOCKER_BUILD_ARGS="--build-arg VCS_REF=$(git rev-parse --short HEAD)"

  for ARG_NAME in "${BUILD_ARGS[@]}"
  do
     DOCKER_BUILD_ARGS="$DOCKER_BUILD_ARGS --build-arg $ARG_NAME=${!ARG_NAME}"
  done

  if ! image_exists $DOCKER_REGISTRY_ID $APPLICATION $CI_COMMIT_SHORT_SHA ; then
    docker pull $DOCKER_IMAGE || true
    SOURCE_URL=${CI_PROJECT_URL:8} # without "https://" protocol, like gitlab.com/colisweb-idl/colisweb/back/packing

    docker buildx create --use

    docker buildx build $DOCKER_BUILD_ARGS \
      -t $DOCKER_IMAGE_SHA \
      --platform "linux/arm64,linux/amd64" \
      --label org.opencontainers.image.revision=$(git rev-parse HEAD) \
      --label org.opencontainers.image.source=$SOURCE_URL \
      --provenance=false \
      --push \
      $DOCKER_STAGE_PATH
  fi
}


docker_promote() {
   # inspired by https://dille.name/blog/2018/09/20/how-to-tag-docker-images-without-pulling-them/
   OLD_TAG=${1//[^0-9a-zA-Z-.]/_}
   NEW_TAG=${2//[^0-9a-zA-Z-.]/_}
   echo "promoting from $OLD_TAG to $NEW_TAG"
   TOKEN=$(aws_ecr_token)
   CONTENT_TYPE="application/vnd.docker.distribution.manifest.v2+json"
   MANIFESTS_API="https://${DOCKER_REGISTRY}/v2/${APPLICATION}/manifests"

   if MANIFEST=$(curl --fail -H "Authorization: Basic $TOKEN" -H "Accept: ${CONTENT_TYPE}" "$MANIFESTS_API/${OLD_TAG}"); then
     echo "authenticated on $MANIFESTS_API"
   else
     return 1
   fi
   if curl --fail -H "Authorization: Basic $TOKEN" -X PUT -H "Content-Type: ${CONTENT_TYPE}" -d "${MANIFEST}" "$MANIFESTS_API/$NEW_TAG" ; then
     echo "promoted ${APPLICATION} from $OLD_TAG to $NEW_TAG"
   else
     return 2
   fi
 }

 ensure_images_exists() {
   for IMAGE_TO_CHECK in $(echo $1 | tr "," "\n"); do
     image_exists ${DOCKER_REGISTRY_ID} ${IMAGE_TO_CHECK} ${VERSION} || return 1
   done
 }

#!/usr/bin/env bash

extract_yaml_config_variable() {
  set +e
  set +x

  check_args "--environment" $1
  shift
  ENVIRONMENT=$1
  shift

  check_args "--configs-path" $1
  shift
  CONFIGS_PATH=$1
  shift

  check_args "--variable" $1
  shift
  VARIABLE=$1
  shift

  [[ "$1" == "--optional" ]] && OPTIONAL=true || OPTIONAL=false

  if [ ! -f ${CONFIGS_PATH}/common.yaml ]; then
    echo >&2 "Missing $CONFIGS_PATH/common.yaml configuration file"
    exit 1
  fi
  if [ ! -f ${CONFIGS_PATH}/${ENVIRONMENT}.yaml ]; then
    echo >&2 "Missing $CONFIGS_PATH/$ENVIRONMENT.yaml configuration file"
    exit 1
  fi
  if [ ! -f ${CONFIGS_PATH}/${ENVIRONMENT}-secrets.yaml ]; then
    echo >&2 "Missing $CONFIGS_PATH/$ENVIRONMENT-secrets.yaml configuration file"
    exit 1
  fi

  result=$(yq -r ${VARIABLE} "$CONFIGS_PATH/$ENVIRONMENT-secrets.yaml")
  if [ $? -ne 0 ] || [ "$result" = "null" ]; then
    result=$(yq -r ${VARIABLE} "$CONFIGS_PATH/$ENVIRONMENT.yaml")
    if [ $? -ne 0 ] || [ "$result" = "null" ]; then
      result=$(yq -r ${VARIABLE} "$CONFIGS_PATH/common.yaml")
      if [ $? -ne 0 ] || [ "$result" = "null" ]; then
        if [ $OPTIONAL = true ]; then
          echo ""
          exit 0
        else
          echo >&2 "Missing path $VARIABLE in $CONFIGS_PATH/$ENVIRONMENT-secrets.yaml, $CONFIGS_PATH/$ENVIRONMENT.yaml or $CONFIGS_PATH/common.yaml"
          exit 1
        fi
      fi
    fi
  fi
  echo ${result}
}
#!/usr/bin/env bash

flyway_clean() {
  HOST="$1"
  PORT="$2"
  DATABASE="$3"
  USER="$4"
  PASSWORD="$5"

  kubectl run -it --rm flywayclean \
  --image=flyway/flyway \
  --restart=Never \
  -- \
  -cleanDisabled=false \
  -url="jdbc:postgresql://$HOST:$PORT/$DATABASE" \
  -user="$USER" \
  -password="$PASSWORD" \
  clean
}

#!/usr/bin/env bash

FLYWAY_VERSION="7.4.0"


get_yaml_variable() {
  extract_yaml_config_variable --environment ${ENVIRONMENT} --configs-path $(pwd)/deploy --variable $@
}

init_migrate_db() {
  set -e

  check_env_vars 4 "APPLICATION" "ENVIRONMENT" "FLYWAY_VERSION" "MIGRATION_SQL_PATH"

  PG_YAML_PATH=".${APPLICATION}config.postgres"

  DB_PORT="5432"
  DB_HOST=$(get_yaml_variable "${PG_YAML_PATH}.host")
  DB_INIT_USERNAME=$(get_yaml_variable "${PG_YAML_PATH}.initUsername")
  DB_INIT_PASSWORD=$(get_yaml_variable "${PG_YAML_PATH}.initPassword")
  DB_DATABASE=$(get_yaml_variable "${PG_YAML_PATH}.database")
  DB_USER=$(get_yaml_variable "${PG_YAML_PATH}.user")
  DB_PASSWORD=$(get_yaml_variable "${PG_YAML_PATH}.password")
  DB_URL="jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_DATABASE}"

  DB_RO_USER=$(get_yaml_variable "${PG_YAML_PATH}.readOnlyUser" --optional)
  DB_RO_PASSWORD=$(get_yaml_variable "${PG_YAML_PATH}.readOnlyPassword" --optional)

  unset KUBECONFIG

  configure_kubectl_for ${ENVIRONMENT}

  kube_init_service_database \
    --namespace ${ENVIRONMENT} \
    --service ${APPLICATION} \
    --db_host ${DB_HOST} \
    --db_port ${DB_PORT} \
    --db_init_username ${DB_INIT_USERNAME} \
    --db_init_password ${DB_INIT_PASSWORD} \
    --db_database ${DB_DATABASE} \
    --db_username ${DB_USER} \
    --db_password ${DB_PASSWORD}

  if [[ ! -z "$DB_RO_USER" ]] && [[ ! -z "$DB_RO_USER" ]]; then
    kube_init_database_readonly_account \
      --namespace ${ENVIRONMENT} \
      --service ${APPLICATION} \
      --db_connection "$DB_INIT_USERNAME:$DB_INIT_PASSWORD@$DB_HOST:$DB_PORT" \
      --db_database ${DB_DATABASE} \
      --db_readonly_username ${DB_RO_USER} \
      --db_readonly_password ${DB_RO_PASSWORD}
  fi

  flyway_migrate \
    --environment ${ENVIRONMENT} \
    --namespace ${ENVIRONMENT} \
    --service ${APPLICATION} \
    --db_url ${DB_URL} \
    --db_user ${DB_USER} \
    --db_password ${DB_PASSWORD} \
    --flyway_version ${FLYWAY_VERSION} \
    --flyway_sql_folder $(pwd)/${MIGRATION_SQL_PATH}
}

flyway_migrate() {
  set -e

  extract_args 8 \
    environment namespace service db_url db_user db_password flyway_version flyway_sql_folder $*

  echo "running flyway migrations for service $service in environment $environment namespace $namespace for db_url $db_url with user $db_user"
  echo "migration files expected in $flyway_sql_folder"

  CONFIGMAP_NAME="$service-flyway-migration-sql"
  POD_NAME="$service-flyway-migration"

  configure_kubectl_for $environment

  kubectl -n $namespace delete configmap $CONFIGMAP_NAME --ignore-not-found
  kubectl -n $namespace delete pod $POD_NAME --ignore-not-found
  kubectl -n $namespace create configmap $CONFIGMAP_NAME --from-file=$flyway_sql_folder

  kubectl -n $namespace run $POD_NAME --image ignored -ti --restart=Never --attach --rm --overrides='
{
   "spec":{
      "containers":[
         {
            "name":"'$POD_NAME'",
            "image":"flyway/flyway:'$flyway_version'",
            "command":["flyway", "-url='$db_url'", "-user='$db_user'", "-password='$db_password'", "migrate"],
            "volumeMounts":[
               {
                  "name":"sql",
                  "mountPath":"/flyway/sql"
               }
            ]
         }
      ],
      "volumes":[
         {
            "name":"sql",
            "configMap":{
               "name":"'$CONFIGMAP_NAME'"
            }
         }
      ]
   }
}
'

  kubectl -n $namespace delete configmap $CONFIGMAP_NAME
}

#!/usr/bin/env bash
 flyway_repair() {
  set -e
  check_env_vars 4 "APPLICATION" "ENVIRONMENT" "FLYWAY_VERSION" "MIGRATION_SQL_PATH"

  PG_YAML_PATH=".${APPLICATION}config.postgres"

  DB_PORT="5432"
  DB_HOST=$(get_yaml_variable "${PG_YAML_PATH}.host")
  DB_DATABASE=$(get_yaml_variable "${PG_YAML_PATH}.database")
  DB_USER=$(get_yaml_variable "${PG_YAML_PATH}.user")
  DB_PASSWORD=$(get_yaml_variable "${PG_YAML_PATH}.password")
  DB_URL="jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_DATABASE}"

  flyway_sql_folder=$(pwd)/${MIGRATION_SQL_PATH}

  configure_kubectl_for "${ENVIRONMENT}"
  POD_NAME="${APPLICATION}-flyway-repair"
  CONFIGMAP_NAME="${APPLICATION}-flyway-repair-sql"

  kubectl -n "${ENVIRONMENT}" delete configmap $CONFIGMAP_NAME --ignore-not-found
  kubectl -n "${ENVIRONMENT}" delete pod $POD_NAME --ignore-not-found
  kubectl -n "${ENVIRONMENT}" create configmap $CONFIGMAP_NAME --from-file="${flyway_sql_folder}"

  kubectl -n "${ENVIRONMENT}" run --rm  -it "${POD_NAME}" \
  --image=flyway/flyway \
  --restart=Never \
  --overrides='
  {
     "spec":{
        "containers":[
           {
              "name":"'$POD_NAME'",
              "image":"flyway/flyway:'${FLYWAY_VERSION}'",
              "command":["flyway", "-url='$DB_URL'", "-user='$DB_USER'", "-password='$DB_PASSWORD'", "repair"],
              "volumeMounts":[
                 {
                    "name":"sql",
                    "mountPath":"/flyway/sql"
                 }
              ]
           }
        ],
        "volumes":[
           {
              "name":"sql",
              "configMap":{
                 "name":"'$CONFIGMAP_NAME'"
              }
           }
        ]
     }
  }
  '
  kubectl -n "${ENVIRONMENT}" delete configmap $CONFIGMAP_NAME
}

#!/usr/bin/env bash

record_git_commit() {
    for file in $GIT_COMMIT_FILES; do
      sed -i 's&GIT_COMMIT&'"${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}&" "$file"
    done
}

gitlab_import_pgp_key() {
  if [ "$GITLAB_PGP_PRIVATE_KEY" != "" ]
  then
    KEY_FOLDER=<(echo "$GITLAB_PGP_PRIVATE_KEY")
    gpg --import $KEY_FOLDER > /dev/null
  else
    echo '$GITLAB_PGP_PRIVATE_KEY is not set'
    return 1
  fi
}

git_reveal() {
  gitlab_import_pgp_key
  gpg --decrypt $1
}
#!/usr/bin/env bash

helm_deploy() {
  APPLICATION=$1
  ENVIRONMENT=$2
  VERSION=$3
  deploy_chart \
    --path_configs deploy \
    --path_chart deploy/$APPLICATION \
    --application $APPLICATION \
    --environment $ENVIRONMENT \
    --namespace $ENVIRONMENT \
    --helm_extra_args --set global.version=$VERSION
}

deploy_chart() {
  set -e
  set -x

  # Rigid parsing, but all args are mandatory (expect last) and flexible order is unnecessary
  check_args "--path_configs" $1; shift
  path_configs=$1; shift
  check_args "--path_chart" $1; shift
  path_chart=$1; shift
  check_args "--application" $1; shift
  application=$1; shift
  check_args "--environment" $1; shift
  environment=$1; shift
  check_args "--namespace" $1; shift
  namespace=$1; shift
  if [ $# -ne 0 ]; then
    check_args "--helm_extra_args" $1; shift
    helm_extra_args=$*
  fi

  echo "================================"
  echo " Deploying $application"
  echo " - Environment: $environment"
  echo " - Namespace: $namespace"
  echo "================================"

  root_path=$(pwd)

  # Check the configs exists

  check_config_file ${root_path}/${path_configs}/common.yaml
  check_config_file ${root_path}/${path_configs}/${namespace}.yaml
  check_config_file ${root_path}/${path_configs}/${namespace}-secrets.yaml

  # Check the chart exists
  if [ ! -d ${root_path}/${path_chart} ] || [ ! -f ${root_path}/${path_chart}/Chart.yaml ]; then
      echo "Bad Chart $root_path/$path_chart : does not exists or missing Chart.yaml"
      print_usage
      exit 1
  fi

  # Unset Kubectl configuration made via the KUBECONFIG env variable
  #  it would override the config made by configure_kubectl_for
  #  for example, using Gitlab runners in Kubernetes sets this variable and causes conflict
  unset KUBECONFIG

  # Configure Kubectl
  configure_kubectl_for ${environment}

  # Configure helm
  helm version --namespace ${namespace} || true
  # helm stable repo have changed and must be updated manually, in versions < v2.17.0
  helm repo add colisweb s3://colisweb-helm-charts/colisweb
  helm repo add stable https://charts.helm.sh/stable
  helm repo update
  helm dependency update ${root_path}/${path_chart}

  # Gather values/*.yaml files
  values_path="${root_path}/${path_chart}/values"
  values_files=''
  [ -d $values_path ] && values_files=$(find $values_path -type f -maxdepth 1 -name "*.yaml" | sed 's/^/ -f /' | tr -d \\n | sed 's/%//')

  # Deploy
  helm upgrade --install \
    --namespace ${namespace} \
    ${values_files} \
    -f ${root_path}/${path_configs}/common.yaml \
    -f ${root_path}/${path_configs}/${namespace}.yaml \
    -f ${root_path}/${path_configs}/${namespace}-secrets.yaml \
    ${helm_extra_args} \
    ${application} ${root_path}/${path_chart}

  #send event to dd
  PUBLISHED_VERSION="$CI_COMMIT_REF_NAME-$CI_COMMIT_SHA"
  emit_datadog_deploy_event  --environment $environment --service $application  --version $PUBLISHED_VERSION

  echo "================================"
  echo " Deployed $application"
  echo " - Environment: $environment"
  echo " - Namespace: $namespace"
  echo "================================"

  set +x
}

verify_deployments() {
  set -e

  # usage :
  # verify_deployments staging price
  # verify_deployments -t 15m testing price

  if [ "$1" = "-t" ] ; then
    TIMEOUT=$2
    shift
    shift
  else
    TIMEOUT=5m
  fi

  NAMESPACE=$1
  RELEASE=$2

  # Get all Deployments names from the deployed chart
  DEPLOYMENTS=(
    $(helm get manifest --namespace $NAMESPACE $RELEASE | yq --no-doc -r 'select(.kind=="Deployment").metadata.name')
  )

  echo "verifying on $NAMESPACE deployments ${DEPLOYMENTS[@]} with a timeout of $TIMEOUT"

  PIDS=()
  for D in "${DEPLOYMENTS[@]}"; do
    kubectl -n ${NAMESPACE} rollout status deployment ${D} --timeout=${TIMEOUT} &
    PIDS+=($!)
  done

  for P in ${PIDS[@]}; do
    wait $P

    if [ $? -ne 0 ]; then
      echo "at least one deployment failed or timed out (after $TIMEOUT)"
      exit 1
    fi
  done

}

print_usage() {
  echo "Usage:"
  echo "deploy_chart \\"
  echo "  --path_configs <path to .yaml namespaces and secret config files>"
  echo "  --path_chart <path to Helm Chart>"
  echo "  --application <application name used by Helm>"
  echo "  --environment <infrastructure environment>"
  echo "  --namespace <namespace>"
  echo "  --helm-extra-args <extra args to pass to helm, ex: --set my.value=42 --set your.setting=on>"
  echo ""
}

check_config_file() {
    local filename=$1
    if [ ! -f ${filename} ]; then
        echo "Missing $filename configuration file"
        print_usage
        exit 1
    fi
}

notify_new_deployment() {
  jq --version || (apt update && apt install -y jq)

  CHAT_URL=${1:-$DEFAULT_CHAT_URL}

  STATUS=$(echo $CI_JOB_STATUS | tr '[:lower:]' '[:upper:]' )
  ENV_NAME=$(echo $ENVIRONMENT | tr '[:lower:]' '[:upper:]' )

  JOB_LINK="<$CI_JOB_URL| $CI_JOB_NAME $CI_JOB_ID>"

  DESCRIPTION="
  $STATUS : Deployment for $CI_PROJECT_NAME on $ENV_NAME
  $JOB_LINK
  $CI_COMMIT_TITLE
  "

  JSON_MESSAGE=$(jq -n --arg text "$DESCRIPTION" '{text: $text }')
  curl -X POST $CHAT_URL \
  --header "Content-Type: application/json" \
  --data "$JSON_MESSAGE"
}
notify_new_version() {

  ! test -z $CI_COMMIT_TAG || exit 0

  jq --version || (apt update && apt install -y jq)

  KIND=$1
  CHAT_URL=${2:-$DEFAULT_CHAT_URL}

  STATUS=$(echo $CI_JOB_STATUS | tr '[:lower:]' '[:upper:]' )
  ENV_NAME=$(echo $ENVIRONMENT | tr '[:lower:]' '[:upper:]' )
  TITLE="$ENV_NAME *$STATUS* $KIND for version *$CI_COMMIT_TAG* of *$CI_PROJECT_NAME* "

  RELEASE_URL="https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/releases/$CI_COMMIT_TAG"

  NOTES=$(curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" $RELEASE_URL |
    jq .description |
    sed -e 's/^"//' -e 's/"$//' |
    sed -E 's/\[([^]]+)\]\(([^)]+)\)/<\2|\1>/g' |
    sed -E 's/\\n/\'$'\n/g')

  JOB_LINK="<$CI_JOB_URL| $CI_JOB_NAME $CI_JOB_ID>"

  DESCRIPTION="
  $TITLE
  $JOB_LINK
  $NOTES
  "

  JSON_MESSAGE=$(jq -n --arg text "$DESCRIPTION" '{text: $text }')
  curl -X POST $CHAT_URL \
    --header "Content-Type: application/json" \
    --data "$JSON_MESSAGE"
}
#!/usr/bin/env bash

skip_sbt_compile_cache() {
  COMPARED_BRANCH="${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-$CI_DEFAULT_BRANCH}"
  echo "branch to compare to: $COMPARED_BRANCH"
  git fetch origin $COMPARED_BRANCH
  echo "fetched $COMPARED_BRANCH"
  [[ "$CI_COMMIT_REF_NAME" =~ ^(master|develop)$ || $(git diff origin/$COMPARED_BRANCH --exit-code -- project) ]]
}
#!/usr/bin/env bash

# in case of trouble with functions for update history during import
# https://stackoverflow.com/questions/56729192/pg-restore-fails-when-trying-to-create-function-referencing-table-that-does-not

# example: clone_databases --source_env testing --destination_env recette --services "order,notification,parcel,ikea"
clone_databases() {
  export USERNAME="database-cloner"

  set -e

  extract_args 3 source_env destination_env services $*

  dump_databases "$source_env" "$services"
  import_databases "$destination_env" "$services"
}

dump_databases() {
  local env="$1"
  local services=$(echo -n "$2" | tr ',' '\n')

  database_k8s_output_dump_path="/tmp/database_k8s_output_dump"

  configure_kubectl_for "$env"
  set +e
  database_k8s "$env" > "$database_k8s_output_dump_path"
  set -e

  source_pg_local_port=$(extract_pg_local_port "$database_k8s_output_dump_path")

  for service in $services
  do
    service_path="/tmp/$service"

    set +e
    git clone "git@gitlab.com:colisweb/back/$service.git" "$service_path"
    set -e

    if cd "$service_path"; then
      echo "dump the database for service $service.."

      git secret reveal -f

      PG_YAML_PATH=".${service}config.postgres"

      SOURCE_DB_DATABASE=$(extract_yaml_config_variable --environment "$env" --configsPath ./deploy --variable "${PG_YAML_PATH}.database")
      SOURCE_DB_USER=$(extract_yaml_config_variable --environment "$env" --configsPath ./deploy --variable "${PG_YAML_PATH}.user")
      SOURCE_DB_PASSWORD=$(extract_yaml_config_variable --environment "$env" --configsPath ./deploy --variable "${PG_YAML_PATH}.password")

      export PGPASSWORD="$SOURCE_DB_PASSWORD"

      DUMP_PATH="/tmp/db_dump_${service}.sql"
      pg_dump --no-owner -h localhost -p "$source_pg_local_port" -U "$SOURCE_DB_USER" "$SOURCE_DB_DATABASE" > "$DUMP_PATH"

      cd ..
      rm -rf "$service_path"
    else
      echo "WARN: failed to clone $service - skipping"
    fi
  done
}

import_databases() {
  local env="$1"
  local services=$(echo -n "$2" | tr ',' '\n')

  database_k8s_output_import_path="/tmp/database_k8s_output_import"

  configure_kubectl_for "$env"
  set +e
  database_k8s "$env" > "$database_k8s_output_import_path"
  set -e

  destination_pg_local_port=$(extract_pg_local_port "$database_k8s_output_import_path")

  for service in $services
  do
    service_path="/tmp/$service"

    set +e
    git clone "git@gitlab.com:colisweb/back/$service.git" "$service_path"
    set -e

    if cd "$service_path"; then
      echo "create and import database for $service.."

      git secret reveal -f

      PG_YAML_PATH=".${service}config.postgres"

      DB_PORT="5432"
      DB_HOST=$(extract_yaml_config_variable --environment "$env" --configsPath ./deploy --variable "${PG_YAML_PATH}.host")
      DB_INIT_USERNAME=$(extract_yaml_config_variable --environment "$env" --configsPath ./deploy --variable "${PG_YAML_PATH}.initUsername")
      DB_INIT_PASSWORD=$(extract_yaml_config_variable --environment "$env" --configsPath ./deploy --variable "${PG_YAML_PATH}.initPassword")
      DB_DATABASE=$(extract_yaml_config_variable --environment "$env" --configsPath ./deploy --variable "${PG_YAML_PATH}.database")
      DB_USER=$(extract_yaml_config_variable --environment "$env" --configsPath ./deploy --variable "${PG_YAML_PATH}.user")
      DB_PASSWORD=$(extract_yaml_config_variable --environment "$env" --configsPath ./deploy --variable "${PG_YAML_PATH}.password")

      kube_init_service_database \
        --namespace ${env} \
        --service ${service} \
        --db_host ${DB_HOST} \
        --db_port ${DB_PORT} \
        --db_init_username ${DB_INIT_USERNAME} \
        --db_init_password ${DB_INIT_PASSWORD} \
        --db_database ${DB_DATABASE} \
        --db_username ${DB_USER} \
        --db_password ${DB_PASSWORD}

      echo "WARN: A complete clean of $DB_DATABASE on $DB_HOST will be operated"
      read -rsn1 -p"Press any key to continue";echo
      flyway_clean "$DB_HOST" "$DB_PORT" "$DB_DATABASE" "$DB_USER" "$DB_PASSWORD"

      DUMP_PATH="/tmp/db_dump_${service}.sql"
      export PGPASSWORD="$DB_PASSWORD"
      set +e
      psql "postgres://$DB_USER@127.0.0.1:$destination_pg_local_port" -p "$DB_DATABASE" -f "$DUMP_PATH"
      set -e

      cd ..
      rm -rf "$service_path"
    else
      echo "WARN: failed to clone $service - skipping"
    fi
  done
}

extract_pg_local_port() {
  cat "$1" | grep 'postgres@127.0.0.1:' | sed 's/.*postgres@127.0.0.1:\(.*[0-9]\).*/\1/g'
}
#!/usr/bin/env bash

emit_datadog_deploy_event() {
  extract_args 3 environment service version $*
  check_env_vars 1 "DD_API_KEY"

  response=$(
    curl -X POST -H "Content-type: application/json" \
      -d '{
              "title": "deploying '"$service"' to '"$environment"'",
              "text": "deploying '"$service"' version '"$version"' to '"$environment"'",
              "priority": "normal",
              "tags": ["service:'"$service"' ", "env:'"$environment"'" ,"action:'"deployment"'"] ,

              "alert_type": "Info"
        }' \
      "https://api.datadoghq.com/api/v1/events?api_key=$DD_API_KEY"
  )

  #echo $response
  EventID=$(echo $response | jq ".event.id")
  url=$(echo $response | jq ".event.url")

  if [[ $EventID -ne 0 ]]; then
    echo "event successfully created check in datadog UI : $url"
  else
    echo " failed to create event "
    exit 1
  fi
}

#!/usr/bin/env bash

# DEPRECATED
emit_datadog_error_events() {
  set -e
  extract_args 4 title text priority environment $*
  check_env_vars 1 "DD_API_KEY"

  curl -X POST -H "Content-type: application/json" \
    -d '{
              "title": "'"$title"'",
              "text": "'"$text"'",
              "priority": "'"$priority"'",
              "tags": ["environment:'"$environment"'"],
              "alert_type": "Error"
        }' \
    "https://api.datadoghq.com/api/v1/events?api_key=$DD_API_KEY"
}

#!/usr/bin/env bash
terraform_init() {
  SECTION=$1
  ENV=$2
  cd $SECTION
  terraform init -input=false
  terraform workspace select $ENV || terraform workspace new $ENV
}
