#!/bin/bash

##################################################################
#
# Migrate SLES to SLES for SAP
#
# Copyright (C) 2019 SUSE LLC
# Author:   Peter Varkoly <varkoly@suse.com>
#           Diego Akechi <dakechi@suse.com>
#           Stefan Weiberg <sweiberg@suse.com>
#           Malte Kraus <malte.kraus@suse.com>
#
##################################################################

ARCH=$(uname -m)
CPE_NAME=$(xml_grep --text_only cpeid /etc/products.d/baseproduct)
PRETTY_NAME=$(xml_grep --text_only summary /etc/products.d/baseproduct)
VERSION_ID=$(xml_grep --text_only version /etc/products.d/baseproduct)
SLE_VERSION=$(xml_grep --text_only baseversion /etc/products.d/baseproduct)
PATCH_LEVEL=$(xml_grep --text_only patchlevel /etc/products.d/baseproduct)
SLE15_defaultModules=("SLES_SAP" "sle-module-basesystem" "sle-module-desktop-applications" "sle-module-server-applications" "sle-ha" "sle-module-sap-applications")
TEMP_FOLDER=$(mktemp -d)

if [ "$PATCH_LEVEL" -ne 0 ] ; then
    VERSION="${SLE_VERSION} SP${PATCH_LEVEL}"
else
    VERSION=${SLE_VERSION}
fi

start_migration() {

    read -r ANSWER

    case $ANSWER in
        y)
            echo -e "\nNow starting the migration...\n"
        ;;  
        n)
            echo -e "\nExiting.\n"
            exit 0
        ;;  
        *)
            echo -e "\nInvalid answer. Please enter either 'y' or 'n'.\n"
            start_migration
        ;;  
    esac
}

get_cert() {
    name="$1"
    name_upper=$(tr [:lower:] [:upper:] <<< "$name")

    echo -e "\nPlease enter the https URL to the $name_upper server
    Example: https://my$name.corp.com:\n" >&2
    read -r REG_URL

    need_confirm=0
    wget --no-verbose -q --dns-timeout 10 --connect-timeout 10 --output-document "$TEMP_FOLDER/$name".crt "$REG_URL/$name".crt
    wget_exit=$?
    if [[ $wget_exit -eq 5 ]] ; then
        need_confirm=1
        wget --no-check-certificate --no-verbose -q --dns-timeout 10 --connect-timeout 10 --output-document "$TEMP_FOLDER/$name".crt "$REG_URL/$name".crt
        wget_exit=$?
    fi
    if [[ $wget_exit -ne 0 ]] ; then
        echo -e "\nUnable to contact $name_upper server. Exiting.\n" >&2
        exit 1
    fi

    if [[ "$name" == "rmt" ]]; then
        if [[ $need_confirm -eq 1 ]] ; then
            if ! wget --no-check-certificate --no-verbose -q --dns-timeout 10 --connect-timeout 10 --output-document "$TEMP_FOLDER"/rmt-client-setup.sh "$REG_URL"/tools/rmt-client-setup ; then
                echo -e "\nUnable to download RMT client setup script. Exiting.\n"
                exit 1
            fi
        else
            if ! wget --no-verbose -q --dns-timeout 10 --connect-timeout 10 --output-document "$TEMP_FOLDER"/rmt-client-setup.sh "$REG_URL"/tools/rmt-client-setup ; then
                echo -e "\nUnable to download RMT client setup script. Exiting.\n"
                exit 1
            fi
            chmod +x "${TEMP_FOLDER}"/rmt-client-setup.sh
        fi
    else
        if [[ $need_confirm -eq 1 ]] ; then
            if ! wget --no-check-certificate --no-verbose -q --dns-timeout 10 --connect-timeout 10 --output-document "$TEMP_FOLDER"/clientSetup4SMT.sh "$REG_URL"/tools/clientSetup4SMT.sh ; then
                echo -e "\nUnable to download SMT client setup script. Exiting.\n"
                exit 1
            fi
        else
            if ! wget --no-verbose -q --dns-timeout 10 --connect-timeout 10 --output-document "$TEMP_FOLDER/$name"-client-setup.sh "$REG_URL"/tools/"$name"-client-setup ; then
                echo -e "\nUnable to download SMT client setup script. Exiting.\n"
                exit 1
            fi
            chmod +x "$TEMP_FOLDER"/clientSetup4SMT.sh
        fi
    fi

    FINGERPRINT=$(openssl x509 -in "$TEMP_FOLDER/$name".crt -fingerprint -sha1 -noout | cut -d'=' -f2)

    if [[ $need_confirm -eq 1 ]] ; then
        echo -e "\nGot a certificate with SHA1 fingerprint $FINGERPRINT. Trust the $name_upper server with this certificate? [y/n/?]\n" >&2
        while : ; do
            read -r response
            case "$response" in
                y)
                    if [[ "$name" == "rmt" ]]; then
                        chmod +x "${TEMP_FOLDER}"/rmt-client-setup.sh
                    else
                        chmod +x "$TEMP_FOLDER"/clientSetup4SMT.sh
                    fi
                    break
                ;;
                n)
                    echo -e "\nExiting.\n" >&2
                    exit 0
                ;;
                *)
                    echo -e "\nGet the fingerprint of a known-good certificate by running" >&2
                    echo -e "\topenssl x509 -in $name.crt -fingerprint -sha1 -noout" >&2
                    echo -e "If output matches '$FINGERPRINT' press 'y', otherwise the connection to $REG_URL has been tampered with and you must press 'n' to abort." >&2
                ;;
            esac
        done
    fi

    echo -n "$REG_URL"
}

server_selection() {

    read -r ANSWER

    case $ANSWER in
        r)
            USE_RMT=y
            USE_SMT=n

            #Get RMT certificate and clientSetup4RMT.sh
            REG_URL=$(get_cert rmt)
            if [[ $REG_URL == "" ]] ; then
                exit 1
            fi
        ;;
        s)
            USE_SMT=y
            USE_RMT=n

            REG_URL=$(get_cert smt)
            if [[ $REG_URL == "" ]] ; then
                exit 1
            fi
        ;;
        c)
            USE_RMT=n
	        USE_SMT=n
            echo -e "\nPlease enter the email address to be used to register
            SUSE Linux Enterprise Server for SAP Applications ${VERSION}:\n"
            read -r EMAIL_ADDRESS

            echo -e "\nPlease enter your activation code for
            SUSE Linux Enterprise Server for SAP Applications ${VERSION}:\n"
            read -r ACTIVATION_CODE
        ;;
        *)
            echo -e "\nInvalid answer. Please enter either 'c' for SCC, 'r' for RMT or 's' for SMT.\n"
            server_selection
        ;;
    esac
}

rollback() {
    echo -e "\nThe registration was NOT successful."
    echo -e "\nPlease check your credentials or contact support.\n"
    
    echo -e "\nRolling back to SUSE Linux Enterprise Server ${VERSION}..."
    
    if zypper -n install --auto-agree-with-licenses -f "$TEMP_FOLDER"/sles-release*.rpm ; then
        rm -f "$TEMP_FOLDER"/sles-release*.rpm
    else
        echo -e "\nSomething went wrong during the rollback.\n
        If you are missing the /etc/os-release file, please \n
        insert the packages DVD and install the sles-release\n
        package via zypper and register your\n
        SUSE Linux Enterprise Server ${VERSION} via SUSEConnect."
        exit 1
    fi
    
    echo -e "\nPlease register your SUSE Linux Enterprise Server ${VERSION} via SUSEConnect."
    echo -e "\nDo not execute this script without first activating SUSE Linux Enterprise Server."

    echo -e "\nExiting.\n"
    exit 1
}

do_registration() {
    echo -e "\nPlease be aware that the next step will take a few minutes."
    echo -e "\nAs soon as it was successful you will receive a listing"
    echo -e "\nof the subscribed channels.\n"
    echo -e "\nRegistering the default products and modules for"
    echo -e "\nSUSE Linux Enterprise Server for SAP Applications ${VERSION}..."

    # Registering SLES for SAP
    if [ "$USE_RMT" = "y" ] || [ "$USE_SMT" = "y" ] ; then
        if [ "${SLE_VERSION}" = "15" ] ; then
            for i in "${SLE15_defaultModules[@]}"
            do
                do_smtrmt_registration "$i"
            done
        else
            do_smtrmt_registration "SLES_SAP"
        fi
    else
        if [ "${SLE_VERSION}" = "15" ] ; then
            for i in "${SLE15_defaultModules[@]}"
            do
                    do_scc_registration "$i"
            done
        else
            do_scc_registration "SLES_SAP"
        fi
    fi
}

do_smtrmt_registration() {
    /usr/sbin/SUSEConnect -p "$1"/"${VERSION_ID}"/"${ARCH}" --url "$REG_URL"
    retval="$?"

    #in case the registration fails we roll back to sles-release
    if [ "$retval" -ne 0 ] ; then
        rollback
    fi
}

do_scc_registration() {
    if [[ "$i" == *"module"* ]]; then
        /usr/sbin/SUSEConnect -p "$1"/"${VERSION_ID}"/"${ARCH}"
        retval="$?"
    else
        /usr/sbin/SUSEConnect -p "$1"/"${VERSION_ID}"/"${ARCH}" -e "$EMAIL_ADDRESS" -r "$ACTIVATION_CODE"
        retval="$?"
    fi

    #in case the registration fails we roll back to sles-release
    if [ "$retval" -ne 0 ] ; then
        rollback
    fi
}

unregister_system() {
    echo -e "\nUnregistering the System..."
    /usr/sbin/SUSEConnect --de-register > /dev/null
    /usr/sbin/SUSEConnect --cleanup > /dev/null
    rpm -e --nodeps sles-release > /dev/null
    rpm -e --nodeps sles-release-DVD > /dev/null 2>&1
    rpm -e --nodeps sles-release-POOL > /dev/null 2>&1
}

# Check if root runs this script
if [[ $EUID -ne 0 ]]; then
    echo -e "\nThis script must be run as root\n" 1>&2
    exit 1
fi

# Check if the script is run on a plain SLES
if ! grep -q "cpe:/o:suse:sles:${SLE_VERSION}" <<< "${CPE_NAME}" ; then
    echo -e "\nThis is an installation of ${PRETTY_NAME}"
    echo -e "\nMigration is only supported for plain SUSE Linux Enterprise Server ${VERSION}\n"
    exit 1
fi

echo -e "\nThis script will migrate your installed\n
\tSUSE Linux Enterprise Server ${VERSION}\n
to a\n
\tSUSE Linux Enterprise Server for SAP Applications ${VERSION}.\n\n
WARNING: Please be aware that after confirmation this script shouldn't be\n
interrupted as this could result in a damaged system. To recover\n
your system in such case you have to reinstall sles-release RPM from the\n
packages DVD or downloaded from a repository mirror and register\n
your system via SUSEConnect as a SUSE Linux Enterprise Server.\n\n
Do you want to continue? [y/n]\n"

start_migration

echo -e "\nThis script can use a local RMT or SMT  server\n
instead of using SCC for the migration.\n
Which server do you want to use?\n
Type 'c' for SCC 'r' for RMT or 's' for SMT.\n"

server_selection

# execute migration via SUSEConnect
if [ -x /usr/sbin/SUSEConnect ] ; then
    # download backup of sles-release package and the flavor package
    zypper -n install --auto-agree-with-licenses -f --download-only sles-release > /dev/null
    zypper -n install --auto-agree-with-licenses -f --download-only sles-release-POOL > /dev/null
    find /var/cache/zypp/packages/ -name "sles-release-POOL-${SLE_VERSION}.*" -exec cp {} "$TEMP_FOLDER"/sles-release-POOL.rpm \;
    find /var/cache/zypp/packages/ -name "sles-release-${SLE_VERSION}.*" -exec cp {} "$TEMP_FOLDER"/sles-release.rpm \;
    
    unregister_system

    if [ "$USE_SMT" = "y" ] ; then   
        FINGERPRINT=$(openssl x509 -in "$TEMP_FOLDER"/smt.crt -fingerprint -sha1 -noout | cut -d'=' -f2)
        "$TEMP_FOLDER"/clientSetup4SMT.sh "$REG_URL"/center/regsvc --fingerprint "$FINGERPRINT" --yes > /dev/null
    elif [ "$USE_RMT" = "y" ] ; then
        FINGERPRINT=$(openssl x509 -in "$TEMP_FOLDER"/rmt.crt -fingerprint -sha1 -noout | cut -d'=' -f2)
        "$TEMP_FOLDER"/rmt-client-setup.sh "$REG_URL" --fingerprint "$FINGERPRINT" --yes > /dev/null
    fi

    do_registration
else
    echo -e "\n/usr/sbin/SUSEConnect is either not available or not executable.\n"
    echo -e "\nPlease install the package 'SUSEConnect' or ensure /usr/sbin/SUSEConnect is executable.\n"

    echo -e "\nExiting.\n"
    exit 1
fi

#Cleanup files
rm -rf "$TEMP_FOLDER"

echo -e "\nYou're now subscribed to following channels:\n"
zypper lr

# EOF
