VMware Cloud on AWS Integrations Demos - Code

Code from Re:Invent 2017 on integrations with AWS services. The
re:Invent session can be watched on youtube here:
https://www.youtube.com/watch?v=lGq806eej54
This commit is contained in:
Brian Graf
2018-03-09 10:46:46 -07:00
parent 58c110be5a
commit 009a298bff
5 changed files with 325 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>VMware Cloud on AWS VM Request-O-Matic</title><!-- Get a pretty style sheet -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div align="center"><img src="vmc-sticker.png" width="200"></div>
<h2 align="center">VM Request-O-Matic</h2>
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 col-sm-6 col-sm-push-3">
<p>Use this form to create a new VM on VMware Cloud on AWS</p>
<form id="vmForm" name="vmForm">
<div class="form-group">
<label for="username">Your Name</label> <input class="form-control" id="username" name="username" placeholder="Bob Bobber" required="" type="tel">
</div>
<div class="form-group">
<label for="emailaddress">Email Address</label> <input class="form-control" id="emailaddress" name="emailaddress" placeholder="Bob@bobber.com" required="" type="tel">
</div>
<div class="form-group">
<label for="vmtype">VM Type</label> <select class="form-control" id="vmtype" name="vmtype" required="">
<option selected value="40ff3b8c-f6c7-4aa3-8db8-bb631e16ffae">
Windows 10 Desktop (4 CPU, 4GB RAM, 25GB HDD)
</option>
<option value="37561477-a8c2-4aed-9fce-1bb38557c2b0">
Windows Server 2016 (8 CPU, 12GB RAM, 100GB HDD)
</option>
<option value="40ff3b8c-f6c7-4aa3-8db8-bb631e16ffae">
Ubuntu Desktop (4 CPU, 4GB RAM, 25GB HDD)
</option>
<option value="575fbc82-fb0f-4c1f-95c3-3b0fb0613b82">
Ubuntu Server (8 CPU, 12GB RAM, 100GB HDD)
</option>
</select>
</div><button class="btn btn-default" type="submit">Create a VM!</button>
</form>
</div>
<div class="hidden alert alert-success" id="success" role="alert">
<br>
<br>
Success! Your VM was created successfully, check your email for login instructions.
</div>
<div class="hidden alert alert-danger" id="error" role="alert">
<br>
<br>
Dang. Something went wrong, check your email for next steps.
</div>
</div>
</div><!-- get the AWS Javascript library -->
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.98.0.min.js">
</script>
<script>
// set up Amazon Cognito (create a federated identity pool)
// https://us-west-2.console.aws.amazon.com/cognito/create
// Initialize the Amazon Cognito credentials provider
AWS.config.region = 'us-west-2'; // Region
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'us-west-2:e93c4c86-240d-4966-86ef-e56cf60ba468',
});
function invokeLambda( e ){
<!-- pull the variables out of the form -->
var username = document.getElementById('username'),
emailaddress = document.getElementById('emailaddress');
var selectid = document.getElementById("vmtype");
var selectedvm = selectid.options[selectid.selectedIndex].value;
// create JSON object for parameters for invoking Lambda function
var lambdaParams = {
FunctionName : 'vm-request-o-matic',
InvocationType : 'RequestResponse',
LogType : 'None',
Payload: JSON.stringify({
username: username.value,
emailaddress: emailaddress.value,
vmtype: selectedvm})
};
// create variable to hold data returned by the Lambda function
var lambdaResults;
var lambda = new AWS.Lambda({region: 'us-west-2', apiVersion: '2015-03-31'});
e.preventDefault();
lambda.invoke(lambdaParams, function(error, data) {
if (error) {
prompt(error);
} else {
lambdaResults = JSON.parse(data.Payload);
prompt(lambdaResults);
}
});
};
document.getElementById('vmForm').addEventListener('submit', invokeLambda);
</script>
</body>
</html>

View File

@@ -0,0 +1,22 @@
This is a simple 'serverless application' that allows you to create a VM in
an SDDC on VMware Cloud on AWS using a few cool tools including: Lambda,
Cognito, S3, and VMware Cloud on AWS.
Matt Dreyer
August 16, 2017
To make this work you need to do the following:
1. Make sure that the vCenter in your SDDC is publicly accessible, or painfully configure Lambda
to run in an VPC and NAT to a specific IP address (which requires even more IAM roles for VPC access).
2. Create a working VM, and then Clone it to an OVF template in Content Library
3. Use the vCenter API browser to discover the UUID of the your OVF template
4. Update the HTML in index.html to match the UUID(s) of the VMs you wish to deploy
5. Create a new Lambda function and upload vm-request-form.zip as your code
6. Create a new Cognito "Federated Identity" for "anonymous access"
7. Update the javascript in index.html to match your new Cognito role
8. Create an S3 bucket and configure it for Webhosting
9. Upload index.html and vmc-sticker.png into your bucket
10. Muck with IAM until Lambda and Cognito get along together
(required Cognito role permissions are AWSLambdaExecute and AWSLambdaRole)

View File

@@ -0,0 +1,193 @@
"""
Basic Tests against the Skyscraper API
VMC API documentation available at https://vmc.vmware.com/swagger/index.html#/
CSP API documentation is available at https://saas.csp.vmware.com/csp/gateway/api-docs
vCenter API documentation is available at https://code.vmware.com/apis/191/vsphere-automation
Matt Dreyer
August 15, 2017
You can install python 3.6 from https://www.python.org/downloads/windows/
You can install the dependent python packages locally (handy for Lambda) with:
pip install requests -t . --upgrade
pip install simplejson -t . --upgrade
pip install certifi -t . --upgrade
pip install pyvim -t . --upgrade
pip install datetime -t . --upgrade
"""
import requests #need this for Get/Post/Delete
import simplejson as json #need this for JSON
import datetime #need this for a time stamp
# To use this script you need to create an OAuth Refresh token for your Org
# You can generate an OAuth Refresh Token using the tool at vmc.vmware.com
# https://console.cloud.vmware.com/csp/gateway/portal/#/user/tokens
strAccessKey = "your key goes here"
#where are our service end points
strProdURL = "https://vmc.vmware.com"
strCSPProdURL = "https://console.cloud.vmware.com"
slackURL = "https://hooks.slack.com/services/T6Mrrrrr/B6TSrrrrr/RUldlEzzeY0Dy3drrrrrr"
#make a datestamp
rightnow = str(datetime.datetime.now())
rightnow = rightnow.split(".")[0] #get rid of miliseconds
def getAccessToken(myKey):
params = {'refresh_token': myKey}
headers = {'Content-Type': 'application/json'}
response = requests.post('https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize', params=params, headers=headers)
json_response = response.json()
access_token = json_response['access_token']
# debug only
# print(response.status_code)
# print(response.json())
return access_token
#-------------------- Figure out which Org we are in
def getTenantID(sessiontoken):
myHeader = {'csp-auth-token' : sessiontoken}
response = requests.get( strProdURL + '/vmc/api/orgs', headers=myHeader)
# debug only
# print(response.status_code)
# print(response.json())
# parse the response to grab our tenant id
jsonResponse = response.json()
strTenant = str(jsonResponse[0]['id'])
return(strTenant)
#---------------Login to vCenter and get an API token
# this will only work if the MGW firewall rules are configured appropriately
def vCenterLogin(sddcID, tenantid, sessiontoken):
#Get the vCenter details from VMC
myHeader = {'csp-auth-token' : sessiontoken}
myURL = strProdURL + "/vmc/api/orgs/" + tenantid + "/sddcs/" + sddcID
response = requests.get(myURL, headers=myHeader)
jsonResponse = response.json()
vCenterURL = jsonResponse['resource_config']['vc_ip']
vCenterUsername = jsonResponse['resource_config']['cloud_username']
vCenterPassword = jsonResponse['resource_config']['cloud_password']
#Now get an API token from vcenter
myURL = vCenterURL + "rest/com/vmware/cis/session"
response = requests.post(myURL, auth=(vCenterUsername,vCenterPassword))
token = response.json()['value']
vCenterAuthHeader = {'vmware-api-session-id':token}
return(vCenterURL, vCenterAuthHeader)
#------------ Get vCenter inventory and post to slack
def getSDDCInventory(sddcID, tenantid, sessiontoken):
#first we need to get an authentication token from vCenter
vCenterURL, vCenterAuthHeader = vCenterLogin(sddcID, tenantid, sessiontoken)
#now let's get a VM count
# for all vms use this : myURL = vCenterURL + "rest/vcenter/vm"
# for management vms use this: myURL = vCenterURL + "rest/vcenter/vm?filter.resource_pools=resgroup-54"
# for workload vms use this: myURL = vCenterURL + "rest/vcenter/vm?filter.resource_pools=resgroup-55"
myURL = vCenterURL + "rest/vcenter/vm"
response = requests.get(myURL, headers=vCenterAuthHeader)
#deal with vAPI wrapping
vms = response.json()['value']
poweredon = []
poweredoff = []
for i in vms:
if i['power_state'] == "POWERED_ON":
poweredon.append(i['name'])
else:
poweredoff.append(i['name'])
vm_on = len(poweredon)
vm_off = len(poweredoff)
#next let's figure out how much space we have left on the datastore
myURL = vCenterURL + "rest/vcenter/datastore"
response = requests.get(myURL, headers=vCenterAuthHeader)
#grab the workload datastore
datastore = response.json()['value'][1]
ds_total = int(datastore['capacity'])
ds_free = int(datastore['free_space'])
usage = int((ds_free / ds_total) * 100)
freeTB = ( ds_free / 1024 / 1024 / 1024 / 1024)
jsonSlackMessage = {'text': \
"SDDC Inventory Report\n" + \
"\t " + str(vm_on) + " Virtual Machines Running\n" + \
"\t " + str(vm_off) + " Virtual Machines Powered Off\n" + \
"\t " + str(usage) + "% Datastore Capacity Remaining (" + str(int(freeTB)) + " TB)"}
postSlack(slackURL, jsonSlackMessage)
return()
#------------------ Post something to Slack
# Slack API info can be found at https://api.slack.com/incoming-webhooks
# https://api.slack.com/tutorials/slack-apps-hello-world
# Need to create a new App using the Slack API App Builder -- it only needs to do one thing - catch a webhook
def postSlack(slackURL, slackJSONData):
slackData = json.dumps(slackJSONData)
myHeader = {'Content-Type': 'application/json'}
response = requests.post(slackURL, slackData, headers=myHeader)
if response.status_code != 200:
raise ValueError(
'Request to slack returned an error %s, the response is:\n%s'
% (response.status_code, response.text)
)
return
#--------------------------------------------
#---------------- Main ----------------------
#--------------------------------------------
def lambda_handler(event, context):
sddcID = " your id goes here"
tenantID = "your tenant goes here"
#Get our access token
sessiontoken = getAccessToken(strAccessKey)
#get the inventory and dump it to
getSDDCInventory(sddcID, tenantID, sessiontoken)
return
#testing only
#lambda_handler(0, 0)