diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index aff47a6..0000000 --- a/.coveragerc +++ /dev/null @@ -1,8 +0,0 @@ -[run] -branch = True -source = oslo_vmware -omit = oslo_vmware/tests/* - -[report] -ignore_errors = True -precision = 2 diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 7f191f8..0000000 --- a/.gitignore +++ /dev/null @@ -1,56 +0,0 @@ -*.py[cod] - -# C extensions -*.so - -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg -lib -lib64 - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -cover -.tox -nosetests.xml -.testrepository - -# Translations -*.mo - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject - -# Complexity -output/*.html -output/*/index.html - -# Sphinx -doc/build - -# pbr generates these -AUTHORS -ChangeLog - -# Editors -*~ -.*.swp -/doc/source/reference/api/ - -# reno build -releasenotes/build diff --git a/.gitreview b/.gitreview deleted file mode 100644 index 50c08fe..0000000 --- a/.gitreview +++ /dev/null @@ -1,4 +0,0 @@ -[gerrit] -host=review.openstack.org -port=29418 -project=openstack/oslo.vmware.git \ No newline at end of file diff --git a/.mailmap b/.mailmap deleted file mode 100644 index cc92f17..0000000 --- a/.mailmap +++ /dev/null @@ -1,3 +0,0 @@ -# Format is: -# -# \ No newline at end of file diff --git a/.testr.conf b/.testr.conf deleted file mode 100644 index fb62267..0000000 --- a/.testr.conf +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] -test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ - OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ - OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \ - ${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION -test_id_option=--load-list $IDFILE -test_list_option=--list \ No newline at end of file diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst deleted file mode 100644 index 2384f9d..0000000 --- a/CONTRIBUTING.rst +++ /dev/null @@ -1,20 +0,0 @@ -============= -Contributing -============= - -If you would like to contribute to the development of OpenStack, -you must follow the steps in this page: - - https://docs.openstack.org/infra/manual/developers.html - -Once those steps have been completed, changes to OpenStack -should be submitted for review via the Gerrit tool, following -the workflow documented at: - - https://docs.openstack.org/infra/manual/developers.html#development-workflow - -Pull requests submitted through GitHub will be ignored. - -Bugs should be filed on Launchpad, not GitHub: - - https://bugs.launchpad.net/oslo.vmware diff --git a/HACKING.rst b/HACKING.rst deleted file mode 100644 index 02ef182..0000000 --- a/HACKING.rst +++ /dev/null @@ -1,6 +0,0 @@ - Style Commandments -==================== - -Read the OpenStack Style Commandments in the following link - -https://docs.openstack.org/hacking/latest/ diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 67db858..0000000 --- a/LICENSE +++ /dev/null @@ -1,175 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. diff --git a/README b/README new file mode 100644 index 0000000..8fcd2b2 --- /dev/null +++ b/README @@ -0,0 +1,14 @@ +This project is no longer maintained. + +The contents of this repository are still available in the Git +source code management system. To see the contents of this +repository before it reached its end of life, please check out the +previous commit with "git checkout HEAD^1". + +For ongoing work on maintaining OpenStack packages in the Debian +distribution, please see the Debian OpenStack packaging team at +https://wiki.debian.org/OpenStack/. + +For any further questions, please email +openstack-dev@lists.openstack.org or join #openstack-dev on +Freenode. diff --git a/README.rst b/README.rst deleted file mode 100644 index ac7c88e..0000000 --- a/README.rst +++ /dev/null @@ -1,28 +0,0 @@ -======================== -Team and repository tags -======================== - -.. image:: https://governance.openstack.org/badges/oslo.vmware.svg - :target: https://governance.openstack.org/reference/tags/index.html - -.. Change things from this point on - -=================================================== - oslo.vmware --- VMware support code for OpenStack -=================================================== - -.. image:: https://img.shields.io/pypi/v/oslo.vmware.svg - :target: https://pypi.python.org/pypi/oslo.vmware/ - :alt: Latest Version - -.. image:: https://img.shields.io/pypi/dm/oslo.vmware.svg - :target: https://pypi.python.org/pypi/oslo.vmware/ - :alt: Downloads - -The Oslo VMware library provides support for common VMware operations -and APIs. - -* License: Apache License, Version 2.0 -* Documentation: https://docs.openstack.org/oslo.vmware/latest/ -* Source: https://git.openstack.org/cgit/openstack/oslo.vmware -* Bugs: https://bugs.launchpad.net/oslo.vmware diff --git a/babel.cfg b/babel.cfg deleted file mode 100644 index efceab8..0000000 --- a/babel.cfg +++ /dev/null @@ -1 +0,0 @@ -[python: **.py] diff --git a/doc/source/conf.py b/doc/source/conf.py deleted file mode 100644 index 7f21752..0000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,102 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import sys -import fileinput -import fnmatch - -sys.path.insert(0, os.path.abspath('../..')) -# -- General configuration ---------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [ - 'sphinx.ext.autodoc', - #'sphinx.ext.intersphinx', - 'openstackdocstheme' -] - -# openstackdocstheme options -repository_name = 'openstack/oslo.vmware' -bug_project = 'oslo.vmware' -bug_tag = '' - -# autodoc generation is a bit aggressive and a nuisance when doing heavy -# text edit cycles. -# execute "export SPHINX_DEBUG=1" in your terminal to disable - -# A list of glob-style patterns that should be excluded when looking for source -# files. -exclude_patterns = [ - 'api/tests.*', # avoid of docs generation from tests - 'api/oslo.vmware._*', # skip private modules -] - -# Prune the excluded patterns from the autoindex -PATH = 'api/autoindex.rst' -if os.path.isfile(PATH) and os.access(PATH, os.R_OK): - for line in fileinput.input(PATH, inplace=True): - found = False - for pattern in exclude_patterns: - if fnmatch.fnmatch(line, '*' + pattern[4:]): - found = True - if not found: - print line, - -# The suffix of source filenames. -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'oslo.vmware' -copyright = u'2014, OpenStack Foundation' - -# If true, '()' will be appended to :func: etc. cross-reference text. -add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -add_module_names = True - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# -- Options for HTML output -------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. Major themes that come with -# Sphinx are currently 'default' and 'sphinxdoc'. -# html_theme_path = ["."] -# html_theme = '_theme' -# html_static_path = ['static'] -html_theme = 'openstackdocs' - -html_last_updated_fmt = '%Y-%m-%d %H:%M' - -# Output file base name for HTML help builder. -htmlhelp_basename = '%sdoc' % project - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass -# [howto/manual]). -latex_documents = [ - ('index', - '%s.tex' % project, - u'%s Documentation' % project, - u'OpenStack Foundation', 'manual'), -] - -# Example configuration for intersphinx: refer to the Python standard library. -#intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/doc/source/contributor/index.rst b/doc/source/contributor/index.rst deleted file mode 100644 index b1cd2f3..0000000 --- a/doc/source/contributor/index.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../../CONTRIBUTING.rst diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100644 index b5e6d74..0000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,20 +0,0 @@ -=================================================== - oslo.vmware --- VMware support code for OpenStack -=================================================== - -The Oslo VMware library provides support for common VMware operations -and APIs. - -.. toctree:: - :maxdepth: 2 - - install/index - user/index - contributor/index - reference/index - -.. rubric:: Indices and tables - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/doc/source/install/index.rst b/doc/source/install/index.rst deleted file mode 100644 index e7a6f4d..0000000 --- a/doc/source/install/index.rst +++ /dev/null @@ -1,12 +0,0 @@ -============ -Installation -============ - -At the command line:: - - $ pip install oslo.vmware - -Or, if you have virtualenvwrapper installed:: - - $ mkvirtualenv oslo.vmware - $ pip install oslo.vmware diff --git a/doc/source/reference/index.rst b/doc/source/reference/index.rst deleted file mode 100644 index be6c6b7..0000000 --- a/doc/source/reference/index.rst +++ /dev/null @@ -1,9 +0,0 @@ -============= -API Reference -============= - -.. toctree:: - :maxdepth: 1 - :glob: - - api/* diff --git a/doc/source/user/history.rst b/doc/source/user/history.rst deleted file mode 100644 index f69be70..0000000 --- a/doc/source/user/history.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../../ChangeLog diff --git a/doc/source/user/index.rst b/doc/source/user/index.rst deleted file mode 100644 index b314802..0000000 --- a/doc/source/user/index.rst +++ /dev/null @@ -1,9 +0,0 @@ -================= -Using oslo.vmware -================= - -.. toctree:: - :maxdepth: 1 - - usage - history diff --git a/doc/source/user/usage.rst b/doc/source/user/usage.rst deleted file mode 100644 index 9561ffc..0000000 --- a/doc/source/user/usage.rst +++ /dev/null @@ -1,25 +0,0 @@ -======= - Usage -======= - -Example usage of getting a handle to a vSphere session and retrieving all the -ESX hosts in a server:: - - from oslo_vmware import api - from oslo_vmware import vim_util - - # Get a handle to a vSphere API session - session = api.VMwareAPISession( - '10.1.2.3', # vSphere host endpoint - 'administrator', # vSphere username - 'password', # vSphere password - 10, # Number of retries for connection failures in tasks - 0.1 # Poll interval for async tasks (in seconds) - ) - - # Example call to get all the managed objects of type "HostSystem" - # on the server. - result = session.invoke_api( - vim_util, # Handle to VIM utility module - 'get_objects', # API method name to invoke - session.vim, 'HostSystem', 100) # Params to API method (*args) diff --git a/oslo_vmware/__init__.py b/oslo_vmware/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oslo_vmware/_i18n.py b/oslo_vmware/_i18n.py deleted file mode 100644 index f17faa4..0000000 --- a/oslo_vmware/_i18n.py +++ /dev/null @@ -1,25 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""oslo.i18n integration module. - -See https://docs.openstack.org/oslo.i18n/latest/user/index.html - -""" - -import oslo_i18n - - -_translators = oslo_i18n.TranslatorFactory(domain='oslo_vmware') - -# The primary translation function using the well-known name "_" -_ = _translators.primary diff --git a/oslo_vmware/api.py b/oslo_vmware/api.py deleted file mode 100644 index 4224a96..0000000 --- a/oslo_vmware/api.py +++ /dev/null @@ -1,525 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Session and API call management for VMware ESX/VC server. - -This module contains classes to invoke VIM APIs. It supports -automatic session re-establishment and retry of API invocations -in case of connection problems or server API call overload. -""" - -import logging - -from oslo_concurrency import lockutils -from oslo_utils import excutils -from oslo_utils import reflection -import six - -from oslo_vmware._i18n import _ -from oslo_vmware.common import loopingcall -from oslo_vmware import exceptions -from oslo_vmware import pbm -from oslo_vmware import vim -from oslo_vmware import vim_util - - -LOG = logging.getLogger(__name__) - - -def _trunc_id(session_id): - """Returns truncated session id which is suitable for logging.""" - if session_id is not None: - return session_id[-5:] - - -# TODO(vbala) Move this class to excutils.py. -class RetryDecorator(object): - """Decorator for retrying a function upon suggested exceptions. - - The decorated function is retried for the given number of times, and the - sleep time between the retries is incremented until max sleep time is - reached. If the max retry count is set to -1, then the decorated function - is invoked indefinitely until an exception is thrown, and the caught - exception is not in the list of suggested exceptions. - """ - - def __init__(self, max_retry_count=-1, inc_sleep_time=10, - max_sleep_time=60, exceptions=()): - """Configure the retry object using the input params. - - :param max_retry_count: maximum number of times the given function must - be retried when one of the input 'exceptions' - is caught. When set to -1, it will be retried - indefinitely until an exception is thrown - and the caught exception is not in param - exceptions. - :param inc_sleep_time: incremental time in seconds for sleep time - between retries - :param max_sleep_time: max sleep time in seconds beyond which the sleep - time will not be incremented using param - inc_sleep_time. On reaching this threshold, - max_sleep_time will be used as the sleep time. - :param exceptions: suggested exceptions for which the function must be - retried - """ - self._max_retry_count = max_retry_count - self._inc_sleep_time = inc_sleep_time - self._max_sleep_time = max_sleep_time - self._exceptions = exceptions - self._retry_count = 0 - self._sleep_time = 0 - - def __call__(self, f): - func_name = reflection.get_callable_name(f) - - def _func(*args, **kwargs): - result = None - try: - if self._retry_count: - LOG.debug("Invoking %(func_name)s; retry count is " - "%(retry_count)d.", - {'func_name': func_name, - 'retry_count': self._retry_count}) - result = f(*args, **kwargs) - except self._exceptions: - with excutils.save_and_reraise_exception() as ctxt: - LOG.warning("Exception which is in the suggested list " - "of exceptions occurred while invoking " - "function: %s.", - func_name, - exc_info=True) - if (self._max_retry_count != -1 and - self._retry_count >= self._max_retry_count): - LOG.error("Cannot retry upon suggested exception " - "since retry count (%(retry_count)d) " - "reached max retry count " - "(%(max_retry_count)d).", - {'retry_count': self._retry_count, - 'max_retry_count': self._max_retry_count}) - else: - ctxt.reraise = False - self._retry_count += 1 - self._sleep_time += self._inc_sleep_time - return self._sleep_time - raise loopingcall.LoopingCallDone(result) - - def func(*args, **kwargs): - loop = loopingcall.DynamicLoopingCall(_func, *args, **kwargs) - evt = loop.start(periodic_interval_max=self._max_sleep_time) - return evt.wait() - - return func - - -class VMwareAPISession(object): - """Setup a session with the server and handles all calls made to it. - - Example: - api_session = VMwareAPISession('10.1.2.3', 'administrator', - 'password', 10, 0.1, - create_session=False, port=443) - result = api_session.invoke_api(vim_util, 'get_objects', - api_session.vim, 'HostSystem', 100) - """ - - def __init__(self, host, server_username, server_password, - api_retry_count, task_poll_interval, scheme='https', - create_session=True, wsdl_loc=None, pbm_wsdl_loc=None, - port=443, cacert=None, insecure=True, pool_size=10, - connection_timeout=None, op_id_prefix='oslo.vmware'): - """Initializes the API session with given parameters. - - :param host: ESX/VC server IP address or host name - :param port: port for connection - :param server_username: username of ESX/VC server admin user - :param server_password: password for param server_username - :param api_retry_count: number of times an API must be retried upon - session/connection related errors - :param task_poll_interval: sleep time in seconds for polling an - on-going async task as part of the API call - :param scheme: protocol-- http or https - :param create_session: whether to setup a connection at the time of - instance creation - :param wsdl_loc: VIM API WSDL file location - :param pbm_wsdl_loc: PBM service WSDL file location - :param cacert: Specify a CA bundle file to use in verifying a - TLS (https) server certificate. - :param insecure: Verify HTTPS connections using system certificates, - used only if cacert is not specified - :param pool_size: Maximum number of connections in http - connection pool - :param connection_timeout: Maximum time in seconds to wait for peer to - respond. - :param op_id_prefix: String prefix for the operation ID. - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException - """ - self._host = host - self._port = port - self._server_username = server_username - self._server_password = server_password - self._api_retry_count = api_retry_count - self._task_poll_interval = task_poll_interval - self._scheme = scheme - self._vim_wsdl_loc = wsdl_loc - self._pbm_wsdl_loc = pbm_wsdl_loc - self._session_id = None - self._session_username = None - self._vim = None - self._pbm = None - self._cacert = cacert - self._insecure = insecure - self._pool_size = pool_size - self._connection_timeout = connection_timeout - self._op_id_prefix = op_id_prefix - if create_session: - self._create_session() - - def pbm_wsdl_loc_set(self, pbm_wsdl_loc): - self._pbm_wsdl_loc = pbm_wsdl_loc - self._pbm = None - LOG.info('PBM WSDL updated to %s', pbm_wsdl_loc) - - @property - def vim(self): - if not self._vim: - self._vim = vim.Vim(protocol=self._scheme, - host=self._host, - port=self._port, - wsdl_url=self._vim_wsdl_loc, - cacert=self._cacert, - insecure=self._insecure, - pool_maxsize=self._pool_size, - connection_timeout=self._connection_timeout, - op_id_prefix=self._op_id_prefix) - return self._vim - - @property - def pbm(self): - if not self._pbm and self._pbm_wsdl_loc: - self._pbm = pbm.Pbm(protocol=self._scheme, - host=self._host, - port=self._port, - wsdl_url=self._pbm_wsdl_loc, - cacert=self._cacert, - insecure=self._insecure, - pool_maxsize=self._pool_size, - connection_timeout=self._connection_timeout, - op_id_prefix=self._op_id_prefix) - if self._session_id: - # To handle the case where pbm property is accessed after - # session creation. If pbm property is accessed before session - # creation, we set the cookie in _create_session. - self._pbm.set_soap_cookie(self._vim.get_http_cookie()) - return self._pbm - - @RetryDecorator(exceptions=(exceptions.VimConnectionException,)) - @lockutils.synchronized('oslo_vmware_api_lock') - def _create_session(self): - """Establish session with the server.""" - # Another thread might have created the session while the current one - # was waiting for the lock. - if self._session_id and self.is_current_session_active(): - LOG.debug("Current session: %s is active.", - _trunc_id(self._session_id)) - return - - session_manager = self.vim.service_content.sessionManager - # Login and create new session with the server for making API calls. - LOG.debug("Logging into host: %s.", self._host) - session = self.vim.Login(session_manager, - userName=self._server_username, - password=self._server_password) - self._session_id = session.key - # We need to save the username in the session since we may need it - # later to check active session. The SessionIsActive method requires - # the username parameter to be exactly same as that in the session - # object. We can't use the username used for login since the Login - # method ignores the case. - self._session_username = session.userName - LOG.info("Successfully established new session; session ID is " - "%s.", - _trunc_id(self._session_id)) - - # Set PBM client cookie. - if self._pbm is not None: - self._pbm.set_soap_cookie(self._vim.get_http_cookie()) - - def logout(self): - """Log out and terminate the current session.""" - if self._session_id: - LOG.info("Logging out and terminating the current session " - "with ID = %s.", - _trunc_id(self._session_id)) - try: - self.vim.Logout(self.vim.service_content.sessionManager) - self._session_id = None - except Exception: - LOG.exception("Error occurred while logging out and " - "terminating the current session with " - "ID = %s.", - _trunc_id(self._session_id)) - else: - LOG.debug("No session exists to log out.") - - def invoke_api(self, module, method, *args, **kwargs): - """Wrapper method for invoking APIs. - - The API call is retried in the event of exceptions due to session - overload or connection problems. - - :param module: module corresponding to the VIM API call - :param method: method in the module which corresponds to the - VIM API call - :param args: arguments to the method - :param kwargs: keyword arguments to the method - :returns: response from the API call - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - - @RetryDecorator(max_retry_count=self._api_retry_count, - exceptions=(exceptions.VimSessionOverLoadException, - exceptions.VimConnectionException)) - def _invoke_api(module, method, *args, **kwargs): - try: - api_method = getattr(module, method) - return api_method(*args, **kwargs) - except exceptions.VimFaultException as excep: - # If this is due to an inactive session, we should re-create - # the session and retry. - if exceptions.NOT_AUTHENTICATED in excep.fault_list: - # The NotAuthenticated fault is set by the fault checker - # due to an empty response. An empty response could be a - # valid response; for e.g., response for the query to - # return the VMs in an ESX server which has no VMs in it. - # Also, the server responds with an empty response in the - # case of an inactive session. Therefore, we need a way to - # differentiate between these two cases. - if self.is_current_session_active(): - LOG.debug("Returning empty response for " - "%(module)s.%(method)s invocation.", - {'module': module, - 'method': method}) - return [] - else: - # empty response is due to an inactive session - excep_msg = ( - _("Current session: %(session)s is inactive; " - "re-creating the session while invoking " - "method %(module)s.%(method)s.") % - {'session': _trunc_id(self._session_id), - 'module': module, - 'method': method}) - LOG.debug(excep_msg) - self._create_session() - raise exceptions.VimConnectionException(excep_msg, - excep) - else: - # no need to retry for other VIM faults like - # InvalidArgument - # Raise specific exceptions here if possible - if excep.fault_list: - LOG.debug("Fault list: %s", excep.fault_list) - fault = excep.fault_list[0] - clazz = exceptions.get_fault_class(fault) - if clazz: - raise clazz(six.text_type(excep), - details=excep.details) - raise - - except exceptions.VimConnectionException: - with excutils.save_and_reraise_exception(): - # Re-create the session during connection exception only - # if the session has expired. Otherwise, it could be - # a transient issue. - if not self.is_current_session_active(): - LOG.debug("Re-creating session due to connection " - "problems while invoking method " - "%(module)s.%(method)s.", - {'module': module, - 'method': method}) - self._create_session() - - return _invoke_api(module, method, *args, **kwargs) - - def is_current_session_active(self): - """Check if current session is active. - - :returns: True if the session is active; False otherwise - """ - LOG.debug("Checking if the current session: %s is active.", - _trunc_id(self._session_id)) - - is_active = False - try: - is_active = self.vim.SessionIsActive( - self.vim.service_content.sessionManager, - sessionID=self._session_id, - userName=self._session_username) - except exceptions.VimException as ex: - LOG.debug("Error: %(error)s occurred while checking whether the " - "current session: %(session)s is active.", - {'error': six.text_type(ex), - 'session': _trunc_id(self._session_id)}) - - return is_active - - def wait_for_task(self, task): - """Waits for the given task to complete and returns the result. - - The task is polled until it is done. The method returns the task - information upon successful completion. In case of any error, - appropriate exception is raised. - - :param task: managed object reference of the task - :returns: task info upon successful completion of the task - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - loop = loopingcall.FixedIntervalLoopingCall(self._poll_task, task) - evt = loop.start(self._task_poll_interval) - LOG.debug("Waiting for the task: %s to complete.", task) - return evt.wait() - - def _poll_task(self, task): - """Poll the given task until completion. - - If the task completes successfully, the method returns the task info - using the input event (param done). In case of any error, appropriate - exception is set in the event. - - :param task: managed object reference of the task - """ - try: - # we poll tasks too often, so skip logging the opID as it generates - # too much noise in the logs - task_info = self.invoke_api(vim_util, - 'get_object_property', - self.vim, - task, - 'info', - skip_op_id=True) - except exceptions.VimException: - with excutils.save_and_reraise_exception(): - LOG.exception("Error occurred while reading info of " - "task: %s.", - task) - else: - task_detail = {'id': task.value} - # some internal tasks do not have 'name' set - if getattr(task_info, 'name', None): - task_detail['name'] = task_info.name - - if task_info.state in ['queued', 'running']: - if hasattr(task_info, 'progress'): - LOG.debug("Task: %(task)s progress is %(progress)s%%.", - {'task': task_detail, - 'progress': task_info.progress}) - elif task_info.state == 'success': - def get_completed_task(): - complete_time = getattr(task_info, 'completeTime', None) - if complete_time: - duration = complete_time - task_info.queueTime - task_detail['duration_secs'] = duration.total_seconds() - return task_detail - LOG.debug("Task: %s completed successfully.", - get_completed_task()) - raise loopingcall.LoopingCallDone(task_info) - else: - error_msg = six.text_type(task_info.error.localizedMessage) - error = task_info.error - name = error.fault.__class__.__name__ - fault_class = exceptions.get_fault_class(name) - if fault_class: - task_ex = fault_class(error_msg) - else: - task_ex = exceptions.VimFaultException([name], - error_msg) - raise task_ex - - def wait_for_lease_ready(self, lease): - """Waits for the given lease to be ready. - - This method return when the lease is ready. In case of any error, - appropriate exception is raised. - - :param lease: lease to be checked for - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - loop = loopingcall.FixedIntervalLoopingCall(self._poll_lease, lease) - evt = loop.start(self._task_poll_interval) - LOG.debug("Waiting for the lease: %s to be ready.", lease) - evt.wait() - - def _poll_lease(self, lease): - """Poll the state of the given lease. - - When the lease is ready, the event (param done) is notified. In case - of any error, appropriate exception is set in the event. - - :param lease: lease whose state is to be polled - """ - try: - state = self.invoke_api(vim_util, - 'get_object_property', - self.vim, - lease, - 'state', - skip_op_id=True) - except exceptions.VimException: - with excutils.save_and_reraise_exception(): - LOG.exception("Error occurred while checking " - "state of lease: %s.", - lease) - else: - if state == 'ready': - LOG.debug("Lease: %s is ready.", lease) - raise loopingcall.LoopingCallDone() - elif state == 'initializing': - LOG.debug("Lease: %s is initializing.", lease) - elif state == 'error': - LOG.debug("Invoking VIM API to read lease: %s error.", - lease) - error_msg = self._get_error_message(lease) - excep_msg = _("Lease: %(lease)s is in error state. Details: " - "%(error_msg)s.") % {'lease': lease, - 'error_msg': error_msg} - LOG.error(excep_msg) - raise exceptions.VimException(excep_msg) - else: - # unknown state - excep_msg = _("Unknown state: %(state)s for lease: " - "%(lease)s.") % {'state': state, - 'lease': lease} - LOG.error(excep_msg) - raise exceptions.VimException(excep_msg) - - def _get_error_message(self, lease): - """Get error message associated with the given lease.""" - try: - return self.invoke_api(vim_util, - 'get_object_property', - self.vim, - lease, - 'error') - except exceptions.VimException: - LOG.warning("Error occurred while reading error message for " - "lease: %s.", - lease, - exc_info=True) - return "Unknown" diff --git a/oslo_vmware/common/__init__.py b/oslo_vmware/common/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oslo_vmware/common/loopingcall.py b/oslo_vmware/common/loopingcall.py deleted file mode 100644 index 489b198..0000000 --- a/oslo_vmware/common/loopingcall.py +++ /dev/null @@ -1,144 +0,0 @@ -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# Copyright 2011 Justin Santa Barbara -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import logging -import sys - -from eventlet import event -from eventlet import greenthread -from oslo_utils import timeutils - - -LOG = logging.getLogger(__name__) - - -class LoopingCallDone(Exception): - """Exception to break out and stop a LoopingCall. - - The poll-function passed to LoopingCall can raise this exception to - break out of the loop normally. This is somewhat analogous to - StopIteration. - - An optional return-value can be included as the argument to the exception; - this return-value will be returned by LoopingCall.wait() - - """ - - def __init__(self, retvalue=True): - """:param retvalue: Value that LoopingCall.wait() should return.""" - self.retvalue = retvalue - - -class LoopingCallBase(object): - def __init__(self, f=None, *args, **kw): - self.args = args - self.kw = kw - self.f = f - self._running = False - self.done = None - - def stop(self): - self._running = False - - def wait(self): - return self.done.wait() - - -class FixedIntervalLoopingCall(LoopingCallBase): - """A fixed interval looping call.""" - - def start(self, interval, initial_delay=None): - self._running = True - done = event.Event() - - def _inner(): - if initial_delay: - greenthread.sleep(initial_delay) - - try: - while self._running: - start = timeutils.utcnow() - self.f(*self.args, **self.kw) - end = timeutils.utcnow() - if not self._running: - break - delay = interval - timeutils.delta_seconds(start, end) - if delay <= 0: - LOG.warning('task run outlasted interval ' - 'by %s sec', - -delay) - greenthread.sleep(delay if delay > 0 else 0) - except LoopingCallDone as e: - self.stop() - done.send(e.retvalue) - except Exception: - LOG.exception('in fixed duration looping call') - done.send_exception(*sys.exc_info()) - return - else: - done.send(True) - - self.done = done - - greenthread.spawn_n(_inner) - return self.done - - -# TODO(mikal): this class name is deprecated in Havana and should be removed -# in the I release -LoopingCall = FixedIntervalLoopingCall - - -class DynamicLoopingCall(LoopingCallBase): - """A looping call which sleeps until the next known event. - - The function called should return how long to sleep for before being - called again. - """ - - def start(self, initial_delay=None, periodic_interval_max=None): - self._running = True - done = event.Event() - - def _inner(): - if initial_delay: - greenthread.sleep(initial_delay) - - try: - while self._running: - idle = self.f(*self.args, **self.kw) - if not self._running: - break - - if periodic_interval_max is not None: - idle = min(idle, periodic_interval_max) - LOG.debug('Dynamic looping call sleeping for %.02f ' - 'seconds', idle) - greenthread.sleep(idle) - except LoopingCallDone as e: - self.stop() - done.send(e.retvalue) - except Exception: - done.send_exception(*sys.exc_info()) - return - else: - done.send(True) - - self.done = done - - greenthread.spawn(_inner) - return self.done diff --git a/oslo_vmware/constants.py b/oslo_vmware/constants.py deleted file mode 100644 index d166d4e..0000000 --- a/oslo_vmware/constants.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -""" -Shared constants across the VMware ecosystem. -""" - -# Datacenter path for HTTP access to datastores if the target server is an ESX/ -# ESXi system: http://goo.gl/B5Htr8 for more information. -ESX_DATACENTER_PATH = 'ha-datacenter' - -# User Agent for HTTP requests between OpenStack and vCenter. -USER_AGENT = 'OpenStack-ESX-Adapter' - -# Key of the cookie header when using a SOAP session. -SOAP_COOKIE_KEY = 'vmware_soap_session' - -# Key of the cookie header when using a CGI session. -CGI_COOKIE_KEY = 'vmware_cgi_ticket' diff --git a/oslo_vmware/exceptions.py b/oslo_vmware/exceptions.py deleted file mode 100644 index 4018a82..0000000 --- a/oslo_vmware/exceptions.py +++ /dev/null @@ -1,306 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Exception definitions. -""" - -import logging - -import six - -from oslo_vmware._i18n import _ - -LOG = logging.getLogger(__name__) - -ALREADY_EXISTS = 'AlreadyExists' -CANNOT_DELETE_FILE = 'CannotDeleteFile' -DUPLICATE_NAME = 'DuplicateName' -FILE_ALREADY_EXISTS = 'FileAlreadyExists' -FILE_FAULT = 'FileFault' -FILE_LOCKED = 'FileLocked' -FILE_NOT_FOUND = 'FileNotFound' -INVALID_POWER_STATE = 'InvalidPowerState' -INVALID_PROPERTY = 'InvalidProperty' -NO_DISK_SPACE = 'NoDiskSpace' -NO_PERMISSION = 'NoPermission' -NOT_AUTHENTICATED = 'NotAuthenticated' -SECURITY_ERROR = "SecurityError" -MANAGED_OBJECT_NOT_FOUND = 'ManagedObjectNotFound' -TASK_IN_PROGRESS = 'TaskInProgress' -TOOLS_UNAVAILABLE = 'ToolsUnavailable' - - -class VMwareDriverException(Exception): - """Base oslo.vmware exception - - To correctly use this class, inherit from it and define - a 'msg_fmt' property. That msg_fmt will get printf'd - with the keyword arguments provided to the constructor. - - """ - msg_fmt = _("An unknown exception occurred.") - - if six.PY2: - __str__ = lambda self: six.text_type(self).encode('utf8') - __unicode__ = lambda self: self.description - else: - __str__ = lambda self: self.description - - def __init__(self, message=None, details=None, **kwargs): - - if message is not None and isinstance(message, list): - # we need this to protect against developers using - # this method like VimFaultException - raise ValueError(_("exception message must not be a list")) - - if details is not None and not isinstance(details, dict): - raise ValueError(_("details must be a dict")) - - self.kwargs = kwargs - self.details = details - self.cause = None - - if not message: - try: - message = self.msg_fmt % kwargs - except Exception: - # kwargs doesn't match a variable in the message - # log the issue and the kwargs - LOG.exception('Exception in string format operation') - for name, value in six.iteritems(kwargs): - LOG.error("%(name)s: %(value)s", - {'name': name, 'value': value}) - # at least get the core message out if something happened - message = self.msg_fmt - - self.message = message - super(VMwareDriverException, self).__init__(message) - - @property - def msg(self): - return self.message - - @property - def description(self): - # NOTE(jecarey): self.msg and self.cause may be i18n objects - # that do not support str or concatenation, but can be used - # as replacement text. - descr = six.text_type(self.msg) - if self.cause: - descr += '\nCause: ' + six.text_type(self.cause) - return descr - - -class VimException(VMwareDriverException): - """The base exception class for all VIM related exceptions.""" - - def __init__(self, message=None, cause=None, details=None, **kwargs): - super(VimException, self).__init__(message, details, **kwargs) - self.cause = cause - - -class VimSessionOverLoadException(VMwareDriverException): - """Thrown when there is an API call overload at the VMware server.""" - - def __init__(self, message, cause=None): - super(VimSessionOverLoadException, self).__init__(message) - self.cause = cause - - -class VimConnectionException(VMwareDriverException): - """Thrown when there is a connection problem.""" - - def __init__(self, message, cause=None): - super(VimConnectionException, self).__init__(message) - self.cause = cause - - -class VimAttributeException(VMwareDriverException): - """Thrown when a particular attribute cannot be found.""" - - def __init__(self, message, cause=None): - super(VimAttributeException, self).__init__(message) - self.cause = cause - - -class VimFaultException(VimException): - """Exception thrown when there are unrecognized VIM faults.""" - - def __init__(self, fault_list, message, cause=None, details=None): - super(VimFaultException, self).__init__(message, cause, details) - if not isinstance(fault_list, list): - raise ValueError(_("fault_list must be a list")) - self.fault_list = fault_list - - @property - def description(self): - descr = VimException.description.fget(self) - if self.fault_list: - # fault_list doesn't contain non-ASCII chars, we can use str() - descr += '\nFaults: ' + str(self.fault_list) - if self.details: - # details may contain non-ASCII values - details = '{%s}' % ', '.join(["'%s': '%s'" % (k, v) for k, v in - six.iteritems(self.details)]) - descr += '\nDetails: ' + details - return descr - - -class ImageTransferException(VMwareDriverException): - """Thrown when there is an error during image transfer.""" - - def __init__(self, message, cause=None): - super(ImageTransferException, self).__init__(message) - self.cause = cause - - -def _print_deprecation_warning(clazz): - LOG.warning("Exception %s is deprecated, it will be removed in the " - "next release.", clazz.__name__) - - -class VMwareDriverConfigurationException(VMwareDriverException): - """Base class for all configuration exceptions. - """ - msg_fmt = _("VMware Driver configuration fault.") - - def __init__(self, message=None, details=None, **kwargs): - super(VMwareDriverConfigurationException, self).__init__( - message, details, **kwargs) - _print_deprecation_warning(self.__class__) - - -class UseLinkedCloneConfigurationFault(VMwareDriverConfigurationException): - msg_fmt = _("No default value for use_linked_clone found.") - - -class MissingParameter(VMwareDriverException): - msg_fmt = _("Missing parameter : %(param)s") - - def __init__(self, message=None, details=None, **kwargs): - super(MissingParameter, self).__init__(message, details, **kwargs) - _print_deprecation_warning(self.__class__) - - -class AlreadyExistsException(VimException): - msg_fmt = _("Resource already exists.") - code = 409 - - -class CannotDeleteFileException(VimException): - msg_fmt = _("Cannot delete file.") - code = 403 - - -class FileAlreadyExistsException(VimException): - msg_fmt = _("File already exists.") - code = 409 - - -class FileFaultException(VimException): - msg_fmt = _("File fault.") - code = 409 - - -class FileLockedException(VimException): - msg_fmt = _("File locked.") - code = 403 - - -class FileNotFoundException(VimException): - msg_fmt = _("File not found.") - code = 404 - - -class InvalidPowerStateException(VimException): - msg_fmt = _("Invalid power state.") - code = 409 - - -class InvalidPropertyException(VimException): - msg_fmt = _("Invalid property.") - code = 400 - - -class NoPermissionException(VimException): - msg_fmt = _("No Permission.") - code = 403 - - -class NotAuthenticatedException(VimException): - msg_fmt = _("Not Authenticated.") - code = 403 - - -class TaskInProgress(VimException): - msg_fmt = _("Entity has another operation in process.") - - -class DuplicateName(VimException): - msg_fmt = _("Duplicate name.") - - -class NoDiskSpaceException(VimException): - msg_fmt = _("Insufficient disk space.") - - -class ToolsUnavailableException(VimException): - msg_fmt = _("VMware Tools is not running.") - - -class ManagedObjectNotFoundException(VimException): - msg_fmt = _("Managed object not found.") - code = 404 - - -# Populate the fault registry with the exceptions that have -# special treatment. -_fault_classes_registry = { - ALREADY_EXISTS: AlreadyExistsException, - CANNOT_DELETE_FILE: CannotDeleteFileException, - DUPLICATE_NAME: DuplicateName, - FILE_ALREADY_EXISTS: FileAlreadyExistsException, - FILE_FAULT: FileFaultException, - FILE_LOCKED: FileLockedException, - FILE_NOT_FOUND: FileNotFoundException, - INVALID_POWER_STATE: InvalidPowerStateException, - INVALID_PROPERTY: InvalidPropertyException, - MANAGED_OBJECT_NOT_FOUND: ManagedObjectNotFoundException, - NO_DISK_SPACE: NoDiskSpaceException, - NO_PERMISSION: NoPermissionException, - NOT_AUTHENTICATED: NotAuthenticatedException, - TASK_IN_PROGRESS: TaskInProgress, - TOOLS_UNAVAILABLE: ToolsUnavailableException, -} - - -def get_fault_class(name): - """Get a named subclass of VimException.""" - name = str(name) - fault_class = _fault_classes_registry.get(name) - if not fault_class: - LOG.debug('Fault %s not matched.', name) - return fault_class - - -def register_fault_class(name, exception): - fault_class = _fault_classes_registry.get(name) - if not issubclass(exception, VimException): - raise TypeError(_("exception should be a subclass of " - "VimException")) - if fault_class: - LOG.debug('Overriding exception for %s', name) - _fault_classes_registry[name] = exception diff --git a/oslo_vmware/hacking/__init__.py b/oslo_vmware/hacking/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oslo_vmware/hacking/checks.py b/oslo_vmware/hacking/checks.py deleted file mode 100644 index 8591d71..0000000 --- a/oslo_vmware/hacking/checks.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (c) 2017 OpenStack Foundation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import re - - -_all_log_levels = {'critical', 'error', 'exception', 'info', - 'warning', 'debug'} - -# Since _Lx() have been removed, we just need to check _() -_all_hints = {'_'} - -_log_translation_hint = re.compile( - r".*LOG\.(%(levels)s)\(\s*(%(hints)s)\(" % { - 'levels': '|'.join(_all_log_levels), - 'hints': '|'.join(_all_hints), - }) - - -def no_translate_logs(logical_line, filename): - """N537 - Don't translate logs. - - Check for 'LOG.*(_(' - - Translators don't provide translations for log messages, and operators - asked not to translate them. - - * This check assumes that 'LOG' is a logger. - - :param logical_line: The logical line to check. - :param filename: The file name where the logical line exists. - :returns: None if the logical line passes the check, otherwise a tuple - is yielded that contains the offending index in logical line and a - message describe the check validation failure. - """ - if _log_translation_hint.match(logical_line): - yield (0, "N537: Log messages should not be translated!") - - -def factory(register): - register(no_translate_logs) diff --git a/oslo_vmware/image_transfer.py b/oslo_vmware/image_transfer.py deleted file mode 100644 index eb6d6c5..0000000 --- a/oslo_vmware/image_transfer.py +++ /dev/null @@ -1,332 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Functions and classes for image transfer between ESX/VC & image service. -""" - -import logging -import tarfile - -from eventlet import timeout -import six - -from oslo_utils import units -from oslo_vmware._i18n import _ -from oslo_vmware.common import loopingcall -from oslo_vmware import constants -from oslo_vmware import exceptions -from oslo_vmware import image_util -from oslo_vmware.objects import datastore as ds_obj -from oslo_vmware import rw_handles -from oslo_vmware import vim_util - - -LOG = logging.getLogger(__name__) - -NFC_LEASE_UPDATE_PERIOD = 60 # update NFC lease every 60sec. -CHUNK_SIZE = 64 * units.Ki # default chunk size for image transfer - - -def _start_transfer(read_handle, write_handle, timeout_secs): - # write_handle could be an NFC lease, so we need to periodically - # update its progress - update_cb = getattr(write_handle, 'update_progress', lambda: None) - updater = loopingcall.FixedIntervalLoopingCall(update_cb) - timer = timeout.Timeout(timeout_secs) - try: - updater.start(interval=NFC_LEASE_UPDATE_PERIOD) - while True: - data = read_handle.read(CHUNK_SIZE) - if not data: - break - write_handle.write(data) - except timeout.Timeout as excep: - msg = (_('Timeout, read_handle: "%(src)s", write_handle: "%(dest)s"') % - {'src': read_handle, - 'dest': write_handle}) - LOG.exception(msg) - raise exceptions.ImageTransferException(msg, excep) - except Exception as excep: - msg = (_('Error, read_handle: "%(src)s", write_handle: "%(dest)s"') % - {'src': read_handle, - 'dest': write_handle}) - LOG.exception(msg) - raise exceptions.ImageTransferException(msg, excep) - finally: - timer.cancel() - updater.stop() - read_handle.close() - write_handle.close() - - -def download_image(image, image_meta, session, datastore, rel_path, - bypass=True, timeout_secs=7200): - """Transfer an image to a datastore. - - :param image: file-like iterator - :param image_meta: image metadata - :param session: VMwareAPISession object - :param datastore: Datastore object - :param rel_path: path where the file will be stored in the datastore - :param bypass: if set to True, bypass vCenter to download the image - :param timeout_secs: time in seconds to wait for the xfer to complete - """ - image_size = int(image_meta['size']) - method = 'PUT' - if bypass: - hosts = datastore.get_connected_hosts(session) - host = ds_obj.Datastore.choose_host(hosts) - host_name = session.invoke_api(vim_util, 'get_object_property', - session.vim, host, 'name') - ds_url = datastore.build_url(session._scheme, host_name, rel_path, - constants.ESX_DATACENTER_PATH) - cookie = ds_url.get_transfer_ticket(session, method) - conn = ds_url.connect(method, image_size, cookie) - else: - ds_url = datastore.build_url(session._scheme, session._host, rel_path) - cookie = '%s=%s' % (constants.SOAP_COOKIE_KEY, - session.vim.get_http_cookie().strip("\"")) - conn = ds_url.connect(method, image_size, cookie) - conn.write = conn.send - - read_handle = rw_handles.ImageReadHandle(image) - _start_transfer(read_handle, conn, timeout_secs) - - -def download_flat_image(context, timeout_secs, image_service, image_id, - **kwargs): - """Download flat image from the image service to VMware server. - - :param context: image service write context - :param timeout_secs: time in seconds to wait for the download to complete - :param image_service: image service handle - :param image_id: ID of the image to be downloaded - :param kwargs: keyword arguments to configure the destination - file write handle - :raises: VimConnectionException, ImageTransferException, ValueError - """ - LOG.debug("Downloading image: %s from image service as a flat file.", - image_id) - - # TODO(vbala) catch specific exceptions raised by download call - read_iter = image_service.download(context, image_id) - read_handle = rw_handles.ImageReadHandle(read_iter) - file_size = int(kwargs.get('image_size')) - write_handle = rw_handles.FileWriteHandle(kwargs.get('host'), - kwargs.get('port'), - kwargs.get('data_center_name'), - kwargs.get('datastore_name'), - kwargs.get('cookies'), - kwargs.get('file_path'), - file_size, - cacerts=kwargs.get('cacerts')) - _start_transfer(read_handle, write_handle, timeout_secs) - LOG.debug("Downloaded image: %s from image service as a flat file.", - image_id) - - -def download_file( - read_handle, host, port, dc_name, ds_name, cookies, - upload_file_path, file_size, cacerts, timeout_secs): - """Download file to VMware server. - - :param read_handle: file read handle - :param host: VMware server host name or IP address - :param port: VMware server port number - :param dc_name: name of the datacenter which contains the destination - datastore - :param ds_name: name of the destination datastore - :param cookies: cookies to build the cookie header while establishing - http connection with VMware server - :param upload_file_path: destination datastore file path - :param file_size: source file size - :param cacerts: CA bundle file to use for SSL verification - :param timeout_secs: timeout in seconds to wait for the download to - complete - """ - write_handle = rw_handles.FileWriteHandle(host, - port, - dc_name, - ds_name, - cookies, - upload_file_path, - file_size, - cacerts=cacerts) - _start_transfer(read_handle, write_handle, timeout_secs) - - -def download_stream_optimized_data(context, timeout_secs, read_handle, - **kwargs): - """Download stream optimized data to VMware server. - - :param context: image service write context - :param timeout_secs: time in seconds to wait for the download to complete - :param read_handle: handle from which to read the image data - :param kwargs: keyword arguments to configure the destination - VMDK write handle - :returns: managed object reference of the VM created for import to VMware - server - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException, - ImageTransferException, ValueError - """ - file_size = int(kwargs.get('image_size')) - write_handle = rw_handles.VmdkWriteHandle(kwargs.get('session'), - kwargs.get('host'), - kwargs.get('port'), - kwargs.get('resource_pool'), - kwargs.get('vm_folder'), - kwargs.get('vm_import_spec'), - file_size, - kwargs.get('http_method', 'PUT')) - _start_transfer(read_handle, write_handle, timeout_secs) - return write_handle.get_imported_vm() - - -def _get_vmdk_handle(ova_handle): - - with tarfile.open(mode="r|", fileobj=ova_handle) as tar: - vmdk_name = None - for tar_info in tar: - if tar_info and tar_info.name.endswith(".ovf"): - vmdk_name = image_util.get_vmdk_name_from_ovf( - tar.extractfile(tar_info)) - elif vmdk_name and tar_info.name.startswith(vmdk_name): - # Actual file name is .XXXXXXX - return tar.extractfile(tar_info) - - -def download_stream_optimized_image(context, timeout_secs, image_service, - image_id, **kwargs): - """Download stream optimized image from image service to VMware server. - - :param context: image service write context - :param timeout_secs: time in seconds to wait for the download to complete - :param image_service: image service handle - :param image_id: ID of the image to be downloaded - :param kwargs: keyword arguments to configure the destination - VMDK write handle - :returns: managed object reference of the VM created for import to VMware - server - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException, - ImageTransferException, ValueError - """ - metadata = image_service.show(context, image_id) - container_format = metadata.get('container_format') - - LOG.debug("Downloading image: %(id)s (container: %(container)s) from image" - " service as a stream optimized file.", - {'id': image_id, - 'container': container_format}) - - # TODO(vbala) catch specific exceptions raised by download call - read_iter = image_service.download(context, image_id) - read_handle = rw_handles.ImageReadHandle(read_iter) - - if container_format == 'ova': - read_handle = _get_vmdk_handle(read_handle) - if read_handle is None: - raise exceptions.ImageTransferException( - _("No vmdk found in the OVA image %s.") % image_id) - - imported_vm = download_stream_optimized_data(context, timeout_secs, - read_handle, **kwargs) - - LOG.debug("Downloaded image: %s from image service as a stream " - "optimized file.", - image_id) - return imported_vm - - -def copy_stream_optimized_disk( - context, timeout_secs, write_handle, **kwargs): - """Copy virtual disk from VMware server to the given write handle. - - :param context: context - :param timeout_secs: time in seconds to wait for the copy to complete - :param write_handle: copy destination - :param kwargs: keyword arguments to configure the source - VMDK read handle - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException, - ImageTransferException, ValueError - """ - vmdk_file_path = kwargs.get('vmdk_file_path') - LOG.debug("Copying virtual disk: %(vmdk_path)s to %(dest)s.", - {'vmdk_path': vmdk_file_path, - 'dest': write_handle.name}) - file_size = kwargs.get('vmdk_size') - read_handle = rw_handles.VmdkReadHandle(kwargs.get('session'), - kwargs.get('host'), - kwargs.get('port'), - kwargs.get('vm'), - kwargs.get('vmdk_file_path'), - file_size) - _start_transfer(read_handle, write_handle, timeout_secs) - LOG.debug("Downloaded virtual disk: %s.", vmdk_file_path) - - -# TODO(vbala) Remove dependency on image service provided by the client. -def upload_image(context, timeout_secs, image_service, image_id, owner_id, - **kwargs): - """Upload the VM's disk file to image service. - - :param context: image service write context - :param timeout_secs: time in seconds to wait for the upload to complete - :param image_service: image service handle - :param image_id: upload destination image ID - :param kwargs: keyword arguments to configure the source - VMDK read handle - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException, - ImageTransferException, ValueError - """ - - LOG.debug("Uploading to image: %s.", image_id) - file_size = kwargs.get('vmdk_size') - read_handle = rw_handles.VmdkReadHandle(kwargs.get('session'), - kwargs.get('host'), - kwargs.get('port'), - kwargs.get('vm'), - kwargs.get('vmdk_file_path'), - file_size) - - # TODO(vbala) Remove this after we delete the keyword argument 'is_public' - # from all client code. - if 'is_public' in kwargs: - LOG.debug("Ignoring keyword argument 'is_public'.") - - if 'image_version' in kwargs: - LOG.warning("The keyword argument 'image_version' is deprecated " - "and will be ignored in the next release.") - - image_ver = six.text_type(kwargs.get('image_version')) - image_metadata = {'disk_format': 'vmdk', - 'name': kwargs.get('image_name'), - 'properties': {'vmware_image_version': image_ver, - 'vmware_disktype': 'streamOptimized', - 'owner_id': owner_id}} - - updater = loopingcall.FixedIntervalLoopingCall(read_handle.update_progress) - try: - updater.start(interval=NFC_LEASE_UPDATE_PERIOD) - image_service.update(context, image_id, image_metadata, - data=read_handle) - finally: - updater.stop() - read_handle.close() - LOG.debug("Uploaded image: %s.", image_id) diff --git a/oslo_vmware/image_util.py b/oslo_vmware/image_util.py deleted file mode 100644 index 46546f0..0000000 --- a/oslo_vmware/image_util.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (c) 2016 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from lxml import etree # nosec (bandit bug 1582516) - - -def _get_vmdk_name_from_ovf(root): - ns_ovf = "{{{0}}}".format(root.nsmap["ovf"]) - disk = root.find("./{0}DiskSection/{0}Disk".format(ns_ovf)) - file_id = disk.get("{0}fileRef".format(ns_ovf)) - f = root.find('./{0}References/{0}File[@{0}id="{1}"]'.format(ns_ovf, - file_id)) - return f.get("{0}href".format(ns_ovf)) - - -def get_vmdk_name_from_ovf(ovf_handle): - """Get the vmdk name from the given ovf descriptor.""" - return _get_vmdk_name_from_ovf(etree.parse(ovf_handle).getroot()) diff --git a/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware-log-error.po b/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware-log-error.po deleted file mode 100644 index aaf42da..0000000 --- a/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware-log-error.po +++ /dev/null @@ -1,50 +0,0 @@ -# Andi Chandler , 2016. #zanata -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.vmware 2.15.1.dev2\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-10-22 08:58+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-06-09 11:21+0000\n" -"Last-Translator: Andi Chandler \n" -"Language-Team: English (United Kingdom)\n" -"Language: en-GB\n" -"X-Generator: Zanata 3.7.3\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#, python-format -msgid "%(name)s: %(value)s" -msgstr "%(name)s: %(value)s" - -#, python-format -msgid "" -"Cannot retry upon suggested exception since retry count (%(retry_count)d) " -"reached max retry count (%(max_retry_count)d)." -msgstr "" -"Cannot retry upon suggested exception since retry count (%(retry_count)d) " -"reached max retry count (%(max_retry_count)d)." - -#, python-format -msgid "Error occurred while checking state of lease: %s." -msgstr "Error occurred while checking state of lease: %s." - -#, python-format -msgid "" -"Error occurred while logging out and terminating the current session with ID " -"= %s." -msgstr "" -"Error occurred while logging out and terminating the current session with ID " -"= %s." - -#, python-format -msgid "Error occurred while reading info of task: %s." -msgstr "Error occurred while reading info of task: %s." - -msgid "Exception in string format operation" -msgstr "Exception in string format operation" - -msgid "in fixed duration looping call" -msgstr "in fixed duration looping call" diff --git a/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware-log-info.po b/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware-log-info.po deleted file mode 100644 index 3de6055..0000000 --- a/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware-log-info.po +++ /dev/null @@ -1,27 +0,0 @@ -# Andi Chandler , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.vmware 2.7.1.dev8\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-06-02 23:59+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-06-09 11:22+0000\n" -"Last-Translator: Andi Chandler \n" -"Language-Team: English (United Kingdom)\n" -"Language: en-GB\n" -"X-Generator: Zanata 3.7.3\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#, python-format -msgid "Logging out and terminating the current session with ID = %s." -msgstr "Logging out and terminating the current session with ID = %s." - -#, python-format -msgid "PBM WSDL updated to %s" -msgstr "PBM WSDL updated to %s" - -#, python-format -msgid "Successfully established new session; session ID is %s." -msgstr "Successfully established new session; session ID is %s." diff --git a/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware-log-warning.po b/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware-log-warning.po deleted file mode 100644 index 787e2fc..0000000 --- a/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware-log-warning.po +++ /dev/null @@ -1,53 +0,0 @@ -# Andi Chandler , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.vmware 2.7.1.dev8\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-06-02 23:59+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-06-09 11:23+0000\n" -"Last-Translator: Andi Chandler \n" -"Language-Team: English (United Kingdom)\n" -"Language: en-GB\n" -"X-Generator: Zanata 3.7.3\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -msgid "Error occurred while closing the file handle" -msgstr "Error occurred while closing the file handle" - -#, python-format -msgid "Error occurred while reading error message for lease: %s." -msgstr "Error occurred while reading error message for lease: %s." - -msgid "Error occurred while reading the HTTP response." -msgstr "Error occurred while reading the HTTP response." - -#, python-format -msgid "Error occurred while releasing the lease for %s." -msgstr "Error occurred while releasing the lease for %s." - -#, python-format -msgid "Exception %s is deprecated, it will be removed in the next release." -msgstr "Exception %s is deprecated, it will be removed in the next release." - -#, python-format -msgid "" -"Exception which is in the suggested list of exceptions occurred while " -"invoking function: %s." -msgstr "" -"Exception which is in the suggested list of exceptions occurred while " -"invoking function: %s." - -#, python-format -msgid "PBM WSDL file %s not found." -msgstr "PBM WSDL file %s not found." - -#, python-format -msgid "Unable to retrieve value for %(path)s Reason: %(reason)s" -msgstr "Unable to retrieve value for %(path)s Reason: %(reason)s" - -#, python-format -msgid "task run outlasted interval by %s sec" -msgstr "task run outlasted interval by %s sec" diff --git a/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware.po b/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware.po deleted file mode 100644 index 2d72f38..0000000 --- a/oslo_vmware/locale/en_GB/LC_MESSAGES/oslo_vmware.po +++ /dev/null @@ -1,202 +0,0 @@ -# Andi Chandler , 2016. #zanata -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.vmware 2.15.1.dev2\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-10-22 08:58+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-06-09 11:20+0000\n" -"Last-Translator: Andi Chandler \n" -"Language-Team: English (United Kingdom)\n" -"Language: en-GB\n" -"X-Generator: Zanata 3.7.3\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -msgid "An unknown exception occurred." -msgstr "An unknown exception occurred." - -msgid "Cannot delete file." -msgstr "Cannot delete file." - -msgid "Capacity is smaller than free space" -msgstr "Capacity is smaller than free space" - -#, python-format -msgid "Connection error occurred while writing data to %s." -msgstr "Connection error occurred while writing data to %s." - -msgid "Could not retrieve VMDK URL from lease info." -msgstr "Could not retrieve VMDK URL from lease info." - -#, python-format -msgid "" -"Current session: %(session)s is inactive; re-creating the session while " -"invoking method %(module)s.%(method)s." -msgstr "" -"Current session: %(session)s is inactive; re-creating the session while " -"invoking method %(module)s.%(method)s." - -msgid "Datacenter name cannot be None" -msgstr "Datacentre name cannot be None" - -msgid "Datacenter reference cannot be None" -msgstr "Datacentre reference cannot be None" - -msgid "Datastore name cannot be None" -msgstr "Datastore name cannot be None" - -msgid "Datastore name cannot be empty" -msgstr "Datastore name cannot be empty" - -msgid "Datastore path cannot be empty" -msgstr "Datastore path cannot be empty" - -msgid "Datastore reference cannot be None" -msgstr "Datastore reference cannot be None" - -msgid "Duplicate name." -msgstr "Duplicate name." - -msgid "Entity has another operation in process." -msgstr "Entity has another operation in process." - -msgid "Error occurred while calling RetrievePropertiesEx." -msgstr "Error occurred while calling RetrievePropertiesEx." - -#, python-format -msgid "" -"Error occurred while creating HTTP connection to write to VMDK file with URL " -"= %s." -msgstr "" -"Error occurred while creating HTTP connection to write to VMDK file with URL " -"= %s." - -#, python-format -msgid "" -"Error occurred while creating HTTP connection to write to file with URL = %s." -msgstr "" -"Error occurred while creating HTTP connection to write to file with URL = %s." - -#, python-format -msgid "Error occurred while opening URL: %s for reading." -msgstr "Error occurred while opening URL: %s for reading." - -#, python-format -msgid "Error occurred while reading data from %s." -msgstr "Error occurred while reading data from %s." - -#, python-format -msgid "Error occurred while writing data to %s." -msgstr "Error occurred while writing data to %s." - -#, python-format -msgid "Exception in %s." -msgstr "Exception in %s." - -msgid "File already exists." -msgstr "File already exists." - -msgid "File fault." -msgstr "File fault." - -msgid "File locked." -msgstr "File locked." - -msgid "File not found." -msgstr "File not found." - -msgid "Insufficient disk space." -msgstr "Insufficient disk space." - -msgid "Invalid capacity" -msgstr "Invalid capacity" - -msgid "Invalid power state." -msgstr "Invalid power state." - -msgid "Invalid property." -msgstr "Invalid property." - -#, python-format -msgid "Invalid scheme: %s." -msgstr "Invalid scheme: %s." - -#, python-format -msgid "Lease: %(lease)s is in error state. Details: %(error_msg)s." -msgstr "Lease: %(lease)s is in error state. Details: %(error_msg)s." - -msgid "Managed object not found." -msgstr "Managed object not found." - -#, python-format -msgid "Missing parameter : %(param)s" -msgstr "Missing parameter : %(param)s" - -msgid "No Permission." -msgstr "No Permission." - -msgid "No default value for use_linked_clone found." -msgstr "No default value for use_linked_clone found." - -#, python-format -msgid "No such SOAP method %s." -msgstr "No such SOAP method %s." - -msgid "Not Authenticated." -msgstr "Not Authenticated." - -msgid "Path component cannot be None" -msgstr "Path component cannot be None" - -msgid "Resource already exists." -msgstr "Resource already exists." - -#, python-format -msgid "Socket error in %s." -msgstr "Socket error in %s." - -#, python-format -msgid "Type error in %s." -msgstr "Type error in %s." - -#, python-format -msgid "Unknown state: %(state)s for lease: %(lease)s." -msgstr "Unknown state: %(state)s for lease: %(lease)s." - -msgid "VMware Driver configuration fault." -msgstr "VMware Driver configuration fault." - -msgid "VMware Tools is not running." -msgstr "VMware Tools is not running." - -msgid "cause" -msgstr "cause" - -msgid "datacenter must be set to build url" -msgstr "datacentre must be set to build url" - -msgid "details must be a dict" -msgstr "details must be a dict" - -msgid "exception message must not be a list" -msgstr "exception message must not be a list" - -msgid "exception should be a subclass of VimException" -msgstr "exception should be a subclass of VimException" - -msgid "fault_list must be a list" -msgstr "fault_list must be a list" - -#, python-format -msgid "httplib error in %s." -msgstr "httplib error in %s." - -#, python-format -msgid "requests error in %s." -msgstr "requests error in %s." - -msgid "string" -msgstr "string" diff --git a/oslo_vmware/locale/fr/LC_MESSAGES/oslo_vmware-log-error.po b/oslo_vmware/locale/fr/LC_MESSAGES/oslo_vmware-log-error.po deleted file mode 100644 index d92f8fb..0000000 --- a/oslo_vmware/locale/fr/LC_MESSAGES/oslo_vmware-log-error.po +++ /dev/null @@ -1,59 +0,0 @@ -# Translations template for oslo.vmware. -# Copyright (C) 2015 ORGANIZATION -# This file is distributed under the same license as the oslo.vmware -# project. -# -# Translators: -# Maxime COQUEREL , 2014 -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.vmware 2.15.1.dev2\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-10-22 08:58+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2014-10-27 05:28+0000\n" -"Last-Translator: Maxime COQUEREL \n" -"Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"Generated-By: Babel 2.0\n" -"X-Generator: Zanata 3.7.3\n" -"Language-Team: French\n" - -#, python-format -msgid "%(name)s: %(value)s" -msgstr "%(name)s: %(value)s" - -#, python-format -msgid "" -"Cannot retry upon suggested exception since retry count (%(retry_count)d) " -"reached max retry count (%(max_retry_count)d)." -msgstr "" -"Vous ne pouvez pas recommencer cela à suggéré une exception puisque le " -"nombre de tentatives (%(retry_count)d) a atteint le nombre de tentatives max " -"(%(max_retry_count)d)." - -#, python-format -msgid "Error occurred while checking state of lease: %s." -msgstr "Une erreur est survenue pendant la vérification de l'état du bail: %s" - -#, python-format -msgid "" -"Error occurred while logging out and terminating the current session with ID " -"= %s." -msgstr "" -"Une erreur est survenue pendant la fin de connexion et la fin de la session " -"courante avec ID = %s." - -#, python-format -msgid "Error occurred while reading info of task: %s." -msgstr "" -"Une erreur est survenue pendant la lecture des informations de la taches: %s" - -msgid "Exception in string format operation" -msgstr "Exception dans le formatage de la chaîne" - -msgid "in fixed duration looping call" -msgstr "Fixe la durée de l'appel de la boucle" diff --git a/oslo_vmware/locale/fr/LC_MESSAGES/oslo_vmware-log-info.po b/oslo_vmware/locale/fr/LC_MESSAGES/oslo_vmware-log-info.po deleted file mode 100644 index 154b42e..0000000 --- a/oslo_vmware/locale/fr/LC_MESSAGES/oslo_vmware-log-info.po +++ /dev/null @@ -1,36 +0,0 @@ -# Translations template for oslo.vmware. -# Copyright (C) 2015 ORGANIZATION -# This file is distributed under the same license as the oslo.vmware -# project. -# -# Translators: -# Maxime COQUEREL , 2014-2015 -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.vmware 2.5.1.dev6\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-04-19 23:10+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2015-03-24 05:17+0000\n" -"Last-Translator: openstackjenkins \n" -"Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"Generated-By: Babel 2.0\n" -"X-Generator: Zanata 3.7.3\n" -"Language-Team: French\n" - -#, python-format -msgid "Logging out and terminating the current session with ID = %s." -msgstr "Déconnexion et fin de la session encours avec l'identifiant = %s" - -#, python-format -msgid "PBM WSDL updated to %s" -msgstr "PBM WSD mise à jour de %s" - -#, python-format -msgid "Successfully established new session; session ID is %s." -msgstr "" -"nouvelle session établit avec succès; l'identifiant de la session est %s." diff --git a/oslo_vmware/locale/fr/LC_MESSAGES/oslo_vmware-log-warning.po b/oslo_vmware/locale/fr/LC_MESSAGES/oslo_vmware-log-warning.po deleted file mode 100644 index 00e5023..0000000 --- a/oslo_vmware/locale/fr/LC_MESSAGES/oslo_vmware-log-warning.po +++ /dev/null @@ -1,64 +0,0 @@ -# Translations template for oslo.vmware. -# Copyright (C) 2015 ORGANIZATION -# This file is distributed under the same license as the oslo.vmware -# project. -# -# Translators: -# Maxime COQUEREL , 2014-2015 -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.vmware 2.5.1.dev6\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-04-19 23:10+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2015-07-27 10:54+0000\n" -"Last-Translator: Maxime COQUEREL \n" -"Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"Generated-By: Babel 2.0\n" -"X-Generator: Zanata 3.7.3\n" -"Language-Team: French\n" - -msgid "Error occurred while closing the file handle" -msgstr "Une erreur est survenue pendant la fermeuture du fichier de traitement" - -#, python-format -msgid "Error occurred while reading error message for lease: %s." -msgstr "" -"Une erreur est survenue pendant la lecture du message d'erreur pour le bail: " -"%s." - -msgid "Error occurred while reading the HTTP response." -msgstr "Une erreur est survenue pendant la lecture de la réponse HTTP." - -#, python-format -msgid "Error occurred while releasing the lease for %s." -msgstr "Une erreur est survenue pendant la libération du bail pour %s." - -#, python-format -msgid "Exception %s is deprecated, it will be removed in the next release." -msgstr "" -"Exception %s est obsolète , il sera supprimé dans la prochaine version." - -#, python-format -msgid "" -"Exception which is in the suggested list of exceptions occurred while " -"invoking function: %s." -msgstr "" -"Exception qui est dans la liste proposée des exceptions est survenu lors de " -"l'appel fonction: %s. " - -#, python-format -msgid "PBM WSDL file %s not found." -msgstr "Fichier PBM WSDL %s non trouvé." - -#, python-format -msgid "Unable to retrieve value for %(path)s Reason: %(reason)s" -msgstr "Impossible de récupérer les valeurs pour %(path)s Raison: %(reason)s" - -#, python-format -msgid "task run outlasted interval by %s sec" -msgstr "Exécution de la tache par intervalle de %s sec" diff --git a/oslo_vmware/locale/fr/LC_MESSAGES/oslo_vmware.po b/oslo_vmware/locale/fr/LC_MESSAGES/oslo_vmware.po deleted file mode 100644 index 7294260..0000000 --- a/oslo_vmware/locale/fr/LC_MESSAGES/oslo_vmware.po +++ /dev/null @@ -1,211 +0,0 @@ -# Translations template for oslo.vmware. -# Copyright (C) 2015 ORGANIZATION -# This file is distributed under the same license as the oslo.vmware -# project. -# -# Translators: -# Maxime COQUEREL , 2014-2015 -# Andreas Jaeger , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.vmware 2.15.1.dev2\n" -"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" -"POT-Creation-Date: 2016-10-22 08:58+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2015-07-27 10:54+0000\n" -"Last-Translator: Maxime COQUEREL \n" -"Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"Generated-By: Babel 2.0\n" -"X-Generator: Zanata 3.7.3\n" -"Language-Team: French\n" - -msgid "An unknown exception occurred." -msgstr "Une exception inconnue s'est produite " - -msgid "Cannot delete file." -msgstr "Le fichier ne peut pas etre supprimé." - -msgid "Capacity is smaller than free space" -msgstr "La capacité est plus petite que l'espace libre" - -#, python-format -msgid "Connection error occurred while writing data to %s." -msgstr "Erreur de connexion pendant l'écriture des données de %s" - -msgid "Could not retrieve VMDK URL from lease info." -msgstr "Impossible de récupérer VMDK URL depuis l'emplacement d'information." - -#, python-format -msgid "" -"Current session: %(session)s is inactive; re-creating the session while " -"invoking method %(module)s.%(method)s." -msgstr "" -"Session courante: %(session)s est inactive; recréation de la session en " -"invoquant la méthode %(module)s.%(method)s." - -msgid "Datacenter name cannot be None" -msgstr "Le nom du datacenter ne peut pas être \"vide\"" - -msgid "Datacenter reference cannot be None" -msgstr "La référence du datastore ne peut pas etre \"vide\"" - -msgid "Datastore name cannot be None" -msgstr "Le nom du datastore ne peut pas etre \"vide\"" - -msgid "Datastore name cannot be empty" -msgstr "Le nom du datastore ne pas etre \"vide\"" - -msgid "Datastore path cannot be empty" -msgstr "Le chemin du datastore ne peut pas etre \"vide\"" - -msgid "Datastore reference cannot be None" -msgstr "La référence du datastore ne peut pas etre \"vide\"" - -msgid "Duplicate name." -msgstr "Duplicat du nom." - -msgid "Entity has another operation in process." -msgstr "L'entité a une autre opération en cours." - -msgid "Error occurred while calling RetrievePropertiesEx." -msgstr "Une erreur est survenue pendant l'appelle RetrievePropertiesEx." - -#, python-format -msgid "" -"Error occurred while creating HTTP connection to write to VMDK file with URL " -"= %s." -msgstr "" -"Une erreur est survenue pendant la création des connexion HTTP pour écrire " -"le fichier VMDK avec URL = %s." - -#, python-format -msgid "" -"Error occurred while creating HTTP connection to write to file with URL = %s." -msgstr "" -"Une erreur est survenue pendant la création des connexion HTTP pour écrire " -"le fichier avec URL = %s." - -#, python-format -msgid "Error occurred while opening URL: %s for reading." -msgstr "" -"Une erreur est survenue pendant l'ouverture de URL: %s pour la lecture." - -#, python-format -msgid "Error occurred while reading data from %s." -msgstr "Une erreur est survenue pendant la lecture des données depuis %s." - -#, python-format -msgid "Error occurred while writing data to %s." -msgstr "Une erreur est survenue pendant l'écriture des données de %s." - -#, python-format -msgid "Exception in %s." -msgstr "Exception dans %s." - -msgid "File already exists." -msgstr "Le fichier existe déjà." - -msgid "File fault." -msgstr "Redirection fichier." - -msgid "File locked." -msgstr "Fichier verrouillé." - -msgid "File not found." -msgstr "Fichier non trouvé." - -msgid "Insufficient disk space." -msgstr "Espace disque insuffisant." - -msgid "Invalid capacity" -msgstr "Capacité non valide" - -msgid "Invalid power state." -msgstr "Status de démarrage non valide." - -msgid "Invalid property." -msgstr "Propriété non valide." - -#, python-format -msgid "Invalid scheme: %s." -msgstr "Invalide schéma: %s" - -#, python-format -msgid "Lease: %(lease)s is in error state. Details: %(error_msg)s." -msgstr "Bail: %(lease)s est dans une erreur de status. Détails: %(error_msg)s." - -msgid "Managed object not found." -msgstr "Objet géré introuvable." - -#, python-format -msgid "Missing parameter : %(param)s" -msgstr "Paramètre manquant : %(param)s" - -msgid "No Permission." -msgstr "Pas de permission." - -msgid "No default value for use_linked_clone found." -msgstr "Pas de valeur par défaut pour use_linked_clone trouvé." - -#, python-format -msgid "No such SOAP method %s." -msgstr "Pas de méthode SOAP %s." - -msgid "Not Authenticated." -msgstr "Non authentifié." - -msgid "Path component cannot be None" -msgstr "Le chemin du composant ne peut pas etre \"vide\"" - -msgid "Resource already exists." -msgstr "La ressource existe déjà." - -#, python-format -msgid "Socket error in %s." -msgstr "Erreur de socket dans %s." - -#, python-format -msgid "Type error in %s." -msgstr "Erreur de type dans %s." - -#, python-format -msgid "Unknown state: %(state)s for lease: %(lease)s." -msgstr "Statut inconnu: %(state)s for lease: %(lease)s." - -msgid "VMware Driver configuration fault." -msgstr "Redirection de la configuration du pilote VMware." - -msgid "VMware Tools is not running." -msgstr "VMware Tools ne fonctionne pas." - -msgid "cause" -msgstr "cause" - -msgid "datacenter must be set to build url" -msgstr "datacenter doit être initialiser pour construire url" - -msgid "details must be a dict" -msgstr "details doit etre un dict" - -msgid "exception message must not be a list" -msgstr "exception ne doit pas etre une liste" - -msgid "exception should be a subclass of VimException" -msgstr "exception devrait être une subclass de VimException" - -msgid "fault_list must be a list" -msgstr "fault_list doit etre une liste" - -#, python-format -msgid "httplib error in %s." -msgstr "httplib erreur dans %s." - -#, python-format -msgid "requests error in %s." -msgstr "erreur de requetes dans %s." - -msgid "string" -msgstr "chaîne de caractère" diff --git a/oslo_vmware/objects/__init__.py b/oslo_vmware/objects/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oslo_vmware/objects/datacenter.py b/oslo_vmware/objects/datacenter.py deleted file mode 100644 index 7657042..0000000 --- a/oslo_vmware/objects/datacenter.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_vmware._i18n import _ - - -class Datacenter(object): - - def __init__(self, ref, name): - """Datacenter object holds ref and name together for convenience.""" - if name is None: - raise ValueError(_("Datacenter name cannot be None")) - if ref is None: - raise ValueError(_("Datacenter reference cannot be None")) - self.ref = ref - self.name = name diff --git a/oslo_vmware/objects/datastore.py b/oslo_vmware/objects/datastore.py deleted file mode 100644 index c435fd5..0000000 --- a/oslo_vmware/objects/datastore.py +++ /dev/null @@ -1,365 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import logging -import posixpath -import random - -import six.moves.http_client as httplib -import six.moves.urllib.parse as urlparse - -from oslo_vmware._i18n import _ -from oslo_vmware import constants -from oslo_vmware import exceptions -from oslo_vmware import vim_util - -LOG = logging.getLogger(__name__) - - -def get_datastore_by_ref(session, ds_ref): - """Returns a datastore object for a given reference. - - :param session: a vmware api session object - :param ds_ref: managed object reference of a datastore - :rtype: a datastore object - """ - lst_properties = ["summary.type", - "summary.name", - "summary.capacity", - "summary.freeSpace", - "summary.uncommitted"] - - props = session.invoke_api( - vim_util, - "get_object_properties_dict", - session.vim, - ds_ref, - lst_properties) - # TODO(sabari): Instantiate with datacenter info. - return Datastore(ds_ref, props["summary.name"], - capacity=props.get("summary.capacity"), - freespace=props.get("summary.freeSpace"), - uncommitted=props.get("summary.uncommitted"), - type=props.get("summary.type")) - - -class Datastore(object): - - def __init__(self, ref, name, capacity=None, freespace=None, - uncommitted=None, type=None, datacenter=None): - """Datastore object holds ref and name together for convenience. - - :param ref: a vSphere reference to a datastore - :param name: vSphere unique name for this datastore - :param capacity: (optional) capacity in bytes of this datastore - :param freespace: (optional) free space in bytes of datastore - :param uncommitted: (optional) Total additional storage space - in bytes of datastore - :param type: (optional) datastore type - :param datacenter: (optional) oslo_vmware Datacenter object - """ - if name is None: - raise ValueError(_("Datastore name cannot be None")) - if ref is None: - raise ValueError(_("Datastore reference cannot be None")) - if freespace is not None and capacity is None: - raise ValueError(_("Invalid capacity")) - if capacity is not None and freespace is not None: - if capacity < freespace: - raise ValueError(_("Capacity is smaller than free space")) - - self.ref = ref - self.name = name - self.capacity = capacity - self.freespace = freespace - self.uncommitted = uncommitted - self.type = type - self.datacenter = datacenter - - def build_path(self, *paths): - """Constructs and returns a DatastorePath. - - :param paths: list of path components, for constructing a path relative - to the root directory of the datastore - :return: a DatastorePath object - """ - return DatastorePath(self.name, *paths) - - def build_url(self, scheme, server, rel_path, datacenter_name=None): - """Constructs and returns a DatastoreURL. - - :param scheme: scheme of the URL (http, https). - :param server: hostname or ip - :param rel_path: relative path of the file on the datastore - :param datacenter_name: (optional) datacenter name - :return: a DatastoreURL object - """ - if self.datacenter is None and datacenter_name is None: - raise ValueError(_("datacenter must be set to build url")) - if datacenter_name is None: - datacenter_name = self.datacenter.name - return DatastoreURL(scheme, server, rel_path, datacenter_name, - self.name) - - def __str__(self): - return '[%s]' % self.name - - def get_summary(self, session): - """Get datastore summary. - - :param datastore: Reference to the datastore - :return: 'summary' property of the datastore - """ - return session.invoke_api(vim_util, 'get_object_property', - session.vim, self.ref, 'summary') - - def get_connected_hosts(self, session): - """Get a list of usable (accessible, mounted, read-writable) hosts where - the datastore is mounted. - - :param: session: session - :return: list of HostSystem managed object references - """ - hosts = [] - summary = self.get_summary(session) - if not summary.accessible: - return hosts - host_mounts = session.invoke_api(vim_util, 'get_object_property', - session.vim, self.ref, 'host') - if not hasattr(host_mounts, 'DatastoreHostMount'): - return hosts - for host_mount in host_mounts.DatastoreHostMount: - if self.is_datastore_mount_usable(host_mount.mountInfo): - hosts.append(host_mount.key) - connectables = [] - if hosts: - host_runtimes = session.invoke_api( - vim_util, - 'get_properties_for_a_collection_of_objects', - session.vim, 'HostSystem', hosts, ['runtime']) - for host_object in host_runtimes.objects: - host_props = vim_util.propset_dict(host_object.propSet) - host_runtime = host_props.get('runtime') - if hasattr(host_runtime, 'inMaintenanceMode') and ( - not host_runtime.inMaintenanceMode): - connectables.append(host_object.obj) - return connectables - - @staticmethod - def is_datastore_mount_usable(mount_info): - """Check if a datastore is usable as per the given mount info. - - The datastore is considered to be usable for a host only if it is - writable, mounted and accessible. - - :param mount_info: HostMountInfo data object - :return: True if datastore is usable - """ - writable = mount_info.accessMode == 'readWrite' - mounted = getattr(mount_info, 'mounted', True) - accessible = getattr(mount_info, 'accessible', False) - - return writable and mounted and accessible - - @staticmethod - def choose_host(hosts): - if not hosts: - return None - - i = random.SystemRandom().randrange(0, len(hosts)) - return hosts[i] - - -class DatastorePath(object): - - """Class for representing a directory or file path in a vSphere datatore. - - This provides various helper methods to access components and useful - variants of the datastore path. - - Example usage: - - DatastorePath("datastore1", "_base/foo", "foo.vmdk") creates an - object that describes the "[datastore1] _base/foo/foo.vmdk" datastore - file path to a virtual disk. - - Note: - - - Datastore path representations always uses forward slash as separator - (hence the use of the posixpath module). - - Datastore names are enclosed in square brackets. - - Path part of datastore path is relative to the root directory - of the datastore, and is always separated from the [ds_name] part with - a single space. - """ - - def __init__(self, datastore_name, *paths): - if datastore_name is None or datastore_name == '': - raise ValueError(_("Datastore name cannot be empty")) - self._datastore_name = datastore_name - self._rel_path = '' - if paths: - if None in paths: - raise ValueError(_("Path component cannot be None")) - self._rel_path = posixpath.join(*paths) - - def __str__(self): - """Full datastore path to the file or directory.""" - if self._rel_path != '': - return "[%s] %s" % (self._datastore_name, self.rel_path) - return "[%s]" % self._datastore_name - - @property - def datastore(self): - return self._datastore_name - - @property - def parent(self): - return DatastorePath(self.datastore, posixpath.dirname(self._rel_path)) - - @property - def basename(self): - return posixpath.basename(self._rel_path) - - @property - def dirname(self): - return posixpath.dirname(self._rel_path) - - @property - def rel_path(self): - return self._rel_path - - def join(self, *paths): - """Join one or more path components intelligently into a datastore path. - - If any component is an absolute path, all previous components are - thrown away, and joining continues. The return value is the - concatenation of the paths with exactly one slash ('/') inserted - between components, unless p is empty. - - :return: A datastore path - """ - if paths: - if None in paths: - raise ValueError(_("Path component cannot be None")) - return DatastorePath(self.datastore, self._rel_path, *paths) - return self - - def __eq__(self, other): - return (isinstance(other, DatastorePath) and - self._datastore_name == other._datastore_name and - self._rel_path == other._rel_path) - - @classmethod - def parse(cls, datastore_path): - """Constructs a DatastorePath object given a datastore path string.""" - if not datastore_path: - raise ValueError(_("Datastore path cannot be empty")) - - spl = datastore_path.split('[', 1)[1].split(']', 1) - path = "" - if len(spl) == 1: - datastore_name = spl[0] - else: - datastore_name, path = spl - return cls(datastore_name, path.strip()) - - -class DatastoreURL(object): - - """Class for representing a URL to HTTP access a file in a datastore. - - This provides various helper methods to access components and useful - variants of the datastore URL. - """ - - def __init__(self, scheme, server, path, datacenter_path, datastore_name): - self._scheme = scheme - self._server = server - self._path = path - self._datacenter_path = datacenter_path - self._datastore_name = datastore_name - params = {'dcPath': self._datacenter_path, - 'dsName': self._datastore_name} - self._query = urlparse.urlencode(params) - - @classmethod - def urlparse(cls, url): - scheme, server, path, params, query, fragment = urlparse.urlparse(url) - if not query: - path = path.split('?') - query = path[1] - path = path[0] - params = urlparse.parse_qs(query) - dc_path = params.get('dcPath') - if dc_path is not None and len(dc_path) > 0: - datacenter_path = dc_path[0] - ds_name = params.get('dsName') - if ds_name is not None and len(ds_name) > 0: - datastore_name = ds_name[0] - path = path[len('/folder'):] - return cls(scheme, server, path, datacenter_path, datastore_name) - - @property - def path(self): - return self._path.strip('/') - - @property - def datacenter_path(self): - return self._datacenter_path - - @property - def datastore_name(self): - return self._datastore_name - - def __str__(self): - return '%s://%s/folder/%s?%s' % (self._scheme, self._server, - self.path, self._query) - - def connect(self, method, content_length, cookie): - try: - if self._scheme == 'http': - conn = httplib.HTTPConnection(self._server) - elif self._scheme == 'https': - # TODO(browne): This needs to be changed to use python requests - conn = httplib.HTTPSConnection(self._server) # nosec - else: - excep_msg = _("Invalid scheme: %s.") % self._scheme - LOG.error(excep_msg) - raise ValueError(excep_msg) - conn.putrequest(method, '/folder/%s?%s' % (self.path, self._query)) - conn.putheader('User-Agent', constants.USER_AGENT) - conn.putheader('Content-Length', content_length) - conn.putheader('Cookie', cookie) - conn.endheaders() - LOG.debug("Created HTTP connection to transfer the file with " - "URL = %s.", str(self)) - return conn - except (httplib.InvalidURL, httplib.CannotSendRequest, - httplib.CannotSendHeader) as excep: - excep_msg = _("Error occurred while creating HTTP connection " - "to write to file with URL = %s.") % str(self) - LOG.exception(excep_msg) - raise exceptions.VimConnectionException(excep_msg, excep) - - def get_transfer_ticket(self, session, method): - client_factory = session.vim.client.factory - spec = vim_util.get_http_service_request_spec(client_factory, method, - str(self)) - ticket = session.invoke_api( - session.vim, - 'AcquireGenericServiceTicket', - session.vim.service_content.sessionManager, - spec=spec) - return '%s="%s"' % (constants.CGI_COOKIE_KEY, ticket.id) diff --git a/oslo_vmware/pbm.py b/oslo_vmware/pbm.py deleted file mode 100644 index 849cd55..0000000 --- a/oslo_vmware/pbm.py +++ /dev/null @@ -1,241 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -VMware PBM service client and PBM related utility methods - -PBM is used for policy based placement in VMware datastores. -Refer http://goo.gl/GR2o6U for more details. -""" - -import logging -import os - -import six.moves.urllib.parse as urlparse -import six.moves.urllib.request as urllib - -from oslo_vmware import service -from oslo_vmware import vim_util - - -SERVICE_TYPE = 'PbmServiceInstance' - -LOG = logging.getLogger(__name__) - - -class Pbm(service.Service): - """Service class that provides access to the Storage Policy API.""" - - def __init__(self, protocol='https', host='localhost', port=443, - wsdl_url=None, cacert=None, insecure=True, pool_maxsize=10, - connection_timeout=None, op_id_prefix='oslo.vmware'): - """Constructs a PBM service client object. - - :param protocol: http or https - :param host: server IP address or host name - :param port: port for connection - :param wsdl_url: PBM WSDL url - :param cacert: Specify a CA bundle file to use in verifying a - TLS (https) server certificate. - :param insecure: Verify HTTPS connections using system certificates, - used only if cacert is not specified - :param pool_maxsize: Maximum number of connections in http - connection pool - :param op_id_prefix: String prefix for the operation ID. - :param connection_timeout: Maximum time in seconds to wait for peer to - respond. - """ - base_url = service.Service.build_base_url(protocol, host, port) - soap_url = base_url + '/pbm' - super(Pbm, self).__init__(wsdl_url, soap_url, cacert, insecure, - pool_maxsize, connection_timeout, - op_id_prefix) - - def set_soap_cookie(self, cookie): - """Set the specified vCenter session cookie in the SOAP header - - :param cookie: cookie to set - """ - self._vc_session_cookie = cookie - - def retrieve_service_content(self): - ref = vim_util.get_moref(service.SERVICE_INSTANCE, SERVICE_TYPE) - return self.PbmRetrieveServiceContent(ref) - - def __repr__(self): - return "PBM Object" - - def __str__(self): - return "PBM Object" - - -def get_all_profiles(session): - """Get all the profiles defined in VC server. - - :returns: PbmProfile data objects - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - LOG.debug("Fetching all the profiles defined in VC server.") - - pbm = session.pbm - profile_manager = pbm.service_content.profileManager - res_type = pbm.client.factory.create('ns0:PbmProfileResourceType') - res_type.resourceType = 'STORAGE' - profiles = [] - profile_ids = session.invoke_api(pbm, - 'PbmQueryProfile', - profile_manager, - resourceType=res_type) - LOG.debug("Fetched profile IDs: %s.", profile_ids) - if profile_ids: - profiles = session.invoke_api(pbm, - 'PbmRetrieveContent', - profile_manager, - profileIds=profile_ids) - return profiles - - -def get_profile_id_by_name(session, profile_name): - """Get the profile UUID corresponding to the given profile name. - - :param profile_name: profile name whose UUID needs to be retrieved - :returns: profile UUID string or None if profile not found - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - LOG.debug("Retrieving profile ID for profile: %s.", profile_name) - for profile in get_all_profiles(session): - if profile.name == profile_name: - profile_id = profile.profileId - LOG.debug("Retrieved profile ID: %(id)s for profile: %(name)s.", - {'id': profile_id, - 'name': profile_name}) - return profile_id - return None - - -def filter_hubs_by_profile(session, hubs, profile_id): - """Filter and return hubs that match the given profile. - - :param hubs: PbmPlacementHub morefs - :param profile_id: profile ID - :returns: subset of hubs that match the given profile - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - LOG.debug("Filtering hubs: %(hubs)s that match profile: %(profile)s.", - {'hubs': hubs, - 'profile': profile_id}) - - pbm = session.pbm - placement_solver = pbm.service_content.placementSolver - filtered_hubs = session.invoke_api(pbm, - 'PbmQueryMatchingHub', - placement_solver, - hubsToSearch=hubs, - profile=profile_id) - LOG.debug("Filtered hubs: %s", filtered_hubs) - return filtered_hubs - - -def convert_datastores_to_hubs(pbm_client_factory, datastores): - """Convert given datastore morefs to PbmPlacementHub morefs. - - :param pbm_client_factory: Factory to create PBM API input specs - :param datastores: list of datastore morefs - :returns: list of PbmPlacementHub morefs - """ - hubs = [] - for ds in datastores: - hub = pbm_client_factory.create('ns0:PbmPlacementHub') - hub.hubId = ds.value - hub.hubType = 'Datastore' - hubs.append(hub) - return hubs - - -def filter_datastores_by_hubs(hubs, datastores): - """Get filtered subset of datastores corresponding to the given hub list. - - :param hubs: list of PbmPlacementHub morefs - :param datastores: all candidate datastores - :returns: subset of datastores corresponding to the given hub list - """ - filtered_dss = [] - hub_ids = [hub.hubId for hub in hubs] - for ds in datastores: - if ds.value in hub_ids: - filtered_dss.append(ds) - return filtered_dss - - -def get_pbm_wsdl_location(vc_version): - """Return PBM WSDL file location corresponding to VC version. - - :param vc_version: a dot-separated version string. For example, "1.2". - :return: the pbm wsdl file location. - """ - if not vc_version: - return - ver = vc_version.split('.') - major_minor = ver[0] - if len(ver) >= 2: - major_minor = '%s.%s' % (major_minor, ver[1]) - curr_dir = os.path.abspath(os.path.dirname(__file__)) - pbm_service_wsdl = os.path.join(curr_dir, 'wsdl', major_minor, - 'pbmService.wsdl') - if not os.path.exists(pbm_service_wsdl): - LOG.warning("PBM WSDL file %s not found.", pbm_service_wsdl) - return - pbm_wsdl = urlparse.urljoin('file:', urllib.pathname2url(pbm_service_wsdl)) - LOG.debug("Using PBM WSDL location: %s.", pbm_wsdl) - return pbm_wsdl - - -def get_profiles(session, vm): - """Query storage profiles associated with the given vm. - - :param session: VMwareAPISession instance - :param vm: vm reference - :return: profile IDs - """ - pbm = session.pbm - profile_manager = pbm.service_content.profileManager - - object_ref = pbm.client.factory.create('ns0:PbmServerObjectRef') - object_ref.key = vm.value - object_ref.objectType = 'virtualMachine' - - return session.invoke_api(pbm, 'PbmQueryAssociatedProfile', - profile_manager, entity=object_ref) - - -def get_profiles_by_ids(session, profile_ids): - """Get storage profiles by IDs. - - :param session: VMwareAPISession instance - :param profile_ids: profile IDs - :return: profile objects - """ - profiles = [] - if profile_ids: - pbm = session.pbm - profile_manager = pbm.service_content.profileManager - profiles = session.invoke_api(pbm, - 'PbmRetrieveContent', - profile_manager, - profileIds=profile_ids) - return profiles diff --git a/oslo_vmware/rw_handles.py b/oslo_vmware/rw_handles.py deleted file mode 100644 index e2f1bed..0000000 --- a/oslo_vmware/rw_handles.py +++ /dev/null @@ -1,650 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Classes defining read and write handles for image transfer. - -This module defines various classes for reading and writing files including -VMDK files in VMware servers. It also contains a class to read images from -glance server. -""" - -import logging -import ssl -import time - -from oslo_utils import excutils -from oslo_utils import netutils -import requests -import six -import six.moves.urllib.parse as urlparse -from urllib3 import connection as httplib - -from oslo_vmware._i18n import _ -from oslo_vmware import exceptions -from oslo_vmware import vim_util - - -LOG = logging.getLogger(__name__) - -MIN_PROGRESS_DIFF_TO_LOG = 25 -MIN_UPDATE_INTERVAL = 60 -READ_CHUNKSIZE = 65536 -USER_AGENT = 'OpenStack-ESX-Adapter' - - -class FileHandle(object): - """Base class for VMware server file (including VMDK) access over HTTP. - - This class wraps a backing file handle and provides utility methods - for various sub-classes. - """ - - def __init__(self, file_handle): - """Initializes the file handle. - - :param file_handle: backing file handle - """ - self._eof = False - self._file_handle = file_handle - - def _create_connection(self, url, method, cacerts=False, - ssl_thumbprint=None): - _urlparse = urlparse.urlparse(url) - scheme, netloc, path, params, query, fragment = _urlparse - if scheme == 'http': - conn = httplib.HTTPConnection(netloc) - elif scheme == 'https': - conn = httplib.HTTPSConnection(netloc) - cert_reqs = None - - # cacerts can be either True or False or contain - # actual certificates. If it is a boolean, then - # we need to set cert_reqs and clear the cacerts - if isinstance(cacerts, bool): - if cacerts: - cert_reqs = ssl.CERT_REQUIRED - else: - cert_reqs = ssl.CERT_NONE - cacerts = None - conn.set_cert(ca_certs=cacerts, cert_reqs=cert_reqs, - assert_fingerprint=ssl_thumbprint) - else: - excep_msg = _("Invalid scheme: %s.") % scheme - LOG.error(excep_msg) - raise ValueError(excep_msg) - - if query: - path = path + '?' + query - conn.putrequest(method, path) - return conn - - def _create_read_connection(self, url, cookies=None, cacerts=False, - ssl_thumbprint=None): - LOG.debug("Opening URL: %s for reading.", url) - try: - conn = self._create_connection(url, 'GET', cacerts, ssl_thumbprint) - vim_cookie = self._build_vim_cookie_header(cookies) - conn.putheader('User-Agent', USER_AGENT) - conn.putheader('Cookie', vim_cookie) - conn.endheaders() - return conn.getresponse() - except Exception as excep: - # TODO(vbala) We need to catch and raise specific exceptions - # related to connection problems, invalid request and invalid - # arguments. - excep_msg = _("Error occurred while opening URL: %s for " - "reading.") % url - LOG.exception(excep_msg) - raise exceptions.VimException(excep_msg, excep) - - def _create_write_connection(self, method, url, - file_size=None, - cookies=None, - overwrite=None, - content_type=None, - cacerts=False, - ssl_thumbprint=None): - """Create HTTP connection to write to VMDK file.""" - LOG.debug("Creating HTTP connection to write to file with " - "size = %(file_size)d and URL = %(url)s.", - {'file_size': file_size, - 'url': url}) - try: - conn = self._create_connection(url, method, cacerts, - ssl_thumbprint) - headers = {'User-Agent': USER_AGENT} - if file_size: - headers.update({'Content-Length': str(file_size)}) - if overwrite: - headers.update({'Overwrite': overwrite}) - if cookies: - headers.update({'Cookie': - self._build_vim_cookie_header(cookies)}) - if content_type: - headers.update({'Content-Type': content_type}) - for key, value in six.iteritems(headers): - conn.putheader(key, value) - conn.endheaders() - return conn - except requests.RequestException as excep: - excep_msg = _("Error occurred while creating HTTP connection " - "to write to VMDK file with URL = %s.") % url - LOG.exception(excep_msg) - raise exceptions.VimConnectionException(excep_msg, excep) - - def close(self): - """Close the file handle.""" - try: - self._file_handle.close() - except Exception: - LOG.warning("Error occurred while closing the file handle", - exc_info=True) - - def _build_vim_cookie_header(self, vim_cookies): - """Build ESX host session cookie header.""" - cookie_header = "" - for vim_cookie in vim_cookies: - cookie_header = vim_cookie.name + '=' + vim_cookie.value - break - return cookie_header - - def write(self, data): - """Write data to the file. - - :param data: data to be written - :raises: NotImplementedError - """ - raise NotImplementedError() - - def read(self, chunk_size): - """Read a chunk of data. - - :param chunk_size: read chunk size - :raises: NotImplementedError - """ - raise NotImplementedError() - - def get_size(self): - """Get size of the file to be read. - - :raises: NotImplementedError - """ - raise NotImplementedError() - - def _get_soap_url(self, scheme, host, port): - """Returns the IPv4/v6 compatible SOAP URL for the given host.""" - if netutils.is_valid_ipv6(host): - return '%s://[%s]:%d' % (scheme, host, port) - return '%s://%s:%d' % (scheme, host, port) - - -class FileWriteHandle(FileHandle): - """Write handle for a file in VMware server.""" - - def __init__(self, host, port, data_center_name, datastore_name, cookies, - file_path, file_size, scheme='https', cacerts=False, - thumbprint=None): - """Initializes the write handle with given parameters. - - :param host: ESX/VC server IP address or host name - :param port: port for connection - :param data_center_name: name of the data center in the case of a VC - server - :param datastore_name: name of the datastore where the file is stored - :param cookies: cookies to build the vim cookie header - :param file_path: datastore path where the file is written - :param file_size: size of the file in bytes - :param scheme: protocol-- http or https - :param cacerts: CA bundle file to use for SSL verification - :param thumbprint: expected SHA1 thumbprint of server's certificate - :raises: VimConnectionException, ValueError - """ - soap_url = self._get_soap_url(scheme, host, port) - param_list = {'dcPath': data_center_name, 'dsName': datastore_name} - self._url = '%s/folder/%s' % (soap_url, file_path) - self._url = self._url + '?' + urlparse.urlencode(param_list) - - self._conn = self._create_write_connection('PUT', - self._url, - file_size, - cookies=cookies, - cacerts=cacerts, - ssl_thumbprint=thumbprint) - FileHandle.__init__(self, self._conn) - - def write(self, data): - """Write data to the file. - - :param data: data to be written - :raises: VimConnectionException, VimException - """ - try: - self._file_handle.send(data) - except requests.RequestException as excep: - excep_msg = _("Connection error occurred while writing data to" - " %s.") % self._url - LOG.exception(excep_msg) - raise exceptions.VimConnectionException(excep_msg, excep) - except Exception as excep: - # TODO(vbala) We need to catch and raise specific exceptions - # related to connection problems, invalid request and invalid - # arguments. - excep_msg = _("Error occurred while writing data to" - " %s.") % self._url - LOG.exception(excep_msg) - raise exceptions.VimException(excep_msg, excep) - - def close(self): - """Get the response and close the connection.""" - LOG.debug("Closing write handle for %s.", self._url) - try: - self._conn.getresponse() - except Exception: - LOG.warning("Error occurred while reading the HTTP response.", - exc_info=True) - super(FileWriteHandle, self).close() - - def __str__(self): - return "File write handle for %s" % self._url - - -class VmdkHandle(FileHandle): - """VMDK handle based on HttpNfcLease.""" - - def __init__(self, session, lease, url, file_handle): - self._session = session - self._lease = lease - self._url = url - self._last_logged_progress = 0 - self._last_progress_udpate = 0 - - super(VmdkHandle, self).__init__(file_handle) - - def _log_progress(self, progress): - """Log data transfer progress.""" - if (progress == 100 or (progress - self._last_logged_progress >= - MIN_PROGRESS_DIFF_TO_LOG)): - LOG.debug("Data transfer progress is %d%%.", progress) - self._last_logged_progress = progress - - def _get_progress(self): - """Get current progress for updating progress to lease.""" - pass - - def update_progress(self): - """Updates progress to lease. - - This call back to the lease is essential to keep the lease alive - across long running write/read operations. - - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - now = time.time() - if (now - self._last_progress_udpate < MIN_UPDATE_INTERVAL): - return - self._last_progress_udpate = now - progress = int(self._get_progress()) - self._log_progress(progress) - - try: - self._session.invoke_api(self._session.vim, - 'HttpNfcLeaseProgress', - self._lease, - percent=progress) - except exceptions.VimException: - with excutils.save_and_reraise_exception(): - LOG.exception("Error occurred while updating the " - "write/read progress of VMDK file " - "with URL = %s.", - self._url) - - def _release_lease(self): - """Release the lease - - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - LOG.debug("Getting lease state for %s.", self._url) - - state = self._session.invoke_api(vim_util, - 'get_object_property', - self._session.vim, - self._lease, - 'state') - LOG.debug("Lease for %(url)s is in state: %(state)s.", - {'url': self._url, - 'state': state}) - if state == 'ready': - LOG.debug("Releasing lease for %s.", self._url) - self._session.invoke_api(self._session.vim, - 'HttpNfcLeaseComplete', - self._lease) - else: - LOG.debug("Lease for %(url)s is in state: %(state)s; no " - "need to release.", - {'url': self._url, - 'state': state}) - - @staticmethod - def _create_import_vapp_lease(session, rp_ref, import_spec, vm_folder_ref): - """Create and wait for HttpNfcLease lease for vApp import.""" - LOG.debug("Creating HttpNfcLease lease for vApp import into resource" - " pool: %s.", - rp_ref) - lease = session.invoke_api(session.vim, - 'ImportVApp', - rp_ref, - spec=import_spec, - folder=vm_folder_ref) - LOG.debug("Lease: %(lease)s obtained for vApp import into resource" - " pool %(rp_ref)s.", - {'lease': lease, - 'rp_ref': rp_ref}) - session.wait_for_lease_ready(lease) - - LOG.debug("Invoking VIM API for reading info of lease: %s.", lease) - lease_info = session.invoke_api(vim_util, - 'get_object_property', - session.vim, - lease, - 'info') - return lease, lease_info - - @staticmethod - def _create_export_vm_lease(session, vm_ref): - """Create and wait for HttpNfcLease lease for VM export.""" - LOG.debug("Creating HttpNfcLease lease for exporting VM: %s.", - vm_ref) - lease = session.invoke_api(session.vim, 'ExportVm', vm_ref) - LOG.debug("Lease: %(lease)s obtained for exporting VM: %(vm_ref)s.", - {'lease': lease, - 'vm_ref': vm_ref}) - session.wait_for_lease_ready(lease) - - LOG.debug("Invoking VIM API for reading info of lease: %s.", lease) - lease_info = session.invoke_api(vim_util, - 'get_object_property', - session.vim, - lease, - 'info') - return lease, lease_info - - @staticmethod - def _fix_esx_url(url, host, port): - """Fix netloc in the case of an ESX host. - - In the case of an ESX host, the netloc is set to '*' in the URL - returned in HttpNfcLeaseInfo. It should be replaced with host name - or IP address. - """ - urlp = urlparse.urlparse(url) - if urlp.netloc == '*': - scheme, netloc, path, params, query, fragment = urlp - if netutils.is_valid_ipv6(host): - netloc = '[%s]:%d' % (host, port) - else: - netloc = "%s:%d" % (host, port) - url = urlparse.urlunparse((scheme, - netloc, - path, - params, - query, - fragment)) - return url - - @staticmethod - def _find_vmdk_url(lease_info, host, port): - """Find the URL corresponding to a VMDK file in lease info.""" - url = None - ssl_thumbprint = None - for deviceUrl in lease_info.deviceUrl: - if deviceUrl.disk: - url = VmdkHandle._fix_esx_url(deviceUrl.url, host, port) - ssl_thumbprint = deviceUrl.sslThumbprint - break - if not url: - excep_msg = _("Could not retrieve VMDK URL from lease info.") - LOG.error(excep_msg) - raise exceptions.VimException(excep_msg) - LOG.debug("Found VMDK URL: %s from lease info.", url) - return url, ssl_thumbprint - - -class VmdkWriteHandle(VmdkHandle): - """VMDK write handle based on HttpNfcLease. - - This class creates a vApp in the specified resource pool and uploads the - virtual disk contents. - """ - - def __init__(self, session, host, port, rp_ref, vm_folder_ref, import_spec, - vmdk_size, http_method='PUT'): - """Initializes the VMDK write handle with input parameters. - - :param session: valid API session to ESX/VC server - :param host: ESX/VC server IP address or host name - :param port: port for connection - :param rp_ref: resource pool into which the backing VM is imported - :param vm_folder_ref: VM folder in ESX/VC inventory to use as parent - of backing VM - :param import_spec: import specification of the backing VM - :param vmdk_size: size of the backing VM's VMDK file - :param http_method: either PUT or POST - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException, - ValueError - """ - self._vmdk_size = vmdk_size - self._bytes_written = 0 - - # Get lease and its info for vApp import - lease, lease_info = self._create_import_vapp_lease(session, - rp_ref, - import_spec, - vm_folder_ref) - - # Find VMDK URL where data is to be written - url, thumbprint = self._find_vmdk_url(lease_info, host, port) - self._vm_ref = lease_info.entity - - cookies = session.vim.client.options.transport.cookiejar - # Create HTTP connection to write to VMDK URL - if http_method == 'PUT': - overwrite = 't' - content_type = 'binary/octet-stream' - elif http_method == 'POST': - overwrite = None - content_type = 'application/x-vnd.vmware-streamVmdk' - else: - raise ValueError('http_method must be either PUT or POST') - self._conn = self._create_write_connection(http_method, - url, - vmdk_size, - cookies=cookies, - overwrite=overwrite, - content_type=content_type, - ssl_thumbprint=thumbprint) - super(VmdkWriteHandle, self).__init__(session, lease, url, self._conn) - - def get_imported_vm(self): - """"Get managed object reference of the VM created for import.""" - return self._vm_ref - - def write(self, data): - """Write data to the file. - - :param data: data to be written - :raises: VimConnectionException, VimException - """ - try: - self._file_handle.send(data) - self._bytes_written += len(data) - except requests.RequestException as excep: - excep_msg = _("Connection error occurred while writing data to" - " %s.") % self._url - LOG.exception(excep_msg) - raise exceptions.VimConnectionException(excep_msg, excep) - except Exception as excep: - # TODO(vbala) We need to catch and raise specific exceptions - # related to connection problems, invalid request and invalid - # arguments. - excep_msg = _("Error occurred while writing data to" - " %s.") % self._url - LOG.exception(excep_msg) - raise exceptions.VimException(excep_msg, excep) - - def close(self): - """Releases the lease and close the connection. - - :raises: VimAttributeException, VimSessionOverLoadException, - VimConnectionException - """ - try: - self._release_lease() - except exceptions.VimException: - LOG.warning("Error occurred while releasing the lease " - "for %s.", - self._url, - exc_info=True) - super(VmdkWriteHandle, self).close() - LOG.debug("Closed VMDK write handle for %s.", self._url) - - def _get_progress(self): - return float(self._bytes_written) / self._vmdk_size * 100 - - def __str__(self): - return "VMDK write handle for %s" % self._url - - -class VmdkReadHandle(VmdkHandle): - """VMDK read handle based on HttpNfcLease.""" - - def __init__(self, session, host, port, vm_ref, vmdk_path, - vmdk_size): - """Initializes the VMDK read handle with the given parameters. - - During the read (export) operation, the VMDK file is converted to a - stream-optimized sparse disk format. Therefore, the size of the VMDK - file read may be smaller than the actual VMDK size. - - :param session: valid api session to ESX/VC server - :param host: ESX/VC server IP address or host name - :param port: port for connection - :param vm_ref: managed object reference of the backing VM whose VMDK - is to be exported - :param vmdk_path: path of the VMDK file to be exported - :param vmdk_size: actual size of the VMDK file - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - self._vmdk_size = vmdk_size - self._bytes_read = 0 - - # Obtain lease for VM export - lease, lease_info = self._create_export_vm_lease(session, vm_ref) - - # find URL of the VMDK file to be read and open connection - url, thumbprint = self._find_vmdk_url(lease_info, host, port) - cookies = session.vim.client.options.transport.cookiejar - self._conn = self._create_read_connection(url, - cookies=cookies, - ssl_thumbprint=thumbprint) - super(VmdkReadHandle, self).__init__(session, lease, url, self._conn) - - def read(self, chunk_size): - """Read a chunk of data from the VMDK file. - - :param chunk_size: size of read chunk - :returns: the data - :raises: VimException - """ - try: - data = self._file_handle.read(READ_CHUNKSIZE) - self._bytes_read += len(data) - return data - except Exception as excep: - # TODO(vbala) We need to catch and raise specific exceptions - # related to connection problems, invalid request and invalid - # arguments. - excep_msg = _("Error occurred while reading data from" - " %s.") % self._url - LOG.exception(excep_msg) - raise exceptions.VimException(excep_msg, excep) - - def close(self): - """Releases the lease and close the connection. - - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - try: - self._release_lease() - except exceptions.VimException: - LOG.warning("Error occurred while releasing the lease " - "for %s.", - self._url, - exc_info=True) - raise - finally: - super(VmdkReadHandle, self).close() - LOG.debug("Closed VMDK read handle for %s.", self._url) - - def _get_progress(self): - return float(self._bytes_read) / self._vmdk_size * 100 - - def __str__(self): - return "VMDK read handle for %s" % self._url - - -class ImageReadHandle(object): - """Read handle for glance images.""" - - def __init__(self, glance_read_iter): - """Initializes the read handle with given parameters. - - :param glance_read_iter: iterator to read data from glance image - """ - self._glance_read_iter = glance_read_iter - self._iter = self.get_next() - - def read(self, chunk_size): - """Read an item from the image data iterator. - - The input chunk size is ignored since the client ImageBodyIterator - uses its own chunk size. - """ - try: - data = next(self._iter) - return data - except StopIteration: - LOG.debug("Completed reading data from the image iterator.") - return "" - - def get_next(self): - """Get the next item from the image iterator.""" - for data in self._glance_read_iter: - yield data - - def close(self): - """Close the read handle. - - This is a NOP. - """ - pass - - def __str__(self): - return "Image read handle" diff --git a/oslo_vmware/service.py b/oslo_vmware/service.py deleted file mode 100644 index 0f262ab..0000000 --- a/oslo_vmware/service.py +++ /dev/null @@ -1,458 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Common classes that provide access to vSphere services. -""" - -import logging -import os - -import netaddr -from oslo_utils import timeutils -from oslo_utils import uuidutils -import requests -import six -import six.moves.http_client as httplib -import suds -from suds import cache -from suds import client -from suds import plugin -import suds.sax.element as element -from suds import transport - -from oslo_vmware._i18n import _ -from oslo_vmware import exceptions -from oslo_vmware import vim_util - -CACHE_TIMEOUT = 60 * 60 # One hour cache timeout -ADDRESS_IN_USE_ERROR = 'Address already in use' -CONN_ABORT_ERROR = 'Software caused connection abort' -RESP_NOT_XML_ERROR = 'Response is "text/html", not "text/xml"' - -SERVICE_INSTANCE = 'ServiceInstance' - -LOG = logging.getLogger(__name__) - - -class ServiceMessagePlugin(plugin.MessagePlugin): - """Suds plug-in handling some special cases while calling VI SDK.""" - - # list of XML elements which are allowed to be empty - EMPTY_ELEMENTS = ["VirtualMachineEmptyProfileSpec"] - - def add_attribute_for_value(self, node): - """Helper to handle AnyType. - - Suds does not handle AnyType properly. But VI SDK requires type - attribute to be set when AnyType is used. - - :param node: XML value node - """ - if node.name == 'value' or node.name == 'val': - node.set('xsi:type', 'xsd:string') - # removeKey may be a 'int' or a 'string' - if node.name == 'removeKey': - try: - int(node.text) - node.set('xsi:type', 'xsd:int') - except (ValueError, TypeError): - node.set('xsi:type', 'xsd:string') - - def prune(self, el): - pruned = [] - for c in el.children: - self.prune(c) - if c.isempty(False) and c.name not in self.EMPTY_ELEMENTS: - pruned.append(c) - for p in pruned: - el.children.remove(p) - - def marshalled(self, context): - """Modifies the envelope document before it is sent. - - This method provides the plug-in with the opportunity to prune empty - nodes and fix nodes before sending it to the server. - - :param context: send context - """ - # Suds builds the entire request object based on the WSDL schema. - # VI SDK throws server errors if optional SOAP nodes are sent - # without values; e.g., as opposed to test. - - self.prune(context.envelope) - context.envelope.walk(self.add_attribute_for_value) - - -class Response(six.BytesIO): - """Response with an input stream as source.""" - - def __init__(self, stream, status=200, headers=None): - self.status = status - self.headers = headers or {} - self.reason = requests.status_codes._codes.get( - status, [''])[0].upper().replace('_', ' ') - six.BytesIO.__init__(self, stream) - - @property - def _original_response(self): - return self - - @property - def msg(self): - return self - - def read(self, chunk_size, **kwargs): - return six.BytesIO.read(self, chunk_size) - - def info(self): - return self - - def get_all(self, name, default): - result = self.headers.get(name) - if not result: - return default - return [result] - - def getheaders(self, name): - return self.get_all(name, []) - - def release_conn(self): - self.close() - - -class LocalFileAdapter(requests.adapters.HTTPAdapter): - """Transport adapter for local files. - - See http://stackoverflow.com/a/22989322 - """ - def __init__(self, pool_maxsize=10): - super(LocalFileAdapter, self).__init__(pool_connections=pool_maxsize, - pool_maxsize=pool_maxsize) - - def _build_response_from_file(self, request): - file_path = request.url[7:] - with open(file_path, 'r') as f: - buff = bytearray(os.path.getsize(file_path)) - f.readinto(buff) - resp = Response(buff) - return self.build_response(request, resp) - - def send(self, request, stream=False, timeout=None, - verify=True, cert=None, proxies=None): - return self._build_response_from_file(request) - - -class RequestsTransport(transport.Transport): - def __init__(self, cacert=None, insecure=True, pool_maxsize=10, - connection_timeout=None): - transport.Transport.__init__(self) - # insecure flag is used only if cacert is not - # specified. - self.verify = cacert if cacert else not insecure - self.session = requests.Session() - self.session.mount('file:///', - LocalFileAdapter(pool_maxsize=pool_maxsize)) - self.session.mount('https://', requests.adapters.HTTPAdapter( - pool_connections=pool_maxsize, pool_maxsize=pool_maxsize)) - self.cookiejar = self.session.cookies - self._connection_timeout = connection_timeout - - def open(self, request): - resp = self.session.get(request.url, verify=self.verify) - return six.BytesIO(resp.content) - - def send(self, request): - resp = self.session.post(request.url, - data=request.message, - headers=request.headers, - verify=self.verify, - timeout=self._connection_timeout) - return transport.Reply(resp.status_code, resp.headers, resp.content) - - -class MemoryCache(cache.ObjectCache): - def __init__(self): - self._cache = {} - - def get(self, key): - """Retrieves the value for a key or None.""" - now = timeutils.utcnow_ts() - for k in list(self._cache): - (timeout, _value) = self._cache[k] - if timeout and now >= timeout: - del self._cache[k] - - return self._cache.get(key, (0, None))[1] - - def put(self, key, value, time=CACHE_TIMEOUT): - """Sets the value for a key.""" - timeout = 0 - if time != 0: - timeout = timeutils.utcnow_ts() + time - self._cache[key] = (timeout, value) - return True - - -_CACHE = MemoryCache() - - -class Service(object): - """Base class containing common functionality for invoking vSphere - services - """ - - def __init__(self, wsdl_url=None, soap_url=None, - cacert=None, insecure=True, pool_maxsize=10, - connection_timeout=None, op_id_prefix='oslo.vmware'): - self.wsdl_url = wsdl_url - self.soap_url = soap_url - self.op_id_prefix = op_id_prefix - LOG.debug("Creating suds client with soap_url='%s' and wsdl_url='%s'", - self.soap_url, self.wsdl_url) - transport = RequestsTransport(cacert=cacert, - insecure=insecure, - pool_maxsize=pool_maxsize, - connection_timeout=connection_timeout) - self.client = client.Client(self.wsdl_url, - transport=transport, - location=self.soap_url, - plugins=[ServiceMessagePlugin()], - cache=_CACHE) - self._service_content = None - self._vc_session_cookie = None - - @staticmethod - def build_base_url(protocol, host, port): - proto_str = '%s://' % protocol - host_str = '[%s]' % host if netaddr.valid_ipv6(host) else host - port_str = '' if port is None else ':%d' % port - return proto_str + host_str + port_str - - @staticmethod - def _retrieve_properties_ex_fault_checker(response): - """Checks the RetrievePropertiesEx API response for errors. - - Certain faults are sent in the SOAP body as a property of missingSet. - This method raises VimFaultException when a fault is found in the - response. - - :param response: response from RetrievePropertiesEx API call - :raises: VimFaultException - """ - fault_list = [] - details = {} - if not response: - # This is the case when the session has timed out. ESX SOAP - # server sends an empty RetrievePropertiesExResponse. Normally - # missingSet in the response objects has the specifics about - # the error, but that's not the case with a timed out idle - # session. It is as bad as a terminated session for we cannot - # use the session. Therefore setting fault to NotAuthenticated - # fault. - LOG.debug("RetrievePropertiesEx API response is empty; setting " - "fault to %s.", - exceptions.NOT_AUTHENTICATED) - fault_list = [exceptions.NOT_AUTHENTICATED] - else: - for obj_cont in response.objects: - if hasattr(obj_cont, 'missingSet'): - for missing_elem in obj_cont.missingSet: - f_type = missing_elem.fault.fault - f_name = f_type.__class__.__name__ - fault_list.append(f_name) - if f_name == exceptions.NO_PERMISSION: - details['object'] = f_type.object.value - details['privilegeId'] = f_type.privilegeId - - if fault_list: - fault_string = _("Error occurred while calling " - "RetrievePropertiesEx.") - raise exceptions.VimFaultException(fault_list, - fault_string, - details=details) - - def _set_soap_headers(self, op_id): - """Set SOAP headers for the next remote call to vCenter. - - SOAP headers may include operation ID and vcSessionCookie. - The operation ID is a random string which allows to correlate log - messages across different systems (OpenStack, vCenter, ESX). - vcSessionCookie is needed when making PBM calls. - """ - headers = [] - if self._vc_session_cookie: - elem = element.Element('vcSessionCookie').setText( - self._vc_session_cookie) - headers.append(elem) - if op_id: - elem = element.Element('operationID').setText(op_id) - headers.append(elem) - if headers: - self.client.set_options(soapheaders=headers) - - @property - def service_content(self): - if self._service_content is None: - self._service_content = self.retrieve_service_content() - return self._service_content - - def get_http_cookie(self): - """Return the vCenter session cookie.""" - cookies = self.client.options.transport.cookiejar - for cookie in cookies: - if cookie.name.lower() == 'vmware_soap_session': - return cookie.value - - def __getattr__(self, attr_name): - """Returns the method to invoke API identified by param attr_name.""" - - def request_handler(managed_object, **kwargs): - """Handler for vSphere API calls. - - Invokes the API and parses the response for fault checking and - other errors. - - :param managed_object: managed object reference argument of the - API call - :param kwargs: keyword arguments of the API call - :returns: response of the API call - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - try: - if isinstance(managed_object, str): - # For strings, use string value for value and type - # of the managed object. - managed_object = vim_util.get_moref(managed_object, - managed_object) - if managed_object is None: - return - - skip_op_id = kwargs.pop('skip_op_id', False) - op_id = None - if not skip_op_id: - # Generate opID. It will appear in vCenter and ESX logs for - # this particular remote call. - op_id = '%s-%s' % (self.op_id_prefix, - uuidutils.generate_uuid()) - LOG.debug('Invoking %s.%s with opID=%s', - managed_object._type, - attr_name, - op_id) - self._set_soap_headers(op_id) - request = getattr(self.client.service, attr_name) - response = request(managed_object, **kwargs) - if (attr_name.lower() == 'retrievepropertiesex'): - Service._retrieve_properties_ex_fault_checker(response) - return response - except exceptions.VimFaultException: - # Catch the VimFaultException that is raised by the fault - # check of the SOAP response. - raise - - except suds.WebFault as excep: - fault_string = None - if excep.fault: - fault_string = excep.fault.faultstring - - doc = excep.document - detail = None - if doc is not None: - detail = doc.childAtPath('/detail') - if not detail: - # NOTE(arnaud): this is needed with VC 5.1 - detail = doc.childAtPath('/Envelope/Body/Fault/detail') - fault_list = [] - details = {} - if detail: - for fault in detail.getChildren(): - fault_type = fault.get('type') - if fault_type.endswith(exceptions.SECURITY_ERROR): - fault_type = exceptions.NOT_AUTHENTICATED - fault_list.append(fault_type) - for child in fault.getChildren(): - details[child.name] = child.getText() - raise exceptions.VimFaultException(fault_list, fault_string, - excep, details) - - except AttributeError as excep: - raise exceptions.VimAttributeException( - _("No such SOAP method %s.") % attr_name, excep) - - except (httplib.CannotSendRequest, - httplib.ResponseNotReady, - httplib.CannotSendHeader) as excep: - raise exceptions.VimSessionOverLoadException( - _("httplib error in %s.") % attr_name, excep) - - except requests.RequestException as excep: - raise exceptions.VimConnectionException( - _("requests error in %s.") % attr_name, excep) - - except Exception as excep: - # TODO(vbala) should catch specific exceptions and raise - # appropriate VimExceptions. - - # Socket errors which need special handling; some of these - # might be caused by server API call overload. - if (six.text_type(excep).find(ADDRESS_IN_USE_ERROR) != -1 or - six.text_type(excep).find(CONN_ABORT_ERROR)) != -1: - raise exceptions.VimSessionOverLoadException( - _("Socket error in %s.") % attr_name, excep) - # Type error which needs special handling; it might be caused - # by server API call overload. - elif six.text_type(excep).find(RESP_NOT_XML_ERROR) != -1: - raise exceptions.VimSessionOverLoadException( - _("Type error in %s.") % attr_name, excep) - else: - raise exceptions.VimException( - _("Exception in %s.") % attr_name, excep) - return request_handler - - def __repr__(self): - return "vSphere object" - - def __str__(self): - return "vSphere object" - - -class SudsLogFilter(logging.Filter): - """Filter to mask/truncate vCenter credentials in suds logs.""" - - def filter(self, record): - if not hasattr(record.msg, 'childAtPath'): - return True - - # Suds will log vCenter credentials if SessionManager.Login or - # SessionManager.SessionIsActive fails. - login = (record.msg.childAtPath('/Envelope/Body/Login') or - record.msg.childAtPath('/Envelope/Body/SessionIsActive')) - if login is None: - return True - - if login.childAtPath('userName') is not None: - login.childAtPath('userName').setText('***') - if login.childAtPath('password') is not None: # nosec - login.childAtPath('password').setText('***') # nosec - - session_id = login.childAtPath('sessionID') - if session_id is not None: - session_id.setText(session_id.getText()[-5:]) - - return True - -# Set log filter to mask/truncate vCenter credentials in suds logs. -suds.client.log.addFilter(SudsLogFilter()) diff --git a/oslo_vmware/tests/__init__.py b/oslo_vmware/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oslo_vmware/tests/base.py b/oslo_vmware/tests/base.py deleted file mode 100644 index 69e6a80..0000000 --- a/oslo_vmware/tests/base.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os - -import fixtures -import testtools - -_TRUE_VALUES = ('true', '1', 'yes') - -# FIXME(dhellmann) Update this to use oslo.test library - - -class TestCase(testtools.TestCase): - - """Test case base class for all unit tests.""" - - def setUp(self): - """Run before each test method to initialize test environment.""" - - super(TestCase, self).setUp() - test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0) - try: - test_timeout = int(test_timeout) - except ValueError: - # If timeout value is invalid do not set a timeout. - test_timeout = 0 - if test_timeout > 0: - self.useFixture(fixtures.Timeout(test_timeout, gentle=True)) - - self.useFixture(fixtures.NestedTempfile()) - self.useFixture(fixtures.TempHomeDir()) - - if os.environ.get('OS_STDOUT_CAPTURE') in _TRUE_VALUES: - stdout = self.useFixture(fixtures.StringStream('stdout')).stream - self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout)) - if os.environ.get('OS_STDERR_CAPTURE') in _TRUE_VALUES: - stderr = self.useFixture(fixtures.StringStream('stderr')).stream - self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr)) - - self.log_fixture = self.useFixture(fixtures.FakeLogger()) diff --git a/oslo_vmware/tests/objects/__init__.py b/oslo_vmware/tests/objects/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/oslo_vmware/tests/objects/test_datacenter.py b/oslo_vmware/tests/objects/test_datacenter.py deleted file mode 100644 index c4d261e..0000000 --- a/oslo_vmware/tests/objects/test_datacenter.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import mock - -from oslo_vmware.objects import datacenter -from oslo_vmware.tests import base - - -class DatacenterTestCase(base.TestCase): - - """Test the Datacenter object.""" - - def test_dc(self): - self.assertRaises(ValueError, datacenter.Datacenter, None, 'dc-1') - self.assertRaises(ValueError, datacenter.Datacenter, mock.Mock(), None) - dc = datacenter.Datacenter('ref', 'name') - self.assertEqual('ref', dc.ref) - self.assertEqual('name', dc.name) diff --git a/oslo_vmware/tests/objects/test_datastore.py b/oslo_vmware/tests/objects/test_datastore.py deleted file mode 100644 index 9ee23bb..0000000 --- a/oslo_vmware/tests/objects/test_datastore.py +++ /dev/null @@ -1,435 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import mock -from oslo_utils import units -import six.moves.urllib.parse as urlparse - -from oslo_vmware import constants -from oslo_vmware.objects import datastore -from oslo_vmware.tests import base -from oslo_vmware import vim_util - - -class HostMount(object): - - def __init__(self, key, mountInfo): - self.key = key - self.mountInfo = mountInfo - - -class MountInfo(object): - - def __init__(self, accessMode, mounted, accessible): - self.accessMode = accessMode - self.mounted = mounted - self.accessible = accessible - - -class DatastoreTestCase(base.TestCase): - - """Test the Datastore object.""" - - def test_ds(self): - ds = datastore.Datastore( - "fake_ref", "ds_name", 2 * units.Gi, 1 * units.Gi, 1 * units.Gi) - self.assertEqual('ds_name', ds.name) - self.assertEqual('fake_ref', ds.ref) - self.assertEqual(2 * units.Gi, ds.capacity) - self.assertEqual(1 * units.Gi, ds.freespace) - self.assertEqual(1 * units.Gi, ds.uncommitted) - - def test_ds_invalid_space(self): - self.assertRaises(ValueError, datastore.Datastore, - "fake_ref", "ds_name", 1 * units.Gi, 2 * units.Gi) - self.assertRaises(ValueError, datastore.Datastore, - "fake_ref", "ds_name", None, 2 * units.Gi) - - def test_ds_no_capacity_no_freespace(self): - ds = datastore.Datastore("fake_ref", "ds_name") - self.assertIsNone(ds.capacity) - self.assertIsNone(ds.freespace) - - def test_ds_invalid(self): - self.assertRaises(ValueError, datastore.Datastore, None, "ds_name") - self.assertRaises(ValueError, datastore.Datastore, "fake_ref", None) - - def test_build_path(self): - ds = datastore.Datastore("fake_ref", "ds_name") - ds_path = ds.build_path("some_dir", "foo.vmdk") - self.assertEqual('[ds_name] some_dir/foo.vmdk', str(ds_path)) - - def test_build_url(self): - ds = datastore.Datastore("fake_ref", "ds_name") - path = 'images/ubuntu.vmdk' - self.assertRaises(ValueError, ds.build_url, 'https', '10.0.0.2', path) - ds.datacenter = mock.Mock() - ds.datacenter.name = "dc_path" - ds_url = ds.build_url('https', '10.0.0.2', path) - self.assertEqual(ds_url.datastore_name, "ds_name") - self.assertEqual(ds_url.datacenter_path, "dc_path") - self.assertEqual(ds_url.path, path) - - def test_get_summary(self): - ds_ref = vim_util.get_moref('ds-0', 'Datastore') - ds = datastore.Datastore(ds_ref, 'ds-name') - summary = mock.sentinel.summary - session = mock.Mock() - session.invoke_api = mock.Mock() - session.invoke_api.return_value = summary - ret = ds.get_summary(session) - self.assertEqual(summary, ret) - session.invoke_api.assert_called_once_with(vim_util, - 'get_object_property', - session.vim, - ds.ref, 'summary') - - def _test_get_connected_hosts(self, in_maintenance_mode, - m1_accessible=True): - session = mock.Mock() - ds_ref = vim_util.get_moref('ds-0', 'Datastore') - ds = datastore.Datastore(ds_ref, 'ds-name') - ds.get_summary = mock.Mock() - ds.get_summary.return_value.accessible = False - self.assertEqual([], ds.get_connected_hosts(session)) - ds.get_summary.return_value.accessible = True - m1 = HostMount("m1", MountInfo('readWrite', True, m1_accessible)) - m2 = HostMount("m2", MountInfo('read', True, True)) - m3 = HostMount("m3", MountInfo('readWrite', False, True)) - m4 = HostMount("m4", MountInfo('readWrite', True, False)) - ds.get_summary.assert_called_once_with(session) - - class Prop(object): - DatastoreHostMount = [m1, m2, m3, m4] - - class HostRuntime(object): - inMaintenanceMode = in_maintenance_mode - - class HostProp(object): - name = 'runtime' - val = HostRuntime() - - class Object(object): - obj = "m1" - propSet = [HostProp()] - - class Runtime(object): - objects = [Object()] - - session.invoke_api = mock.Mock(side_effect=[Prop(), Runtime()]) - hosts = ds.get_connected_hosts(session) - calls = [mock.call(vim_util, 'get_object_property', - session.vim, ds_ref, 'host')] - if m1_accessible: - calls.append( - mock.call(vim_util, - 'get_properties_for_a_collection_of_objects', - session.vim, 'HostSystem', ["m1"], ['runtime'])) - self.assertEqual(calls, session.invoke_api.mock_calls) - return hosts - - def test_get_connected_hosts(self): - hosts = self._test_get_connected_hosts(False) - self.assertEqual(1, len(hosts)) - self.assertEqual("m1", hosts.pop()) - - def test_get_connected_hosts_in_maintenance(self): - hosts = self._test_get_connected_hosts(True) - self.assertEqual(0, len(hosts)) - - def test_get_connected_hosts_ho_hosts(self): - hosts = self._test_get_connected_hosts(False, False) - self.assertEqual(0, len(hosts)) - - def test_is_datastore_mount_usable(self): - m = MountInfo('readWrite', True, True) - self.assertTrue(datastore.Datastore.is_datastore_mount_usable(m)) - m = MountInfo('read', True, True) - self.assertFalse(datastore.Datastore.is_datastore_mount_usable(m)) - m = MountInfo('readWrite', False, True) - self.assertFalse(datastore.Datastore.is_datastore_mount_usable(m)) - m = MountInfo('readWrite', True, False) - self.assertFalse(datastore.Datastore.is_datastore_mount_usable(m)) - m = MountInfo('readWrite', False, False) - self.assertFalse(datastore.Datastore.is_datastore_mount_usable(m)) - m = MountInfo('readWrite', None, None) - self.assertFalse(datastore.Datastore.is_datastore_mount_usable(m)) - m = MountInfo('readWrite', None, True) - self.assertFalse(datastore.Datastore.is_datastore_mount_usable(m)) - - -class DatastorePathTestCase(base.TestCase): - - """Test the DatastorePath object.""" - - def test_ds_path(self): - p = datastore.DatastorePath('dsname', 'a/b/c', 'file.iso') - self.assertEqual('[dsname] a/b/c/file.iso', str(p)) - self.assertEqual('a/b/c/file.iso', p.rel_path) - self.assertEqual('a/b/c', p.parent.rel_path) - self.assertEqual('[dsname] a/b/c', str(p.parent)) - self.assertEqual('dsname', p.datastore) - self.assertEqual('file.iso', p.basename) - self.assertEqual('a/b/c', p.dirname) - - def test_ds_path_no_ds_name(self): - bad_args = [ - ('', ['a/b/c', 'file.iso']), - (None, ['a/b/c', 'file.iso'])] - for t in bad_args: - self.assertRaises( - ValueError, datastore.DatastorePath, - t[0], *t[1]) - - def test_ds_path_invalid_path_components(self): - bad_args = [ - ('dsname', [None]), - ('dsname', ['', None]), - ('dsname', ['a', None]), - ('dsname', ['a', None, 'b']), - ('dsname', [None, '']), - ('dsname', [None, 'b'])] - - for t in bad_args: - self.assertRaises( - ValueError, datastore.DatastorePath, - t[0], *t[1]) - - def test_ds_path_no_subdir(self): - args = [ - ('dsname', ['', 'x.vmdk']), - ('dsname', ['x.vmdk'])] - - canonical_p = datastore.DatastorePath('dsname', 'x.vmdk') - self.assertEqual('[dsname] x.vmdk', str(canonical_p)) - self.assertEqual('', canonical_p.dirname) - self.assertEqual('x.vmdk', canonical_p.basename) - self.assertEqual('x.vmdk', canonical_p.rel_path) - for t in args: - p = datastore.DatastorePath(t[0], *t[1]) - self.assertEqual(str(canonical_p), str(p)) - - def test_ds_path_ds_only(self): - args = [ - ('dsname', []), - ('dsname', ['']), - ('dsname', ['', ''])] - - canonical_p = datastore.DatastorePath('dsname') - self.assertEqual('[dsname]', str(canonical_p)) - self.assertEqual('', canonical_p.rel_path) - self.assertEqual('', canonical_p.basename) - self.assertEqual('', canonical_p.dirname) - for t in args: - p = datastore.DatastorePath(t[0], *t[1]) - self.assertEqual(str(canonical_p), str(p)) - self.assertEqual(canonical_p.rel_path, p.rel_path) - - def test_ds_path_equivalence(self): - args = [ - ('dsname', ['a/b/c/', 'x.vmdk']), - ('dsname', ['a/', 'b/c/', 'x.vmdk']), - ('dsname', ['a', 'b', 'c', 'x.vmdk']), - ('dsname', ['a/b/c', 'x.vmdk'])] - - canonical_p = datastore.DatastorePath('dsname', 'a/b/c', 'x.vmdk') - for t in args: - p = datastore.DatastorePath(t[0], *t[1]) - self.assertEqual(str(canonical_p), str(p)) - self.assertEqual(canonical_p.datastore, p.datastore) - self.assertEqual(canonical_p.rel_path, p.rel_path) - self.assertEqual(str(canonical_p.parent), str(p.parent)) - - def test_ds_path_non_equivalence(self): - args = [ - # leading slash - ('dsname', ['/a', 'b', 'c', 'x.vmdk']), - ('dsname', ['/a/b/c/', 'x.vmdk']), - ('dsname', ['a/b/c', '/x.vmdk']), - # leading space - ('dsname', ['a/b/c/', ' x.vmdk']), - ('dsname', ['a/', ' b/c/', 'x.vmdk']), - ('dsname', [' a', 'b', 'c', 'x.vmdk']), - # trailing space - ('dsname', ['/a/b/c/', 'x.vmdk ']), - ('dsname', ['a/b/c/ ', 'x.vmdk'])] - - canonical_p = datastore.DatastorePath('dsname', 'a/b/c', 'x.vmdk') - for t in args: - p = datastore.DatastorePath(t[0], *t[1]) - self.assertNotEqual(str(canonical_p), str(p)) - - def test_equal(self): - a = datastore.DatastorePath('ds_name', 'a') - b = datastore.DatastorePath('ds_name', 'a') - self.assertEqual(a, b) - - def test_join(self): - p = datastore.DatastorePath('ds_name', 'a') - ds_path = p.join('b') - self.assertEqual('[ds_name] a/b', str(ds_path)) - - p = datastore.DatastorePath('ds_name', 'a') - ds_path = p.join() - bad_args = [ - [None], - ['', None], - ['a', None], - ['a', None, 'b']] - for arg in bad_args: - self.assertRaises(ValueError, p.join, *arg) - - def test_ds_path_parse(self): - p = datastore.DatastorePath.parse('[dsname]') - self.assertEqual('dsname', p.datastore) - self.assertEqual('', p.rel_path) - - p = datastore.DatastorePath.parse('[dsname] folder') - self.assertEqual('dsname', p.datastore) - self.assertEqual('folder', p.rel_path) - - p = datastore.DatastorePath.parse('[dsname] folder/file') - self.assertEqual('dsname', p.datastore) - self.assertEqual('folder/file', p.rel_path) - - for p in [None, '']: - self.assertRaises(ValueError, datastore.DatastorePath.parse, p) - - for p in ['bad path', '/a/b/c', 'a/b/c']: - self.assertRaises(IndexError, datastore.DatastorePath.parse, p) - - -class DatastoreURLTestCase(base.TestCase): - - """Test the DatastoreURL object.""" - - def test_path_strip(self): - scheme = 'https' - server = '13.37.73.31' - path = 'images/ubuntu-14.04.vmdk' - dc_path = 'datacenter-1' - ds_name = 'datastore-1' - params = {'dcPath': dc_path, 'dsName': ds_name} - query = urlparse.urlencode(params) - url = datastore.DatastoreURL(scheme, server, path, dc_path, ds_name) - expected_url = '%s://%s/folder/%s?%s' % ( - scheme, server, path, query) - self.assertEqual(expected_url, str(url)) - - def test_path_lstrip(self): - scheme = 'https' - server = '13.37.73.31' - path = '/images/ubuntu-14.04.vmdk' - dc_path = 'datacenter-1' - ds_name = 'datastore-1' - params = {'dcPath': dc_path, 'dsName': ds_name} - query = urlparse.urlencode(params) - url = datastore.DatastoreURL(scheme, server, path, dc_path, ds_name) - expected_url = '%s://%s/folder/%s?%s' % ( - scheme, server, path.lstrip('/'), query) - self.assertEqual(expected_url, str(url)) - - def test_path_rstrip(self): - scheme = 'https' - server = '13.37.73.31' - path = 'images/ubuntu-14.04.vmdk/' - dc_path = 'datacenter-1' - ds_name = 'datastore-1' - params = {'dcPath': dc_path, 'dsName': ds_name} - query = urlparse.urlencode(params) - url = datastore.DatastoreURL(scheme, server, path, dc_path, ds_name) - expected_url = '%s://%s/folder/%s?%s' % ( - scheme, server, path.rstrip('/'), query) - self.assertEqual(expected_url, str(url)) - - def test_urlparse(self): - dc_path = 'datacenter-1' - ds_name = 'datastore-1' - params = {'dcPath': dc_path, 'dsName': ds_name} - query = urlparse.urlencode(params) - url = 'https://13.37.73.31/folder/images/aa.vmdk?%s' % query - ds_url = datastore.DatastoreURL.urlparse(url) - self.assertEqual(url, str(ds_url)) - - def test_datastore_name(self): - dc_path = 'datacenter-1' - ds_name = 'datastore-1' - params = {'dcPath': dc_path, 'dsName': ds_name} - query = urlparse.urlencode(params) - url = 'https://13.37.73.31/folder/images/aa.vmdk?%s' % query - ds_url = datastore.DatastoreURL.urlparse(url) - self.assertEqual(ds_name, ds_url.datastore_name) - - def test_datacenter_path(self): - dc_path = 'datacenter-1' - ds_name = 'datastore-1' - params = {'dcPath': dc_path, 'dsName': ds_name} - query = urlparse.urlencode(params) - url = 'https://13.37.73.31/folder/images/aa.vmdk?%s' % query - ds_url = datastore.DatastoreURL.urlparse(url) - self.assertEqual(dc_path, ds_url.datacenter_path) - - def test_path(self): - dc_path = 'datacenter-1' - ds_name = 'datastore-1' - params = {'dcPath': dc_path, 'dsName': ds_name} - path = 'images/aa.vmdk' - query = urlparse.urlencode(params) - url = 'https://13.37.73.31/folder/%s?%s' % (path, query) - ds_url = datastore.DatastoreURL.urlparse(url) - self.assertEqual(path, ds_url.path) - - @mock.patch('six.moves.http_client.HTTPSConnection') - def test_connect(self, mock_conn): - dc_path = 'datacenter-1' - ds_name = 'datastore-1' - params = {'dcPath': dc_path, 'dsName': ds_name} - query = urlparse.urlencode(params) - url = 'https://13.37.73.31/folder/images/aa.vmdk?%s' % query - ds_url = datastore.DatastoreURL.urlparse(url) - cookie = mock.Mock() - ds_url.connect('PUT', 128, cookie) - mock_conn.assert_called_once_with('13.37.73.31') - - def test_get_transfer_ticket(self): - dc_path = 'datacenter-1' - ds_name = 'datastore-1' - params = {'dcPath': dc_path, 'dsName': ds_name} - query = urlparse.urlencode(params) - url = 'https://13.37.73.31/folder/images/aa.vmdk?%s' % query - session = mock.Mock() - session.invoke_api = mock.Mock() - - class Ticket(object): - id = 'fake_id' - session.invoke_api.return_value = Ticket() - ds_url = datastore.DatastoreURL.urlparse(url) - ticket = ds_url.get_transfer_ticket(session, 'PUT') - self.assertEqual('%s="%s"' % (constants.CGI_COOKIE_KEY, 'fake_id'), - ticket) - - def test_get_datastore_by_ref(self): - session = mock.Mock() - ds_ref = mock.Mock() - expected_props = {'summary.name': 'datastore1', - 'summary.type': 'NFS', - 'summary.freeSpace': 1000, - 'summary.capacity': 2000} - session.invoke_api = mock.Mock() - session.invoke_api.return_value = expected_props - ds_obj = datastore.get_datastore_by_ref(session, ds_ref) - self.assertEqual(expected_props['summary.name'], ds_obj.name) - self.assertEqual(expected_props['summary.type'], ds_obj.type) - self.assertEqual(expected_props['summary.freeSpace'], ds_obj.freespace) - self.assertEqual(expected_props['summary.capacity'], ds_obj.capacity) diff --git a/oslo_vmware/tests/test.ovf b/oslo_vmware/tests/test.ovf deleted file mode 100644 index f96e1b2..0000000 --- a/oslo_vmware/tests/test.ovf +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - - - Virtual disk information - - - - The list of logical networks - - The dvportgroup-81 network - - - - A virtual machine - test - - The kind of installed guest operating system - - - Virtual hardware requirements - - Virtual Hardware Family - 0 - test - vmx-10 - - - hertz * 10^6 - Number of Virtual CPUs - 1 virtual CPU(s) - 1 - 3 - 1 - - - byte * 2^20 - Memory Size - 512MB of memory - 2 - 4 - 512 - - - 1 - IDE Controller - VirtualIDEController 1 - 3 - 5 - - - 0 - IDE Controller - VirtualIDEController 0 - 4 - 5 - - - false - VirtualVideoCard - 5 - 24 - - - - - - - - false - VirtualVMCIDevice - 6 - vmware.vmci - 1 - - - - - 1 - true - CD-ROM 1 - ovf:/file/file1 - 7 - 4 - vmware.cdrom.iso - 15 - - - 0 - Hard Disk 1 - ovf:/disk/vmdisk1 - 8 - 4 - 17 - - - - 7 - true - dvportgroup-81 - E1000 ethernet adapter on "dvportgroup-81" - Ethernet 1 - 9 - E1000 - 10 - - - - - - - - - - - - - - - - - - - - - - - A human-readable annotation - foo - - - \ No newline at end of file diff --git a/oslo_vmware/tests/test_api.py b/oslo_vmware/tests/test_api.py deleted file mode 100644 index b3e11db..0000000 --- a/oslo_vmware/tests/test_api.py +++ /dev/null @@ -1,577 +0,0 @@ -# coding=utf-8 -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Unit tests for session management and API invocation classes. -""" - -from datetime import datetime -from eventlet import greenthread -import mock -import six -import suds - -from oslo_vmware import api -from oslo_vmware import exceptions -from oslo_vmware import pbm -from oslo_vmware.tests import base -from oslo_vmware import vim_util - - -class RetryDecoratorTest(base.TestCase): - """Tests for retry decorator class.""" - - def test_retry(self): - result = "RESULT" - - @api.RetryDecorator() - def func(*args, **kwargs): - return result - - self.assertEqual(result, func()) - - def func2(*args, **kwargs): - return result - - retry = api.RetryDecorator() - self.assertEqual(result, retry(func2)()) - self.assertTrue(retry._retry_count == 0) - - def test_retry_with_expected_exceptions(self): - result = "RESULT" - responses = [exceptions.VimSessionOverLoadException(None), - exceptions.VimSessionOverLoadException(None), - result] - - def func(*args, **kwargs): - response = responses.pop(0) - if isinstance(response, Exception): - raise response - return response - - sleep_time_incr = 0.01 - retry_count = 2 - retry = api.RetryDecorator(10, sleep_time_incr, 10, - (exceptions.VimSessionOverLoadException,)) - self.assertEqual(result, retry(func)()) - self.assertTrue(retry._retry_count == retry_count) - self.assertEqual(retry_count * sleep_time_incr, retry._sleep_time) - - def test_retry_with_max_retries(self): - responses = [exceptions.VimSessionOverLoadException(None), - exceptions.VimSessionOverLoadException(None), - exceptions.VimSessionOverLoadException(None)] - - def func(*args, **kwargs): - response = responses.pop(0) - if isinstance(response, Exception): - raise response - return response - - retry = api.RetryDecorator(2, 0, 0, - (exceptions.VimSessionOverLoadException,)) - self.assertRaises(exceptions.VimSessionOverLoadException, retry(func)) - self.assertTrue(retry._retry_count == 2) - - def test_retry_with_unexpected_exception(self): - - def func(*args, **kwargs): - raise exceptions.VimException(None) - - retry = api.RetryDecorator() - self.assertRaises(exceptions.VimException, retry(func)) - self.assertTrue(retry._retry_count == 0) - - -class VMwareAPISessionTest(base.TestCase): - """Tests for VMwareAPISession.""" - - SERVER_IP = '10.1.2.3' - PORT = 443 - USERNAME = 'admin' - PASSWORD = 'password' - POOL_SIZE = 15 - - def setUp(self): - super(VMwareAPISessionTest, self).setUp() - patcher = mock.patch('oslo_vmware.vim.Vim') - self.addCleanup(patcher.stop) - self.VimMock = patcher.start() - self.VimMock.side_effect = lambda *args, **kw: mock.MagicMock() - self.cert_mock = mock.Mock() - - def _create_api_session(self, _create_session, retry_count=10, - task_poll_interval=1): - return api.VMwareAPISession(VMwareAPISessionTest.SERVER_IP, - VMwareAPISessionTest.USERNAME, - VMwareAPISessionTest.PASSWORD, - retry_count, - task_poll_interval, - 'https', - _create_session, - port=VMwareAPISessionTest.PORT, - cacert=self.cert_mock, - insecure=False, - pool_size=VMwareAPISessionTest.POOL_SIZE) - - def test_vim(self): - api_session = self._create_api_session(False) - api_session.vim - self.VimMock.assert_called_with( - protocol=api_session._scheme, - host=VMwareAPISessionTest.SERVER_IP, - port=VMwareAPISessionTest.PORT, - wsdl_url=api_session._vim_wsdl_loc, - cacert=self.cert_mock, - insecure=False, - pool_maxsize=VMwareAPISessionTest.POOL_SIZE, - connection_timeout=None, - op_id_prefix='oslo.vmware') - - @mock.patch.object(pbm, 'Pbm') - def test_pbm(self, pbm_mock): - api_session = self._create_api_session(True) - vim_obj = api_session.vim - cookie = mock.Mock() - vim_obj.get_http_cookie.return_value = cookie - api_session._pbm_wsdl_loc = mock.Mock() - - pbm = mock.Mock() - pbm_mock.return_value = pbm - api_session._get_session_cookie = mock.Mock(return_value=cookie) - - self.assertEqual(pbm, api_session.pbm) - pbm.set_soap_cookie.assert_called_once_with(cookie) - - def test_create_session(self): - session = mock.Mock() - session.key = "12345" - api_session = self._create_api_session(False) - cookie = mock.Mock() - vim_obj = api_session.vim - vim_obj.Login.return_value = session - vim_obj.get_http_cookie.return_value = cookie - - pbm = mock.Mock() - api_session._pbm = pbm - - api_session._create_session() - session_manager = vim_obj.service_content.sessionManager - vim_obj.Login.assert_called_once_with( - session_manager, userName=VMwareAPISessionTest.USERNAME, - password=VMwareAPISessionTest.PASSWORD) - self.assertFalse(vim_obj.TerminateSession.called) - self.assertEqual(session.key, api_session._session_id) - pbm.set_soap_cookie.assert_called_once_with(cookie) - - def test_create_session_with_existing_inactive_session(self): - old_session_key = '12345' - new_session_key = '67890' - session = mock.Mock() - session.key = new_session_key - api_session = self._create_api_session(False) - api_session._session_id = old_session_key - api_session._session_username = api_session._server_username - vim_obj = api_session.vim - vim_obj.Login.return_value = session - vim_obj.SessionIsActive.return_value = False - - api_session._create_session() - session_manager = vim_obj.service_content.sessionManager - vim_obj.SessionIsActive.assert_called_once_with( - session_manager, sessionID=old_session_key, - userName=VMwareAPISessionTest.USERNAME) - vim_obj.Login.assert_called_once_with( - session_manager, userName=VMwareAPISessionTest.USERNAME, - password=VMwareAPISessionTest.PASSWORD) - self.assertEqual(new_session_key, api_session._session_id) - - def test_create_session_with_existing_active_session(self): - old_session_key = '12345' - api_session = self._create_api_session(False) - api_session._session_id = old_session_key - api_session._session_username = api_session._server_username - vim_obj = api_session.vim - vim_obj.SessionIsActive.return_value = True - - api_session._create_session() - session_manager = vim_obj.service_content.sessionManager - vim_obj.SessionIsActive.assert_called_once_with( - session_manager, sessionID=old_session_key, - userName=VMwareAPISessionTest.USERNAME) - self.assertFalse(vim_obj.Login.called) - self.assertEqual(old_session_key, api_session._session_id) - - def test_invoke_api(self): - api_session = self._create_api_session(True) - response = mock.Mock() - - def api(*args, **kwargs): - return response - - module = mock.Mock() - module.api = api - ret = api_session.invoke_api(module, 'api') - self.assertEqual(response, ret) - - def test_logout_with_exception(self): - session = mock.Mock() - session.key = "12345" - api_session = self._create_api_session(False) - vim_obj = api_session.vim - vim_obj.Login.return_value = session - vim_obj.Logout.side_effect = exceptions.VimFaultException([], None) - api_session._create_session() - api_session.logout() - self.assertEqual("12345", api_session._session_id) - - def test_logout_no_session(self): - api_session = self._create_api_session(False) - vim_obj = api_session.vim - api_session.logout() - self.assertEqual(0, vim_obj.Logout.call_count) - - def test_logout_calls_vim_logout(self): - session = mock.Mock() - session.key = "12345" - api_session = self._create_api_session(False) - vim_obj = api_session.vim - vim_obj.Login.return_value = session - vim_obj.Logout.return_value = None - - api_session._create_session() - session_manager = vim_obj.service_content.sessionManager - vim_obj.Login.assert_called_once_with( - session_manager, userName=VMwareAPISessionTest.USERNAME, - password=VMwareAPISessionTest.PASSWORD) - api_session.logout() - vim_obj.Logout.assert_called_once_with( - session_manager) - self.assertIsNone(api_session._session_id) - - def test_invoke_api_with_expected_exception(self): - api_session = self._create_api_session(True) - api_session._create_session = mock.Mock() - vim_obj = api_session.vim - vim_obj.SessionIsActive.return_value = False - ret = mock.Mock() - responses = [exceptions.VimConnectionException(None), ret] - - def api(*args, **kwargs): - response = responses.pop(0) - if isinstance(response, Exception): - raise response - return response - - module = mock.Mock() - module.api = api - with mock.patch.object(greenthread, 'sleep'): - self.assertEqual(ret, api_session.invoke_api(module, 'api')) - api_session._create_session.assert_called_once_with() - - def test_invoke_api_not_recreate_session(self): - api_session = self._create_api_session(True) - api_session._create_session = mock.Mock() - vim_obj = api_session.vim - vim_obj.SessionIsActive.return_value = True - ret = mock.Mock() - responses = [exceptions.VimConnectionException(None), ret] - - def api(*args, **kwargs): - response = responses.pop(0) - if isinstance(response, Exception): - raise response - return response - - module = mock.Mock() - module.api = api - with mock.patch.object(greenthread, 'sleep'): - self.assertEqual(ret, api_session.invoke_api(module, 'api')) - self.assertFalse(api_session._create_session.called) - - def test_invoke_api_with_vim_fault_exception(self): - api_session = self._create_api_session(True) - - def api(*args, **kwargs): - raise exceptions.VimFaultException([], None) - - module = mock.Mock() - module.api = api - self.assertRaises(exceptions.VimFaultException, - api_session.invoke_api, - module, - 'api') - - def test_invoke_api_with_vim_fault_exception_details(self): - api_session = self._create_api_session(True) - fault_string = 'Invalid property.' - fault_list = [exceptions.INVALID_PROPERTY] - details = {u'name': suds.sax.text.Text(u'фира')} - - module = mock.Mock() - module.api.side_effect = exceptions.VimFaultException(fault_list, - fault_string, - details=details) - e = self.assertRaises(exceptions.InvalidPropertyException, - api_session.invoke_api, - module, - 'api') - details_str = u"{'name': 'фира'}" - expected_str = "%s\nFaults: %s\nDetails: %s" % (fault_string, - fault_list, - details_str) - self.assertEqual(expected_str, six.text_type(e)) - self.assertEqual(details, e.details) - - def test_invoke_api_with_empty_response(self): - api_session = self._create_api_session(True) - vim_obj = api_session.vim - vim_obj.SessionIsActive.return_value = True - - def api(*args, **kwargs): - raise exceptions.VimFaultException( - [exceptions.NOT_AUTHENTICATED], None) - - module = mock.Mock() - module.api = api - ret = api_session.invoke_api(module, 'api') - self.assertEqual([], ret) - vim_obj.SessionIsActive.assert_called_once_with( - vim_obj.service_content.sessionManager, - sessionID=api_session._session_id, - userName=api_session._session_username) - - def test_invoke_api_with_stale_session(self): - api_session = self._create_api_session(True) - api_session._create_session = mock.Mock() - vim_obj = api_session.vim - vim_obj.SessionIsActive.return_value = False - result = mock.Mock() - responses = [exceptions.VimFaultException( - [exceptions.NOT_AUTHENTICATED], None), result] - - def api(*args, **kwargs): - response = responses.pop(0) - if isinstance(response, Exception): - raise response - return response - - module = mock.Mock() - module.api = api - with mock.patch.object(greenthread, 'sleep'): - ret = api_session.invoke_api(module, 'api') - self.assertEqual(result, ret) - vim_obj.SessionIsActive.assert_called_once_with( - vim_obj.service_content.sessionManager, - sessionID=api_session._session_id, - userName=api_session._session_username) - api_session._create_session.assert_called_once_with() - - def test_invoke_api_with_unknown_fault(self): - api_session = self._create_api_session(True) - fault_list = ['NotAFile'] - - module = mock.Mock() - module.api.side_effect = exceptions.VimFaultException(fault_list, - 'Not a file.') - ex = self.assertRaises(exceptions.VimFaultException, - api_session.invoke_api, - module, - 'api') - self.assertEqual(fault_list, ex.fault_list) - - def test_wait_for_task(self): - api_session = self._create_api_session(True) - task_info_list = [('queued', 0), ('running', 40), ('success', 100)] - task_info_list_size = len(task_info_list) - - def invoke_api_side_effect(module, method, *args, **kwargs): - (state, progress) = task_info_list.pop(0) - task_info = mock.Mock() - task_info.progress = progress - task_info.queueTime = datetime(2016, 12, 6, 15, 29, 43, 79060) - task_info.completeTime = datetime(2016, 12, 6, 15, 29, 50, 79060) - task_info.state = state - return task_info - - api_session.invoke_api = mock.Mock(side_effect=invoke_api_side_effect) - task = mock.Mock() - with mock.patch.object(greenthread, 'sleep'): - ret = api_session.wait_for_task(task) - self.assertEqual('success', ret.state) - self.assertEqual(100, ret.progress) - api_session.invoke_api.assert_called_with(vim_util, - 'get_object_property', - api_session.vim, task, - 'info', - skip_op_id=True) - self.assertEqual(task_info_list_size, - api_session.invoke_api.call_count) - - def test_wait_for_task_with_error_state(self): - api_session = self._create_api_session(True) - task_info_list = [('queued', 0), ('running', 40), ('error', -1)] - task_info_list_size = len(task_info_list) - - def invoke_api_side_effect(module, method, *args, **kwargs): - (state, progress) = task_info_list.pop(0) - task_info = mock.Mock() - task_info.progress = progress - task_info.state = state - return task_info - - api_session.invoke_api = mock.Mock(side_effect=invoke_api_side_effect) - task = mock.Mock() - with mock.patch.object(greenthread, 'sleep'): - self.assertRaises(exceptions.VimFaultException, - api_session.wait_for_task, - task) - api_session.invoke_api.assert_called_with(vim_util, - 'get_object_property', - api_session.vim, task, - 'info', - skip_op_id=True) - self.assertEqual(task_info_list_size, - api_session.invoke_api.call_count) - - def test_wait_for_task_with_invoke_api_exception(self): - api_session = self._create_api_session(True) - api_session.invoke_api = mock.Mock( - side_effect=exceptions.VimException(None)) - task = mock.Mock() - with mock.patch.object(greenthread, 'sleep'): - self.assertRaises(exceptions.VimException, - api_session.wait_for_task, - task) - api_session.invoke_api.assert_called_once_with(vim_util, - 'get_object_property', - api_session.vim, task, - 'info', - skip_op_id=True) - - def test_wait_for_lease_ready(self): - api_session = self._create_api_session(True) - lease_states = ['initializing', 'ready'] - num_states = len(lease_states) - - def invoke_api_side_effect(module, method, *args, **kwargs): - return lease_states.pop(0) - - api_session.invoke_api = mock.Mock(side_effect=invoke_api_side_effect) - lease = mock.Mock() - with mock.patch.object(greenthread, 'sleep'): - api_session.wait_for_lease_ready(lease) - api_session.invoke_api.assert_called_with(vim_util, - 'get_object_property', - api_session.vim, lease, - 'state', - skip_op_id=True) - self.assertEqual(num_states, api_session.invoke_api.call_count) - - def test_wait_for_lease_ready_with_error_state(self): - api_session = self._create_api_session(True) - responses = ['initializing', 'error', 'error_msg'] - - def invoke_api_side_effect(module, method, *args, **kwargs): - return responses.pop(0) - - api_session.invoke_api = mock.Mock(side_effect=invoke_api_side_effect) - lease = mock.Mock() - with mock.patch.object(greenthread, 'sleep'): - self.assertRaises(exceptions.VimException, - api_session.wait_for_lease_ready, - lease) - exp_calls = [mock.call(vim_util, 'get_object_property', - api_session.vim, lease, 'state', - skip_op_id=True)] * 2 - exp_calls.append(mock.call(vim_util, 'get_object_property', - api_session.vim, lease, 'error')) - self.assertEqual(exp_calls, api_session.invoke_api.call_args_list) - - def test_wait_for_lease_ready_with_unknown_state(self): - api_session = self._create_api_session(True) - - def invoke_api_side_effect(module, method, *args, **kwargs): - return 'unknown' - - api_session.invoke_api = mock.Mock(side_effect=invoke_api_side_effect) - lease = mock.Mock() - self.assertRaises(exceptions.VimException, - api_session.wait_for_lease_ready, - lease) - api_session.invoke_api.assert_called_once_with(vim_util, - 'get_object_property', - api_session.vim, - lease, 'state', - skip_op_id=True) - - def test_wait_for_lease_ready_with_invoke_api_exception(self): - api_session = self._create_api_session(True) - api_session.invoke_api = mock.Mock( - side_effect=exceptions.VimException(None)) - lease = mock.Mock() - self.assertRaises(exceptions.VimException, - api_session.wait_for_lease_ready, - lease) - api_session.invoke_api.assert_called_once_with( - vim_util, 'get_object_property', api_session.vim, lease, - 'state', skip_op_id=True) - - def _poll_task_well_known_exceptions(self, fault, - expected_exception): - api_session = self._create_api_session(False) - - def fake_invoke_api(self, module, method, *args, **kwargs): - task_info = mock.Mock() - task_info.progress = -1 - task_info.state = 'error' - error = mock.Mock() - error.localizedMessage = "Error message" - error_fault = mock.Mock() - error_fault.__class__.__name__ = fault - error.fault = error_fault - task_info.error = error - return task_info - - with ( - mock.patch.object(api_session, 'invoke_api', fake_invoke_api) - ): - fake_task = mock.Mock() - fake_task.value = 'task-1' - self.assertRaises(expected_exception, - api_session._poll_task, - fake_task) - - def test_poll_task_well_known_exceptions(self): - for k, v in six.iteritems(exceptions._fault_classes_registry): - self._poll_task_well_known_exceptions(k, v) - - def test_poll_task_unknown_exception(self): - _unknown_exceptions = { - 'NotAFile': exceptions.VimFaultException, - 'RuntimeFault': exceptions.VimFaultException - } - - for k, v in six.iteritems(_unknown_exceptions): - self._poll_task_well_known_exceptions(k, v) - - def test_update_pbm_wsdl_loc(self): - session = mock.Mock() - session.key = "12345" - api_session = self._create_api_session(False) - self.assertIsNone(api_session._pbm_wsdl_loc) - api_session.pbm_wsdl_loc_set('fake_wsdl') - self.assertEqual('fake_wsdl', api_session._pbm_wsdl_loc) diff --git a/oslo_vmware/tests/test_exceptions.py b/oslo_vmware/tests/test_exceptions.py deleted file mode 100644 index 419b769..0000000 --- a/oslo_vmware/tests/test_exceptions.py +++ /dev/null @@ -1,117 +0,0 @@ -# Copyright (c) 2015 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Unit tests for exceptions module. -""" -from oslo_vmware._i18n import _ -from oslo_vmware import exceptions -from oslo_vmware.tests import base - - -class ExceptionsTest(base.TestCase): - - def test_exception_summary_exception_as_list(self): - # assert that if a list is fed to the VimException object - # that it will error. - self.assertRaises(ValueError, - exceptions.VimException, - [], ValueError('foo')) - - def test_exception_summary_string(self): - e = exceptions.VimException(_("string"), ValueError("foo")) - string = str(e) - self.assertEqual("string\nCause: foo", string) - - def test_vim_fault_exception_string(self): - self.assertRaises(ValueError, - exceptions.VimFaultException, - "bad", ValueError("argument")) - - def test_vim_fault_exception(self): - vfe = exceptions.VimFaultException([ValueError("example")], _("cause")) - string = str(vfe) - self.assertEqual("cause\nFaults: [ValueError('example',)]", string) - - def test_vim_fault_exception_with_cause_and_details(self): - vfe = exceptions.VimFaultException([ValueError("example")], - "MyMessage", - "FooBar", - {'foo': 'bar'}) - string = str(vfe) - self.assertEqual("MyMessage\n" - "Cause: FooBar\n" - "Faults: [ValueError('example',)]\n" - "Details: {'foo': 'bar'}", - string) - - def _create_subclass_exception(self): - class VimSubClass(exceptions.VimException): - pass - return VimSubClass - - def test_register_fault_class(self): - exc = self._create_subclass_exception() - exceptions.register_fault_class('ValueError', exc) - self.assertEqual(exc, exceptions.get_fault_class('ValueError')) - - def test_register_fault_class_override(self): - exc = self._create_subclass_exception() - exceptions.register_fault_class(exceptions.ALREADY_EXISTS, exc) - self.assertEqual(exc, - exceptions.get_fault_class(exceptions.ALREADY_EXISTS)) - - def test_register_fault_class_invalid(self): - self.assertRaises(TypeError, - exceptions.register_fault_class, - 'ValueError', ValueError) - - def test_log_exception_to_string(self): - self.assertEqual('Insufficient disk space.', - str(exceptions.NoDiskSpaceException())) - - def test_get_fault_class(self): - self.assertEqual(exceptions.AlreadyExistsException, - exceptions.get_fault_class("AlreadyExists")) - self.assertEqual(exceptions.CannotDeleteFileException, - exceptions.get_fault_class("CannotDeleteFile")) - self.assertEqual(exceptions.FileAlreadyExistsException, - exceptions.get_fault_class("FileAlreadyExists")) - self.assertEqual(exceptions.FileFaultException, - exceptions.get_fault_class("FileFault")) - self.assertEqual(exceptions.FileLockedException, - exceptions.get_fault_class("FileLocked")) - self.assertEqual(exceptions.FileNotFoundException, - exceptions.get_fault_class("FileNotFound")) - self.assertEqual(exceptions.InvalidPowerStateException, - exceptions.get_fault_class("InvalidPowerState")) - self.assertEqual(exceptions.InvalidPropertyException, - exceptions.get_fault_class("InvalidProperty")) - self.assertEqual(exceptions.NoPermissionException, - exceptions.get_fault_class("NoPermission")) - self.assertEqual(exceptions.NotAuthenticatedException, - exceptions.get_fault_class("NotAuthenticated")) - self.assertEqual(exceptions.TaskInProgress, - exceptions.get_fault_class("TaskInProgress")) - self.assertEqual(exceptions.DuplicateName, - exceptions.get_fault_class("DuplicateName")) - self.assertEqual(exceptions.NoDiskSpaceException, - exceptions.get_fault_class("NoDiskSpace")) - self.assertEqual(exceptions.ToolsUnavailableException, - exceptions.get_fault_class("ToolsUnavailable")) - self.assertEqual(exceptions.ManagedObjectNotFoundException, - exceptions.get_fault_class("ManagedObjectNotFound")) - # Test unknown fault. - self.assertIsNone(exceptions.get_fault_class("NotAFile")) diff --git a/oslo_vmware/tests/test_hacking.py b/oslo_vmware/tests/test_hacking.py deleted file mode 100644 index 9f5599d..0000000 --- a/oslo_vmware/tests/test_hacking.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2017 OpenStack Foundation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import itertools - -from oslo_vmware.hacking import checks -from oslo_vmware.tests import base - - -class HackingTestCase(base.TestCase): - def test_no_log_translations(self): - for log, hint in itertools.product(checks._all_log_levels, - checks._all_hints): - bad = 'LOG.%s(%s("Bad"))' % (log, hint) - self.assertEqual(1, len(list(checks.no_translate_logs(bad, 'f')))) - # Catch abuses when used with a variable and not a literal - bad = 'LOG.%s(%s(msg))' % (log, hint) - self.assertEqual(1, len(list(checks.no_translate_logs(bad, 'f')))) diff --git a/oslo_vmware/tests/test_image_transfer.py b/oslo_vmware/tests/test_image_transfer.py deleted file mode 100644 index 22506e6..0000000 --- a/oslo_vmware/tests/test_image_transfer.py +++ /dev/null @@ -1,403 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Unit tests for functions and classes for image transfer. -""" - -import mock -import six - -from oslo_vmware import exceptions -from oslo_vmware import image_transfer -from oslo_vmware.tests import base - - -class ImageTransferUtilityTest(base.TestCase): - """Tests for image_transfer utility methods.""" - - def test_start_transfer(self): - data = b'image-data-here' - read_handle = six.BytesIO(data) - write_handle = mock.Mock() - image_transfer._start_transfer(read_handle, write_handle, None) - write_handle.write.assert_called_once_with(data) - - @mock.patch('oslo_vmware.rw_handles.FileWriteHandle') - @mock.patch('oslo_vmware.rw_handles.ImageReadHandle') - @mock.patch.object(image_transfer, '_start_transfer') - def test_download_flat_image( - self, - fake_transfer, - fake_rw_handles_ImageReadHandle, - fake_rw_handles_FileWriteHandle): - - context = mock.Mock() - image_id = mock.Mock() - image_service = mock.Mock() - image_service.download = mock.Mock() - image_service.download.return_value = 'fake_iter' - - fake_ImageReadHandle = 'fake_ImageReadHandle' - fake_FileWriteHandle = 'fake_FileWriteHandle' - cookies = [] - timeout_secs = 10 - image_size = 1000 - host = '127.0.0.1' - port = 443 - dc_path = 'dc1' - ds_name = 'ds1' - file_path = '/fake_path' - - fake_rw_handles_ImageReadHandle.return_value = fake_ImageReadHandle - fake_rw_handles_FileWriteHandle.return_value = fake_FileWriteHandle - - image_transfer.download_flat_image( - context, - timeout_secs, - image_service, - image_id, - image_size=image_size, - host=host, - port=port, - data_center_name=dc_path, - datastore_name=ds_name, - cookies=cookies, - file_path=file_path) - - image_service.download.assert_called_once_with(context, image_id) - - fake_rw_handles_ImageReadHandle.assert_called_once_with('fake_iter') - - fake_rw_handles_FileWriteHandle.assert_called_once_with( - host, - port, - dc_path, - ds_name, - cookies, - file_path, - image_size, - cacerts=None) - - fake_transfer.assert_called_once_with( - fake_ImageReadHandle, - fake_FileWriteHandle, - timeout_secs) - - @mock.patch('oslo_vmware.rw_handles.FileWriteHandle') - @mock.patch.object(image_transfer, '_start_transfer') - def test_download_file(self, start_transfer, file_write_handle_cls): - write_handle = mock.sentinel.write_handle - file_write_handle_cls.return_value = write_handle - - read_handle = mock.sentinel.read_handle - host = mock.sentinel.host - port = mock.sentinel.port - dc_name = mock.sentinel.dc_name - ds_name = mock.sentinel.ds_name - cookies = mock.sentinel.cookies - upload_file_path = mock.sentinel.upload_file_path - file_size = mock.sentinel.file_size - cacerts = mock.sentinel.cacerts - timeout_secs = mock.sentinel.timeout_secs - image_transfer.download_file( - read_handle, host, port, dc_name, ds_name, cookies, - upload_file_path, file_size, cacerts, timeout_secs) - - file_write_handle_cls.assert_called_once_with( - host, port, dc_name, ds_name, cookies, upload_file_path, - file_size, cacerts=cacerts) - start_transfer.assert_called_once_with( - read_handle, write_handle, timeout_secs) - - @mock.patch('oslo_vmware.rw_handles.VmdkWriteHandle') - @mock.patch.object(image_transfer, '_start_transfer') - def test_download_stream_optimized_data(self, fake_transfer, - fake_rw_handles_VmdkWriteHandle): - - context = mock.Mock() - session = mock.Mock() - read_handle = mock.Mock() - timeout_secs = 10 - image_size = 1000 - host = '127.0.0.1' - port = 443 - resource_pool = 'rp-1' - vm_folder = 'folder-1' - vm_import_spec = None - - fake_VmdkWriteHandle = mock.Mock() - fake_VmdkWriteHandle.get_imported_vm = mock.Mock() - fake_rw_handles_VmdkWriteHandle.return_value = fake_VmdkWriteHandle - - image_transfer.download_stream_optimized_data( - context, - timeout_secs, - read_handle, - session=session, - host=host, - port=port, - resource_pool=resource_pool, - vm_folder=vm_folder, - vm_import_spec=vm_import_spec, - image_size=image_size) - - fake_rw_handles_VmdkWriteHandle.assert_called_once_with( - session, - host, - port, - resource_pool, - vm_folder, - vm_import_spec, - image_size, - 'PUT') - - fake_transfer.assert_called_once_with(read_handle, - fake_VmdkWriteHandle, - timeout_secs) - - fake_VmdkWriteHandle.get_imported_vm.assert_called_once_with() - - @mock.patch('tarfile.open') - @mock.patch('oslo_vmware.image_util.get_vmdk_name_from_ovf') - def test_get_vmdk_handle(self, get_vmdk_name_from_ovf, tar_open): - - ovf_info = mock.Mock() - ovf_info.name = 'test.ovf' - vmdk_info = mock.Mock() - vmdk_info.name = 'test.vmdk' - tar = mock.Mock() - tar.__iter__ = mock.Mock(return_value=iter([ovf_info, vmdk_info])) - tar.__enter__ = mock.Mock(return_value=tar) - tar.__exit__ = mock.Mock(return_value=None) - tar_open.return_value = tar - - ovf_handle = mock.Mock() - get_vmdk_name_from_ovf.return_value = 'test.vmdk' - vmdk_handle = mock.Mock() - tar.extractfile.side_effect = [ovf_handle, vmdk_handle] - - ova_handle = mock.sentinel.ova_handle - ret = image_transfer._get_vmdk_handle(ova_handle) - - self.assertEqual(vmdk_handle, ret) - tar_open.assert_called_once_with(mode="r|", fileobj=ova_handle) - self.assertEqual([mock.call(ovf_info), mock.call(vmdk_info)], - tar.extractfile.call_args_list) - get_vmdk_name_from_ovf.assert_called_once_with(ovf_handle) - - @mock.patch('tarfile.open') - def test_get_vmdk_handle_with_invalid_ova(self, tar_open): - - tar = mock.Mock() - tar.__iter__ = mock.Mock(return_value=iter([])) - tar.__enter__ = mock.Mock(return_value=tar) - tar.__exit__ = mock.Mock(return_value=None) - tar_open.return_value = tar - - ova_handle = mock.sentinel.ova_handle - ret = image_transfer._get_vmdk_handle(ova_handle) - - self.assertIsNone(ret) - tar_open.assert_called_once_with(mode="r|", fileobj=ova_handle) - self.assertFalse(tar.extractfile.called) - - @mock.patch('oslo_vmware.rw_handles.ImageReadHandle') - @mock.patch.object(image_transfer, 'download_stream_optimized_data') - @mock.patch.object(image_transfer, '_get_vmdk_handle') - def _test_download_stream_optimized_image( - self, - get_vmdk_handle, - download_stream_optimized_data, - image_read_handle, - container=None, - invalid_ova=False): - - image_service = mock.Mock() - if container: - image_service.show.return_value = {'container_format': container} - read_iter = mock.sentinel.read_iter - image_service.download.return_value = read_iter - read_handle = mock.sentinel.read_handle - image_read_handle.return_value = read_handle - - if container == 'ova': - if invalid_ova: - get_vmdk_handle.return_value = None - else: - vmdk_handle = mock.sentinel.vmdk_handle - get_vmdk_handle.return_value = vmdk_handle - - imported_vm = mock.sentinel.imported_vm - download_stream_optimized_data.return_value = imported_vm - - context = mock.sentinel.context - timeout_secs = mock.sentinel.timeout_secs - image_id = mock.sentinel.image_id - session = mock.sentinel.session - image_size = mock.sentinel.image_size - host = mock.sentinel.host - port = mock.sentinel.port - resource_pool = mock.sentinel.port - vm_folder = mock.sentinel.vm_folder - vm_import_spec = mock.sentinel.vm_import_spec - - if container == 'ova' and invalid_ova: - self.assertRaises(exceptions.ImageTransferException, - image_transfer.download_stream_optimized_image, - context, - timeout_secs, - image_service, - image_id, - session=session, - host=host, - port=port, - resource_pool=resource_pool, - vm_folder=vm_folder, - vm_import_spec=vm_import_spec, - image_size=image_size) - else: - ret = image_transfer.download_stream_optimized_image( - context, - timeout_secs, - image_service, - image_id, - session=session, - host=host, - port=port, - resource_pool=resource_pool, - vm_folder=vm_folder, - vm_import_spec=vm_import_spec, - image_size=image_size) - - self.assertEqual(imported_vm, ret) - image_service.show.assert_called_once_with(context, image_id) - image_service.download.assert_called_once_with(context, image_id) - image_read_handle.assert_called_once_with(read_iter) - if container == 'ova': - get_vmdk_handle.assert_called_once_with(read_handle) - exp_read_handle = vmdk_handle - else: - exp_read_handle = read_handle - download_stream_optimized_data.assert_called_once_with( - context, - timeout_secs, - exp_read_handle, - session=session, - host=host, - port=port, - resource_pool=resource_pool, - vm_folder=vm_folder, - vm_import_spec=vm_import_spec, - image_size=image_size) - - def test_download_stream_optimized_image(self): - self._test_download_stream_optimized_image() - - def test_download_stream_optimized_image_ova(self): - self._test_download_stream_optimized_image(container='ova') - - def test_download_stream_optimized_image_invalid_ova(self): - self._test_download_stream_optimized_image(container='ova', - invalid_ova=True) - - @mock.patch.object(image_transfer, '_start_transfer') - @mock.patch('oslo_vmware.rw_handles.VmdkReadHandle') - def test_copy_stream_optimized_disk( - self, vmdk_read_handle, start_transfer): - - read_handle = mock.sentinel.read_handle - vmdk_read_handle.return_value = read_handle - - context = mock.sentinel.context - timeout = mock.sentinel.timeout - write_handle = mock.Mock(name='/cinder/images/tmpAbcd.vmdk') - session = mock.sentinel.session - host = mock.sentinel.host - port = mock.sentinel.port - vm = mock.sentinel.vm - vmdk_file_path = mock.sentinel.vmdk_file_path - vmdk_size = mock.sentinel.vmdk_size - - image_transfer.copy_stream_optimized_disk( - context, timeout, write_handle, session=session, host=host, - port=port, vm=vm, vmdk_file_path=vmdk_file_path, - vmdk_size=vmdk_size) - - vmdk_read_handle.assert_called_once_with( - session, host, port, vm, vmdk_file_path, vmdk_size) - start_transfer.assert_called_once_with(read_handle, write_handle, - timeout) - - @mock.patch('oslo_vmware.rw_handles.VmdkReadHandle') - @mock.patch.object(image_transfer, '_start_transfer') - def test_upload_image(self, fake_transfer, fake_rw_handles_VmdkReadHandle): - - context = mock.sentinel.context - image_id = mock.sentinel.image_id - owner_id = mock.sentinel.owner_id - session = mock.sentinel.session - vm = mock.sentinel.vm - image_service = mock.Mock() - - timeout_secs = 10 - image_size = 1000 - host = '127.0.0.1' - port = 443 - file_path = '/fake_path' - - # TODO(vbala) Remove this after we delete the keyword argument - # 'is_public' from all client code. - is_public = False - - image_name = 'fake_image' - image_version = 1 - - fake_VmdkReadHandle = mock.Mock() - fake_rw_handles_VmdkReadHandle.return_value = fake_VmdkReadHandle - - image_transfer.upload_image(context, - timeout_secs, - image_service, - image_id, - owner_id, - session=session, - host=host, - port=port, - vm=vm, - vmdk_file_path=file_path, - vmdk_size=image_size, - is_public=is_public, - image_name=image_name, - image_version=image_version) - - fake_rw_handles_VmdkReadHandle.assert_called_once_with(session, - host, - port, - vm, - file_path, - image_size) - - ver_str = six.text_type(image_version) - image_metadata = {'disk_format': 'vmdk', - 'name': image_name, - 'properties': {'vmware_image_version': ver_str, - 'vmware_disktype': 'streamOptimized', - 'owner_id': owner_id}} - - image_service.update.assert_called_once_with(context, - image_id, - image_metadata, - data=fake_VmdkReadHandle) diff --git a/oslo_vmware/tests/test_image_util.py b/oslo_vmware/tests/test_image_util.py deleted file mode 100644 index f97f33f..0000000 --- a/oslo_vmware/tests/test_image_util.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2016 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Unit tests for image_util. -""" - -import os - -from oslo_vmware import image_util -from oslo_vmware.tests import base - - -class ImageUtilTest(base.TestCase): - - def test_get_vmdk_name_from_ovf(self): - ovf_descriptor = os.path.join(os.path.dirname(__file__), 'test.ovf') - with open(ovf_descriptor) as f: - vmdk_name = image_util.get_vmdk_name_from_ovf(f) - self.assertEqual("test-disk1.vmdk", vmdk_name) diff --git a/oslo_vmware/tests/test_pbm.py b/oslo_vmware/tests/test_pbm.py deleted file mode 100644 index bc05f7e..0000000 --- a/oslo_vmware/tests/test_pbm.py +++ /dev/null @@ -1,216 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Unit tests for PBM utility methods. -""" - -import os - -import mock -import six.moves.urllib.parse as urlparse -import six.moves.urllib.request as urllib - -from oslo_vmware import pbm -from oslo_vmware.tests import base - - -class PBMUtilityTest(base.TestCase): - """Tests for PBM utility methods.""" - - def test_get_all_profiles(self): - session = mock.Mock() - session.pbm = mock.Mock() - profile_ids = mock.Mock() - - def invoke_api_side_effect(module, method, *args, **kwargs): - self.assertEqual(session.pbm, module) - self.assertIn(method, ['PbmQueryProfile', 'PbmRetrieveContent']) - self.assertEqual(session.pbm.service_content.profileManager, - args[0]) - if method == 'PbmQueryProfile': - self.assertEqual('STORAGE', - kwargs['resourceType'].resourceType) - return profile_ids - self.assertEqual(profile_ids, kwargs['profileIds']) - - session.invoke_api.side_effect = invoke_api_side_effect - pbm.get_all_profiles(session) - self.assertEqual(2, session.invoke_api.call_count) - - def test_get_all_profiles_with_no_profiles(self): - session = mock.Mock() - session.pbm = mock.Mock() - session.invoke_api.return_value = [] - profiles = pbm.get_all_profiles(session) - session.invoke_api.assert_called_once_with( - session.pbm, - 'PbmQueryProfile', - session.pbm.service_content.profileManager, - resourceType=session.pbm.client.factory.create()) - self.assertEqual([], profiles) - - def _create_profile(self, profile_id, name): - profile = mock.Mock() - profile.profileId = profile_id - profile.name = name - return profile - - @mock.patch.object(pbm, 'get_all_profiles') - def test_get_profile_id_by_name(self, get_all_profiles): - profiles = [self._create_profile(str(i), 'profile-%d' % i) - for i in range(0, 10)] - get_all_profiles.return_value = profiles - - session = mock.Mock() - exp_profile_id = '5' - profile_id = pbm.get_profile_id_by_name(session, - 'profile-%s' % exp_profile_id) - self.assertEqual(exp_profile_id, profile_id) - get_all_profiles.assert_called_once_with(session) - - @mock.patch.object(pbm, 'get_all_profiles') - def test_get_profile_id_by_name_with_invalid_profile(self, - get_all_profiles): - profiles = [self._create_profile(str(i), 'profile-%d' % i) - for i in range(0, 10)] - get_all_profiles.return_value = profiles - - session = mock.Mock() - profile_id = pbm.get_profile_id_by_name(session, - ('profile-%s' % 11)) - self.assertFalse(profile_id) - get_all_profiles.assert_called_once_with(session) - - def test_filter_hubs_by_profile(self): - pbm_client = mock.Mock() - session = mock.Mock() - session.pbm = pbm_client - hubs = mock.Mock() - profile_id = 'profile-0' - - pbm.filter_hubs_by_profile(session, hubs, profile_id) - session.invoke_api.assert_called_once_with( - pbm_client, - 'PbmQueryMatchingHub', - pbm_client.service_content.placementSolver, - hubsToSearch=hubs, - profile=profile_id) - - def _create_datastore(self, value): - ds = mock.Mock() - ds.value = value - return ds - - def test_convert_datastores_to_hubs(self): - ds_values = [] - datastores = [] - for i in range(0, 10): - value = "ds-%d" % i - ds_values.append(value) - datastores.append(self._create_datastore(value)) - - pbm_client_factory = mock.Mock() - pbm_client_factory.create.side_effect = lambda *args: mock.Mock() - hubs = pbm.convert_datastores_to_hubs(pbm_client_factory, datastores) - self.assertEqual(len(datastores), len(hubs)) - hub_ids = [hub.hubId for hub in hubs] - self.assertEqual(set(ds_values), set(hub_ids)) - - def test_filter_datastores_by_hubs(self): - ds_values = [] - datastores = [] - for i in range(0, 10): - value = "ds-%d" % i - ds_values.append(value) - datastores.append(self._create_datastore(value)) - - hubs = [] - hub_ids = ds_values[0:int(len(ds_values) / 2)] - for hub_id in hub_ids: - hub = mock.Mock() - hub.hubId = hub_id - hubs.append(hub) - - filtered_ds = pbm.filter_datastores_by_hubs(hubs, datastores) - self.assertEqual(len(hubs), len(filtered_ds)) - filtered_ds_values = [ds.value for ds in filtered_ds] - self.assertEqual(set(hub_ids), set(filtered_ds_values)) - - def test_get_pbm_wsdl_location(self): - wsdl = pbm.get_pbm_wsdl_location(None) - self.assertIsNone(wsdl) - - def expected_wsdl(version): - driver_abs_dir = os.path.abspath(os.path.dirname(pbm.__file__)) - path = os.path.join(driver_abs_dir, 'wsdl', version, - 'pbmService.wsdl') - return urlparse.urljoin('file:', urllib.pathname2url(path)) - - with mock.patch('os.path.exists') as path_exists: - path_exists.return_value = True - wsdl = pbm.get_pbm_wsdl_location('5') - self.assertEqual(expected_wsdl('5'), wsdl) - wsdl = pbm.get_pbm_wsdl_location('5.5') - self.assertEqual(expected_wsdl('5.5'), wsdl) - wsdl = pbm.get_pbm_wsdl_location('5.5.1') - self.assertEqual(expected_wsdl('5.5'), wsdl) - path_exists.return_value = False - wsdl = pbm.get_pbm_wsdl_location('5.5') - self.assertIsNone(wsdl) - - def test_get_profiles(self): - pbm_service = mock.Mock() - session = mock.Mock(pbm=pbm_service) - - object_ref = mock.Mock() - pbm_service.client.factory.create.return_value = object_ref - - profile_id = mock.sentinel.profile_id - session.invoke_api.return_value = profile_id - - value = 'vm-1' - vm = mock.Mock(value=value) - ret = pbm.get_profiles(session, vm) - - self.assertEqual(profile_id, ret) - session.invoke_api.assert_called_once_with( - pbm_service, - 'PbmQueryAssociatedProfile', - pbm_service.service_content.profileManager, - entity=object_ref) - self.assertEqual(value, object_ref.key) - self.assertEqual('virtualMachine', object_ref.objectType) - - def test_get_profiles_by_ids(self): - pbm_service = mock.Mock() - session = mock.Mock(pbm=pbm_service) - - profiles = mock.sentinel.profiles - session.invoke_api.return_value = profiles - - profile_ids = mock.sentinel.profile_ids - ret = pbm.get_profiles_by_ids(session, profile_ids) - - self.assertEqual(profiles, ret) - session.invoke_api.assert_called_once_with( - pbm_service, - 'PbmRetrieveContent', - pbm_service.service_content.profileManager, - profileIds=profile_ids) - - def test_get_profiles_by_empty_ids(self): - session = mock.Mock() - self.assertEqual([], pbm.get_profiles_by_ids(session, [])) diff --git a/oslo_vmware/tests/test_rw_handles.py b/oslo_vmware/tests/test_rw_handles.py deleted file mode 100644 index ba33ce5..0000000 --- a/oslo_vmware/tests/test_rw_handles.py +++ /dev/null @@ -1,390 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Unit tests for read and write handles for image transfer. -""" - -import ssl - -import mock -import six - -from oslo_vmware import exceptions -from oslo_vmware import rw_handles -from oslo_vmware.tests import base -from oslo_vmware import vim_util - - -class FileHandleTest(base.TestCase): - """Tests for FileHandle.""" - - def test_close(self): - file_handle = mock.Mock() - vmw_http_file = rw_handles.FileHandle(file_handle) - vmw_http_file.close() - file_handle.close.assert_called_once_with() - - @mock.patch('urllib3.connection.HTTPConnection') - def test_create_connection_http(self, http_conn): - conn = mock.Mock() - http_conn.return_value = conn - - handle = rw_handles.FileHandle(None) - ret = handle._create_connection('http://localhost/foo?q=bar', 'GET') - - self.assertEqual(conn, ret) - conn.putrequest.assert_called_once_with('GET', '/foo?q=bar') - - @mock.patch('urllib3.connection.HTTPSConnection') - def test_create_connection_https(self, https_conn): - conn = mock.Mock() - https_conn.return_value = conn - - handle = rw_handles.FileHandle(None) - ret = handle._create_connection('https://localhost/foo?q=bar', 'GET') - - self.assertEqual(conn, ret) - conn.set_cert.assert_called_once_with( - ca_certs=None, cert_reqs=ssl.CERT_NONE, assert_fingerprint=None) - conn.putrequest.assert_called_once_with('GET', '/foo?q=bar') - - @mock.patch('urllib3.connection.HTTPSConnection') - def test_create_connection_https_with_cacerts(self, https_conn): - conn = mock.Mock() - https_conn.return_value = conn - - handle = rw_handles.FileHandle(None) - ret = handle._create_connection('https://localhost/foo?q=bar', 'GET', - cacerts=True) - - self.assertEqual(conn, ret) - conn.set_cert.assert_called_once_with( - ca_certs=None, cert_reqs=ssl.CERT_REQUIRED, - assert_fingerprint=None) - - @mock.patch('urllib3.connection.HTTPSConnection') - def test_create_connection_https_with_ssl_thumbprint(self, https_conn): - conn = mock.Mock() - https_conn.return_value = conn - - handle = rw_handles.FileHandle(None) - cacerts = mock.sentinel.cacerts - thumbprint = mock.sentinel.thumbprint - ret = handle._create_connection('https://localhost/foo?q=bar', 'GET', - cacerts=cacerts, - ssl_thumbprint=thumbprint) - - self.assertEqual(conn, ret) - conn.set_cert.assert_called_once_with( - ca_certs=cacerts, cert_reqs=None, assert_fingerprint=thumbprint) - - -class FileWriteHandleTest(base.TestCase): - """Tests for FileWriteHandle.""" - - def setUp(self): - super(FileWriteHandleTest, self).setUp() - - vim_cookie = mock.Mock() - vim_cookie.name = 'name' - vim_cookie.value = 'value' - - self._conn = mock.Mock() - patcher = mock.patch( - 'urllib3.connection.HTTPConnection') - self.addCleanup(patcher.stop) - HTTPConnectionMock = patcher.start() - HTTPConnectionMock.return_value = self._conn - - self.vmw_http_write_file = rw_handles.FileWriteHandle( - '10.1.2.3', 443, 'dc-0', 'ds-0', [vim_cookie], '1.vmdk', 100, - 'http') - - def test_write(self): - self.vmw_http_write_file.write(None) - self._conn.send.assert_called_once_with(None) - - def test_close(self): - self.vmw_http_write_file.close() - self._conn.getresponse.assert_called_once_with() - self._conn.close.assert_called_once_with() - - -class VmdkHandleTest(base.TestCase): - """Tests for VmdkHandle.""" - - def test_find_vmdk_url(self): - device_url_0 = mock.Mock() - device_url_0.disk = False - device_url_1 = mock.Mock() - device_url_1.disk = True - device_url_1.url = 'https://*/ds1/vm1.vmdk' - device_url_1.sslThumbprint = '11:22:33:44:55' - lease_info = mock.Mock() - lease_info.deviceUrl = [device_url_0, device_url_1] - host = '10.1.2.3' - port = 443 - exp_url = 'https://%s:%d/ds1/vm1.vmdk' % (host, port) - vmw_http_file = rw_handles.VmdkHandle(None, None, None, None) - url, thumbprint = vmw_http_file._find_vmdk_url(lease_info, host, port) - self.assertEqual(exp_url, url) - self.assertEqual('11:22:33:44:55', thumbprint) - - def test_update_progress(self): - session = mock.Mock() - lease = mock.Mock() - handle = rw_handles.VmdkHandle(session, lease, 'fake-url', None) - handle._get_progress = mock.Mock(return_value=50) - - handle.update_progress() - - session.invoke_api.assert_called_once_with(session.vim, - 'HttpNfcLeaseProgress', - lease, percent=50) - - def test_update_progress_with_error(self): - session = mock.Mock() - handle = rw_handles.VmdkHandle(session, None, 'fake-url', None) - - handle._get_progress = mock.Mock(return_value=0) - session.invoke_api.side_effect = exceptions.VimException(None) - - self.assertRaises(exceptions.VimException, handle.update_progress) - - -class VmdkWriteHandleTest(base.TestCase): - """Tests for VmdkWriteHandle.""" - - def setUp(self): - super(VmdkWriteHandleTest, self).setUp() - self._conn = mock.Mock() - patcher = mock.patch( - 'urllib3.connection.HTTPConnection') - self.addCleanup(patcher.stop) - HTTPConnectionMock = patcher.start() - HTTPConnectionMock.return_value = self._conn - - def _create_mock_session(self, disk=True, progress=-1): - device_url = mock.Mock() - device_url.disk = disk - device_url.url = 'http://*/ds/disk1.vmdk' - lease_info = mock.Mock() - lease_info.deviceUrl = [device_url] - session = mock.Mock() - - def session_invoke_api_side_effect(module, method, *args, **kwargs): - if module == session.vim: - if method == 'ImportVApp': - return mock.Mock() - elif method == 'HttpNfcLeaseProgress': - self.assertEqual(progress, kwargs['percent']) - return - return lease_info - - session.invoke_api.side_effect = session_invoke_api_side_effect - vim_cookie = mock.Mock() - vim_cookie.name = 'name' - vim_cookie.value = 'value' - session.vim.client.options.transport.cookiejar = [vim_cookie] - return session - - def test_init_failure(self): - session = self._create_mock_session(False) - self.assertRaises(exceptions.VimException, - rw_handles.VmdkWriteHandle, - session, - '10.1.2.3', - 443, - 'rp-1', - 'folder-1', - None, - 100) - - def test_write(self): - session = self._create_mock_session() - handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', 443, - 'rp-1', 'folder-1', None, - 100) - data = [1] * 10 - handle.write(data) - self.assertEqual(len(data), handle._bytes_written) - self._conn.putrequest.assert_called_once_with('PUT', '/ds/disk1.vmdk') - self._conn.send.assert_called_once_with(data) - - def test_write_post(self): - session = self._create_mock_session() - handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', 443, - 'rp-1', 'folder-1', None, - 100, http_method='POST') - data = [1] * 10 - handle.write(data) - self.assertEqual(len(data), handle._bytes_written) - self._conn.putrequest.assert_called_once_with('POST', '/ds/disk1.vmdk') - self._conn.send.assert_called_once_with(data) - - def test_update_progress(self): - vmdk_size = 100 - data_size = 10 - session = self._create_mock_session(True, 10) - handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', 443, - 'rp-1', 'folder-1', None, - vmdk_size) - handle.write([1] * data_size) - handle.update_progress() - - def test_close(self): - session = self._create_mock_session() - handle = rw_handles.VmdkWriteHandle(session, '10.1.2.3', 443, - 'rp-1', 'folder-1', None, - 100) - - def session_invoke_api_side_effect(module, method, *args, **kwargs): - if module == vim_util and method == 'get_object_property': - return 'ready' - self.assertEqual(session.vim, module) - self.assertEqual('HttpNfcLeaseComplete', method) - - session.invoke_api = mock.Mock( - side_effect=session_invoke_api_side_effect) - handle.close() - self.assertEqual(2, session.invoke_api.call_count) - - -class VmdkReadHandleTest(base.TestCase): - """Tests for VmdkReadHandle.""" - - def setUp(self): - super(VmdkReadHandleTest, self).setUp() - self._resp = mock.Mock() - self._resp.read.return_value = 'fake-data' - self._conn = mock.Mock() - self._conn.getresponse.return_value = self._resp - patcher = mock.patch( - 'urllib3.connection.HTTPConnection') - self.addCleanup(patcher.stop) - HTTPConnectionMock = patcher.start() - HTTPConnectionMock.return_value = self._conn - - def _create_mock_session(self, disk=True, progress=-1): - device_url = mock.Mock() - device_url.disk = disk - device_url.url = 'http://*/ds/disk1.vmdk' - lease_info = mock.Mock() - lease_info.deviceUrl = [device_url] - session = mock.Mock() - - def session_invoke_api_side_effect(module, method, *args, **kwargs): - if module == session.vim: - if method == 'ExportVm': - return mock.Mock() - elif method == 'HttpNfcLeaseProgress': - self.assertEqual(progress, kwargs['percent']) - return - return lease_info - - session.invoke_api.side_effect = session_invoke_api_side_effect - vim_cookie = mock.Mock() - vim_cookie.name = 'name' - vim_cookie.value = 'value' - session.vim.client.options.transport.cookiejar = [vim_cookie] - return session - - def test_init_failure(self): - session = self._create_mock_session(False) - self.assertRaises(exceptions.VimException, - rw_handles.VmdkReadHandle, - session, - '10.1.2.3', - 443, - 'vm-1', - '[ds] disk1.vmdk', - 100) - - def test_read(self): - chunk_size = rw_handles.READ_CHUNKSIZE - session = self._create_mock_session() - handle = rw_handles.VmdkReadHandle(session, '10.1.2.3', 443, - 'vm-1', '[ds] disk1.vmdk', - chunk_size * 10) - data = handle.read(chunk_size) - self.assertEqual('fake-data', data) - - def test_update_progress(self): - chunk_size = len('fake-data') - vmdk_size = chunk_size * 10 - session = self._create_mock_session(True, 10) - handle = rw_handles.VmdkReadHandle(session, '10.1.2.3', 443, - 'vm-1', '[ds] disk1.vmdk', - vmdk_size) - data = handle.read(chunk_size) - handle.update_progress() - self.assertEqual('fake-data', data) - - def test_close(self): - session = self._create_mock_session() - handle = rw_handles.VmdkReadHandle(session, '10.1.2.3', 443, - 'vm-1', '[ds] disk1.vmdk', - 100) - - def session_invoke_api_side_effect(module, method, *args, **kwargs): - if module == vim_util and method == 'get_object_property': - return 'ready' - self.assertEqual(session.vim, module) - self.assertEqual('HttpNfcLeaseComplete', method) - - session.invoke_api = mock.Mock( - side_effect=session_invoke_api_side_effect) - handle.close() - self.assertEqual(2, session.invoke_api.call_count) - - def test_close_with_error(self): - session = self._create_mock_session() - handle = rw_handles.VmdkReadHandle(session, '10.1.2.3', 443, - 'vm-1', '[ds] disk1.vmdk', - 100) - session.invoke_api.side_effect = exceptions.VimException(None) - - self.assertRaises(exceptions.VimException, handle.close) - self._resp.close.assert_called_once_with() - - -class ImageReadHandleTest(base.TestCase): - """Tests for ImageReadHandle.""" - - def test_read(self): - max_items = 10 - item = [1] * 10 - - class ImageReadIterator(six.Iterator): - - def __init__(self): - self.num_items = 0 - - def __iter__(self): - return self - - def __next__(self): - if (self.num_items < max_items): - self.num_items += 1 - return item - raise StopIteration - - next = __next__ - - handle = rw_handles.ImageReadHandle(ImageReadIterator()) - for _ in range(0, max_items): - self.assertEqual(item, handle.read(10)) - self.assertFalse(handle.read(10)) diff --git a/oslo_vmware/tests/test_service.py b/oslo_vmware/tests/test_service.py deleted file mode 100644 index 336ef0d..0000000 --- a/oslo_vmware/tests/test_service.py +++ /dev/null @@ -1,611 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import mock -import requests -import six -import six.moves.http_client as httplib -import suds - -import ddt -from oslo_vmware import exceptions -from oslo_vmware import service -from oslo_vmware.tests import base -from oslo_vmware import vim_util - - -@ddt.ddt -class ServiceMessagePluginTest(base.TestCase): - """Test class for ServiceMessagePlugin.""" - - def setUp(self): - super(ServiceMessagePluginTest, self).setUp() - self.plugin = service.ServiceMessagePlugin() - - @ddt.data(('value', 'foo', 'string'), ('removeKey', '1', 'int'), - ('removeKey', 'foo', 'string')) - @ddt.unpack - def test_add_attribute_for_value(self, name, text, expected_xsd_type): - node = mock.Mock() - node.name = name - node.text = text - self.plugin.add_attribute_for_value(node) - node.set.assert_called_once_with('xsi:type', - 'xsd:%s' % expected_xsd_type) - - def test_marshalled(self): - context = mock.Mock() - self.plugin.prune = mock.Mock() - self.plugin.marshalled(context) - self.plugin.prune.assert_called_once_with(context.envelope) - context.envelope.walk.assert_called_once_with( - self.plugin.add_attribute_for_value) - - -class ServiceTest(base.TestCase): - - def setUp(self): - super(ServiceTest, self).setUp() - patcher = mock.patch('suds.client.Client') - self.addCleanup(patcher.stop) - self.SudsClientMock = patcher.start() - - def test_retrieve_properties_ex_fault_checker_with_empty_response(self): - ex = self.assertRaises( - exceptions.VimFaultException, - service.Service._retrieve_properties_ex_fault_checker, - None) - self.assertEqual([exceptions.NOT_AUTHENTICATED], - ex.fault_list) - - def test_retrieve_properties_ex_fault_checker(self): - fault_list = ['FileFault', 'VimFault'] - missing_set = [] - for fault in fault_list: - missing_elem = mock.Mock() - missing_elem.fault.fault.__class__.__name__ = fault - missing_set.append(missing_elem) - obj_cont = mock.Mock() - obj_cont.missingSet = missing_set - response = mock.Mock() - response.objects = [obj_cont] - - ex = self.assertRaises( - exceptions.VimFaultException, - service.Service._retrieve_properties_ex_fault_checker, - response) - self.assertEqual(fault_list, ex.fault_list) - - def test_request_handler(self): - managed_object = 'VirtualMachine' - resp = mock.Mock() - - def side_effect(mo, **kwargs): - self.assertEqual(managed_object, mo._type) - self.assertEqual(managed_object, mo.value) - return resp - - svc_obj = service.Service() - attr_name = 'powerOn' - service_mock = svc_obj.client.service - setattr(service_mock, attr_name, side_effect) - ret = svc_obj.powerOn(managed_object) - self.assertEqual(resp, ret) - - def test_request_handler_with_retrieve_properties_ex_fault(self): - managed_object = 'Datacenter' - - def side_effect(mo, **kwargs): - self.assertEqual(managed_object, mo._type) - self.assertEqual(managed_object, mo.value) - return None - - svc_obj = service.Service() - attr_name = 'retrievePropertiesEx' - service_mock = svc_obj.client.service - setattr(service_mock, attr_name, side_effect) - self.assertRaises(exceptions.VimFaultException, - svc_obj.retrievePropertiesEx, - managed_object) - - def test_request_handler_with_web_fault(self): - managed_object = 'VirtualMachine' - fault_list = ['Fault'] - - doc = mock.Mock() - - def side_effect(mo, **kwargs): - self.assertEqual(managed_object, mo._type) - self.assertEqual(managed_object, mo.value) - fault = mock.Mock(faultstring="MyFault") - - fault_children = mock.Mock() - fault_children.name = "name" - fault_children.getText.return_value = "value" - child = mock.Mock() - child.get.return_value = fault_list[0] - child.getChildren.return_value = [fault_children] - detail = mock.Mock() - detail.getChildren.return_value = [child] - doc.childAtPath.return_value = detail - raise suds.WebFault(fault, doc) - - svc_obj = service.Service() - service_mock = svc_obj.client.service - setattr(service_mock, 'powerOn', side_effect) - - ex = self.assertRaises(exceptions.VimFaultException, svc_obj.powerOn, - managed_object) - - self.assertEqual(fault_list, ex.fault_list) - self.assertEqual({'name': 'value'}, ex.details) - self.assertEqual("MyFault", ex.msg) - doc.childAtPath.assert_called_once_with('/detail') - - def test_request_handler_with_empty_web_fault_doc(self): - - def side_effect(mo, **kwargs): - fault = mock.Mock(faultstring="MyFault") - raise suds.WebFault(fault, None) - - svc_obj = service.Service() - service_mock = svc_obj.client.service - setattr(service_mock, 'powerOn', side_effect) - - ex = self.assertRaises(exceptions.VimFaultException, - svc_obj.powerOn, - 'VirtualMachine') - self.assertEqual([], ex.fault_list) - self.assertEqual({}, ex.details) - self.assertEqual("MyFault", ex.msg) - - def test_request_handler_with_vc51_web_fault(self): - managed_object = 'VirtualMachine' - fault_list = ['Fault'] - - doc = mock.Mock() - - def side_effect(mo, **kwargs): - self.assertEqual(managed_object, mo._type) - self.assertEqual(managed_object, mo.value) - fault = mock.Mock(faultstring="MyFault") - - fault_children = mock.Mock() - fault_children.name = "name" - fault_children.getText.return_value = "value" - child = mock.Mock() - child.get.return_value = fault_list[0] - child.getChildren.return_value = [fault_children] - detail = mock.Mock() - detail.getChildren.return_value = [child] - doc.childAtPath.side_effect = [None, detail] - raise suds.WebFault(fault, doc) - - svc_obj = service.Service() - service_mock = svc_obj.client.service - setattr(service_mock, 'powerOn', side_effect) - - ex = self.assertRaises(exceptions.VimFaultException, svc_obj.powerOn, - managed_object) - - self.assertEqual(fault_list, ex.fault_list) - self.assertEqual({'name': 'value'}, ex.details) - self.assertEqual("MyFault", ex.msg) - exp_calls = [mock.call('/detail'), - mock.call('/Envelope/Body/Fault/detail')] - self.assertEqual(exp_calls, doc.childAtPath.call_args_list) - - def test_request_handler_with_security_error(self): - managed_object = 'VirtualMachine' - doc = mock.Mock() - - def side_effect(mo, **kwargs): - self.assertEqual(managed_object, mo._type) - self.assertEqual(managed_object, mo.value) - fault = mock.Mock(faultstring="MyFault") - - fault_children = mock.Mock() - fault_children.name = "name" - fault_children.getText.return_value = "value" - child = mock.Mock() - child.get.return_value = 'vim25:SecurityError' - child.getChildren.return_value = [fault_children] - detail = mock.Mock() - detail.getChildren.return_value = [child] - doc.childAtPath.return_value = detail - raise suds.WebFault(fault, doc) - - svc_obj = service.Service() - service_mock = svc_obj.client.service - setattr(service_mock, 'powerOn', side_effect) - - ex = self.assertRaises(exceptions.VimFaultException, svc_obj.powerOn, - managed_object) - - self.assertEqual([exceptions.NOT_AUTHENTICATED], ex.fault_list) - self.assertEqual({'name': 'value'}, ex.details) - self.assertEqual("MyFault", ex.msg) - doc.childAtPath.assert_called_once_with('/detail') - - def test_request_handler_with_attribute_error(self): - managed_object = 'VirtualMachine' - svc_obj = service.Service() - # no powerOn method in Service - service_mock = mock.Mock(spec=service.Service) - svc_obj.client.service = service_mock - self.assertRaises(exceptions.VimAttributeException, - svc_obj.powerOn, - managed_object) - - def test_request_handler_with_http_cannot_send_error(self): - managed_object = 'VirtualMachine' - - def side_effect(mo, **kwargs): - self.assertEqual(managed_object, mo._type) - self.assertEqual(managed_object, mo.value) - raise httplib.CannotSendRequest() - - svc_obj = service.Service() - attr_name = 'powerOn' - service_mock = svc_obj.client.service - setattr(service_mock, attr_name, side_effect) - self.assertRaises(exceptions.VimSessionOverLoadException, - svc_obj.powerOn, - managed_object) - - def test_request_handler_with_http_response_not_ready_error(self): - managed_object = 'VirtualMachine' - - def side_effect(mo, **kwargs): - self.assertEqual(managed_object, mo._type) - self.assertEqual(managed_object, mo.value) - raise httplib.ResponseNotReady() - - svc_obj = service.Service() - attr_name = 'powerOn' - service_mock = svc_obj.client.service - setattr(service_mock, attr_name, side_effect) - self.assertRaises(exceptions.VimSessionOverLoadException, - svc_obj.powerOn, - managed_object) - - def test_request_handler_with_http_cannot_send_header_error(self): - managed_object = 'VirtualMachine' - - def side_effect(mo, **kwargs): - self.assertEqual(managed_object, mo._type) - self.assertEqual(managed_object, mo.value) - raise httplib.CannotSendHeader() - - svc_obj = service.Service() - attr_name = 'powerOn' - service_mock = svc_obj.client.service - setattr(service_mock, attr_name, side_effect) - self.assertRaises(exceptions.VimSessionOverLoadException, - svc_obj.powerOn, - managed_object) - - def test_request_handler_with_connection_error(self): - managed_object = 'VirtualMachine' - - def side_effect(mo, **kwargs): - self.assertEqual(managed_object, mo._type) - self.assertEqual(managed_object, mo.value) - raise requests.ConnectionError() - - svc_obj = service.Service() - attr_name = 'powerOn' - service_mock = svc_obj.client.service - setattr(service_mock, attr_name, side_effect) - self.assertRaises(exceptions.VimConnectionException, - svc_obj.powerOn, - managed_object) - - def test_request_handler_with_http_error(self): - managed_object = 'VirtualMachine' - - def side_effect(mo, **kwargs): - self.assertEqual(managed_object, mo._type) - self.assertEqual(managed_object, mo.value) - raise requests.HTTPError() - - svc_obj = service.Service() - attr_name = 'powerOn' - service_mock = svc_obj.client.service - setattr(service_mock, attr_name, side_effect) - self.assertRaises(exceptions.VimConnectionException, - svc_obj.powerOn, - managed_object) - - @mock.patch.object(vim_util, 'get_moref', return_value=None) - def test_request_handler_no_value(self, mock_moref): - managed_object = 'VirtualMachine' - svc_obj = service.Service() - ret = svc_obj.UnregisterVM(managed_object) - self.assertIsNone(ret) - - def _test_request_handler_with_exception(self, message, exception): - managed_object = 'VirtualMachine' - - def side_effect(mo, **kwargs): - self.assertEqual(managed_object, mo._type) - self.assertEqual(managed_object, mo.value) - raise Exception(message) - - svc_obj = service.Service() - attr_name = 'powerOn' - service_mock = svc_obj.client.service - setattr(service_mock, attr_name, side_effect) - self.assertRaises(exception, svc_obj.powerOn, managed_object) - - def test_request_handler_with_address_in_use_error(self): - self._test_request_handler_with_exception( - service.ADDRESS_IN_USE_ERROR, - exceptions.VimSessionOverLoadException) - - def test_request_handler_with_conn_abort_error(self): - self._test_request_handler_with_exception( - service.CONN_ABORT_ERROR, exceptions.VimSessionOverLoadException) - - def test_request_handler_with_resp_not_xml_error(self): - self._test_request_handler_with_exception( - service.RESP_NOT_XML_ERROR, exceptions.VimSessionOverLoadException) - - def test_request_handler_with_generic_error(self): - self._test_request_handler_with_exception( - 'GENERIC_ERROR', exceptions.VimException) - - def test_get_session_cookie(self): - svc_obj = service.Service() - cookie_value = 'xyz' - cookie = mock.Mock() - cookie.name = 'vmware_soap_session' - cookie.value = cookie_value - svc_obj.client.options.transport.cookiejar = [cookie] - self.assertEqual(cookie_value, svc_obj.get_http_cookie()) - - def test_get_session_cookie_with_no_cookie(self): - svc_obj = service.Service() - cookie = mock.Mock() - cookie.name = 'cookie' - cookie.value = 'xyz' - svc_obj.client.options.transport.cookiejar = [cookie] - self.assertIsNone(svc_obj.get_http_cookie()) - - def test_set_soap_headers(self): - def fake_set_options(*args, **kwargs): - headers = kwargs['soapheaders'] - self.assertEqual(1, len(headers)) - txt = headers[0].getText() - self.assertEqual('fira-12345', txt) - - svc_obj = service.Service() - svc_obj.client.options.soapheaders = None - setattr(svc_obj.client, 'set_options', fake_set_options) - svc_obj._set_soap_headers('fira-12345') - - def test_soap_headers_pbm(self): - def fake_set_options(*args, **kwargs): - headers = kwargs['soapheaders'] - self.assertEqual(2, len(headers)) - self.assertEqual('vc-session-cookie', headers[0].getText()) - self.assertEqual('fira-12345', headers[1].getText()) - - svc_obj = service.Service() - svc_obj._vc_session_cookie = 'vc-session-cookie' - setattr(svc_obj.client, 'set_options', fake_set_options) - svc_obj._set_soap_headers('fira-12345') - - -class MemoryCacheTest(base.TestCase): - """Test class for MemoryCache.""" - - def test_get_set(self): - cache = service.MemoryCache() - cache.put('key1', 'value1') - cache.put('key2', 'value2') - self.assertEqual('value1', cache.get('key1')) - self.assertEqual('value2', cache.get('key2')) - self.assertIsNone(cache.get('key3')) - - @mock.patch('suds.reader.DefinitionsReader.open') - @mock.patch('suds.reader.DocumentReader.download', create=True) - def test_shared_cache(self, mock_reader, mock_open): - cache1 = service.Service().client.options.cache - cache2 = service.Service().client.options.cache - self.assertIs(cache1, cache2) - - @mock.patch('oslo_utils.timeutils.utcnow_ts') - def test_cache_timeout(self, mock_utcnow_ts): - mock_utcnow_ts.side_effect = [100, 125, 150, 175, 195, 200, 225] - - cache = service.MemoryCache() - cache.put('key1', 'value1', 10) - cache.put('key2', 'value2', 75) - cache.put('key3', 'value3', 100) - - self.assertIsNone(cache.get('key1')) - self.assertEqual('value2', cache.get('key2')) - self.assertIsNone(cache.get('key2')) - self.assertEqual('value3', cache.get('key3')) - - -class RequestsTransportTest(base.TestCase): - """Tests for RequestsTransport.""" - - def test_open(self): - transport = service.RequestsTransport() - - data = b"Hello World" - resp = mock.Mock(content=data) - transport.session.get = mock.Mock(return_value=resp) - - request = mock.Mock(url=mock.sentinel.url) - self.assertEqual(data, - transport.open(request).getvalue()) - transport.session.get.assert_called_once_with(mock.sentinel.url, - verify=transport.verify) - - def test_send(self): - transport = service.RequestsTransport() - - resp = mock.Mock(status_code=mock.sentinel.status_code, - headers=mock.sentinel.headers, - content=mock.sentinel.content) - transport.session.post = mock.Mock(return_value=resp) - - request = mock.Mock(url=mock.sentinel.url, - message=mock.sentinel.message, - headers=mock.sentinel.req_headers) - reply = transport.send(request) - - self.assertEqual(mock.sentinel.status_code, reply.code) - self.assertEqual(mock.sentinel.headers, reply.headers) - self.assertEqual(mock.sentinel.content, reply.message) - - def test_set_conn_pool_size(self): - transport = service.RequestsTransport(pool_maxsize=100) - local_file_adapter = transport.session.adapters['file:///'] - self.assertEqual(100, local_file_adapter._pool_connections) - self.assertEqual(100, local_file_adapter._pool_maxsize) - https_adapter = transport.session.adapters['https://'] - self.assertEqual(100, https_adapter._pool_connections) - self.assertEqual(100, https_adapter._pool_maxsize) - - @mock.patch('os.path.getsize') - def test_send_with_local_file_url(self, get_size_mock): - transport = service.RequestsTransport() - - url = 'file:///foo' - request = requests.PreparedRequest() - request.url = url - - data = b"Hello World" - get_size_mock.return_value = len(data) - - def readinto_mock(buf): - buf[0:] = data - - if six.PY3: - builtin_open = 'builtins.open' - open_mock = mock.MagicMock(name='file_handle', - spec=open) - import _io - file_spec = list(set(dir(_io.TextIOWrapper)).union( - set(dir(_io.BytesIO)))) - else: - builtin_open = '__builtin__.open' - open_mock = mock.MagicMock(name='file_handle', - spec=file) - file_spec = file - - file_handle = mock.MagicMock(spec=file_spec) - file_handle.write.return_value = None - file_handle.__enter__.return_value = file_handle - file_handle.readinto.side_effect = readinto_mock - open_mock.return_value = file_handle - - with mock.patch(builtin_open, open_mock, create=True): - resp = transport.session.send(request) - self.assertEqual(data, resp.content) - - def test_send_with_connection_timeout(self): - transport = service.RequestsTransport(connection_timeout=120) - - request = mock.Mock(url=mock.sentinel.url, - message=mock.sentinel.message, - headers=mock.sentinel.req_headers) - with mock.patch.object(transport.session, "post") as mock_post: - transport.send(request) - mock_post.assert_called_once_with( - mock.sentinel.url, - data=mock.sentinel.message, - headers=mock.sentinel.req_headers, - timeout=120, - verify=transport.verify) - - -class SudsLogFilterTest(base.TestCase): - """Tests for SudsLogFilter.""" - - def setUp(self): - super(SudsLogFilterTest, self).setUp() - self.log_filter = service.SudsLogFilter() - - self.login = mock.Mock(spec=suds.sax.element.Element) - self.username = suds.sax.element.Element('username').setText('admin') - self.password = suds.sax.element.Element('password').setText( - 'password') - self.session_id = suds.sax.element.Element('session_id').setText( - 'abcdef') - - def login_child_at_path_mock(path): - if path == 'userName': - return self.username - if path == 'password': - return self.password - if path == 'sessionID': - return self.session_id - - self.login.childAtPath.side_effect = login_child_at_path_mock - - def test_filter_with_no_child_at_path(self): - message = mock.Mock(spec=object) - record = mock.Mock(msg=message) - self.assertTrue(self.log_filter.filter(record)) - - def test_filter_with_login_failure(self): - message = mock.Mock(spec=suds.sax.element.Element) - - def child_at_path_mock(path): - if path == '/Envelope/Body/Login': - return self.login - - message.childAtPath.side_effect = child_at_path_mock - record = mock.Mock(msg=message) - - self.assertTrue(self.log_filter.filter(record)) - self.assertEqual('***', self.username.getText()) - self.assertEqual('***', self.password.getText()) - self.assertEqual('bcdef', self.session_id.getText()) - - def test_filter_with_session_is_active_failure(self): - message = mock.Mock(spec=suds.sax.element.Element) - - def child_at_path_mock(path): - if path == '/Envelope/Body/SessionIsActive': - return self.login - - message.childAtPath.side_effect = child_at_path_mock - record = mock.Mock(msg=message) - - self.assertTrue(self.log_filter.filter(record)) - self.assertEqual('***', self.username.getText()) - self.assertEqual('***', self.password.getText()) - self.assertEqual('bcdef', self.session_id.getText()) - - def test_filter_with_unknown_failure(self): - message = mock.Mock(spec=suds.sax.element.Element) - - def child_at_path_mock(path): - return None - - message.childAtPath.side_effect = child_at_path_mock - record = mock.Mock(msg=message) - - self.assertTrue(self.log_filter.filter(record)) - self.assertEqual('admin', self.username.getText()) - self.assertEqual('password', self.password.getText()) - self.assertEqual('abcdef', self.session_id.getText()) diff --git a/oslo_vmware/tests/test_vim.py b/oslo_vmware/tests/test_vim.py deleted file mode 100644 index ddfa82e..0000000 --- a/oslo_vmware/tests/test_vim.py +++ /dev/null @@ -1,109 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Unit tests for classes to invoke VMware VI SOAP calls. -""" - -import copy - -import mock -from oslo_i18n import fixture as i18n_fixture -import suds - -from oslo_vmware import exceptions -from oslo_vmware.tests import base -from oslo_vmware import vim - - -class VimTest(base.TestCase): - """Test class for Vim.""" - - def setUp(self): - super(VimTest, self).setUp() - patcher = mock.patch('suds.client.Client') - self.addCleanup(patcher.stop) - self.SudsClientMock = patcher.start() - self.useFixture(i18n_fixture.ToggleLazy(True)) - - @mock.patch.object(vim.Vim, '__getattr__', autospec=True) - def test_service_content(self, getattr_mock): - getattr_ret = mock.Mock() - getattr_mock.side_effect = lambda *args: getattr_ret - vim_obj = vim.Vim() - vim_obj.service_content - getattr_mock.assert_called_once_with(vim_obj, 'RetrieveServiceContent') - getattr_ret.assert_called_once_with('ServiceInstance') - self.assertEqual(self.SudsClientMock.return_value, vim_obj.client) - self.assertEqual(getattr_ret.return_value, vim_obj.service_content) - - def test_configure_non_default_host_port(self): - vim_obj = vim.Vim('https', 'www.test.com', 12345) - self.assertEqual('https://www.test.com:12345/sdk/vimService.wsdl', - vim_obj.wsdl_url) - self.assertEqual('https://www.test.com:12345/sdk', - vim_obj.soap_url) - - def test_configure_ipv6(self): - vim_obj = vim.Vim('https', '::1') - self.assertEqual('https://[::1]/sdk/vimService.wsdl', - vim_obj.wsdl_url) - self.assertEqual('https://[::1]/sdk', - vim_obj.soap_url) - - def test_configure_ipv6_and_non_default_host_port(self): - vim_obj = vim.Vim('https', '::1', 12345) - self.assertEqual('https://[::1]:12345/sdk/vimService.wsdl', - vim_obj.wsdl_url) - self.assertEqual('https://[::1]:12345/sdk', - vim_obj.soap_url) - - def test_configure_with_wsdl_url_override(self): - vim_obj = vim.Vim('https', 'www.example.com', - wsdl_url='https://test.com/sdk/vimService.wsdl') - self.assertEqual('https://test.com/sdk/vimService.wsdl', - vim_obj.wsdl_url) - self.assertEqual('https://www.example.com/sdk', vim_obj.soap_url) - - -class VMwareSudsTest(base.TestCase): - def setUp(self): - super(VMwareSudsTest, self).setUp() - - def new_client_init(self, url, **kwargs): - return - - mock.patch.object(suds.client.Client, - '__init__', new=new_client_init).start() - self.addCleanup(mock.patch.stopall) - self.vim = self._vim_create() - - def _mock_getattr(self, attr_name): - class fake_service_content(object): - def __init__(self): - self.ServiceContent = {} - self.ServiceContent.fake = 'fake' - - self.assertEqual("RetrieveServiceContent", attr_name) - return lambda obj, **kwargs: fake_service_content() - - def _vim_create(self): - with mock.patch.object(vim.Vim, '__getattr__', self._mock_getattr): - return vim.Vim() - - def test_exception_with_deepcopy(self): - self.assertIsNotNone(self.vim) - self.assertRaises(exceptions.VimAttributeException, - copy.deepcopy, self.vim) diff --git a/oslo_vmware/tests/test_vim_util.py b/oslo_vmware/tests/test_vim_util.py deleted file mode 100644 index c5c20fe..0000000 --- a/oslo_vmware/tests/test_vim_util.py +++ /dev/null @@ -1,534 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Unit tests for VMware API utility module. -""" - -import collections - -import mock - -from oslo_vmware.tests import base -from oslo_vmware import vim_util - - -class VimUtilTest(base.TestCase): - """Test class for utility methods in vim_util.""" - - def test_get_moref(self): - moref = vim_util.get_moref("vm-0", "VirtualMachine") - self.assertEqual("vm-0", moref.value) - self.assertEqual("VirtualMachine", moref._type) - - def test_build_selection_spec(self): - client_factory = mock.Mock() - sel_spec = vim_util.build_selection_spec(client_factory, "test") - self.assertEqual("test", sel_spec.name) - - def test_build_traversal_spec(self): - client_factory = mock.Mock() - sel_spec = mock.Mock() - traversal_spec = vim_util.build_traversal_spec(client_factory, - 'dc_to_hf', - 'Datacenter', - 'hostFolder', False, - [sel_spec]) - self.assertEqual("dc_to_hf", traversal_spec.name) - self.assertEqual("hostFolder", traversal_spec.path) - self.assertEqual([sel_spec], traversal_spec.selectSet) - self.assertFalse(traversal_spec.skip) - self.assertEqual("Datacenter", traversal_spec.type) - - @mock.patch.object(vim_util, 'build_selection_spec') - def test_build_recursive_traversal_spec(self, build_selection_spec_mock): - sel_spec = mock.Mock() - rp_to_rp_sel_spec = mock.Mock() - rp_to_vm_sel_spec = mock.Mock() - - def build_sel_spec_side_effect(client_factory, name): - if name == 'visitFolders': - return sel_spec - elif name == 'rp_to_rp': - return rp_to_rp_sel_spec - elif name == 'rp_to_vm': - return rp_to_vm_sel_spec - else: - return None - - build_selection_spec_mock.side_effect = build_sel_spec_side_effect - traversal_spec_dict = {'dc_to_hf': {'type': 'Datacenter', - 'path': 'hostFolder', - 'skip': False, - 'selectSet': [sel_spec]}, - 'dc_to_vmf': {'type': 'Datacenter', - 'path': 'vmFolder', - 'skip': False, - 'selectSet': [sel_spec]}, - 'dc_to_netf': {'type': 'Datacenter', - 'path': 'networkFolder', - 'skip': False, - 'selectSet': [sel_spec]}, - 'h_to_vm': {'type': 'HostSystem', - 'path': 'vm', - 'skip': False, - 'selectSet': [sel_spec]}, - 'cr_to_h': {'type': 'ComputeResource', - 'path': 'host', - 'skip': False, - 'selectSet': []}, - 'cr_to_ds': {'type': 'ComputeResource', - 'path': 'datastore', - 'skip': False, - 'selectSet': []}, - 'cr_to_rp': {'type': 'ComputeResource', - 'path': 'resourcePool', - 'skip': False, - 'selectSet': [rp_to_rp_sel_spec, - rp_to_vm_sel_spec]}, - 'cr_to_rp': {'type': 'ComputeResource', - 'path': 'resourcePool', - 'skip': False, - 'selectSet': [rp_to_rp_sel_spec, - rp_to_vm_sel_spec]}, - 'ccr_to_h': {'type': 'ClusterComputeResource', - 'path': 'host', - 'skip': False, - 'selectSet': []}, - 'ccr_to_ds': {'type': 'ClusterComputeResource', - 'path': 'datastore', - 'skip': False, - 'selectSet': []}, - 'ccr_to_rp': {'type': 'ClusterComputeResource', - 'path': 'resourcePool', - 'skip': False, - 'selectSet': [rp_to_rp_sel_spec, - rp_to_vm_sel_spec]}, - 'rp_to_rp': {'type': 'ResourcePool', - 'path': 'resourcePool', - 'skip': False, - 'selectSet': [rp_to_rp_sel_spec, - rp_to_vm_sel_spec]}, - 'rp_to_vm': {'type': 'ResourcePool', - 'path': 'vm', - 'skip': False, - 'selectSet': [rp_to_rp_sel_spec, - rp_to_vm_sel_spec]}, - } - - client_factory = mock.Mock() - client_factory.create.side_effect = lambda ns: mock.Mock() - trav_spec = vim_util.build_recursive_traversal_spec(client_factory) - self.assertEqual("visitFolders", trav_spec.name) - self.assertEqual("childEntity", trav_spec.path) - self.assertFalse(trav_spec.skip) - self.assertEqual("Folder", trav_spec.type) - - self.assertEqual(len(traversal_spec_dict) + 1, - len(trav_spec.selectSet)) - for spec in trav_spec.selectSet: - if spec.name not in traversal_spec_dict: - self.assertEqual(sel_spec, spec) - else: - exp_spec = traversal_spec_dict[spec.name] - self.assertEqual(exp_spec['type'], spec.type) - self.assertEqual(exp_spec['path'], spec.path) - self.assertEqual(exp_spec['skip'], spec.skip) - self.assertEqual(exp_spec['selectSet'], spec.selectSet) - - def test_build_property_spec(self): - client_factory = mock.Mock() - prop_spec = vim_util.build_property_spec(client_factory) - self.assertFalse(prop_spec.all) - self.assertEqual(["name"], prop_spec.pathSet) - self.assertEqual("VirtualMachine", prop_spec.type) - - def test_build_object_spec(self): - client_factory = mock.Mock() - root_folder = mock.Mock() - specs = [mock.Mock()] - obj_spec = vim_util.build_object_spec(client_factory, - root_folder, specs) - self.assertEqual(root_folder, obj_spec.obj) - self.assertEqual(specs, obj_spec.selectSet) - self.assertFalse(obj_spec.skip) - - def test_build_property_filter_spec(self): - client_factory = mock.Mock() - prop_specs = [mock.Mock()] - obj_specs = [mock.Mock()] - filter_spec = vim_util.build_property_filter_spec(client_factory, - prop_specs, - obj_specs) - self.assertEqual(obj_specs, filter_spec.objectSet) - self.assertEqual(prop_specs, filter_spec.propSet) - - @mock.patch( - 'oslo_vmware.vim_util.build_recursive_traversal_spec') - def test_get_objects(self, build_recursive_traversal_spec): - vim = mock.Mock() - trav_spec = mock.Mock() - build_recursive_traversal_spec.return_value = trav_spec - max_objects = 10 - _type = "VirtualMachine" - - def vim_RetrievePropertiesEx_side_effect(pc, specSet, options): - self.assertTrue(pc is vim.service_content.propertyCollector) - self.assertEqual(max_objects, options.maxObjects) - - self.assertEqual(1, len(specSet)) - property_filter_spec = specSet[0] - - propSet = property_filter_spec.propSet - self.assertEqual(1, len(propSet)) - prop_spec = propSet[0] - self.assertFalse(prop_spec.all) - self.assertEqual(["name"], prop_spec.pathSet) - self.assertEqual(_type, prop_spec.type) - - objSet = property_filter_spec.objectSet - self.assertEqual(1, len(objSet)) - obj_spec = objSet[0] - self.assertTrue(obj_spec.obj is vim.service_content.rootFolder) - self.assertEqual([trav_spec], obj_spec.selectSet) - self.assertFalse(obj_spec.skip) - - vim.RetrievePropertiesEx.side_effect = ( - vim_RetrievePropertiesEx_side_effect) - vim_util.get_objects(vim, _type, max_objects) - self.assertEqual(1, vim.RetrievePropertiesEx.call_count) - - def test_get_object_properties_with_empty_moref(self): - vim = mock.Mock() - ret = vim_util.get_object_properties(vim, None, None) - self.assertIsNone(ret) - - @mock.patch('oslo_vmware.vim_util.cancel_retrieval') - def test_get_object_properties(self, cancel_retrieval): - vim = mock.Mock() - moref = mock.Mock() - moref._type = "VirtualMachine" - retrieve_result = mock.Mock() - - def vim_RetrievePropertiesEx_side_effect(pc, specSet, options, - skip_op_id=False): - self.assertTrue(pc is vim.service_content.propertyCollector) - self.assertEqual(1, options.maxObjects) - - self.assertEqual(1, len(specSet)) - property_filter_spec = specSet[0] - - propSet = property_filter_spec.propSet - self.assertEqual(1, len(propSet)) - prop_spec = propSet[0] - self.assertTrue(prop_spec.all) - self.assertEqual(['name'], prop_spec.pathSet) - self.assertEqual(moref._type, prop_spec.type) - - objSet = property_filter_spec.objectSet - self.assertEqual(1, len(objSet)) - obj_spec = objSet[0] - self.assertEqual(moref, obj_spec.obj) - self.assertEqual([], obj_spec.selectSet) - self.assertFalse(obj_spec.skip) - - return retrieve_result - - vim.RetrievePropertiesEx.side_effect = ( - vim_RetrievePropertiesEx_side_effect) - - res = vim_util.get_object_properties(vim, moref, None) - self.assertEqual(1, vim.RetrievePropertiesEx.call_count) - self.assertTrue(res is retrieve_result.objects) - cancel_retrieval.assert_called_once_with(vim, retrieve_result) - - def test_get_token(self): - retrieve_result = object() - self.assertFalse(vim_util._get_token(retrieve_result)) - - @mock.patch('oslo_vmware.vim_util.get_object_properties') - def test_get_object_properties_dict_empty(self, mock_obj_prop): - mock_obj_prop.return_value = None - vim = mock.Mock() - moref = mock.Mock() - res = vim_util.get_object_properties_dict(vim, moref, None) - self.assertEqual({}, res) - - @mock.patch('oslo_vmware.vim_util.get_object_properties') - def test_get_object_properties_dict(self, mock_obj_prop): - expected_prop_dict = {'name': 'vm01'} - mock_obj_content = mock.Mock() - prop = mock.Mock() - prop.name = "name" - prop.val = "vm01" - mock_obj_content.propSet = [prop] - del mock_obj_content.missingSet - mock_obj_prop.return_value = [mock_obj_content] - vim = mock.Mock() - moref = mock.Mock() - res = vim_util.get_object_properties_dict(vim, moref, None) - self.assertEqual(expected_prop_dict, res) - - @mock.patch('oslo_vmware.vim_util.get_object_properties') - def test_get_object_properties_dict_missing(self, mock_obj_prop): - mock_obj_content = mock.Mock() - missing_prop = mock.Mock() - missing_prop.path = "name" - missing_prop.fault = mock.Mock() - mock_obj_content.missingSet = [missing_prop] - del mock_obj_content.propSet - mock_obj_prop.return_value = [mock_obj_content] - vim = mock.Mock() - moref = mock.Mock() - res = vim_util.get_object_properties_dict(vim, moref, None) - self.assertEqual({}, res) - - @mock.patch('oslo_vmware.vim_util._get_token') - def test_cancel_retrieval(self, get_token): - token = mock.Mock() - get_token.return_value = token - vim = mock.Mock() - retrieve_result = mock.Mock() - vim_util.cancel_retrieval(vim, retrieve_result) - get_token.assert_called_once_with(retrieve_result) - vim.CancelRetrievePropertiesEx.assert_called_once_with( - vim.service_content.propertyCollector, token=token) - - @mock.patch('oslo_vmware.vim_util._get_token') - def test_continue_retrieval(self, get_token): - token = mock.Mock() - get_token.return_value = token - vim = mock.Mock() - retrieve_result = mock.Mock() - vim_util.continue_retrieval(vim, retrieve_result) - get_token.assert_called_once_with(retrieve_result) - vim.ContinueRetrievePropertiesEx.assert_called_once_with( - vim.service_content.propertyCollector, token=token) - - @mock.patch('oslo_vmware.vim_util.continue_retrieval') - @mock.patch('oslo_vmware.vim_util.cancel_retrieval') - def test_with_retrieval(self, cancel_retrieval, continue_retrieval): - vim = mock.Mock() - retrieve_result0 = mock.Mock() - retrieve_result0.objects = [mock.Mock(), mock.Mock()] - retrieve_result1 = mock.Mock() - retrieve_result1.objects = [mock.Mock(), mock.Mock()] - continue_retrieval.side_effect = [retrieve_result1, None] - expected = retrieve_result0.objects + retrieve_result1.objects - - with vim_util.WithRetrieval(vim, retrieve_result0) as iterator: - self.assertEqual(expected, list(iterator)) - - calls = [ - mock.call(vim, retrieve_result0), - mock.call(vim, retrieve_result1)] - continue_retrieval.assert_has_calls(calls) - self.assertFalse(cancel_retrieval.called) - - @mock.patch('oslo_vmware.vim_util.continue_retrieval') - @mock.patch('oslo_vmware.vim_util.cancel_retrieval') - def test_with_retrieval_early_exit(self, cancel_retrieval, - continue_retrieval): - vim = mock.Mock() - retrieve_result = mock.Mock() - with vim_util.WithRetrieval(vim, retrieve_result): - pass - - cancel_retrieval.assert_called_once_with(vim, retrieve_result) - - @mock.patch('oslo_vmware.vim_util.get_object_properties') - def test_get_object_property(self, get_object_properties): - prop = mock.Mock() - prop.val = "ubuntu-12.04" - properties = mock.Mock() - properties.propSet = [prop] - properties_list = [properties] - get_object_properties.return_value = properties_list - vim = mock.Mock() - moref = mock.Mock() - property_name = 'name' - val = vim_util.get_object_property(vim, moref, property_name) - self.assertEqual(prop.val, val) - get_object_properties.assert_called_once_with( - vim, moref, [property_name], skip_op_id=False) - - def test_find_extension(self): - vim = mock.Mock() - ret = vim_util.find_extension(vim, 'fake-key') - self.assertIsNotNone(ret) - service_content = vim.service_content - vim.FindExtension.assert_called_once_with( - service_content.extensionManager, extensionKey='fake-key') - - def test_register_extension(self): - vim = mock.Mock() - ret = vim_util.register_extension(vim, 'fake-key', 'fake-type') - self.assertIsNone(ret) - service_content = vim.service_content - vim.RegisterExtension.assert_called_once_with( - service_content.extensionManager, extension=mock.ANY) - - def test_get_vc_version(self): - session = mock.Mock() - expected_version = '6.0.1' - session.vim.service_content.about.version = expected_version - version = vim_util.get_vc_version(session) - self.assertEqual(expected_version, version) - expected_version = '5.5' - session.vim.service_content.about.version = expected_version - version = vim_util.get_vc_version(session) - self.assertEqual(expected_version, version) - - def test_get_inventory_path_folders(self): - ObjectContent = collections.namedtuple('ObjectContent', ['propSet']) - DynamicProperty = collections.namedtuple('Property', ['name', 'val']) - - obj1 = ObjectContent(propSet=[ - DynamicProperty(name='Datacenter', val='dc-1'), - ]) - obj2 = ObjectContent(propSet=[ - DynamicProperty(name='Datacenter', val='folder-2'), - ]) - obj3 = ObjectContent(propSet=[ - DynamicProperty(name='Datacenter', val='folder-1'), - ]) - objects = ['foo', 'bar', obj1, obj2, obj3] - result = mock.sentinel.objects - result.objects = objects - session = mock.Mock() - session.vim.RetrievePropertiesEx = mock.Mock() - session.vim.RetrievePropertiesEx.return_value = result - entity = mock.Mock() - inv_path = vim_util.get_inventory_path(session.vim, entity, 100) - self.assertEqual('/folder-2/dc-1', inv_path) - - def test_get_inventory_path_no_folder(self): - ObjectContent = collections.namedtuple('ObjectContent', ['propSet']) - DynamicProperty = collections.namedtuple('Property', ['name', 'val']) - - obj1 = ObjectContent(propSet=[ - DynamicProperty(name='Datacenter', val='dc-1'), - ]) - objects = ['foo', 'bar', obj1] - result = mock.sentinel.objects - result.objects = objects - session = mock.Mock() - session.vim.RetrievePropertiesEx = mock.Mock() - session.vim.RetrievePropertiesEx.return_value = result - entity = mock.Mock() - inv_path = vim_util.get_inventory_path(session.vim, entity, 100) - self.assertEqual('dc-1', inv_path) - - def test_get_prop_spec(self): - client_factory = mock.Mock() - prop_spec = vim_util.get_prop_spec( - client_factory, "VirtualMachine", ["test_path"]) - self.assertEqual(["test_path"], prop_spec.pathSet) - self.assertEqual("VirtualMachine", prop_spec.type) - - def test_get_obj_spec(self): - client_factory = mock.Mock() - mock_obj = mock.Mock() - obj_spec = vim_util.get_obj_spec( - client_factory, mock_obj, select_set=["abc"]) - self.assertEqual(mock_obj, obj_spec.obj) - self.assertFalse(obj_spec.skip) - self.assertEqual(["abc"], obj_spec.selectSet) - - def test_get_prop_filter_spec(self): - client_factory = mock.Mock() - mock_obj = mock.Mock() - filter_spec = vim_util.get_prop_filter_spec( - client_factory, [mock_obj], ["test_prop"]) - self.assertEqual([mock_obj], filter_spec.objectSet) - self.assertEqual(["test_prop"], filter_spec.propSet) - - @mock.patch('oslo_vmware.vim_util.get_prop_spec') - @mock.patch('oslo_vmware.vim_util.get_obj_spec') - @mock.patch('oslo_vmware.vim_util.get_prop_filter_spec') - def _test_get_properties_for_a_collection_of_objects( - self, objs, max_objects, - mock_get_prop_filter_spec, - mock_get_obj_spec, - mock_get_prop_spec): - vim = mock.Mock() - if len(objs) == 0: - self.assertEqual( - [], vim_util.get_properties_for_a_collection_of_objects( - vim, 'VirtualMachine', [], {})) - return - - mock_prop_spec = mock.Mock() - mock_get_prop_spec.return_value = mock_prop_spec - - mock_get_obj_spec.side_effect = [mock.Mock() - for obj in objs] - get_obj_spec_calls = [mock.call(vim.client.factory, obj) - for obj in objs] - - mock_prop_spec = mock.Mock() - mock_get_prop_spec.return_value = mock_prop_spec - - mock_prop_filter_spec = mock.Mock() - mock_get_prop_filter_spec.return_value = mock_prop_filter_spec - mock_options = mock.Mock() - vim.client.factory.create.return_value = mock_options - - mock_return_value = mock.Mock() - vim.RetrievePropertiesEx.return_value = mock_return_value - res = vim_util.get_properties_for_a_collection_of_objects( - vim, 'VirtualMachine', objs, ['runtime'], max_objects) - self.assertEqual(mock_return_value, res) - - mock_get_prop_spec.assert_called_once_with(vim.client.factory, - 'VirtualMachine', - ['runtime']) - self.assertEqual(get_obj_spec_calls, mock_get_obj_spec.mock_calls) - vim.client.factory.create.assert_called_once_with( - 'ns0:RetrieveOptions') - self.assertEqual(max_objects if max_objects else len(objs), - mock_options.maxObjects) - vim.RetrievePropertiesEx.assert_called_once_with( - vim.service_content.propertyCollector, - specSet=[mock_prop_filter_spec], - options=mock_options) - - def test_get_properties_for_a_collection_of_objects( - self): - objects = ["m1", "m2"] - self._test_get_properties_for_a_collection_of_objects(objects, None) - - def test_get_properties_for_a_collection_of_objects_max_objects_1( - self): - objects = ["m1", "m2"] - self._test_get_properties_for_a_collection_of_objects(objects, 1) - - def test_get_properties_for_a_collection_of_objects_no_objects( - self): - self._test_get_properties_for_a_collection_of_objects([], None) - - def test_propset_dict(self): - self.assertEqual({}, vim_util.propset_dict(None)) - - mock_propset = [] - for i in range(2): - mock_obj = mock.Mock() - mock_obj.name = "test_name_%d" % i - mock_obj.val = "test_val_%d" % i - mock_propset.append(mock_obj) - - self.assertEqual({"test_name_0": "test_val_0", - "test_name_1": "test_val_1"}, - vim_util.propset_dict(mock_propset)) diff --git a/oslo_vmware/version.py b/oslo_vmware/version.py deleted file mode 100644 index d6e096f..0000000 --- a/oslo_vmware/version.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2016 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -import pbr.version - -version_info = pbr.version.VersionInfo('oslo.vmware') diff --git a/oslo_vmware/vim.py b/oslo_vmware/vim.py deleted file mode 100644 index a97ffc2..0000000 --- a/oslo_vmware/vim.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_vmware import service - - -class Vim(service.Service): - """Service class that provides access to the VIM API.""" - - def __init__(self, protocol='https', host='localhost', port=None, - wsdl_url=None, cacert=None, insecure=True, pool_maxsize=10, - connection_timeout=None, op_id_prefix='oslo.vmware'): - """Constructs a VIM service client object. - - :param protocol: http or https - :param host: server IP address or host name - :param port: port for connection - :param wsdl_url: VIM WSDL url - :param cacert: Specify a CA bundle file to use in verifying a - TLS (https) server certificate. - :param insecure: Verify HTTPS connections using system certificates, - used only if cacert is not specified - :param pool_maxsize: Maximum number of connections in http - connection pool - :param connection_timeout: Maximum time in seconds to wait for peer to - respond. - :param op_id_prefix: String prefix for the operation ID. - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - base_url = service.Service.build_base_url(protocol, host, port) - soap_url = base_url + '/sdk' - if wsdl_url is None: - wsdl_url = soap_url + '/vimService.wsdl' - super(Vim, self).__init__(wsdl_url, soap_url, cacert, insecure, - pool_maxsize, connection_timeout, - op_id_prefix) - - def retrieve_service_content(self): - return self.RetrieveServiceContent(service.SERVICE_INSTANCE) - - def __repr__(self): - return "VIM Object" - - def __str__(self): - return "VIM Object" diff --git a/oslo_vmware/vim_util.py b/oslo_vmware/vim_util.py deleted file mode 100644 index f56f338..0000000 --- a/oslo_vmware/vim_util.py +++ /dev/null @@ -1,623 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -The VMware API utility module. -""" - -import logging - -from oslo_utils import timeutils -from suds import sudsobject - -LOG = logging.getLogger(__name__) - - -def get_moref(value, type_): - """Get managed object reference. - - :param value: value of the managed object - :param type_: type of the managed object - :returns: managed object reference with given value and type - """ - moref = sudsobject.Property(value) - moref._type = type_ - return moref - - -def build_selection_spec(client_factory, name): - """Builds the selection spec. - - :param client_factory: factory to get API input specs - :param name: name for the selection spec - :returns: selection spec - """ - sel_spec = client_factory.create('ns0:SelectionSpec') - sel_spec.name = name - return sel_spec - - -def build_traversal_spec(client_factory, name, type_, path, skip, select_set): - """Builds the traversal spec. - - :param client_factory: factory to get API input specs - :param name: name for the traversal spec - :param type_: type of the managed object - :param path: property path of the managed object - :param skip: whether or not to filter the object identified by param path - :param select_set: set of selection specs specifying additional objects - to filter - :returns: traversal spec - """ - traversal_spec = client_factory.create('ns0:TraversalSpec') - traversal_spec.name = name - traversal_spec.type = type_ - traversal_spec.path = path - traversal_spec.skip = skip - traversal_spec.selectSet = select_set - return traversal_spec - - -def build_recursive_traversal_spec(client_factory): - """Builds recursive traversal spec to traverse managed object hierarchy. - - :param client_factory: factory to get API input specs - :returns: recursive traversal spec - """ - visit_folders_select_spec = build_selection_spec(client_factory, - 'visitFolders') - # Next hop from Datacenter - dc_to_hf = build_traversal_spec(client_factory, - 'dc_to_hf', - 'Datacenter', - 'hostFolder', - False, - [visit_folders_select_spec]) - dc_to_vmf = build_traversal_spec(client_factory, - 'dc_to_vmf', - 'Datacenter', - 'vmFolder', - False, - [visit_folders_select_spec]) - dc_to_netf = build_traversal_spec(client_factory, - 'dc_to_netf', - 'Datacenter', - 'networkFolder', - False, - [visit_folders_select_spec]) - - # Next hop from HostSystem - h_to_vm = build_traversal_spec(client_factory, - 'h_to_vm', - 'HostSystem', - 'vm', - False, - [visit_folders_select_spec]) - - # Next hop from ComputeResource - cr_to_h = build_traversal_spec(client_factory, - 'cr_to_h', - 'ComputeResource', - 'host', - False, - []) - cr_to_ds = build_traversal_spec(client_factory, - 'cr_to_ds', - 'ComputeResource', - 'datastore', - False, - []) - - rp_to_rp_select_spec = build_selection_spec(client_factory, 'rp_to_rp') - rp_to_vm_select_spec = build_selection_spec(client_factory, 'rp_to_vm') - - cr_to_rp = build_traversal_spec(client_factory, - 'cr_to_rp', - 'ComputeResource', - 'resourcePool', - False, - [rp_to_rp_select_spec, - rp_to_vm_select_spec]) - - # Next hop from ClusterComputeResource - ccr_to_h = build_traversal_spec(client_factory, - 'ccr_to_h', - 'ClusterComputeResource', - 'host', - False, - []) - ccr_to_ds = build_traversal_spec(client_factory, - 'ccr_to_ds', - 'ClusterComputeResource', - 'datastore', - False, - []) - ccr_to_rp = build_traversal_spec(client_factory, - 'ccr_to_rp', - 'ClusterComputeResource', - 'resourcePool', - False, - [rp_to_rp_select_spec, - rp_to_vm_select_spec]) - # Next hop from ResourcePool - rp_to_rp = build_traversal_spec(client_factory, - 'rp_to_rp', - 'ResourcePool', - 'resourcePool', - False, - [rp_to_rp_select_spec, - rp_to_vm_select_spec]) - rp_to_vm = build_traversal_spec(client_factory, - 'rp_to_vm', - 'ResourcePool', - 'vm', - False, - [rp_to_rp_select_spec, - rp_to_vm_select_spec]) - - # Get the assorted traversal spec which takes care of the objects to - # be searched for from the rootFolder - traversal_spec = build_traversal_spec(client_factory, - 'visitFolders', - 'Folder', - 'childEntity', - False, - [visit_folders_select_spec, - h_to_vm, - dc_to_hf, - dc_to_vmf, - dc_to_netf, - cr_to_ds, - cr_to_h, - cr_to_rp, - ccr_to_h, - ccr_to_ds, - ccr_to_rp, - rp_to_rp, - rp_to_vm]) - return traversal_spec - - -def build_property_spec(client_factory, type_='VirtualMachine', - properties_to_collect=None, all_properties=False): - """Builds the property spec. - - :param client_factory: factory to get API input specs - :param type_: type of the managed object - :param properties_to_collect: names of the managed object properties to be - collected while traversal filtering - :param all_properties: whether all properties of the managed object need - to be collected - :returns: property spec - """ - if not properties_to_collect: - properties_to_collect = ['name'] - - property_spec = client_factory.create('ns0:PropertySpec') - property_spec.all = all_properties - property_spec.pathSet = properties_to_collect - property_spec.type = type_ - return property_spec - - -def build_object_spec(client_factory, root_folder, traversal_specs): - """Builds the object spec. - - :param client_factory: factory to get API input specs - :param root_folder: root folder reference; the starting point of traversal - :param traversal_specs: filter specs required for traversal - :returns: object spec - """ - object_spec = client_factory.create('ns0:ObjectSpec') - object_spec.obj = root_folder - object_spec.skip = False - object_spec.selectSet = traversal_specs - return object_spec - - -def build_property_filter_spec(client_factory, property_specs, object_specs): - """Builds the property filter spec. - - :param client_factory: factory to get API input specs - :param property_specs: property specs to be collected for filtered objects - :param object_specs: object specs to identify objects to be filtered - :returns: property filter spec - """ - property_filter_spec = client_factory.create('ns0:PropertyFilterSpec') - property_filter_spec.propSet = property_specs - property_filter_spec.objectSet = object_specs - return property_filter_spec - - -def get_objects(vim, type_, max_objects, properties_to_collect=None, - all_properties=False): - """Get all managed object references of the given type. - - It is the caller's responsibility to continue or cancel retrieval. - - :param vim: Vim object - :param type_: type of the managed object - :param max_objects: maximum number of objects that should be returned in - a single call - :param properties_to_collect: names of the managed object properties to be - collected - :param all_properties: whether all properties of the managed object need to - be collected - :returns: all managed object references of the given type - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - if not properties_to_collect: - properties_to_collect = ['name'] - - client_factory = vim.client.factory - recur_trav_spec = build_recursive_traversal_spec(client_factory) - object_spec = build_object_spec(client_factory, - vim.service_content.rootFolder, - [recur_trav_spec]) - property_spec = build_property_spec( - client_factory, - type_=type_, - properties_to_collect=properties_to_collect, - all_properties=all_properties) - property_filter_spec = build_property_filter_spec(client_factory, - [property_spec], - [object_spec]) - options = client_factory.create('ns0:RetrieveOptions') - options.maxObjects = max_objects - return vim.RetrievePropertiesEx(vim.service_content.propertyCollector, - specSet=[property_filter_spec], - options=options) - - -def get_object_properties(vim, moref, properties_to_collect, skip_op_id=False): - """Get properties of the given managed object. - - :param vim: Vim object - :param moref: managed object reference - :param properties_to_collect: names of the managed object properties to be - collected - :param skip_op_id: whether to skip putting opID in the request - :returns: properties of the given managed object - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - if moref is None: - return None - - client_factory = vim.client.factory - all_properties = (properties_to_collect is None or - len(properties_to_collect) == 0) - property_spec = build_property_spec( - client_factory, - type_=moref._type, - properties_to_collect=properties_to_collect, - all_properties=all_properties) - object_spec = build_object_spec(client_factory, moref, []) - property_filter_spec = build_property_filter_spec(client_factory, - [property_spec], - [object_spec]) - - options = client_factory.create('ns0:RetrieveOptions') - options.maxObjects = 1 - retrieve_result = vim.RetrievePropertiesEx( - vim.service_content.propertyCollector, - specSet=[property_filter_spec], - options=options, - skip_op_id=skip_op_id) - cancel_retrieval(vim, retrieve_result) - return retrieve_result.objects - - -def get_object_properties_dict(vim, moref, properties_to_collect): - """Get properties of the given managed object as a dict. - - :param vim: Vim object - :param moref: managed object reference - :param properties_to_collect: names of the managed object properties to be - collected - :returns: a dict of properties of the given managed object - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - obj_contents = get_object_properties(vim, moref, properties_to_collect) - if obj_contents is None: - return {} - property_dict = {} - if hasattr(obj_contents[0], 'propSet'): - dynamic_properties = obj_contents[0].propSet - if dynamic_properties: - for prop in dynamic_properties: - property_dict[prop.name] = prop.val - # The object may have information useful for logging - if hasattr(obj_contents[0], 'missingSet'): - for m in obj_contents[0].missingSet: - LOG.warning("Unable to retrieve value for %(path)s " - "Reason: %(reason)s", - {'path': m.path, - 'reason': m.fault.localizedMessage}) - return property_dict - - -def _get_token(retrieve_result): - """Get token from result to obtain next set of results. - - :retrieve_result: Result of RetrievePropertiesEx API call - :returns: token to obtain next set of results; None if no more results. - """ - return getattr(retrieve_result, 'token', None) - - -def cancel_retrieval(vim, retrieve_result): - """Cancels the retrieve operation if necessary. - - :param vim: Vim object - :param retrieve_result: result of RetrievePropertiesEx API call - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - token = _get_token(retrieve_result) - if token: - collector = vim.service_content.propertyCollector - vim.CancelRetrievePropertiesEx(collector, token=token) - - -def continue_retrieval(vim, retrieve_result): - """Continue retrieving results, if available. - - :param vim: Vim object - :param retrieve_result: result of RetrievePropertiesEx API call - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - token = _get_token(retrieve_result) - if token: - collector = vim.service_content.propertyCollector - return vim.ContinueRetrievePropertiesEx(collector, token=token) - - -class WithRetrieval(object): - """Context to retrieve results. - - This context provides an iterator to retrieve results and cancel (when - needed) retrieve operation on __exit__. - - Example: - - with WithRetrieval(vim, retrieve_result) as objects: - for obj in objects: - # Use obj - """ - - def __init__(self, vim, retrieve_result): - super(WithRetrieval, self).__init__() - self.vim = vim - self.retrieve_result = retrieve_result - - def __enter__(self): - return iter(self) - - def __exit__(self, exc_type, exc_value, traceback): - if self.retrieve_result: - cancel_retrieval(self.vim, self.retrieve_result) - - def __iter__(self): - while self.retrieve_result: - for obj in self.retrieve_result.objects: - yield obj - self.retrieve_result = continue_retrieval( - self.vim, self.retrieve_result) - - -def get_object_property(vim, moref, property_name, skip_op_id=False): - """Get property of the given managed object. - - :param vim: Vim object - :param moref: managed object reference - :param property_name: name of the property to be retrieved - :param skip_op_id: whether to skip putting opID in the request - :returns: property of the given managed object - :raises: VimException, VimFaultException, VimAttributeException, - VimSessionOverLoadException, VimConnectionException - """ - props = get_object_properties(vim, moref, [property_name], - skip_op_id=skip_op_id) - prop_val = None - if props: - prop = None - if hasattr(props[0], 'propSet'): - # propSet will be set only if the server provides value - # for the field - prop = props[0].propSet - if prop: - prop_val = prop[0].val - return prop_val - - -def find_extension(vim, key): - """Looks for an existing extension. - - :param vim: Vim object - :param key: the key to search for - :returns: the data object Extension or None - """ - extension_manager = vim.service_content.extensionManager - return vim.FindExtension(extension_manager, extensionKey=key) - - -def register_extension(vim, key, type, label='OpenStack', - summary='OpenStack services', version='1.0'): - """Create a new extention. - - :param vim: Vim object - :param key: the key for the extension - :param type: Managed entity type, as defined by the extension. This - matches the type field in the configuration about a - virtual machine or vApp - :param label: Display label - :param summary: Summary description - :param version: Extension version number as a dot-separated string - """ - extension_manager = vim.service_content.extensionManager - client_factory = vim.client.factory - os_ext = client_factory.create('ns0:Extension') - os_ext.key = key - entity_info = client_factory.create('ns0:ExtManagedEntityInfo') - entity_info.type = type - os_ext.managedEntityInfo = [entity_info] - os_ext.version = version - desc = client_factory.create('ns0:Description') - desc.label = label - desc.summary = summary - os_ext.description = desc - os_ext.lastHeartbeatTime = timeutils.utcnow().isoformat() - vim.RegisterExtension(extension_manager, extension=os_ext) - - -def get_vc_version(session): - """Return the dot-separated vCenter version string. For example, "1.2". - - :param session: vCenter soap session - :return: vCenter version - """ - return session.vim.service_content.about.version - - -def get_inventory_path(vim, entity_ref, max_objects=100): - """Get the inventory path of a managed entity. - - :param vim: Vim object - :param entity_ref: managed entity reference - :param max_objects: maximum number of objects that should be returned in - a single call - :return: inventory path of the entity_ref - """ - client_factory = vim.client.factory - property_collector = vim.service_content.propertyCollector - - prop_spec = build_property_spec(client_factory, 'ManagedEntity', - ['name', 'parent']) - select_set = build_selection_spec(client_factory, 'ParentTraversalSpec') - select_set = build_traversal_spec( - client_factory, 'ParentTraversalSpec', 'ManagedEntity', 'parent', - False, [select_set]) - obj_spec = build_object_spec(client_factory, entity_ref, select_set) - prop_filter_spec = build_property_filter_spec(client_factory, - [prop_spec], [obj_spec]) - options = client_factory.create('ns0:RetrieveOptions') - options.maxObjects = max_objects - retrieve_result = vim.RetrievePropertiesEx( - property_collector, - specSet=[prop_filter_spec], - options=options) - entity_name = None - propSet = None - path = "" - with WithRetrieval(vim, retrieve_result) as objects: - for obj in objects: - if hasattr(obj, 'propSet'): - propSet = obj.propSet - if len(propSet) >= 1 and not entity_name: - entity_name = propSet[0].val - elif len(propSet) >= 1: - path = '%s/%s' % (propSet[0].val, path) - # NOTE(arnaud): slice to exclude the root folder from the result. - if propSet is not None and len(propSet) > 0: - path = path[len(propSet[0].val):] - if entity_name is None: - entity_name = "" - return '%s%s' % (path, entity_name) - - -def get_http_service_request_spec(client_factory, method, uri): - """Build a HTTP service request spec. - - :param client_factory: factory to get API input specs - :param method: HTTP method (GET, POST, PUT) - :param uri: target URL - """ - http_service_request_spec = client_factory.create( - 'ns0:SessionManagerHttpServiceRequestSpec') - http_service_request_spec.method = method - http_service_request_spec.url = uri - return http_service_request_spec - - -def get_prop_spec(client_factory, spec_type, properties): - """Builds the Property Spec Object.""" - prop_spec = client_factory.create('ns0:PropertySpec') - prop_spec.type = spec_type - prop_spec.pathSet = properties - return prop_spec - - -def get_obj_spec(client_factory, obj, select_set=None): - """Builds the Object Spec object.""" - obj_spec = client_factory.create('ns0:ObjectSpec') - obj_spec.obj = obj - obj_spec.skip = False - if select_set is not None: - obj_spec.selectSet = select_set - return obj_spec - - -def get_prop_filter_spec(client_factory, obj_spec, prop_spec): - """Builds the Property Filter Spec Object.""" - prop_filter_spec = client_factory.create('ns0:PropertyFilterSpec') - prop_filter_spec.propSet = prop_spec - prop_filter_spec.objectSet = obj_spec - return prop_filter_spec - - -def get_properties_for_a_collection_of_objects(vim, type_, - obj_list, properties, - max_objects=None): - """Gets the list of properties for the collection of - objects of the type specified. - """ - client_factory = vim.client.factory - if len(obj_list) == 0: - return [] - prop_spec = get_prop_spec(client_factory, type_, properties) - lst_obj_specs = [] - for obj in obj_list: - lst_obj_specs.append(get_obj_spec(client_factory, obj)) - prop_filter_spec = get_prop_filter_spec(client_factory, - lst_obj_specs, [prop_spec]) - options = client_factory.create('ns0:RetrieveOptions') - options.maxObjects = max_objects if max_objects else len(obj_list) - return vim.RetrievePropertiesEx( - vim.service_content.propertyCollector, - specSet=[prop_filter_spec], options=options) - - -def propset_dict(propset): - """Turn a propset list into a dictionary - - PropSet is an optional attribute on ObjectContent objects - that are returned by the VMware API. - - You can read more about these at: - | http://pubs.vmware.com/vsphere-51/index.jsp - | #com.vmware.wssdk.apiref.doc/ - | vmodl.query.PropertyCollector.ObjectContent.html - - :param propset: a property "set" from ObjectContent - :return: dictionary representing property set - """ - if propset is None: - return {} - - return {prop.name: prop.val for prop in propset} diff --git a/oslo_vmware/wsdl/5.5/core-types.xsd b/oslo_vmware/wsdl/5.5/core-types.xsd deleted file mode 100644 index 51aedf4..0000000 --- a/oslo_vmware/wsdl/5.5/core-types.xsd +++ /dev/null @@ -1,242 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/5.5/pbm-messagetypes.xsd b/oslo_vmware/wsdl/5.5/pbm-messagetypes.xsd deleted file mode 100644 index 1f06b9f..0000000 --- a/oslo_vmware/wsdl/5.5/pbm-messagetypes.xsd +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/5.5/pbm-types.xsd b/oslo_vmware/wsdl/5.5/pbm-types.xsd deleted file mode 100644 index e919a2a..0000000 --- a/oslo_vmware/wsdl/5.5/pbm-types.xsd +++ /dev/null @@ -1,729 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/5.5/pbm.wsdl b/oslo_vmware/wsdl/5.5/pbm.wsdl deleted file mode 100644 index dee980f..0000000 --- a/oslo_vmware/wsdl/5.5/pbm.wsdl +++ /dev/null @@ -1,889 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/5.5/pbmService.wsdl b/oslo_vmware/wsdl/5.5/pbmService.wsdl deleted file mode 100644 index ff77383..0000000 --- a/oslo_vmware/wsdl/5.5/pbmService.wsdl +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - diff --git a/oslo_vmware/wsdl/6.0/core-types.xsd b/oslo_vmware/wsdl/6.0/core-types.xsd deleted file mode 100644 index 57a00c1..0000000 --- a/oslo_vmware/wsdl/6.0/core-types.xsd +++ /dev/null @@ -1,237 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/6.0/pbm-messagetypes.xsd b/oslo_vmware/wsdl/6.0/pbm-messagetypes.xsd deleted file mode 100644 index 22e2993..0000000 --- a/oslo_vmware/wsdl/6.0/pbm-messagetypes.xsd +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/6.0/pbm-types.xsd b/oslo_vmware/wsdl/6.0/pbm-types.xsd deleted file mode 100644 index ef0503c..0000000 --- a/oslo_vmware/wsdl/6.0/pbm-types.xsd +++ /dev/null @@ -1,806 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/6.0/pbm.wsdl b/oslo_vmware/wsdl/6.0/pbm.wsdl deleted file mode 100644 index 390b2e0..0000000 --- a/oslo_vmware/wsdl/6.0/pbm.wsdl +++ /dev/null @@ -1,1104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/6.0/pbmService.wsdl b/oslo_vmware/wsdl/6.0/pbmService.wsdl deleted file mode 100644 index 103212a..0000000 --- a/oslo_vmware/wsdl/6.0/pbmService.wsdl +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - diff --git a/oslo_vmware/wsdl/6.5/core-types.xsd b/oslo_vmware/wsdl/6.5/core-types.xsd deleted file mode 100644 index 505ae9d..0000000 --- a/oslo_vmware/wsdl/6.5/core-types.xsd +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/6.5/pbm-messagetypes.xsd b/oslo_vmware/wsdl/6.5/pbm-messagetypes.xsd deleted file mode 100644 index 7cc2341..0000000 --- a/oslo_vmware/wsdl/6.5/pbm-messagetypes.xsd +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/6.5/pbm-types.xsd b/oslo_vmware/wsdl/6.5/pbm-types.xsd deleted file mode 100644 index fd2d10c..0000000 --- a/oslo_vmware/wsdl/6.5/pbm-types.xsd +++ /dev/null @@ -1,988 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/6.5/pbm.wsdl b/oslo_vmware/wsdl/6.5/pbm.wsdl deleted file mode 100644 index 0e42d83..0000000 --- a/oslo_vmware/wsdl/6.5/pbm.wsdl +++ /dev/null @@ -1,3975 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/6.5/pbmService.wsdl b/oslo_vmware/wsdl/6.5/pbmService.wsdl deleted file mode 100644 index a4a5f9b..0000000 --- a/oslo_vmware/wsdl/6.5/pbmService.wsdl +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - diff --git a/oslo_vmware/wsdl/6.5/query-types.xsd b/oslo_vmware/wsdl/6.5/query-types.xsd deleted file mode 100644 index a8fc0d7..0000000 --- a/oslo_vmware/wsdl/6.5/query-types.xsd +++ /dev/null @@ -1,254 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/oslo_vmware/wsdl/6.5/reflect-types.xsd b/oslo_vmware/wsdl/6.5/reflect-types.xsd deleted file mode 100644 index f8c601a..0000000 --- a/oslo_vmware/wsdl/6.5/reflect-types.xsd +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/oslo_vmware/wsdl/6.5/vim-types.xsd b/oslo_vmware/wsdl/6.5/vim-types.xsd deleted file mode 100644 index f8a2ca2..0000000 --- a/oslo_vmware/wsdl/6.5/vim-types.xsd +++ /dev/null @@ -1,32649 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pylintrc b/pylintrc deleted file mode 100644 index 4ec63b1..0000000 --- a/pylintrc +++ /dev/null @@ -1,31 +0,0 @@ -# The format of this file isn't really documented; just use --generate-rcfile - -[Messages Control] -# C0111: Don't require docstrings on every method -# W0511: TODOs in code comments are fine. -# W0142: *args and **kwargs are fine. -# W0622: Redefining id is fine. -disable=C0111,W0511,W0142,W0622 - -[Basic] -# Variable names can be 1 to 31 characters long, with lowercase and underscores -variable-rgx=[a-z_][a-z0-9_]{0,30}$ - -# Argument names can be 2 to 31 characters long, with lowercase and underscores -argument-rgx=[a-z_][a-z0-9_]{1,30}$ - -# Method names should be at least 3 characters long -# and be lowercased with underscores -method-rgx=([a-z_][a-z0-9_]{2,50}|setUp|tearDown)$ - -[Design] -max-public-methods=100 -min-public-methods=0 -max-args=6 - -[Variables] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -# _ is used by our localization -additional-builtins=_ diff --git a/releasenotes/notes/add_reno-3b4ae0789e9c45b4.yaml b/releasenotes/notes/add_reno-3b4ae0789e9c45b4.yaml deleted file mode 100644 index 46a2da6..0000000 --- a/releasenotes/notes/add_reno-3b4ae0789e9c45b4.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -other: - - Switch to reno for managing release notes. \ No newline at end of file diff --git a/releasenotes/source/_static/.placeholder b/releasenotes/source/_static/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/releasenotes/source/_templates/.placeholder b/releasenotes/source/_templates/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py deleted file mode 100644 index 2b49a5a..0000000 --- a/releasenotes/source/conf.py +++ /dev/null @@ -1,282 +0,0 @@ -# -*- coding: utf-8 -*- -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'openstackdocstheme', - 'reno.sphinxext', -] - -# openstackdocstheme options -repository_name = 'openstack/oslo.vmware' -bug_project = 'oslo.vmware' -bug_tag = '' - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -# source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'oslo.vmware Release Notes' -copyright = u'2016, oslo.vmware Developers' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -from oslo_vmware.version import version_info as oslo_vmware_version -# The full version, including alpha/beta/rc tags. -release = oslo_vmware_version.version_string_with_vcs() -# The short X.Y version. -version = oslo_vmware_version.canonical_version_string() - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# today = '' -# Else, today_fmt is used as the format for a strftime call. -# today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'openstackdocs' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -# html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -html_last_updated_fmt = '%Y-%m-%d %H:%M' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# html_additional_pages = {} - -# If false, no module index is generated. -# html_domain_indices = True - -# If false, no index is generated. -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'oslo.vmwareReleaseNotesDoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # 'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ('index', 'oslo.vmwareReleaseNotes.tex', - u'oslo.vmware Release Notes Documentation', - u'oslo.vmware Developers', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# latex_use_parts = False - -# If true, show page references after internal links. -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# latex_appendices = [] - -# If false, no module index is generated. -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'oslo.vmwareReleaseNotes', - u'oslo.vmware Release Notes Documentation', - [u'oslo.vmware Developers'], 1) -] - -# If true, show URL addresses after external links. -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'oslo.vmwareReleaseNotes', - u'oslo.vmware Release Notes Documentation', - u'oslo.vmware Developers', 'oslo.vmwareReleaseNotes', - 'The Oslo VMware library provides support for common VMware operations' - ' and APIs.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -# texinfo_appendices = [] - -# If false, no module index is generated. -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# texinfo_no_detailmenu = False - -# -- Options for Internationalization output ------------------------------ -locale_dirs = ['locale/'] diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst deleted file mode 100644 index a2214ea..0000000 --- a/releasenotes/source/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -=========================== - oslo.vmware Release Notes -=========================== - - .. toctree:: - :maxdepth: 1 - - unreleased - ocata - newton diff --git a/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po b/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po deleted file mode 100644 index 1548524..0000000 --- a/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po +++ /dev/null @@ -1,27 +0,0 @@ -# Andi Chandler , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.vmware Release Notes 2.15.1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-10-22 08:58+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-06-09 11:20+0000\n" -"Last-Translator: Andi Chandler \n" -"Language-Team: English (United Kingdom)\n" -"Language: en-GB\n" -"X-Generator: Zanata 3.7.3\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -msgid "Other Notes" -msgstr "Other Notes" - -msgid "Switch to reno for managing release notes." -msgstr "Switch to reno for managing release notes." - -msgid "Unreleased Release Notes" -msgstr "Unreleased Release Notes" - -msgid "oslo.vmware Release Notes" -msgstr "oslo.vmware Release Notes" diff --git a/releasenotes/source/locale/fr/LC_MESSAGES/releasenotes.po b/releasenotes/source/locale/fr/LC_MESSAGES/releasenotes.po deleted file mode 100644 index c34f634..0000000 --- a/releasenotes/source/locale/fr/LC_MESSAGES/releasenotes.po +++ /dev/null @@ -1,33 +0,0 @@ -# Gérald LONLAS , 2016. #zanata -msgid "" -msgstr "" -"Project-Id-Version: oslo.vmware Release Notes 2.15.1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-10-22 08:58+0000\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2016-10-22 06:06+0000\n" -"Last-Translator: Gérald LONLAS \n" -"Language-Team: French\n" -"Language: fr\n" -"X-Generator: Zanata 3.7.3\n" -"Plural-Forms: nplurals=2; plural=(n > 1)\n" - -msgid "2.8.0" -msgstr "2.8.0" - -msgid "Newton Series Release Notes" -msgstr "Note de release pour Newton" - -msgid "Other Notes" -msgstr "Autres notes" - -msgid "Switch to reno for managing release notes." -msgstr "Commence à utiliser reno pour la gestion des notes de release" - -msgid "Unreleased Release Notes" -msgstr "Note de release pour les changements non déployées" - -msgid "oslo.vmware Release Notes" -msgstr "Note de release pour oslo.vmware" diff --git a/releasenotes/source/newton.rst b/releasenotes/source/newton.rst deleted file mode 100644 index 7b7d735..0000000 --- a/releasenotes/source/newton.rst +++ /dev/null @@ -1,6 +0,0 @@ -============================= - Newton Series Release Notes -============================= - -.. release-notes:: - :branch: origin/stable/newton diff --git a/releasenotes/source/ocata.rst b/releasenotes/source/ocata.rst deleted file mode 100644 index 9515f6c..0000000 --- a/releasenotes/source/ocata.rst +++ /dev/null @@ -1,6 +0,0 @@ -============================ - Ocata Series Release Notes -============================ - -.. release-notes:: - :branch: origin/stable/ocata diff --git a/releasenotes/source/unreleased.rst b/releasenotes/source/unreleased.rst deleted file mode 100644 index 5860a46..0000000 --- a/releasenotes/source/unreleased.rst +++ /dev/null @@ -1,5 +0,0 @@ -========================== - Unreleased Release Notes -========================== - -.. release-notes:: diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 93adefe..0000000 --- a/requirements.txt +++ /dev/null @@ -1,22 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. - -pbr!=2.1.0,>=2.0.0 # Apache-2.0 - -stevedore>=1.20.0 # Apache-2.0 -netaddr!=0.7.16,>=0.7.13 # BSD -six>=1.9.0 # MIT - -oslo.i18n!=3.15.2,>=2.1.0 # Apache-2.0 -oslo.utils>=3.20.0 # Apache-2.0 - -# for the routing notifier -PyYAML>=3.10.0 # MIT - -lxml!=3.7.0,>=2.3 # BSD -suds-jurko>=0.6 # LGPLv3+ -eventlet!=0.18.3,!=0.20.1,<0.21.0,>=0.18.2 # MIT -requests>=2.14.2 # Apache-2.0 -urllib3>=1.21.1 # MIT -oslo.concurrency>=3.8.0 # Apache-2.0 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index a99771b..0000000 --- a/setup.cfg +++ /dev/null @@ -1,56 +0,0 @@ -[metadata] -name = oslo.vmware -summary = Oslo VMware library -description-file = - README.rst -author = OpenStack -author-email = openstack-dev@lists.openstack.org -home-page = https://docs.openstack.org/oslo.vmware/latest/ -classifier = - Environment :: OpenStack - Intended Audience :: Information Technology - Intended Audience :: System Administrators - License :: OSI Approved :: Apache Software License - Operating System :: POSIX :: Linux - Programming Language :: Python - Programming Language :: Python :: 2 - Programming Language :: Python :: 2.7 - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.5 - -[files] -packages = - oslo_vmware - -[build_sphinx] -source-dir = doc/source -build-dir = doc/build -all_files = 1 -warning-is-error = 1 - -[upload_sphinx] -upload-dir = doc/build/html - -[compile_catalog] -directory = oslo_vmware/locale -domain = oslo_vmware - -[update_catalog] -domain = oslo_vmware -output_dir = oslo_vmware/locale -input_file = oslo_vmware/locale/oslo_vmware.pot - -[extract_messages] -keywords = _ gettext ngettext l_ lazy_gettext -mapping_file = babel.cfg -output_file = oslo_vmware/locale/oslo_vmware.pot - -[pbr] -autodoc_index_modules = 1 -autodoc_exclude_modules = - oslo_vmware._i18n - oslo_vmware.tests.* -api_doc_dir = reference/api - -[wheel] -universal = 1 diff --git a/setup.py b/setup.py deleted file mode 100644 index 566d844..0000000 --- a/setup.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT -import setuptools - -# In python < 2.7.4, a lazy loading of package `pbr` will break -# setuptools if some other modules registered functions in `atexit`. -# solution from: http://bugs.python.org/issue15881#msg170215 -try: - import multiprocessing # noqa -except ImportError: - pass - -setuptools.setup( - setup_requires=['pbr>=2.0.0'], - pbr=True) diff --git a/test-requirements.txt b/test-requirements.txt deleted file mode 100644 index cbad5d9..0000000 --- a/test-requirements.txt +++ /dev/null @@ -1,25 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. - -# Hacking already pins down pep8, pyflakes and flake8 -hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0 - -fixtures>=3.0.0 # Apache-2.0/BSD -mock>=2.0 # BSD -python-subunit>=0.0.18 # Apache-2.0/BSD -testrepository>=0.0.18 # Apache-2.0/BSD -testtools>=1.4.0 # MIT - -# when we can require tox>= 1.4, this can go into tox.ini: -# [testenv:cover] -# deps = {[testenv]deps} coverage -coverage!=4.4,>=4.0 # Apache-2.0 - -# this is required for the docs build jobs -openstackdocstheme>=1.11.0 # Apache-2.0 -sphinx>=1.6.2 # BSD -reno!=2.3.1,>=1.8.0 # Apache-2.0 - -bandit>=1.1.0 # Apache-2.0 -ddt>=1.0.1 # MIT diff --git a/tools/tox_install.sh b/tools/tox_install.sh deleted file mode 100755 index 43468e4..0000000 --- a/tools/tox_install.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -# Client constraint file contains this client version pin that is in conflict -# with installing the client from source. We should remove the version pin in -# the constraints file before applying it for from-source installation. - -CONSTRAINTS_FILE=$1 -shift 1 - -set -e - -# NOTE(tonyb): Place this in the tox enviroment's log dir so it will get -# published to logs.openstack.org for easy debugging. -localfile="$VIRTUAL_ENV/log/upper-constraints.txt" - -if [[ $CONSTRAINTS_FILE != http* ]]; then - CONSTRAINTS_FILE=file://$CONSTRAINTS_FILE -fi -# NOTE(tonyb): need to add curl to bindep.txt if the project supports bindep -curl $CONSTRAINTS_FILE --insecure --progress-bar --output $localfile - -pip install -c$localfile openstack-requirements - -# This is the main purpose of the script: Allow local installation of -# the current repo. It is listed in constraints file and thus any -# install will be constrained and we need to unconstrain it. -edit-constraints $localfile -- $CLIENT_NAME - -pip install -c$localfile -U $* -exit $? diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 212109b..0000000 --- a/tox.ini +++ /dev/null @@ -1,63 +0,0 @@ -[tox] -minversion = 2.0 -envlist = py35,py27,pypy,pep8 - -[testenv] -setenv = - VIRTUAL_ENV={envdir} - BRANCH_NAME=master - CLIENT_NAME=oslo.vmware -install_command = {toxinidir}/tools/tox_install.sh {env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages} -whitelist_externals = find - rm -deps = -r{toxinidir}/test-requirements.txt -commands = python setup.py testr --slowest --testr-args='{posargs}' - -[testenv:pep8] -commands = - flake8 - # Run security linter - bandit -r oslo_vmware - -[testenv:pylint] -deps = -r{toxinidir}/test-requirements.txt - pylint>=1.3.0 -commands = pylint oslo - -[testenv:bandit] -deps = -r{toxinidir}/test-requirements.txt -commands = bandit -r oslo_vmware - -[testenv:docs] -commands = python setup.py build_sphinx - -[testenv:cover] -commands = - coverage erase - find . -type f -name "*.pyc" -delete - python setup.py test --coverage --coverage-package-name=oslo_vmware --testr-args='{posargs}' - coverage report - -[testenv:venv] -commands = {posargs} - -[flake8] -show-source = True -ignore = H405 -exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build,__init__.py - -[hacking] -import_exceptions = oslo_vmware.tests.base - tests.base -local-check-factory = oslo_vmware.hacking.checks.factory - -[testenv:pip-missing-reqs] -# do not install test-requirements as that will pollute the virtualenv for -# determining missing packages -# this also means that pip-missing-reqs must be installed separately, outside -# of the requirements.txt files -deps = pip_missing_reqs -commands = pip-missing-reqs -d --ignore-module=oslo_vmware* --ignore-file=oslo_vmware/tests/* oslo_vmware - -[testenv:releasenotes] -commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html