#!/bin/bash
echo "ECS_CLUSTER=<%= ecs_cluster_name %>" >> /etc/ecs/ecs.config

declare -A regions
regions["ap-northeast-1"]="nrt"
regions["ap-northeast-2"]="icn"
regions["ap-south-1"]="bom"
regions["ap-southeast-1"]="sin"
regions["ap-southeast-2"]="syd"
regions["ca-central-1"]="yul"
regions["eu-central-1"]="fra"
regions["eu-west-1"]="dub"
regions["eu-west-2"]="lhr"
regions["eu-west-3"]="cdg"
regions["sa-east-1"]="gru"
regions["us-east-1"]="iad"
regions["us-east-2"]="cle"
regions["us-west-1"]="sjc"
regions["us-west-2"]="pdx"

# Make sure this is idempotent, it will run occasionally through cfn-hup

ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id | cut -c 3-)
REGION_AZ=$(curl -s 169.254.169.254/latest/meta-data/placement/availability-zone)
REGION="${REGION_AZ::-1}"
AZ="${REGION_AZ: -1}"
new_ip_address=$(ip route get 1 | awk '{print $NF;exit}')
new_host_name=<%= host_prefix %>-${regions[$REGION]}-$AZ-$ID
new_domain_name=<%= domain %>

if ! $(grep -q "$new_ip_address $new_host_name.$new_domain_name $new_host_name" /etc/hosts); then
  # Remove the 127.0.1.1 put there by the debian installer
  TMPHOSTS=/etc/hosts.dhcp.new
  grep -v  -e '^127\.0\.1\.1' -e $new_host_name -e $new_ip_address < /etc/hosts > $TMPHOSTS
  # Add the new ip address and name
  echo "$new_ip_address $new_host_name.$new_domain_name $new_host_name" >> $TMPHOSTS
  mv $TMPHOSTS /etc/hosts

  # Rename Host
  sed -i -e "/HOSTNAME=/s/localhost.localdomain/$new_host_name.$new_domain_name/" /etc/sysconfig/network
  hostname $new_host_name.$new_domain_name
fi

cd /tmp

# Chef Stuff
NODE_NAME="$new_host_name.$new_domain_name"
REGION="us-west-2"
CHEF_SERVER_NAME="CPE-Chef"
CHEF_SERVER_ENDPOINT="cpe-chef-heqtcjndac2ptfp4.us-west-2.opsworks-cm.io"
RUN_LIST=<%= chef_runlist %>
ENVIRONMENT=<%= chef_environment %>
CHEF_ORGANIZATION="default"
CHEF_CLIENT_VERSION="13.7.16"
export OPSWORKS_ROLE_ARN="arn:aws:iam::994136867826:role/OpsworksRegisterClientIAMRole-USWest2-7adf25b740fb4c9e37248fa01"

set -e -o pipefail

CHEF_CA_PATH="/etc/chef/opsworks-cm-ca-root.pem"

install_aws_cli() {
  yum install python2-pip -y
  pip install awscli --upgrade --user
}

aws_cli() {
  # Get temporary credentials for opsworks client role
  SESSION_NAME=$(echo "opsworks-chef-$(hostname)" | cut -c 1-64)
  IFS=" " read AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN <<< $(~/.local/bin/aws sts assume-role --role-arn="$OPSWORKS_ROLE_ARN" --role-session-name=$SESSION_NAME --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' --output=text)
  export AWS_ACCESS_KEY_ID ; export AWS_SECRET_ACCESS_KEY ; export AWS_SESSION_TOKEN
  ~/.local/bin/aws opsworks-cm --region "${REGION}" --output text "$@" --server-name "${CHEF_SERVER_NAME}"
}

associate_node() {
  touch /tmp/client.rnd && chmod 777 /tmp/client.rnd
  client_key="/etc/chef/client.pem"
  ( umask 077; RANDFILE="/tmp/client.rnd" openssl genrsa -out "${client_key}" 2048 )

  aws_cli associate-node \
    --node-name "${NODE_NAME}" \
    --engine-attributes \
    "Name=CHEF_ORGANIZATION,Value=${CHEF_ORGANIZATION}" \
    "Name=CHEF_NODE_PUBLIC_KEY,Value='$(RANDFILE="/tmp/client.rnd" openssl rsa -in "${client_key}" -pubout)'"
}

write_chef_config() {
  (
    echo "chef_server_url   'https://${CHEF_SERVER_ENDPOINT}/organizations/${CHEF_ORGANIZATION}'"
    echo "node_name         '${NODE_NAME}'"
    echo "ssl_ca_file       '${CHEF_CA_PATH}'"
  ) >> /etc/chef/client.rb
}

install_chef_client() {
  # see: https://docs.chef.io/install_omnibus.html
  curl --silent --show-error --retry 3 --location https://omnitruck.chef.io/install.sh | bash -s -- -v "${CHEF_CLIENT_VERSION}"
}

install_trusted_certs() {
  curl --silent --show-error --retry 3 --location --output "${CHEF_CA_PATH}" \
    "https://opsworks-cm-${REGION}-prod-default-assets.s3.amazonaws.com/misc/opsworks-cm-ca-2016-root.pem"
}

wait_node_associated() {
  aws_cli wait node-associated --node-association-status-token "$1"
}

test -d /etc/chef || mkdir /etc/chef
test -f /usr/local/bin/aws || install_aws_cli
test -f /usr/bin/chef-client || install_chef_client
test -f /etc/chef/client.rb || write_chef_config
test -f /etc/chef/opsworks-cm-ca-root.pem || install_trusted_certs

if [ ! -f /etc/chef/client.pem ]; then
  node_association_status_token="$(associate_node)"
  wait_node_associated "${node_association_status_token}"
fi

unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN

if [ ! -z "$ENVIRONMENT" ]; then
cat > /usr/local/bin/chef-run <<CHEFRUN
#!/usr/bin/env bash
chef-client -j /etc/chef/attributes.json -r "${RUN_LIST}" -E "${ENVIRONMENT}"
CHEFRUN
else
cat > /usr/local/bin/chef-run <<CHEFRUN
#!/usr/bin/env bash
chef-client -j /etc/chef/attributes.json -r "${RUN_LIST}"
CHEFRUN
fi
chmod 700 /usr/local/bin/chef-run

cat > /etc/chef/attributes.json <<CHEFJSON
<%= "\n#{JSON.pretty_generate(chef_attributes)}\n" %>
CHEFJSON

/usr/local/bin/chef-run
/usr/local/bin/chef-run
