#!/usr/bin/perl # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # # # Licensed Materials - Property of IBM # # (C) COPYRIGHT International Business Machines Corp. 2000,2019 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # sccsid = "@(#)74 1.13.1.8 src/rsct/rm/ER/cli/bin/mkcondresp.perl, errmcli, rsct_rady, rady2035a 11/12/15 16:39:48" ###################################################################### # # # Module: mkcondresp # # # # Purpose: # # mkcondresp - link an existing condition to an existing response # # # # Syntax: # # mkcondresp [-h] [-T] [-V] Condition[:Node_name] Response # # [Response ...] # # Flags: # # -h help - writes this command's usage statement to stdout # # -T Trace. IBM Support Center use only. # # -V Verbose. # # # # Operands: # # Condition The name of the existing Condition to be linked to # # the existing Response. The Condition is always specified# # first. Node_name specifies where the condition (and # # responses) is defined. # # Response [Response ...] # # The names of one or more Responses to be linked to the # # existing Condition. Specifying more than one Response # # links all specified responses to the specified Condition.# # # # Description: # # The mkcondresp command creates a link between a condition and a # # response. More than one response may be linked with a condition. # # You can start monitoring for this condition and its linked # # response later by using the startcondresp command. # # # # Exit Values: # # 0 ERRM_CLI_SUCCESS Command completed successfully. # # 1 ERRM_CLI_RMC_ERROR Command terminated due to an underlying # # RMC error. # # 2 ERRM_CLI_ERROR Command terminated due to an underlying # # error in the command script. # # 3 ERRM_CLI_BAD_FLAG Command terminated due to user # # specifying an invalid flag. # # 4 ERRM_CLI_BAD_OPERAND Command terminated due to user # # specifying a bad operand. # # 5 ERRM_CLI_USER_ERROR Command terminated due to a user error. # # For example specifying a name that # # already exists. # # # # Examples: # # 1. Link existing condition "JFS space used" to existing response # # "Broadcast event on-shift": # # mkcondresp "JFS space used" "Broadcast event on-shift" # # 2. Link existing condition "JFS space used" to existing responses# # "Broadcast event on-shift" and "E-mail root anytime": # # mkcondresp "JFS space used" "Broadcast event on-shift" \ # # "E-mail root anytime" # # # # Man Page: # # For the most current detailed description of this command see # # the mkcondresp man page in /opt/rsct/man. # # # #--------------------------------------------------------------------# # Inputs: # # /opt/rsct/msgmaps/errmcli.mkcondresp.map - message mapping # # # # Outputs: # # stdout - display information on the condition. # # stderr - any error message. # # # # External Ref: # # Commands: ctdspmsg # # Modules: ERRM_cli_utils.pm, ERRM_cli_rc.pm # # CT_cli_utils.pm # # Perl library routines: Getopt::Std # # # # Tab Settings: # # 4 and tabs should be expanded to spaces before saving this file. # # in vi: (:set ts=4 and :%!expand -4) # # # # Change Activity: # # 001106 JAC 67469: Initial design & write. # # 001228 JAC 67470: Completed mkcondresp command. # # 010103 JAC 70296: Make TRUE/FALSE come from utils. # # 010109 JAC 70406: Update syntax to remove -c and -r flags. # # 010123 JAC 70355: Updates for final messages ship. # # 010129 JAC 70951: Shift rc after RMC calls if error occurs. # # 010301 JAC 71185: Continue to make resources even if a # # condition or response is not found. # # 010303 JAC 71044: Comment out code to name the association. # # 010403 JAC 72894: Eliminate extra call to lsrsrc to get handle # # 010507 JAC 73620: Check for RMC CLI user error (rc=5) and # # return ERRM user error for this case. # # 011120 JAC 77597: Add distributed RMC changes # # 020128 JAC 79559: Change how destination/locator node is used. # # 020306 JAC 80865: Fix for multiple associations using locator. # # 020416 JAC 81754: Fix exit code checking and use mkrsrc-api. # # 020719 JAC 84425: Add $rc to process_api_error call. # # 020729 JAC 85061: Use 4 (DM/SR/local) for scope if locator used # # and scope not set. # # 071026 JAC 146726: set delimiter for -api calls. # ###################################################################### #--------------------------------------------------------------------# # General Program Flow/Logic: # # # # 1. Parse command line flags and operands, determine which flavor # # of this command we are actually invoking. # # This command allows a user to create condition-response assoc. # # 2. Print usage if -h specified # # 3. Make sure one and only one condition is specified and that it # # exists. # # 4. Make sure all responses that are specified exist. # # 5. Find the resource handles for the condition and responses. # # 6. Call RMC command mkrsrc to create an association resource for # # condition-response pair using the resource handles. Also pass # # along -VT if necessary. # # 7. Return back any errors. # # # #--------------------------------------------------------------------# #--------------------------------------------------------------------# # Included Libraries and Extensions # #--------------------------------------------------------------------# use lib "/opt/rsct/pm"; use locale; use Getopt::Long; use CT_cli_utils qw(printIMsg printEMsg); use ERRM_cli_rc qw(ERRM_CLI_SUCCESS ERRM_CLI_RMC_ERROR ERRM_CLI_ERROR ERRM_CLI_BAD_FLAG ERRM_CLI_BAD_OPERAND ERRM_CLI_USER_ERROR); use ERRM_cli_utils qw(error_exit printCIMsg printCEMsg get_handle get_source_node find_resource_name get_locator_node find_association_handle set_orig_rmc_scope check_set_cluster_scope process_api_error process_exit_code $TRUE $FALSE $DELIMITERO $DELIMITERI $CTDIR $CTBINDIR $RMC_CLI_USER_ERROR $RMC_LOCAL_SCOPE $MKRSRC $RSCASSC $RSCCOND $RSCEVRS); #--------------------------------------------------------------------# # Global Variables # #--------------------------------------------------------------------# Getopt::Long::Configure ("bundling", "no_auto_abbrev", "no_ignore_case", "require_order", "prefix_pattern=(--|-)"); $Trace = $FALSE; # default - trace off $Verbose = $FALSE; # default - verbose turned off $Scope_orig_set = $FALSE; # default - no CT_MANAGEMENT_SCOPE $Scope_orig_value = 0; # default - scope value $PROGNAME = "mkcondresp"; # Program Name for messages $LSMSG = "$CTBINDIR/ctdspmsg"; # list / display message rtn $MSGCAT = "errmcli.cat"; # msg catalogue for this cmd $ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps"; # msg maps used by $LSMSG #--------------------------------------------------------------------# # Variables # #--------------------------------------------------------------------# my $condition = ""; # condition to use -c my @responses = (); # responses to use -r my $Cond_handle = ""; # handle for condition my @Resp_handle = (); # handle for response my $response_handle = ""; # handle for response my $Assoc_name = ""; # association name my $passopts = ""; # options to pass to RMC my $other_opts = ""; # options to pass to RMC my $node_select = ""; # to specify a specific node my $nhandle; # handle counter my $i; # counter my $temp_name = ""; # holds condition name my $locator = ""; # locator my @cmd_out = (); # command output #--------------------------------------------------------------------# # Main Code # #--------------------------------------------------------------------# my $rc = 0; my $errmcli_rc = 0; # save original rmc management scope value, in case it's changed later if (defined $ENV{CT_MANAGEMENT_SCOPE}) { $Scope_orig_set = $TRUE; $Scope_orig_value = $ENV{CT_MANAGEMENT_SCOPE}; } # parse the command line, exit if there are errors ($rc, $condition, @responses) = &parse_cmd_line; ($rc == 0) || error_exit($rc); if ($Trace || $Verbose) { $passopts = $passopts." -"; } if ($Trace) { $passopts = $passopts."T"; } if ($Verbose) { $passopts = $passopts."V"; } # extract the locator from condition, if it exists ($temp_name, $locator) = get_locator_node($condition); # put back condition name without locator if ($locator ne "") { $condition = $temp_name; } # make sure the condition already exists and get the handle ($rc, $Cond_handle) = get_handle($condition, $RSCCOND, $locator); # if RMC CLI user error, exit if ($rc == $RMC_CLI_USER_ERROR) { exit(ERRM_CLI_USER_ERROR); } if ($rc < 0) { # condition name not found printEMsg("EMsgmkcondrespConditionNotFound",$condition); exit(ERRM_CLI_USER_ERROR); } # initialize response handle counter to 0 $nhandle = -1; # for each response, see if an association already exists for ($i=0; $i<=$#responses; $i++) { # make sure this response already exists and get the handle ($rc, $response_handle) = get_handle($responses[$i], $RSCEVRS, $locator); # if RMC CLI user error, set ERRM CLI user error if ($rc == $RMC_CLI_USER_ERROR) { $errmcli_rc = ERRM_CLI_USER_ERROR; } else { if ($rc < 0) { # response name not found printEMsg("EMsgmkcondrespResponseNotFound",$responses[$i]); $errmcli_rc = ERRM_CLI_USER_ERROR; } else { # response name exists # check to see if the condition - resource are already in Association $rc = find_association_handle($Cond_handle,$response_handle,$locator); if ($rc == 0) { # already defined printEMsg("EMsgmkcondrespCondRespExists",$condition,$responses[$i]); $errmcli_rc = ERRM_CLI_USER_ERROR; } else { # if RMC CLI user error, set ERRM CLI user error if ($rc == $RMC_CLI_USER_ERROR) { $errmcli_rc = ERRM_CLI_USER_ERROR; } else { # save response handle to delete it $nhandle++; $Resp_handle[$nhandle] = $response_handle; } } } } } # make the association resource for each condition-response pair for ($i=0; $i<=$#Resp_handle; $i++) { # temporarily add a resource name # $Assoc_name = $condition . "->" . $responses[$i]; 71044 # set CT_MANAGEMENT_SCOPE to original setting, in case it was used set_orig_rmc_scope; # if the destination node was not specified, make a local association. # Make sure rmc scope is set to local scope. if ($locator eq "") { $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE; } # a locator was specified, use it for NodeNameList else { # $node_select = " NodeNameList='{$locator}'"; $node_select = "${DELIMITERI}NodeNameList${DELIMITERI}{$locator}"; # use DM/SR/Local scope if scope not set check_set_cluster_scope; } if ($Verbose) { printIMsg("IMsgmkcondrespStart",$condition,$responses[$i]);} if ($Trace) { print STDERR "$PROGNAME: calling mkrsrc-api\n";} # call RMC mkrsrc to create the association # `$CTBINDIR/$MKRSRC $passopts $RSCASSC ConditionHandle='$Cond_handle' EventResponseHandle='$Resp_handle[$i]' $node_select`; @cmd_out=`$CTBINDIR/mkrsrc-api -I $DELIMITERI -D $DELIMITERO ${RSCASSC}${DELIMITERI}ConditionHandle${DELIMITERI}${Cond_handle}${DELIMITERI}EventResponseHandle${DELIMITERI}${Resp_handle[$i]}${node_select} 2>&1`; $rc = $?; $rc = &process_exit_code($rc); if ($Trace) { print STDERR "mkrsrc-api results:\n"; print STDERR "@cmd_out";} if ($Trace) { print STDERR "$PROGNAME: mkrsrc-api returned $rc\n";} # show any errors if there was a bad rc if ($rc != 0) { process_api_error($DELIMITERO,$rc,@cmd_out); } # if mkrsrc command failed due to RMC CLI user error 73620 # set ERRM CLI user error and go to next condition/response if ($rc == $RMC_CLI_USER_ERROR) { $errmcli_rc = ERRM_CLI_USER_ERROR; } # if mkrsrc command failed, print RMC error message and exit else { if ($rc != 0) { printCEMsg("EMsgERRMcliUnExpectRMCrc",$rc); exit(ERRM_CLI_RMC_ERROR); } } } # end for loop creating associations if ($Verbose) { printIMsg("IMsgmkcondrespEnd");} if ($errmcli_rc == 0) { exit($rc); } else { exit($errmcli_rc); } #--------------------------------------------------------------------# # End Main Code # #--------------------------------------------------------------------# #--------------------------------------------------------------------# # parse_cmd_line - Parse the command line for options and operands. # # Set appropriate global variables as outlined below, make sure we # # have a valid combination of arguments / options. # # # # Return: # # $rc 0 Command line parsed fine, no problem. # # ERRM_CLI_BAD_FLAG Command line contained a bad flag. # # $condition_name Name of the condition # # @responses Names of one or more responses # # # # Global Variables Modified: # # $Verbose output True (-V) turn Verbose mode on. # # $Trace output True (-T) turn Trace mode on. # #--------------------------------------------------------------------# sub parse_cmd_line { my(@original_argv) = @ARGV; my $condition_name = ""; # condition name my @responses = (); # response names my %opts = (); my $i; # Process the command line... if (!GetOptions(\%opts, 'h' , 'V' , 'T')) { # Gather options; # if errors &print_usage; # display proper usage return ERRM_CLI_BAD_FLAG; # return bad rc - bad flag } # process h flag if (defined $opts{h}) { # -h, help request &print_usage; # print usage statement exit(0); # all done with good return! } if (defined $opts{T}) { # -T turn trace on $Trace = $TRUE; } if (defined $opts{V}) { # -V turn verbose mode on $Verbose = $TRUE; } # Get the arguments... # Operands: Condition Response [Response ...] if ($#ARGV >= 1) { # must have at least 2 # first one is Condition name $condition_name = shift @ARGV; # the rest are responses @responses = @ARGV; } # end of processing valid operands else { # not enough operands printCEMsg("EMsgERRMcliInvalidNumberOfOperands"); &print_usage; return ERRM_CLI_BAD_OPERAND; } return(0, $condition_name, @responses); # success } # end parse_cmd_line #--------------------------------------------------------------------# # print_usage : print the usage statement (syntax) to stdout. # #--------------------------------------------------------------------# sub print_usage { &printIMsg("IMsgmkcondrespUsage51D"); } # end print_usage