#!/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_modify_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_modify_backup_profile

=head1 SYNOPSIS

 For configuring cloud based backup:
 clmgr modify backup_profile <resource_group|rootvg_profile> \
                             [ ENABLE_BACKUP={yes|no} ] \
                             [ VOLUME_GROUP={<vg_name>[,<vg_name#2>,...]|ALL|rootvg} ] \
                             [ REPLICATED_RESOURCES={<replicated_resource>[,<replicated_resource#2>,...]} \
                             [ 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 modify backup_profile <resource_group> \
                             [ ENABLE_BACKUP={yes|no} ] \
                             [ VOLUME_GROUP={<vg_name>[,<vg_name#2>,...]|ALL} ] \
                             [ REPLICATED_RESOURCES={<replicated_resource>[,<replicated_resource#2>,...]} \
                             [ STORAGE_NAME={<storage_name>[,<storage_name#2>,...]} \
                             [ NOTIFYMETHOD=</script/to/notify> ]


 modify => change, set
 backup_profile => bp, backup_p, replication_profile

 NOTE: an alias for "volume_group" is "vg".
 NOTE: Modification of BACKUP_METHOD option is not supported.


=head1 DESCRIPTION

 Attempts to modify a existing 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 must be single resource group.
 For rootvg backup, mention backup profile name as "rootvg_profile".

 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. STORAGE_NAME [REQUIRED] [string]
 To provide the storage name. For remote copy pprc relation you should provide svc cluster name.

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

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

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

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

 11. 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.

 12. 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.

 13. 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_modify_backup_profile
#
# Description: This is the main, FPATH function that is invoked by clmgr
#              to modify backup_profile configuration. The cl_cbm_list utility is
#              used to query configured backup_profile and cl_cbm_modify utility
#              is invoked to save the modified 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_modify_backup_profile {
    . $HALIBROOT/log_entry "$0()" "$CL"
    : version=@(#)  5f56dbd 43haes/lib/ksh93/hacmp/KLIB_HACMP_modify_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 cloud_service=${9//\"/}
    typeset compression=${10//\"/}
    typeset backup_frequency_value=${11//\"/}
    typeset backup_schedule=${12//\"/}
    typeset inc_backup_freq_value=${13//\"/}
    typeset notify_method=${14//\"/}
    typeset -l encryption=${15//\"/}

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

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

    if [[ -z $vg$replicated_resources$enable_backup$storage_name$bucket_name$target_location$cloud_service$compression$backup_frequency_value$backup_schedule$inc_backup_freq_value$notify_method$encryption && -n $rg ]]
    then
        dspmsg -s $CLMGR_SET $CLMGR_MSGS 401 "\nERROR: no valid modifications were specified for \"%1\$s\".\n\n" "$rg" 1>&2
        rc=$RC_MISSING_INPUT
        log_return_msg "$rc" "$0()" "$LINENO"
        return $?
    fi

    #====================================
    : 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 backup_method=""
    typeset available_vg=""
    typeset available_rg=""
    typeset output=""
    typeset temp=""
    typeset unknown_vg=""
    typeset -l lc_vg=""
    typeset -i schedule_backup_hour
    typeset -i schedule_backup_minutes
    typeset -i backup_frequency=-1
    typeset -i inc_backup_freq=-1
    typeset -A backupAttr
    typeset dt=""
    typeset tm=""

    rg=${rg##+([[:space:]])}
    rg=${rg%%+([[:space:]])}
    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  [[ $rg == *[[:space:]]* ]]
        then
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1214 "\nERROR: For Backup Profile modification, multiple resource groups are not allowed.\n\n" 1>&2
            rc=$RC_INCORRECT_INPUT
            log_return_msg "$rc" "$0()" "$LINENO"
            return $?
        else
            print -- "$0()[$LINENO]($SECONDS): cl_cbm_list" >>$CLMGR_TMPLOG # Always log command result
            available_rg=$(LANG=C cl_cbm_list 2>>$CLMGR_TMPLOG)
            rc=$?
            print -- "$0()[$LINENO]($SECONDS): cl_cbm_list RC: $rc" >>$CLMGR_TMPLOG # Always log command result
            if (( $rc != RC_SUCCESS ));then
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1197 "\nERROR: No resource group configured for backup.\n\n" 1>&2
                rc=$RC_ERROR
            else
                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
                if (( $rc != RC_SUCCESS ));then
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1191 "\nERROR: Resource group \"%1\$s\" not configured for backup.\n\n" "$rg" 1>&2
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1192 "Configured resource groups for backup:\n\n" 1>&2
                    print -u2 "\t$available_rg"
                    print -u2 ""
                    rc=$RC_ERROR
                else
                    backup_method=$(echo "$output" | grep -w "Backup_method" | cut -f 2 -d '=')
                    backup_method=${backup_method// /} # Removes space
                fi
            fi
        fi
    fi

    # Validate enable_backup option
    if [[ -n $enable_backup ]]
    then
        CL=$LINENO verify_in_set ENABLE_BACKUP "$enable_backup" "yes no" enable_backup
        if (( $? != RC_SUCCESS ));then
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    # Validate Volume Group
    if [[ -n $vg ]]
    then
        if [[ $lc_vg != "rootvg" ]]
        then
            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 $unkonwn_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_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
        fi
    fi

    # Validate enable_backup option
    if [[ -n $enable_backup ]]
    then
        CL=$LINENO verify_in_set ENABLE_BACKUP "$enable_backup" "yes no" enable_backup
        if (( $? != RC_SUCCESS ));then
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    #Validate Storage_name
    if [[ -n $storage_name ]]
    then
        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
    
    # Get configured values.
    CL=$LINENO KLIB_HACMP_get_backup_profile_attributes "$rg" backupAttr 2>>$CLMGR_TMPLOG
    if [[ $backup_method == "cloud" ]]
    then
        # Validate cloud service option
        if [[ -n $cloud_service ]]
        then
            CL=$LINENO verify_in_set CLOUD_SERVICE "$cloud_service" "aws,ibm" cloud_service
            if (( $? != RC_SUCCESS )); then
                rc=$RC_INCORRECT_INPUT
            else
                # If user only modifies "cloud service" check
                # encryption algorithm applicable with new cloud service value
                if [[ -z  $encryption ]]
                then
                    if [[ $cloud_service == "ibm" && ${backupAttr[ENCRYPTION]} == "kms" ]]
                    then
                        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1410 "\nERROR: Encryption algorithm \"%1\$s\" is not valid for \"%2\$s\" cloud service.\nValid values are \"%3\$s\".\n\n" "${backupAttr[ENCRYPTION]}" "$cloud_service" "disable,AES" 1>&2
                        rc=$RC_INCORRECT_INPUT
                    fi
                fi
                # If user modifies "cloud service", validate the bucket name
                # if bucket name is not provided as input, fetch the previous value
                if [[ -z $bucket_name ]]
                then
                    bucket_name="${backupAttr[BUCKET_NAME]}"
                fi
            fi
        else
            # If user modifies "bucket name or encryption algorithm",
            # fetch the cloud service details for validating the
            # bucket name, encryption algorithm
            if [[ -n $encryption || -n $bucket_name ]]
            then
                cloud_service="${backupAttr[CLOUD_SERVICE]}"
            fi
        fi
        
        if [[ -n $bucket_name ]]
        then
            # Validate the provided bucket is exists or not 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 compression option
        if [[ -n $compression ]]
        then
            CL=$LINENO verify_in_set COMPRESSION "$compression" "enabled disabled" compression
            if (( $? != RC_SUCCESS )); then
                rc=$RC_INCORRECT_INPUT
            fi
        fi

        # Validate encryption option
        if [[ -n $encryption ]]
        then
            if [[ $cloud_service == "ibm" ]];then
                CL=$LINENO verify_in_set ENCRYPTION "$encryption" "disable AES" encryption
            else
                CL=$LINENO verify_in_set ENCRYPTION "$encryption" "disable KMS AES" encryption
            fi
 
            if (( $? != RC_SUCCESS )); then
                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_INCORRECT_INPUT
                else
                    backup_frequency=$backup_frequency_value
                    CL=$LINENO verify_numeric_range "$backup_frequency" 0 999  "BACKUP_FREQUENCY"
                    if (( $? != RC_SUCCESS ))
                    then
                        rc=$RC_INCORRECT_INPUT
                    fi
                fi
            else
                rc=$RC_INCORRECT_INPUT
            fi
        elif [[ " ${!_ENV_ARGS[*]} " == *\ BACKUP_FREQUENCY\ * ]]
        then
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" BACKUP_FREQUENCY 1>&2
            rc=$RC_INCORRECT_INPUT
        fi

        # Validate backup_schedule option
        if [[ -n $backup_schedule ]]
        then
            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 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_INCORRECT_INPUT
                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
                        rc=$RC_INCORRECT_INPUT
                    fi
                fi
            else
                rc=$RC_INCORRECT_INPUT
            fi
        elif [[ " ${!_ENV_ARGS[*]} " == *\ INC_BACKUP_FREQ\ * ]]
        then
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" INC_BACKUP_FREQ 1>&2
            rc=$RC_INCORRECT_INPUT
        fi

        # Check backup frequency is not less than incremental backup frequency
        if (( $? == RC_SUCCESS && (( $inc_backup_freq != -1 || $backup_frequency != -1 )) )) 
        then
            typeset -i bp_frequency=$backup_frequency
            if (( $bp_frequency == -1 ))
            then
                bp_frequency="${backupAttr[BACKUP_FREQUENCY]}"
            fi
            typeset -i bp_inc_frequency=$inc_backup_freq
            if (( $bp_inc_frequency == -1 ))
            then
                bp_inc_frequency="${backupAttr[INC_BACKUP_FREQ]}"
            fi

            if (( $bp_frequency )) && (( $bp_inc_frequency >= $bp_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_INCORRECT_INPUT
            fi
        fi

        # Validate target location option
        if [[ -n $target_location ]]
        then
            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
    elif [[ $backup_method == "remote_storage" ]]
    then
        [[ $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 $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
        [[ -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 $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 $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 $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 $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
    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

    #=============================================================================
    : If no errors have been detected in the input, save configuration in XML file
    #=============================================================================
    if (( $rc == RC_SUCCESS ));then
        # Fetch resource group backup_profile configuration from xml.
        if [[ ${backupAttr[@]} ]]; then
            if [[ -z $enable_backup ]]
            then
                if [[ " ${!_ENV_ARGS[*]} " == *\ ENABLE_BACKUP\ * ]]
                then
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" ENABLE_BACKUP 1>&2
                    rc=$RC_INCORRECT_INPUT
                fi
                enable_backup="${backupAttr[ENABLE_BACKUP]}"
            fi

            if [[ -z $vg ]]
            then
                if [[ " ${!_ENV_ARGS[*]} " == *\ VOLUME_GROUP\ * ]]
                then
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" VOLUME_GROUP 1>&2
                    rc=$RC_INCORRECT_INPUT
                fi
            fi

            if [[ -z $storage_name ]]
            then
                if [[ " ${!_ENV_ARGS[*]} " == *\ STORAGE_NAME\ * ]]
                then
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" STORAGE_NAME 1>&2
                    rc=$RC_INCORRECT_INPUT
                fi
            fi

            if [[ -z $bucket_name ]]
            then
                if [[ " ${!_ENV_ARGS[*]} " == *\ 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
                    bucket_name="${backupAttr[BUCKET_NAME]}"
                fi
            fi

            if [[ -z $target_location ]]
            then
                if [[ $backup_method == "cloud" ]]
                then
                    if [[ " ${!_ENV_ARGS[*]} " == *\ 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
                        target_location="${backupAttr[TARGET_LOCATION]}"
                    fi
                fi
            fi

            if [[ -z $cloud_service ]]
            then
                if [[ $backup_method == "cloud" ]] && [[ " ${!_ENV_ARGS[*]} " == *\ CLOUD_SERVICE\ * ]]
                then
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" CLOUD_SERVICE 1>&2
                    rc=$RC_INCORRECT_INPUT
                else
                    cloud_service="${backupAttr[CLOUD_SERVICE]}"
                fi
            fi

            if [[ -z $compression ]]
            then
                if [[ $backup_method == "cloud" ]] && [[ " ${!_ENV_ARGS[*]} " == *\ COMPRESSION\ * ]]
                then
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" COMPRESSION 1>&2
                    rc=$RC_INCORRECT_INPUT
                else
                    compression="${backupAttr[COMPRESSION]}"
                fi
            fi

            if (( $backup_frequency == -1 ))
            then
                backup_frequency="${backupAttr[BACKUP_FREQUENCY]}"
            fi

            if [[ -z $backup_schedule ]]
            then
                if [[ " ${!_ENV_ARGS[*]} " == *\ BACKUP_SCHEDULE\ * ]]
                then
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" BACKUP_SCHEDULE 1>&2
                    rc=$RC_INCORRECT_INPUT
                else
                    backup_schedule="${backupAttr[BACKUP_SCHEDULE]}"
                    backup_schedule=${backup_schedule//#!:/:}
                fi
            fi

            if (( $inc_backup_freq == -1 ))
            then
                inc_backup_freq="${backupAttr[INC_BACKUP_FREQ]}"
            fi

            if [[ -z $notify_method ]] && [[ " ${!_ENV_ARGS[*]} " != *\ NOTIFYMETHOD\ * ]]
            then
                notify_method="${backupAttr[NOTIFYMETHOD]}"
            fi

            if [[ -z $encryption ]]
            then
                if [[ " ${!_ENV_ARGS[*]} " == *\ ENCRYPTION\ * ]]
                then
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" ENCRYPTION 1>&2
                    rc=$RC_INCORRECT_INPUT
                fi
                encryption="${backupAttr[ENCRYPTION]}"
            fi

            if [[ -z $replicated_resources ]]
            then
                if [[ " ${!_ENV_ARGS[*]} " == *\ 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
                fi
            fi
            # If no input errors are detected, validate resources
            if (( $rc == RC_SUCCESS ));then
                if [[ -n $vg || -n $replicated_resources || -n $storage_name ]]
                then
                    [[ -z $replicated_resources ]] && replicated_resources="${backupAttr[REPLICATED_RESOURCES]}"
                    [[ -z $storage_name ]] && storage_name="${backupAttr[STORAGE_NAME]}"
                    [[ -z $vg ]] && vg="${backupAttr[VOLUME_GROUP]}"

                    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"
                    rc=$?
                    print -- "$0()[$LINENO]($SECONDS):  cl_cbm_replicated_resources $rg $vg $replicated_resources $backup_method $storage_name $rc" >>$CLMGR_TMPLOG # Always log command result
                    if (( $rc != RC_SUCCESS ))
                    then
                        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1201 "\nERROR: Replicated resources validation failed.\n" 1>&2
                        rc=$RC_ERROR
                    fi
                else
                    replicated_resources="${backupAttr[REPLICATED_RESOURCES]}"
                    storage_name="${backupAttr[STORAGE_NAME]}"
                    vg="${backupAttr[VOLUME_GROUP]}"
                fi
                replicated_resources=$(echo $replicated_resources | tr -d '')
                storage_name=$(echo $storage_name | tr -d '')
                vg=$(echo $vg | tr -d '')
            fi
        fi
        unset backupAttr

        if (( $rc == RC_SUCCESS ));then
            # For portability between Linux and AIX we are saving config in xml file.
            print -- "$0()[$LINENO]($SECONDS): cl_cbm_modify $rg" >>$CLMGR_TMPLOG # Always log command result
            output=$(LANG=C cl_cbm_modify "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" 2>>$CLMGR_TMPLOG)
            rc=$?
            print -- "$0()[$LINENO]($SECONDS): cl_cbm_modify $rg RC:$rc" >>$CLMGR_TMPLOG # Always log command result
            if (( $rc != RC_SUCCESS ));then
                print -- "$0()[$LINENO]($SECONDS): cl_cbm_modify $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 )) && [[ $backup_method == "cloud" ]]
        then
            if [[ -n $target_location ]] && [[ " ${!_ENV_ARGS[*]} " == *\ TARGET_LOCATION\ * ]]
            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
            fi
            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 for every %1\$d hours.\n\n" "$inc_backup_freq" 1>&2
                fi
            else
                rc=$RC_ERROR
            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 1211 "\nBackup profile %1\$s is updated successfully.\n\n" "$rg"
        #================================================================
        : Check if BACKUP_ENABLED entry exists in HACMPresource
        #=================================================================
        bp_exists=$(clodmget -q "name=BACKUP_ENABLED AND group=$rg" -f value -n HACMPresource)
        if [[ $enable_backup == "yes" && -z $bp_exists ]]
        then
            #================================================================
            : If BACKUP_ENABLED entry is empty then create it
            #=================================================================
            # 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
        elif [[ $enable_backup == "no" && -n $bp_exists ]]
        then
            #================================================================
            : If BACKUP_ENABLED entry exists, remove it
            #=================================================================
            print -- "$0()[$LINENO]($SECONDS): odmdelete -o  HACMPresource -q "group=$rg AND name=BACKUP_ENABLED" " >>$CLMGR_TMPLOG
            odmdelete -o  HACMPresource -q "group=$rg AND name=BACKUP_ENABLED" >>/dev/null
            print -- "$0()[$LINENO]($SECONDS): odmdelete -o  HACMPresource -q "group=$rg AND name=BACKUP_ENABLED" RC:$?" >>$CLMGR_TMPLOG
        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" \
        "modify backup_profile -h" "$CLMGR_PROGNAME" 1>&2
    fi

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

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