#!/bin/bash

#iscsi relevant operations

clienta="iqn.1994-05.com.redhat:clienta"
clientb="iqn.1994-05.com.redhat:clientb"
# clientc="iqn.1994-05.com.redhat:clientc"
clientc=""
if [[ -e /etc/iscsi/initiatorname.iscsi ]]; then
  clientself=$(cat /etc/iscsi/initiatorname.iscsi | cut -f 2 -d "=")
  if echo "$clienta $clientb $clientc" | grep $clientself; then
    clientself=
  fi
fi

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
DISABLE_COLOR='\033[0m' # Disable Color

wiscsi_cmd() {
  # echo "CMD: $@"
  # eval "$@"

  printf "${GREEN}$*${DISABLE_COLOR}\n"
  eval "$@"
  ret=$?
  # [ $ret -eq 0 ] || echo -e "$RED ERROR $@$DISABLE_COLOR"
  return $ret
}

wiscsi_deploy() {
  #deploy targetcli
  mkdir -p /etc/target/pr
  mkdir -p /home/iscsi/
  yum install targetcli -y
  if uname -r | grep el7; then
    yum install -y iscsi-initiator-utils scsi-target-utils
  fi
  systemctl enable target
  systemctl start target
  if uname -r | grep el8; then
    systemctl enable targetcli
    systemctl start targetcli
  fi
  if [[ -e /etc/iscsi/initiatorname.iscsi ]]; then
    clientself=$(cat /etc/iscsi/initiatorname.iscsi | cut -f 2 -d "=")
    if echo "$clienta $clientb $clientc" | grep $clientself; then
      clientself=
    fi
  else
    h=${1:-$(hostname -s)}
    echo "Create InitiatorName"
    echo "InitiatorName=iqn.1994-05.com.redhat:$h" >/etc/iscsi/initiatorname.iscsi
    clientself="iqn.1994-05.com.redhat:$h"
  fi

  #  dd if=/dev/zero of=/home/iscsi/share4g.img bs=1M count=4096
  #  dd if=/dev/zero of=/home/iscsi/share10g.img bs=1M count=10240
  targetcli clearconfig confirm=True
}

wiscsi_clear() {
  targetcli clearconfig confirm=True
  targetcli saveconfig
  systemctl restart target
  #iscsi iscsid
}
wiscsi_delete_target() {
  local usage="wiscsi_delete [-t <targets>] [-f force delete backstores] "
  local OPT OPTARG OPTIND
  local tg bs delete_bs targets
  delete_bs=1
  while getopts 't:hf' OPT; do
    case $OPT in
    t) targets="$OPTARG" ;;
    f) delete_bs=1 ;;
    h)
      echo -e ${usage}
      return 0
      ;;
    ?)
      echo "unknow $OPT"
      echo -e ${usage}
      return 0
      ;;
    esac
  done
  echo "targets: $targets"
  for tg in $targets; do
    echo "Ready to delete $tg"
    bs=$(targetcli ls /iscsi/$tg | grep default_tg_pt_gp | cut -f2 -d '[' | awk '{print $1}')
    targetcli /iscsi delete $tg
    bs_type=$(echo $bs | cut -f 1 -d /)
    bs_name=$(echo $bs | cut -f 2 -d /)
    [ "x$delete_bs" == "x1" ] && {
      echo "delete bs $bs"
      targetcli /backstores/$bs_type delete $bs_name
    }
  done
  targetcli ls /
}

wiscsi_logout() {
  local OPT OPTARG OPTIND
  local file=/tmp/iscsi
  local usage="wiscsi_logout [-t targets] [-p portals]"
  local file target portal t_targets t_portals

  while getopts 'p:t:h' OPT; do
    case $OPT in
    t) t_targets="$OPTARG" ;;
    p) t_portals="$OPTARG" ;;
    h)
      echo -e ${usage}
      return 0
      ;;
    ?)
      echo -e ${usage}
      return 0
      ;;
    esac
  done
  if ! iscsiadm -m session >$file; then
    echo "No session found"
    return 1
  fi
  # if [[ "$targets" == "" ]]; then
  #   targets=$(cat $file)
  # fi
  echo -e "Current session: \n$(cat $file)"
  echo ""
  cat $file | while read LINE; do
    echo -e "=====\nFound session: $LINE\n"
    portal=$(echo $LINE | awk '{print $3}' | cut -f 1 -d "," | cut -f 1 -d ":")
    target=$(echo $LINE | awk '{print $4}')
    echo "Check $portal : $target"

    if [ -n "${t_portals}" ]; then
      if ! echo -n "${t_portals}" | grep "${portal}"; then
        echo "Skip portal: ${portal}"
        continue
      fi
    fi
    if [ -n "${t_targets}" ]; then
      if ! echo -n "${t_targets}" | grep "${target}"; then
        echo "Skip target: ${target}"
        continue
      fi
    fi

    echo "Ready to logout $portal : $target"
    wiscsi_cmd iscsiadm -m node -T $target -p $portal -u
    wiscsi_cmd iscsiadm -m node -T $target -p $portal -o delete

  done
  wiscsi_cmd iscsiadm -m session
}

wiscsi_login() {
  local OPT OPTARG OPTIND
  local usage="wiscsi_login [-t <targets>] [-p <portal>] "
  local file target portal targets
  local file=/tmp/targets
  local portal=127.0.0.1
  while getopts 't:p:h' OPT; do
    case $OPT in
    t) targets="$OPTARG" ;;
    p) portal="$OPTARG" ;;
    h)
      echo -e ${usage}
      return 0
      ;;
    ?)
      echo -e ${usage}
      return 0
      ;;
    esac
  done

  if [[ "$targets" == "" ]]; then
    total=$(iscsiadm -m discovery -t st -p $portal | awk '{print $2}')
    targets=$(echo -e "$total" | sort)
  fi
  for target in $targets; do
    echo "iscsiadm -m node -T $target -p $portal -l"
    iscsiadm -m node -T $target -p $portal -l
    sleep 2
  done

}

wiscsi_create() {
  local usage="usage: -l lun_name -n [dev/file] name -t targets -b backend [block/fileio] \n
  -c clients -s size [ -a attrs] [-p portals] -r [Will reset exist lun and target] \n
example: -l disk0 -n /home/iscsi/share4g.img -t iqn.2016-06.one.server:4g \n
-b fileio -c iqn.1994-05.com.redhat:clienta -a block_size=4096"

  local OPT OPTARG OPTIND
  #  local backend="fileio"
  local attrs reset clients
  echo "Params:$#: $@"
  if ! echo "$IFS" | od -b | grep 040 >/dev/null; then
    echo "IFS wrong"
    return 0
  fi
  while getopts 't:a:l:b:c:s:p:n:hr' OPT; do
    case $OPT in
    t) targets="$OPTARG" ;;
    n) name="$OPTARG" ;;
    l) lun="$OPTARG" ;;
    c) clients="$OPTARG" ;;
    b) backend="$OPTARG" ;;
    s) size="$OPTARG" ;;
    a) attrs="$OPTARG" ;;
    p) portals="$OPTARG" ;;
    r)
      reset=1
      ;;
    h)
      echo -e ${usage}
      return 0
      ;;
    ?)
      echo -e ${usage}
      return 0
      ;;
    esac
  done

  [ -e /home/iscsi ] || mkdir -p /home/iscsi
  [[ "${backend}" == "" ]] && { echo -e "No backend:\n${usage}" && return 0; }
  # [[ "${clients}" == "" ]] && { echo -e "No clients:\n${usage}" && return 0; }
  [[ "${targets}" == "" ]] && { echo -e "No targets:\n${usage}" && return 0; }
  #  [[ "${lun}" == "" ]] && { echo -e "No lun:\n${usage}" && return 0; }
  [[ "${lun}" == "" ]] && lun=disk0
  [[ "${clients}" == "all" ]] && clients="$clienta $clientb $clientc $clientself"
  if [[ "${name}" == "" ]]; then
    [[ "${backend}" == "fileio" ]] && name="/home/iscsi/$lun" || { echo -e "No name:\n${usage}" && return 0; }
  fi
  [[ "${backend}" == "fileio" ]] && rm ${name} -rf
  echo -e "T: ${targets} \nL: ${lun} \nN: ${name} \nB: ${backend} \nC: ${clients} \nS: ${size} \nA: ${attrs} \n"

  if targetcli / ls /backstores/${backend}/${lun}; then
    if [[ "$reset" == "1" ]]; then
      echo "** Delete exist lun ${lun}, All associated target will deleted also."
      wiscsi_cmd "targetcli /backstores/${backend} delete ${lun}"
    else
      echo "** Skip create lun ${lun}"
    fi
  fi
  if ! targetcli / ls /backstores/${backend}/${lun}; then
    echo "Ready to targetcli /backstores/${backend} create ${lun} ${name} ${size}"
    wiscsi_cmd "targetcli /backstores/${backend} create ${lun} ${name} ${size}"
    #Fixme set attribute for backstores
    for attr in ${attrs}; do
      echo "set attribute ${attr}"
      wiscsi_cmd "targetcli /backstores/${backend}/${lun} set attribute ${attr}"
    done
  fi
  for target in ${targets}; do

    if [[ "$reset" == "1" ]]; then
      echo "  ** Delete target ${target}"
      wiscsi_cmd targetcli /iscsi delete ${target}
    fi
    echo "Ready create target ${target}"
    wiscsi_cmd targetcli /iscsi create ${target}
    wiscsi_cmd targetcli /iscsi/${target}/tpg1/luns create /backstores/${backend}/${lun}
    # set tpg attribute
    if [ "${clients}" == "" ]; then
      # no clients means anyone may access
      wiscsi_cmd targetcli /iscsi/${target}/tpg1 set attribute authentication=0 demo_mode_write_protect=0 generate_node_acls=1 cache_dynamic_acls=1
    fi
    for c in ${clients}; do
      #      echo "Ready create acls for client ${c}"
      wiscsi_cmd "targetcli /iscsi/${target}/tpg1/acls create ${c}"
    done
    if [ -n "${portals}" ]; then
      wiscsi_cmd "targetcli /iscsi/${target}/tpg1/portals delete 0.0.0.0 3260"
      for p in ${portals}; do
        wiscsi_cmd "targetcli /iscsi/${target}/tpg1/portals create ${p} 3260"
      done
    fi
  done
  targetcli / ls
  targetcli saveconfig
  targetcli exit

}

wiscsi_create_block_scsi() {
  #targetcli script and targetcli can not run meanwhile
  #create one block device backend
  #  local targeta="iqn.2016-06.share.server:scsi-debug"
  #  modprobe -r scsi_debug
  #  modprobe scsi_debug dev_size_mb=3000
  #  dev=$(lsscsi | grep scsi | awk '{ print $6 }')
  #  pvcreate ${dev}
  #  vgcreate vg ${dev}
  #  #  lvcreate iscsi_disk01 -l 100%FREE -n iscsi_lv01
  #  lvcreate -L 2G -n lv vg
  #  dev=/dev/vg/lv
  #  local file=/tmp/loopbackfile.img
  #  dd if=/dev/zero of=$file bs=100M count=20
  #  local loopdev=$(losetup -f)
  #  losetup $loopdev $file
  #  wiscsi_create -t "iqn.2016-06.block.server:4g" -b block -c "$clienta $clientb" -l block1 -n $loopdev
  #
  #  #losetup -d $loopdev
  backend="block"
  targets="iqn.2016-06.one.server:block-a"
  clients="$clienta $clientb $clientc $clientself"
  #you need specify -n
  wiscsi_create "$@"

}
wiscsi_create_one() {
  local targets name lun clients backend size attrs
  size=3g
  targets="iqn.2016-06.one.server:one-a"
  backend="fileio"
  clients="$clienta $clientb $clientc $clientself"
  lun="one"
  #  name=/home/iscsi/onex.img
  wiscsi_create "$@"

}

wiscsi_create_share() {
  local targets name lun clients backend size attrs
  size=10g
  targets="iqn.2016-06.share.server:share-a iqn.2016-06.share.server:share-b"
  backend="fileio"
  clients="$clienta $clientb $clientc $clientself"
  lun="share"
  #  name=/home/iscsi/share.img
  wiscsi_create "$@"

}

#wiscsi_create_share_old() {
#  #targetcli script and targetcli can not run meanwhile
#  #create two shared target and can be accessed by two client
#  local targeta=iqn.2016-06.share.server:4g-a
#  local targetb=iqn.2016-06.share.server:4g-b
#  targetcli /backstores/fileio create disk0 /home/iscsi/share4g.img
#  targetcli /iscsi create ${targeta}
#  targetcli /iscsi create ${targetb}
#  targetcli /iscsi/${targeta}/tpg1/luns create /backstores/fileio/disk0
#  targetcli /iscsi/${targetb}/tpg1/luns create /backstores/fileio/disk0
#  targetcli /iscsi/${targeta}/tpg1/acls create ${clienta}
#  targetcli /iscsi/${targeta}/tpg1/acls create ${clientb}
#  targetcli /iscsi/${targetb}/tpg1/acls create ${clienta}
#  targetcli /iscsi/${targetb}/tpg1/acls create ${clientb}
#  targetcli / ls
#  targetcli saveconfig
#  targetcli exit
#
#  systemctl restart target iscsi iscsid
#
#}

wiscsi_discover() {

  local usage="usage: -t <targets> -p hostname -f filter"
  local targets name cmd filter OPT OPTARG OPTIND

  port=3260
  #  name=10.66.8.105
  name=127.0.0.1

  while getopts 'f:t:p:h' OPT; do
    case $OPT in
    t) targets="$OPTARG" ;;
    p) name="$OPTARG" ;;
    f) filter="$OPTARG" ;;
    h) echo -e ${usage} ;;
    ?) echo -e ${usage} ;;
    esac
  done

  if [[ "$targets" == "" ]]; then
    if [[ "$name" == "127.0.0.1" || "$name" == "localhost" ]]; then
      targets=$(targetcli /iscsi ls depth=1 | grep iqn | awk '{print $2}')
    else
      # get remote targets
      cmd="iscsiadm -m discovery -t st -p $name"
      echo "$cmd"
      targets=$(eval $cmd | awk '{print $2}')
      [ $? == 0 ] || {
        echo "Discovry command failed"
        return 1
      }
    fi
  fi

  if [[ "$filter" != "" ]]; then
    targets=$(echo -e "$targets" | grep "$filter"ef)
  fi

  local opa=("-l" "-u" "-o delete")
  echo "Demo login/logout/delete command:"
  for o in "${opa[@]}"; do
    for target in ${targets}; do
      echo "iscsiadm -m node -T ${target}  -p $name:$port $o"
      #    echo "iscsiadm -m node -T ${target}  -p $name:$port -l"
      #    echo "iscsiadm -m node -T ${target}  -p $name:$port -u"
      #    echo "iscsiadm -m node -T ${target}  -p $name:$port -o delete"
    done
  done

}

wiscsi_restart() {
  echo "$#"
  if [[ $# -gt 0 ]]; then
    #all
    echo "restart all"
    systemctl restart target iscsi iscsid
  else
    echo "restart target"
    systemctl restart target
  fi

}

wiscsi_session() {
  echo "target server:"
  targetcli sessions detail
  echo "target client:"
  iscsiadm -m session
  #  iscsiadm -m node

}
#libiscsi windows guest inititorname
#uuid=ea78071a-f6e4-4347-8077-9cb9f7959e66
#uuid=ea78071a-f6e4-4347-8077-9cb9f7959e88
#iqn.2008-11.org.linux-kvm:${uuid}
#wiscsi $@
