#!/bin/bash

function help() {
    echo -e "Эта команда используется для редактирования дискреционного контроля доступа к ВМ"
    echo -e "Можно добавлять или удалять доступ к ВМ для пользователя или группы"
    echo -e "Примеры:\none-securityvm <VM_ID> --add --control --group <GROUP_NAME>\none-securityvm <VM_ID> --remove --control --user <USER_NAME>"
    echo -e "one-securityvm <VM_ID> --remove --use --group <GROUP_NAME>\none-securityvm <VM_ID> --add --use --user <USER_NAME>"
}

case $1 in
    '-h'|'--help') help;
        exit 1;
    ;;
esac

vm_id=$1
add_remove=$2
u_c=$3
u_g=$4
n_u_g=$5
SCRIPT=/tmp/one_editor_script
CONFIG=/tmp/one_updateconf_vm${vm_id}

function errorFunc() {
    echo -e "Wrong keys. Examples:\none-securityvm <VM_ID> --add --control --group <GROUP_NAME>\none-securityvm <VM_ID> --add --control --user <USER_NAME>"
}

function addFunc() {
    local new_param="<aclentry>${u_g}:${n_u_g}:${u_c}</aclentry>"
    if echo "${vmconf}" | grep -q "${new_param}"; then
        exit 20
    fi
    if echo "${vmconf}" | grep -q '^RAW=\[';then
        local raw_info=`echo "${vmconf}" | sed '/^RAW=/,/]/!d'`
        if echo "${raw_info}" | grep -q 'DATA=';then
            local date_info=$(echo "${raw_info}" | grep 'DATA="')
            if ! echo "${date_info}" | grep -qE '<acl>|<\/acl>'; then
                date_info=$(echo "$date_info" | awk '/DATA=/ {gsub(/(\",$)/,"<acl>'${new_param}'</acl>\","); print}')
                raw_info=$(echo "$raw_info" | sed "/DATA=/c \\${date_info}")
            else
                local raw_date_param=($(echo ''$raw_info'' | grep DATA= | awk '{gsub(/(.*<acl>)|(<\/acl>.*)/," ");print}'))
                new_param="${raw_date_param[*]}${new_param}"
                raw_info=$(echo "$raw_info" | awk '{gsub(/(<aclentry>.*<\/aclentry>)/,"'${new_param}'");print}')
            fi
        else
            raw_info=$(echo "$raw_info" | sed "/RAW=\[/c RAW=\[ \n  DATA=\"<seclabel type='dynamic' model='parsec' relabel='yes'/><acl>${new_param}</acl>\",")
        fi
    # create config
    new_config="$new_config $(cat << EOF
${vmconf_without_raw}
${raw_info}
EOF
)"
    else
    local hyperv="$(onevm show $vm_id -x | xmlstarlet sel -t -v "/VM/USER_TEMPLATE/HYPERVISOR")"
    if [ -z "$hyperv" ]; then 
        echo "No hypervisor information"; exit 21
    fi
    new_config="$new_config $(cat << EOF
${vmconf}
RAW=[
  DATA="<acl>${new_param}</acl>",
  TYPE="${hyperv}" ]
EOF
)"
    fi
}

function delFunc() {
    local del_param="${u_g}:${n_u_g}:${u_c}"
    if ! echo "${vmconf}" | grep -q "${del_param}"; then
        exit 22
    fi
    local raw_info=$(echo "${vmconf}" | sed '/^RAW=/,/]/!d')
    raw_info=$(echo "$raw_info" | awk '{gsub(/(<aclentry>'${del_param}'<\/aclentry>)|(<acl><aclentry>'${del_param}'<\/aclentry><\/acl>)/,"");print}')
    new_config="$new_config $(cat << EOF
${vmconf_without_raw}
${raw_info}
EOF
)"

}

[ -z "$vm_id" -o -z "$add_remove" -o -z "$u_c" -o -z "$u_g" -o -z "$n_u_g" ] && errorFunc && exit -1

### check VM
if ! onevm list -x | xmlstarlet sel -t -v "/VM_POOL/VM/ID" -n | grep -qw "^${vm_id}"; then
    echo "VM \"${vm_id}\" does not exist"
    exit 10
fi
if [ "$(onevm show $vm_id -x | xmlstarlet sel -t -v "/VM/STATE" -n)" != "8" ]; then
    echo "Status VM is not \"poweroff\""
    exit 11
fi

### check options
case $u_c in
    '-u'|'--use') u_c="r-x"
        COMMAND="USE"
    ;;
    '-c'|'--control')  u_c="rwx"
        COMMAND="USE+MANAGE"
    ;;
    *) errorFunc; exit 12;;
esac
case $u_g in
    '-g'|'--group') u_g='g'
        if ! onegroup list -x | xmlstarlet sel -t -v "/GROUP_POOL/GROUP/NAME" -n | grep -qw "^${n_u_g}"; then
            echo "Group \"${n_u_g}\" does not exist"
            exit 13
        fi
        OBJECT="@$(onegroup show  ${n_u_g} -x | xmlstarlet sel -t -v "GROUP/ID")"
    ;;
    '-u'|'--user')  u_g='u'
        if ! oneuser list -x | xmlstarlet sel -t -v "/USER_POOL/USER/NAME" -n | grep -qw "^${n_u_g}"; then
            echo "User \"${n_u_g}\" does not exist"
            exit 14
        fi
        OBJECT="#$(oneuser show ${n_u_g} -x | xmlstarlet sel -t -v "USER/ID")"
    ;;
    *) errorFunc; exit 15
    ;;
esac
case $add_remove in
    '-a'|'--add')
        if onevm show $vm_id --all | grep -q "${u_g}:${n_u_g}:${u_c}"; then
            # echo "Option already applied"
            exit 16  
        fi
        ACTION="create"
    ;;
    '-r'|'--remove') 
        if ! onevm show $vm_id --all | grep -q "${u_g}:${n_u_g}:${u_c}"; then
            # echo "Option does not exist"
            exit 17  
        fi
        ACTION="delete"
    ;;
    *) errorFunc; exit 18;;
esac

### get config
scred="$(echo -e '#!/bin/bash\necho "$(cat $1)"\n')"
if ! [ -f $SCRIPT ]; then
    echo "$scred" > $SCRIPT
    sudo chmod 755 $SCRIPT
else
    if [ "$(cat $SCRIPT)" != "$scred" ]; then
        echo "$scred" > $SCRIPT
    fi
fi
vmconf=$(EDITOR=$SCRIPT onevm updateconf $vm_id)
if [ "x$?" != "x0" ]; then
    echo "error get VM config"
    exit 22
fi
vmconf_without_raw=$(echo "$vmconf" | sed '/^RAW=\[/,/]/d')

### create new config
case $add_remove in
    '-a'|'--add') addFunc;;
    '-r'|'--remove') delFunc;;
esac

### apply config
echo "$new_config" > $CONFIG
onevm updateconf $vm_id $CONFIG && echo "Successful!"
if [ $ACTION = "create" ]; then
    oneacl $ACTION "${OBJECT} VM/#${vm_id} ${COMMAND}"
else
    id_ACL=$(oneacl list -x | xmlstarlet sel -t -v "//ACL[STRING='${OBJECT} VM/#${vm_id} ${COMMAND} #0']/ID")
    oneacl $ACTION $id_ACL
fi
rm -f $CONFIG
