New REST API’s for vVols Objects in Pure Storage FlashArray REST API 2.14

There are some new REST API’s for vVols objects in Pure Storage’s FlashArray REST API 2.14!  Specifically operations for virtual-machines and virtual-machine-snapshots. The hardest part for me was figuring out how to use REST 2.0 with the FlashArray. I had a lot of fun playing around and learning about them and want to share that process! 

For my examples in the post I am going to be using PowerShell to issue the REST calls by invoking web requests.

Authenticating with FlashArray for REST API 2.14 Requests

In order to issue REST Requests from PowerShell I first need to be able to get the authentication header constructed. I found a few ways that I could issue REST API 2.x requests. I cover those processes in this a blog post covering my journey and discovery. I’ll keep it simple and just use the Pure Storage PowerShell SDK to get my header constructed.

$flasharray = new-pfaarray -endpoint 10.21.149.39 -credentials (get-credential) -ignoreCertificateError
$ApiToken =@{"api-token"=$flasharray.ApiToken}
$AuthResponse = Invoke-webrequest -Method Post -Uri "https://$($flasharray.Endpoint)/api/2.2/login" -Headers $ApiToken -SkipCertificateCheck   
$AuthHeader = @{"x-auth-token" = ($AuthResponse.Headers."x-auth-token")[0]}

From this point forward all of my web requests will be using this $AuthHeader in the Invoke-WebRequest.

Virtual-Machines REST Call

When I was looking through the REST API release notes I noticed that we had added quite a bit of documentation for some new cals. I really recommend looking through the 2.14 reference guide if possible. It does require a support.purestorage.com account and login though. I specifically wanted to look at /api/2.14/virtual-machines and /api/2.14/virtual-machine-snapshots. I wanted to dig at what an end user could get from them. Starting with the virtual-machines, I want to find out what ends up getting returned back from it?

$faVMs = Invoke-WebRequest -Method Get -Uri "https://$flasharray/api/2.14/virtual-machines?vm_type=vvol" -Headers $AuthHeader -SkipCertificateCheck
$faVMs
PS C:\Users\alex> $faVMs = Invoke-WebRequest -Method Get -Uri "https://$flasharray/api/2.14/virtual-machines?vm_type=vvol" -Headers $AuthHeader -SkipCertificateCheck
PS C:\Users\alex> $faVMs

StatusCode        : 200
StatusDescription : OK
Content           : {"continuation_token":null,"items":[{"created":1620680626452,"vm_id":"500d8e95-237f-263b-1a31-f5409ef4da39","name":"vvol-w2k16-no-cbt-b-3","id":"500d8e95-237f-263b-1a31-f5409ef4da39","time_remaining":…
RawContent        : HTTP/1.1 200 OK
                    Server: nginx
                    Date: Mon, 15 Aug 2022 22:49:35 GMT
                    Connection: keep-alive
                    Strict-Transport-Security: max-age=31536000; includeSubDomains;
                    X-Frame-Options: DENY
                    X-Content-Type-Opti…
Headers           : {[Server, System.String[]], [Date, System.String[]], [Connection, System.String[]], [Strict-Transport-Security, System.String[]]…}
Images            : {}
InputFields       : {}
Links             : {}
RawContentLength  : 4078
RelationLink      : {}

Right away that’s a lot of not much that I can use. So I played around with selecting specific sections of that call and then converting from JSON to something readable. That’s why I set the initial output to $faVMs. Test out some different forms of selecting and converting the data. Here was kind of my progression through it.

$faVMs
$faVMs.content
$faVMs.content | convertfrom-json
($faVMs.content | convertfrom-json).items

Here is just what it looked like when selecting the items on that last line.

($faVMs.content | convertfrom-json).items

created         : 1620680626452
vm_id           : 500d8e95-237f-263b-1a31-f5409ef4da39
name            : vvol-w2k16-no-cbt-b-3
id              : 500d8e95-237f-263b-1a31-f5409ef4da39
time_remaining  : 
destroyed       : False
vm_type         : vvol
recover_context : @{name=; id=}

created         : 1655305922937
vm_id           : 500d9a18-d4eb-9648-46a9-43503caa6c85
name            : c05-vVol-DB-VM-01
id              : 500d9a18-d4eb-9648-46a9-43503caa6c85
time_remaining  : 
destroyed       : False
vm_type         : vvol
recover_context : @{name=; id=}

created         : 1620681512770
vm_id           : 500de701-15ec-2ab8-9843-58564ec95f84
name            : vvol-w2k16-nor-b-3
id              : 500de701-15ec-2ab8-9843-58564ec95f84
time_remaining  : 
destroyed       : False
vm_type         : vvol
recover_context : @{name=; id=}

I cut it off after a few VMs. As you can see, it can get pretty overwhelming fast. Playing around with a bit more and I came up with this as an easy way to find the vms.

($faVMs.content | convertfrom-json).items | Select-Object Name, vm_id, destroyed
($faVMs.content | convertfrom-json).items | Select-Object Name, vm_id, destroyed

name                  vm_id                                destroyed
----                  -----                                ---------
vvol-w2k16-no-cbt-b-3 500d8e95-237f-263b-1a31-f5409ef4da39     False
c05-vVol-DB-VM-01     500d9a18-d4eb-9648-46a9-43503caa6c85     False
vvol-w2k16-nor-b-3    500de701-15ec-2ab8-9843-58564ec95f84     False
vvol-w2k16-no-cbt-b-4 50126c72-a347-6a3d-517a-c5c588e7a6ca     False
vvol-load-vm-b-2      50385376-475b-7094-d837-8f00578cdf90     False
vvol-w2k16-res-b-1    50387c83-4c42-eaa6-da86-5651b518dc17     False
vvol-w2k16-nor-b-1    5038868e-f4d6-4f91-67e3-f2dde5a63d50     False
vvol-w2k16-no-cbt-b-1 50389bdd-8787-ad28-4c54-2adcb66f9346     False
vvol-w2k16-light-b-1  5038b0a4-10b3-4619-41c2-0611c5087af4     False
vvol-w2k16-cbt-b-1    5038e5ad-3c45-25e6-ec27-f2f97406cc5e     False
vVol-VM-LOAD-B        5038f4eb-5016-4f96-1ddc-60aebee9e09e     False
MSSQL-VM-02           5039814f-113e-8e1f-f678-be7bcbe2a001     False
vvol-w2k16-no-cbt-b-2 5039ab78-91f8-f257-2bda-a52b3eb0b37e     False
vvol-w2k16-tiny-b-2   5039d9b7-3567-f2b8-593d-26e2a2309d73     False
.vSphere-HA           ffff0000-2da8-8e2f-9e28-e3b15939db0f     False
catalog               ffff0000-bac9-fe86-e118-f92e309b7641     False

From there I can do more filtering, sorting, etc. However, I want to go ahead and move on to the snapshots.

Virtual-Machine-Snapshots REST CALL

After playing around with virtual-machines I started to play around with virtual-machine-snapshots. At first the content was pretty overwhelming and depending on the scale of the environment it could be even more.

$vmSnaps = Invoke-WebRequest -Method Get -Uri "https://$flasharray/api/2.14/virtual-machine-snapshots?vm_type=vvol" -Headers $AuthHeader -SkipCertificateCheck
$vmSnaps
$vmSnaps.content
$vmSnaps.content | ConvertFrom-Json
($vmSnaps.content | ConvertFrom-Json).items

I actually ended up running out of scroll back with some of my arrays. Just too many VM snapshots stored over a long period of time. Here is just a small look at what the formatted items look like.

($vmSnaps.content | ConvertFrom-Json).items

created         : 1660590060018
vm_id           : 500d0e5a-6bfb-5dda-b558-c3b3a47fb978
name            : MSSQL-VM-01
id              : 500d0e5a-6bfb-5dda-b558-c3b3a47fb978
time_remaining  : 
destroyed       : False
vm_type         : vvol
recover_context : @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.805; id=116aaf8d-cc56-1c67-279b-40141bbb6088}

created         : 1660564860022
vm_id           : 500d0e5a-6bfb-5dda-b558-c3b3a47fb978
name            : MSSQL-VM-01
id              : 500d0e5a-6bfb-5dda-b558-c3b3a47fb978
time_remaining  : 
destroyed       : False
vm_type         : vvol
recover_context : @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.798; id=ecfcf700-1d20-e119-ba61-5a8501bb247b}

created         : 1660539660023
vm_id           : 500d0e5a-6bfb-5dda-b558-c3b3a47fb978
name            : MSSQL-VM-01
id              : 500d0e5a-6bfb-5dda-b558-c3b3a47fb978
time_remaining  : 
destroyed       : False
vm_type         : vvol
recover_context : @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.791; id=bc8028dd-80d8-0791-58f3-51495bbf2516}

I ended up needing to play around a lot with filtering, selecting the right objects and sorting. Here I just went ahead an listed out the name, vm_id and recover_context.

($vmSnaps.Content | ConvertFrom-Json).items | Select-Object Name, recover_context

name                 recover_context
----                 ---------------
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.661; id=6d3829c7-74f0-917f-91d2-d6864401e98b}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.786; id=a0523f9a-39a2-da48-8961-4688ef901c40}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.745; id=c457003f-4321-7d39-9d5c-457a80cda3f1}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.619; id=8db11afa-79ca-39d4-e901-3652c2cd49d6}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.804; id=eaefa2fe-5ee3-a9b2-7aa1-bbb42b1ca7e2}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.797; id=72ddcb8a-925b-5d45-38b4-3e1a7260b394}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.727; id=b9fa6de0-2532-9670-084a-40b0c7a2ad67}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.790; id=76e6c359-b5b1-00ad-f453-c0053e9b54e5}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.685; id=fcd9a995-a3d6-69e1-9636-316b63a77bfb}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.769; id=64aadecb-5fee-df11-dcad-2cf9c05ece17}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.643; id=2dc491fe-9406-777f-d6eb-889cac5dcfc9}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.baseline-powered-on; id=0ca0b803-c16c-1bdd-c90e-bab98b175f50}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.808; id=fa728001-3de9-126a-aa0f-836a219510c8}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.801; id=45f866c7-b6f0-e0ca-2c53-bf90dd175088}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.794; id=33765419-2366-63ec-810f-0f7bc50146fd}
MSSQL-VM-01          @{name=sn1-x70-b05-33:vvols-mssql-replication-1-hour-01.709; id=e5fed2b3-9c8a-4689-7163-7d4d2399daa2}
MSSQL-VM-02          @{name=vvols-mssql-replication-1-hour-02.799; id=b2ce4252-46d4-a27d-9d2b-2b63b9222305}

Overall it’s a lot of data and I found that filtering out by VM was for sure the easiest way to have it be something useful.

Putting it all Together!

Putting all of that together here is what I came up with!

$faVMs = Invoke-WebRequest -Method Get -Uri "https://$flasharray/api/2.14/virtual-machines?vm_type=vvol" -Headers $AuthHeader -SkipCertificateCheck

$vmid = (($faVMs.Content | ConvertFrom-Json).items | where-object {$_.name -eq "MSSQL-VM-02"}).vm_id

$vmSnapshots = Invoke-WebRequest -Method Get -Uri "https://$flasharray/api/2.14/virtual-machine-snapshots?vm_type=vvol&filter=vm_id='$vmid'" -Headers $AuthHeader -SkipCertificateCheck
($vmSnapshots.content | ConvertFrom-Json).items

($vmSnapshots.content | ConvertFrom-Json).items |Sort-Object -Property Created
$faVMs = Invoke-WebRequest -Method Get -Uri "https://$flasharray/api/2.14/virtual-machines?vm_type=vvol" -Headers $AuthHeader -SkipCertificateCheck

$vmid = (($faVMs.Content | ConvertFrom-Json).items | where-object {$_.name -eq "MSSQL-VM-02"}).vm_id

$vmSnapshots = Invoke-WebRequest -Method Get -Uri "https://$flasharray/api/2.14/virtual-machine-snapshots?vm_type=vvol&filter=vm_id='$vmid'" -Headers $AuthHeader -SkipCertificateCheck
($vmSnapshots.content | ConvertFrom-Json).items

($vmSnapshots.content | ConvertFrom-Json).items |Sort-Object -Property Created

----

created         : 1660605450010
vm_id           : 5039814f-113e-8e1f-f678-be7bcbe2a001
name            : MSSQL-VM-02
id              : 5039814f-113e-8e1f-f678-be7bcbe2a001
time_remaining  : 
destroyed       : False
vm_type         : vvol
recover_context : @{name=vvols-mssql-replication-1-hour-02.800; id=3bc97095-4cf7-b27c-b3d1-a2890487c80c}

created         : 1660605450010
vm_id           : 5039814f-113e-8e1f-f678-be7bcbe2a001
name            : MSSQL-VM-02
id              : 5039814f-113e-8e1f-f678-be7bcbe2a001
time_remaining  : 
destroyed       : False
vm_type         : vvol
recover_context : @{name=vvols-mssql-replication-1-hour-02.800; id=3bc97095-4cf7-b27c-b3d1-a2890487c80c}

That got me a very simple output for the two snapshots that existed on this array for the vm ‘MSSQL-VM-02’. I can create some nice outputs which include what VMs are on the array, what their vm_id is and if it’s destroyed. Then you can also use that same kind of workflow to find out what source or target vm snapshots are there.

In the end this is the exact API that we needed to create to make the vSphere Remote Plugin’s VM Undelete workflow work correctly. In addition to that, we were also able to get the Point in Time Revert and Point in Time undelete to work because of these APIs! It’s super exciting stuff from the engineering teams at Pure!

Posted in PowerCLI, PowerShell, Virtual Volumes, VMware and tagged , , , , .

Leave a Reply

Your email address will not be published. Required fields are marked *