#!/usr/bin/perl 
###################################################################
# (C) Copyright 2017 Hewlett Packard Enterprise Development, L.P.
# 
# @(#) HPE Serviceguard Network Configuration Script
# @(#) Product Name    : HP Serviceguard
# @(#) Product Version : A.12.10.00
# @(#) Patch Name      : 
#
#  *** Note: This file MUST NOT be edited. *****
# Purpose:
# cmnwmap - creates and copies the network map file of the 
# configured cluster to all its member nodes in protected 
# or recovery site of VMware's SRM administered disaster 
# recovery environment. 
#
# NOTE: This file must not be used when any of your network subnets
# or IP between protected and recovery sites are same.
###################################################################

use strict;
use Fcntl;
use warnings;
use Sys::Hostname;
use File::Path;
use File::Copy;
use Data::Dumper;
my $sgeasylib = undef;
my @file_out = undef;
my $CMD_PWD_MGMT = "cmnwmap";

BEGIN {
    my $sgconffile = "/etc/cmcluster.conf";
    $CMD_PWD_MGMT = "cmnwmap";
    if (-f $sgconffile) {
        @file_out = `cat $sgconffile`;
    } else {
        print STDERR "ERROR: Unable to run $CMD_PWD_MGMT command.\n";
        exit 99;
    }

    my @sglib_out = grep(/^SGLIB/, @file_out);
    my @split_sglib_name = split(/=/,$sglib_out[0]);
    chomp($split_sglib_name[1]);
    $sgeasylib = $split_sglib_name[1];
}
use lib "$sgeasylib";
use EDTools;
use EDPkgTools;

#Global variables
my $sgeasyTool   = new EDTools($CMD_PWD_MGMT);
my $SGBIN        = get_sgsbin_path(); # SGSBIN value obtained from
                                      # /etc/cmcluster.conf
my $SGLIB        = $sgeasyTool->get_sglib_path();  # SGLIB value obtained from
                                                   # /etc/cmcluster.conf
my $SG_CONF_PATH = $sgeasyTool->get_sgconf_path(); # SGCONF value obtained from
                                                   # /etc/cmcluster.conf
my $SGRUN        = $sgeasyTool->get_sgrun_path();  # SGRUN value obtained from
                                                   # /etc/cmcluster.conf
my $CMVIEWCL_SCONFIG = $SGBIN."/cmviewcl -s config -vf line";
my $CMVIEWCL = $SGBIN."/cmviewcl -vf line"; 	   #only used to get other nodes information
my $filename = $SGRUN. '/srm/srm-ip-config';
my $cmclconfig = $SG_CONF_PATH . "/cmclconfig" ;

#Check SRM directory
my $srmdir = $SGRUN . '/srm/' ; 
	if ( ! -e $srmdir ){
		mkdir $srmdir or die "Error creating directory :  $srmdir \n" ;
	}

#Remove all trailing and leading whilte spaces.
sub trim {
    my ($str) = @_;
    $str =~ s/^\s+//;
    $str =~ s/\s+$//;
    return $str;
}

#------------------------------------------------------------------------------
#
# Subroutine    : runandCaptureCommand()
# Calls         : open system call
# Called by     : check_license()
# Globals       : -
# Input Params  : The command to be executed
# Return Value  : returns the exitcode and output of command execution.
#
# This function opens the command in a pipe and returns the output and 
# exit code of the command to the calling function.
#
#------------------------------------------------------------------------------

sub runandCaptureCommand {
        my ($cmd, $node) = @_;

        my $my_cmd = "$SGBIN/cmexec " . $node . " " . $cmd. "  2>&1 |";
        open (CMD, $my_cmd) or fail("Cannot run command $my_cmd : $!");
        my @output = <CMD>;
        close(CMD);
        my $exitCode = ($? >> 8);
        return ($exitCode, @output);
}

#Check if the Serviceguard version is A.12.10.00 or later
sub check_version {
	my @node_list = `$CMVIEWCL_SCONFIG | grep -i ^node | awk -F'|' '{ print \$2 }' | grep -i name | awk -F'=' '{ print \$2 }'`;
	my $flag = 0;
	foreach my $node (@node_list){
	chomp ($node);
	my $version = `$CMVIEWCL | grep -i '$node' | grep -i sg_version | awk -F'|' '{ print \$2 }' | awk -F'=' '{ print \$2 }'` ;
		if ( $version lt "A.12.10.00" ) {
		  $flag = 1;
		  print "ERROR: Minimum required HPE Serviceguard version not installed on $node.\n" ;
		}
	}
	if ( $flag == 1 ) {
		print "Support for VMware SRM feature requires HPE Serviceguard version A.12.10.00\n".
              "or higher to be installed on all cluster nodes.\n" ; 
		return 1 ;
	}
}

# Check for License
sub check_license {
	my @node_list = `$CMVIEWCL_SCONFIG | grep -i ^node | awk -F'|' '{ print \$2 }' | grep -i name | awk -F'=' '{ print \$2 }'`;
	my $lic_err = 0;
	foreach my $node (@node_list){
	    chomp ($node);		 
	    my $cmd = "'$SGBIN/cmgetlicense -f line  |  head -n 1 | cut -f 2 -d '=''";
	    (my $ret, my $op) = runandCaptureCommand($cmd, $node);
	    my $lic = trim($op);
	    if (($lic eq "Enterprise") || ($lic eq "Instant_ON")) {
		    ;
	    } else {
		    $lic_err = 1;
		    print "ERROR: Invalid license on $node\n" ;
	    }
	}
	if ( $lic_err == 1 ) {
		print "Co-existence support of HPE Serviceguard with VMware SRM requires\n";
		print "Enterprise license to be installed on all the cluster nodes.\n" ;
		print "Contact HPE for for purchase of Enterprise License.\n";
		return 1 ;
	}
}

#############################################################################################
# Function create_map_file() : created the SRM mapping file, on the local node.
# The user needs to manually enter the corresponding details of the recovery site 
# in the file.
# To create the mapping file :  cmnwmap -c command is used.
#############################################################################################
sub create_map_file{
	
    # Check for Serviceguard cluster configuration
    if ( ! -s $cmclconfig )  {
        die "ERROR: Failed to run cmnwmap command.\n".
            "HPE Serviceguard cluster must be configured to create the SRM network map file.\n" ;
    }
	
	my $check_version = check_version();
	if ( $check_version !=  0 ){
		return 1;
	}

	my $check_lic = check_license();
	if ( $check_lic !=  0 ){
		return 1;
	}
	
	print "Creating configuration file ... \n" ;
	open(my $fh, '>', $filename) or die "Could not open file '$filename' $! \n";
	
	my $output = `$CMVIEWCL_SCONFIG | grep -i ^name | awk -F'=' '{ print \$2 }'`;
	#cluster name remains same for protected and recovery site
	print $fh "# ***********************************************************************
# ********* HPE Serviceguard Cluster MAP File for recovery of ***********
# *************** Virtual Machines in SRM environment *******************
# ***** For complete details on network parameters and their use,********
# ************ refer to Managing HPE Serviceguard manual. ***************
# ***********************************************************************
\n";
	print $fh "# NOTE: The format of this SRM network map file will be like below.\n
#-------------------------------------------------------------------
# Cluster Parameter Name | Primary Site Value | Recovery Site Value
#-------------------------------------------------------------------
# NOTE: Primary site values must not be modified or edited manually.
# Any change to primary site values will lead to recovery failure 
# of cluster and packages at the recovery site.
#
# Certain cluster parameters such as cluster name and NETWORK_INTERFACE 
# should remain as the same both at protected and recovery sites. 
# The script would automatically populate the values for such parameters
# in the map file which should not be modified.
\n";
	print $fh "# IMPORTANT INFORMATION: Post creation of this map file if there is any 
# change in the network configuration of cluster nodes either at 
# protected or recovery site, the map file must be recreated and 
# distributed successfully to all nodes in the cluster. Avoidance
# of this step will result in cluster and package start sequence
# failures in SRM administered recovery or switch operation.
# This file is not required to be created when cluster subnets
# and IP addresses remain the same both at protected and recovery
# sites.\n\n";
	print $fh "# The name of the cluster remains the same for the protected and recovery\n".
	          "# site.\n\n";
	chomp($output);
	$output = "CLUSTER_NAME\t|\t" . $output . "\t|\t" . $output . "\n\n"; 
	print $fh $output ;
        print $fh "# Domain name of all the cluster nodes which are part of protected site.
# Provide the domain name for the recovery site nodes. \n\n";
	my $dns_name = `/bin/dnsdomainname` ;
	chomp ($dns_name);
	print $fh "DNS_NAME\t|\t" . $dns_name . "\t|\n\n" ;
	
	my $output2 = `$CMVIEWCL_SCONFIG | grep -i ^vcenter_name | awk -F'=' '{ print \$2 }'` ;
	if ( $output2 ne '' ){
		print $fh "# The vCenter details must be present in the Serviceguard Cluster configuration in 
# an SRM environment. Enter the vCenter details of recovery site. \n\n";
		chomp($output2);
		$output2 = "VCENTER\t\t|\t" . $output2 . "\t|\n\n" ;
		print $fh $output2 ;
	}
	
	
	#get node information
	print $fh "# NODE_NAME is the specified node name in the cluster.
# It must match the hostname excluding the fully qualified domain name.
# The node names remains same for both the protected and the recovery site.\n\n";
	print $fh "# Each NETWORK_INTERFACE configured for HEARTBEAT_IP or STATIONARY_IP 
# using IPv4 address format must have only one address associated with
# it. When NETWORK_INTERFACE is configured with IPv6 address, HPE 
# Serviceguard allows multiple IPv6 addresses to be used for each 
# network interface. However, SRM allows only one address to be used
# for network interface failing which SRM recovery operation will fail
# with an appropriate error message. In consistent with SRM requirement,
# HPE recommends that cluster nodes be configured with only one IPv6 
# address per network interface for heartbeat or stationary IP for 
# successful recovery with SRM managed recovery plans. As far as the 
# use of multiple network interfaces configured either with IPv4 or IPv6 
# or combination for redundant heartbeat networks will continue to be 
# supported in SRM environment.
# Enter the details of the respective interface IP address for recovery 
# site in the SRM environment.\n";
	print $fh "\n# SUBNET is the subnet to be configured whether or not to be monitored
# at IP layer.
# Enter the subnet for the recovery site.\n";
	print $fh "\n# POLLING_TARGET is the IP address to which polling messages are sent
# from each network interface in the subnet.
# Enter the polling target IP for recovery site in the SRM environment.\n";

	my @node_list = `$CMVIEWCL_SCONFIG | grep -i ^node | awk -F'|' '{ print \$2 }' | grep -i name | awk -F'=' '{ print \$2 }'`;
	foreach my $node (@node_list){
		#node names remain same on both the sites
		chomp($node);
		print $fh "\nNODE_NAME\t\t|\t" . $node . "\t\t\t|\t" . $node . "\n";

		my @interface_list = `$CMVIEWCL_SCONFIG | grep -i '$node' | grep -i interface | awk -F'|' '{ print \$3 }' | grep -i name | awk -F'=' '{ print \$2 }'`;
		foreach my $interface (@interface_list){
			chomp($interface);
			print $fh "NETWORK_INTERFACE\t|\t" . $interface . "\t\t\t|\t" . $interface . "\n";
			my @interface_ip_list = `$CMVIEWCL_SCONFIG | grep -i '$node' | grep -i '$interface' | grep -i ip_address | awk -F'|' '{ print \$4 }' | grep -i name | awk -F'=' '{ print \$2 }'`;
			my $count = 1;
			foreach my $interface_ip (@interface_ip_list){
				chomp($interface_ip);
				if ( $interface_ip =~ /:/ ){
					print $fh "IPV6_" . $count ."\t\t\t|\t" . $interface_ip . "\t|\n";
				}else{
					print $fh "IP\t\t\t|\t" . $interface_ip . "\t\t|\n" ;
				}
				
				my @interface_netmask_list = `$CMVIEWCL_SCONFIG | grep -i '$node' | grep -i '$interface' | grep -i ip_address | grep -i '$interface_ip' | awk -F'|' '{ print \$4 }' | grep -i netmask | awk -F'=' '{ print \$2 }'`;
				my $poll_count = 1 ;
				foreach my $interface_netmask (@interface_netmask_list){ 
					chomp ($interface_netmask);
					if ( $interface_netmask =~ /:/ ){
						print $fh "NETMASK_IPV6_" . $count . "\t\t|\t" . $interface_netmask . "\t|\n";
						$poll_count = $count ;
						$count++;
					}else{
						print $fh "NETMASK_IP\t\t|\t" . $interface_netmask . "\t\t|\n" ;
					}
				}
					
				my @interface_subnet_list = `$CMVIEWCL_SCONFIG | grep -i '$node' | grep -i '$interface' | grep -i ip_address | grep -i '$interface_ip' | awk -F'|' '{ print \$4 }' | grep -i subnet | awk -F'=' '{ print \$2 }'`;
				foreach my $interface_subnet (@interface_subnet_list){
					chomp ($interface_subnet);
					my @polling_target_list = `$CMVIEWCL_SCONFIG | grep -i '$node' | grep -i polling_target | grep -i subnet:'$interface_subnet' | awk -F'|' '{ print \$3 }'  | awk -F'=' '{ print \$2 }'` ;
					foreach my $polling_target (@polling_target_list){
						chomp ($polling_target);
						if ( $polling_target =~ /:/ ){
							print $fh "IPV6_POLLING_TARGET_" . $poll_count . "\t|\t" . $polling_target . "\t|\n";
						}else{
							print $fh "IP_POLLING_TARGET\t|\t" . $polling_target . "\t|\n" ;
						}
					}
				}
			}
		}
	}
	
	#mapping netmask and associated subnet
	my @subnet_netmask ;
	my @ip_address_list = `$CMVIEWCL_SCONFIG | grep -i ^node | grep -i ip_address | grep -e name | awk -F'|' '{ print \$4 }' | awk -F'=' '{ print \$2 }'` ;
	my $i = 0;
	foreach my $ip_address ( @ip_address_list ){
		chomp ( $ip_address );
		$subnet_netmask[$i][0] = `$CMVIEWCL_SCONFIG | grep -i ^node | grep -i ip_address:'$ip_address'| grep -e subnet | awk -F'|' '{ print \$4 }' | awk -F'=' '{ print \$2 }'` ;
		$subnet_netmask[$i][0] =~ s/\/.*//;
		$subnet_netmask[$i][1] = `$CMVIEWCL_SCONFIG | grep -i ^node | grep -i ip_address:'$ip_address' | grep -e netmask | awk -F'|' '{ print \$4 }' | awk -F'=' '{ print \$2 }'` ;
		$subnet_netmask[$i][1] =~ s/\/.*//;
		chomp ($subnet_netmask[$i][0]);
		chomp ($subnet_netmask[$i][1]);
		$i++;
	}
	
	#get package information

	my @package_name_list = `$CMVIEWCL_SCONFIG | grep -i ^package | awk -F'|' '{ print \$2 }' | grep -i ^name | awk -F'=' '{ print \$2 }'`;
	if ( scalar (@package_name_list) > 0 ){
		print $fh "\n# PACKAGE_NAME is the name that is used to identify the package.
# Package names must be unique within a cluster.
# The package names remain same for both the protected and the recovery site in 
# the SRM environment.\n\n";
		print $fh "# MONITORED_SUBNET specifies the addresses of subnets that are to be monitored 
# for this package.
#
# Enter the netmask IP of which the package subnet is a part of, that is to be 
# monitored for this package. Repeat this line as necessary for
# for additional subnets.  If any of the subnets defined goes down,
# the package will be switched to another node that is configured for this
# package and has all the defined subnets available.
#
# The netmask address can be IPv4 or IPv6, or a mix of both.\n\n";
		print $fh "# PACKAGE_NETMASK_IP and IP_ADDRESS specify subnets and
# IP addresses used by this package.
# Enter the details for the recovery site.\n\n";
		foreach my $package_name (@package_name_list){
			chomp($package_name);
			print $fh "PACKAGE_NAME\t\t|\t" . $package_name . "\t\t|\t" . $package_name . "\n" ;
			my @package_monitored_subnet_list = `$CMVIEWCL_SCONFIG | grep -w ^package:'$package_name' | grep -i subnet | awk -F'|' '{ print \$3 }' | grep -i ^name | awk -F'=' '{ print \$2 }'` ;
			foreach my $package_monitored_subnet (@package_monitored_subnet_list) {
				chomp($package_monitored_subnet);
				print $fh "MONITORED_SUBNET\t|\t" . $package_monitored_subnet . "\t|\n" ;
			}
			my @package_subnet_list = `$CMVIEWCL_SCONFIG | grep -w ^package:'$package_name' | awk -F'|' '{ print \$3 }' | grep -i ip_subnet | awk -F'=' '{ print \$2 }'`;
			foreach my $package_subnet (@package_subnet_list){
				$package_subnet =~ s/\/.*//;
				chomp ($package_subnet);
				for ( my $i = 0; $i < scalar (@subnet_netmask); $i++ ){
					if ( $subnet_netmask[$i][0] eq $package_subnet ){
						chomp ($subnet_netmask[$i][1]);
						print $fh "PACKAGE_NETMASK_IP\t|\t" . $subnet_netmask[$i][1] . "\t|\n";
						last;
					}
				}
				my @package_subnet_address_list = `$CMVIEWCL_SCONFIG | grep -w ^package:'$package_name' | grep -i ip_subnet:'$package_subnet' | awk -F'|' '{ print \$3 }' | grep -i ip_address | awk -F'=' '{ print \$2 }'`;
				foreach my $package_subnet_address (@package_subnet_address_list) {
					chomp($package_subnet_address);
					print $fh "IP_ADDRESS\t\t|\t" . $package_subnet_address . "\t|\n" ;
				}
			}	
			print $fh "\n";
		}
	}	

	#get quorum server details
	my $count = 1;
	my $quorum_name = `$CMVIEWCL_SCONFIG | grep -i ^quorum_server | awk -F'|' '{print \$2}' | grep -i name | awk -F'=' '{print \$2}'`;
	if ( $quorum_name ne '' ) {
		print $fh "\n
# The QUORUM_NAME and QUORUM_IP specify the host name and IP address 
# of the node where cluster quorum service is hosted. Quorum service 
# host could be configured with multiple IP addresses as well for 
# network redundancy, details of which should be provided in the map 
# file for recovery site. 
#
# If quorum server is placed at a third site and remains accessible 
# from protected and recovery sites, the same host name and IP 
# address may be used for recovery site field in the map file.  
#
# Enter the quorum server details for recovery site.\n";
		chomp($quorum_name);
		print $fh "QUORUM_NAME\t|\t" . $quorum_name . "\t\t|\n";

		my @quorum_ip_list = `$CMVIEWCL_SCONFIG | grep -i ^quorum_server | awk -F'|' '{print \$3}' | grep -i name | awk -F'=' '{print \$2}'`;
		foreach my $quorum_ip (@quorum_ip_list){
			chomp($quorum_ip);
			print $fh "QUORUM_IP_" . $count . "\t|\t" . $quorum_ip . "\t|\n";
			$count++ ;
			}
	}
	
	close $fh;
	
	print "Mapping file template is created in $filename
This file must be updated with the recovery site values for each entry before it can be used.\n";

}

###########################################################################################
# Function validate_file(): validates if all entries are present in the SRM mapping file 
# entered manually by the user for the recovery site.
# Validation of mapping file takes place before copying the files to all nodes.
###########################################################################################

sub validate_file{
	my $check_flag = 1;
	
	open(my $fh, '<:encoding(UTF-8)', $filename) 
            or die "'$filename' file is missing, create the file by running cmnwmap -c command.\n";
	while (my $row = <$fh>){
		chomp $row ;
		#skip comments and blank lines to validate in the mapping file.
		if ( $row =~ /^(\s*(#.*)?)?$/ ){
			next;
		}else{
			my @row_entries = split (/[|]/, $row, 3);
			chomp (@row_entries) ;
			for (my $i = 0; $i < scalar (@row_entries); $i++){
				for ( my $j = 0; $j < 3; $j++ ){
					$row_entries[$j] =~ s/^\s+//;
					$row_entries[$j] =~ s/\s+$//;
				}
			}
			if ( $row_entries[2] eq '' ){
				$check_flag = 0 ;
				print "\n" . $row . "\n";
				print "ERROR: Missing value for " . $row_entries[0] . "\n"  ;
				next;
			}
			
			if (( $row_entries[0] =~ /^IP/ ) || ( $row_entries[0] =~ /^MON/ )){
				if ( $row_entries[1] eq $row_entries[2] ) {
					print "\n" . $row . "\n" ;
					print "ERROR: Value cannot be same for both the sites.\n" ;
					$check_flag = 0;
				}
				if (( $row_entries[0] eq "IP") && ( $row_entries[2] =~ /^((?!\.).)*$/ )){
					print "\n" . $row . "\n";
					print "ERROR: Invalid IPv4 address for " . $row_entries[1] . "\n" ;
					$check_flag = 0 ;
				}
				if (( $row_entries[0] =~ /IPV6/ ) && ( $row_entries[2] =~ /^((?!\:).)*$/ )){
					print "\n" . $row . "\n";
					print "ERROR: Invalid IPv6 address for " . $row_entries[1] . "\n" ;
					$check_flag = 0 ;
				}
			}
		}
	}
	close $fh;
	if ( $check_flag == 0 ){
		print "ERROR: $filename is having invalid/missing values\n" ;
		return 1 ;
		
	}else {
		return 0;
	}
}


#-----------------------------------------------------------------------------
#
# Subroutine    : runCmd()
# Calls         : fail()
# Called by     : -
# Globals       : -
# Input Params  : command 
# Return Value  : -
#
# This function execute command on local system and returns exit code of cmd
#-----------------------------------------------------------------------------
sub runCmd {
    my ($cmd) = @_;
    my $exitCode = 0;
	chomp($cmd);
    system("$cmd");
    if ( $? != 0 ) {
        print "Cannot run command $cmd : $!";
		$exitCode = 1;
    } else {
        $exitCode = ($? >> 8);
    }
    return $exitCode;
}



##########################################################################################
# Function copy_mapfile(): copies the SRM mapping file to all the nodes of the 
# cluster. 
# To distribute the file to all nodes : cmnwmap -d command is used.
#
# The file is copies after the user has entered the details of the recovery site 
# manually in the mapping file.
# Before copying the file to all nodes, the details of the recovery site entered by the 
# user are validated to see if all entries are present.
# If the validation is successful, file is copied to all nodes in the cluster. If any node is
# not reachable, the command fails to copy the file to that node.
# If the validation fails, file is not copied to any node and ERROR is thrown.
##########################################################################################

sub copy_mapfile {

    # Check for Serviceguard cluster configuration
    if ( ! -s $cmclconfig )  {
        die "ERROR: Failed to run cmnwmap command.\n".
            "HPE Serviceguard cluster must be configured to distribute the SRM network map file.\n" ;
    }
	
	my $check_lic = check_license();
	if ( $check_lic !=  0 ){
		return 1;
	}
		
	my $exitCode = validate_file();
	my $copy_flag = 1;
	if ( $exitCode == 0 ){
		#copy to nodes
		my @node_list = `$CMVIEWCL_SCONFIG | grep -i ^node | awk -F'|' '{ print \$2 }' | grep -i name | awk -F'=' '{ print \$2 }'`;
		for( my $i = 0; $i < scalar(@node_list); $i++){
			chomp ($filename);
			my $node = $node_list[$i];
			chomp($node);
			print "Copying the map file to ". $node ."...\n";
			my $cmdo = `$SGBIN/cmdo -n $node mkdir -p $srmdir`;
			if ( $? == 0 ){
				my $cmd = "$SGBIN/cmcp $filename ". " $node" .":$filename" ;
				my $exitcode = runCmd($cmd);
				if ( $exitcode != 0 ) {
					print "Copy to node " . $node . " failed. Copy the $filename manually to the $node\n";
					$copy_flag = 0;
					next;
				}
			}else {
				print "Copy to node " . $node . " failed. Node not reachable. Once the node is reachable, redistribute the map file $filename\n";
				$copy_flag = 0 ;
				next;
			}	
		}
		if ( $copy_flag != 0 ){
			print "Copied SRM mapfile to all the nodes of the cluster successfully.\n";
			return 0;
		}else {
			return 1;
		}
	}else{
		print "Validation failed, SRM mapfile will not be copied to all cluster nodes.\n" ;
		return 1;
	}
}


#check usage
sub display_usage {
	print "USAGE:";
	print "
	cmnwmap -c 
	cmnwmap -d 
	cmnwmap -h \n";
	
    print "Options:

-c  Creates the map file after reading the cluster configuration 
    attributes from the node at which the command is executed.
	
-d  The command distributes the map file to all the other nodes of 
    the cluster. While copying the map file to the cluster nodes, 
    if any node is down or not reachable, the command fails to copy 
    the map file to those nodes. It copies to rest of the reachable 
    nodes, but the command returns failure. In such cases the file 
    needs to be copied appropriately for successful recovery of the 
    cluster and packages at recovery site. 

-h  Displays help.\n";
}


my $arg_count = $#ARGV + 1;
if ( $arg_count == 1 ){
	if ( $ARGV[0] eq "-c" ) {
		&create_map_file();
	} elsif ( $ARGV[0] eq "-d" ){
		&copy_mapfile();
	} elsif ( $ARGV[0] eq "-h" ){
		&display_usage();
	} else{
        print"ERROR:Invalid option for the command cmnwmap. Refer the below help.\n";
		&display_usage();
	}
} else{
    print"ERROR:Invalid option for the command cmnwmap. Refer the below help.\n";
	&display_usage();
}
