RSS .92| RSS 2.0| ATOM 0.3
  • Home
  • About
  •  

    Consuming Nutanix PrismAPI with Powershell – Display information about CVM

    March 19th, 2014

    A customer recently asked how to list the IP address of the Nutanix CVM (Controller Virtual Machine).

    I have already blogged how to consume the PrismAPI with vCenter Orchestrator.  This time we will use Powershell.

    PrismAPI exposes a whole bunch of awesome data.  In particular the /hosts/ endpoint is what we need:

    https://<yourblock>:9440/PrismGateway/services/rest/v1/hosts/

    It will respond with:

    “entities”: [
    {
    "serviceVMId": 10,
    "name": "NTNX-<redacted>-D",
    "serviceVMExternalIP": "192.168.2.",
    "hypervisorAddress": "192.168.2.",

    But in reality, it will be one gigantic string/array blob.

    The following code will connect to your block, query the data and respond with the serviceVMid, CVM name, CVM IP and hypervisor IP.  Note: You will need Powershell 4.0 for the invoke-restmethod.

    Be sure to enter proper data to the <FILL THIS IN> sections.  Have fun!

    add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
    public bool CheckValidationResult(
    ServicePoint srvPoint, X509Certificate certificate,
    WebRequest request, int certificateProblem) {
     return true;
     }
    }
    "@
    [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
    
    #declare an array to be used later
    $array = @()
    
    $Uri = "https://:9440/PrismGateway/services/rest/v1/hosts/"
    $username = ""
    $password = ""
    $Header = @{"Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($username+":"+$password ))}
    $results = Invoke-RestMethod -Method Get -Uri $Uri -Headers $Header
    
    # grab the results of the entity section
    ($results.entities) |%{
    # set the output of the foreach to the $array var
    $array = $_
    #iterate through the array
    ($array) | %{
    write-host "`nname:"$array.name "`n serviceID:"$array.serviceVMid "`n externalIP:"$array.serviceVMExternalIP "`n hypervisorAddress:"$array.hypervisorAddress"`n"
    
     }
    }
    
    

    Connecting to the Nutanix PrismAPI with vCenter Orchestrator – Part 3

    March 4th, 2014

    Part 1 covered pointing the vCO HTTP-REST plugin to a PrismAPI endpoint.

    Part 2 covered building a workflow and consuming the bulk data output from the PrismAPI.

    Part 3 will cover consuming the data, and in this case displaying values from Nutanix Protection Domains.

    Add a Scriptable Task

    Right click on the workflow created in Part 2, and click Edit.  In my case, the workflow is called Nutanix PrismAPI – protection_domains.

    1. Drag a Scriptable Task to the blue line that connects Invoke a REST operation and the end ball.add parseJSON scriptable task
    2. Switch to the Info tab, and name it parseJSON.
    3. Switch to the IN tab, hit the single dumb bell, and select contentAsString  scriptable task input
    4. Change to the Scripting tab.  Plug in the following code:
    // built in JSON parser to vCO via javascript
    var jsonResponse = JSON.parse(contentAsString);
    
    System.log("\n\n--------\n\n");
    
    // get the length of the JSON array that is returned
    length=jsonResponse.length;
    
    // iterate through the array and look for particular values we want to use
    for(var i=0;i<length;i++) {
     for(obj in jsonResponse[i]) {
     if(obj == "name") {
     foundName=obj;
     //System.log("object: "+obj);
     System.log("---> Protection_domain: "+jsonResponse[i][obj]);
     }
     if(obj == "pendingReplicationCount") {
     foundReplicationCount=obj;
     System.log("---> pendingReplicationCount: "+jsonResponse[i][obj]);
     }
     if(obj == "ongoingReplicationCount") {
     foundOngoingReplicationCount=obj;
     System.log("---> ongoingReplicationCount: "+jsonResponse[i][obj]);
     }
     if(obj == "totalUserWrittenBytes") {
     foundTotalUserWrittenBytes=obj;
     System.log("---> foundTotalUserWrittenBytes: "+jsonResponse[i][obj]);
     }
    
     }
     System.log("\n");
     }
    

    Validate the workflow and fix any errors.  Right click and run.  My example output looks like this:

    [2014-03-04 15:50:20.402] [I] —> Protection_domain: WANPD2
    [2014-03-04 15:50:20.402] [I] —> pendingReplicationCount: 0
    [2014-03-04 15:50:20.403] [I] —> ongoingReplicationCount: 0
    [2014-03-04 15:50:20.403] [I] —> foundTotalUserWrittenBytes: null
    [2014-03-04 15:50:20.404] [I]

    [2014-03-04 15:50:20.404] [I] —> Protection_domain: WANPD
    [2014-03-04 15:50:20.405] [I] —> pendingReplicationCount: 0
    [2014-03-04 15:50:20.405] [I] —> ongoingReplicationCount: 0
    [2014-03-04 15:50:20.406] [I] —> foundTotalUserWrittenBytes: null
    [2014-03-04 15:50:20.406] [I]

    In my code, I am specifically looking for Protection Domains, and three values:

    • pendingReplicationCount
    •  ongoingReplicationCount
    • foundTotalUserWrittenBytes

    With code such as this, it could be possible to create a scheduled task, and send an alert email if the pendingRelicationCount hits a certain threshold.

    Enjoy!

    Editors note: Mobile shout-out to Ryan Swenson for code assist.


    Connecting to the Nutanix PrismAPI with vCenter Orchestrator – Part 2

    March 3rd, 2014

    Part 1 covered pointing the vCO HTTP-REST plugin to a PrismAPI endpoint.

    Part 3 will cover consuming the data, and in this case displaying values from Nutanix Protection Domains.

    Continuing on, we need to first Add a REST operation.  This, in short, defines an API endpoint we are going to conduct GET operations.  You can also configure endpoints to do POST operations, among others.

    We are going to create a generic endpoint that allows for variable substitution, which we will pass in.  The current PrismAPI endpoint allows for the following resources:

    • /alerts
    • /authconfig
    • /cluster
    • /containers
    • /disks
    • /events
    • /hosts
    • /http_proxies
    • /protection_domains
    • /remote_sites
    • /service_centers
    • /snmp
    • /storage_pools
    • /vdisks
    • /vms
    • /vstores

    I am going to pick /protection_domains, for no other reason than it will probably be a totally fun thing to build workflows against (such as monitoring in-flow replication).

    Add a REST operation

    We will consume the REST host we populated in the first tutorial.

    1. Expand Library->HTTP-REST.  Right-click on Add a REST Operation Add a REST Operation
    2. Select the Parent Host created in the 1st tutorial.  Mine is called “Nutanix PrismAPI”
    3. The REST Workflow leaves an entry for Name.  This can be specific a specific resource, in my case, I want to keep it generic and pass in a resource at runtime.  The PrismAPI is currently constructed thusly: /PrismGateway/services/rest/v1/<resource>/ .. vCO allows for variable substitution, so enter the following string: /PrismGateway/services/rest/v1/{endPoint}/
    4. The HTTP method is GET.  Click submit, and hopefully you have a green response.
    5. Now we get to the fun stuff.  Create a new folder somewhere in your vCO tree.  I called mine Nutanix PrismAPI
    6. Right click on the folder and select New Workflow.  I named mine: Nutanix PrismAPI – protection_domains.  I chose the naming to denote this WF (workflow) will be directly calling the protection_domains resource.
    7. In the general tab, create a new Attribute by clicking on the A+.  Name it restOperation (as so, it makes things easier in a bit).  Select the value, and  drill to the HTTP-REST host you have created for this.  Expand and select the red ball for the Operation.
    8. Create another Attribute and enter the value as protection_domains (again as thus, it is a hard requirement as it is called the REST resource).
    9. Create a final Attribute called contentAsString and leave the value blank.
    10. Great, now click on the Schema tab.  Drag a Workflow element from the left pain to the blue error between the green “Go” ball and the end ball.  In the filter field, type: “Invoke a REST Operation.”  Hit Select.Invoke RestOP WF
    11. Hover over and hit the pencil.  You will now edit the specifics of that WF element.  Hit Pencil
    12. Click the In tab.  For restOperation, click the Source paramenter field and select the restOperation that we created.input to null
    13. Click the Source Parameter for param_0, select the endPoint attribute we created.
    14. Set the rest to NULL.
    15. Click on the Out tab.  Set the contentAsString to the contentAsString attribute we created.output to content as string
    16. The other three Local Parameters can be set to NULL, or you can create attributes for each and wire them.  Hit OK.
    17. Click on the Validate button with the green check.  Hopefully everything is wired properly.  If not, investigate the fix.  Save and close.

    Run the Workflow

    1. Right click on the Workflow that was just created.  With any luck you should see the workflow run, step through and complete.  We will receive the following output (I prettied it up, just a little bit):

    [2014-03-03 20:29:57.546] [I] Request: DynamicWrapper (Instance) : [RESTRequest]-[class com.vmware.o11n.plugin.rest.Request] — VALUE : com.vmware.o11n.plugin.rest.Request@c044893
    [2014-03-03 20:29:57.546] [I] Request URL: https://<URL>/PrismGateway/services/rest/v1/protection_domains/
    [2014-03-03 20:29:57.586] [I] Response: DynamicWrapper (Instance) : [RESTResponse]-[class com.vmware.o11n.plugin.rest.Response] — VALUE : com.vmware.o11n.plugin.rest.Response@3c24b0cd
    [2014-03-03 20:29:57.587] [I] Status code: 200
    [2014-03-03 20:29:57.588] [I] Content as string: <A very long string in JSON format>

    We see awesome metrics such as:

    “pendingReplicationCount”:0,

    “ongoingReplicationCount”:0,

    “totalUserWrittenBytes”:null

    With this, we can theoretically build a workflow that monitors replication status and alerts us with progress and/or completion.  Parsing and using the data will be in Part 3!


    Connecting to the Nutanix PrismAPI with vCenter Orchestrator

    March 3rd, 2014

    REST API are fun to consume!  JSON is fun to consume and use!  vCenter Orchestrator is fun to use, and act as a consumer of data!

    Now that I work for Nutanix let us investigate different ways to consume the platform’s API!

    Editor’s note:  This will hopefully end up being a series of posts.  The post is a bit of a homage to content produced by other people:

    • Jason Langone’s prismdevkit.com series
    • Andre Leibovici’s posts via myvirtualcloud.net on the Nutanix API, and using PowerCLI (multiple)
    • Josh Gray’s series of posts on jaas.co about using vCO to do many cool things

    Special blog-style shout-out to Sasha Armstrong for granting me access.

    Read them all.  There is great content available.

    Editor’s note #2: This post assumes a working installation of vCenter Orchestrator with the HTTP REST plugin imported and available.  The bits can be found at your local VMware download site.

    Prerequisites

    • URL of your Nutanix PrismAPI endpoints
    • username and password
    • Most likely an open window pointing at the Rest API Explorer Live! page of your Nutanix endpoint (can be found by dropping-down next to your user name and selecting)

    Add a REST host

    First we need to add a REST host endpoint to vCO.

    1. Under the Run view, select the Workflows widget.
    2. Expand Library -> HTTP-Rest -> Configuration folders
    3. Right click on Add a REST host and select Start Workflow
    4. Enter something usable under the Name field (note this helps identify your REST endpoint if you have multiple.  So entering foo is not advised)
    5. Enter the URL, including http(s) and/or port (if non-standard) as required.  example: https://api.example.com:4443
    6. Click Next.
    7. Select the appropriate Bool value for Proxy settings, and enter specifics, if necessary.  Click Next.
    8. Select Basic from the Host Authentication drop-down.
    9. Use Shared session mode.
    10. Enter a username and password that has permissions to authenticate to the Nutanix PrismAPI and click Submit.

    Hopefully at that point you have a successful connection to the host.  If a failure was generated, re-run the workflow and fix the errors.

    Part 2 will cover building a workflow and consuming the bulk data output from the PrismAPI.

    Part 3 will cover consuming the data, and in this case displaying values from Nutanix Protection Domains.


    PowerCLI: Calculate the allocated size, in GB, of a catalog in vCloud Director

    October 17th, 2013

    Here is a quick hitter for you to calculate the size, in GB, of a catalog in vCloud Director:

    Usage:

    -catalog <catalog name>

    
    param (
     [string]$catalog = $(throw 'Catalog Required')
     }
    
    [int]$storageGB=0
    (get-catalog $catalog| get-civapptemplate) |% {
     $s=$_.storageusedgb
     $storagegb=$storagegb+$s
     }
    $storageGB=$storageGB*1000
    "{0:N0}" -f $storagegb
    
    

    NOTE: The tricky-trick with {0:N0} can be found here.


    Generate a List of PoweredOn vApps per User in vCloud Director

    October 11th, 2013

    It is important to know what your users are doing in vCloud Director with the content, how many vApps that have Powered On and each user’s memory allocation.

    Here is how to do it!

    This code assumes you are logged in as System Admin role.

    [int]$counter=0
    [int]$grandTotalMem=0
    $array=@()
    
    (get-org ) |% {
     $org = $_
     ($org | get-ciuser) |% {
     [int]$totalMem=0
     [int]$uservAppCounter=0
     $user = $_
     $vmCount = $user.deployedvmcount
     $storedCount = $user.storedvmcount
    
     if ($vmCount -gt 0) {
     ($user | get-civapp) |% {
     $array += $user
     $civapp = $_
     $civappStatus = $civapp.status
     $memAlloc = [math]::round($civapp.MemoryAllocationGB,0)
     if ($civappStatus -ne "PoweredOff") {
     $totalMem = $totalMem + $memAlloc
     $uservAppCounter++
     }
     }
     write-host "$org,$user`n Deployed VM Count:$vmcount`n Stored VM Count: $storedCount`n Deployed/PoweredOn vApps: $uservAppCounter`n Total Memory Allocated: $totalMem GB"
     $counter++
     }
     $grandTotalMem = $grandTotalMem + $totalMem
     }
    }
    
    write-host "`nTotal memory allocated: $grandTotalMem GB`nTotal users with deployed vApps: $counter"
    

    The up to date code can also be pulled from my GitHub repo!


    PowerCLI: Find unhealthy vApps in vCloud Director

    January 24th, 2013

    Ever wonder what vApps that have been deployed inside vCloud Director are in a bad state, and need investigation?  Me too!  Here’s a code block to find vApps that are NOT in the following states:

    • PoweredOn
    • PoweredOff
    • Suspended
    # set up the logfile
     $results = @()
     $logFile = "OUTPUT-unhealthyVApps.txt"
    
    # walk the connected Orgs, best if run as SysAdmin
     (get-orgvdc) | %{
    
    $orgVdc = $_
     $orgVdcName = $orgVdc.name
    
    ($orgVdc | get-civapp) | %{
    
    $vApp = $_
     $vAppName = $vApp.name
     $vAppStatus = $vApp.status
    
    if(($vAppStatus -ne "PoweredOn") -and ($vAppStatus -ne "PoweredOff") -and ($vAppStatus -ne "Suspended")) {
    
    write-host "vApp Name:"$vAppName
     write-host " Org vDC:"$orgVdcName
     write-host " Status:"$vAppStatus"`n"
    
    $results += "vApp Name: $vAppName"
     $results += " Org vDC:$orgVdcName"
     $results += " Status:$vAppStatus"
    
    (get-ciVM -vapp $vAppName) | %{
     $VM = $_
     $vmName = $vm.name
     $vmStatus = $vm.status
     write-host " VM: $vmName"
     write-host " Status:"$vmStatus"`n"
    
    $results += " VM: $vmName"
     $results += " Status: $vmStatus"
     $results += " "
    
    }
     }
    
    }
     }
    
    $results | out-file $logFile
     write-host "Output file is:"$logfile
    
    

    The code will display the following to the screen, and a logfile:

    vApp Name: vApp-vubuntu001
    Org vDC: ohio-demo_ovDC
    Status: Resolved

    VM: vApp-vubuntu001
    Status: PoweredOff

    This may mean that the VM’s that are contained in the vAPP don’t exist anymore, but the vAPP does.  A good one to check out!


    PowerCLI: Set bits to allow for ESXi nested virtualization

    January 23rd, 2013

    This post details totally unsupported materials!

    If you are spinning up nested virtualization, check the blog posts at virtuallyGhetto to set up the environment.

    In order to allow for the nested ESXi, a bit has to be checked to allow for Hardware Virtualization

    CPU hardware options

    Wouldn’t it be nice to set the bit via PowerCLI?  Yes, I think it would.  Here is the code:

    
    # set the guestOS string from vCenter to look for
     $guestOSname = "VMware ESXi 5.x"
    
    # options we need to set for nested virtualization
     $vmxValue = "NestedHVEnabled"
     $boolValue = "TRUE"
    
    # walk vCenter and determine VM's that match $esxiGuest
     (get-vm) | %{
     $vm = $_
    
    $guestType = ($view).summary.config.guestFullName
    
    # do equality string checks and proceed to remediate if
     # $esxiGuest is found
     if ( $guestType -eq "$guestOSname") {
     write-host "`nFound VM:"$vm.name "with guest type:"$guestOSname
    
    # push the value to the VM
     write-host "Now Setting bits for nested virtualization...`n"
    
    $vmValue = (get-vm $vm | get-view)
     $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
     $vmConfigSpec.$vmxValue = $boolValue
     $vmValue.ReconfigVM($vmconfigSpec)
     }
     }
    
    

    The magic bit is NestedHVEnabled which will set vhv.enable = TRUE in the .vmx file of the VM.  That is where the magic happens.  It can be found in the public API documentation.

    Once you run the code, check the CPU config and you will see the box checked.

    CPU hardware options post

    Be aware, this will find all of your ESXi virtual machines.

    Enjoy!


    PowerCLI – Display vCloud Catalog Entries

    January 15th, 2013

    Here is a quick PowerCLI script that will display entries in all Catalogs you have access.  PowerCLI requires the vCloud cmdlets, and you must be attached to the cell via connect-cihost.  It is best run as SysAdmin privs.

    Enjoy!

    $results = @()
    $logFile = "OUTPUT-getCatalogEntries.txt"
    
    foreach ($catalog in get-catalog) {
    $results += (get-catalog -name $catalog | foreach-object {$_.ExtensionData.CatalogItems.CatalogItem |select @{N="Org";E={$catalog.org}},@{N="Catalog";E={$catalog.name}},@{N="CatalogItem";E={$_.name}},@{N="Description";E={$_.Description}}} |format-list)
    
    }
    
    $results | out-file $logFile
    

    You can then check the output file from $logFILE.  The contents will look like:

    Name : AllOrgConsumable <- Name of catalog entry
    Org : Catalog <- The Organization it belongs
    Shared : True <- If it is shared out
    Published : True <- If it is published
    Owner : system <- Who created/owns


    PowerCLI – Report on Organization Resource usage in vCloud Director

    December 6th, 2012

    It is important to monitor Organization resource usage in vCloud Director.  There is a view in the Monitor area but what if you want a quick look?  Voila, here it is!

    You will need PowerCLI installed with the vCloud cmdlets.  You will also need to be connected to the cell.  This will walk through all of your configured Organizations and display the percentage usage.  Very useful when you are using the Allocation model.

    (get-orgvdc) | %{
     $orgvdc = $_
     $cpuAlloc = $orgvdc.CpuAllocationGhz
     $ramAlloc = $orgvdc.MemoryAllocationGB
     $storAlloc = $orgvdc.StorageAllocationGB
    
     if ($orgvdc.CpuUsedGhz -ne 0 -and $orgvdc.CpuAllocationGhz -ne 0) {
     $orgcpuspc = (($orgvdc.CpuUsedGhz * 100) / $orgvdc.CpuAllocationGB) }
    
     if ($orgvdc.MemoryUsedGB -ne 0 -and $orgvdc.MemoryAllocationGB -ne 0) {
     $orgramuspc = (($orgvdc.MemoryUsedGB * 100) / $orgvdc.MemoryAllocationGB) }
    
     if ($orgvdc.StorageUsedGB -ne 0 -and $orgvdc.StorageAllocationGB -ne 0) {
     $orgstoruspc = (($orgvdc.StorageUsedGB * 100) / $orgvdc.StorageAllocationGB) }
     $orgram = [System.math]::round($orgramuspc,1)
     $orgcpu = [System.math]::round($orgcpuspc,1)
     $orgstor = [System.math]::round($orgstoruspc,1)
    
     write-host `n"Org vDC: $orgvdc"
     write-host "CPU: $orgcpu% of $cpuAlloc Ghz, MEM: $orgram% of $ramAlloc GB, Storage: $orgstor% of $storAlloc GB"`n
     }
    
    

    The output will be:

    OvDC: My Org vDC, CPU: 25.3%, MEM: 18.6%, Storage: 60.1%