#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2001,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 = "@(#)19   1.11   src/rsct/rm/ConfigRM/cli/bin/rmcomg.perl, configrmcli, rsct_rady, rady2035a 11/12/15 16:40:34"
######################################################################
#                                                                    #
# Module: rmcomg                                                     #
#                                                                    #
# Purpose:                                                           #
#   rmcomg - removes an already defined communication group from a   #
#            cluster.                                                #
#                                                                    #
# Syntax:                                                            #
#   rmcomg  [-h]  [-TV]  Communication_group                         #
#                                                                    #
# Flags:                                                             #
#   -h      Help. Writes the command's usage statement to standard   #
#           output.                                                  #
#   -T      Trace. Writes the command's trace messages to standard   #
#           error. For your software-service organization's use only.#
#   -V      Verbose. Writes the command's verbose messages to        #
#           standard output.                                         #
#                                                                    #
# Operands:                                                          #
#   Communication_group   The name of the defined communication group#
#           to be removed from the cluster.                          #
#                                                                    #
# Description:                                                       #
#   The rmcomg command removes the definition of the existing        #
#   communication group with the name specified by the               #
#   Communication_group operand for the online cluster.  The         #
#   communication group is used to define heartbeat rings for use by #
#   HATS and to define the tunables for each heartbeat ring.  The    #
#   communication group determines the network interfaces that are   #
#   used in the cluster.                                             #
#                                                                    #
#   The rmcomg command must be run on a node which is currently      #
#   online in the cluster where the communication group is defined.  #
#                                                                    #
# Exit Values:                                                       #
#   0  CRM_CLI_SUCCESS       Command completed successfully.         #
#   1  CRM_CLI_RMC_ERROR     Command terminated due to an underlying #
#                            RMC error.                              #
#   2  CRM_CLI_ERROR         Command terminated due to an underlying #
#                            error in the command script.            #
#   3  CRM_CLI_BAD_FLAG      Command terminated due to user          #
#                            specifying an invalid flag.             #
#   4  CRM_CLI_BAD_OPERAND   Command terminated due to user          #
#                            specifying a bad operand.               #
#   5  CRM_CLI_USER_ERROR    Command terminated due to a user error, #
#                            for example specifying a name that      #
#                            already exists.                         #
#   6  CRM_CLI_COMG_NOT_FOUND   Communication group definition does  #
#                            not exist.                              #
#                                                                    #
# Examples:                                                          #
#   1. To remove the communication group definition ComGrp1 for the  #
#      cluster ApplCluster and nodeA is defined and online to        #
#      ApplCluster, run the following command on nodeA:              #
#      rmcomg ComGrp1                                                #
#                                                                    #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the rmcomg man page in /opt/rsct/man.                       #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/configrmcli.rmcomg.map -                  # 
#       message mapping                                              #
#                                                                    #
# Outputs:                                                           #
#   stdout - none.                                                   #
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: ctdspmsg                                               #
#   Modules:  CRM_cli_utils.pm, CRM_cli_rc.pm,                       #
#             CRM_cli_include.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:                                                   #
#   010827 JAC 75436: Initial design & write.                        #
#   011206 JAC 77315: Updates for final rmcomg version.              #
#   011219 JAC 78807: Don't resolve node names or check if in cluster#
#   020204 JAC 80023: Use rmrsrc-api instead of rmrsrc.              #
#   020207 JAC 80121: Make printing of c-api results a trace msg.    #
#   020428 JAC 82316: Call process_exit_code to check $rc.           #
#   020503 JAC 82564: Set peer domain scope before calling rmrsrc-api#
#   040407 JAC 105863: Use escape_chars for "\" searches.            #
#   050406 JAC 119510: Add rc when calling process_api_error.        #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# 1. Parse command line flags and operands.                          #
# 2. Print usage if -h specified                                     #
# 3. Make sure the node is online to the cluster.                    #
# 4. Call RMC command rmrsrc. Also pass along -VT if necessary.      #
# 5. Check for resource not found and pass back to user.             #
# 6. Return back any other errors.                                   #
#                                                                    #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# Included Libraries and Extensions                                  #
#--------------------------------------------------------------------#
use lib "/opt/rsct/pm";
use locale;
use Getopt::Std;

use CT_cli_utils qw(printIMsg
                    printEMsg);
use CT_cli_input_utils qw(escape_chars);

use CRM_cli_rc qw(CRM_CLI_SUCCESS CRM_CLI_RMC_ERROR
                  CRM_CLI_ERROR CRM_CLI_BAD_FLAG
                  CRM_CLI_BAD_OPERAND CRM_CLI_USER_ERROR
                  CRM_CLI_COMG_NOT_FOUND);
use CRM_cli_utils qw(error_exit
                     printCIMsg
                     printCEMsg
                     process_exit_code
                     process_api_error);
use CRM_cli_include qw($TRUE $FALSE
                       $RMC_CLI_USER_ERROR
                       $RSCOMG $PEER_DOMAIN_SCOPE
                       $RSNETI
                       $RMC_CLI_RSRC_NOT_FOUND
                       $CTBINDIR $CTDIR);

#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
$Trace = $FALSE;                        # default - trace off
$Verbose = $FALSE;                      # default - verbose turned off
$Opt_Quiet = $FALSE;                    # default - no Quiet option

$PROGNAME = "rmcomg";                   # Program Name for messages
$LSMSG = "$CTBINDIR/ctdspmsg";          # list / display message rtn
$MSGCAT = "configrmcli.cat";            # msg catalogue for this cmd
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # msg maps used by $LSMSG

#--------------------------------------------------------------------#
# Variables                                                          #
#--------------------------------------------------------------------#
my $comg_name = "";                     # communication group to create
my $i = 0;                              # counter
my $found = $FALSE;                     # boolean
my @interface_out = ();                 # for lsrsrc output
my @cmd_out = ();                       # for rmrsrc output

my $passopts = "";                      # TV options to pass to RMC CLI
#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#
my $rc = 0;

# set peer domain scope
$ENV{CT_MANAGEMENT_SCOPE} = $PEER_DOMAIN_SCOPE;

# parse the command line, exit if there are errors 
($rc, $comg_name) = &parse_cmd_line;
($rc == 0) || error_exit($rc);

if ($Verbose) { printIMsg("IMsgrmcomgStart",$comg_name); }

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

# Do some escaping on strings.  Do the escape character first
# for anything that's a string, escape any inner \
#$comg_name =~ s/\\/\\\\/g;

# for anything that's a string, escape any inner double quotes
#$comg_name =~ s/\"/\\\"/g;

$comg_name = escape_chars($comg_name);

# make sure it's not referred to from an interface resource
# check NetworkInterface
if ($Trace) { print STDERR "$PROGNAME: calling lsrsrc-api\n";}

#$interface_out = `$CTBINDIR/lsrsrc $passopts -t -x -s "CommGroup == \\\"$comg_name\\\"" $RSNETI`;
@interface_out = `$CTBINDIR/lsrsrc-api -i -s ${RSNETI}::"CommGroup == \\\"$comg_name\\\"" 2>&1`;

# capture the return code from lsrsrc-api
$rc = $?;
$rc = process_exit_code($rc);

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

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

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

# return ConfigRM CLI user error if it's an RMC CLI user error
if ($rc == $RMC_CLI_USER_ERROR) { exit(CRM_CLI_USER_ERROR);}

# if lsrsrc failed for something else, exit
if ($rc != 0) {
    exit(CRM_CLI_RMC_ERROR);
    }

# error if communication group is referenced
if ($#interface_out >= 0) {
   printEMsg("EMsgrmcomgComgrpInInterface",$RSNETI);
   exit(CRM_CLI_USER_ERROR);
}

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

#`$CTBINDIR/rmrsrc $passopts -s "Name == \\\"$comg_name\\\"" $RSCOMG`;
@cmd_out=`$CTBINDIR/rmrsrc-api -s ${RSCOMG}::"Name==\\\"$comg_name\\\"" 2>&1`;

# capture the return code from rmrsrc
$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";}

# return not found error if rmc couldn't find it
if ($rc == $RMC_CLI_RSRC_NOT_FOUND) {
   if (!$Opt_Quiet) {
      printEMsg("EMsgrmcomgComgrpNotFound",$comg_name);
      exit(CRM_CLI_COMG_NOT_FOUND);
   }
   else {
      exit(0);
   }
}

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

# return ConfigRM CLI user error if it's an RMC CLI user error
if ($rc == $RMC_CLI_USER_ERROR) { exit(CRM_CLI_USER_ERROR);}

# if rmrsrc failed for something else, print RMC error message and exit
if ($rc != 0) {
#   printCEMsg("EMsgConfigRMcliUnExpectRMCrc",$rc);
    exit(CRM_CLI_RMC_ERROR);
}

if ($Verbose) { printIMsg("IMsgrmcomgEnd",$comg_name); }

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.   #
#         CRM_CLI_BAD_FLAG   Command line contained a bad flag.      #
#   $comg_name               Name of communication group to create   #
#                                                                    #
# Global Variables Modified:                                         #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Trace             output   True (-T) turn Trace mode on.        #
#   $Opt_Quiet         output   True (-q) Quiet option specified.    #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my $comg_name = "";                     # communication group name
my %opts = ();

# Process the command line...
if (!&getopts('hqVT', \%opts)) {        # Gather options; 
                                        # if errors
    &print_usage;                       # display proper usage
    return CRM_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;
}

if (defined $opts{q}) {                 # -q turn quiet mode on
    $Opt_Quiet = $TRUE;                 # -q flag specified
}

# Get the arguments...
# Operands:  communication group
if ($#ARGV == 0) {                      # communication group name
   $comg_name = shift @ARGV;            # get the name
}

else {            
    # communication group name not specified or too many
    printCEMsg("EMsgConfigRMcliInvalidNumberOfOperands");
    &print_usage;
    return CRM_CLI_BAD_OPERAND;
}

return(0, $comg_name);                  # success

}   # end parse_cmd_line


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