#!/usr/local/bin/perl
# 
# $Header: has/crs/template/rgexportstub.pl /main/3 2016/03/15 07:18:40 shiyer Exp $
#
# rgexportstub.pl
# 
#    NAME
#      rgexportstub.pl - RG EXPORT TEMPLATE
#
#    DESCRIPTION
#      Template file for 'crsctl export group'
#
#    NOTES
#      EDITABLE SECTION BEGINS FROM '###### EDIT TO CUSTOMIZE #####'
#
#    MODIFIED   (MM/DD/YY)
#    shiyer      07/05/15 - RG Export
#    shiyer      07/05/15 - Creation
#

#import packages
use strict;
use English;
use POSIX; 

#constants
use constant TRUE     => '1';
use constant FALSE    => '0';
use constant SUCCESS  => '1';
use constant FAILED   => '0';

#globals
my $CRSCTL                   = "crsctl";
my $trialRun                 = FALSE;
my $tracing                  = FALSE; #set to TRUE to trace execution

#trace to screen
sub trace
{
  if ($tracing)
  {
    print "@_\n";
  }
}

#print error and DIE
sub fatalError
{
  print "@_\n";
  die("Fatal error, terminating import");
}

#execute a command
sub executeCmd
{
  my ($rc, $prc) = 0;
  my @output = ();

  trace("executing cmd : @_");
  
  if (!open(CMD, "@_ 2>&1 |"))
  {  
    $rc = -1;
  } 
  else
  {
    @output = (<CMD>);
    close CMD;
    
    # the code return must be after the close
    $prc = $CHILD_ERROR >> 8; # get program return code right away
    chomp(@output);
  } 
  
  if ($prc != 0)
  {
    # program returned error code
    $rc = $prc;
  }
  elsif ($rc < 0 || ($rc = $CHILD_ERROR) < 0)
  {
    my $mycmd = join(' ', @_);
    push @output,
    "Error in execution (rc=$rc, $CHILD_ERROR, $!) for command @_";
  }
  elsif ($rc & 127)
  {
    # program returned error code
    my $sig = $rc & 127;
    my $mycmd = join(' ', @_);
    trace("Failure with signal=$sig from command=@_");
    push @output,
    "Failure with signal $sig from command: @_";
  }
  elsif ($rc)
  {
    trace("Failure with return code $rc from command @_");
  }

  return ($rc, @output);
}

#execute a crsctl command
sub executeCrsctlCmd
{
  {
    my @out = executeCmd(@_);
    return @out;
  }
}

#check if crsctl & CRS are fine
sub checkCrs
{
  my @cmd = ($CRSCTL, 'check' , 'crs');
  my @out = executeCrsctlCmd(@cmd);
  my $rc  = shift @out;
  if (scalar(grep(/^CRS-4537/, @out)))
  {
    trace("crsctl & CRS fine");
    return TRUE;
  }
  else
  {
    trace("checkCrs = @out");
    fatalError("Cannot contact CRS, verify 'crsctl' is in PATH and CRS is ready.");
    return FALSE;
  }
}

#check if resource/group/type/rgtype exists
sub checkIfEntityExists
{
  my $entityType = shift;
  my $entityName = shift;

  my @cmd = ($CRSCTL, 'status' , $entityType, $entityName);
  my @out = executeCrsctlCmd(@cmd);
  my $rc  = shift @out;
  if (scalar(grep(/^CRS-/, @out)))
  {
    trace("$entityType = $entityName does not exist");
    return FALSE;
  }
  else
  {
    return TRUE; #no errors
  } 
}

#check if resource already exists
sub resourceExistsCheck
{
  my $resName = shift;

  if (checkIfEntityExists('resource', $resName))
  {
    fatalError("Resource '$resName' already exists");
  }
}

#check if resource group already exists
sub resourceGroupExistsCheck
{
  my $rgName = shift;

  if (checkIfEntityExists('resourcegroup', $rgName))
  {
    fatalError("Resource Group '$rgName' already exists");
  }
}

#create temporary filename for the entity
sub tmpFileName
{
  my $suffix = shift;

  if ($OSNAME eq 'MSWin32')
  {
    return $ENV{'TEMP'} . "\\$suffix.attrs";
  }
  else
  {
    return "/tmp/$suffix.attrs";
  }
}

#create a resource group type
sub createResourceGroupType
{
  my $typeName = shift;
  my $baseType = shift;
  my $fileName = shift;

  my @cmd = ($CRSCTL, 'add' , 'resourcegrouptype', $typeName, '-basetype', 
             $baseType, '-file', $fileName);
  my @out = executeCrsctlCmd(@cmd);
  my $rc  = shift @out;
  if (scalar(grep(/^CRS-/, @out)))
  {
    if (scalar(grep(/^CRS-33728/, @out)))
    {
      print "Warning! Trying to reuse existing type '$typeName'\n";
    }
    else
    {
      fatalError("Failed to create resource group type '$typeName'\n@out");
    }
  }
}

#create a resource type
sub createResourceType
{
  my $typeName = shift;
  my $baseType = shift;
  my $fileName = shift;

  my @cmd = ($CRSCTL, 'add' , 'type', $typeName, '-basetype', 
             $baseType, '-file', $fileName);
  my @out = executeCrsctlCmd(@cmd);
  my $rc  = shift @out;
  if (scalar(grep(/^CRS-/, @out)))
  {
    if (scalar(grep(/^CRS-2728/, @out)))
    {
      print "Warning! Trying to reuse existing type '$typeName'\n";
    }
    else
    {
      fatalError("Failed to create resource type '$typeName'\n@out");
    }
  }
}

#create a resource group
sub createResourceGroup
{
  my $rgName    = shift;
  my $rgType    = shift;
  my $fileName  = shift;

  my @cmd = ($CRSCTL, 'add' , 'resourcegroup', $rgName, '-type', $rgType,
             '-file', $fileName, '-f');
  my @out = executeCrsctlCmd(@cmd);
  my $rc  = shift @out;
  if (scalar(grep(/^CRS-/, @out)))
  {
    fatalError("Failed to create resource group '$rgName'\n@out");
  }
}

#create a resource 
sub createResource
{
  my $rName    = shift;
  my $rType    = shift;
  my $fileName = shift;

  my @cmd = ($CRSCTL, 'add' , 'resource', $rName, '-type', $rType,
             '-file', $fileName, '-f');
  my @out = executeCrsctlCmd(@cmd);
  if (scalar(grep(/^CRS-/, @out)))
  {
    fatalError("Failed to create resource '$rName'\n@out");
  }
}

# Runtime variables
my $typeFileName;
my $resFileName;
my $fh;

#****************************************************************************
# MAIN SCRIPT BODY
# ***************************************************************************
#
checkCrs;
$ENV{'ORA_CRSCTL_UNSUPPORTED_FLAG'} = 'true';
#
# The rest of the script is generated by 'crsctl export' command
# EDIT TO CUSTOMIZE
