HEX
Server: Apache/2.4.34 (Red Hat) OpenSSL/1.0.2k-fips
System: Linux WORDPRESS 3.10.0-1160.118.1.el7.x86_64 #1 SMP Thu Apr 4 03:33:23 EDT 2024 x86_64
User: digital (1020)
PHP: 7.2.24
Disabled: NONE
Upload Files
File: //var/opt/OV/bin/instrumentation/OvCluster.pm
###############################
# 
# HP Operations Smart Plug-ins for Infrastructure 11.14.014 06/07/14
#
###############################
package OvCluster;

my $catalog = OvCommon::GetCatalog(qw/ClusterPerl/);

use DiscoverResult;
use OvTrace;
use Data::Dumper;
use File::Path;
use Fcntl qw(:flock);
use Encode;

sub new
{
	my $class = shift;
	my $self = {};

	$self->{CLUSTYPE} = ();
	$self->{CLUSNAME} = ();
	$self->{CLUSSTATUS} = ();
	$self->{NODE} = ();
	$self->{RG} = ();
	$self->{DR} = DiscoverResult->new;
	$self->{TRACE} = OvTrace->new("OvCluster",,,);

	bless ($self, $class);
	return $self;
}

sub discoverCluster
{
    my $self = shift;
    my $clusthashref = shift;
    my %clusthash = %$clusthashref;
    $self->{CLUSTYPE} = $clusthash{type};
    $self->{CLUSNAME} = $clusthash{name};
    $self->{CLUSSTATUS} = $clusthash{status};
 }

sub discoverClusterMember
{
	my $self = shift;
	my $nodehashref = shift;
	my %nodehash = %$nodehashref;
	my %thisnode = {};
	$thisnode{"nodename"} = OvCommon::getFQDN($nodehash{"Node"});
	$thisnode{"nodestate"} = $nodehash{"state"};
	$thisnode{"nodeid"} = $nodehash{"id"};
	push (@nodearray, \%thisnode);
	$self->{NODE} = \@nodearray;
}

sub discoverRG
{
	my $self = shift;
	my $rghashref = shift;
	my %rghash = %$rghashref;
	my %thisrg = {};
	$thisrg{"rgname"} = $rghash{"Group"};
	$thisrg{"rgstate"} = $rghash{"state"};
	$thisrg{"rglocalstate"} = $rghash{"local state"};
	$thisrg{"rgnodes"} = $rghash{"nodes"};
	$thisrg{"rgvirtualip"} = OvCommon::getFQDN($rghash{"virtual IP"});
	if ($rghash{"active node"} ne "") {
		$thisrg{"rgactivenode"} = OvCommon::getFQDN($rghash{"active node"});
	} else {
		$thisrg{"rgactivenode"} = "none";
	}
	$thisrg{"rgvirtualip"} = OvCommon::getFQDN($rghash{"virtual IP"});
	push (@rgarray, \%thisrg);
	$self->{RG} = \@rgarray;
}

sub getClusterInfo
{
	my $self = shift;
	if ($^O eq qw/MSWin32/)
	{
		#get windows current codepage
		my $WinCurrentEncoding=""; 
		my $WinTargetEncoding="utf8";

		open (CPDATA, "chcp |");
		while (<CPDATA>)
		{
			chomp;
			my @cp_val = split(': ', $_);
			# Windows code pages for Japenese (simplified)
			if($cp_val[$#cp_val] == 932)
			{
				$WinCurrentEncoding="shiftjis";
			}
			# Windows code pages for Chinese (simplified)
			elsif ($cp_val[$#cp_val] == 936)
			{
				$WinCurrentEncoding="cp936";
			}
			# Windows code pages for Chinese (Traditional)
			elsif ($cp_val[$#cp_val] == 950)
			{
				$WinCurrentEncoding="cp950";
			}
		}
		close (CPDATA);
		$self->getClusterInfoEx($WinCurrentEncoding,$WinTargetEncoding);
	}
	else
	{
		$self->getClusterInfoEx("","");
	}	
}

sub getClusterInfoEx
{
	my $self = shift;
	my $decodefrom = shift;  
	my $encodeto = shift; 
	my $datadir = OvCommon::GetDataDir();
	my $cispi_path=$datadir."conf/cispi/";
	my $cispi_cfg = $cispi_path."/cispi.cfg";
	my $SEMAPHORE_CFG = $cispi_cfg.'.lck';
	my $SEMAPHORE_PIPE = $cispi_path."/ovclusterinfo".'.lck';
	
	# Set # as record separator
	local $/ = "\n#";
	local @nodearray=();
	local @rgarray=();
	my $traceObj = $self->{TRACE};
	
	open(SP,">$SEMAPHORE_PIPE") or warn $!;
	flock(SP,LOCK_EX) or warn "flock() failed for $SEMAPHORE_PIPE: $!";	
	if (!defined(open (OVCLUSTERINFODUMP, "ovclusterinfo -a |")))
	{
		$traceObj-> SendOpcmsg ("CISPI", "Cluster Info", "Error(s) running ovclusterinfo: ".$!, "major");
		close SP;
		exit;
	}
	my @Parentsections = <OVCLUSTERINFODUMP>;
	close (OVCLUSTERINFODUMP);
	close SP;
	foreach (@Parentsections)
	{
		my %cur_hash =  ();
		my $class = undef;
		#print "The line is $_ \n";
		my @sections = split (/\n/, $_);
		foreach my $line (@sections)
		{
			if ($line)
			{
			   chomp;
			   if (defined $encodeto && $encodeto ne '' && defined $decodefrom && $decodefrom ne '') 
			   {
					$line=Encode::encode($encodeto,Encode::decode($decodefrom,$line));
			   }
			   if ($line =~ /^#Cluster/)
			   {
						$class = "Cluster";
						%cur_hash = ();
				}
			   elsif ($line =~ /^Node\s(.*)/)
			   {
						$class = "Node";
						%cur_hash = ();
						$cur_hash{'Node'} = $1;
			   }
			   elsif ($line =~ /^Group\s(.*)/)
			   {
						$class = "Group";
						%cur_hash = ();
						$cur_hash{'Group'} = $1;
			   }
				my @temparray = split (/  +/, $line, 2);
				$cur_hash{"$temparray[0]"} = $temparray[1];				
			}
		}
		#Initiate discovery of cluster & cluster memebers.
		if ($class eq qw/Cluster/)
		{
			   $self->discoverCluster(\%cur_hash);
			   # Record cluster info(clustername, clustertype) first time around in cispi.cfg file!
			   if ( $cur_hash{status} eq "Up" )
			   {
					if ( !-d $cispi_path )
					{
						&File::Path::mkpath ($cispi_path, 0, 02755);
						my ($uid, $gid) = (getpwnam(qw/bin/))[2,3] if ($^O ne qw/MSWin32/);
						chown ($uid, $gid, $cispi_path) if ($uid);
					}
					open(SC,">$SEMAPHORE_CFG") or warn $!;
					flock(SC,LOCK_EX) or warn "flock() failed for $SEMAPHORE_CFG: $!";
					open(CLUSCFGFILE, ">$cispi_cfg") or warn "Cannont open the config file: $!";
					print CLUSCFGFILE "$cur_hash{name}:$cur_hash{type}\n";
					close CLUSCFGFILE;
					close SC;
				}
		}
		elsif ($class eq qw/Node/)
		{
			   $self->discoverClusterMember(\%cur_hash);
		}
		elsif ($class eq qw/Group/)
		{
			   $self->discoverRG(\%cur_hash);
		}
	}
	return 0;
}

sub genTopXml
{
	my $self = shift;
	my $dr = $self->{DR};

	# define ClusterInfrastructure element - do not create service
	$dr->DefineInstance ("hCI","HAClusterInfrastructure",true);
	$dr->DefineInstance ("hCV","Class_ClusterVendor",true); # true - virtual
	$dr->AddAttr("hCV", "vendor", $self->{CLUSTYPE});

	# create top-level service and child relationship to ClusterInfrastructure
	$dr->CreateService ("hCV");
	$dr->CreateComponent("hCI", "hCV");

	# create element pertaining to Cluster
	$dr->DefineInstance ("hCluster","Class_HACluster",true); # true - virtual
	
	# both attributes hCluster are required here
	$dr->AddAttr("hCluster", "clustername", $self->{CLUSNAME});
	$dr->AddAttr("hCluster", "status", $self->{CLUSSTATUS});
	$dr->AddAttr("hCluster", "vendor", $self->{CLUSTYPE});
	
	# set parent for hCluster element as hCV name
	$dr->CreateService ("hCluster");
	$dr->CreateComponent("hCV", "hCluster");

}

sub genErrXml
{
 
}

sub dispXml
{
	my $self = shift;
	my $dr = $self->{DR};

	$dr->OutputResult;
}

sub genClusterMemberXml
{
  my $self = shift;
  my $dr = $self->{DR};
  # create the ClusterNode Collection Element
  $dr->DefineInstance("hClusterMemberCollection", "Class_HAMemberCollection", true);
  
  $dr->AddAttr("hClusterMemberCollection", "clustername", $self->{CLUSNAME});
  $dr->AddAttr("hClusterMemberCollection", "vendor", $self->{CLUSTYPE});
  
  $dr->CreateService("hClusterMemberCollection");

  $dr->CreateComponent("hCluster", "hClusterMemberCollection");

  my @nodearray = @{ $self->{NODE} };
  my $product_name;
  foreach my $node (@nodearray) {
	$dr->DefineInstance("hClusterMember".$node->{"nodename"}, "Class_HAMember", false, $node->{"nodename"}); 
	
	$dr->AddAttr("hClusterMember".$node->{"nodename"}, "membername", $node->{"nodename"});
	$dr->AddAttr("hClusterMember".$node->{"nodename"}, "id", $node->{"nodeid"});
	$dr->AddAttr("hClusterMember".$node->{"nodename"}, "memberstate", $node->{"nodestate"});
	$dr->AddAttr("hClusterMember".$node->{"nodename"}, "clustername", $self->{CLUSNAME});
	$dr->AddAttr("hClusterMember".$node->{"nodename"}, "vendor", $self->{CLUSTYPE});
	
			if ($self->{CLUSTYPE} =~ /^Microsoft.*/i)
			{
				$product_name = "microsoft_cluster";
			}
			elsif ($self->{CLUSTYPE} =~ /^MC.*/i)
			{
				$product_name = "service_guard_cluster";
			}
			elsif ($self->{CLUSTYPE} =~ /^VERITAS.*/i)
			{
				$product_name = "veritas_cluster";
			}
			elsif ($self->{CLUSTYPE} =~ /^Red.*/i)
			{
				$product_name = "redhat_cluster";
			}
			elsif ($self->{CLUSTYPE} =~ /^AIX.*/i)
			{
				$product_name = "ibm_hacmp_cluster";
			}
			elsif ($self->{CLUSTYPE} =~ /^SUN.*/i)
			{
				$product_name = "sun_cluster";
			}
			else
			{
				$product_name = "unknown";
			}
			$dr->AddAttr("hClusterMember".$node->{"nodename"}, "productname", $product_name);
	
	$dr->CreateService("hClusterMember".$node->{"nodename"});
	$dr->CreateComponent("hClusterMemberCollection","hClusterMember".$node->{"nodename"});
	
	$dr->DefineInstance ("hNode".$node->{"nodename"},"Class_NodeSystem",false, $node->{"nodename"}, "SI@@");
	$dr->CreateDependent("hClusterMember".$node->{"nodename"}, "hNode".$node->{"nodename"});
  }
}

sub genRGXml
{
  my $self = shift;
  my $dr = $self->{DR};
  # create the ClusterRG Collection Element
  $dr->DefineInstance("hClusterRGCollection", "Class_RGCollection", true);

  $dr->AddAttr("hClusterRGCollection", "clustername", $self->{CLUSNAME});
  $dr->AddAttr("hClusterRGCollection", "vendor", $self->{CLUSTYPE});
 
 $dr->CreateService("hClusterRGCollection");

  $dr->CreateComponent("hCluster","hClusterRGCollection");

  my @rgarray = @{ $self->{RG} };
	my $rg_names;
	my $rg_name;
  foreach my $rg (@rgarray) {
     if ($rg->{rgvirtualip} !~ /None/) {
		$dr->DefineInstance("hClusterRG".$rg->{"rgname"}, "Class_RG", false, $rg->{rgvirtualip}); # false - hosted-on
    } else {
		# ($sRef, $Std, $Virtual, $Guid, $Key, $GraphID, $attrs)
		# key for non-hosted RG's (without Virtual IP) is CI:<ClusterName>:<RGName> - virtual service
		$dr->DefineInstance("hClusterRG".$rg->{"rgname"}, "Class_RG", true, "", "CI:".$self->{CLUSNAME}.":".$rg->{"rgname"}); # virtual service
	}
	$dr->AddAttr("hClusterRG".$rg->{"rgname"}, "rgname", $rg->{"rgname"});
	$dr->AddAttr("hClusterRG".$rg->{"rgname"}, "rglocalstate", $rg->{"rglocalstate"});
	$dr->AddAttr("hClusterRG".$rg->{"rgname"}, "rgstate", $rg->{"rgstate"});
	#$rg->{"rgnodes"} eg: tcpc096 tcpc097

	$rg_names = $rg->{"rgnodes"};
	$rg_name = undef;
	map{ $rg_name .= " " . OvCommon::getFQDN($_); } split(/ /,$rg_names);
	$rg->{"rgnodes"} = $rg_name;
	
	$dr->AddAttr("hClusterRG".$rg->{"rgname"}, "rgnodes", $rg->{"rgnodes"});
	$dr->AddAttr("hClusterRG".$rg->{"rgname"}, "activenode", $rg->{"rgactivenode"});
	$dr->AddAttr("hClusterRG".$rg->{"rgname"}, "rgvirtualip", $rg->{"rgvirtualip"});
	$dr->AddAttr("hClusterRG".$rg->{"rgname"}, "dynamicrgtype", eval {my $z = `ovxplmsg -c $catalog -m 23 -t "Resource Group"`;$z =~ s/\\x22/\x22/g;$z =~ s/\\x25/\x25/g;$z =~ s/\\x27/\x27/g;$z =~ s/\\\\/\\/g;$z =~ s/\\\$/@%@%@/g;$z =~ s/(\$[\w_!?]+[\[\{][\w_!?\$]+[\]\}])/$1/eeg;$z =~ s/(\$[\w_!?^]+)/$1/eeg;$z =~ s/@%@%@/\$/g;$z =~ s/\\x24/\x24/g;chomp($z);return($z);});
	$dr->AddAttr("hClusterRG".$rg->{"rgname"}, "clustername", $self->{CLUSNAME});
	$dr->AddAttr("hClusterRG".$rg->{"rgname"}, "vendor", $self->{CLUSTYPE});

	$dr->CreateService("hClusterRG".$rg->{"rgname"});
	$dr->CreateComponent("hClusterRGCollection","hClusterRG".$rg->{"rgname"});
	$dr->CreateDependent("hClusterRG".$rg->{"rgname"}, "hClusterMember".$rg->{"rgactivenode"});

  }
}

1;