#!/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 # pod2text -c # pod2text -c --code # pod2html 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 \ [ ENABLE_BACKUP={yes|no} ] \ [ VOLUME_GROUP={[,,...]|ALL|rootvg} ] \ [ REPLICATED_RESOURCES={[,,...]} \ [ STORAGE_NAME={[,,...]} \ [ BUCKET_NAME={} ] \ [ TARGET_LOCATION= ] \ [ CLOUD_SERVICE={ibm|aws} ] \ [ COMPRESSION={enabled|disabled} ] \ [ BACKUP_FREQUENCY=<0...999 days> ] \ [ BACKUP_SCHEDULE= ] \ [ INC_BACKUP_FREQ=<0...999 hours>] \ [ NOTIFYMETHOD= ] \ [ ENCRYPTION={disable|kms|aes} ] For configuring remote storage based backup: clmgr modify backup_profile \ [ ENABLE_BACKUP={yes|no} ] \ [ VOLUME_GROUP={[,,...]|ALL} ] \ [ REPLICATED_RESOURCES={[,,...]} \ [ STORAGE_NAME={[,,...]} \ [ NOTIFYMETHOD= ] 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 #================================================