Nutanix REST API with Golang/Go Tutorial – Part 2 – Authentication

full course
  1. Nutanix REST API with Golang/Go Tutorial – Part 1 – Nutanix REST API Overview
  2. Nutanix REST API with Golang/Go Tutorial – Part 2 – Authentication
  3. Nutanix REST API with Golang/Go Tutorial – Part 3 – Retrieve information about a VM (IP address, vCPU, MEM)

The first step when interacting with the Nutanix Rest API with GO is to authenticate against the API. To do so you need to know that Nutanix makes use of user authentication. There is a role concept for users, which means a user can have different rights when connecting.

There are three roles a user can be assigned to:

  • Viewer: This role allows a user to view information only. It does not provide permission to perform any administrative tasks.
  • Cluster Admin: This role allows a user to view information and perform any administrative task (but not create or modify user accounts).
  • User Admin: This role allows the user to view information, perform any administrative task, and create or modify user accounts.

The first user in PRISM (GUI) which is direct related to the API authentication is “admin” with the default password “admin” which will be changed via the first connect to PRISM. I prefer to set the admin password to the default password “nutanix/4u” in my test environments but this is up to you. The admin user does have all three roles assigned.

admin_roles

Using Google Chrome developer tools to learn how PRISM authentication works (optional and before AOS 5.0)

At the moment the documentation of the REST API lacks some easy examples and explanations how the authentication should be done. I started to learn this by making use of the Google Chrome developer tools when I am connecting to Nutanix via the Web GUI.

First step is to open Google Chrome and show the developer tools and switch to the Network tab. Clear all and start the recording. Type in CVM or Cluster IP/DNS to open the PRISM GUI.

open_prism_gui

There are two important URL the browser requested:

  1. https://192.168.178.130:9440/PrismGateway/services/rest/v1/users/session_info
    • It looks like that the client tries to check if we are already connected which is this case fails because the response code shows “401” which means we are not authorized to access this URL at the moment.
  2. https://192.168.178.130:9440/PrismGateway/services/rest/v1/utils/pre_login_details
    • After the client understood that this session is not authorized it ask to get some details before a login will take place.
    • What is good to know that a response looks like this which gives a lot of details which helps to identify what API version should be supported etc.: (without authentication!)

 

Let’s type in the user and password now and stop the recording ones we are successfully connected to the GUI. You should found a POST to  https://192.168.178.130:9440/PrismGateway/j_spring_security_check. There are three interesting parts:

  1. It is posting the username and password in Form data as j_username and j_password
  2. It is receiving the Set-Cookie: … in the Response header which means a cookie can be used for all subsequent http methods
  3. It is receiving the Location: https://192.168.178.130:9440/PrismGateway/nmb/loginsuccess which is like a redirection in this case

j_spring_security_check

The https://192.168.178.130:9440/PrismGateway/nmb/loginsuccess GET will be requested via the client with the cookie which seems to check if it works. A response of the status code of “200” and the response of “Success” means cookie authentication is working. Then a https://192.168.178.130:9440/PrismGateway/services/rest/v1/users/session_info is followed which gets some user session info like userDTO.

I believe the rest can be ignored for our task now. We learned this basic workflow for authentication.

  1. Request session_info to check if we are already authenticated
  2. Request pre_login_details which may be used to react on different API versions
  3. Send username and password with the request
  4. Set or receive a cookie for subsequent http methods
  5. check if we are connected via loginsuccess

Nutanix REST API Authentication with GO

There are two methods to authenticate to the Nutanix REST API.

1. Basic Authentication :
The user provides user-id and password every time a request is send as the auth-header.

2. Session Authentication :
The user credentials are stored in a cookie.

GO Authenticate via “Basic Authentication”

I wrote an example which shows how the basic authentication works. The general workflow is simple. EVERY http method sends the username and password in a encoded fashion. Nutanix REST API requires a base64 encondig which is included in the “encoding/base64” package.

I created the func EncodeCredentials which encodes the input parameter username and password as required.

The next four functions return the API entry points for v0.8,v1.0,v2.0,v3.0 of the Nutanix API. It uses the NutanixHost parameter to generate the full https request string.

For testing purposes I set some variables to meet my test environment in the main function. Feel free to change this to your settings.

The next part is only required if a certificate at the Nutanix cluster is used which is self-signed. Basically this ignores that this certificate can not be validated.

A http client will be created which leverage the Transport “tr” we just defined.

Now we are able to create the GET request to session_info at https://NutanixHost:9440/PrismGateway/services/rest/v1/users/session_info. This is inline with the PRISM GUI workflow.

Before we send the request we make sure username and password will be included in the request header. The key we need to set is “Authorization” with a defined base64 value with isa string of “Basic “+encodedString.

The request can be send and we are able to handle the response. In this example I am checking for some response codes but it is up to you to implement more.

The last part prints the response body to give you a feedback and the received info about the user.

That’s it. Just remember you only need to make sure the header of the request includes the base64 encoded string.

GO Authenticate via “Session Authentication”

I wrote an example which shows how the session authentication works. The general workflow is like that. Send a “basic authentication” http Get with base64 encoded credentials and set a cookie. Use the cookie in all subsequent http methods .

I will only focus on the parts which change to the “basic authentication” part.

The way how the HTTP client will be created changed. First the cookie will be created and the the new created http client is using this cookie.

There is a second request but this time we don’t set the authorization header. The reason is simple. The http client makes sure the cookie is send with the encrypted credentials.

Done.

I found two blogs which helped me to learn about this:

Dwayne Lessner @dlink7 

and

Jason Langone @langonej