In my venture to learn new things and languages, I’ve decided to take a look at consuming RESTful APIs in a few different languages. For those just joining, I’ve already gone over how to do this with RestClient and Ruby – so for today, let’s take that same example of adding a VM to a Rubrik SLA Domain and see what we can’t do in c#. The code involved may vary a little bit depending on what scripting environment you are using so keep that in mind. This go around I’ve decided to use Visual Studio Code – which does require a little bit of pre-work with the setup which I have completely documented here – so if you are new to VS Code, be sure to go through those steps first.
Stop fighting squigglies on your own!
There is one more pre-requisite that will make our lives a little easier involving RESTful APIs and c# – and that is the NewtonSoft JSON package! Don’t fight those squiggly brackets on your own – use this package to help manipulate some of that stuff 🙂 To get this installed we will use that the NuGet package. After you have your project setup, simply hit the F1 key to bring up the command palette. Begin typing NuGet, and select the NuGet Package Manager: Add Package option.
From the next prompt, enter in ‘Newtonsoft’ to filter our available packages, then select the ‘Newtonsoft.Json’ package to add it to our projects reference assemblies.
Show Me The Code!
With JSON support set up we are good to start looking at some code – With Ruby it was easy enough to break out different portions of the code and explain them – however, due to the layout and whatnot of c# I find it easier to simply show all of the code first, and I’ll explain some of the functionality after – so without further ado, the code!
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 |
using System; using System.Net; using System.IO; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace c_examples { classProgram { public const string username = "mike.preston@rubrik.us"; public const string password = "SuperSecret"; public static String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username+":"+password)); public static JObject responseToJSON (WebResponse wr) { var response = (HttpWebResponse)(wr); StreamReader sr = newStreamReader(response.GetResponseStream()); var re = sr.ReadToEnd(); var dobject = JsonConvert.DeserializeObject(re.ToString()); var jobj = (JObject) dobject; return jobj; } static void Main(string[] args) { ServicePointManager.ServerCertificateValidationCallback+= (sender, cert, chain, sslPolicyErrors) =>true; var vmname = "MPRESTON-VM1"; var slaname = "Gold"; var request = (HttpWebRequest) WebRequest.Create("https://192.168.150.111/api/v1/vmware/vm?name="+vmname ); request.Method = "GET"; request.Headers.Add("Authorization", "Basic "+encoded); var response = (HttpWebResponse)request.GetResponse(); JObject jo = responseToJSON(response); var vmid = jo["data"][0]["id"]; request= (HttpWebRequest) WebRequest.Create("https://192.168.150.111/api/v1/sla_domain?name="+slaname); request.Method="GET"; request.Headers.Add("Authorization", "Basic "+encoded); response= (HttpWebResponse) request.GetResponse(); jo = responseToJSON(response); var slaid = jo["data"][0]["id"]; request = (HttpWebRequest) WebRequest.Create("https://192.168.150.111/api/v1/vmware/vm/"+vmid); request.Method ="PATCH"; request.Headers.Add("Authorization", "Basic "+encoded); string body = "{\"configuredSlaDomainId\":\""+slaid+"\"}"; byte[] byteArray = Encoding.UTF8.GetBytes(body); request.ContentLength = byteArray.Length; Stream dataStream = request.GetRequestStream(); dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Close(); response = (HttpWebResponse) request.GetResponse(); } } } |
Alright, there’s a lot to get through here so let’s break it down! Lines 1 through 6 simply include the assembly references that we want to use within the script – pretty easy stuff thus far! 🙂
1 2 3 4 5 6 |
using System; using System.Net; using System.IO; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Linq; |
Lines 11 and 12 just define our username and password that we will use to authenticate to the Rubrik API. Line 13 takes this information and base64 encodes it so we can use basic authentication within our API requests. We store these publically, outside of any functions as we will need to reuse these over and over.
1 2 3 |
public const string username ="mike.preston@rubrik.us"; public const string password ="SuperSecret"; public static String encoded =System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username+":"+password)); |
The function defined from Lines 14 through 22 is there to basically ease the amount of code we need to write. Since each request that we send will return a JSON formatted response, this function can be called rather than having to write code to parse each and every response. All this really does is read the response from the API request, and return a JSON object that we can easily search and move through to get the data we need.
1 2 3 4 5 6 7 8 9 |
public static JObject responseToJSON (WebResponse wr) { var response = (HttpWebResponse)(wr); StreamReader sr =newStreamReader(response.GetResponseStream()); var re =sr.ReadToEnd(); var dobject =JsonConvert.DeserializeObject(re.ToString()); var jobj = (JObject) dobject; returnjobj; } |
Line 25 is used in order to skip, or to ignore any SSL errors when calling the API – because we all use purchased certificates from trusted entities right – no self signed at all (*sarcasm*).
1 |
ServicePointManager.ServerCertificateValidationCallback+= (sender, cert, chain, sslPolicyErrors) =>true; |
Line 27 and 28 are just variable definitions – defining the VM we would like to manipulate and the SLA name we would like to add it to.
1 2 |
var vmname ="MPRESTON-VM1"; var slaname ="Gold"; |
Finally, we start to get into some of the good stuff! Line 30 through 35 make an API GET request to our Rubrik Cluster, obtaining the VM ID from the vmware/vm resource. Line 30 defines our actual URI and Resource we wish to connect to. Line 31 shows we are looking to perform a GET request, while line 32 adds the authorization information we created earlier into the request header. Line 33 executes the actual API request, returning a response which is then converted to an HTTPWebResponse Object. Line 34 sends that response into the function we created, while Line 35 extracts the VM ID from the JSON object returned.
1 2 3 4 5 6 |
var request = (HttpWebRequest) WebRequest.Create("https://192.168.150.111/api/v1/vmware/vm?name="+vmname ); request.Method="GET"; request.Headers.Add("Authorization", "Basic "+encoded); var response = (HttpWebResponse)request.GetResponse(); JObject jo =responseToJSON(response); var vmid =jo["data"][0]["id"]; |
Line 37 through 42 executed pretty much the same code as the previous GET Request, instead, grabbing data from the sla_domain resource. This data, the sla domain id is then stored into a variable for the next step.
1 2 3 4 5 6 |
request= (HttpWebRequest) WebRequest.Create("https://192.168.150.111/api/v1/sla_domain?name="+slaname); request.Method="GET"; request.Headers.Add("Authorization", "Basic "+encoded); response= (HttpWebResponse) request.GetResponse(); jo=responseToJSON(response); var slaid =jo["data"][0]["id"]; |
Finally, we move into Lines 44 through 53. Here we send a PATCH request to the vmware/vm resource, essentially stating we would like to PATCH the object, meaning update a certain portion of it. In our case, it’s the configuredSlaDomainId which we would like to manipulate. The biggest difference from a PATCH and GET request is we actually need to send some data within the body of the request – the configuredSlaDomainId. This is accomplished by Lines 47 through 52, where we create our body variable then read it into a bytearray. We then assign this bytearray to our requests Stream, or body. From there it’s as simple as calling the GetResponse method of our request we have built!
1 2 3 4 5 6 7 8 9 10 |
request= (HttpWebRequest) WebRequest.Create("https://192.168.150.111/api/v1/vmware/vm/"+vmid); request.Method="PATCH"; request.Headers.Add("Authorization", "Basic "+encoded); string body ="{\"configuredSlaDomainId\":\""+slaid+"\"}"; byte[] byteArray =Encoding.UTF8.GetBytes(body); request.ContentLength=byteArray.Length; Stream dataStream =request.GetRequestStream(); dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Close(); response= (HttpWebResponse) request.GetResponse(); |