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+
|
The samples have been developed to work with python 2.7.x and 3.3+
|
||||||
|
|
||||||
## Supported OnPrem vCenter Releases
|
## 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.
|
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
|
## Supported NSX-T Releases
|
||||||
@ -214,8 +214,8 @@ $ python samples/vsphere/vcenter/vm/list_vms.py -v
|
|||||||
### vSphere API Documentation
|
### vSphere API Documentation
|
||||||
|
|
||||||
* [VMware Cloud on AWS vSphere (latest version)](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/cloud/index.html)
|
* [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/)
|
* [vSphere 7.0 Update 2 (latest)](https://vmware.github.io/vsphere-automation-sdk-python/vsphere/7.0.2.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)
|
* 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
|
### 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()
|
2
setup.py
2
setup.py
@ -5,7 +5,7 @@ import os
|
|||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
setup(name='vSphere Automation SDK',
|
setup(name='vSphere Automation SDK',
|
||||||
version='1.49.0',
|
version='1.50.0',
|
||||||
description='VMware vSphere Automation SDK for Python',
|
description='VMware vSphere Automation SDK for Python',
|
||||||
url='https://github.com/vmware/vsphere-automation-sdk-python',
|
url='https://github.com/vmware/vsphere-automation-sdk-python',
|
||||||
author='VMware, Inc.',
|
author='VMware, Inc.',
|
||||||
|
Loading…
Reference in New Issue
Block a user