#!/usr/bin/env bash VERSION="0.1" VERBOSE=false SSLOPTION=false AWSREGION="us-west-2" US_W_1="ami-6d1ffd0e" US_W_2="ami-7be8a103" US_E_1="ami-b3be85cc" US_E_2="ami-cc7a40a9" AMI_IMAGE=$US_W_2 AWS_CLI=$(which aws) DOCKER_CLI=$(which docker) DOCKER_IMG="hunterlong/statup" AWS_ECS="$AWS_CLI --output json" DOCKER_PORT=8080 function usage() { cat < /dev/null 2>&1 || { echo "Some of the required software is not installed:" APP="$1" >&2; echo " Required application: $APP" if [ $OS == "osx" ]; then echo " You can run 'brew install $APP'" elif [ $OS == "linux" ]; then echo " You can run 'apt install $APP'" fi exit 4; } } # Get the latest release from github get_latest_release() { STATUP_VERSION=$(curl --silent "https://api.github.com/repos/$DOCKER_IMG/releases/latest" | jq -r .tag_name) } # auto set AWS environment variables function setAWSPresets { if [ -z ${AWS_DEFAULT_REGION+x} ]; then unset AWS_DEFAULT_REGION else AWS_ECS="$AWS_ECS --region $AWS_DEFAULT_REGION" fi if [ -z ${AWS_PROFILE+x} ]; then unset AWS_PROFILE else AWS_ECS="$AWS_ECS --profile $AWS_PROFILE" fi } # ask the user to inser their AWS region function awsAskRegion { if [ -z ${AWS_DEFAULT_REGION+x} ]; then read -p "Enter the AWS Region: " AWSREGION else AWSREGION=$AWS_DEFAULT_REGION fi } # ask for the EC2 instance name function askEC2Name { read -p "Enter the Name for EC2 Instance: " SERVERNAME } # ask user if they want to use SSL function askSSLOption { read -p "Do you want to install a SSL certificate? (y/N):" SSLOPTION } # ask user for domain for SSL function askSSLDomain { read -p "Enter the Domain to attach the SSL certificate on: " SSLDOMAIN } # ask user for email for Letencrypt function askSSLEmail { read -p "Enter the Email for Lets Encrypt: " SSLEMAIL } # ask user for their EC2 Keypair for instance function askEC2KeyName { read -p "Enter the Keypair for EC2 Instance: " EC2KEYNAME } # ask user to create a new AWS security group namne function askSecurityName { read -p "Enter a name for the new Security Group: " EC2SECGROUP } # ask user if they want to install statup to the bin folder function askInstallGlobal { read -p "Do you want to move Statup to the bin folder? (y/N): " MOVEBIN } # ask user if they want statup to start on boot function askInstallSystemCTL { read -p "Do you want to auto start Statup on boot? (y/N): " SYSTEMCTL } # Task to create a new AWS security group function awsSecurityGroup { echo "Running task: Creating Security Group"; GROUPID=`$AWS_ECS ec2 create-security-group --group-name "$EC2SECGROUP" --description "Statup HTTP Server on port 80 and 443" | jq -r .GroupId` echo "Created new security group: $GROUPID"; awsAuthSecurityGroup } # Task to open ports 80 and 443 for the security group function awsAuthSecurityGroup { $AWS_ECS ec2 authorize-security-group-ingress --group-id $GROUPID --protocol tcp --port 80 --cidr 0.0.0.0/0 $AWS_ECS ec2 authorize-security-group-ingress --group-id $GROUPID --protocol tcp --port 443 --cidr 0.0.0.0/0 echo "Authorize security group to be open on ports 80 and 443"; } function awsCreateEC2 { NEW_SRV=`$AWS_ECS ec2 run-instances --image-id $US_W_2 --count 1 --instance-type t2.nano --key-name $EC2KEYNAME --security-group-ids $GROUPID` INSTANCE_ID=$(echo "${NEW_SRV}" | jq -r .Instances[0].InstanceId) EC2_STATUS=$(echo "${NEW_SRV}" | jq -r .Instances[0].StateReason.Message) echo "New EC2 instance created: $INSTANCE_ID with status $EC2_STATUS"; } # task to created a new EC2 instance with statup image function ec2TaskComplete { echo "New EC2 instance is ready! $INSTANCE_ID with status $EC2_STATUS"; echo "Instance ID: $INSTANCE_ID with status $EC2_STATUS"; echo "Public DNS: $EC2_DNS"; if [ $SSLOPTION == "y" ]; then echo "Now you have to add a CNAME DNS record on $SSLDOMAIN pointing to $EC2_DNS" fi } # function to check the EC2 instance function checkEC2Instance { SRV_INFO=`$AWS_ECS ec2 describe-instances --instance-ids $INSTANCE_ID` EC2_STATUS=$(echo "${SRV_INFO}" | jq -r .Reservations[0].Instances[0].State.Name) EC2_DNS=$(echo "${SRV_INFO}" | jq -r .Reservations[0].Instances[0].PublicDnsName) EC2_STATUS=$(echo "${SRV_INFO}" | jq -r .Reservations[0].Instances[0].State.Name) if [ $EC2_STATUS == '"pending"' ]; then echo "EC2 instance is still being created: $INSTANCE_ID"; sleep 2 checkEC2Instance fi } # function to create the Statup EC2 instance function awsTask { setAWSPresets askEC2Name awsAskRegion askSecurityName askEC2KeyName askSSLOption if [ $SSLOPTION == "y" ]; then askSSLDomain askSSLEmail fi awsSecurityGroup awsCreateEC2 checkEC2Instance ec2TaskComplete } # function to move the statup binary to the bin folder function moveToBin { mv statup /usr/local/bin/statup } # function to install a systemctl service to the local system function installSystemCTL { FILE=statup.service cat > $FILE <<- EOM [Unit] Description=Statup Server After=network.target After=systemd-user-sessions.service After=network-online.target [Service] Type=simple Restart=always ExecStart=/usr/local/bin/statup [Install] WantedBy=multi-user.target EOM echo "Installing systemctl service file to: /etc/systemd/system/$FILE" mv $FILE /etc/systemd/system/$FILE systemctl daemon-reload systemctl enable statup.service systemctl start statup echo "Statup has been installed to SystemCTL and will start on boot" } function downloadBin { getOS getArch get_latest_release GIT_DOWNLOAD="https://github.com/$DOCKER_IMG/releases/download/$STATUP_VERSION/statup-$OS-$ARCH.tar.gz" echo "Downloading Statup $STATUP_VERSION from $GIT_DOWNLOAD" curl -L --silent $GIT_DOWNLOAD | tar xz echo "Download complete" } # install statup locally from github function localTask { downloadBin echo "Try Statup by running 'statup version'!" askInstallGlobal if [ $MOVEBIN == "y" ]; then moveToBin echo "Statup can now be ran anywhere with command 'statup'" echo "Install location: /usr/local/bin/statup" if [ $OS == "linux" ]; then askInstallSystemCTL if [ $SYSTEMCTL == "y" ]; then installSystemCTL fi fi fi } function uninstallTask { rm -f /usr/local/bin/statup } # start the Statup docker image function dockerTask { echo "Starting Statup Docker container on port $DOCKER_PORT" $DOCKER_CLI run -d -p $DOCKER_PORT:8080 $DOCKER_IMG } # get 64x or 32 machine arch function getArch { MACHINE_TYPE=`uname -m` if [ ${MACHINE_TYPE} == 'x86_64' ]; then ARCH="x64" else ARCH="x32" fi } # get the users operating system function getOS { OS="`uname`" case $OS in 'Linux') OS='linux' alias ls='ls --color=auto' ;; 'FreeBSD') OS='freebsd' alias ls='ls -G' ;; 'WindowsNT') OS='windows' ;; 'Darwin') OS='osx' ;; 'SunOS') OS='solaris' ;; 'AIX') ;; *) ;; esac } function echoVersion { require jq get_latest_release echo "Statup Latest: $STATUP_VERSION" echo "Statuper Tool: v$VERSION" } # main CLI entrypoint if [ "$BASH_SOURCE" == "$0" ]; then set -o errexit set -o pipefail set -u set -e # If no args are provided, display usage information if [ $# == 0 ]; then usage; fi COMMD=$1 # Loop through arguments, two at a time for key and value while [[ $# -gt 0 ]] do key="$1" case $key in -k|--aws-access-key) AWS_ACCESS_KEY_ID="$2" shift # past argument ;; -s|--aws-secret-key) AWS_SECRET_ACCESS_KEY="$2" shift # past argument ;; -r|--region) AWS_DEFAULT_REGION="$2" shift # past argument ;; -p|--port) DOCKER_PORT="$2" shift # past argument ;; -x|--verbose) VERBOSE=true ;; *) ;; esac shift # past argument or value done if [ $VERBOSE == true ]; then set -x fi case $COMMD in aws) require aws require jq awsTask exit 0 ;; docker) require docker dockerTask exit 0 ;; docker-compose) require docker-compose dockerComposeTask exit 0 ;; install) require jq require curl require tar localTask shift # past argument ;; uninstall) uninstallTask shift # past argument ;; version|v) echoVersion exit 0 ;; *) ;; esac shift # past argument or value fi exit 0 fi