├── PowerShell ├── SET-count-desktop-logins.ps1 └── create-lab-users.ps1 ├── README.md ├── bash ├── curl-commands.sh └── curl-vmc-authenticate.sh ├── img └── github-zip.png ├── python ├── connect-vcenter.py ├── vcenter-REST-host.py ├── vcenter-REST.py ├── vmc-REST-segments.py └── vmc-REST.py └── terraform └── main.tf /PowerShell/SET-count-desktop-logins.ps1: -------------------------------------------------------------------------------- 1 | # Written to monitor desktop logins during TechSummit 2021 Start Coding: Today session 2 | 3 | # Required Horizon module 4 | Import-Module VMware.VimAutomation.HorizonView 5 | 6 | # User Configuration 7 | $hzUser = "" 8 | $hzPass = "" 9 | $hzDomain = "" 10 | $hzConn = "" 11 | $poolName = "" 12 | $slackWebhook = 'https://hooks.slack.com/services/xxx' 13 | 14 | # Connect to the Horizon View server 15 | $hzServer = Connect-HVServer -server $hzConn -User $hzUser -Password $hzPass -Domain $hzDomain 16 | 17 | # Execute loop how many times 18 | $MAX_ITERATIONS = 120 19 | 20 | # Pause for how long after each loop - i.e. every 5 seconds for 120 iterations means the script runs for 10 minutes 21 | $SLEEP_INTERVAL_IN_SECONDS = 5 22 | 23 | $numIterations = 1 24 | 25 | # Store the last message posted to Slack outside the scope of the loop, to detect change from one iteration to the next 26 | $previousValues = '' 27 | 28 | while ( $numIterations -le $MAX_ITERATIONS ) 29 | { 30 | Write-Host "Iteration" $numIterations "of" $MAX_ITERATIONS 31 | $allVMs = Get-HVMachineSummary -PoolName $PoolName | select -ExpandProperty Base | Select-Object Name,UserName, BasicState 32 | $totalVMs = $allVMs.length 33 | $connectedVMs = 0 34 | foreach ($vm in $allVMs) 35 | { 36 | # Find and count VMs that show CONNECTED state 37 | if ( $vm.BasicState -eq "CONNECTED") 38 | { 39 | $connectedVMs += 1 40 | write-Host $vm.Name $vm.NamesData.UserName $vm.BasicState 41 | } 42 | } 43 | $values = "Pool '" + $poolName + "' connected desktops: " + $connectedVMs + " of " + $totalVMs 44 | $msg = "$(Get-Date) - $values" 45 | Write-Host $msg 46 | $body = ConvertTo-Json @{ 47 | text = $msg 48 | } 49 | 50 | # Post via Slack webhook if something has changed since the last iteration 51 | if ($previousValues -ne $values) { 52 | try { 53 | Invoke-RestMethod -uri $slackWebhook -Method Post -body $body -ContentType 'application/json' 54 | } catch { 55 | Write-Host "Unable to invoke webhook" 56 | } 57 | } 58 | 59 | $numIterations += 1 60 | $previousValues = $values 61 | Write-Host "Sleeping..." 62 | Start-Sleep $SLEEP_INTERVAL_IN_SECONDS 63 | } 64 | Disconnect-HVServer -server $hzConn -confirm:$false -------------------------------------------------------------------------------- /PowerShell/create-lab-users.ps1: -------------------------------------------------------------------------------- 1 | # Allows us to use the ActiveDirectory module, a set of cmdlets Microsoft provides for AD operations 2 | Import-Module ActiveDirectory 3 | 4 | # First student number 5 | $StartNum = 1 6 | 7 | # Last student number 8 | $EndNum = 32 9 | 10 | # Create the new accounts on this domain controller 11 | $DCName = "dc01.set.local" 12 | 13 | # Organization Unit for our accounts 14 | $OUPath = "OU=TechSummit,OU=Users,OU=SET AMER,DC=set,DC=local" 15 | 16 | # Add new users to this group for desktop entitlement 17 | $VDIGroup = "Horizon TechSummit AMER" 18 | 19 | # Prompt the operator for a password to set on the accounts 20 | $StudentPassword = Read-Host -AsSecureString "Enter student account password" 21 | 22 | # Loop through the account numbers 23 | for ($StudentNum = $StartNum; $StudentNum -le $EndNum; $StudentNum++) 24 | { 25 | # Build the Active Directory name - i.e. Tech Summit01. 26 | # PadLeft will turn the digit 1 into '01'. 27 | $Name = "Tech Summit" + $StudentNum.ToString().PadLeft(2,'0') 28 | 29 | # Build the Active Directory account name i.e. techsummit01 30 | # PadLeft will turn the digit 1 into '01'. 31 | $SamAccountName = 'techsummit' + $StudentNum.ToString().PadLeft(2,'0') 32 | 33 | # Display the names 34 | write-host "Adding" $Name "("$SamAccountName ")" 35 | 36 | # Add the user to Active Directory. 37 | New-ADUser -Name $name -GivenName "Tech" -Surname "Summit" -AccountPassword $StudentPassword -SamAccountName $SamAccountName -Path $OUPath -Server $DCName -Enabled $TRUE 38 | 39 | # Add the user to the VDI group to entitle the user to a desktop 40 | Add-ADGroupMember -Identity $VDIGroup -Members $SamAccountName -Server $DCName 41 | } 42 | 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Start Coding Today 2 | 3 | ## Introduction to API calls 4 | Co-presented by Patrick Kremer and Nico Vibert. 5 | This session will be presented at the internal VMware conference TechSummit. 6 | 7 | ## Objectives 8 | 9 | In 45 minutes, attendees will be able to learn and practice coding with a VMware environment, giving them a little taste of the power of automation. 10 | 11 | ## Requirements 12 | 13 | A browser with Internet access. 14 | 15 | That's it. No coding experience required. 16 | 17 | ## What the attendee will do during the session: 18 | 19 | * Learn the basic concepts behind REST APIs 20 | * Run a PowerCLI script against a vCenter 21 | * Run API calls with Curl against a vCenter 22 | * Deploy VMware resources with Terraform 23 | * Invoke REST APIs with Python 24 | 25 | ## Session Structure 26 | 27 | ### Part 1 - Introduction 28 | 29 | Welcome to the session. This session is for anyone who's never had the confidence or the motivation to learn to code. 30 | It's hard to get started with coding without a use case, a mentor, an environment you can learn and a safe place where there's no stupid questions. 31 | 32 | This is a short session and this session is more of an introduction to coding for folks who have a background as infrastructure and virtualization administrators and would like to understand the 'art of the possible'. 33 | 34 | ### Part 2a - Live - Desktop Access 35 | 36 | For VMware attendees, access your VDI session. Usernames and passwords will be provided in the Zoom session. 37 | 38 | ### Part 2b - Offline with your own vCenter 39 | 40 | Obviously you are welcome to run the commands above in your own lab! 41 | 42 | You will need to install: 43 | - [Python3](https://wiki.python.org/moin/BeginnersGuide/Download) 44 | - [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli) 45 | - [PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-7.1) 46 | - [PowerCLI](https://code.vmware.com/docs/13638/powercli-12-3-0-user-s-guide/GUID-ACD2320C-D00F-4CCE-B968-B3C41A95C085.html) 47 | 48 | You also need a code editor. [VS Code](https://code.visualstudio.com/download) is free and cross-platform. 49 | 50 | If you want to start learning Git, which we strongly recommend if you're going to learn about code, you can [install it](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git). You can then clone this code repo with `git clone https://github.com/nvibert/start-coding-today.git` 51 | 52 | Alternatively, you can download the code in zip format from the [repo](https://github.com/nvibert/start-coding-today) ![](img/github-zip.png) 53 | 54 | ### Part 3 - PowerCLI 55 | 56 | PowerCLI is one of the most common tools to automate tasks against a VMware environment. PowerCLI abstracts the API calls by providing a command-line interface tool that is self-explanatory. 57 | 58 | PowerCLI is a collection of Windows Powershell modules which are used to manage and maintain a VMware virtual environment. 59 | PowerCLI is a great tool for system administrators and can be used to gather detailed information and/or execute bulk commands against multiple VMs, Hosts, Network or Storage devices. 60 | 61 | Open the PowerShell windows and run the following command: 62 | 63 | ```powershell 64 | Connect-VIServer -Server vcenter.sddc-A-B-C-D.vmwarevmc.com -Protocol https -User cloudadmin@vmc.local -Password 'qwerty' 65 | ``` 66 | 67 | You are now connected to a VMware Cloud vCenter. 68 | 69 | Now that you are connected, you can run multiple PowerCLI commands, such as the following. Note how you can use Tab to auto-complete the commands. 70 | 71 | ```powershell 72 | Get-VM 73 | 74 | Get-VMHost 75 | 76 | Get-Folder 77 | 78 | Get-Datacenter 79 | 80 | Get-Datastore 81 | ``` 82 | 83 | You can run the following command to understand why cmdlets are supported: 84 | ```powershell 85 | Get-Command -Module *VMware* 86 | ``` 87 | 88 | Let's try to create a new folder inside an existing folder. One way to do this is to create a PowerShell variable, using the '$' prefix. 89 | 90 | ```powershell 91 | $WorkloadsFolder = Get-Folder -Name Workloads 92 | ``` 93 | 94 | Now you can refer to this variable in your next command and create a sub-folder. Update the folder name with your own username. 95 | 96 | ```powershell 97 | New-Folder "your_user_name_power_cli_folder" -Location $WorkloadsFolder 98 | ``` 99 | 100 | By now, you should know how to check if your folder has been successfully created. Can you find out the UID of the new folder? 101 | 102 | Great! You've just used some scripts to create vSphere resources over APIs. Yes, PowerCLI just executes some API calls under the hood but a lot of the complexity was hidden from you. 103 | 104 | There are many PowerCLI sample scripts you can find on VMware {code} such as: 105 | 106 | [PowerCLI code_samples](https://code.vmware.com/samples?categories=Sample&keywords=&tags=PowerShell&groups=&filters=&sort=dateDesc&page=) 107 | 108 | Go and explore some of the commands. 109 | 110 | As you will see as you go through the examples, you will see that PowerCLI is not just for vSphere: there are modules for NSX-T, Horizon, vRealize, etc... 111 | If you see a product without a PowerCLI module...well, what is stopping you from creating the module? 112 | 113 | ### Part 4 - Terraform 114 | 115 | PowerCLI is the most commonly used VMware scripting tool and is pretty easy to pick up. It's commonly used for bulk tasks. 116 | 117 | An alternative to PowerCLI would be Terraform - the use case is different but it can achieve similar results. 118 | 119 | While PowerCLI's approach is to run a series of scripts to execute a task, Terraform's approach is to describe an entire infrastructure as code. 120 | 121 | PowerCLI is great for tasks and works great for brownfield and greenfield environments. It's particularly useful for Windows workloads and for users with a Windows background! 122 | 123 | Terraform is a great tool to build an entire templated infrastructure from scratch but works better in a greenfield environment. 124 | 125 | Terraform builds infrastructure based on code. For example, the following code would create a vSphere Tag Category. 126 | 127 | ```hcl 128 | resource "vsphere_tag_category" "region" { 129 | name = "region" 130 | cardinality = "SINGLE" 131 | 132 | associable_types = [ 133 | "VirtualMachine" 134 | ] 135 | } 136 | ``` 137 | 138 | To create a tag using the category above, you would use the following command: 139 | 140 | ```hcl 141 | resource "vsphere_tag" "region" { 142 | name = "UK" 143 | category_id = vsphere_tag_category.region.id 144 | } 145 | ``` 146 | 147 | You can see how, by using `vsphere_tag_category.region.id`, we are referring to another resource created by Terraform. 148 | 149 | One of the advantages about using Terraform is that it is able, in most cases, to work out dependencies between each resources. For example, in this instance, Terraform would create the Tag Category before creating the Tag. 150 | 151 | If you want to deploy a resource in something that was not created by Terraform, you can use the data block. 152 | 153 | Imagine you want to create a Folder in the Datacenter "SDDC-Datacenter". You would do the following. 154 | 155 | ```hcl 156 | resource "vsphere_folder" "folder" { 157 | path = "terraform-test-folder" 158 | type = "vm" 159 | datacenter_id = data.vsphere_datacenter.dc.id 160 | } 161 | 162 | data "vsphere_datacenter" "dc" { 163 | name = "SDDC-Datacenter" 164 | } 165 | ``` 166 | 167 | "Data" is simple a read-only API call to work out the ID of the DC in which we will deploy the folder. 168 | 169 | Let's go and practice some of this. Go to Visual Studio Code and open the Terminal. 170 | 171 | Clone this GitHub repo, using the command: 172 | 173 | `git clone https://github.com/nvibert/start-coding-today.git` 174 | 175 | If it's your first time using Git, well done! 176 | 177 | You will see we have now download a file called main.tf . This is the main Terraform configuration. 178 | 179 | ```hcl 180 | provider "vsphere" { 181 | user = "cloudadmin@vmc.local" 182 | password = "" 183 | vsphere_server = "vcenter.sddc-A-B-C-D.vmwarevmc.com" 184 | allow_unverified_ssl = true 185 | } 186 | 187 | data "vsphere_datacenter" "dc" { 188 | name = "SDDC-Datacenter" 189 | } 190 | 191 | 192 | resource "vsphere_folder" "folder" { 193 | path = "your_user_name_terraform_folder" 194 | type = "vm" 195 | datacenter_id = data.vsphere_datacenter.dc.id 196 | } 197 | ``` 198 | 199 | Update the file with the password, the vCenter IP address and the user_name. The configuration above will create a folder. 200 | 201 | Run the following commands: 202 | 203 | `terraform init` to initialize the provider. Did you see "provider vsphere" in the configuration earlier? This tells Terraform to download a Terraform 'plugin' to let interact with vSphere. There are also providers for NSX-T, VMC, vRA, vCD, etc... 204 | `terraform validate` to validate the syntax of your Terraform config file 205 | `terraform plan` to work out which resources Terraform will create, modify or delete on your behalf 206 | `terraform apply` to execute the plan. 207 | 208 | 209 | This is a very simple example. But imagine you add not just folders, but resources pools, clusters, tags, networks and security rules (using Terraform for NSX-T); you could define your entire VMware infrastructure as code. 210 | 211 | If you're enjoying Terraform and want to do something a bit more sophisticated, you could try to create vSphere tags and categories. Add this to your main.tf, run `terraform apply` and you will see that Terraform doesn't try to add another folder. Instead, it will just create the tag category and the tag. 212 | 213 | ```hcl 214 | resource "vsphere_tag_category" "user" { 215 | name = "your_user_name" 216 | cardinality = "SINGLE" 217 | 218 | associable_types = [ 219 | "VirtualMachine" 220 | ] 221 | } 222 | resource "vsphere_tag" "last_name" { 223 | name = "your_last_name" 224 | category_id = vsphere_tag_category.user.id 225 | } 226 | ``` 227 | 228 | As you expand your code and your configuration, you can see how you could describe your entire infrastructure as code - not just compute but also security, networking, automation, cloud, migration, SD-WAN when you include providers for AWS, NSX, SD-WAN, HCX, vRA, etc.... 229 | You could then version it, repeat it, patch it, etc... 230 | 231 | If you want to see a very advanced example, go through what Gilles and I did for VMworld: 232 | https://github.com/gchek/VMworld2020 233 | 234 | Finally: if you think that there is a provider missing for the product of your choice, let us know. 235 | Creating a provider is for advanced users as it required knowledge of the Go programming language but you know what? There are many Go programmers within VMware that can help you. 236 | 237 | ### Part 5 - REST APIs 238 | 239 | PowerCLI and Terraform are very easy to use as you can see. But what PowerCLI and Terraform only do is making API calls under the hood. 240 | 241 | You will find easier to understand automation by building some understanding of API architectures. 242 | 243 | An API is an Application Programming Interface. Typically, a developer would create an API on an application or platform to enable a client to interact with it. 244 | 245 | Most of the API requests follow the REST model on how communications with an API are executed (REST stands for Representation State Transfer). 246 | 247 | Most common REST implementations use HTTP as the application protocol. 248 | 249 | Typically, API calls run a CRUD Action: Create, Read, Update or Delete. 250 | 251 | For example: 252 | - Create a VM 253 | - Check the items of a content library 254 | - Update the vSAN storage policy on a VM 255 | - Remove a NSX network 256 | 257 | Typically REST API requests are made through a HTTP verb, which would be: 258 | 259 | - PUT ===== CREATE 260 | - GET ===== READ 261 | - PATCH ==== UPDATE 262 | - DELETE ==== DELETE 263 | 264 | When you browse any page on the web, you just make a HTTP GET request to get the contents of a webpage. 265 | 266 | It's the same if you want to get the contents of a vCenter, it will just be a GET call. 267 | 268 | When you submit a form online, you just make a HTTP POST request to submit your details. 269 | 270 | It's same when you want to create a network with NSX over the APIs: you just make a HTTP POST call, with the details about your network (subnet, mask, DHCP settings) in the body of the packet. 271 | 272 | To leverage vSphere APIs, let's use cURL. Curl is a tool to make HTTP requests and will let us interact with the APIs directly. 273 | 274 | Go back to your virtual desktop and open up the terminal. 275 | 276 | The way it works with the vSphere APIs is that you need to get a temporary token in exchange for your vCenter credentials with a 277 | 278 | `POST https://{api_host}/rest/com/vmware/cis/session` 279 | 280 | For example, on a Mac: 281 | 282 | `curl -k -i -u $TF_VAR_vsphere_user:$TF_VAR_vsphere_password -X POST -c token.txt https://$TF_VAR_vsphere_server/rest/com/vmware/cis/session` 283 | 284 | On a Windows machine, it would be: 285 | 286 | `curl -k -i -u %TF_VAR_vsphere_user%:%TF_VAR_vsphere_password% -X POST -c token.txt https://%TF_VAR_vsphere_server%/rest/com/vmware/cis/session` 287 | 288 | The output of the command would be something like this: 289 | 290 | {"value":"f3be0a4e-7fc8-48d8-b796-eb3c2f66970b"} 291 | 292 | This temporary token above `f3be0a4e-7fc8-48d8-b796-eb3c2f66970b` can be used in subsequent API requests to authenticate against vCenter. 293 | 294 | You can then use the value of the token to make an API call, for example, to get the list of folders in your environment (that will include the folders you created earlier): 295 | 296 | On a Mac: 297 | 298 | `curl -k -i -b token.txt https://$TF_VAR_vsphere_server/rest/vcenter/folder` 299 | 300 | On a Windows machine: 301 | 302 | `curl -k -i -b token.txt https://%TF_VAR_vsphere_server%/rest/vcenter/folder` 303 | 304 | ### Part 6 - REST APIs in Python 305 | 306 | cURL is great for testing REST APIs, but to truly use the API you will need to use a programming language. 307 | 308 | Open [vcenter-REST.py](python/vcenter-REST.py) 309 | 310 | This program makes the same API calls that we did with cURL. 311 | 312 | Fill in the environment variables with your vCenter username, password, and URL 313 | ``` 314 | # Environment variables 315 | VC_USERNAME = 'cloudadmin@vmc.local' 316 | VC_PASSWORD = '' 317 | VC_URL = '' 318 | ``` 319 | Execute the program: 320 | 321 | `python vcenter-REST.py` 322 | 323 | Inspect the code and the output. 324 | 325 | Now, try to write a GET call to list the hosts in your vCenter 326 | If you need help, the code to do it is in vcenter-REST-host.py(python/vcenter-REST-host.py) 327 | 328 | ### Additional Resources 329 | 330 | PowerCLI resources can be found [here](https://developer.vmware.com/powercli). 331 | 332 | Official Terraform providers can be found [here](https://registry.terraform.io/namespaces/vmware). 333 | 334 | Additional Terraform scripts and examples can be found on Nico's blog [here](https://nicovibert.com). 335 | 336 | The Curl script used above was found [here](https://www.stevetrefethen.com/accessing-vmware-vcenter-rest-api-authentication-from-curl/). 337 | 338 | -------------------------------------------------------------------------------- /bash/curl-commands.sh: -------------------------------------------------------------------------------- 1 | # These commands are examples to use against a local installation of vcsim 2 | # curl -k -X POST -H "vmware-use-header-authn: string" -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" https://localhost:8989/rest/com/vmware/cis/session 3 | # curl -k -H "vmware-api-session-id: e4821a1f-75a1-46f1-af7b-4fcdb16dd6cb" https://localhost:8989/rest/vcenter/folder 4 | 5 | # These commmands demonstrate a login to a vCenter and a request to list vCenter folders 6 | # -k indicates insecure - this allows you to connect to a homelab or other vCenter that doesn't have a valid certificate chain 7 | # -i prints out the HTTP headers that the API responds with - useful to understand what's happening 8 | # -u lets you pass credentials in the form of username:password 9 | # -X POST specifies that we want a POST instead of the default GET 10 | # -c specifies that you want all of the cookies written out to a textfile 11 | # curl -k -i -u cloudadmin@vmc.local:password -X POST -c token.txt https://vcenterURL/rest/com/vmware/cis/session 12 | 13 | # -k indicates insecure - this allows you to connect to a homelab or other vCenter that doesn't have a valid certificate chain 14 | # -i prints out the HTTP headers that the API responds with - useful to understand what's happening 15 | # -b says to use a cookie file to pass cookies along with the request 16 | # curl -k -i -b token.txt https://vcenterURL/rest/vcenter/folder` -------------------------------------------------------------------------------- /bash/curl-vmc-authenticate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Author: Alan Renouf 3 | # Product: VMware Cloud on AWS 4 | # Description: Sample CURL statement for using the VMware Cloud on AWS APIs 5 | # Obtain your refresh_token used to get a valid authentication token which can be obtained after successful login to the following URL via a web browser: https://console.cloud.vmware.com/csp/gateway/portal/#/user/account. 6 | REFRESH_TOKEN=xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx 7 | 8 | # Login with Refresh token and store Access token for future calls 9 | AUTH_RESPONSE=$(curl -s -X POST "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize" -H "accept: application/json" -H "content-type: application/x-www-form-urlencoded" -d "refresh_token=$REFRESH_TOKEN") 10 | ACCESS_TOKEN=$(echo $AUTH_RESPONSE | awk -F '"access_token":"' '{print $2}' | awk -F '","' '{print $1}') 11 | 12 | # List Orgs 13 | curl -s -X GET -H "Content-Type: application/json" "https://vmc.vmware.com/vmc/api/orgs" -H "csp-auth-token: $ACCESS_TOKEN" -------------------------------------------------------------------------------- /img/github-zip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nvibert/start-coding-today/2215f34f4e5baa9e1f8d8ac54e6b8a365c811e8f/img/github-zip.png -------------------------------------------------------------------------------- /python/connect-vcenter.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import urllib3 3 | from vmware.vapi.vsphere.client import create_vsphere_client 4 | session = requests.session() 5 | 6 | VC_NAME = 'localhost:8989' 7 | VC_USERNAME = 'foo' 8 | VC_PASSWORD = 'bar' 9 | # Disable cert verification for demo purpose. 10 | # This is not recommended in a production environment. 11 | session.verify = False 12 | 13 | # Disable the secure connection warning for demo purpose. 14 | # This is not recommended in a production environment. 15 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 16 | 17 | # Connect to a vCenter Server using username and password 18 | vsphere_client = create_vsphere_client(server=VC_NAME, username=VC_USERNAME, password=VC_PASSWORD, session=session) 19 | 20 | # List all VMs inside the vCenter Server 21 | vsphere_client.vcenter.VM.list() -------------------------------------------------------------------------------- /python/vcenter-REST-host.py: -------------------------------------------------------------------------------- 1 | # This file will not run directly, this code is intended to be pasted into vcenter-REST.py. 2 | # The student should be trying to figure out the code on their own and use this file as a reference if they get stuck. 3 | 4 | vc_host_url = VC_NAME + '/api/vcenter/host' 5 | response = requests.get(vc_host_url,headers=GET_HEADER) 6 | host_json = response.json() 7 | print('\n\nHosts found on vCenter',VC_NAME) 8 | for host in host_json: 9 | print(host['name'],host['power_state']) -------------------------------------------------------------------------------- /python/vcenter-REST.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | 4 | # Environment variables 5 | VC_USERNAME = '' 6 | VC_PASSWORD = '' 7 | VC_URL = '' 8 | 9 | # Prints out debugging information if set to true 10 | DEBUG_MODE = True 11 | 12 | # API header to use for the session token 13 | SESSION_HEADER = {"Content-Type": "application/json","Accept": "application/json"} 14 | 15 | # Build the API URL to retrieve a session token 16 | vc_session_url = VC_URL + '/rest/com/vmware/cis/session' 17 | if DEBUG_MODE: 18 | print('Session token URL:',vc_session_url) 19 | 20 | # Invoke the API to retrieve a session token 21 | response = requests.post(vc_session_url,headers=SESSION_HEADER,auth=(VC_USERNAME,VC_PASSWORD),verify=False) 22 | if DEBUG_MODE: 23 | print ('Session response status: ', response.status_code) 24 | 25 | # Save the JSON sent back by the API into a variable 26 | session_json = response.json() 27 | if DEBUG_MODE: 28 | print('Session JSON: ',session_json) 29 | 30 | # Extract the session token from the response JSON 31 | session_token = session_json['value'] 32 | if DEBUG_MODE: 33 | print('Session token: ', session_token) 34 | 35 | folder_filter_spec = {"type","VIRTUAL_MACHINE"} 36 | 37 | # Header for the list folders API call, passing it the session token that we retrieved earlier 38 | GET_HEADER = {"Content-Type": "application/json","Accept": "application/json","vmware-api-session-id":session_token} 39 | if DEBUG_MODE: 40 | print('GET_HEADER: ',GET_HEADER) 41 | 42 | # Build the API URL to list folders 43 | vc_folder_url = VC_URL + '/rest/vcenter/folder' 44 | if DEBUG_MODE: 45 | print('FOLDER URL:', vc_folder_url) 46 | 47 | # Invoke the API to list folders 48 | response = requests.get(vc_folder_url,headers=GET_HEADER,verify=False) 49 | if DEBUG_MODE: 50 | print ('Folder response status: ', response.status_code) 51 | 52 | # Save the JSON sent back by the API into a variable 53 | folder_json = response.json() 54 | if DEBUG_MODE: 55 | print ('Raw folder JSON:\n',folder_json) 56 | print ('Formatted folder JSON:\n',json.dumps(folder_json,indent=1),'\n\n') 57 | 58 | # Print the folder list 59 | print('All folders found on vCenter',VC_URL) 60 | for fldr in folder_json['value']: 61 | print(fldr['name'], '(',fldr['type'],')') 62 | 63 | # Print only VM folders 64 | print('\n\nVM folders found on vCenter',VC_URL) 65 | for fldr in folder_json['value']: 66 | if fldr['type'] == 'VIRTUAL_MACHINE': 67 | print(fldr['name'], '(',fldr['type'],')') 68 | 69 | # Now write the next set of code yourself using the above code as examples! 70 | # Print out the host name and power state 71 | # Host API path is /api/vcenter/host 72 | # If you get stuck, use the code in vcenter-REST-host.py to help you -------------------------------------------------------------------------------- /python/vmc-REST-segments.py: -------------------------------------------------------------------------------- 1 | ### List segments in VMC ### 2 | import requests 3 | import json 4 | 5 | # Enable DEBUG mode for verbose output 6 | DEBUG_MODE = True 7 | 8 | # Generate a token in the Cloud Services Portal 9 | REFRESH_TOKEN='' 10 | 11 | # Cloud services portal 12 | CSP_URL='https://console.cloud.vmware.com' 13 | VMC_URL='https://vmc.vmware.com' 14 | 15 | params = {'refresh_token': REFRESH_TOKEN} 16 | headers = {'Content-Type': 'application/json'} 17 | url = CSP_URL + '/csp/gateway/am/api/auth/api-tokens/authorize' 18 | response = requests.post(url,params=params,headers=headers) 19 | jsonResponse = response.json() 20 | access_token = jsonResponse['access_token'] 21 | 22 | # Build the URL to list segments 23 | url = 'https://nsx-xx-xx-xx-xxx.rp.vmwarevmc.com/vmc/reverse-proxy/api/orgs/xx/sddcs/xx/policy/api/v1/infra/tier-1s/cgw/segments' 24 | if DEBUG_MODE: 25 | print('\nSegment list URL:',url) 26 | 27 | # Build the headers for the GET request - we're using JSON, we pass the content type and the access token 28 | seg_list_headers = {'Content-Type': 'application/json','csp-auth-token':access_token} 29 | 30 | # Invoke the API - there are no parameters for this GET request, only headers 31 | response = requests.get(url,headers=seg_list_headers) 32 | 33 | # Retrieve the JSON response 34 | seg_json = response.json() 35 | if DEBUG_MODE: 36 | print('\nRaw Seg JSON:', seg_json) 37 | print('\nFormatted Seg JSON',json.dumps(seg_json,indent=2)) 38 | # This code writes the JSON to a file for easier reading 39 | with open('seg.json','w') as outfile: 40 | json.dump(seg_json,outfile,indent=2) 41 | 42 | # Print out segment details 43 | 44 | -------------------------------------------------------------------------------- /python/vmc-REST.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | 4 | # Enable DEBUG mode for verbose output 5 | DEBUG_MODE = True 6 | 7 | # Generate a token in the Cloud Services Portal 8 | REFRESH_TOKEN='' 9 | 10 | # Cloud services portal URL 11 | CSP_URL='https://console.cloud.vmware.com' 12 | VMC_URL='https://vmc.vmware.com' 13 | 14 | # The refresh token parameter 15 | # This is equivalent to the -d parameter that we pass into cURL: -d "refresh_token=$REFRESH_TOKEN" 16 | # Except here in Python we are passing JSON because Python dictionaries make it super simple to work with JSON 17 | params = {'refresh_token': REFRESH_TOKEN} 18 | if DEBUG_MODE: 19 | print ('Params:\n',json.dumps(params)) 20 | 21 | # The request header 22 | # This is equivalent to the -H parameter we pass into cURL: -H "content-type: application/x-www-form-urlencoded" 23 | # Here we're passing it JSON 24 | headers = {'Content-Type': 'application/json'} 25 | if DEBUG_MODE: 26 | print ('Headers:\n',json.dumps(headers)) 27 | 28 | # Create the URL. You could build this directly in the requests.post 29 | # We build it here to easily print it in debug mode 30 | url = CSP_URL + '/csp/gateway/am/api/auth/api-tokens/authorize' 31 | if DEBUG_MODE: 32 | print('Token Auth URL:',url) 33 | input('\n\nPress any key to continue') 34 | 35 | 36 | # Execute the API request using the python Requests library 37 | # This can look confusing if you're not used to Python syntax 38 | # The first argument is a required positional argument - you can't call an API without sending a URL! 39 | # The other two are called kwargs - or keyword arguments, the format of keyword=value 40 | # We pass the keyword 'params' on the left the value in the variable params on the right 41 | response = requests.post(url,params=params,headers=headers) 42 | jsonResponse = response.json() 43 | if DEBUG_MODE: 44 | print('\nRaw token JSON:\n',jsonResponse) 45 | print ('\nFormatted token JSON:\n',json.dumps(jsonResponse,indent=1),'\n\n') 46 | input('\n\nPress any key to continue') 47 | 48 | # Extract the access_token from the JSON into a variable 49 | access_token = jsonResponse['access_token'] 50 | if DEBUG_MODE: 51 | print('\nExtracted access token:', access_token) 52 | 53 | # Build the URL to list organizations 54 | url = VMC_URL + '/vmc/api/orgs' 55 | if DEBUG_MODE: 56 | print('\nOrg list URL:',url) 57 | 58 | # Build the headers for the GET request - we're using JSON, we pass the content type and the access token 59 | org_list_headers = {'Content-Type': 'application/json','csp-auth-token':access_token} 60 | if DEBUG_MODE: 61 | print('\nOrg list headers: ', org_list_headers) 62 | input('\n\nPress any key to continue') 63 | 64 | # Invoke the API - there are no parameters for this GET request, only headers 65 | response = requests.get(url,headers=org_list_headers) 66 | 67 | # Retrieve the JSON response 68 | org_json = response.json() 69 | if DEBUG_MODE: 70 | print('\nRaw Org JSON:', org_json) 71 | print('\nFormatted Org JSON',json.dumps(org_json,indent=2)) 72 | # This code writes the JSON to a file for easier reading 73 | with open('orgs.json','w') as outfile: 74 | json.dump(org_json,outfile,indent=2) 75 | input('\n\nPress any key to continue') 76 | 77 | # Print out the display_name for every org 78 | print('Organization display names: ') 79 | for org in org_json: 80 | print(org['display_name']) 81 | -------------------------------------------------------------------------------- /terraform/main.tf: -------------------------------------------------------------------------------- 1 | provider "vsphere" { 2 | user = "cloudadmin@vmc.local" 3 | password = "" 4 | vsphere_server = "vcenter.sddc-A-B-C-D.vmwarevmc.com" 5 | allow_unverified_ssl = true 6 | } 7 | 8 | data "vsphere_datacenter" "dc" { 9 | name = "SDDC-Datacenter" 10 | } 11 | 12 | 13 | resource "vsphere_folder" "folder" { 14 | path = "your_user_name_terraform_folder" 15 | type = "vm" 16 | datacenter_id = data.vsphere_datacenter.dc.id 17 | } 18 | --------------------------------------------------------------------------------