Skip to content
provision 7.19 KiB
Newer Older
#!/usr/bin/env bash
Pierre Ozoux's avatar
Pierre Ozoux committed
# Provision an application for a user for LibrePaaS
#
# This file:
#  - Registers the domain name to NameCheap
#  - Configures the DNS
#
Pierre Ozoux's avatar
Pierre Ozoux committed
# Version 0.0.3
#
# Authors:
#  - Pierre Ozoux (pierre-o.fr)
#
# Usage:
Pierre Ozoux's avatar
Pierre Ozoux committed
#  LOG_LEVEL=7 ./provision -a github.com/indiehosters/known -u example.org -g -b -c
#
# Licensed under AGPLv3


### Configuration
#####################################################################

# Environment variables and their defaults
LOG_LEVEL="${LOG_LEVEL:-6}" # 7 = debug -> 0 = emergency

# Commandline options. This defines the usage page, and is used to parse cli
# opts & defaults from. The parsing is unforgiving so be precise in your syntax
read -r -d '' usage <<-'EOF'
  -u   [arg] URL to process. Required.
Michel Memeteau's avatar
Michel Memeteau committed
  -a   [arg] Application to install. (in the form github.com/indiehosters/wordpress or wordpress in REPO_MODE)
  -t   [arg] Checkout a specific tag or branch from the application repo. default to master
Pierre Ozoux's avatar
Pierre Ozoux committed
  -s         Start the application right away.
  -b         Buys the associated domain name.
Pierre Ozoux's avatar
Pierre Ozoux committed
  -i         Configure OpenDKIM.
Michel Memeteau's avatar
Michel Memeteau committed
  -c         Configures DNS if possible.
  -d         Enables debug mode
  -h         This page
EOF

### Functions
#####################################################################

Pierre Ozoux's avatar
Pierre Ozoux committed
source /etc/environment
Pierre Ozoux's avatar
Pierre Ozoux committed
source /opt/bin/helpers
source /opt/bin/configure_dkim_dns
function buy_domain_name () {
  not_supported_extensions=( "us" "eu" "nu" "asia" "ca" "co.uk" "me.uk" "org.uk" "com.au" "net.au" "org.au" "es" "nom.es" "com.es" "org.es" "de" "fr" )
  if [ $(contains "${not_supported_extensions[@]}" "$(TLD)") == "y" ]; then
    error "Extension .$(TLD) is not yet supported.."
    exit 1
  fi 

  info "Buying Domain name."
  arguments="&Command=namecheap.domains.create\
&DomainName=${arg_u}\
&Years=1\
&AuxBillingFirstName=${FirstName}\
&AuxBillingLastName=${LastName}\
&AuxBillingAddress1=${Address}\
&AuxBillingCity=${City}\
&AuxBillingPostalCode=${PostalCode}\
&AuxBillingCountry=${Country}\
&AuxBillingPhone=${Phone}\
&AuxBillingEmailAddress=${EmailAddress}\
&AuxBillingStateProvince=${City}\
&TechFirstName=${FirstName}\
&TechLastName=${LastName}\
&TechAddress1=${Address}\
&TechCity=${City}\
&TechPostalCode=${PostalCode}\
&TechCountry=${Country}\
&TechPhone=${Phone}\
&TechEmailAddress=${EmailAddress}\
&TechStateProvince=${City}\
&AdminFirstName=${FirstName}\
&AdminLastName=${LastName}\
&AdminAddress1=${Address}\
&AdminCity=${City}\
&AdminPostalCode=${PostalCode}\
&AdminCountry=${Country}\
&AdminPhone=${Phone}\
&AdminEmailAddress=${EmailAddress}\
&AdminStateProvince=${City}\
&RegistrantFirstName=${FirstName}\
&RegistrantLastName=${LastName}\
&RegistrantAddress1=${Address}\
&RegistrantCity=${City}\
&RegistrantPostalCode=${PostalCode}\
&RegistrantCountry=${Country}\
&RegistrantPhone=${Phone}\
&RegistrantEmailAddress=${EmailAddress}\
&RegistrantStateProvince=${City}"

  call_API ${arguments}

  info "Changing email forwarding."
  arguments="&Command=namecheap.domains.dns.setEmailForwarding\
&DomainName=${arg_u}\
&mailbox1=hostmaster\
&ForwardTo1=${EmailAddress}"

  call_API ${arguments}
}

Pierre Ozoux's avatar
Pierre Ozoux committed
function application () {
  #We check if a APP_REPO_URL was specified

  if [ -z ${APP_REPO_URL:-} ]; then
    warning "NO repo URL specified, using argument as full URL"
    git_url=https://${arg_a}.git
  else
    warning "REPO specified, using argument as app name"
    git_url=https://${APP_REPO_URL}/${arg_a}.git
  fi
Michel Memeteau's avatar
Michel Memeteau committed
  
  #Define the tag/branch 
  
  if [ "${arg_t}" = "1" ]; then
Michel Memeteau's avatar
Michel Memeteau committed
    warning "No tag/branch specified, Using master "
    git_tag=master
  else
    git_tag=${arg_t}
  fi
  git clone ${git_url} -b ${arg_t} /data/domains/${arg_u} 
Pierre Ozoux's avatar
Pierre Ozoux committed
  cd /data/domains/${arg_u}
Michel Memeteau's avatar
Michel Memeteau committed
  
Pierre Ozoux's avatar
Pierre Ozoux committed
  if [ -f ./scripts/install ]; then
    export URL=${arg_u}
    if [ -z ${MAIL_DOMAIN:-} ]; then
      warning "you have no email server setup, we'll print a random configuration in your application. Make sure to check the parameters for your app to send proper emails."
Pierre Ozoux's avatar
Pierre Ozoux committed
      warning "To stop having this warning, please configure your libre.sh to be abble to create email accounts."
      warning "You can also contact support@indie.host to setup an email account for you"
Pierre Ozoux's avatar
Pierre Ozoux committed
      export MAIL_PASS="randompass"
      export MAIL_USER="example@indie.host"
      export MAIL_DOMAIN="indie.host"
      export MAIL_HOST="mail.indie.host"
      export MAIL_PORT="587"
    else
      echo "using MAIL_DOMAIN from server env"
      #export MAIL_PASS=`tr -dc A-Za-z0-9_ < /dev/urandom | head -c 20 | xargs`
      #export MAIL_USER="noreply.${arg_u}@${MAIL_DOMAIN}"
      #/opt/bin/add_mailbox ${MAIL_USER} ${MAIL_PASS}
Pierre Ozoux's avatar
Pierre Ozoux committed
    ./scripts/install
  fi
Pierre Ozoux's avatar
Pierre Ozoux committed
}

function start () {
  systemctl start u@${arg_u}
  systemctl enable u@${arg_u}
}

### Parse commandline options
#####################################################################

# Translate usage string -> getopts arguments, and set $arg_<flag> defaults
while read line; do
  opt="$(echo "${line}" |awk '{print $1}' |sed -e 's#^-##')"
  if ! echo "${line}" |egrep '\[.*\]' >/dev/null 2>&1; then
    init="0" # it's a flag. init with 0
  else
    opt="${opt}:" # add : if opt has arg
    init=""  # it has an arg. init with ""
  fi
  opts="${opts}${opt}"

  varname="arg_${opt:0:1}"
  if ! echo "${line}" |egrep '\. Default=' >/dev/null 2>&1; then
    eval "${varname}=\"${init}\""
  else
    match="$(echo "${line}" |sed 's#^.*Default=\(\)#\1#g')"
    eval "${varname}=\"${match}\""
  fi
done <<< "${usage}"

# Reset in case getopts has been used previously in the shell.
OPTIND=1

# Overwrite $arg_<flag> defaults with the actual CLI options
while getopts "${opts}" opt; do
  line="$(echo "${usage}" |grep "\-${opt}")"


  [ "${opt}" = "?" ] && help "Invalid use of script: ${@} "
  varname="arg_${opt:0:1}"
  default="${!varname}"

  value="${OPTARG}"
  if [ -z "${OPTARG}" ] && [ "${default}" = "0" ]; then
    value="1"
  fi

  eval "${varname}=\"${value}\""
  debug "cli arg ${varname} = ($default) -> ${!varname}"
done

shift $((OPTIND-1))

[ "$1" = "--" ] && shift


### Switches (like -d for debugmdoe, -h for showing helppage)
#####################################################################

# debug mode
if [ "${arg_d}" = "1" ]; then
  set -o xtrace
  LOG_LEVEL="7"
fi

# help mode
if [ "${arg_h}" = "1" ]; then
  # Help exists with code 1
  help "Help using ${0}"
fi


### Validation (decide what's required for running your script and error out)
#####################################################################

[ -z "${arg_u}" ]     && help      "URL is required."
[ -z "${LOG_LEVEL}" ] && emergency "Cannot continue without LOG_LEVEL."
# tags/branch for modules 
[ -z "${arg_t}" ]     && arg_t=master


### Runtime
#####################################################################

# Exit on error. Append ||true if you expect an error.
# set -e is safer than #!/bin/bash -e because that is neutralised if
Pierre Ozoux's avatar
Pierre Ozoux committed
# someone runs your script like `bash yourscript`
set -o errexit
set -o nounset

# Bash will remember & return the highest exitcode in a chain of pipes.
# This way you can catch the error in case mysqldump fails in `mysqldump |gzip`
set -o pipefail

FOLDER=/data/domains/${arg_u}
TLS_FOLDER=${FOLDER}/TLS

[ ${arg_b} -eq 1 ] && buy_domain_name
Pierre Ozoux's avatar
Pierre Ozoux committed
[ ! -z "${arg_a}" ] && application
Pierre Ozoux's avatar
Pierre Ozoux committed
[ ${arg_i} -eq 1 ] && provision_dkim
[ ${arg_c} -eq 1 ] && configure_dns
Pierre Ozoux's avatar
Pierre Ozoux committed
[ ${arg_s} -eq 1 ] && start