Pure Storage REST API + Windows PowerShell (Part 2)

In my Part 1 post I discussed the basics of how to use the REST API with the Post method to authenticate and establish a session then using the Get method retrieve volume information, controller and space details. The focus of this article is implementing what I consider a step toward the Pure Storage PowerShell Tool Kit (PPTK). The core functions I have implemented are to connect and disconnect to the FlashArray, create snapshots, create new volumes from scratch or from snapshots and connecting volumes to existing hosts.

Let’s start off by connecting to the array using the Connect-PfaController function. This function takes in the FlashArray IP address or name. The –Username and –Password parameters are optional and default to the FlashArray’s single purpose account for performing actions. If you have enabled Directory Service on the FlashArray you can pass the $env:USERNAME and $env:SESSIONNAME to login with Active Directory; look for another future post on setting up Directory Service using the REST API soon (hmmm Part 3 maybe). I use of “Pfa” which stands for Pure FlashArray to denote that the cmdlet is for Pure Storage.

Function Connect-PfaController() {
    [CmdletBinding()]
    Param(
	    [Parameter(Mandatory=$True)][ValidateNotNullOrEmpty()][string] $FlashArray,
	    [Parameter()][ValidateNotNullOrEmpty()][string] $Username = "pureuser",
	    [Parameter()][ValidateNotNullOrEmpty()][string] $Password = "pureuser"
    )
    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
    $AuthAction = @{
        password = $Username
        username = $Password
    }
    Write-Host $AuthAction.Values
    $ApiToken = Invoke-RestMethod -Method Post -Uri "https://$FlashArray/api/1.2/auth/apitoken" -Body $AuthAction
 
    $SessionAction = @{
        api_token = $ApiToken.api_token
    }
    Invoke-RestMethod -Method Post -Uri "https://$FlashArray/api/1.2/auth/session" -Body $SessionAction -SessionVariable Session
    $Global:Session = $Session
    Invoke-RestMethod -Method Get -Uri "https://$FlashArray/api/1.2/array" -WebSession $Session | Format-Table -AutoSize
}

Just as your parents always told you clean-up after yourself so with a Connect method always comes a Disconnect method. This will disconnect the current session with the FlashArray.

Function Disconnect-PfaController() {
    [CmdletBinding()]
    Param(
	    [Parameter(Mandatory=$True)][ValidateNotNullOrEmpty()][string] $FlashArray
    )
    Invoke-RestMethod -Method Delete -Uri "https://${FlashArray}/api/1.2/auth/session" -WebSession $Session
}

Now we have the core connection functionality created we can begin using the WebSession with the FlashArray to perform some useful actions like taking snapshots, creating volumes and such. The first action to perform is to create a snapshot using the New-PfaSnapshot function which takes several parameters. I implemented this function and others to call the Connect-PfaController to make the connection as part of the request then disconnect when completed. There really isn’t a need to only connect to the FlashArray without performing an action. When the connection is made to the FlashArray the Session is stored in a Global:Session variable.

REST_API_Part2_New-PfaSnapshot_Params

Function New-PfaSnapshot() {
    [CmdletBinding()]
    Param(
	    [Parameter(Mandatory=$True)][ValidateNotNullOrEmpty()][string] $FlashArray,
        [Parameter(Mandatory=$True)][ValidateNotNullOrEmpty()][string] $SnapshotVolume,
        [Parameter(Mandatory=$True)][ValidateNotNullOrEmpty()][string] $SnapshotSuffix
    )
    $Snapshot = $null
    $Snapshot = [ordered]@{
        snap = "true"
        source = [Object[]]"$SnapshotVolume"
        suffix = $SnapshotSuffix
    } | ConvertTo-Json
    Connect-PfaController -FlashArray $FlashArray
    Invoke-RestMethod -Method Post -Uri "https://$FlashArray/api/1.2/volume" -Body $Snapshot -WebSession $Session -ContentType "application/json"
    Disconnect-PfaController -FlashArray $FlashArray
}

Use example
New-PfaSnapshot -FlashArray 0.0.0.0 -SnapshotVolume “SAMPLE” -SnapshotSuffix ([Guid]::NewGuid())

REST_API_Part2_New-PfaSnapshot

Next is the New-PfaVolume function to create new volumes from scratch just using a name and size. The size needs to be in the format of S, K. M, G, T or P; in the use example I create a 500MB volume using the –Size 500M. I tried to account for the different variations of how the REST API can be used to create a new volume or a new volume based on a source volume. The one TODO I have is to support our Overwrite parameter which allows for an existing volume to be overwritten.

Function New-PfaVolume() {
    [CmdletBinding()]
    Param(
	    [Parameter(Mandatory=$True)][ValidateNotNullOrEmpty()][string] $FlashArray,
        [Parameter(Mandatory=$True)][ValidateNotNullOrEmpty()][string] $Name,
        [Parameter()][ValidateNotNullOrEmpty()][string] $Size = $null,
        [Parameter()][ValidateNotNullOrEmpty()][string] $Source = $null
        #TODO: Add Overwrite support.
    )
    $Volume = $null
    If($Source) {
        $Volume = @{
            source = $Source
        } | ConvertTo-Json
    } Else {
        $Volume = @{
            size = $Size
        } | ConvertTo-Json
    }

    Connect-PfaController -FlashArray $FlashArray
    Invoke-RestMethod -Method Post -Uri "https://$FlashArray/api/1.2/volume/$Name" -Body $Volume -WebSession $Session -ContentType "application/json"
    Disconnect-PfaController -FlashArray $FlashArray
}

Use examples
Create a new volume called SAMPLE5 of the size 1TB:
New-PfaVolume -FlashArray 10.21.8.82 -Name “SAMPLE5” -Size 1T

REST_API_Part2_New-PfaVolume2

Create a new volume SAMPLE4 based on the source volume SAMPLE1:
New-PfaVolume -FlashArray 10.21.8.82 -Name “SAMPLE6” -Source “SAMPLE1”

REST_API_Part2_New-PfaVolume1

Depending on whether a new volume was created from an existing or from scratch it needs to be connected to a host. This function is implemented with the requirement of knowing what hosts are available which is somewhat limiting but will have to suffice for now.

Function Get-PfaHosts() {
    [CmdletBinding()]
    Param(
	    [Parameter(Mandatory=$True)][ValidateNotNullOrEmpty()][string] $FlashArray
        #TODO: Add All parameter support.
        #TODO: Add Chap parameter support.
        #TODO: Add Personality parameter support.
        #TODO: Add Space parameter support.
    )

    Connect-PfaController -FlashArray $FlashArray
    Invoke-RestMethod -Method Get -Uri "https://$FlashArray/api/1.2/host" -WebSession $Session -ContentType "application/json" | Format-Table -AutoSize
    Disconnect-PfaController -FlashArray $FlashArray
}

Use example
Connect-PfaHost -FlashArray 10.21.8.82 -HostName MEMPHIS -Volume SAMPLE5

REST_API_Part2_Connect-PfaHost

Next article (Part 3?) I’ll expand on the Pure PowerShell Tool Kit and add support for more REST APIs.

Ping me @purepowershell if you have any questions or just leave a comment.

Cheers,
barkz