#!/bin/ksh93
#  ALTRAN_PROLOG_BEGIN_TAG                                                    
#  This is an automatically generated prolog.                                  
#                                                                              
#  Copyright (C) Altran ACT S.A.S. 2018,2019,2020,2021.  All rights reserved.  
#                                                                              
#  ALTRAN_PROLOG_END_TAG                                                      
#                                                                              
# @(#)  5f56dbd 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_backup_profile.sh, 726, 2147A_aha726, Mar 08 2021 04:44 PM

# Start of POD-formatted documentation. Viewing suggestions:
#      perldoc <FILENAME>
#      pod2text -c <FILENAME>
#      pod2text -c --code <FILENAME>
#      pod2html <FILENAME>
function devDoc {
: <<'=cut' >/dev/null 2>&1

=head1 NAME

 KLIB_HACMP_add_backup_profile

=head1 SYNOPSIS

 For configuring cloud based backup:
 clmgr add backup_profile {<resource_group>|ALL|rootvg_profile} \
                          ENABLE_BACKUP={yes|no} \
                          VOLUME_GROUP={<vg_name>[,<vg_name#2>,...]|ALL|rootvg} \
                          REPLICATED_RESOURCES={<replicated_resource>[,<replicated_resource#2>,...]} \
                          BACKUP_METHOD=<cloud> \
                          STORAGE_NAME={<storage_name>[,<storage_name#2>,...]} \
                          BUCKET_NAME={<bucket_name>} \
                          TARGET_LOCATION=<directory> \
                          [ CLOUD_SERVICE={ibm|aws} ] \
                          [ COMPRESSION={enabled|disabled} ] \
                          [ BACKUP_FREQUENCY=<0...999 days> ] \
                          [ BACKUP_SCHEDULE=<HH:MM> ] \
                          [ INC_BACKUP_FREQ=<0...999 hours>] \
                          [ NOTIFYMETHOD=</script/to/notify> ] \
                          [ ENCRYPTION={disable|kms|aes} ]

 For configuring remote storage based backup:
 clmgr add backup_profile {<resource_group>|ALL} \
                          ENABLE_BACKUP={yes|no} \
                          VOLUME_GROUP={<vg_name>[,<vg_name#2>,...]|ALL} \
                          REPLICATED_RESOURCES={<replicated_resource>[,<replicated_resource#2>,...]} \
                          BACKUP_METHOD=<remote_storage> \
                          STORAGE_NAME={<storage_name>[,storage_name#2>,...]} \
                          [ NOTIFYMETHOD=</script/to/notify> ]

 add => create, make, mk
 backup_profile => bp, backup_p, replication_profile

 NOTE: an alias for "volume_group" is "vg".

=head1 DESCRIPTION

 Attempts to create a backup profile configuration for resource group in PowerHA SystemMirror.

=head1 ARGUMENTS

 1. properties [REQUIRED] [hash ref]
 An associative array within which data about the
 created object can be returned to the caller.

 2. resource_group [REQUIRED] [string]
 Resource group name can be single resource group.
 ALL indicates all resource groups in PowerHA SystemMirror. For rootvg backup, 
 mention backup profile name as rootvg_profile and volume group name as "rootvg".

 3. ENABLE_BACKUP [REQUIRED] [string]
 The backup process can be enable or disable without deleting configuration.

 4. VOLUME_GROUP [REQUIRED] [string]
 Volume group name can be single or multiple volume groups. ALL indicates all volume groups in resource group.

 5. REPLICATED_RESOURCES [REQUIRED] [string]
 List of replicated resources created in a storage.
 For SVC, replicated resource is consistency group.

 6. BACKUP_METHOD [REQUIRED] [string]
 The type of backup remote_storage/cloud.

 7. STORAGE_NAME [REQUIRED] [string]
 To provide the storage name. For remote copy pprc relation you should provide svc cluster name.

 8. BUCKET_NAME [REQUIRED] [string]
 Bucket name to keep backup files in the cloud. For AWS bucket name refers to the S3 bucket.

 9. TARGET_LOCATION [OPTIONAL] [string]
 This directory containes final backup files and these files are uploaded to cloud.

 10. CLOUD_SERVICE [OPTIONAL] [string]
 Define the cloud service provider where the data should be backed up. Only "ibm" and "aws" are supported.

 11. COMPRESSION [OPTIONAL] [string]
 The COMPRESSION can be enabled or disabled. By default it is disabled.

 12. BACKUP_FREQUENCY [OPTIONAL] [integer]
 Schedule backup within specific time interval.
 This value is expressed in days.
 The default value is 0. Allowed values are 0 to 999.

 13. BACKUP_SCHEDULE [OPTIONAL] [integer:integer]
 Run backup operation on schedule time. Expressed in HH:MM.
 The default value is 00:42 midnight of that day.

 14. INC_BACKUP_FREQ [OPTIONAL] [integer]
 Schedule incremental backup within specific time interval.
 This value is expressed in hours.
 The default value is 0. Allowed values are 0 to 999.

 15. NOTIFYMETHOD [OPTIONAL] [string]
 Script to send backup status notification.

 16. ENCRYPTION [OPTIONAL] [string]
 Disable encryption on backup file.
 Enable encryption with KMS/AES algorithms.
 The default value is disable.

=head1 RETURN

 0: no errors were detected; the operation appears to have been successful
 1: a general error has occurred
 2: a specified resource does not exist, or could not be found
 3: some required input was missing
 4: some detected input was incorrect in some way
 5: a required dependency does not exist
 6: a specified search failed to match any data

=cut
} # End of POD-formatted documentation.

#============================================================================
#
# Name:        KLIB_HACMP_add_backup_profile
#
# Description: This is the main, FPATH function that is invoked by clmgr
#              to add backup_profile configuration. The cl_cbm_add utility is invoked
#              to save the necessary data in xml file.
#
# Inputs:      See the "devDoc()" function at the top of this file.
#
# Outputs:     The properties hash is populated. The only other outputs are
#              any error messages that might be needed.
#
# Returns:     Zero if no errors are detected. Otherwise, an appropriate
#              non-zero value is returned. Refer to the "RETURN" section
#              of the "devDoc()" function at the top of this file for
#              the standard return code values/meanings for clmgr.
#
#============================================================================
function KLIB_HACMP_add_backup_profile {
    . $HALIBROOT/log_entry "$0()" "$CL"
    : version=@(#)  5f56dbd 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_backup_profile.sh, 726, 2147A_aha726, Mar 08 2021 04:44 PM
    : INPUTS: $*

    typeset -n properties=$1
    typeset rg=${2//\"/}
    typeset -l enable_backup=${3//\"/}
    typeset vg=${4//\"/}
    typeset replicated_resources=${5//\"/}
    typeset storage_name=${6//\"/}
    typeset bucket_name=${7//\"/}
    typeset target_location=${8//\"/}
    typeset -l backup_method=${9//\"/}
    typeset -l cloud_service=${10//\"/}
    typeset compression=${11//\"/}
    typeset backup_frequency_value=${12//\"/}
    typeset backup_schedule=${13//\"/}
    typeset inc_backup_freq_value=${14//\"/}
    typeset notify_method=${15//\"/}
    typeset -l encryption=${16//\"/}

    [[ $CLMGR_LOGGING == 'med' ]] && set +x  # Only trace param values

    #===================================
    # Declare and initialize variables
    #===================================
    typeset -i rc=$RC_SUCCESS
    typeset output=""

    #====================================
    : Check python is installed or not
    #====================================
    LANG=C cl_get_python_version 2>&1 >>/dev/null
    rc=$?
    if (( $rc != 0 )); then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1315 "\nERROR: Python must be installed for using backup feature.\n\n" 1>&2
        log_return_msg "$rc" "$0()" "$LINENO"
        return $rc
    fi

    #================================================================
    : Check for a defined cluster. No need to continue without one.
    #================================================================
    CL=$LINENO isClusterDefined
    if (( $? != RC_SUCCESS )); then
        log_return_msg "$RC_MISSING_DEPENDENCY" "$0()" "$LINENO"
        return $?
    fi

    typeset available_vg=""
    typeset available_rg=""
    typeset temp=""
    typeset -l lc_rg=""
    typeset -l lc_vg=""
    typeset -i schedule_backup_hour
    typeset -i schedule_backup_minutes
    typeset -i backup_frequency=0
    typeset -i inc_backup_freq=0
    typeset dt=""
    typeset tm=""

    rg=${rg##+([[:space:]])}
    rg=${rg%%+([[:space:]])}
    rg=${rg//,/ }
    lc_rg=$rg

    #Removing duplicate entries from vg, storage_name, replicated_resources
    [[ -n $vg ]] && {
        vg=${vg//,/ }
        vg=$(echo $vg | tr " " "\n" | sort -u | tr "\n" " ")
        vg=${vg##+([[:space:]])}
        vg=${vg%%+([[:space:]])}
        lc_vg=$vg
    }

    [[ -n $storage_name ]] && {
        storage_name=${storage_name//,/ }
        storage_name=$(echo $storage_name | tr " " "\n" | sort -u | tr "\n" " ")
        storage_name=${storage_name##+([[:space:]])}
        storage_name=${storage_name%%+([[:space:]])}
    }

    [[ -n $replicated_resources ]] && {
        replicated_resources=${replicated_resources//,/ }
        replicated_resources=$(echo $replicated_resources | tr " " "\n" | sort -u | tr "\n" " ")
        replicated_resources=${replicated_resources##+([[:space:]])}
        replicated_resources=${replicated_resources%%+([[:space:]])}
    }

    #=========================
    : Validate Resource Group.
    #=========================
    if [[ -z $rg ]]
    then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 100 "\nERROR: a name/label must be provided.\n\n" 1>&2
        rc=$RC_MISSING_INPUT
    else
        if [[ $lc_rg != "all" ]]
        then
            if  [[ $rg == *[[:space:]]* ]]
            then
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1182 "\nERROR: Multiple resource groups are not allowed.\n\n" 1>&2
                rc=$RC_INCORRECT_INPUT
                log_return_msg "$rc" "$0()" "$LINENO"
                return $?
            else
                if [[ $rg != "rootvg_profile" ]]; then
                    CL=$LINENO KLIB_HACMP_is_known_rg "$rg"
                    if (( $? != RC_SUCCESS ));then
                        rc=$RC_INCORRECT_INPUT
                    else
                        STARTUP=$(clodmget -q "group=$rg" -f startup_pref -n HACMPgroup)
                        if [[ $STARTUP == "OAAN" ]]
                        then
                            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1317 "\nERROR: \"%1\$s\" is a concurrent resource group.\nPlease provide resource group which is non-concurrent.\n" "$rg" 1>&2
                            rc=$RC_INCORRECT_INPUT
                            log_return_msg "$rc" "$0()" "$LINENO"
                            return $?
                        fi
                    fi
                fi
                if (( $rc == RC_SUCCESS ));then
                    print -- "$0()[$LINENO]($SECONDS): cl_cbm_list $rg" >>$CLMGR_TMPLOG # Always log command result
                    output=$(LANG=C cl_cbm_list "$rg" 2>>$CLMGR_TMPLOG)
                    rc=$?
                    print -- "$0()[$LINENO]($SECONDS): cl_cbm_list $rg RC: $rc" >>$CLMGR_TMPLOG # Always log command result
                    # Resource group already configured for backup
                    if (( $rc == RC_SUCCESS ));then
                        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 229 "\nERROR: the specified object already exists: \"%1\$s\"\n\n" "$rg" 1>&2
                        rc=$RC_ERROR
                        log_return_msg "$rc" "$0()" "$LINENO"
                        return $?
                    else
                        rc=$RC_SUCCESS
                    fi
                fi
            fi
        else
            # Get all configured resource groups.
            CL=$LINENO KLIB_HACMP_list_resourcegroups available_rg
            rc=$?
            (( $rc != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
            if (( $rc == RC_SUCCESS )) && [[ -n $available_rg ]];then
                concurrent_rg=""
                existing_rg=""
                existing_rg=${available_rg[*]}
                for (( i=0; i<${#available_rg[*]}; i++ ))
                do
                    STARTUP=$(clodmget -q "group=${available_rg[$i]}" -f startup_pref -n HACMPgroup)
                    if [[ $STARTUP == "OAAN" ]]
                    then
                        concurrent_rg=${concurrent_rg:+$concurrent_rg,}"${available_rg[$i]}"
                        existing_rg=${existing_rg/${available_rg[$i]}/}
                    fi
                done
                if [[ -n $concurrent_rg ]];then
                    set -A available_rg
                    index=0
                    for rg in $existing_rg
                    do
                        available_rg[$index]=$rg
                        (( index++ ))
                    done
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1318 "\nWARNING:Only non-concurrent resource groups shall be considered for backup.\nThe following concurrent resource groups are not considered for backup\n%1\$s\n" "$concurrent_rg"
                fi
            fi
        fi
    fi

    if (( $rc == RC_INCORRECT_INPUT ))
    then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$rg" 1>&2
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 154 "Available Resource Groups:\n\n" 1>&2

        if [[ -z $available_rg ]]
        then
            CL=$LINENO KLIB_HACMP_list_resourcegroups available_rg
            (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
        fi

        for (( i=0; i<${#available_rg[*]}; i++ ))
        do
            if [[ ${available_rg[$i]} != *([[:space:]]) ]]
            then
                 STARTUP=$(clodmget -q "group=${available_rg[$i]}" -f startup_pref -n HACMPgroup)
                 if [[ $STARTUP != "OAAN" ]]
                 then
                    print -u2 "\t${available_rg[$i]}"
                 fi
            fi
        done
        print -u2 ""
    fi

    # Validate Volume Group
    if [[ -z $vg ]]
    then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" VOLUME_GROUP 1>&2
        rc=$RC_MISSING_INPUT
    elif [[ $lc_vg != "rootvg" ]]
    then
        if [[ $lc_rg == "all" ]] && [[ $lc_vg != "all" ]]
        then
            # Select all volume groups if Resource Group value is all
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1199 "\nAll resource groups are selected, so all volume groups from all the resource groups will be configured in backup.\n\n" 1>&2
            vg="all"
            lc_vg=$vg
        fi

        if [[ $lc_vg != "all" ]]
        then
            for i in $vg
            do
                CL=$LINENO KLIB_HACMP_is_known_volume_group "$i"
                if (( $? != RC_SUCCESS ))
                then
                    unknown_vg=${unknown_vg:+$unknown_vg,}$i
                    rc=$RC_INCORRECT_INPUT
                fi
            done
            if [[ -n $unknown_vg ]] 
            then
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 '\nERROR: "%1$s" does not appear to exist!\n\n' "$unknown_vg" 1>&2
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 160 'Available Volume Groups:\n\n' 1>&2

                CL=$LINENO KLIB_HACMP_list_volume_groups available_vg
                if (( $? == RC_SUCCESS ))
                then
                    for (( i=0; i<${#available_vg[*]}; i++ ))
                    do
                        if [[ ${available_vg[$i]} != *([[:space:]]) ]]
                        then
                            print -u2 "\t${available_vg[$i]}"
                        fi
                    done
                    print -u2 ""
                else
                    rc=$RC_INCORRECT_INPUT
                fi
            else
                # Validate that provided volume groups mapped to resource group
                typeset -A rgAttrs
                CL=$LINENO KLIB_HACMP_get_rg_attributes "$rg" rgAttrs 2>>$CLMGR_TMPLOG
                temp=""
                for temp in $vg
                do
                    if [[ "$(echo ${rgAttrs[VOLUME_GROUP]} | grep -w $temp)" == *([[:space:]]) ]]
                    then
                        temp="${rgAttrs[VOLUME_GROUP]}"
                        temp=${temp// /,}
                        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1183 "\nERROR: Invalid volume group provided for RG=%1\$s.\n\n" "$rg" 1>&2
                        if [[ -n $temp ]]
                        then
                            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 160 'Available Volume Groups:\n\n' 1>&2
                            print -u2 "$temp"
                        fi
                        rc=$RC_INCORRECT_INPUT
                        break
                    fi
                done
                unset rgAttrs
            fi
        elif [[ $lc_rg != "all" ]] && [[ $lc_vg == "all" ]]
        then
            typeset -A rgAttrs
            CL=$LINENO KLIB_HACMP_get_rg_attributes "$rg" rgAttrs 2>>$CLMGR_TMPLOG
            vg=${rgAttrs[VOLUME_GROUP]}
            lc_vg=$vg
            unset rgAttrs
        fi
    elif [[ $rg != "rootvg_profile" ]]; then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1200 "\nERROR: rootvg backup only supported with backup profile \"%1\$s\".\n\n" "rootvg_profile" 1>&2
        rc=$RC_INCORRECT_INPUT
    fi

    #Validate Storage_name
    if [[ -z $storage_name ]]
    then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" STORAGE_NAME 1>&2
        rc=$RC_MISSING_INPUT
    else
        for stg in $storage_name
        do
            typeset TYPE="" BACKUP_PROFILE="Enable"
            CL=$LINENO KLIB_HACMP_is_known_storage_system "$stg" TYPE BACKUP_PROFILE
            if (( $? != RC_SUCCESS )) || [[ $BACKUP_PROFILE != "Enable" ]]; then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$stg" 1>&2
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 164 "Available Storage Systems:\n\n" 1>&2

                typeset available
                # List Storage Systems configured only for backup management
                CL=$LINENO KLIB_HACMP_list_storage_systems available BACKUP=1
                for (( i=0; i<${#available[*]}; i++ )); do
                    if [[ ${available[$i]} != *([[:space:]]) ]]; then
                        print -u2 "\t${available[$i]}"
                    fi
                done
                rc=$RC_NOT_FOUND
                break
            fi
        done
    fi

    # Validate enable_backup option
    if [[ -z $enable_backup ]]
    then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" ENABLE_BACKUP 1>&2
        rc=$RC_MISSING_INPUT
    else
        CL=$LINENO verify_in_set ENABLE_BACKUP "$enable_backup" "yes no" enable_backup
        if (( $? != RC_SUCCESS ));then
            rc=$RC_INCORRECT_INPUT
        fi
    fi


    # Validate backup_method option
    if [[ -z $backup_method ]]
    then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" BACKUP_METHOD 1>&2
        rc=$RC_MISSING_INPUT
    else
        CL=$LINENO verify_in_set BACKUP_METHOD "$backup_method" "remote_storage cloud" backup_method
        if (( $? != RC_SUCCESS )); then
            rc=$RC_INCORRECT_INPUT
        elif [[ $backup_method == "cloud" ]]
        then
            # Validate cloud service option
            if [[ -z $cloud_service ]]
            then
                cloud_service="ibm"
            else
                CL=$LINENO verify_in_set CLOUD_SERVICE "$cloud_service" "aws,ibm" cloud_service
                if (( $? != RC_SUCCESS )); then
                    rc=$RC_INCORRECT_INPUT
                fi
            fi

            # Validate Bucket name
            if [[ -z $bucket_name ]]
            then
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" BUCKET_NAME 1>&2
                rc=$RC_INCORRECT_INPUT
            else
                # Validate the provided bucket is exists or not in aws cloud
                print -- "$0()[$LINENO]($SECONDS): cl_cbm_cloud_utils -o check -b $bucket_name -c $cloud_service" >>$CLMGR_TMPLOG
                LANG=C cl_cbm_cloud_utils -o check -b $bucket_name -c $cloud_service 2>/dev/null
                ret=$?
                print -- "$0()[$LINENO]($SECONDS): cl_cbm_cloud_utils -o check -b $bucket_name -c $cloud_service RC=$ret" >>$CLMGR_TMPLOG
                if (( $ret != 0 ))
                then
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1314 "\nERROR: The specified bucket \"%1\$s\" is not reachable. Please check firewall settings and network connectivity.\n" "$bucket_name" 1>&2
                    rc=$RC_INCORRECT_INPUT
                fi
               
            fi

            # Validate target location option
            if [[ -z $target_location ]]
            then
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1184 "\nERROR: Target location must be provided for cloud backup method.\n\n" 1>&2
                rc=$RC_INCORRECT_INPUT
            else
                if [[ ${target_location:0:1} != "/" || $target_location == @(/proc/*|/etc/objrepos/Cu/*|/aha/*|/dev/*|/var/*|.|/.) ]]
                then
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1213 '\nERROR: Target location %1$s is not valid. Please provide valid target location for cloud backup method.\n\n' "$target_location" 1>&2
                    rc=$RC_INCORRECT_INPUT
                elif [[ ! -d $target_location ]]
                then
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1212 '\nERROR: the specified path %1$s does not appear to exist on "%2$s":\n\n' "$target_location" "$LOCAL_NODE" 1>&2
                    rc=$RC_INCORRECT_INPUT
                fi
            fi
            
            # Validate backup_frequency option
            if [[ -n $backup_frequency_value ]]
            then
                CL=$LINENO verify_is_numeric $backup_frequency_value 10 "BACKUP_FREQUENCY"
                if (( $? == RC_SUCCESS ))
                then
                    if [[ $backup_frequency_value == +([0-9])\.+([0-9]) ]]
                    then
                        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 111 "\nERROR: \"%1\$s\" requires a positive, integer value.\n\n" "BACKUP_FREQUENCY" 1>&2
                        rc=$RC_ERROR
                    else
                        backup_frequency=$backup_frequency_value
                        CL=$LINENO verify_numeric_range "$backup_frequency" 0 999  "BACKUP_FREQUENCY"
                        (( $? != 0 )) && rc=$RC_ERROR
                    fi
                else
                    rc=$RC_ERROR
                fi
            fi

            # Validate incremental backup frequency option
            if [[ -n $inc_backup_freq_value ]]
            then
                CL=$LINENO verify_is_numeric $inc_backup_freq_value 10 "INC_BACKUP_FREQ"
                if (( $? == RC_SUCCESS ))
                then
                    if [[ $inc_backup_freq_value == +([0-9])\.+([0-9]) ]]
                    then
                        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 111 "\nERROR: \"%1\$s\" requires a positive, integer value.\n\n" "INC_BACKUP_FREQ" 1>&2
                        rc=$RC_ERROR
                    else
                        inc_backup_freq=$inc_backup_freq_value
                        CL=$LINENO verify_numeric_range "$inc_backup_freq" 0 999  "INC_BACKUP_FREQ"
                        if (( $? == RC_SUCCESS ))
                        then
                            if (( $backup_frequency )) && (( $inc_backup_freq >= $backup_frequency * 24 ))
                            then
                                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1186 "\nERROR: Invalid %1\$s value, %2\$s value should be less than %3\$s value.\n\n" "INC_BACKUP_FREQ" "INC_BACKUP_FREQ" "BACKUP_FREQUENCY" 1>&2
                                rc=$RC_ERROR
                            fi
                        else
                            rc=$RC_ERROR
                        fi
                    fi
                else
                    rc=$RC_ERROR
                fi
            fi

            # Validate compression option
            if [[ -z $compression ]]
            then
                compression="disabled"
            else
                CL=$LINENO verify_in_set COMPRESSION "$compression" "enabled disabled" compression
                if (( $? != RC_SUCCESS )); then
                    rc=$RC_INCORRECT_INPUT
                fi
            fi

            # Validate backup_schedule option
            if [[ -z $backup_schedule ]]
            then
                # By default backup_schedule will be midnight of that day.
                backup_schedule="00:42"
            else
                typeset hrs
                typeset min
                # Remove extra spaces from backup_schedule input
                backup_schedule=$(echo $backup_schedule| sed 's/[[:space:]]//g')
                # Validate backup_schedule format is in HH:MM or not
                echo $backup_schedule | IFS=: read hrs min
                if [[ -n $hrs && -n $min ]]
                then
                    CL=$LINENO verify_is_numeric $hrs 10 "BACKUP_SCHEDULE"
                    if (( $? == RC_SUCCESS ))
                    then
                        CL=$LINENO verify_numeric_range "$hrs" 0 23  "BACKUP_SCHEDULE"
                        if (( $? != RC_SUCCESS ));then
                            rc=$RC_INCORRECT_INPUT
                        fi
                    else
                        rc=$RC_INCORRECT_INPUT
                    fi

                    CL=$LINENO verify_is_numeric $min 10 "BACKUP_SCHEDULE"
                    if (( $? == RC_SUCCESS ))
                    then
                        CL=$LINENO verify_numeric_range "$min" 0 59  "BACKUP_SCHEDULE"
                        if (( $? != RC_SUCCESS ));then
                            rc=$RC_INCORRECT_INPUT
                        fi
                    else
                        rc=$RC_INCORRECT_INPUT
                    fi
                else
                    rc=$RC_INCORRECT_INPUT
                fi

                if (( $rc == $RC_INCORRECT_INPUT ));then
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\"\n\n" "BACKUP_SCHEDULE" "$backup_schedule" 1>&2
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1456 "Provide \"%1\$s\" value in HH:MM format.\n\n" "BACKUP_SCHEDULE" 1>&2
                fi
            fi

            # Validate encryption option
            if [[ -z $encryption ]]
            then
                # By default encryption is disabled
                encryption="disable"
            else
                if [[ $cloud_service == "ibm" ]]; then 
                    CL=$LINENO verify_in_set ENCRYPTION "$encryption" "disable AES" encryption
                else
                    # KMS supports only aws
                    CL=$LINENO verify_in_set ENCRYPTION "$encryption" "disable KMS AES" encryption
                fi
 
                if (( $? != RC_SUCCESS )); then
                    rc=$RC_INCORRECT_INPUT
                fi
            fi
        else
            [[ $rg == "rootvg_profile" ]] && cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1193 "\nERROR: \"%1\$s\" option is not supported in remote_storage backup method.\n\n" "rootvg_profile"  1>&2 && rc=$RC_INCORRECT_INPUT
            [[ -n $cloud_service ]] && cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1193 "\nERROR: \"%1\$s\" option is not supported in remote_storage backup method.\n\n" CLOUD_SERVICE  1>&2 && rc=$RC_INCORRECT_INPUT
            [[ -n $target_location ]] && cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1193 "\nERROR: \"%1\$s\" option is not supported in remote_storage backup method.\n\n" TARGET_LOCATION 1>&2 && rc=$RC_INCORRECT_INPUT
            [[ -n $bucket_name ]] && cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1193 "\nERROR: \"%1\$s\" option is not supported in remote_storage backup method.\n\n" BUCKET_NAME 1>&2 && rc=$RC_INCORRECT_INPUT
            [[ -n $inc_backup_freq_value ]] && cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1193 "\nERROR: \"%1\$s\" option is not supported in remote_storage backup method.\n\n" INCREMENTAL_BACKUP_FREQUENCY 1>&2 && rc=$RC_INCORRECT_INPUT
            [[ -n $encryption ]] && cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1193 "\nERROR: \"%1\$s\" option is not supported in remote_storage backup method.\n\n" ENCRYPTION 1>&2 && rc=$RC_INCORRECT_INPUT
            [[ -n $backup_schedule ]] && cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1193 "\nERROR: \"%1\$s\" option is not supported in remote_storage backup method.\n\n" BACKUP_SCHEDULE 1>&2 && rc=$RC_INCORRECT_INPUT
            [[ -n $backup_frequency_value ]] && cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1193 "\nERROR: \"%1\$s\" option is not supported in remote_storage backup method.\n\n" BACKUP_FREQUENCY 1>&2 && rc=$RC_INCORRECT_INPUT
            [[ -n $compression ]] && cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1193 "\nERROR: \"%1\$s\" option is not supported in remote_storage backup method.\n\n" COMPRESSION 1>&2 && rc=$RC_INCORRECT_INPUT
        fi
    fi

    # Validate notify_method option.
    if [[ -n $notify_method ]]
    then
        if [[ -f "$notify_method" ]]; then
            # check notify script is executable.
            if [[ ! -x "$notify_method" ]]
            then
                cl_dspmsg -s 32 scripts.cat 23 "Notify method \"%1\$s\" is not a valid executable routine\n" $notify_method 1>&2
                rc=$RC_ERROR
            else
                # Get backup status notification using notify_method.
                (( $rc == RC_SUCCESS )) &&  cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1187 "\nNotify method \"%1\$s\" is used to get backup status.\n\n" "$notify_method" 1>&2
            fi
        else
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 107 '\nERROR: the specified path/file does not appear to exist on "%2$s": %1$s\n\n' "$notify_method" "$LOCAL_NODE" 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
    fi
    
    # Validate replicated_resources option
    typeset -i replicated_resources_rc=0
    if [[ -z $replicated_resources ]]
    then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" "replicated_resources" 1>&2
        rc=$RC_INCORRECT_INPUT
    elif (( $rc == RC_SUCCESS ))
    then
        # If resource_group is all.
        if [[ $lc_rg == "all" ]]
        then
            CL=$LINENO KLIB_HACMP_list_resourcegroups available_rg
            typeset all_vg_list=""
            typeset vg_cg_list=""
            if (( $? == RC_SUCCESS ))
            then
                for (( i=0; i<${#available_rg[*]}; i++ ))
                do
                    if [[ ${available_rg[$i]} != *([[:space:]]) ]]
                    then
                        typeset -A rgAttrs
                        CL=$LINENO KLIB_HACMP_get_rg_attributes "${available_rg[$i]}" rgAttrs 2>>$CLMGR_TMPLOG
                        all_vg_list=${all_vg_list:+$all_vg_list}"${rgAttrs[VOLUME_GROUP]} "
                        unset rgAttrs
                    fi
                done
                print -- "$0()[$LINENO]($SECONDS): cl_cbm_replicated_resources $lc_rg $all_vg_list $replicated_resources $backup_method $storage_name" >>$CLMGR_TMPLOG
                vg_cg_list=$(cl_cbm_replicated_resources "$lc_rg" "$all_vg_list" "$replicated_resources" "$backup_method" "$storage_name")
                replicated_resources_rc=$?
                print -- "$0()[$LINENO]($SECONDS): cl_cbm_replicated_resources $lc_rg $all_vg_list $replicated_resources $backup_method $storage_name RC: $replicated_resources_rc" >>$CLMGR_TMPLOG # Always log command result
                if (( $replicated_resources_rc != RC_SUCCESS ))
                then
                    print -- "$vg_cg_list" # Prints error messages of cl_cbm_replicated_resources
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1201 "\nERROR: Replicated resources validation failed.\n" 1>&2
                    rc=$RC_ERROR
                fi
            else
                rc=$RC_INCORRECT_INPUT
            fi
        else
            print -- "$0()[$LINENO]($SECONDS): cl_cbm_replicated_resources $rg $vg $replicated_resources $backup_method $storage_name" >>$CLMGR_TMPLOG # Always log command
            cl_cbm_replicated_resources "$rg" "$vg" "$replicated_resources" "$backup_method" "$storage_name"
            replicated_resources_rc=$?
            print -- "$0()[$LINENO]($SECONDS):  cl_cbm_replicated_resources $rg $vg $replicated_resources $backup_method $storage_name RC: $replicated_resources_rc" >>$CLMGR_TMPLOG # Always log command result
            if (( $replicated_resources_rc != RC_SUCCESS ))
            then
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1201 "\nERROR: Replicated resources validation failed.\n" 1>&2
                rc=$RC_ERROR
            fi
        fi
    fi

    #=============================================================================
    : If no errors have been detected in the input, save configuration in XML file
    #=============================================================================
    if (( $rc == RC_SUCCESS ));then
        # If all resource group selcted.
        typeset rep_resource_list=""
        if [[ -n $available_rg ]]
        then
            for (( i=0; i<${#available_rg[*]}; i++ ))
            do
                typeset -A rgAttrs
                CL=$LINENO KLIB_HACMP_get_rg_attributes "${available_rg[$i]}" rgAttrs 2>>$CLMGR_TMPLOG
                rep_resource_list=""
                for vg_name in ${rgAttrs[VOLUME_GROUP]}
                do
                    for vg_cg_data in $vg_cg_list
                    do
                        if [[ ${vg_cg_data%%:*} == "$vg_name" ]]
                        then
                            rep_resource_list=${rep_resource_list:+$rep_resource_list}"$(echo "$vg_cg_data" | cut -f2 -d ":") "
                            break
                        fi
                    done
                done

                # For portability between Linux and AIX we are saving config in xml file.
                print -- "$0()[$LINENO]($SECONDS): cl_cbm_add ${available_rg[$i]}" >>$CLMGR_TMPLOG # Always log command result
                output=$(LANG=C cl_cbm_add "Resource_group=${available_rg[$i]}"\
                    "Enable_backup=$enable_backup"\
                    "Volume_group=${rgAttrs[VOLUME_GROUP]}"\
                    "Replicated_resources=$rep_resource_list" "Storage_system=$storage_name"\
                    "Bucket_name=$bucket_name" "Backup_method=$backup_method"\
                    "Target_location=$target_location" "Cloud_service=$cloud_service"\
                    "Compression=$compression" "Backup_frequency=$backup_frequency"\
                    "Backup_schedule=$backup_schedule"\
                    "Inc_backup_freq=$inc_backup_freq" "Notify_method=$notify_method"\
                    "Encryption=$encryption" 2>>$CLMGR_TMPLOG)
                rc=$?
                print -- "$0()[$LINENO]($SECONDS): cl_cbm_add ${available_rg[$i]} RC:$rc" >>$CLMGR_TMPLOG # Always log command result
                if (( $rc != RC_SUCCESS ));then
                    print -- "$0()[$LINENO]($SECONDS): cl_cbm_add ${available_rg[$i]} RC:$rc \noutput=$output" >>$CLMGR_TMPLOG # Always log command result
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1188 "\nERROR: Failed to save backup configuration.\n\n" 1>&2
                    rc=$RC_ERROR
                fi
                unset rgAttrs
            done
        else
            # For portability between Linux and AIX we are saving config in xml file.
            print -- "$0()[$LINENO]($SECONDS): cl_cbm_add $rg" >>$CLMGR_TMPLOG # Always log command result
            output=$(LANG=C cl_cbm_add "Resource_group=$rg"\
                "Enable_backup=$enable_backup"\
                "Volume_group=$vg"\
                "Replicated_resources=$replicated_resources" "Storage_system=$storage_name"\
                "Bucket_name=$bucket_name" "Backup_method=$backup_method"\
                "Target_location=$target_location" "Cloud_service=$cloud_service"\
                "Compression=$compression" "Backup_frequency=$backup_frequency"\
                "Backup_schedule=$backup_schedule"\
                "Inc_backup_freq=$inc_backup_freq" "Notify_method=$notify_method"\
                "Encryption=$encryption")
            rc=$?
            print -- "$0()[$LINENO]($SECONDS): cl_cbm_add $rg RC:$rc" >>$CLMGR_TMPLOG # Always log command result
            if (( $rc != RC_SUCCESS ));then
                print -- "$0()[$LINENO]($SECONDS): cl_cbm_add $rg RC:$rc \noutput=$output" >>$CLMGR_TMPLOG # Always log command result
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1188 "\nERROR: Failed to save backup configuration.\n\n" 1>&2
                rc=$RC_ERROR
            fi
        fi

        #===========================================================
        : If output from this operation was requested, retrieve it
        #===========================================================
        if (( CLMGR_VERBOSE )) || [[ -n $CLMGR_ATTRS ]]
        then
            CL=$LINENO KLIB_HACMP_get_backup_profile_attributes "$rg" properties
        fi
        if (( $rc == RC_SUCCESS ))
        then
            if [[ $backup_method == "cloud" ]]
            then
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1190 "\nMake sure sufficient storage is available in target location \"%1\$s\" to store backup file.\n\n" "$target_location" 1>&2
                print -- "$0()[$LINENO]($SECONDS): find_next_backup_schedule $backup_schedule" >>$CLMGR_TMPLOG # Always log command result
                output=$(LANG=C find_next_backup_schedule $backup_schedule)
                rc=$?
                print -- "$0()[$LINENO]($SECONDS): find_next_backup_schedule $backup_schedule RC:$rc" >>$CLMGR_TMPLOG # Always log command result
                if (( rc == RC_SUCCESS ))
                then
                    echo $output | read dt tm
                    [[ $enable_backup == "yes" ]] && cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1185 "\nBackup scheduled on %1\$s at %2\$s.\n\n" "$dt" "$tm" 1>&2
                    if (( $inc_backup_freq )) && [[ $enable_backup == "yes" ]]
                    then
                        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1196 "\nIncremental backup runs every %1\$d hours.\n\n" "$inc_backup_freq"
                    fi
                else
                    rc=$RC_ERROR
                fi
            fi
        fi
    else
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1189 "\nERROR: Invalid configuration.\n\n" 1>&2
    fi

    if (( $rc == RC_SUCCESS ))
    then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1210 "\nBackup profile %1\$s is added successfully.\n\n" "$rg" 1>&2
        if [[ $enable_backup == "yes" ]]
        then
            #================================================================
            : Check if cbm is configured or not by verifying HACMPresource entry
            : If BACKUP_ENABLED entry is empty then create it
            #=================================================================
            bp_exists=$(clodmget -q "name=BACKUP_ENABLED AND group=$rg" -f value -n HACMPresource)
            if [[ -z $bp_exists ]];then
                # Fetching next available HACMPresource entry to add BACKUP_ENABLED
                # and id sequence may not be proprper so get the last id number and add 1 to it
                bp_id=$(clodmget -f id -n HACMPresource)
                bp_id=$(echo $bp_id | tr " " "\n" | sort -n | tr "\n" " ")
                last_id=$(echo $bp_id | rev | cut -d " " -f 1 | rev)
                last_id=$(($last_id+1))
                print -- "$0()[$LINENO]($SECONDS): adding BACKUP_ENABLED entry in HACMPresource odm for $rg" >>$CLMGR_TMPLOG
                print -- "HACMPresource:\n\tgroup=$rg\n\tname=BACKUP_ENABLED\n\tvalue=Yes\n\tid=$last_id" | odmadd
                print -- "$0()[$LINENO]($SECONDS): adding BACKUP_ENABLED entry in HACMPresource odm for $rg returned $?" >>$CLMGR_TMPLOG
            fi
        fi
    fi
    #=======================================================================
    : If a user input error was detected, provide some helpful suggestions
    #=======================================================================
    if (( $rc == RC_MISSING_INPUT || $rc == RC_INCORRECT_INPUT )) && \
       [[ $CLMGR_GUI == *([[:space:]]) ]]
    then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 104 "For more information about available options and syntax, try\n\"$HAUTILS/clmgr %1\$s\". As an\nalternative, if the PowerHA SystemMirror man pages have been installed, invoke\n\"$HAUTILS/clmgr -hv\" (or \"/usr/bin/man clmgr\"),\nsearching for \"%2\$s\" in the displayed text.\n\n" \
        "add backup_profile -h" "$CLMGR_PROGNAME" 1>&2
    fi

    log_return_msg "$rc" "$0()" "$LINENO"
    return $?
}
# End of "KLIB_HACMP_add_backup_profile()"

#================================================
# The following, commented line enforces coding
# standards when this file is edited via vim.
#================================================
# vim:tabstop=4:shiftwidth=4:expandtab:smarttab
#================================================
