Earlier this month at EMC World the new Unity storage array was unveiled. There are some cool new features with this product and the architecture is a bit different from the VNX. I like to experiment in my home lab and especially with PowerShell and REST APIs. So when I heard a Unity VSA would be available including the EMC Unity REST API. I was waiting for the EMC World release so I could get my hands on it.
I downloaded the EMC Unity VSA and set it up the first day of EMC World, then started some initial testing with the Unity REST API and PowerShell. I quickly found some distinct differences in the API when compared to the Isilon and XtremIO API’s. The first difference is the authentication mechanism which took some time to figure out. I found some quirks with the PowerShell Invoke-RestMethod and Invoke-WebRequest cmdlets. These cmdlets did not provide enough control over the web requests so I had to resort to creating my own with the .NET framework.
The EMC Unity REST API uses basic authentication via a request header, but also uses login session cookies. While trying to get this working I found I needed to use the .NET class System.Net.HttpWebRequest object for greater control. The two problems I had with the PowerShell cmdlets was the inability to control auto redirect and use request cookies. The use of request cookies is required to maintain session after initial login. The data required to create one of the cookies was returned in a response after an auto redirect so this had to be turned off to capture the information successfully.
The two cookies which have to be captured during the login process are MOD_AUTH_CAS_S and mod_sec_emc which are then used in all subsequent requests to the API. There are also a couple of additional cookies which are passed back and forth during the authentication process. I created a couple of functions to complete the login process, one of which is a recursive function which handles the auto redirects and collects the required login session cookies into global variables. The complete code is more than makes sense to show in this post, but the below example shows the main elements of building the request. This code is called recursively and collects the required session information to be passed in subsequent requests.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$URI = $Response.Headers.Item('Location') $Cookies = New-Object -TypeName System.Net.CookieContainer If($Global:JSESSIONID){$Cookies.Add($Global:JSESSIONID)} If($Global:CASTGC){$Cookies.Add($Global:CASTGC)} If($Global:mod_sec_emc){$Cookies.Add($Global:mod_sec_emc)} If($Global:MOD_AUTH_CAS_S){$Cookies.Add($Global:MOD_AUTH_CAS_S)} If($Global:CASPRIVACY){$Cookies.Add($Global:CASPRIVACY)} $Request = [System.Net.HttpWebRequest]::Create($URI) $Request.CookieContainer = $Cookies $Request.AllowAutoRedirect = $false $Request.Accept = "application/json" $Request.ContentType = "application/json" $Request.Headers.Add("X-EMC-REST-CLIENT","true") $Request.Headers.Add('Authorization',"Basic $($EncodedPassword)") $NewResponse = $Request.GetResponse() |
Once the login process is complete and the required session cookies are collected data requests to the EMC Unity REST API can be issued. The below code is an example of issuing a request for system information.
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 |
$Cookies = New-Object -TypeName System.Net.CookieContainer If($Global:mod_sec_emc){$Cookies.Add($Global:mod_sec_emc)} If($Global:MOD_AUTH_CAS_S){$Cookies.Add($Global:MOD_AUTH_CAS_S)} $UriString = ($UriObject + "/instances/system?fields=id, name, model, platform, macAddress, isEULAAccepted") $URI = $Global:APIBaseUri + $UriString $DataRequest = [System.Net.HttpWebRequest]::Create($URI) $DataRequest.AllowAutoRedirect = $false $DataRequest.CookieContainer = $Cookies $DataRequest.Method = $Method $DataRequest.Accept = "application/json" $DataRequest.Headers.Add("X-EMC-REST-CLIENT","true") $DataRequest.Headers.Add('Authorization',"Basic $($EncodedPassword)") If($Global:EMC_CSRF_TOKEN){$DataRequest.Headers.Add('EMC-CSRF-TOKEN',$Global:EMC_CSRF_TOKEN)} $DataResponse = $DataRequest.GetResponse() if($DataResponse -ne $null) { $rs = $DataResponse.GetResponseStream(); [System.IO.StreamReader] $sr = New-Object System.IO.StreamReader -argumentList $rs; [string] $results = $sr.ReadToEnd(); Return ConvertFrom-Json $results } |
The above code also includes the header EMC_CSRF_TOKEN which is actually only required when doing a POST or DELETE. Another thing to notice in the code above is the use of the fields query string. The desired object properties to be returned must be specified using this method. The output is below.
1 2 3 4 5 6 |
id : 0 name : MLABUNT01 model : UnityVSA platform : Tungsten_SingleSP macAddress : 00:50:56:A3:15:C0 isEULAAccepted : True |
The EMC Unity REST API was a bit of a challenge to get started and took some time with fiddler to figure out. I will say though for the initial release, the API documentation was pretty good. Unity does seem pretty cool, easy to use, and it’s awesome to have the Unity VSA for experimentation. I will try to get some more comprehensive example code on GitHub soon.
Regards,
Dave