mirror of
https://github.com/vmware/vsphere-automation-sdk-python.git
synced 2024-11-24 10:19:59 -05:00
commit
4d36739d3e
@ -21,7 +21,7 @@ samples require the vSphere Management SDK packages (pyVmomi) to be installed on
|
||||
The samples have been developed to work with python 2.7.x and 3.3+
|
||||
|
||||
## Supported OnPrem vCenter Releases
|
||||
vCenter 6.0, 6.5, 6.7, 7.0 and 7.0U1.
|
||||
vCenter 6.0, 6.5, 6.7, 7.0, 7.0U1 and 7.0U2.
|
||||
Certain APIs and samples that are introduced in 6.5 release, such as vCenter, Virtual Machine and Appliance Management. Please refer to the notes in each sample for detailed compatibility information.
|
||||
|
||||
## Supported NSX-T Releases
|
||||
@ -214,8 +214,8 @@ $ python samples/vsphere/vcenter/vm/list_vms.py -v
|
||||
### vSphere API Documentation
|
||||
|
||||
* [VMware Cloud on AWS vSphere (latest version)](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/cloud/index.html)
|
||||
* [vSphere 7.0 Update 1 (latest)](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/7.0.1.0/)
|
||||
* Previous releases: [7.0](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/7.0.0.1/) [6.7.0](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/6.7.0) [6.6.1](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/6.6.1) [6.5](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/6.5) [6.0](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/6.0)
|
||||
* [vSphere 7.0 Update 2 (latest)](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/7.0.2.0/)
|
||||
* Previous releases: [7.0 U1](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/7.0.1.0/) [7.0](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/7.0.0.1/) [6.7.0](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/6.7.0) [6.6.1](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/6.6.1) [6.5](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/6.5) [6.0](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/6.0)
|
||||
|
||||
### VMware Cloud on AWS API Documentation
|
||||
|
||||
|
302
samples/vsphere/vcenter/vm/guest/guest_ops.py
Normal file
302
samples/vsphere/vcenter/vm/guest/guest_ops.py
Normal file
@ -0,0 +1,302 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
* *******************************************************
|
||||
* Copyright (c) VMware, Inc. 2020. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
* *******************************************************
|
||||
*
|
||||
* DISCLAIMER. THIS PROGRAM IS PROVIDED TO YOU "AS IS" WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, WHETHER ORAL OR WRITTEN,
|
||||
* EXPRESS OR IMPLIED. THE AUTHOR SPECIFICALLY DISCLAIMS ANY IMPLIED
|
||||
* WARRANTIES OR CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY,
|
||||
* NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
"""
|
||||
|
||||
__author__ = 'VMware Inc.'
|
||||
__vcenter_version__ = 'VCenter 7.0 U2'
|
||||
|
||||
import os
|
||||
import ssl
|
||||
import time
|
||||
|
||||
from com.vmware.vcenter.vm.guest.filesystem_client import Transfers
|
||||
from com.vmware.vcenter.vm.guest_client import Credentials
|
||||
from com.vmware.vcenter.vm.guest_client import Processes
|
||||
from com.vmware.vcenter_client import VM
|
||||
from samples.vsphere.common import sample_cli
|
||||
from samples.vsphere.common import sample_util
|
||||
from samples.vsphere.common.ssl_helper import get_unverified_session
|
||||
from vmware.vapi.vsphere.client import create_vsphere_client
|
||||
|
||||
try:
|
||||
# Python 3
|
||||
from urllib.parse import urlparse
|
||||
import http.client as httpclient
|
||||
except ImportError:
|
||||
# Python 2
|
||||
from urlparse import urlparse
|
||||
import httplib as httpclient
|
||||
|
||||
|
||||
class GuestOps(object):
|
||||
"""
|
||||
Demonstrate the vAPI Guest Operations.
|
||||
|
||||
Show the basic procedure to start a program or process on a Linux
|
||||
guest VM and collect any output:
|
||||
- create a temporary directory and temporary files for the process
|
||||
stdout and stderr.
|
||||
- upload a script to the guest.
|
||||
- execute the script and collect the output.
|
||||
|
||||
Prerequisites:
|
||||
- vCenter
|
||||
- ESX host
|
||||
- running guest 'Photon-3.2-64-EFI-Open-VM-Tools-for-GuestOps-SDK'
|
||||
with open-vm-tools installed and running. The testbed created by
|
||||
samples/vsphere/vcenter/setup/main.py does not contain a guest
|
||||
with a runnable Linux or Windows OS.
|
||||
"""
|
||||
|
||||
# Create the Process.CreateSpec for initiating processes in the guest
|
||||
def _process_create_spec(self, path, args=None, dir=None, env={}):
|
||||
return Processes.CreateSpec(path=path,
|
||||
arguments=args,
|
||||
working_directory=dir,
|
||||
environment_variables=env)
|
||||
|
||||
# Create the Transfer.CreateSpec for the file transfer to/from the guest
|
||||
def _create_transfer_spec(self,
|
||||
path,
|
||||
attributes=None):
|
||||
return Transfers.CreateSpec(attributes=attributes,
|
||||
path=path)
|
||||
|
||||
# Create a FileAttributeCreateSpec for a generic (non-OS specific) guest
|
||||
def _fileAttributeCreateSpec_Plain(self,
|
||||
size,
|
||||
overwrite=None,
|
||||
last_modified=None,
|
||||
last_accessed=None):
|
||||
return Transfers.FileCreationAttributes(size,
|
||||
overwrite=overwrite,
|
||||
last_modified=last_modified,
|
||||
last_accessed=last_accessed)
|
||||
|
||||
# Create a FileAttributeCreateSpec for a linux (Posix) guest
|
||||
def _fileAttributeCreateSpec_Linux(self,
|
||||
size,
|
||||
overwrite=None,
|
||||
last_modified=None,
|
||||
last_accessed=None,
|
||||
owner_id=None,
|
||||
group_id=None,
|
||||
permissions=None):
|
||||
posix = Transfers.PosixFileAttributesCreateSpec(owner_id=owner_id,
|
||||
group_id=group_id,
|
||||
permissions=permissions)
|
||||
return Transfers.FileCreationAttributes(size,
|
||||
overwrite=overwrite,
|
||||
last_modified=last_modified,
|
||||
last_accessed=last_accessed,
|
||||
posix=posix)
|
||||
|
||||
def _download(self,
|
||||
url,
|
||||
expectedLen=None):
|
||||
urloptions = urlparse(url)
|
||||
# Skip server cert verification.
|
||||
# This is not recommended in production code.
|
||||
conn = httpclient.HTTPSConnection(urloptions.netloc,
|
||||
context=ssl._create_unverified_context())
|
||||
|
||||
conn.request("GET", urloptions.path + "?" + urloptions.query)
|
||||
res = conn.getresponse()
|
||||
if res.status != 200:
|
||||
print("GET request failed with errorcode : %s" % res.status)
|
||||
raise HTTPError(res.status, res.reason)
|
||||
body = res.read().decode()
|
||||
|
||||
return body
|
||||
|
||||
def _upload(self, url, body):
|
||||
urloptions = urlparse(url)
|
||||
conn = httpclient.HTTPSConnection(urloptions.netloc,
|
||||
context=ssl._create_unverified_context())
|
||||
|
||||
headers = {"Content-Length": len(body)}
|
||||
# Skip server cert verification.
|
||||
# This is not recommended in production code.
|
||||
conn.request("PUT", urloptions.path + "?" + urloptions.query,
|
||||
body,
|
||||
headers)
|
||||
res = conn.getresponse()
|
||||
if res.status != 200:
|
||||
print("PUT request failed with errorcode : %s" % res.status)
|
||||
raise HTTPError(res.status, res.reason)
|
||||
|
||||
return res
|
||||
|
||||
def __init__(self):
|
||||
# Create argument parser for standard inputs:
|
||||
# server, username, password, cleanup and skipverification
|
||||
parser = sample_cli.build_arg_parser()
|
||||
|
||||
# Add your custom input arguments
|
||||
parser.add_argument('--vm_name',
|
||||
action='store',
|
||||
help='Name of the testing vm')
|
||||
parser.add_argument('--root_user',
|
||||
action='store',
|
||||
help='Administrator account user name')
|
||||
parser.add_argument('--root_passwd',
|
||||
action='store',
|
||||
help='Administrator account password')
|
||||
|
||||
args = sample_util.process_cli_args(parser.parse_args())
|
||||
self.vm_name = args.vm_name
|
||||
self.root_user = args.root_user
|
||||
self.root_passwd = args.root_passwd
|
||||
|
||||
self.cleardata = args.cleardata
|
||||
|
||||
# Skip server cert verification if needed.
|
||||
# This is not recommended in production code.
|
||||
session = get_unverified_session() if args.skipverification else None
|
||||
|
||||
# Connect to vSphere client
|
||||
self.client = create_vsphere_client(server=args.server,
|
||||
username=args.username,
|
||||
password=args.password,
|
||||
session=session)
|
||||
|
||||
def run(self):
|
||||
# Using vAPI to find VM.
|
||||
filter_spec = VM.FilterSpec(names=set([self.vm_name]))
|
||||
vms = self.client.vcenter.VM.list(filter_spec)
|
||||
if len(vms) != 1:
|
||||
raise Exception('Could not locate the required VM with name ' +
|
||||
self.vm_name + '. Please create the vm first.')
|
||||
if vms[0].power_state != 'POWERED_ON':
|
||||
raise Exception('VM is not powered on: ' + vms[0].power_state)
|
||||
vm_id = vms[0].vm
|
||||
|
||||
# Check that vmtools svc (non-interactive user) is running.
|
||||
info = self.client.vcenter.vm.guest.Operations.get(vm_id)
|
||||
if info.guest_operations_ready is not True:
|
||||
raise Exception('VMware Tools/open-vm-tools is not running as required.')
|
||||
|
||||
# Establish the user credentials that will be needed for all Guest Ops
|
||||
# APIs.
|
||||
creds = Credentials(interactive_session=False,
|
||||
user_name=self.root_user,
|
||||
password=self.root_passwd,
|
||||
type=Credentials.Type.USERNAME_PASSWORD)
|
||||
|
||||
# Step 2 - Create a temporary directory from which to run the command
|
||||
# and capture any output
|
||||
tempDir = self.client.vcenter.vm.guest.filesystem.Directories.create_temporary(
|
||||
vm_id, creds, '', '', parent_path=None)
|
||||
|
||||
# Step 3 - Create temproary files to reveive stdout and stderr
|
||||
# as needed.
|
||||
stdout = self.client.vcenter.vm.guest.filesystem.Files.create_temporary(
|
||||
vm_id, creds, '', '.stdout', parent_path=tempDir)
|
||||
stderr = self.client.vcenter.vm.guest.filesystem.Files.create_temporary(
|
||||
vm_id, creds, '', '.stderr', parent_path=tempDir)
|
||||
|
||||
# Step 4 - (Optional) copy in the script to be run.
|
||||
# While optional, using this step to demo tranfer of a
|
||||
# file to a guest.
|
||||
scriptPath = self.client.vcenter.vm.guest.filesystem.Files.create_temporary(
|
||||
vm_id, creds, '', '.sh', tempDir)
|
||||
|
||||
# Create script contents and transfer to the guest.
|
||||
# TODO: Need generic pick up of script content
|
||||
baseFN = os.path.basename(scriptPath)
|
||||
script = ('#! /bin/bash\n'
|
||||
'# ' +
|
||||
baseFN + '\n'
|
||||
'\n'
|
||||
'sleep 5 # Adding a little length to the process.\n'
|
||||
'ps -ef\n'
|
||||
'echo\n'
|
||||
'rpm -qa | sort\n'
|
||||
'\n')
|
||||
print(script)
|
||||
attr = self._fileAttributeCreateSpec_Linux(size=len(script),
|
||||
overwrite=True,
|
||||
permissions='0755')
|
||||
spec = self._create_transfer_spec(path=scriptPath,
|
||||
attributes=attr)
|
||||
toURL = self.client.vcenter.vm.guest.filesystem.Transfers.create(vm_id,
|
||||
creds,
|
||||
spec)
|
||||
res = self._upload(toURL, script)
|
||||
|
||||
# Check that the uploaded file size is correct.
|
||||
info = self.client.vcenter.vm.guest.filesystem.Files.get(vm_id,
|
||||
creds,
|
||||
scriptPath)
|
||||
if info.size != len(script):
|
||||
raise Exception('Uploaded file size not as epected.')
|
||||
|
||||
# Step 5 - Start the program on the guest, capturing stdout and stderr
|
||||
# in the separate temp files obtained earlier.
|
||||
options = (" > " + stdout + " 2> " + stderr)
|
||||
|
||||
spec = self._process_create_spec(scriptPath,
|
||||
args=options,
|
||||
dir=tempDir)
|
||||
pid = self.client.vcenter.vm.guest.Processes.create(vm_id, creds, spec)
|
||||
print('process created with pid: %s\n' % pid)
|
||||
|
||||
# Step 6
|
||||
# Need a loop to wait for the process to finish to handle longer
|
||||
# running processes.
|
||||
while True:
|
||||
time.sleep(1.0)
|
||||
try:
|
||||
# List the single process for pid.
|
||||
result = self.client.vcenter.vm.guest.Processes.get(vm_id,
|
||||
creds,
|
||||
pid)
|
||||
if result.exit_code is not None:
|
||||
print('Command: ' + result.command)
|
||||
print('Exit code: %s\n' % result.exit_code)
|
||||
break
|
||||
if result.finished is None:
|
||||
print('Process with pid %s is still running.' % pid)
|
||||
continue
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
# Step 7 Copy out the results (stdout).
|
||||
spec = self._create_transfer_spec(path=stdout)
|
||||
# create the download URL
|
||||
fromURL = self.client.vcenter.vm.guest.filesystem.Transfers.create(vm_id,
|
||||
creds,
|
||||
spec)
|
||||
body = self._download(fromURL, expectedLen=info.size)
|
||||
print("----------- stdout ------------------")
|
||||
print(body)
|
||||
print("---------------------------------------")
|
||||
|
||||
# Optionally the contents of "stderr" could be downloaded.
|
||||
|
||||
# And finally, clean up the temporary files and directories on the
|
||||
# Linux guest. Deleting the temporary diretory and its contents.
|
||||
self.client.vcenter.vm.guest.filesystem.Directories.delete(vm_id,
|
||||
creds,
|
||||
tempDir,
|
||||
recursive=True)
|
||||
|
||||
|
||||
def main():
|
||||
sample = GuestOps()
|
||||
sample.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue
Block a user