diff --git a/.travis.yml b/.travis.yml index 237fb909..5d95a6dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,8 @@ python: - "3.6" # command to install dependencies install: - - pip install -r requirements.txt --extra-index-url file://$PWD/lib --upgrade --ignore-installed six + - pip install -r requirements.txt --extra-index-url file://$PWD/lib --upgrade --ignore-installed six - pip install -r test-requirements.txt - pip install pycodestyle # command to run tests -script: pycodestyle samples/* +script: pycodestyle samples/*.py diff --git a/README.md b/README.md index e7be76bb..b666fbfd 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ [![Build Status](https://travis-ci.com/vmware/vsphere-automation-sdk-python.svg?token=v9mEJjcpDiQ9DrYbzyaQ&branch=master)](https://travis-ci.com/vmware/vsphere-automation-sdk-python) ## Table of Contents - [Abstract](#abstract) +- [Supported vCenter Releases](#supported-vcenter-releases) +- [VMware Cloud on AWS Support](#vmware-cloud-on-aws-support) - [Quick Start Guide](#quick-start-guide) - [Installing the required Python Packages](#installing-the-required-python-packages) - [Setting up a vSphere Test Environment](#setting-up-a-vsphere-test-environment) @@ -29,10 +31,13 @@ vSphere Automation and vSphere APIs. To support this combined use, the vSphere A samples require the vSphere Management SDK packages (pyVmomi) to be installed on the client. The samples have been developed to work with python 2.7.x and 3.3+ -## Supported vCenter Releases: +## Supported vCenter Releases vCenter 6.0 and 6.5. 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. +## VMware Cloud on AWS Support +The VMware Cloud on AWS API and samples are currently available as a preview and are subject to change in the future. + ## Quick Start Guide This document will walk you through getting up and running with the Python SDK Samples. Prior to running the samples you will need to setup a vCenter test environment and @@ -55,11 +60,13 @@ The required packages are: * pyVmomi * suds (suds-jurko for python3+) * vapi-client-bindings +* vmc-client-bindings +* vapi-vmc-client These dependencies are listed in the requirements.txt file and installed using "pip install"; For more details on how to install python packages using pip please refer to the [pip user guide](http://pip.readthedocs.io/en/latest/user_guide/). ```cmd -pip install -r requirements.txt --extra-index-url +pip install --upgrade --force-reinstall --no-cache -r requirements.txt --extra-index-url ``` **NOTE:** The SDK also requires OpenSSL 1.0.1+ if you want to connect to vSphere 6.5+ in order to support TLS1.1 & 1.2 diff --git a/doc/client.zip b/doc/client.zip index 03ae935d..a083ec77 100644 Binary files a/doc/client.zip and b/doc/client.zip differ diff --git a/doc/vmc.zip b/doc/vmc.zip new file mode 100644 index 00000000..3c79cff4 Binary files /dev/null and b/doc/vmc.zip differ diff --git a/lib/README.md b/lib/README.md index 8d4bc719..e7527cd4 100644 --- a/lib/README.md +++ b/lib/README.md @@ -4,5 +4,7 @@ For python developers, client libraries are supplied for testing and development Name | Description ------------------------------------| ------------- -vapi_runtime | vAPI runtime responsible for serialization/de-serialization of objects and wire protocol +vapi_runtime | vAPI runtime responsible for serialization/de-serialization of objects and wire protocol +vapi_vmc_client | Handles VMC CSP authentication process vapi_client_bindings | Client stubs for vSphere Automation APIs +vmc_client_bindings | Client stubs for VMware Cloud Services APIs diff --git a/lib/index.html b/lib/index.html index 65ea5ae4..b62d2eff 100644 --- a/lib/index.html +++ b/lib/index.html @@ -1,4 +1,10 @@ -Simple Index -vapi-client-bindings
-vapi-runtime
- + +Simple Index + + + +vapi-client-bindings
+vmc-client-bindings
+vapi-runtime
+ + diff --git a/lib/vapi-client-bindings/index.html b/lib/vapi-client-bindings/index.html index 22f2119f..29d479e8 100644 --- a/lib/vapi-client-bindings/index.html +++ b/lib/vapi-client-bindings/index.html @@ -1 +1 @@ -vapi_client_bindings-2.7.0-py2.py3-none-any.whl
+vapi_client_bindings-1.0.0-py2.py3-none-any.whl
diff --git a/lib/vapi-client-bindings/vapi_client_bindings-1.0.0-py2.py3-none-any.whl b/lib/vapi-client-bindings/vapi_client_bindings-1.0.0-py2.py3-none-any.whl new file mode 100644 index 00000000..f4c924e9 Binary files /dev/null and b/lib/vapi-client-bindings/vapi_client_bindings-1.0.0-py2.py3-none-any.whl differ diff --git a/lib/vapi-client-bindings/vapi_client_bindings-2.7.0-py2.py3-none-any.whl b/lib/vapi-client-bindings/vapi_client_bindings-2.7.0-py2.py3-none-any.whl deleted file mode 100644 index 0972146a..00000000 Binary files a/lib/vapi-client-bindings/vapi_client_bindings-2.7.0-py2.py3-none-any.whl and /dev/null differ diff --git a/lib/vapi-runtime/index.html b/lib/vapi-runtime/index.html index 139298c5..68a99568 100644 --- a/lib/vapi-runtime/index.html +++ b/lib/vapi-runtime/index.html @@ -1 +1 @@ -vapi_runtime-2.7.0-py2.py3-none-any.whl
+vapi_runtime-2.7.1-py2.py3-none-any.whl
diff --git a/lib/vapi-runtime/vapi_runtime-2.7.0-py2.py3-none-any.whl b/lib/vapi-runtime/vapi_runtime-2.7.0-py2.py3-none-any.whl deleted file mode 100644 index 5be57fde..00000000 Binary files a/lib/vapi-runtime/vapi_runtime-2.7.0-py2.py3-none-any.whl and /dev/null differ diff --git a/lib/vapi-runtime/vapi_runtime-2.7.1-py2.py3-none-any.whl b/lib/vapi-runtime/vapi_runtime-2.7.1-py2.py3-none-any.whl new file mode 100644 index 00000000..7175d584 Binary files /dev/null and b/lib/vapi-runtime/vapi_runtime-2.7.1-py2.py3-none-any.whl differ diff --git a/lib/vapi-vmc-client/index.html b/lib/vapi-vmc-client/index.html new file mode 100644 index 00000000..cca85202 --- /dev/null +++ b/lib/vapi-vmc-client/index.html @@ -0,0 +1 @@ +vapi_vmc_client-2.7.1-py2.py3-none-any.whl
diff --git a/lib/vapi-vmc-client/vapi_vmc_client-2.7.1-py2.py3-none-any.whl b/lib/vapi-vmc-client/vapi_vmc_client-2.7.1-py2.py3-none-any.whl new file mode 100644 index 00000000..d0d73c96 Binary files /dev/null and b/lib/vapi-vmc-client/vapi_vmc_client-2.7.1-py2.py3-none-any.whl differ diff --git a/lib/vapi_client_bindings-2.5.0.zip b/lib/vapi_client_bindings-2.5.0.zip deleted file mode 100644 index 01f6508b..00000000 Binary files a/lib/vapi_client_bindings-2.5.0.zip and /dev/null differ diff --git a/lib/vapi_common_client-2.5.0.zip b/lib/vapi_common_client-2.5.0.zip deleted file mode 100644 index fabafd1e..00000000 Binary files a/lib/vapi_common_client-2.5.0.zip and /dev/null differ diff --git a/lib/vapi_runtime-2.5.0.zip b/lib/vapi_runtime-2.5.0.zip deleted file mode 100644 index 412eee5b..00000000 Binary files a/lib/vapi_runtime-2.5.0.zip and /dev/null differ diff --git a/lib/vmc-client-bindings/index.html b/lib/vmc-client-bindings/index.html new file mode 100644 index 00000000..98de3ffc --- /dev/null +++ b/lib/vmc-client-bindings/index.html @@ -0,0 +1 @@ +vmc_client_bindings-1.0.0-py2.py3-none-any.whl
diff --git a/lib/vmc-client-bindings/vmc_client_bindings-1.0.0-py2.py3-none-any.whl b/lib/vmc-client-bindings/vmc_client_bindings-1.0.0-py2.py3-none-any.whl new file mode 100644 index 00000000..db412bbe Binary files /dev/null and b/lib/vmc-client-bindings/vmc_client_bindings-1.0.0-py2.py3-none-any.whl differ diff --git a/requirements.txt b/requirements.txt index fa853683..b84bd974 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,7 @@ pyVmomi >= 6.5 suds ; python_version < '3' suds-jurko ; python_version >= '3.0' -vapi-client-bindings +tabulate +vapi-client-bindings == 1.0.0 +vmc-client-bindings +vapi-vmc-client diff --git a/samples/README.md b/samples/README.md new file mode 100644 index 00000000..0abe48e6 --- /dev/null +++ b/samples/README.md @@ -0,0 +1,4 @@ +Directory | Description +----------------| ------------- +vSphere | Samples for vSphere APIs +vmc | Samples for VMware Cloud on AWS Services (currently in preview) diff --git a/samples/vmc/README.md b/samples/vmc/README.md new file mode 100644 index 00000000..74db60fb --- /dev/null +++ b/samples/vmc/README.md @@ -0,0 +1,9 @@ +# Samples for VMware Cloud on AWS APIs (currently in preview) + +The following table shows the sample sub-directories and their contents. + +Directory | Description +----------------| ------------- +orgs | Samples for operations on organizations +sddc | Samples for operations on SDDCs +helpers | Helper methods used by VMware Cloud on AWS API samples diff --git a/samples/vmc/__init__.py b/samples/vmc/__init__.py new file mode 100644 index 00000000..6c12653f --- /dev/null +++ b/samples/vmc/__init__.py @@ -0,0 +1,25 @@ +""" +* ******************************************************* +* Copyright VMware, Inc. 2017. 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.' + +# Required to distribute different parts of this +# package as multiple distribution +try: + import pkg_resources + + pkg_resources.declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + + __path__ = extend_path(__path__, __name__) # @ReservedAssignment diff --git a/samples/vmc/helpers/__init__.py b/samples/vmc/helpers/__init__.py new file mode 100644 index 00000000..6c12653f --- /dev/null +++ b/samples/vmc/helpers/__init__.py @@ -0,0 +1,25 @@ +""" +* ******************************************************* +* Copyright VMware, Inc. 2017. 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.' + +# Required to distribute different parts of this +# package as multiple distribution +try: + import pkg_resources + + pkg_resources.declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + + __path__ = extend_path(__path__, __name__) # @ReservedAssignment diff --git a/samples/vmc/helpers/vmc_task_helper.py b/samples/vmc/helpers/vmc_task_helper.py new file mode 100644 index 00000000..73163b10 --- /dev/null +++ b/samples/vmc/helpers/vmc_task_helper.py @@ -0,0 +1,64 @@ +""" +* ******************************************************* +* Copyright (c) VMware, Inc. 2017. 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.' + +from time import sleep +from tabulate import tabulate + +from com.vmware.vmc.model_client import Task + + +def wait_for_task(task_client, org_id, task_id, interval_sec=60): + """ + Helper method to wait for a task to finish + :param task_client: task client to query the task object + :param org_id: organization id + :param task_id: task id + :param interval_sec: task pulling interval_sec in sec + :return: True if task finished successfully, False otherwise. + """ + print('Wait for task {} to finish'.format(task_id)) + print('Checking task status every {} seconds'.format(interval_sec)) + + while True: + task = task_client.get(org_id, task_id) + + if task.status == Task.STATUS_FINISHED: + print('\nTask {} finished successfully'.format(task_id)) + return True + elif task.status == Task.STATUS_FAILED: + print('\nTask {} failed'.format(task_id)) + return False + elif task.status == Task.STATUS_CANCELED: + print('\nTask {} cancelled'.format(task_id)) + return False + else: + print("Estimated time remaining: {} minutes". + format(task.estimated_remaining_minutes)) + sleep(interval_sec) + + +def list_all_tasks(task_client, org_id): + """ + List all tasks in a given org + :param task_client: task client to query the task object + :param org_id: organization id + """ + tasks = task_client.list(org_id) + headers = ['ID', 'Status', 'Progress', 'Started', 'User'] + table = [] + for task in tasks: + table.append([task.id, task.status, task.progress_percent, + task.start_time, task.user_name]) + print(tabulate(table, headers)) diff --git a/samples/vmc/orgs/README.md b/samples/vmc/orgs/README.md new file mode 100644 index 00000000..1ae9ec6a --- /dev/null +++ b/samples/vmc/orgs/README.md @@ -0,0 +1,9 @@ +This directory contains samples for VMC organization APIs: + +Running the samples + + $ python organization_operations.py + +* Testbed Requirement: + - At least one org associated with the calling user. + diff --git a/samples/vmc/orgs/__init__.py b/samples/vmc/orgs/__init__.py new file mode 100644 index 00000000..6c12653f --- /dev/null +++ b/samples/vmc/orgs/__init__.py @@ -0,0 +1,25 @@ +""" +* ******************************************************* +* Copyright VMware, Inc. 2017. 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.' + +# Required to distribute different parts of this +# package as multiple distribution +try: + import pkg_resources + + pkg_resources.declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + + __path__ = extend_path(__path__, __name__) # @ReservedAssignment diff --git a/samples/vmc/orgs/organization_operations.py b/samples/vmc/orgs/organization_operations.py new file mode 100644 index 00000000..a41a5d1b --- /dev/null +++ b/samples/vmc/orgs/organization_operations.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python + +""" +* ******************************************************* +* Copyright (c) VMware, Inc. 2017. 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.' + +import requests +import argparse +import atexit +from tabulate import tabulate + +from vmware.vapi.vmc.client import create_vmc_client + + +class OperationsOnOrganizations(object): + """ + Demonstrates operations on organizations and features + + Sample Prerequisites: + - At least one org associated with the calling user. + """ + + def __init__(self): + self.org = None + self.feature = None + self.vmc_client = None + self.refresh_token = None + + def options(self): + parser = argparse.ArgumentParser( + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + parser.add_argument('refresh_token', + help='VMware Cloud API refresh token') + self.refresh_token = parser.parse_args().refresh_token + + def setup(self): + # Login to VMware Cloud on AWS + session = requests.Session() + self.vmc_client = create_vmc_client(self.refresh_token, session) + atexit.register(session.close) + + def list_orgs(self): + orgs = self.vmc_client.Orgs.list() + if not orgs: + raise ValueError('The sample requires at least one org associated' + 'with the calling user') + print("\n# Example: List organizations") + table = [] + for org in orgs: + table.append([org.id, org.display_name]) + print(tabulate(table, ['ID', 'Display Name'])) + + self.org = orgs[0] + + def get_org_detail(self): + org = self.org + print('\n# Example: List details of the first organization {}:'. + format(org.id)) + + headers = ['ID', 'Display Name', 'Name', 'Created', 'Updated', + 'Project State', 'SLA'] + data = [org.id, org.display_name, org.name, + org.created.strftime('%m/%d/%Y'), + org.updated.strftime('%m/%d/%Y'), + org.project_state, org.sla] + print(tabulate([data], headers)) + + +def main(): + org_operations = OperationsOnOrganizations() + org_operations.options() + org_operations.setup() + org_operations.list_orgs() + org_operations.get_org_detail() + + +if __name__ == '__main__': + main() diff --git a/samples/vmc/sddc/README.md b/samples/vmc/sddc/README.md new file mode 100644 index 00000000..0cf3af97 --- /dev/null +++ b/samples/vmc/sddc/README.md @@ -0,0 +1,14 @@ +This directory contains samples for VMC SDDC APIs: + +Use -h to check the required parameter for each sample: + + $ python add_remove_hosts.py -h + +To run the sample: + + $ python add_remove_hosts.py + +* Testbed Requirement: + - An organization associated with the calling user. + - A SDDC in the organization + diff --git a/samples/vmc/sddc/__init__.py b/samples/vmc/sddc/__init__.py new file mode 100644 index 00000000..6c12653f --- /dev/null +++ b/samples/vmc/sddc/__init__.py @@ -0,0 +1,25 @@ +""" +* ******************************************************* +* Copyright VMware, Inc. 2017. 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.' + +# Required to distribute different parts of this +# package as multiple distribution +try: + import pkg_resources + + pkg_resources.declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + + __path__ = extend_path(__path__, __name__) # @ReservedAssignment diff --git a/samples/vmc/sddc/add_remove_hosts.py b/samples/vmc/sddc/add_remove_hosts.py new file mode 100644 index 00000000..0581759c --- /dev/null +++ b/samples/vmc/sddc/add_remove_hosts.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python + +""" +* ******************************************************* +* Copyright (c) VMware, Inc. 2017. 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.' + +import argparse +import atexit +import requests + +from com.vmware.vmc.model_client import EsxConfig +from vmware.vapi.vmc.client import create_vmc_client + +from samples.vmc.helpers.vmc_task_helper import wait_for_task + + +class AddRemoveHosts(object): + """ + Demonstrates add and remove ESX hosts + + Sample Prerequisites: + - An organization associated with the calling user. + - A SDDC in the organization + """ + + def __init__(self): + self.sddc_id = None + self.org_id = None + self.vmc_client = None + self.refresh_token = None + self.interval_sec = None + + def options(self): + parser = argparse.ArgumentParser( + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + parser.add_argument('refresh_token', + help='VMware Cloud API refresh token') + + parser.add_argument('org_id', + help='Organization identifier.') + + parser.add_argument('sddc_id', + help='Sddc Identifier.') + + parser.add_argument('-i', '--interval_sec', + default=60, + help='Task pulling interval in sec') + + args = parser.parse_args() + + self.refresh_token = args.refresh_token + self.org_id = args.org_id + self.sddc_id = args.sddc_id + self.interval_sec = int(args.interval_sec) + + def setup(self): + + # Login to VMware Cloud on AWS + session = requests.Session() + self.vmc_client = create_vmc_client(self.refresh_token, session) + atexit.register(session.close) + + # Check if the organization exists + orgs = self.vmc_client.Orgs.list() + if self.org_id not in [org.id for org in orgs]: + raise ValueError("Org with ID {} doesn't exist".format(self.org_id)) + + # Check if the SDDC exists + sddcs = self.vmc_client.orgs.Sddcs.list(self.org_id) + if self.sddc_id not in [sddc.id for sddc in sddcs]: + raise ValueError("SDDC with ID {} doesn't exist in org {}". + format(self.sddc_id, self.org_id)) + + def add_host(self): + print('\n# Example: Add 1 ESX hosts to SDDC {}:'.format(self.sddc_id)) + esx_config = EsxConfig(1) + task = self.vmc_client.orgs.sddcs.Esxs.create(org=self.org_id, + sddc=self.sddc_id, + esx_config=esx_config) + wait_for_task(task_client=self.vmc_client.orgs.Tasks, + org_id=self.org_id, + task_id=task.id, + interval_sec=self.interval_sec) + + def remove_host(self): + print('\n# Example: Remove 1 ESX host from SDDC {}:'. + format(self.sddc_id)) + esx_config = EsxConfig(1) + task = self.vmc_client.orgs.sddcs.Esxs.create(org=self.org_id, + sddc=self.sddc_id, + esx_config=esx_config, + action='remove') + wait_for_task(task_client=self.vmc_client.orgs.Tasks, + org_id=self.org_id, + task_id=task.id, + interval_sec=self.interval_sec) + + +def main(): + esx_operations = AddRemoveHosts() + esx_operations.options() + esx_operations.setup() + esx_operations.add_host() + esx_operations.remove_host() + + +if __name__ == '__main__': + main() diff --git a/samples/vmc/sddc/create_delete_sddc.py b/samples/vmc/sddc/create_delete_sddc.py new file mode 100644 index 00000000..84a2ae6e --- /dev/null +++ b/samples/vmc/sddc/create_delete_sddc.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python + +""" +* ******************************************************* +* Copyright (c) VMware, Inc. 2017. 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.' + +import argparse +import atexit +import os +import requests +from random import randrange +from tabulate import tabulate + +from com.vmware.vmc.model_client import AwsSddcConfig +from vmware.vapi.vmc.client import create_vmc_client + +from samples.vmc.helpers.vmc_task_helper import wait_for_task + + +class CreateDeleteSDDC(object): + """ + Demonstrates create and delete a SDDC + + Sample Prerequisites: + - An organization associated with the calling user. + """ + + def __init__(self): + self.org_id = None + self.vmc_client = None + self.sddc_id = None + self.sddc_name = None + self.cleanup = None + self.refresh_token = None + self.interval_sec = None + + def option(self): + parser = argparse.ArgumentParser() + + parser.add_argument('refresh_token', + help='VMware Cloud API refresh token') + + parser.add_argument('org_id', + help='Organization identifier') + + parser.add_argument('-sn', '--sddc_name', + help="Name of the SDDC to be created. " + "Default is 'Sample SDDC xx'") + + parser.add_argument('-i', '--interval_sec', + default=60, + help='Task pulling interval in sec') + + parser.add_argument('-c', '--cleardata', + action='store_true', + help='Clean up after sample run') + + args = parser.parse_args() + + self.refresh_token = args.refresh_token + self.org_id = args.org_id + self.cleanup = args.cleardata + + self.sddc_name = args.sddc_name or \ + 'Sample SDDC {}'.format(randrange(100)) + self.interval_sec = int(args.interval_sec) + + def setup(self): + + # Login to VMware Cloud on AWS + session = requests.Session() + self.vmc_client = create_vmc_client(self.refresh_token, session) + atexit.register(session.close) + + # Check if the organization exists + orgs = self.vmc_client.Orgs.list() + if self.org_id not in [org.id for org in orgs]: + raise ValueError("Org with ID {} doesn't exist".format(self.org_id)) + + def create_sddc(self): + print('\n# Example: Create a SDDC ({}) in org {}:'. + format(self.sddc_name, self.org_id)) + + provider = os.environ.get('VMC_PROVIDER', 'AWS') + sddc_config = AwsSddcConfig( + region='US_WEST_2', num_hosts=1, name=self.sddc_name, + provider=provider) + task = self.vmc_client.orgs.Sddcs.create(org=self.org_id, + sddc_config=sddc_config) + wait_for_task(task_client=self.vmc_client.orgs.Tasks, + org_id=self.org_id, + task_id=task.id, + interval_sec=self.interval_sec) + + print('\n# Example: SDDC created:') + self.sddc_id = task.resource_id + sddc = self.vmc_client.orgs.Sddcs.get(self.org_id, self.sddc_id) + print(tabulate([[sddc.id, sddc.name]], ["ID", "Name"])) + + def delete_sddc(self): + print('\n# Example: Delete SDDC {} from org {}'.format(self.sddc_id, + self.org_id)) + task = self.vmc_client.orgs.Sddcs.delete(org=self.org_id, + sddc=self.sddc_id) + wait_for_task(task_client=self.vmc_client.orgs.Tasks, + org_id=self.org_id, + task_id=task.id, + interval_sec=self.interval_sec) + + print('\n# Example: Remaining SDDCs:'. + format(self.org_id)) + sddcs_list = self.vmc_client.orgs.Sddcs.list(self.org_id) + + headers = ["ID", "Name"] + table = [] + for sddc in sddcs_list: + table.append([sddc.id, sddc.name]) + print(tabulate(table, headers)) + + +def main(): + esx_operations = CreateDeleteSDDC() + esx_operations.option() + esx_operations.setup() + esx_operations.create_sddc() + if esx_operations.cleanup: + esx_operations.delete_sddc() + + +if __name__ == '__main__': + main() diff --git a/samples/vmc/tasks/__init__.py b/samples/vmc/tasks/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/samples/vmc/tasks/cancel_task.py b/samples/vmc/tasks/cancel_task.py new file mode 100644 index 00000000..e69de29b diff --git a/samples/vsphere/README.md b/samples/vsphere/README.md index 8d01a4dc..4022f027 100644 --- a/samples/vsphere/README.md +++ b/samples/vsphere/README.md @@ -1,4 +1,4 @@ -#Client Samples +# vSphere Samples The following table shows the sample sub-directories and their contents. diff --git a/samples/vsphere/__init__.py b/samples/vsphere/__init__.py index 42b8a50b..1a000fbf 100644 --- a/samples/vsphere/__init__.py +++ b/samples/vsphere/__init__.py @@ -12,14 +12,14 @@ """ __author__ = 'VMware, Inc.' -__copyright__ = 'Copyright 2016 VMware, Inc. All rights reserved.' - # Required to distribute different parts of this # package as multiple distribution try: import pkg_resources + pkg_resources.declare_namespace(__name__) except ImportError: from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) # @ReservedAssignment diff --git a/samples/vsphere/contentlibrary/README.md b/samples/vsphere/contentlibrary/README.md index 8d700455..5467e24c 100644 --- a/samples/vsphere/contentlibrary/README.md +++ b/samples/vsphere/contentlibrary/README.md @@ -7,6 +7,8 @@ This directory contains samples for Content Library APIs: * Basic workflow to publish and subscribe content libraries - publishsubscribe/library_publish_subscribe.py * Workflow to capture a virtual machine into a content library - vmcapture/vm_template_capture.py * Content library ISO item mount and unmount workflow - isomount/iso_mount.py + * Create a library item containing a native VMware virtual machine template - vmtemplate/create_vm_template.py + * Deploy a virtual machine from a library item containing a native VMware virtual machine template - vmtemplate/deploy_vm_template.py Running the samples @@ -21,6 +23,8 @@ The additional sample parameters are as follows (all parameters can be displayed * library_publish_subscribe.py --datastorename * vm_template_capture.py --datastorename --vmname * iso_mount.py --datastorename --vmname + * create_vm_template.py --datastorename --vmname + * deploy_vm_template.py --itemname --datacentername --foldername --resourcepoolname --datastorename * Testbed Requirement: - 1 vCenter Server diff --git a/samples/vsphere/contentlibrary/lib/cls_api_client.py b/samples/vsphere/contentlibrary/lib/cls_api_client.py index 217939fb..37ab1084 100644 --- a/samples/vsphere/contentlibrary/lib/cls_api_client.py +++ b/samples/vsphere/contentlibrary/lib/cls_api_client.py @@ -1,6 +1,6 @@ """ * ******************************************************* -* Copyright VMware, Inc. 2016. All Rights Reserved. +* Copyright VMware, Inc. 2016-2017. All Rights Reserved. * SPDX-License-Identifier: MIT * ******************************************************* * @@ -12,7 +12,7 @@ """ __author__ = 'VMware, Inc.' -__copyright__ = 'Copyright 2016 VMware, Inc. All rights reserved.' +__copyright__ = 'Copyright 2016-2017 VMware, Inc. All rights reserved.' __vcenter_version__ = '6.0+' from com.vmware.content_client import (Library, @@ -26,7 +26,7 @@ from com.vmware.content.library.item.updatesession_client import File as UpdateS from com.vmware.vcenter_client import VM from com.vmware.vcenter.iso_client import Image from com.vmware.vcenter.ovf_client import LibraryItem - +from com.vmware.vcenter.vm_template_client import LibraryItems as VmtxLibraryItem class ClsApiClient(object): """ @@ -73,6 +73,10 @@ class ClsApiClient(object): # Returns the service for managing subscribed library items self.subscribed_item_service = SubscribedItem(self.service_manager.stub_config) + # Returns the service for managing library items containing native + # VMware virtual machine templates + self.vmtx_service = VmtxLibraryItem(self.service_manager.stub_config) + # Creates the service that communicates with virtual machines self.vm_service = VM(self.service_manager.stub_config) # TODO: Add the other CLS services, eg. storage, config, type diff --git a/samples/vsphere/contentlibrary/lib/cls_api_helper.py b/samples/vsphere/contentlibrary/lib/cls_api_helper.py index 1a531c64..c677af6a 100644 --- a/samples/vsphere/contentlibrary/lib/cls_api_helper.py +++ b/samples/vsphere/contentlibrary/lib/cls_api_helper.py @@ -1,6 +1,6 @@ """ * ******************************************************* -* Copyright VMware, Inc. 2016. All Rights Reserved. +* Copyright VMware, Inc. 2016-2017. All Rights Reserved. * SPDX-License-Identifier: MIT * ******************************************************* * @@ -12,7 +12,7 @@ """ __author__ = 'VMware, Inc.' -__copyright__ = 'Copyright 2016 VMware, Inc. All rights reserved.' +__copyright__ = 'Copyright 2016-2017 VMware, Inc. All rights reserved.' __vcenter_version__ = '6.0+' import os @@ -25,7 +25,8 @@ except ImportError: import urllib.request as urllib2 from com.vmware.content_client import LibraryModel -from com.vmware.content.library_client import (ItemModel, +from com.vmware.content.library_client import (Item, + ItemModel, StorageBacking) from com.vmware.content.library.item_client import (DownloadSessionModel, UpdateSessionModel) @@ -249,3 +250,22 @@ class ClsApiHelper(object): raise Exception( 'timed out after waiting {0} seconds for file {1} to reach a terminal state'.format( timeout, file_name)) + + def get_item_id_by_name(self, name): + """ + Returns the identifier of the item with the given name. + + Args: + name (str): The name of item to look for + + Returns: + str: The item ID or None if the item is not found + """ + find_spec = Item.FindSpec(name=name) + item_ids = self.client.library_item_service.find(find_spec) + item_id = item_ids[0] if item_ids else None + if item_id: + print('Library item ID: {0}'.format(item_id)) + else: + print("Library item with name '{0}' not found".format(name)) + return item_id diff --git a/samples/vsphere/contentlibrary/ovfdeploy/deploy_ovf_template.py b/samples/vsphere/contentlibrary/ovfdeploy/deploy_ovf_template.py index 4f67d704..4d46a806 100644 --- a/samples/vsphere/contentlibrary/ovfdeploy/deploy_ovf_template.py +++ b/samples/vsphere/contentlibrary/ovfdeploy/deploy_ovf_template.py @@ -2,7 +2,7 @@ """ * ******************************************************* -* Copyright VMware, Inc. 2016. All Rights Reserved. +* Copyright VMware, Inc. 2016-2017. All Rights Reserved. * SPDX-License-Identifier: MIT * ******************************************************* * @@ -14,7 +14,7 @@ """ __author__ = 'VMware, Inc.' -__copyright__ = 'Copyright 2016 VMware, Inc. All rights reserved.' +__copyright__ = 'Copyright 2016-2017 VMware, Inc. All rights reserved.' __vcenter_version__ = '6.0+' try: @@ -24,7 +24,6 @@ except ImportError: import atexit -from com.vmware.content.library_client import Item from com.vmware.vcenter.ovf_client import LibraryItem from pyVmomi import vim @@ -94,15 +93,8 @@ class DeployOvfTemplate: deployment_target = LibraryItem.DeploymentTarget( resource_pool_id=cluster_obj.resourcePool._GetMoId()) - - # Find lib item id from given item name - find_spec = Item.FindSpec() - find_spec.name = self.lib_item_name - item_ids = self.client.library_item_service.find(find_spec) - assert (item_ids is not None and len(item_ids) > 0), ('No items found with name: {0}' - .format(self.lib_item_name)) - lib_item_id = item_ids[0] - + lib_item_id = self.helper.get_item_id_by_name(self.lib_item_name) + assert lib_item_id ovf_summary = self.client.ovf_lib_item_service.filter(ovf_library_item_id=lib_item_id, target=deployment_target) print('Found an OVF template :{0} to deploy.'.format(ovf_summary.name)) diff --git a/samples/vsphere/contentlibrary/vmtemplate/__init__.py b/samples/vsphere/contentlibrary/vmtemplate/__init__.py new file mode 100644 index 00000000..c4ef6922 --- /dev/null +++ b/samples/vsphere/contentlibrary/vmtemplate/__init__.py @@ -0,0 +1,26 @@ +""" +* ******************************************************* +* Copyright VMware, Inc. 2017. 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.' +__copyright__ = 'Copyright 2017 VMware, Inc. All rights reserved.' + + +# Required to distribute different parts of this +# package as multiple distribution +try: + import pkg_resources + pkg_resources.declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) # @ReservedAssignment diff --git a/samples/vsphere/contentlibrary/vmtemplate/create_vm_template.py b/samples/vsphere/contentlibrary/vmtemplate/create_vm_template.py new file mode 100644 index 00000000..8c756685 --- /dev/null +++ b/samples/vsphere/contentlibrary/vmtemplate/create_vm_template.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python + +""" +* ******************************************************* +* Copyright VMware, Inc. 2017. 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.' +__copyright__ = 'Copyright 2017 VMware, Inc. All rights reserved.' +__vcenter_version__ = '6.6.2+' + +from com.vmware.vcenter.vm_template_client import ( + LibraryItems as VmtxLibraryItem) + +from samples.vsphere.common.id_generator import rand +from samples.vsphere.common.sample_base import SampleBase +from samples.vsphere.contentlibrary.lib.cls_api_client import ClsApiClient +from samples.vsphere.contentlibrary.lib.cls_api_helper import ClsApiHelper +from samples.vsphere.vcenter.helper.vm_helper import get_vm + + +class CreateVmTemplate(SampleBase): + """ + Demonstrates how to create a library item containing a native VMware + virtual machine template from a virtual machine. + + Prerequisites: + - A virtual machine + - A datastore + """ + + def __init__(self): + SampleBase.__init__(self, self.__doc__) + self.servicemanager = None + self.client = None + self.helper = None + self.vm_name = None + self.datastore_name = None + self.library_name = 'demo-vmtx-lib' + self.item_name = None + self.item_id = None + + def _options(self): + self.argparser.add_argument('-vmname', '--vmname', + required=True, + help='The name of the source VM from ' + 'which to create a library item') + self.argparser.add_argument('-datastorename', '--datastorename', + required=True, + help='The name of the datastore in which ' + 'to create a library and native VM ' + 'template') + self.argparser.add_argument('-itemname', '--itemname', + help='The name of the library item to ' + 'create. The item will contain a ' + 'native VM template.') + + def _setup(self): + # Required arguments + self.vm_name = self.args.vmname + self.datastore_name = self.args.datastorename + + # Optional arguments + self.item_name = (self.args.itemname if self.args.itemname + else rand('vmtx-item-')) + + self.servicemanager = self.get_service_manager() + self.client = ClsApiClient(self.servicemanager) + self.helper = ClsApiHelper(self.client, self.skip_verification) + + def _execute(self): + # Get the identifier of the source VM + vm_id = get_vm(self.servicemanager.stub_config, self.vm_name) + assert vm_id + + # Create a library + storage_backings = self.helper.create_storage_backings( + self.servicemanager, self.datastore_name) + self.library_id = self.helper.create_local_library(storage_backings, + self.library_name) + + # Build the create specification + create_spec = VmtxLibraryItem.CreateSpec() + create_spec.source_vm = vm_id + create_spec.library = self.library_id + create_spec.name = self.item_name + + # Create a new library item from the source VM + self.item_id = self.client.vmtx_service.create(create_spec) + print("Created VM template item '{0}' with ID: {1}".format( + self.item_name, self.item_id)) + + # Retrieve the library item info + info = self.client.vmtx_service.get(self.item_id) + print('VM template guest OS: {0}'.format(info.guest_os)) + + def _cleanup(self): + if self.library_id: + self.client.local_library_service.delete(self.library_id) + print('Deleted library ID: {0}'.format(self.library_id)) + + +def main(): + sample = CreateVmTemplate() + sample.main() + + +if __name__ == '__main__': + main() diff --git a/samples/vsphere/contentlibrary/vmtemplate/deploy_vm_template.py b/samples/vsphere/contentlibrary/vmtemplate/deploy_vm_template.py new file mode 100644 index 00000000..09394e2b --- /dev/null +++ b/samples/vsphere/contentlibrary/vmtemplate/deploy_vm_template.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python + +""" +* ******************************************************* +* Copyright VMware, Inc. 2017. 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.' +__copyright__ = 'Copyright 2017 VMware, Inc. All rights reserved.' +__vcenter_version__ = '6.6.2+' + +from pyVmomi import vim +from com.vmware.vcenter.vm_template_client import ( + LibraryItems as VmtxLibraryItem) + +from samples.vsphere.common.id_generator import rand +from samples.vsphere.common.sample_base import SampleBase +from samples.vsphere.common.vim.helpers.get_datastore_by_name import ( + get_datastore_id) +from samples.vsphere.common.vim.helpers.vim_utils import ( + delete_object, get_obj_by_moId) +from samples.vsphere.contentlibrary.lib.cls_api_client import ClsApiClient +from samples.vsphere.contentlibrary.lib.cls_api_helper import ClsApiHelper +from samples.vsphere.vcenter.helper.folder_helper import get_folder +from samples.vsphere.vcenter.helper.resource_pool_helper import ( + get_resource_pool) + + +class DeployVmTemplate(SampleBase): + """ + Demonstrates how to deploy a virtual machine from a library item containing + a native VMware virtual machine template. + + Prerequisites: + - A library item containing a native VMware virtual machine template + - A datacenter + - A VM folder + - A datastore + """ + + def __init__(self): + SampleBase.__init__(self, self.__doc__) + self.servicemanager = None + self.client = None + self.helper = None + self.item_name = None + self.datacenter_name = None + self.folder_name = None + self.resource_pool_name = None + self.datastore_name = None + self.vm_name = None + self.vm_id = None + self.vm = None + + def _options(self): + self.argparser.add_argument('-itemname', '--itemname', + required=True, + help='The name of the library item ' + 'containing a native VM template to ' + 'be deployed') + self.argparser.add_argument('-datacentername', '--datacentername', + required=True, + help='The name of the datacenter in which ' + 'to deploy a VM') + self.argparser.add_argument('-foldername', '--foldername', + required=True, + help='The name of the VM folder in the ' + 'datacenter in which to place the ' + 'deployed VM') + self.argparser.add_argument('-resourcepoolname', '--resourcepoolname', + required=True, + help='The name of the resource pool in ' + 'the datacenter in which to place ' + 'the deployed VM') + self.argparser.add_argument('-datastorename', '--datastorename', + required=True, + help='The name of the datastore to store ' + 'the deployed VM home and disks') + self.argparser.add_argument('-vmname', '--vmname', + help='The name of the deployed VM') + + def _setup(self): + # Required arguments + self.item_name = self.args.itemname + self.datacenter_name = self.args.datacentername + self.folder_name = self.args.foldername + self.resource_pool_name = self.args.resourcepoolname + self.datastore_name = self.args.datastorename + + # Optional arguments + self.vm_name = self.args.vmname if self.args.vmname else rand('vm-') + + self.servicemanager = self.get_service_manager() + self.client = ClsApiClient(self.servicemanager) + self.helper = ClsApiHelper(self.client, self.skip_verification) + + def _execute(self): + # Get the identifiers of the resources used for deployment + item_id = self.helper.get_item_id_by_name(self.item_name) + assert item_id + folder_id = get_folder(self.servicemanager.stub_config, + self.datacenter_name, + self.folder_name) + assert folder_id + resource_pool_id = get_resource_pool(self.servicemanager.stub_config, + self.datacenter_name, + self.resource_pool_name) + assert resource_pool_id + datastore_id = get_datastore_id(self.servicemanager, + self.datastore_name) + assert datastore_id + + # Build the deployment specification + placement_spec = VmtxLibraryItem.PlacementSpec( + folder=folder_id, + resource_pool=resource_pool_id) + vm_home_storage_spec = VmtxLibraryItem.DeploySpecVmHomeStorage( + datastore=datastore_id) + disk_storage_spec = VmtxLibraryItem.DeploySpecDiskStorage( + datastore=datastore_id) + deploy_spec = VmtxLibraryItem.DeploySpec( + name=self.vm_name, + placement=placement_spec, + vm_home_storage=vm_home_storage_spec, + disk_storage=disk_storage_spec) + + # Deploy a virtual machine from the VM template item + self.vm_id = self.client.vmtx_service.deploy(item_id, deploy_spec) + self.vm = get_obj_by_moId(self.servicemanager.content, + [vim.VirtualMachine], self.vm_id) + print("Deployed VM '{0}' with ID: {1}".format(self.vm.name, + self.vm_id)) + + # Print a summary of the deployed VM + vm_summary = self.vm.summary.config + print('Guest OS: {0}'.format(vm_summary.guestId)) + print('{0} CPU(s)'.format(vm_summary.numCpu)) + print('{0} MB memory'.format(vm_summary.memorySizeMB)) + print('{0} disk(s)'.format(vm_summary.numVirtualDisks)) + print('{0} network adapter(s)'.format(vm_summary.numEthernetCards)) + + def _cleanup(self): + if self.vm: + delete_object(self.servicemanager.content, self.vm) + + +def main(): + sample = DeployVmTemplate() + sample.main() + + +if __name__ == '__main__': + main() diff --git a/samples/vsphere/vcenter/helper/resource_pool_helper.py b/samples/vsphere/vcenter/helper/resource_pool_helper.py index 76b63de6..fa24a929 100644 --- a/samples/vsphere/vcenter/helper/resource_pool_helper.py +++ b/samples/vsphere/vcenter/helper/resource_pool_helper.py @@ -20,16 +20,19 @@ from com.vmware.vcenter_client import ResourcePool from samples.vsphere.vcenter.helper import datacenter_helper -def get_resource_pool(stub_config, datacenter_name): +def get_resource_pool(stub_config, datacenter_name, resource_pool_name=None): """ - Returns the identifier of the first resourcepool in the datacenter + Returns the identifier of the resource pool with the given name or the + first resource pool in the datacenter if the name is not provided. """ datacenter = datacenter_helper.get_datacenter(stub_config, datacenter_name) if not datacenter: print("Datacenter '{}' not found".format(datacenter_name)) return None - filter_spec = ResourcePool.FilterSpec(datacenters=set([datacenter])) + names = set([resource_pool_name]) if resource_pool_name else None + filter_spec = ResourcePool.FilterSpec(datacenters=set([datacenter]), + names=names) resource_pool_svc = ResourcePool(stub_config) resource_pool_summaries = resource_pool_svc.list(filter_spec)