#! /bin/bash
# -*- coding: utf-8 -*-
#
# AWS firewall
#
# This free software is released under GNU Affero GPL3
# author: Antonio M. Vigliotti - antoniomaria.vigliotti@gmail.com
# (C) 2016-2018 by SHS-AV s.r.l. - http://www.shs-av.com - info@shs-av.com

READLINK=$(which greadlink 2>/dev/null) || READLINK=$(which readlink 2>/dev/null)
export READLINK
# Based on template 2.0.0
THIS=$(basename "$0")
TDIR=$(readlink -f $(dirname $0))
[ $BASH_VERSINFO -lt 4 ] && echo "This script $0 requires bash 4.0+!" && exit 4
if [[ -z $HOME_DEVEL || ! -d $HOME_DEVEL ]]; then
  [[ -d $HOME/odoo/devel ]] && HOME_DEVEL="$HOME/odoo/devel" || HOME_DEVEL="$HOME/devel"
fi
[[ -x $TDIR/../bin/python3 ]] && PYTHON=$(readlink -f $TDIR/../bin/python3) || [[ -x $TDIR/python3 ]] && PYTHON="$TDIR/python3" || PYTHON=$(which python3 2>/dev/null) || PYTHON="python"
[[ -z $PYPATH ]] && PYPATH=$(echo -e "import os,sys\no=os.path\na=o.abspath\nj=o.join\nd=o.dirname\nb=o.basename\nf=o.isfile\np=o.isdir\nC=a('"$TDIR"')\nD='"$HOME_DEVEL"'\nif not p(D) and '/devel/' in C:\n D=C\n while b(D)!='devel':  D=d(D)\nN='venv_tools'\nU='setup.py'\nO='tools'\nH=o.expanduser('~')\nT=j(d(D),O)\nR=j(d(D),'pypi') if b(D)==N else j(D,'pypi')\nW=D if b(D)==N else j(D,'venv')\nS='site-packages'\nX='scripts'\ndef pt(P):\n P=a(P)\n if b(P) in (X,'tests','travis','_travis'):\n  P=d(P)\n if b(P)==b(d(P)) and f(j(P,'..',U)):\n  P=d(d(P))\n elif b(d(C))==O and f(j(P,U)):\n  P=d(P)\n return P\ndef ik(P):\n return P.startswith((H,D,K,W)) and p(P) and p(j(P,X)) and f(j(P,'__init__.py')) and f(j(P,'__main__.py'))\ndef ak(L,P):\n if P not in L:\n  L.append(P)\nL=[C]\nK=pt(C)\nfor B in ('z0lib','zerobug','odoo_score','clodoo','travis_emulator'):\n for P in [C]+sys.path+os.environ['PATH'].split(':')+[W,R,T]:\n  P=pt(P)\n  if B==b(P) and ik(P):\n   ak(L,P)\n   break\n  elif ik(j(P,B,B)):\n   ak(L,j(P,B,B))\n   break\n  elif ik(j(P,B)):\n   ak(L,j(P,B))\n   break\n  elif ik(j(P,S,B)):\n   ak(L,j(P,S,B))\n   break\nak(L,os.getcwd())\nprint(' '.join(L))\n"|$PYTHON)
[[ $TRAVIS_DEBUG_MODE -ge 8 ]] && echo "PYPATH=$PYPATH"
for d in $PYPATH /etc; do
  if [[ -e $d/z0librc ]]; then
    . $d/z0librc
    Z0LIBDIR=$(readlink -e $d)
    break
  fi
done
[[ -z "$Z0LIBDIR" ]] && echo "Library file z0librc not found in <$PYPATH>!" && exit 72
[[ $TRAVIS_DEBUG_MODE -ge 8 ]] && echo "Z0LIBDIR=$Z0LIBDIR"

# DIST_CONF=$(findpkg ".z0tools.conf" "$PYPATH")
# TCONF="$HOME/.z0tools.conf"
CFG_init "ALL"
link_cfg_def
link_cfg $DIST_CONF $TCONF
[[ $TRAVIS_DEBUG_MODE -ge 8 ]] && echo "DIST_CONF=$DIST_CONF" && echo "TCONF=$TCONF"
get_pypi_param ALL
RED="\e[1;31m"
GREEN="\e[1;32m"
CLR="\e[0m"

__version__=2.0.12

get_remote_ip() {
#get_remote_ip(1|net)
    local newip x
    newip=$(who am i|awk '{print $5}')
    x=${newip//(/}
    newip=${x//)/}
    if [ "$1" != "1" ]; then
      newip=$newip/32
    fi
    echo $newip
}

get_ip() {
# get_ip(param 1|net)
    local newip x
    if [ "$1" == "mysship" ]; then
      newip=$(get_remote_ip $2)
    elif [ "$1" == "public" ]; then
      newip=$(dig +short myip.opendns.com @resolver1.opendns.com)
      if [ "$2" != "1" ]; then
        newip=$newip/32
      fi
    elif [ "$1" == "localhost" ]; then
      newip=$(hostname -I)
      if [ "$2" != "1" ]; then
        newip=$newip/32
      fi
    elif [[ $1 =~ [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+ ]]; then
      if [ "$2" != "1" ]; then
        newip=$1
      else
        x=$newip
        newip=$(echo $x|grep --color=never -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
      fi
    elif [[ $1 =~ [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ ]]; then
      if [ "$2" != "1" ]; then
        newip=$1/32
      else
        newip=$1
      fi
    else
      newip=$1
    fi
    echo $newip
}

conf_default() {
    TCONF=$TDIR/.$THIS
    CFG_set "AWS_ACCESS_KEY_ID" "ABCDEFGHIJKLMNOPQRST"
    CFG_set "AWS_SECRET_ACCESS_KEY" "abcdefghijklmnopqrstuvwxyz0123456789ABCD"
    CFG_set "GROUP_IDS" "ab-01234567"
    CFG_set "REGION" "eu-west-1"
    CFG_set "INSTANCES_ID" "i-0123456789abcdef0"
}

OPTOPTS=(h        c                   l             n            q           t         V           v)
OPTDEST=(opt_help opt_conf            opt_log       opt_dry_run  opt_verbose test_mode opt_version opt_verbose)
OPTACTI=("+"      "="                 "="           "1>"         0           1         "*>"        "+" )
OPTDEFL=(1        "$TDIR/.$THIS.conf" "~/awsfw.log" 0            -1          0         ""          -1)
OPTMETA=("help"   "filename"          "filename"    "do nothing" "verbose"   ""        "version"   "silent")
OPTHELP=("this help"\
 "aws configuration file (def $TDIR/.$THIS.conf)"\
 "log filename (def ~/awsfw.log)"\
 "do nothing (dry-run)"\
 "silent mode"\
 "test mode (implies dry-run)"\
 "show version"\
 "verbose mode")
OPTARGS=(act param1 param2 param3)

parseoptargs "$@"

if [[ "$opt_version" ]]; then
  echo "$__version__"
  exit 0
fi
HLPCMDLIST="help|allow|enable|mysship|show|start|stop"
if [[ $opt_help -gt 0 ]]; then
  print_help "AWS or local Firewall\n act may be on of $HLPCMDLIST"\
  "(C) 2015-2018 by zeroincombenze®\nhttp://wiki.zeroincombenze.org/en/Linux/dev\nAuthor: antoniomaria.vigliotti@gmail.com"
  exit 0
fi

CFG_init
conf_default
link_cfg $opt_conf
if [ ${opt_verbose:-0} -gt 0 ]; then
  set_tlog_file "$opt_log" "" "echo"
else
  set_tlog_file "$opt_log"
fi
HLPIPFMT="IP|localhost|public|mysship"
export AWS_ACCESS_KEY_ID=$(get_cfg_value 0 AWS_ACCESS_KEY_ID)
export AWS_SECRET_ACCESS_KEY=$(get_cfg_value 0 AWS_SECRET_ACCESS_KEY)
GROUP_IDS=$(get_cfg_value 0 GROUP_IDS)
REGION=$(get_cfg_value 0 REGION)
INSTANCES_ID=$(get_cfg_value 0 INSTANCES-ID)
sts=$STS_SUCCESS
if [ "$act" == "show" ]; then
  if [ $test_mode -gt 0 ]; then
    echo "aws ec2 describe-security-groups --output=json --region=$REGION --group-ids=$GROUP_IDS|grep CidrIp"
  else
    curip=$(aws ec2 describe-security-groups --output=json --region=$REGION --group-ids=$GROUP_IDS|grep "CidrIp"|tail -n1|grep --color=never -Eo "[0-9.]+[0-9.]+[0-9.]+[0-9]/[0-9]+")
    echo "Current IP: $curip"
  fi
elif [ "$act" == "enable" ]; then
  if [ -z "$param1" ]; then
    echo "Missed new IP"
    echo "use $THIS enable $HLPIPFMT"
    sts=1
  else
    if [ $test_mode -gt 0 ]; then
      echo "aws ec2 describe-security-groups --output=json --region=$REGION --group-ids=$GROUP_IDS|grep CidrIp|tail -n1|grep --color=never -Eo [0-9.]+[0-9.]+[0-9.]+[0-9]/[0-9]+"
      newip=$(get_ip $param1)
      echo "aws ec2 revoke-security-group-ingress  --region=$REGION --group-id $GROUP_IDS --ip-permissions '[{\"IpProtocol\": \"-1\", \"IpRanges\": [{\"CidrIp\": \"'$curip'\"}],\"UserIdGroupPairs\": []}]'"
      echo "aws ec2 authorize-security-group-ingress  --region=$REGION --group-id $GROUP_IDS --ip-permissions '[{\"IpProtocol\": \"-1\", \"IpRanges\": [{\"CidrIp\": \"'$newip'\"}],\"UserIdGroupPairs\": []}]'"
    else
      curip=$(aws ec2 describe-security-groups --output=json --region=$REGION --group-ids=$GROUP_IDS|grep "CidrIp"|tail -n1|grep --color=never -Eo "[0-9.]+[0-9.]+[0-9.]+[0-9]/[0-9]+")
      newip=$(get_ip $param1)
      if [ "$curip" == "$newip" ]; then
        echo "Current and new IP are the same!"
        sts=1
      else
        if [ $opt_verbose -gt 0 ]; then
          echo "Revoke IP $curip"
        fi
        if [ $opt_dry_run -eq 0 ]; then
          aws ec2 revoke-security-group-ingress  --region=$REGION --group-id $GROUP_IDS --ip-permissions '[{"IpProtocol": "-1", "IpRanges": [{"CidrIp": "'$curip'"}],"UserIdGroupPairs": []}]'
        fi
        if [ $opt_verbose -gt 0 ]; then
          echo "Authorize IP $newip"
        fi
        if [ $opt_dry_run -eq 0 ]; then
          aws ec2 authorize-security-group-ingress  --region=$REGION --group-id $GROUP_IDS --ip-permissions '[{"IpProtocol": "-1", "IpRanges": [{"CidrIp": "'$newip'"}],"UserIdGroupPairs": []}]'
        fi
      fi
    fi
  fi
elif [ "$act" == "allow" ]; then
  if [ -z "$param1" ]; then
    echo "Missed new IP"
    echo "use $THIS allow $HLPIPFMT"
    sts=1
  else
    if [ "$param1" == "localhost" ]; then
      curip=$(grep -A1 'myself' /etc/hosts.allow|grep --color=never -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
    else
      curip=$(grep -A1 'ADSL from owner' /etc/hosts.allow|grep --color=never -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
    fi
    if [ $test_mode -gt 0 ]; then
      newip=$(get_ip $param1 1)
      echo "\$ sed -i -e s/$curip/$newip/ /etc/hosts.allow"
    else
      if [ -n "$curip" ]; then
        newip=$(get_ip $param1 1)
        if [ "$curip" == "$newip" ]; then
          echo "Current and new IP are the same!"
          sts=1
        else
          if [ $opt_dry_run -eq 0 ]; then
            sed -i -e "s/$curip/$newip/" /etc/hosts.allow
            echo "Please restart ssh service (i.e service ssh[d] restart)"
          else
            echo "\$ sed -i -e s/$curip/$newip/ /etc/hosts.allow"
          fi
        fi
      fi
    fi
  fi
elif [ "$act" == "mysship" ]; then
  newip=$(get_remote_ip 1)
  echo "remote console ip is $newip"
elif [ "$act" == "start" ]; then
  if [ $test_mode -gt 0 ]; then
    echo "aws ec2 start-instances --region=$REGION --instance-ids $INSTANCES_ID"
  else
    if [ $opt_verbose -gt 0 ]; then
      echo "Start instance"
    fi
    aws ec2 start-instances --region=$REGION --instance-ids $INSTANCES_ID
  fi
elif [ "$act" == "stop" ]; then
  if [ $test_mode -gt 0 ]; then
    echo "aws ec2 stop-instances --region=$REGION --instance-ids $INSTANCES_ID"
  else
    if [ $opt_verbose -gt 0 ]; then
      echo "Stop instance"
    fi
    aws ec2 stop-instances --region=$REGION --instance-ids $INSTANCES_ID
  fi
elif [ "$act" == "help" ]; then
  y=${HLPCMDLIST//|/ }
  for x in $y; do
    if [ "$x" == "enable" -o "$x" == "allow" ]; then
      echo "$THIS $x $HLPIPFMT"
    elif [ "$x" != "help" ]; then
      echo "$THIS $x"
    fi
  done
else
  echo "invalid action, use: $THIS $HLPCMDLIST"
  sts=1
fi
exit $sts


