Milestone 5 Automation continued - zacharylongo/Tech-Journals GitHub Wiki
Automation Code
Includes functions to:
- View VM info
- Create VM's from template
- Delete a target VM
- Power on / off a VM
- Change a VM's network adapter
Reflection
-
This lab took an excruciating amount of time to complete due to my infamiliarity with Python
-
Many times I properly created a function but forgot to ask for input or display that a function complied correctly and did its expected task
-
I accidentally deleted my "save snapshot" function and forgot how I created it. It was functional.
-
Overall this lab was extremely beneficial to my understanding of python scripting and the effectiveness of my use of VScode.
Code (with annotations):
# Import Modules
import getpass # Used to securely input Vcenter password
from pyVim.connect import SmartConnect
from pyVmomi import vim # Imports the VMware vSphere API bindings
import ssl # Imports SSL module
# Define a list of valid network names
valid_networks = ["Network1", "Network2", "Network3"]
# Function to connect to the Vcenter Server
def connect_to_vcenter(vcenter_host, username, password):
try:
s = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
s.verify_mode = ssl.CERT_NONE
si = SmartConnect(host=vcenter_host, user=username, pwd=password, sslContext=s)
return si
except Exception as e:
print(f"Error connecting to vCenter: {str(e)}")
return None
# Function to retrieve names of all virtual machines in vCenter
def get_all_vm_names(si):
vm_names = []
if si is not None:
content = si.RetrieveContent()
view = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
for vm in view.view:
vm_names.append(vm.name)
view.Destroy()
return vm_names
# Function to allow the user to select a virtual machine from the list
def select_vm_to_view_info(vm_names):
print("Available VMs:")
for i, vm_name in enumerate(vm_names, 1):
print(f"{i}. {vm_name}") # Display a numbered list of available VM's
while True:
try:
choice = int(input("Select a VM (enter the number): "))
if 1 <= choice <= len(vm_names): # Check if the choice is within a valid range
return vm_names[choice - 1] # Subtract 1 here
else:
print("Invalid choice. Please select a valid number.")
except ValueError:
print("Invalid input. Please enter a number.")
# Function to retrieve information about a selected virtual machine by name
def get_vm_info_by_name(si, vm_name):
vm_info = []
if si is not None:
content = si.RetrieveContent()
view = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
for vm in view.view:
if vm.name == vm_name:
vm_info.append({
'Name': vm.name,
'Power State': vm.runtime.powerState,
'Number of CPUs': vm.config.hardware.numCPU,
'Memory (GB)': vm.config.hardware.memoryMB / 1024.0,
'IP Address': vm.summary.guest.ipAddress
})
view.Destroy()
return vm_info
# Function to power on a virtual machine by name
def power_on_vm(si, vm_name):
if si is not None:
content = si.RetrieveContent()
view = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
for vm in view.view:
if vm.name == vm_name:
if vm.runtime.powerState == vim.VirtualMachinePowerState.poweredOff:
task = vm.PowerOn()
print(f"Powering on VM: {vm_name}")
return task
else:
print(f"VM {vm_name} is already powered on.")
return None
view.Destroy()
# Function to power off a virtual machine by name
def power_off_vm(si, vm_name):
if si is not None:
content = si.RetrieveContent()
view = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
for vm in view.view:
if vm.name == vm_name:
if vm.runtime.powerState == vim.VirtualMachinePowerState.poweredOn:
task = vm.PowerOff()
print(f"Powering off VM: {vm_name}")
return task
else:
print(f"VM {vm_name} is already powered off.")
return None
view.Destroy()
def create_vm_from_template(si, template_name, vm_name, datastore, cluster, network):
if si is not None:
content = si.RetrieveContent()
datacenter = content.rootFolder.childEntity[0]
# List available templates
available_templates = content.viewManager.CreateContainerView(datacenter, [vim.VirtualMachine], True).view
available_templates = [template for template in available_templates if template.config.template]
if not available_templates:
print("No templates available")
return
print("Available Templates:")
for i, template in enumerate(available_templates, 1):
print(f"{i}. {template.name}")
# Prompt the user to select a template
while True:
try:
template_choice = int(input("Select a Template (enter the number): "))
if 1 <= template_choice <= len(available_templates):
selected_template = available_templates[template_choice - 1]
break
else:
print("Invalid choice. Please select a valid number.")
except ValueError:
print("Invalid input. Please enter a number.")
# List available datastores
available_datastores = content.viewManager.CreateContainerView(datacenter, [vim.Datastore], True).view
print("Available Datastores:")
for i, ds in enumerate(available_datastores, 1):
print(f"{i}. {ds.name}")
# Prompt the user to select a datastore
while True:
try:
datastore_choice = int(input("Select a Datastore (enter the number): "))
if 1 <= datastore_choice <= len(available_datastores):
selected_datastore = available_datastores[datastore_choice - 1]
break
else:
print("Invalid choice. Please select a valid number.")
except ValueError:
print("Invalid input. Please enter a number.")
# Prompt the user to enter the new VM name
vm_name = input("Enter the name for the new VM: ")
# Prompt the user to select a cluster
cluster_name = input("Enter the cluster name: ")
# Prompt the user to select a network
network_name = input("Enter the network name: ")
try:
relospec = vim.vm.RelocateSpec()
relospec.datastore = selected_datastore
relospec.pool = selected_template.resourcePool
clonespec = vim.vm.CloneSpec()
clonespec.location = relospec
clonespec.powerOn = False
clonespec.template = False
new_vm = selected_template.Clone(folder=datacenter.vmFolder, name=vm_name, spec=clonespec)
print(f"Creating VM: {vm_name} from template: {selected_template.name}")
except Exception as e:
print(f"Error creating VM from template: {str(e)}")
else:
print("Could not connect to vCenter.")
# Function to delete a virtual machine
def delete_vm(si, vm_name):
if si is not None:
content = si.RetrieveContent()
view = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
for vm in view.view:
if vm.name == vm_name:
try:
task = vm.Destroy()
print(f"Deleting VM: {vm_name}")
return task
except Exception as e:
print(f"Error deleting VM: {str(e)}")
return None
view.Destroy()
else:
print("Could not connect to vCenter.")
# Function to change a VM's network
def change_vm_network(si, vm_name, network):
if network in valid_networks:
if si is not None:
content = si.RetrieveContent()
view = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
for vm in view.view:
if vm.name == vm_name:
network_spec = vim.vm.device.VirtualDeviceSpec()
network_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
network_spec.device = vim.vm.device.VirtualVmxnet3()
network_spec.device.deviceInfo = vim.Description()
network_spec.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo()
network_spec.device.backing.useAutoDetect = False
network_spec.device.backing.network = get_network_by_name(content, network)
network_spec.device.wakeOnLanEnabled = True
edit_spec = vim.vm.ConfigSpec(deviceChange=[network_spec])
task = vm.ReconfigVM_Task(spec=edit_spec)
print(f"Changing network of VM {vm_name} to {network}")
return task
view.Destroy()
else:
print("Could not connect to vCenter.")
else:
print("Invalid network name. Please enter a valid network name.")
# Function to get network by name
def get_network_by_name(content, network_name):
for network in content.viewManager.CreateContainerView(content.rootFolder, [vim.Network], True).view:
if network.name == network_name:
return network
return None
# Main function to execute code
def main():
vcenter_host = "vcenter.zachary.longo.local" # Updated hostname
username = "zach-adm"
password = getpass.getpass("Enter your vCenter password: ")
si = connect_to_vcenter(vcenter_host, username, password)
if si is not None:
while True:
print("\nActions:")
print("1. View VM Information")
print("2. Power On VM")
print("3. Power Off VM")
print("4. Create VM from Template")
print("5. Delete VM")
print("6. Change VM Network")
print("7. Exit")
choice = input("Select an action (1/2/3/4/5/6/7): ")
if choice == '1':
# Code to view VM information (existing code)
vm_names = get_all_vm_names(si)
if not vm_names:
print("No VMs found in the vCenter.")
else:
selected_vm = select_vm_to_view_info(vm_names)
vm_info = get_vm_info_by_name(si, selected_vm)
if vm_info:
print("VM Information:")
print("VM Name: ", vm_info[0]['Name'])
print("Power State: ", vm_info[0]['Power State'])
print("Number of CPUs: ", vm_info[0]['Number of CPUs'])
print("Memory (GB): ", vm_info[0]['Memory (GB)'])
print("IP Address: ", vm_info[0]['IP Address'])
else:
print(f"No information found for VM: {selected_vm}")
elif choice == '2':
# Code to power on VM (existing code)
vm_names = get_all_vm_names(si)
if not vm_names:
print("No VMs found in the vCenter.")
else:
selected_vm = select_vm_to_view_info(vm_names)
power_on_vm(si, selected_vm)
elif choice == '3':
# Code to power off VM (existing code)
vm_names = get_all_vm_names(si)
if not vm_names:
print("No VMs found in the vCenter.")
else:
selected_vm = select_vm_to_view_info(vm_names)
power_off_vm(si, selected_vm)
elif choice == '4':
# Code to create VM from template
template_name = input("Enter the template name: ")
vm_name = input("Enter the name for the new VM: ")
datastore = input("Enter the datastore name: ")
cluster = input("Enter the cluster name: ")
network = input("Enter the network name: ")
create_vm_from_template(si, template_name, vm_name, datastore, cluster, network)
elif choice == '5':
# Code to delete VM
vm_names = get_all_vm_names(si)
if not vm_names:
print("No VMs found in the vCenter.")
else:
selected_vm = select_vm_to_view_info(vm_names)
delete_vm(si, selected_vm)
elif choice == '6':
# Code to change VM network
vm_names = get_all_vm_names(si)
if not vm_names:
print("No VMs found in the vCenter.")
else:
selected_vm = select_vm_to_view_info(vm_names)
network = input("Enter the new network name: ")
change_vm_network(si, selected_vm, network)
elif choice == '7':
break
else:
print("Invalid choice. Please select a valid option.")
else:
print("Could not connect to vCenter.")
if __name__ == "__main__":
main()