#!/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 = "@(#)85   1.13   src/rsct/rm/ConfigRM/cli/bin/rmrpdomain.perl, configrmcli, rsct_rady, rady2035a 11/12/15 16:40:54"
######################################################################
#                                                                    #
# Module: rmrpdomain                                                 #
#                                                                    #
# Purpose:                                                           #
#   rmrpdomain - remove an already defined RSCT peer domain          #
#                definition.                                         #
#                                                                    #
# Syntax:                                                            #
#   rmrpdomain  [-h] [-f] [-q] [-TV] PeerDomain                      #
#                                                                    #
# Flags:                                                             #
#   -h      Help. Writes the command's usage statement to standard   #
#           output.                                                  #
#   -f      Force. The force option is required for any of the       #
#           following:                                               #
#           o to remove a node from the node's local peer domain     #
#             definition when the node is not online to the peer     #
#             domain.                                                #
#           o to remove the peer domain definition when the peer     #
#             domain below quorum.                                   #
#           o to remove the peer domain definition when a subsystem  #
#             may reject the request, as when resources are          #
#             allocated, for example.                                #
#   -q      Quiet.  Do not return an error if the peer domain does   #
#             not exist.                                             #
#   -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:                                                          #
#   PeerDomain  The name of the defined peer domain to be removed.   #
#                                                                    #
# Description:                                                       #
#   The rmrpdomain command removes the RSCT Peer Domain definition   #
#   specified by the PeerDomain operand. The peer domain must        #
#   already be defined to be removed. The command must be run on a   #
#   node that is defined in the peer domain.  The rmrpdomain command #
#   removes the peer domain definition on all nodes defined to the   #
#   peer domain that are reachable from the node on which the        #
#   command is run.  If a node that is defined to the peer domain is #
#   not reachable, that node's local peer domain definition is not   #
#   removed.  To remove it, run the rmrpdomain command on that node  #
#   and specify the -f force flag.                                   #
#                                                                    #
#   The -f force flag must also be used to override a subsystem's    #
#   rejection of the peer domain removal.  A subsystem may reject    #
#   the request if a peer domain resource is busy, for example.      #
#   Specifying the -f force flag in this situation indicates to the  #
#   subsystems that the peer domain definition must be removed.      #
#                                                                    #
# 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_NOT_FOUND     Peer domain definition does not exist   #
#                                                                    #
# Examples:                                                          #
#   1. To remove the peer domain definition of ApplDomain where nodeA#
#      is defined to ApplDomain, and nodeB and nodeC are reachable   #
#      from nodeA, run the following command from nodeA:             #
#      rmrpdomain ApplDomain                                         #
#                                                                    #
#   2. To remove the peer domain definition of ApplDomain on nodeD   #
#      when nodeD is not reachable from any node, run the following  #
#      command on nodeD:                                             #
#      rmrpdomain -f ApplDomain                                      #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the rmrpdomain man page in /opt/rsct/man.                   #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/configrmcli.rmrpdomain.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:                                                   #
#   010806 JAC 75435: Initial design & write.                        #
#   010827 JAC 75436: Uncomment code for force flag.                 #
#   011008 JAC 75442: Put in the -q flag.                            #
#   020201 JAC 79963: switch to use rmrsrc-api instead of rmrsrc.    #
#   020207 JAC 80121: Make printing of c-api results a trace msg.    #
#   020420 JAC 82248: Rename rmcluster to rmrpdomain.                #
#   020428 JAC 82316: Call process_exit_code to check $rc.           #
#   020502 JAC 82564: Set local/peer domain scope based on -f flag.  #
#   030324 JAC 93122: Don't specify default command arguments.       #
#   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 cluster exists.                                   #
# 4. Fill in the force option if -f is specified.                    #
# 5. Call RMC command rmrsrc. Also pass along -VT if necessary.      #
# 6. Return back any 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_NOT_FOUND);
use CRM_cli_utils qw(error_exit
                     printCIMsg
                     printCEMsg
                     process_api_error
                     process_exit_code
                     get_opstate_by_name);
use CRM_cli_include qw($TRUE $FALSE
                       $RSCLUSTER $RMC_CLI_USER_ERROR
                       $RMC_CLI_RSRC_NOT_FOUND
                       $LOCAL_SCOPE $PEER_DOMAIN_SCOPE
                       $CTBINDIR $CTDIR );

#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
$Trace = $FALSE;                        # default - trace off
$Verbose = $FALSE;                      # default - verbose turned off

$Opt_Force = $FALSE;                    # default - no Force option
$Opt_Quiet = $FALSE;                    # default - no Quiet option

$PROGNAME = "rmrpdomain";               # 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 $cluster_name = "";                  # cluster to remove 
my %cluster_opstates = ();              # cluster information
my @clusters = ();                      # clusters node is in
my $found = 0;                          # search boolean
my $i = 0;                              # counter
my @cmd_out = ();                       # rmrsrc output

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

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

if ($Verbose) { printIMsg("IMsgrmrpdomainStart",$cluster_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 \
#$cluster_name =~ s/\\/\\\\/g;

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

$cluster_name = escape_chars($cluster_name);

# No need to check for online/offline.  rmrpdomain has meaning
# for both

# set the force option, if specified
if ($Opt_Force) {
   $other_opts = "::Force::1";
}
#93122 - comment out specifying the default command argument
#else { $other_opts = "::Force::0"; }

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

# set local scope if -f used, peer domain scope otherwise
if ($Opt_Force) { $ENV{CT_MANAGEMENT_SCOPE} = $LOCAL_SCOPE;}
else { $ENV{CT_MANAGEMENT_SCOPE} = $PEER_DOMAIN_SCOPE;}

#$rmrsrc_out = `$CTBINDIR/rmrsrc $passopts -s "Name == \\\"$cluster_name\\\"" $RSCLUSTER $other_opts 2>&1`;
@cmd_out=`$CTBINDIR/rmrsrc-api -s ${RSCLUSTER}::"Name==\\\"$cluster_name\\\""${other_opts} 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 quiet mode specified, just exit nicely
     if ($Opt_Quiet) {exit(0);}
     else {
        printEMsg("EMsgrmrpdomainClusterNotFound",$cluster_name);
        exit(CRM_CLI_NOT_FOUND);
     }
}

# 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("IMsgrmrpdomainEnd",$cluster_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.      #
#   $cluster_name            Name of cluster to delete.              #
#                                                                    #
# Global Variables Modified:                                         #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Trace             output   True (-T) turn Trace mode on.        #
#   $Opt_Force         output   True (-f) Force option specified.    #
#   $Opt_Quiet         output   True (-q) Quiet option specified.    #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my $cluster_name = "";                  # cluster name    
my %opts = ();

# Process the command line...
if (!&getopts('hfqVT', \%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{f}) {                 # -f turn force mode on
    $Opt_Force = $TRUE;                 # -f flag specified
}

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

# Get the arguments...
# Operands:  one cluster name 
if ($#ARGV == 0) {                      # one argument present
   $cluster_name = shift @ARGV;         # get cluster name
}

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

return(0, $cluster_name);               # success

}   # end parse_cmd_line


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