Active IQ Unified Manager Discussions
Active IQ Unified Manager Discussions
I'm going to be using WFA to create qtrees and CIFS shares in existing volumes that are using snapmirror replication. What I'd like to incorporate into my WFA workflow is creating a CIFS share on the destination qtree once it's created from replication. Has anyone done this or have ideas about the best way to go about getting it accomplished?
Thanks
Solved! See The Solution
Hi,
I have a few ideas for you, I think it would be possible to:
I think the first option is probably the simplest. Here is some base source code for the WFA command, would just need to be modified to add in a loop\wait until success or timeout.
Param( [Parameter(Mandatory = $True, HelpMessage = "The name or IP Address of the cluster")] [String]$ClusterName, [Parameter(Mandatory = $True, HelpMessage = "The name of the vserver")] [String]$VserverName, [Parameter(Mandatory = $True, HelpMessage = "The path of the directory to read")] [String]$Path, [Parameter(Mandatory = $False, HelpMessage = "The maximum number of ZAPI retry attempts")] [Int]$ZapiRetryCount ) #'------------------------------------------------------------------------------ #'Connect to the cluster #'------------------------------------------------------------------------------ Connect-WFACluster $ClusterName #'------------------------------------------------------------------------------ #'Create the command to read the directory. #'------------------------------------------------------------------------------ If(-Not($Path.StartsWith("/vol/"))){
If($Path.StartsWith("/")){
[String]$p = $path.substring(1, ($path.length -1))
[String]$Path = "/vol/$p"
}Else{
[String]$Path = "/vol/$Path"
}
} [String]$command = "Read-NcDirectory -Path ""$Path"" " If($ZapiRetryCount){ [String]$command += "-ZapiRetryCount $ZapiRetryCount " } [String]$command += "-VserverContext $VserverName -ErrorAction Stop" #'------------------------------------------------------------------------------ #'Read the directory to ensure it exists. #'------------------------------------------------------------------------------ Try{ Invoke-Expression -Command $command -ErrorAction Stop Get-WFALogger -Info -Message "Executed Command`: $command" Get-WFALogger -Info -Message "The directory ""$Path"" exists on vserver ""$VserverName""" }Catch{ Get-WFALogger -Info -Message $("Failed Executing Command`: $command. Error " + $_.Exception.Message) Throw "The Directory ""$Path"" does not exist on vserver ""$VserverName""" } #'------------------------------------------------------------------------------
/Matt
how about to start from here: (reading the guides and manuals)?
https://library.netapp.com/documentation/docweb/index.html?productID=62404&language=en-US
thanks
Hi,
That's certainly possible to do but it depends on how you have your environment configured. Assuming you are not using onbox SVM DR, here a few ideas and thoughts to consider:
Alternately what is also possible assuming you don't want to force a snapmirror update for the volume every time you create a CIFS share is to develop a workflow that would create your DR CIFS shares on a scheduled basis (based on your snapmirror schedule and RTO\RPO). For example you could have your WFA workflow that creates your production CIFS share also create an XML configuration file to be read by another workflow which runs on a scheduled basis every X hours, reads the XML then connects to your DR cluster\SVM and creates the CIFS share after normal snapmirror updates as per your schedule have run. If successful then DR CIFS share is created and the XML file is archived. If not the XML file remains queued for processing (until the volume snapmirror has completed).
There are some ideas for you. Let me know if you think they would work in your environment.
/Matt
Thanks for everyone's feedback. I've actually made some progress here. After the initial qtree and share are created in the workflow, I use NetApp's 'Transfer SnapMirror' command, and then proceed to create the CIFS on the destination. I tested in our lab and it works. But I'm thinking when the snapmirror transfer takes a longer period of time, the workflow will fail on the destination share creation due to the qtree not being replicated in time. Is there a way to build in a waiting period, such as 1 hour, after 'Transfer SnapMirror' is initiated so it has time to complete before the workflow attempts to create the CIFS on the destination qtree?
Update -
I added the following to the powershell script for creating the CIFS on the destination. This will wait an hour before execution, giving the replication time to complete:
Start-Sleep -s 3600
It would be optimal to be able to confirm if the snapmirror transfer is complete before proceeding to the next step in the workflow, to avoid wasting further time. If anyone has thoughts on how to accomplish this, please let me know.
Hi,
I have a few ideas for you, I think it would be possible to:
I think the first option is probably the simplest. Here is some base source code for the WFA command, would just need to be modified to add in a loop\wait until success or timeout.
Param( [Parameter(Mandatory = $True, HelpMessage = "The name or IP Address of the cluster")] [String]$ClusterName, [Parameter(Mandatory = $True, HelpMessage = "The name of the vserver")] [String]$VserverName, [Parameter(Mandatory = $True, HelpMessage = "The path of the directory to read")] [String]$Path, [Parameter(Mandatory = $False, HelpMessage = "The maximum number of ZAPI retry attempts")] [Int]$ZapiRetryCount ) #'------------------------------------------------------------------------------ #'Connect to the cluster #'------------------------------------------------------------------------------ Connect-WFACluster $ClusterName #'------------------------------------------------------------------------------ #'Create the command to read the directory. #'------------------------------------------------------------------------------ If(-Not($Path.StartsWith("/vol/"))){
If($Path.StartsWith("/")){
[String]$p = $path.substring(1, ($path.length -1))
[String]$Path = "/vol/$p"
}Else{
[String]$Path = "/vol/$Path"
}
} [String]$command = "Read-NcDirectory -Path ""$Path"" " If($ZapiRetryCount){ [String]$command += "-ZapiRetryCount $ZapiRetryCount " } [String]$command += "-VserverContext $VserverName -ErrorAction Stop" #'------------------------------------------------------------------------------ #'Read the directory to ensure it exists. #'------------------------------------------------------------------------------ Try{ Invoke-Expression -Command $command -ErrorAction Stop Get-WFALogger -Info -Message "Executed Command`: $command" Get-WFALogger -Info -Message "The directory ""$Path"" exists on vserver ""$VserverName""" }Catch{ Get-WFALogger -Info -Message $("Failed Executing Command`: $command. Error " + $_.Exception.Message) Throw "The Directory ""$Path"" does not exist on vserver ""$VserverName""" } #'------------------------------------------------------------------------------
/Matt
Hi,
Here is an "example" WFA command that will wait for a directory to exist (or until a timeout is exceeded). You can apply the same principle to a snapmirror update for the volume or you can just wait for the your snapmirror schedule to update the volume to the destination and use this command to wait for the Qtree you've created on production to replicate to your DR vserver. It really depends on your environment, it might be fine to invoke a snapmirror update for the entire volume (just to replicate the qtree) or your network team might disapprove of that happening more frequently than your agreed snapmirror schedule.
In the following example, the command will "attempt" to read a directory, if it fails, it will wait X seconds (defined by the $WaitInterval variable) until either the directory exists or the $TimeOut values is exceeded.
Source Code:
Param(
[Parameter(Mandatory=$true, HelpMessage="The Cluster name or IP Address")]
[String]$ClusterName,
[Parameter(Mandatory=$true, HelpMessage="The Vserver name")]
[String]$VserverName,
[Parameter(Mandatory=$True, HelpMessage="The junction path of the directory to read")]
[String]$Path,
[Parameter(Mandatory=$True, HelpMessage="The total Number of seconds to wait")]
[Long]$TimeOut,
[Parameter(Mandatory=$True, HelpMessage="The number of seconds to wait in between checks")]
[Long]$WaitInterval
)
#'------------------------------------------------------------------------------
Function Wait-ReadDirectory{
<#
.SYNOPSIS
This function verifies a directory exist or waits for it to be created within a specified timeout.
.DESCRIPTION
Checks if a directory exists or waits for it to be created and returns a boolean.
.PARAMETER
ClusterName Accepts a string containing the destination clusters name or IP Address.
.PARAMETER
VserverName Accepts a string containing the destination vserver hostname.
.PARAMETER
Path Accepts a string containing the junction path of the directory to check it exists.
.PARAMETER
TimeOut Accepts an integer containing the maximum number of seconds to wait for snapmirror operations.
.PARAMETER
WaitInterval Accepts an integer containing the maximum number of seconds to wait in between attempting to read the directory.
.EXAMPLE
Wait-ReadDirectory -VserverName vserver1 -Path "/vol/vol1/qtree1" -TimeOut 3600 -WaitInterval 30
#>
#---------------------------------------------------------------------------
[CmdletBinding()]
Param(
[Parameter(Position=0,
Mandatory=$True,
ValueFromPipeLine=$True,
ValueFromPipeLineByPropertyName=$True)]
[String]$VserverName,
[Parameter(Position=1,
Mandatory=$True,
ValueFromPipeLine=$True,
ValueFromPipeLineByPropertyName=$True)]
[String]$Path,
[Parameter(Position=2,
Mandatory=$True,
ValueFromPipeLine=$True,
ValueFromPipeLineByPropertyName=$True)]
[Long]$TimeOut,
[Parameter(Position=3,
Mandatory=$True,
ValueFromPipeLine=$True,
ValueFromPipeLineByPropertyName=$True)]
[Long]$WaitInterval
)
#'---------------------------------------------------------------------------
#'Wait for the directory to be created or until the timeout is exceeded.
#'---------------------------------------------------------------------------
[Long]$waited = 0
[Long]$timeWaited = $waited
[Bool]$exists = $False
Do{
#'------------------------------------------------------------------------
#'Read the directory to ensure it exists.
#'------------------------------------------------------------------------
[Long]$timeWaited += [Long]($waited + $waitInterval)
[String]$command = "Read-NcDirectory -Path ""$Path"" -VserverContext $VserverName -ErrorAction Stop"
Try{
Invoke-Expression -Command $command -ErrorAction Stop
Get-WFALogger -Info -Message "Executed Command`: $command"
Get-WFALogger -Info -Message "The junction path ""$Path"" exists on vserver ""$VserverName"""
[Bool]$exists = $True
}Catch{
[Bool]$exists = $False
Get-WFALogger -Info -Message $("Failed Executing Command`: $command. Error " + $_.Exception.Message + ". Waiting ""$WaitInterval"" seconds before retrying.")
}
If(($exists) -And ($timeWaited -le $timeOut) -And $timeOut -gt 0){
Break;
}
Start-Sleep -Seconds $waitInterval
}Until(($exists) -Or (($timeWaited -ge $timeOut) -And $timeOut -gt 0))
#'------------------------------------------------------------------------
#'Log the total time waited for the directory to be created.
#'------------------------------------------------------------------------
If(($exists) -And ($timeWaited -lt $timeOut)){
Get-WFALogger -Info -Message "Waited a total of ""$timeWaited"" seconds for the junction path ""$Path"" to exist on vserver ""$VserverName"""
}
#'---------------------------------------------------------------------------
#'Raise an error if the timeout is exceeded.
#'---------------------------------------------------------------------------
If(($timeWaited -ge $timeOut) -And ($timeOut -gt 0) -And ($exists -eq $False)){
Get-WFALogger -Error -Message "The junction path ""$Path"" does not exist on the destination vserver ""$VserverName"" within the timeout of ""$timeOut"" seconds"
}
Return $exists;
}#End Function
#'------------------------------------------------------------------------------
#'Connect to the cluster.
#'------------------------------------------------------------------------------
Connect-WfaCluster $ClusterName
#'------------------------------------------------------------------------------
#'Create the command to read the directory.
#'------------------------------------------------------------------------------
If(-Not($Path.StartsWith("/vol/"))){
If($Path.StartsWith("/")){
[String]$p = $path.substring(1, ($path.length -1))
[String]$Path = "/vol/$p"
}Else{
[String]$Path = "/vol/$Path"
}
}
#'------------------------------------------------------------------------------
#'Wait for the directory to exist on the destination vserver.
#'------------------------------------------------------------------------------
If(Wait-ReadDirectory -VserverName $VserverName -Path $Path -TimeOut $TimeOut -WaitInterval $WaitInterval){
Get-WFALogger -Info -Message "The junction path ""$Path"" on vserver ""$VserverName` exists."
}Else{
Throw "The path ""$Path"" on vserver ""$VserverName"" does not exist or reached the wait timeout of ""$TimeOut"" seconds"
}
#'------------------------------------------------------------------------------
When testing it, i connected to a CIFS share at the root of a volume, wait for a while then created the test directory folder (in your instance that will be a qtree that is created on the destination vserver via snapmirror replication)
Example output:
Hope this helps.
/Matt