1
0
mirror of https://github.com/vmware/vsphere-automation-sdk-python.git synced 2024-11-22 09:39:58 -05:00

Initial version of vm-request-o-matic

This is a simple sample application that includes a web form that creates a VM in a VMware Cloud on AWS SDDC.
This commit is contained in:
Matt Dreyer 2018-03-01 15:44:53 -08:00
parent 8febd6904f
commit 157b3897f1
5 changed files with 315 additions and 0 deletions

Binary file not shown.

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 open to the world, 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,183 @@
"""
Simple web form that creates VMs in a VMware Cloud on AWS SDDC
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
"""
import requests #need this for Get/Post/Delete
import certifi #need this for HTTPS
import simplejson as json #need this for JSON
import uuid #need this to automatically name newly created VMs
# 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"
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)
#------------ Create a VM from an OVF stored in Content Library
def createVM(sddcID, tenantid, sessiontoken, vmID, vmName):
#first we need to get an authentaction token from vCenter
vCenterURL, vCenterAuthHeader = vCenterLogin(sddcID, tenantid, sessiontoken)
#Lets give our cow a name
vmname = vmName + "-" + str(uuid.uuid4())
#now lets create a VM from an OVF template stored in the Content Library
#first we need to create a deployment spec
deploymentspec = { \
"target": { \
"resource_pool_id": "resgroup-55", \
"host_id": "host-31", \
"folder_id": "group-v52" \
}, \
"deployment_spec": { \
"name": vmname, \
"accept_all_EULA": "true", \
"storage_mappings": [ \
{ \
"key": "dont-delete-this-key", \
"value": { \
"type": "DATASTORE", \
"datastore_id": "datastore-61", \
"provisioning": "thin" \
} \
} \
], \
"storage_provisioning": "thin", \
"storage_profile_id": "aa6d5a82-1c88-45da-85d3-3d74b91a5bad", \
} \
}
print("\nPlease wait, VM deployment is in process....")
myURL = vCenterURL + "rest/com/vmware/vcenter/ovf/library-item/id:" + vmID + "?~action=deploy"
response = requests.post(myURL, headers=vCenterAuthHeader, json=deploymentspec, timeout=None)
#print(response.status_code)
#print(response.text)
if response.status_code == 200:
print("Succesfully created a VM named: " + vmname )
else:
print("Failed to create a VM \n" + response.text)
return(vmname)
#--------------------------------------------
#---------------- Main ----------------------
#--------------------------------------------
def lambda_handler(event, context):
sddcID = "your sddc id goes here"
tenantID = "your tenant id goes here"
#Get our access token
sessiontoken = getAccessToken(strAccessKey)
#get our tenant ID if it wasn't hard coded at the top of the file
if tenantID == "":
tenantID = getTenantID(sessiontoken)
#grab the form input
vmType = event['vmtype']
emailAddress = event['emailaddress']
username = event['username']
vmName = emailAddress
#create a vm based on web form input
print("starting vm creation process for " + vmName)
vmName = createVM(sddcID, tenantID, sessiontoken, vmType, vmName)
print("created vm named: " + vmName)
feedback = "Congratulations, your VM named (" + vmName + ") is ready!"
return(feedback)
#testing only
#lambda_handler({'username': 'Matt Dreyer', 'emailaddress': 'matt.dreyer@gmail.com', 'vmtype': '40ff3b8c-f6c7-4aa3-8db8-bb631e16ffae'}, 0)

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB