NetApp’s Workflow Automation (WFA) tool is a valuable asset for providing easily consumed scriptable tasks to perform nearly any function that storage administrators require. For administrators who want to get out of the business of doing mundane tasks, like provisioning generic volumes, adjusting volume sizes, etc., WFA gives you the ability to surface those operations to storage consumers and have them do the work for themselves.
WFA can also play a part in a larger scheme of workflows that can be orchestrated by other software, for example VMware’s vCAC, Puppet, Chef, Microsoft Orchestrator, etc. This leaves the power (and details) of how to automate the task with the storage team, but enables the IT organization to leverage storage resources in a programmatic manner. This is done using the REST interface.
To access the REST interface, simply browse to your WFA server, but instead of “http://your_wfa_host/wfa
” for the URL, use “http://your_wfa_host/rest/docs
“, which will bring you to the documentation for the rest interface.
If you are prompted for credentials, use the same username/password combination you would normally use to connect to WFA. You can select resources, such as workflows, which will then provide the documentation for how to interact with workflow.
As you can see in the screenshot above, we have a “/workflows
” url (which the full URL would be http://your_wfa_host/rest/workflows
), which can be called using the GET method. This will return a list of all of the workflows available. Optionally, a name parameter can be passed which will search for workflows that match the name provided. Let’s try this using the “Create a Clustered Data ONTAP Volume” workflow, a part of the base WFA install.
The above screenshot is of the XML returned from the REST query. I’ve collapsed some of the input and return parameters to show the bottom part of the result, which provides links to the URLs for executing the workflow. Going back to our documentation, let’s look at what it says about the jobs action…
It is expected to be called via a POST method, with the content being the workflowInput XML. This XML is defined by following the link provided, which shows an example:
So, what have we learned so far?
- The WFA rest interface is accessible at
http://your_wfa_host/rest
- The workflows can be searched by name using the url template
http://your_wfa_host/rest/workflows?name=some%20workflow%20name
- Once the workflow is found, the response contains the REST url for executing the workflow, which should be called using a POST operation in the workflowInput XML format
What happens when we execute a WFA workflow using REST? Well, assuming the inputs are valid, once the /rest/{workflow_uuid}/jobs
URL has been successfully invoked a JobRepresentation
will be returned. This contains, among other things, the jobId
for the workflow execution that was just requested.
By requesting, using the GET
method, the URL for the job status we can determine when the workflow has finished execution. The URL template for this is: http://your_wfa_host/rest/workflows/{workflow_uuid}/jobs/{job_id}
. Now, by periodically checking this url, we can determine when WFA has finished execution.
Let’s put this all together using Powershell (version 4 has native cmdlets for executing REST):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# # This script uses Powershell Version 4's native REST cmdlets to execute a WFA workflow # Any workflow can be executed using the below method, the inputs and outputs will have to be adjusted accordingly # # WFA server and credentials $WFAserver = "http://your.wfa.host/rest" $username = "admin"; $password = "********"; # these must match the names of the workflow inputs exactly (case sensitive!) $restParams = @{ "ClusterName" = "cluster1"; "VserverName" = "svm1"; "VolumeName" = "REST_test"; "VolumeSizeInGB" = 1; } # #### end of inputs #### # # the name of the workflow $workflowToExecute = "Create a Clustered Data ONTAP Volume" # a quick function to turn the hash into WFA friendly XML function generateWfaInputXml( $inputs ) { $xml = "`n" $xml += '' $inputs.keys | %{ $xml += '' } $xml += '' return $xml } # convert the username/password into a credential object $credential = New-Object System.Management.Automation.PSCredential ($username, (ConvertTo-SecureString $password -AsPlainText -Force)) # first let's get the execution URL [xml]$workflowXML = Invoke-RestMethod -Method Get -Credential $credential -Uri "$WFAserver/workflows" -body @{ name = $workflowToExecute; } # extract the UUID $workflowUuid = $workflowXML.collection.workflow.uuid # use the UUID to construct the execution URL $workflowExecutionUrl = "$WFAserver/workflows/$workflowUuid/jobs" # convert the input to the expected format $restInput = generateWfaInputXml($restParams) # execute the workflow [xml]$executionXML = Invoke-RestMethod -Method Post -Credential $credential -Uri $workflowExecutionUrl -body $restInput -ContentType "application/xml" # extract the job id $jobId = $executionXML.job.jobId $statusUri = "$($workflowExecutionUrl)/$($jobId)" # monitor for execution status $completed = $false $checkCount = 0 while ($completed -eq $false -and $checkCount -le 20) { # check on the status of the job [xml]$jobXML = Invoke-RestMethod -Method Get -Credential $credential -Uri $statusUri switch ($jobXML.job.jobStatus.jobStatus) { # the job is not finished, check again in a few seconds {$_ -match "EXECUTING|RUNNING|PENDING|SCHEDULED|PLANNING"} { $completed = $false $checkCount++ Write-Host "Job not completed ($($jobXML.job.jobStatus.jobStatus)), sleeping. This is iteration number: $($checkCount) of 20" Start-Sleep -Seconds 15 } # it's done, let's gather some output params to provide info "COMPLETED" { $completed = $true $createdOnNode = ($jobXML.job.jobStatus.returnParameters.returnParameters | ?{ $_.key -eq "NodeName"}).value $createdOnAggr = ($jobXML.job.jobStatus.returnParameters.returnParameters | ?{ $_.key -eq "AggregateName"}).value Write-Host "Volume was created on node $($createdOnNode) using aggregate $($createdOnAggr)" } # something unknown happened! DEFAULT { $completed = $true Write-Error "A strange status was returned: $($jobXML.job.jobStatus.jobStatus). Exiting!" } } } if ($checkCount -ge 20 -and $completed -eq $false) { Write-Error "Job was not finished after 5 minutes of waiting." } |
The above script is about 90 lines, but has some customization specific to the NetApp WFA workflow we are executing (“Create a Clustered Data ONTAP Volume”). For example, I’m using the returned parameters from WFA to provide information back to the console. The majority of the code can be reused to execute any WFA workflow using REST.
Questions and comments are always welcome below. If you have any suggestions for, or need help with, NetApp/VMware integration, automation, and solutions, please let me know using the comments!
$WFAserver = “http://your.wfa.host/rest”
is this syntax is correct? i am not able execute
“Could you please help me on this issue i am not able to call the server getting error here
first let’s get the execution URL
[xml]$workflowXML = Invoke-RestMethod -Method Get -Credential $credential -Uri “$WFAserver/workflows” -body @{ name = $workflowToExecute; }
Invoke-RestMethod : The remote server returned an error: (404) Not Found.
At line:2 char:21
+ [xml]$workflowXML = Invoke-RestMethod -Method Get -Credential $credential -Uri ” …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand”
Hello Raju,
First, thank you for reading!
Please make sure you change the string “your.wfa.server” to the hostname or IP address of your WFA server. Also, I have not tested when using workflows which have special characters in the name, so that could also cause an issue.
If that is correct, you can validate the URL by browsing to “http://wfa_server_hostname_or_IP>/rest/workflows”, which should give you a listing of all workflows on the server. Do a search of the page for the workflow name to make sure it appears.
If you continue to have problems, let me know!
Andrew
Hi Andrew,
When I run this script for the first time, I get (505) Http Version Not Supported error when invoking workflow via Invoke-RestMethod.
I have posted more details of this in NetApp WFA Community.
Do you have any idea ?
http://community.netapp.com/t5/OnCommand-Storage-Management-Software-Discussions/505-Http-Version-Not-Supported-error-when-invoking-workflow-via-Invoke/m-p/105894#U105894
Regards
adai
Hello Adai,
I have responded to your post on the NetApp Communities site. Hopefully that helps.
V/r,
Andrew