#!/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 = "@(#)77   1.17.1.7   src/rsct/rm/ER/cli/bin/rmcondition.perl, errmcli, rsct_rady, rady2035a 11/12/15 16:39:37"
######################################################################
#                                                                    #
# Module: rmcondition                                                #
#                                                                    #
# Purpose:                                                           #
#   rmcondition - remove a condition.                                #
#                                                                    #
# Syntax:                                                            #
#   rmcondition [-h] [-f] [-q] [-TV] Condition[:Node_name]           #
#                                                                    #
# Flags:                                                             #
#   -h      help - writes this command's usage statement to stdout   #
#   -f      forces the condition to be removed even if it is linked  #
#           to responses. The links with the response are removed as #
#           well as the condition, but the responses are not removed.#
#   -q      do not return an error when the Condition does not exist #
#   -T      Trace. IBM Support Center use only.                      #
#   -V      Verbose.                                                 #
#                                                                    #
# Operands:                                                          #
#   Condition       The name of a condition to be removed. Node_name #
#                   specifies where the condition is defined.        #
#                                                                    #
# Description:                                                       #
#   The rmcondition command removes the condition specified by the   #
#   condition operand. The condition must already exist to be        #
#   removed. When the condition must be removed even if it has       #
#   linked responses, use the -f flag to force the condition and     #
#   the links with the responses to be removed. If the -f flag is    #
#   not specified and links with responses exist, the condition is   #
#   not removed.  Responses are not removed by this 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. Remove the condition named "JFS space used up":               #
#      rmcondition "JFS space used up"                               #
#   2. Remove the condition named "JFS space used up" even if the    #
#      condition is linked with responses:                           #
#      rmcondition -f "JFS space used up"                            #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the rmcondition man page in /opt/rsct/man.                  #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/errmcli.rmcondition.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:                                                   #
#   001012 JAC 67469: Initial design & write.                        #
#   001227 JAC 67470: Completed rmcondition command.                 #
#   010103 JAC 70296: Make TRUE/FALSE come from utils.               #
#   010123 JAC 70355: Updates for final messages ship.               #
#   010129 JAC 70951: Shift rc after RMC calls if error occurs.      #
#   010308 JAC 71005: Escape some special characters in strings.     #
#   010330 JAC 72894: Eliminate extra call to lsrsrc and don't check #
#                     association if -f specified                    #
#   010507 JAC 73620: Check for RMC CLI user error (rc=5) and        #
#                     return ERRM user error for this case.          #
#   011120 JAC 77597: Distributed RMC. Check for locator.            #
#   011206 JAC 78841: Fix selection string for locating resources.   #
#   011213 JAC 78976: Fix selection string for locating resources.   #
#   020118 JAC 79558: Fix incorrect error message name.              #
#   020128 JAC 79559: Change how destination/locator node is used.   #
#   020416 JAC 81754: Fix exit code check and switch to xxx-api cmds.#
#   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 commands.              #
######################################################################

#--------------------------------------------------------------------#
# 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 remove conditions                 #
# 2. Print usage if -h specified                                     #
# 3. Make sure one and only one condition is specified               #
# 4. Make sure the condition exists.                                 #
# 5. If it doesn't exist and -q was specified, exit.                 #
# 6. If condition is in an association, make sure -f was specified.  #
# 7. Call RMC command rmrsrc using the condition name within a       #
#    selection string.  Also pass along -VT if necessary.            #
# 8. 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
                    find_resource_name get_locator_node
                    find_resource_handle get_source_node
                    set_orig_rmc_scope check_set_cluster_scope
                    get_handle
                    process_api_error process_exit_code
                    $TRUE $FALSE
                    $DELIMITERI $DELIMITERO
                    $CTDIR $CTBINDIR
                    $RMC_CLI_USER_ERROR $RMC_LOCAL_SCOPE
                    $RMRSRC $RSCCOND $RSCASSC);

#--------------------------------------------------------------------#
# 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 = "rmcondition";              # 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 $resource = "";                      # resource to remove
my $passopts = "";                      # options to pass to RMC
my $Force_req = $FALSE;                 # is -f required for delete?
my $Quiet_req = $FALSE;                 # is -q requested for quiet?
my $condition_handle = "";              # condition handle
my $temp_name = "";                     # holds condition name
my $node_select = "";                   # for NodeNameList when used
my $locator = "";                       # locator 
my @cmd_out = ();                       # command output

#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#
my $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, $resource) = &parse_cmd_line;
($rc == 0) || error_exit($rc);

if ($Verbose) { printIMsg("IMsgrmconditionStart",$resource); }

if ($Trace || $Verbose) { $passopts = $passopts." -"; }

if ($Trace) { $passopts = $passopts."T"; }

if ($Verbose) { $passopts = $passopts."V"; }

# extract the locator, if it exists
($temp_name, $locator) = get_locator_node($resource);
# put back condition name without locator
if ($locator ne "") {
   $resource = $temp_name;
}

# list the condition to see if it exists
($rc, $condition_handle) = get_handle($resource, $RSCCOND, $locator);

# if RMC CLI user error, exit
if ($rc == $RMC_CLI_USER_ERROR) {
   exit(ERRM_CLI_USER_ERROR);
  }

if ($rc != 0) {                         # condition does not exist
   if ($Quiet_req) {                    # don't care about it
      exit(0);
   }
   printEMsg("EMsgrmconditionConditionNotFound",$resource);
   exit(ERRM_CLI_USER_ERROR);
}

# look for the condition in an association if force not specified
if (!$Force_req) {

    # check Association for condition handle
    $rc = find_resource_handle($condition_handle,"c",$locator);
    # if RMC CLI user error
    if ($rc == $RMC_CLI_USER_ERROR) {
       exit(ERRM_CLI_USER_ERROR);
      }
    if ($rc == 0) {                     # found in an Association
       printEMsg("EMsgrmconditionForceRequired",$resource);
       exit(ERRM_CLI_USER_ERROR);
    }
}

# ERRM removes any association entries automatically, but leave code 
# here as comments.
# remove condition from associations if necessary
##if ($Force_req){
##   `$CTBINDIR/$RMRSRC $passopts -s 'ConditionHandle==$condition_handle' $RSCASSC`;
##   $rc = $?;
##}

# set CT_MANAGEMENT_SCOPE to original setting, in case it was used
set_orig_rmc_scope;

# if the destination node was not specified, delete the local definition.
# 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\\\"}";

   # use DM/SR/Local scope if scope not set and there's a locator
   check_set_cluster_scope;
}

if ($Trace) { print STDERR "$PROGNAME: calling rmrsrc-api\n";}

# call rmrsrc to remove the condition

#`$CTBINDIR/$RMRSRC $passopts -s "Name == \\\"$resource\\\" $node_select" $RSCCOND`;
@cmd_out=`$CTBINDIR/rmrsrc-api -I $DELIMITERI -D $DELIMITERO -s ${RSCCOND}${DELIMITERI}"Name==\\\"$resource\\\"${node_select}" 2>&1`;
$rc = $?;
$rc = process_exit_code($rc);

if ($Trace) { print STDERR "rmrsrc-api results:\n";
              print STDERR "@cmd_out";}

if ($Trace) { print STDERR "$PROGNAME: rmrsrc-api returned $rc\n";}

# show any errors if there was a bad rc
if ($rc != 0) {
   process_api_error($DELIMITERO,$rc,@cmd_out);
}

# return ERRM CLI user error if it's an RMC CLI user error    73620
if ($Trace) { print STDERR "$PROGNAME: $RMRSRC returned $rc\n"; }
($rc == $RMC_CLI_USER_ERROR) && ( error_exit(ERRM_CLI_USER_ERROR) );

# if rmrsrc command failed, print RMC error message and exit
if ($rc != 0) {
   printCEMsg("EMsgERRMcliUnExpectRMCrc",$rc);
   exit(ERRM_CLI_RMC_ERROR);
   }

if ($Verbose) { printIMsg("IMsgrmconditionEnd",$resource); }

exit($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.      #
#   $resource                Name of resource to be removed.         #
#                                                                    #
# Global Variables Modified:                                         #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Trace             output   True (-T) turn Trace mode on.        #
#   $Quiet_req         output   True (-q) turn quiet mode on.        #
#   $Force_req         output   True (-f) turn force mode on.        #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my %opts = ();
my $resource = "";                      # condition name
my $rc = 0;

# Process the command line...
if (!GetOptions(\%opts,
		'h' ,
		'f' ,
		'q' ,
		'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!
}

# process q flag  
if (defined $opts{q}) {                 # -q, quiet request
    $Quiet_req = $TRUE                  # set quiet flag
}

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:  resource (only one resource allowed)
if ($#ARGV == 0) {                      # index 0 is last one
    $resource = shift @ARGV;            # user specified resources
}

else {            
    # no resource or too many resources specified 
    printCEMsg("EMsgERRMcliInvalidNumberOfOperands");
    &print_usage;
    return ERRM_CLI_BAD_OPERAND;
}

if (defined $opts{f}) {                 # -f force required
    $Force_req = $TRUE                  # set force flag
}

return(0, $resource);                     # success
}   # end parse_cmd_line


#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
#--------------------------------------------------------------------#
sub print_usage
{
&printIMsg("IMsgrmconditionUsage51D");
}   # end print_usage