diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 2d53dce..0000000 --- a/.coveragerc +++ /dev/null @@ -1,6 +0,0 @@ -[run] -branch = True -source = tricircleclient - -[report] -ignore_errors = True diff --git a/.gitignore b/.gitignore deleted file mode 100644 index a3a8677..0000000 --- a/.gitignore +++ /dev/null @@ -1,58 +0,0 @@ -*.py[cod] - -# C extensions -*.so - -# Packages -*.egg -*.egg-info -dist -build -.eggs -eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg -lib -lib64 - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage* -cover/ -.tox -.stestr/ -.venv - -# 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 -.*sw? -.idea/ - -# generated docs -doc/source/api diff --git a/.stestr.conf b/.stestr.conf deleted file mode 100644 index 7d5fb48..0000000 --- a/.stestr.conf +++ /dev/null @@ -1,3 +0,0 @@ -[DEFAULT] -test_path=./tricircleclient/tests -top_dir=./ diff --git a/.zuul.yaml b/.zuul.yaml deleted file mode 100644 index 39a3138..0000000 --- a/.zuul.yaml +++ /dev/null @@ -1,7 +0,0 @@ -- project: - templates: - - openstack-cover-jobs - - openstack-lower-constraints-jobs - - openstack-python3-victoria-jobs - - check-requirements - - publish-openstack-docs-pti diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst deleted file mode 100644 index f5db196..0000000 --- a/CONTRIBUTING.rst +++ /dev/null @@ -1,17 +0,0 @@ -If you would like to contribute to the development of OpenStack, you must -follow the steps in this page: - - http://docs.openstack.org/infra/manual/developers.html - -If you already have a good understanding of how the system works and your -OpenStack accounts are set up, you can skip to the development workflow -section of this documentation to learn how changes to OpenStack should be -submitted for review via the Gerrit tool: - - http://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/python-tricircleclient diff --git a/HACKING.rst b/HACKING.rst deleted file mode 100644 index 5487413..0000000 --- a/HACKING.rst +++ /dev/null @@ -1,4 +0,0 @@ -tricircleclient Style Commandments -================================== - -Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 68c771a..0000000 --- a/LICENSE +++ /dev/null @@ -1,176 +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.md b/README.md deleted file mode 100644 index ee6069e..0000000 --- a/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Tricircleclient - -Python bindings to the OpenStack Tricircle API - -This is a client for OpenStack Tricircle API providing a Python API (using the -**tricircleclient** module) and a Command Line Interface (installed as the -**tricircle** command). Each implements the entire OpenStack Tricircle API. - -* Free software: Apache license -* [Documentation](https://docs.openstack.org/python-tricircleclient/latest/) -* [Source](http://git.openstack.org/cgit/openstack/python-tricircleclient) -* [Bugs](http://bugs.launchpad.net/python-tricircleclient) diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..86e34d6 --- /dev/null +++ b/README.rst @@ -0,0 +1,10 @@ +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 any further questions, please email +openstack-discuss@lists.openstack.org or join #openstack-dev on +Freenode. diff --git a/doc/requirements.txt b/doc/requirements.txt deleted file mode 100644 index f29bbf0..0000000 --- a/doc/requirements.txt +++ /dev/null @@ -1,6 +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. -sphinx!=1.6.6,!=1.6.7,>=1.6.3,!=3.0.0 # BSD -openstackdocstheme>=1.32.1 # Apache-2.0 -sphinxcontrib-apidoc>=0.2.0 # BSD diff --git a/doc/source/api.rst b/doc/source/api.rst deleted file mode 100644 index 12ea4b5..0000000 --- a/doc/source/api.rst +++ /dev/null @@ -1,21 +0,0 @@ -The :mod:`tricircleclient` Python API -===================================== - -Usage ------ - -To use tricircleclient in a project:: - - >>> from tricircleclient.v1 import client - >>> tricircle = client.Client(...) - >>> tricircle.pod.list() - -Reference ---------- - -For more information, see the reference: - -.. toctree:: - :glob: - - api/* diff --git a/doc/source/conf.py b/doc/source/conf.py deleted file mode 100644 index 9ada0f9..0000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,94 +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. - -import os -import sys - -BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -ROOT = os.path.abspath(os.path.join(BASE_DIR, "..", "..")) - -sys.path.insert(0, ROOT) -sys.path.insert(0, BASE_DIR) - -# -- 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 = [ - 'sphinxcontrib.apidoc', - 'openstackdocstheme' - #'sphinx.ext.intersphinx' -] - - -# 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 - -# The suffix of source filenames. -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'tricircleclient' -copyright = u'2017, OpenStack Foundation' - -# -- Options for openstackdocstheme ------------------------------------------- -repository_name = 'openstack/python-tricircleclient' -bug_project = 'python-tricircleclient' -bug_tag = '' - -# 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'] - -# 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} - -# -- sphinxcontrib.apidoc configuration -------------------------------------- - -apidoc_module_dir = '../../tricircleclient' -apidoc_output_dir = 'api' -apidoc_excluded_paths = [ - 'tests', -] diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100644 index 5b6b847..0000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,29 +0,0 @@ -Python bindings and command line tool to the Tricircle API -========================================================== - -This is a client for OpenStack Tricircle API. There's :doc:`a Python API ` (the -:mod:`tricircleclient` module). Each implements the entire Tricircle API. - -.. seealso:: - - You may want to read the `Tricircle documentation`__ to get an idea of the - concepts. By understanding the concepts this library and client should make - more sense. - - __ https://docs.openstack.org/tricircle/latest/ - -Contents: - -.. toctree:: - :maxdepth: 2 - - api - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - - diff --git a/lower-constraints.txt b/lower-constraints.txt deleted file mode 100644 index 9fd6f44..0000000 --- a/lower-constraints.txt +++ /dev/null @@ -1,75 +0,0 @@ -alabaster==0.7.10 -appdirs==1.3.0 -Babel==2.3.4 -cliff==2.8.0 -cmd2==0.8.0 -contextlib2==0.4.0 -coverage==4.0 -debtcollector==1.2.0 -decorator==3.4.0 -deprecation==1.0 -docutils==0.11 -dogpile.cache==0.6.2 -dulwich==0.15.0 -extras==1.0.0 -fixtures==3.0.0 -flake8==2.5.5 -futurist==1.2.0 -hacking==0.12.0 -imagesize==0.7.1 -iso8601==0.1.11 -Jinja2==2.10 -jmespath==0.9.0 -jsonpatch==1.16 -jsonpointer==1.13 -keystoneauth1==3.4.0 -linecache2==1.0.0 -MarkupSafe==1.0 -mccabe==0.2.1 -mock==2.0.0 -monotonic==0.6 -msgpack-python==0.4.0 -munch==2.1.0 -netaddr==0.7.18 -netifaces==0.10.4 -openstackdocstheme==1.18.1 -openstacksdk==0.11.2 -os-client-config==1.28.0 -os-service-types==1.2.0 -osc-lib==1.8.0 -oslo.config==5.2.0 -oslo.context==2.19.2 -oslo.i18n==3.15.3 -oslo.log==3.36.0 -oslo.serialization==2.18.0 -oslosphinx===4.7.0 -oslo.utils==3.33.0 -pbr==2.0.0 -pep8==1.5.7 -prettytable==0.7.2 -pyflakes==0.8.1 -Pygments==2.2.0 -pyinotify==0.9.6 -pyparsing==2.1.0 -pyperclip==1.5.27 -python-dateutil==2.5.3 -python-mimeparse==1.6.0 -python-subunit==1.0.0 -pytz==2013.6 -PyYAML==3.12 -requests==2.14.2 -requestsexceptions==1.2.0 -rfc3986==0.3.1 -simplejson==3.5.1 -six==1.10.0 -snowballstemmer==1.2.1 -Sphinx==1.6.3 -sphinxcontrib-websupport==1.0.1 -stevedore==1.20.0 -tempest==17.1.0 -testrepository==0.0.18 -stestr==2.0.0 -testtools==2.2.0 -traceback2==1.4.0 -unittest2==1.1.0 -wrapt==1.7.0 diff --git a/releasenotes/notes/drop-py-2-7-3c68ac538cef7e83.yaml b/releasenotes/notes/drop-py-2-7-3c68ac538cef7e83.yaml deleted file mode 100644 index b2de668..0000000 --- a/releasenotes/notes/drop-py-2-7-3c68ac538cef7e83.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -upgrade: - - | - Python 2.7 support has been dropped. Last release of python-tricircleclient - to support py2.7 is OpenStack Train. The minimum version of Python now - supported by python-tricircleclient is Python 3.6. diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 01e027e..0000000 --- a/requirements.txt +++ /dev/null @@ -1,13 +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 -cliff!=2.9.0,>=2.8.0 # Apache-2.0 -osc-lib>=1.8.0 # Apache-2.0 -oslo.log>=3.36.0 # Apache-2.0 -oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0 -oslo.utils>=3.33.0 # Apache-2.0 -keystoneauth1>=3.4.0 # Apache-2.0 -six>=1.10.0 # MIT -futurist>=1.2.0 # Apache-2.0 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index a5b301b..0000000 --- a/setup.cfg +++ /dev/null @@ -1,54 +0,0 @@ -[metadata] -name = tricircleclient -summary = Python client library for Tricircle -description-file = - README.md -author = OpenStack -author-email = openstack-discuss@lists.openstack.org -home-page = https://docs.openstack.org/python-tricircleclient/latest/ -python-requires = >=3.6 -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 :: Implementation :: CPython - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 - -[files] -packages = - tricircleclient - -[entry_points] -openstack.cli.extension = - multiregion_networking = tricircleclient.osc - -openstack.multiregion_networking.v1 = - multiregion_networking_pod_list = tricircleclient.v1.pods_cli:ListPods - multiregion_networking_pod_create = tricircleclient.v1.pods_cli:CreatePod - multiregion_networking_pod_show = tricircleclient.v1.pods_cli:ShowPod - multiregion_networking_pod_delete = tricircleclient.v1.pods_cli:DeletePod - multiregion_networking_routing_list = tricircleclient.v1.routings_cli:ListRoutings - multiregion_networking_routing_create = tricircleclient.v1.routings_cli:CreateRouting - multiregion_networking_routing_show = tricircleclient.v1.routings_cli:ShowRouting - multiregion_networking_routing_delete = tricircleclient.v1.routings_cli:DeleteRouting - multiregion_networking_routing_update = tricircleclient.v1.routings_cli:UpdateRouting - multiregion_networking_job_list = tricircleclient.v1.jobs_cli:ListJobs - multiregion_networking_job_create = tricircleclient.v1.jobs_cli:CreateJob - multiregion_networking_job_show = tricircleclient.v1.jobs_cli:ShowJob - multiregion_networking_job_delete = tricircleclient.v1.jobs_cli:DeleteJob - multiregion_networking_job_redo = tricircleclient.v1.jobs_cli:RedoJob - - -[extras] -test = - coverage!=4.4,>=4.0 # Apache-2.0 - python-subunit>=1.0.0 # Apache-2.0/BSD - tempest>=17.1.0 # Apache-2.0 - testrepository>=0.0.18 # Apache-2.0/BSD - testtools>=2.2.0 # MIT diff --git a/setup.py b/setup.py deleted file mode 100644 index cd35c3c..0000000 --- a/setup.py +++ /dev/null @@ -1,20 +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. - -import setuptools - -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 2c694b7..0000000 --- a/test-requirements.txt +++ /dev/null @@ -1,9 +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. - -fixtures>=3.0.0 # Apache-2.0/BSD -coverage!=4.4,>=4.0 # Apache-2.0 -testtools>=2.2.0 # MIT -hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0 -stestr>=2.0.0 # Apache-2.0 diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 934eb17..0000000 --- a/tox.ini +++ /dev/null @@ -1,71 +0,0 @@ -[tox] -minversion = 3.1.1 -envlist = py37,pep8 -skipsdist = True -ignore_basepython_conflict = True - -[testenv] -basepython = python3 -usedevelop = True -setenv = - VIRTUAL_ENV={envdir} - BRANCH_NAME=master - CLIENT_NAME=python-tricircleclient - DISCOVER_DIRECTORY=tricircleclient/tests/unit -passenv = http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY -deps = - -r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt -# Delete bytecodes from normal directories before running tests. -# Note that bytecodes in dot directories will not be deleted -# to keep bytecodes of python modules installed into virtualenvs. -commands = sh -c "find . -type d -name '.?*' -prune -o \ - \( -type d -name '__pycache__' -o -type f -name '*.py[co]' \) \ - -print0 | xargs -0 rm -rf" - stestr run {posargs} -whitelist_externals = sh - -[testenv:debug] -commands = oslo_debug_helper -t tricircleclient/tests/unit {posargs} - -[testenv:pep8] -deps = - hacking<0.13,>=0.12 - rstcheck -commands = - flake8 - bash -c "find {toxinidir} -not -path {toxinidir}/.tox/\* \ - -name \*.rst -type f \ - -print0 | xargs -0 rstcheck --ignore-directive automodule,module \ - --ignore-roles mod" -whitelist_externals = bash - -[testenv:venv] -commands = {posargs} - -[testenv:cover] -setenv = - PYTHON=coverage run --source tricircleclient --parallel-mode -commands = - stestr run {posargs} - coverage combine - coverage html -d cover - coverage xml -o cover/coverage.xml - coverage report --fail-under=83 --skip-covered - -[testenv:docs] -deps = - -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} - -r{toxinidir}/doc/requirements.txt -commands = sphinx-build -W -b html doc/source doc/build/html - -[flake8] -show-source = True -ignore = -exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build - -[testenv:lower-constraints] -deps = - -c{toxinidir}/lower-constraints.txt - -r{toxinidir}/test-requirements.txt - -r{toxinidir}/requirements.txt diff --git a/tricircleclient/__init__.py b/tricircleclient/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tricircleclient/client.py b/tricircleclient/client.py deleted file mode 100644 index 3b410fa..0000000 --- a/tricircleclient/client.py +++ /dev/null @@ -1,37 +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. - -from keystoneauth1 import adapter -from oslo_utils import importutils - -from tricircleclient import exceptions - - -def Client(version, *args, **kwargs): - module = 'tricircleclient.v%s.client' % version - module = importutils.import_module(module) - client_class = getattr(module, 'Client') - return client_class(*args, **kwargs) - - -class SessionClient(adapter.Adapter): - def request(self, url, method, **kwargs): - kwargs.setdefault('headers', kwargs.get('headers', {})) - raise_exc = kwargs.pop('raise_exc', True) - resp = super(SessionClient, self).request(url, - method, - raise_exc=False, - **kwargs) - - if raise_exc and resp.status_code >= 400: - raise exceptions.from_response(resp, method) - return resp diff --git a/tricircleclient/constants.py b/tricircleclient/constants.py deleted file mode 100644 index dd76400..0000000 --- a/tricircleclient/constants.py +++ /dev/null @@ -1,52 +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. - -# asynchronous job types -JT_CONFIGURE_ROUTE = 'configure_route' -JT_ROUTER_SETUP = 'router_setup' -JT_PORT_DELETE = 'port_delete' -JT_SEG_RULE_SETUP = 'seg_rule_setup' -JT_NETWORK_UPDATE = 'update_network' -JT_SUBNET_UPDATE = 'subnet_update' -JT_SHADOW_PORT_SETUP = 'shadow_port_setup' -JT_TRUNK_SYNC = 'trunk_sync' -JT_SFC_SYNC = 'sfc_sync' -JT_RESOURCE_RECYCLE = 'resource_recycle' - -# all resources needed to run the job. We specify it by -# {job_type: [resource_id1, resource_id2, ...]}. -job_resource_map = { - JT_CONFIGURE_ROUTE: ["router_id"], - JT_ROUTER_SETUP: ["pod_id", "router_id", "network_id"], - JT_PORT_DELETE: ["pod_id", "port_id"], - JT_SEG_RULE_SETUP: ["project_id"], - JT_NETWORK_UPDATE: ["pod_id", "network_id"], - JT_TRUNK_SYNC: ["pod_id", "trunk_id"], - JT_SUBNET_UPDATE: ["pod_id", "subnet_id"], - JT_SHADOW_PORT_SETUP: ["pod_id", "network_id"], - JT_SFC_SYNC: ["pod_id", "portchain_id", "network_id"], - JT_RESOURCE_RECYCLE: ["project_id"] -} - -# job has many attributes, especially its resource attribute may vary with -# job type, To have unified column headers when show the job information, -# only the fields listed below will turn up in column headers. They are -# listed by alphabet order. -COLUMNS = ('id', 'project_id', 'status', 'timestamp', 'type') - -# column headers about job that show in command line. -COLUMNS_REMAP = {'id': 'ID', - 'project_id': 'Project', - 'timestamp': 'Timestamp', - 'status': 'Status', - 'type': 'Type'} diff --git a/tricircleclient/exceptions.py b/tricircleclient/exceptions.py deleted file mode 100644 index 7ee3f2a..0000000 --- a/tricircleclient/exceptions.py +++ /dev/null @@ -1,154 +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 re -import six - -from oslo_utils import encodeutils - - -@six.python_2_unicode_compatible -class ClientException(Exception): - """The base exception class for all exceptions this library raises.""" - message = 'Unknown Error' - - def __init__(self, code=None, message=None, request_id=None, - url=None, method=None): - self.code = code - self.message = encodeutils.safe_decode( - message or self.__class__.message) - self.request_id = request_id - self.url = url - self.method = method - - def __str__(self): - formatted_string = "%s" % self.message - if self.code: - formatted_string += " (HTTP %s)" % self.code - if self.request_id: - formatted_string += " (Request-ID: %s)" % self.request_id - return formatted_string - - -class MutipleMeaningException(object): - """An mixin for exception that can be enhanced by reading the details""" - - -class BadRequest(ClientException): - """HTTP 400 - Bad request: you sent some malformed data.""" - http_status = 400 - message = "Bad request" - - -class Unauthorized(ClientException): - """HTTP 401 - Unauthorized: bad credentials.""" - http_status = 401 - message = "Unauthorized" - - -class NotFound(ClientException): - """HTTP 404 - Not found""" - http_status = 404 - message = "Not found" - - -class PodNotFound(NotFound, MutipleMeaningException): - message = "Pod not found" - match = re.compile("Pod .* does not exist") - - -class Conflict(ClientException): - """HTTP 409 - Conflict""" - http_status = 409 - message = "Conflict" - - -class RecordAlreadyExists(Conflict, MutipleMeaningException): - message = "Record already exists" - match = re.compile("Record already exists") - - -class PodRegionDuplicated(Conflict, MutipleMeaningException): - message = "Pod region name duplicated with the top region name" - match = re.compile("Pod region name duplicated with the top region name") - - -class TopRegionAlreadyExists(Conflict, MutipleMeaningException): - message = "Top region already exists" - match = re.compile("Top region already exists") - - -class UnprocessableEntity(ClientException): - """HTTP 422 - Unprocessable Entity""" - http_status = 422 - message = "Unprocessable Entity" - - -class RegionRequiredForTopRegion(UnprocessableEntity, MutipleMeaningException): - message = "Valid region_name is required for top region" - match = re.compile("Valid region_name is required for top region") - - -class RegionRequiredForPod(UnprocessableEntity, MutipleMeaningException): - message = "Valid region_name is required for pod" - match = re.compile("Valid region_name is required for pod") - - -_error_classes = [BadRequest, Unauthorized, NotFound, Conflict] -_error_classes_enhanced = { - NotFound: [PodNotFound, ], - Conflict: [RecordAlreadyExists, PodRegionDuplicated, - TopRegionAlreadyExists], - UnprocessableEntity: [RegionRequiredForTopRegion, RegionRequiredForPod] -} -_code_map = dict( - (c.http_status, (c, _error_classes_enhanced.get(c, []))) - for c in _error_classes) - - -def from_response(response, method=None): - """Return an instance of one of the ClientException on an requests response. - - Usage:: - - resp, body = requests.request(...) - if resp.status_code != 200: - raise from_response(resp) - - """ - if response.status_code: - cls, enhanced_classes = _code_map.get(response.status_code, - (ClientException, [])) - - req_id = response.headers.get("x-openstack-request-id") - - kwargs = { - 'code': response.status_code, - 'method': method, - 'url': response.url, - 'request_id': req_id, - } - - if "retry-after" in response.headers: - kwargs['retry_after'] = response.headers.get('retry-after') - - desc = response.text - if desc: - for enhanced_cls in enhanced_classes: - if enhanced_cls.match.match(response.text): - cls = enhanced_cls - break - kwargs['message'] = desc - - if not kwargs['message']: - del kwargs['message'] - return cls(**kwargs) diff --git a/tricircleclient/osc.py b/tricircleclient/osc.py deleted file mode 100644 index 08f6ff6..0000000 --- a/tricircleclient/osc.py +++ /dev/null @@ -1,61 +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. - -"""OpenStackClient plugin for Multiregion Networking service.""" - -from osc_lib import utils - - -DEFAULT_MULTIREGION_NETWORKING_API_VERSION = '1' - -# Required by the OSC plugin interface -API_NAME = 'multiregion_networking' -API_VERSION_OPTION = 'os_multiregion_networking_api_version' -API_VERSIONS = { - '1': 'tricircleclient.v1.client.Client', -} - - -# Required by the OSC plugin interface -def make_client(instance): - plugin_client = utils.get_client_class( - API_NAME, - instance._api_version[API_NAME], - API_VERSIONS) - - instance.setup_auth() - - return plugin_client( - session=instance.session, - region_name=instance.region_name) - - -# Required by the OSC plugin interface -def build_option_parser(parser): - """Hook to add global options.""" - parser.add_argument( - "--os-multiregion-networking-api-version", - metavar="", - default=utils.env( - 'OS_MULTIREGION_NETWORKING_API_VERSION', - default=DEFAULT_MULTIREGION_NETWORKING_API_VERSION), - help=("Multiregion Networking API version, default=" + - DEFAULT_MULTIREGION_NETWORKING_API_VERSION + - ' (Env: OS_MULTIREGION_NETWORKING_API_VERSION)')) - parser.add_argument( - "--os-multiregion-networking-url", - default=utils.env( - "OS_MULTIREGION_NETWORKING_URL"), - help=("Data processing API URL, " - "(Env: OS_MULTIREGION_NETWORKING_URL)")) - return parser diff --git a/tricircleclient/tests/__init__.py b/tricircleclient/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tricircleclient/tests/unit/__init__.py b/tricircleclient/tests/unit/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tricircleclient/tests/unit/fakes.py b/tricircleclient/tests/unit/fakes.py deleted file mode 100644 index aeb56ed..0000000 --- a/tricircleclient/tests/unit/fakes.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright 2017 Intel Corporation. -# -# 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 sys -from unittest import mock - - -class FakeStdout(object): - - def __init__(self): - self.content = [] - - def write(self, text): - self.content.append(text) - - def make_string(self): - result = '' - for line in self.content: - result = result + line - return result - - -class FakeLog(object): - - def __init__(self): - self.messages = {} - - def debug(self, msg): - self.messages['debug'] = msg - - def info(self, msg): - self.messages['info'] = msg - - def warning(self, msg): - self.messages['warning'] = msg - - def error(self, msg): - self.messages['error'] = msg - - def critical(self, msg): - self.messages['critical'] = msg - - -class FakeApp(object): - - def __init__(self, _stdout, _log): - self.stdout = _stdout - self.client_manager = None - self.stdin = sys.stdin - self.stdout = _stdout or sys.stdout - self.stderr = sys.stderr - self.log = _log - - -class FakeMultiregionNetworkV1Client(object): - - def __init__(self, **kwargs): - self.pod = mock.Mock() - self.routing = mock.Mock() - self.job = mock.Mock() - - -class FakeClientManager(object): - _api_version = { - 'tricircle': '1', - } - - def __init__(self): - self.multiregion_networking = FakeMultiregionNetworkV1Client() diff --git a/tricircleclient/tests/unit/test_exceptions.py b/tricircleclient/tests/unit/test_exceptions.py deleted file mode 100644 index 9963137..0000000 --- a/tricircleclient/tests/unit/test_exceptions.py +++ /dev/null @@ -1,47 +0,0 @@ -# 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 six -import testtools - -import fixtures -from oslo_utils import encodeutils - -from tricircleclient import exceptions - - -class TestExceptions(testtools.TestCase): - - def test_exception_print_with_unicode(self): - class TestException(exceptions.ClientException): - pass - - multibyte_unicode_string = u'\uff21\uff22\uff23' - e = TestException(message=multibyte_unicode_string) - - fixture = fixtures.StringStream('stdout') - self.useFixture(fixture) - with fixtures.MonkeyPatch('sys.stdout', fixture.stream): - print(e) - self.assertEqual(multibyte_unicode_string, - fixture.getDetails().get('stdout').as_text()) - - def test_exception_message_with_encoded_unicode(self): - class TestException(exceptions.ClientException): - pass - - multibyte_string = u'\uff21\uff22\uff23' - multibyte_binary = encodeutils.safe_encode(multibyte_string) - e = TestException(message=multibyte_binary) - self.assertEqual(multibyte_string, six.text_type(e)) diff --git a/tricircleclient/tests/unit/utils.py b/tricircleclient/tests/unit/utils.py deleted file mode 100644 index 113c40f..0000000 --- a/tricircleclient/tests/unit/utils.py +++ /dev/null @@ -1,188 +0,0 @@ -# Copyright 2017 Intel Corporation. -# -# 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 copy -from oslo_utils import timeutils -from oslo_utils import uuidutils -import testtools - -from tricircleclient.tests.unit import fakes - - -class ParserException(Exception): - pass - - -class TestCommand(testtools.TestCase): - - def setUp(self): - super(TestCommand, self).setUp() - # Build up a fake app - self.fake_stdout = fakes.FakeStdout() - self.fake_log = fakes.FakeLog() - self.app = fakes.FakeApp(self.fake_stdout, self.fake_log) - self.app.client_manager = fakes.FakeClientManager() - - def check_parser(self, cmd, args=[], verify_args=[]): - cmd_parser = cmd.get_parser('check_parser') - try: - parsed_args = cmd_parser.parse_args(args) - except SystemExit: - raise ParserException("Argument parse failed") - for attr, value in verify_args: - if attr: - self.assertIn(attr, parsed_args) - self.assertEqual(value, getattr(parsed_args, attr)) - return parsed_args - - -class TestCommandWithoutOptions(object): - - def test_without_options(self): - self.assertRaises(ParserException, self.check_parser, self.cmd) - - -class FakePod(object): - """Fake one or more Pods.""" - - @staticmethod - def create_single_pod(opts=None): - """Create a fake pod. - - :param opts:Dictionary of options to overwrite - :return: A dictionary with dc_name, pod_name, pod_id, - az_name, pod_az_name, region_name - """ - opts = opts or {} - # Set default options. - fake_pod = { - 'pod': { - 'dc_name': 'datacenter', - 'pod_az_name': 'pod', - 'pod_id': uuidutils.generate_uuid(), - 'az_name': 'availability_zone', - 'region_name': 'central_region', - } - } - - # Overwrite default options - fake_pod['pod'].update(opts) - return copy.deepcopy(fake_pod) - - @staticmethod - def create_multiple_pods(opts=None, count=2): - """Create a list of fake pods. - - :param opts: A dictionary of options to create pod - :param count: The number of pods to create - :return: A list of dictionaries with dc_name, pod_name, pod_id, - az_name, pod_az_name, region_name - """ - return [FakePod.create_single_pod(opts)['pod'] - for i in range(0, count)] - - -class FakeRouting(object): - """Fake one or more Routings.""" - - @staticmethod - def create_single_routing(opts=None): - """Create a fake routing. - - :param opts: Dictionary of options to overwrite - :return: A Dictionary with top_id, bottom_id, pod_id, - project_id, resource_type, id - """ - opts = opts or {} - # Set default options. - fake_routing = { - 'routing': { - 'top_id': uuidutils.generate_uuid(), - 'bottom_id': uuidutils.generate_uuid(), - 'pod_id': uuidutils.generate_uuid(), - 'project_id': uuidutils.generate_uuid(), - 'resource_type': 'network', - 'id': uuidutils.generate_uuid(), - 'created_at': str(timeutils.utcnow()), - 'updated_at': str(timeutils.utcnow()), - } - } - - # Overwrite default options - fake_routing['routing'].update(opts) - return copy.deepcopy(fake_routing) - - @staticmethod - def create_multiple_routings(opts=None, count=2): - """Create a list of fake routings. - - :param opts: A Dictionary of options to create routing - :param count: The number of routings to create - :return: A list of Dictionaries with top_id, bottom_id, pod_id, - project_id, resource_type, id - """ - return [FakeRouting.create_single_routing(opts)['routing'] - for i in range(0, count)] - - -class FakeJob(object): - """Fake one or more Jobs.""" - - @staticmethod - def create_single_job(opts=None): - """Create a fake job. - - :param opts: Dictionary of options to overwrite - :return: A Dictionary with type, project_id. optional parameters are: - router_id, network_id, pod_id, port_id, trunk_id, subnet_id, - portchain_id. Different job type needs different resources, they - are specified as optional parameters. - """ - opts = opts or {} - - # Set default options. - fake_job = { - 'job': { - 'id': uuidutils.generate_uuid(), - 'type': 'router_setup', - 'resource': { - 'pod_id': uuidutils.generate_uuid(), - 'router_id': uuidutils.generate_uuid(), - 'network_id': uuidutils.generate_uuid(), - }, - 'project_id': uuidutils.generate_uuid(), - 'status': 'NEW', - 'timestamp': str(timeutils.utcnow()), - } - } - - # Overwrite default options - fake_job['job'].update(opts) - return fake_job - - @staticmethod - def create_multiple_jobs(opts=None, count=2): - """Create a list of fake jobs. - - :param opts: A Dictionary of options to create job - :param count: The number of routings to create - :return: A list of Dictionaries with type, project_id and some - optional parameters. Optional paramaters are: - router_id, network_id, pod_id, port_id, trunk_id, subnet_id, - portchain_id. Different job type needs different resources, they - are specified as optional parameters. - """ - return [FakeJob.create_single_job(opts)['job'] - for i in range(0, count)] diff --git a/tricircleclient/tests/unit/v1/__init__.py b/tricircleclient/tests/unit/v1/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tricircleclient/tests/unit/v1/test_jobs_cli.py b/tricircleclient/tests/unit/v1/test_jobs_cli.py deleted file mode 100644 index 8ab755b..0000000 --- a/tricircleclient/tests/unit/v1/test_jobs_cli.py +++ /dev/null @@ -1,228 +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. - -from unittest import mock - -from tricircleclient import constants -from tricircleclient.tests.unit import utils -from tricircleclient.v1 import jobs_cli - - -class _TestJobCommand(utils.TestCommand): - - def setUp(self): - super(_TestJobCommand, self).setUp() - self.job_manager = self.app.client_manager.multiregion_networking.job - - -class TestCreateJob(_TestJobCommand, utils.TestCommandWithoutOptions): - - def setUp(self): - super(TestCreateJob, self).setUp() - self.cmd = jobs_cli.CreateJob(self.app, None) - - def test_create_all_options(self): - _job = utils.FakeJob.create_single_job() - arglist = [ - '--type', _job['job']['type'], - '--project_id', _job['job']['project_id'], - '--pod_id', _job['job']['resource']['pod_id'], - '--router_id', _job['job']['resource']['router_id'], - '--network_id', _job['job']['resource']['network_id'], - ] - verifylist = [ - ('type', _job['job']['type']), - ('project_id', _job['job']['project_id']), - ('pod_id', _job['job']['resource']['pod_id']), - ('router_id', _job['job']['resource']['router_id']), - ('network_id', _job['job']['resource']['network_id']), - ] - - self.job_manager.create = mock.Mock(return_value=_job) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(sorted(_job['job'].keys()), sorted(columns)) - self.assertEqual(sorted(_job['job'].values()), sorted(data)) - - -class TestShowJob(_TestJobCommand, utils.TestCommandWithoutOptions): - - def setUp(self): - super(TestShowJob, self).setUp() - self.cmd = jobs_cli.ShowJob(self.app, None) - - def test_show_a_single_job(self): - _job = utils.FakeJob.create_single_job() - arglist = [ - _job['job']['id'], - ] - verifylist = [ - ('job', _job['job']['id']), - ] - self.job_manager.get = mock.Mock(return_value=_job) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(sorted(_job['job'].keys()), sorted(columns)) - self.assertEqual(sorted(_job['job'].values()), sorted(data)) - - -class TestListJob(_TestJobCommand): - - def setUp(self): - super(TestListJob, self).setUp() - self.cmd = jobs_cli.ListJobs(self.app, None) - - def test_list(self): - _jobs = utils.FakeJob.create_multiple_jobs() - self.job_manager.list = mock.Mock(return_value={'jobs': _jobs}) - parsed_args = self.check_parser(self.cmd) - columns, data = (self.cmd.take_action(parsed_args)) - self.assertEqual(sorted(constants.COLUMNS_REMAP.values()), - sorted(columns)) - self.assertEqual(len(_jobs), len(data)) - self.assertEqual( - sorted([tuple(o[k] for k in constants.COLUMNS) for o in _jobs]), - sorted(data)) - - def test_list_with_filters(self): - _job = utils.FakeJob.create_single_job() - _job = _job['job'] - - # we filter the jobs by the following fields: project ID, type, status. - # given values of _job, then only single item _job is retrieved. - arglist = [ - '--project-id', _job['project_id'], - '--type', _job['type'], - '--status', _job['status'], - ] - verifylist = [ - ('project_id', _job['project_id']), - ('type', _job['type']), - ('status', _job['status'].lower()), - ] - - self.job_manager.list = mock.Mock(return_value={'jobs': [_job]}) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(1, len(data)) - self.assertEqual(sorted(constants.COLUMNS_REMAP.values()), - sorted(columns)) - - # lower case of job status - arglist = [ - '--status', _job['status'].lower(), - ] - verifylist = [ - ('status', _job['status'].lower()), - ] - - self.job_manager.list = mock.Mock(return_value={'jobs': [_job]}) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(1, len(data)) - self.assertEqual(sorted(constants.COLUMNS_REMAP.values()), - sorted(columns)) - - def test_invalid_job_status_filter(self): - # unrecognizable job status filter - arglist = [ - '--status', 'new_1', - ] - verifylist = [] - self.assertRaises(utils.ParserException, self.check_parser, - self.cmd, arglist, verifylist) - - def test_list_with_pagination(self): - number_of_jobs = 4 - limit = number_of_jobs - 2 - _jobs = utils.FakeJob.create_multiple_jobs(count=number_of_jobs) - - # test list operation with pagination - arglist = [ - '--limit', str(limit), - ] - verifylist = [ - ('limit', limit), - ] - - self.job_manager.list = mock.Mock(return_value={"jobs": _jobs[:limit]}) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(limit, len(data)) - self.assertEqual(sorted(constants.COLUMNS_REMAP.values()), - sorted(columns)) - - # test list operation with pagination and marker - arglist = [ - '--limit', str(limit), - '--marker', _jobs[0]['id'], - ] - verifylist = [ - ('limit', limit), - ('marker', _jobs[0]['id']), - ] - - self.job_manager.list = mock.Mock( - return_value={"jobs": _jobs[1:limit+1]}) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(limit, len(data)) - self.assertEqual(sorted(constants.COLUMNS_REMAP.values()), - sorted(columns)) - - -class TestDeleteJob(_TestJobCommand, utils.TestCommandWithoutOptions): - - def setUp(self): - super(TestDeleteJob, self).setUp() - self.cmd = jobs_cli.DeleteJob(self.app, None) - - def test_delete_job(self): - _job = utils.FakeJob.create_single_job() - arglist = [ - _job['job']['id'], - ] - verifylist = [ - ('job', [_job['job']['id']]), - ] - self.job_manager.delete = mock.Mock(return_value=None) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - result = self.cmd.take_action(parsed_args) - - self.assertIsNone(result) - - -class TestRedoJob(_TestJobCommand, utils.TestCommandWithoutOptions): - - def setUp(self): - super(TestRedoJob, self).setUp() - self.cmd = jobs_cli.RedoJob(self.app, None) - - def test_redo_job(self): - _job = utils.FakeJob.create_single_job() - arglist = [ - _job['job']['id'], - ] - verifylist = [ - ('job', _job['job']['id']), - ] - self.job_manager.update = mock.Mock(return_value=None) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - result = self.cmd.take_action(parsed_args) - - self.assertIsNone(result) diff --git a/tricircleclient/tests/unit/v1/test_pods_cli.py b/tricircleclient/tests/unit/v1/test_pods_cli.py deleted file mode 100644 index 049a96b..0000000 --- a/tricircleclient/tests/unit/v1/test_pods_cli.py +++ /dev/null @@ -1,178 +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. - -from unittest import mock - -from tricircleclient.tests.unit import utils -from tricircleclient.v1 import pods_cli - - -class _TestPodCommand(utils.TestCommand): - - def setUp(self): - super(_TestPodCommand, self).setUp() - self.pod_manager = self.app.client_manager.multiregion_networking.pod - - -class TestCreatePod(_TestPodCommand, utils.TestCommandWithoutOptions): - - def setUp(self): - super(TestCreatePod, self).setUp() - self.cmd = pods_cli.CreatePod(self.app, None) - - def test_create_all_options(self): - _pod = utils.FakePod.create_single_pod() - arglist = [ - '--region-name', _pod['pod']['region_name'], - '--availability-zone', _pod['pod']['az_name'], - '--pod-availability-zone', _pod['pod']['pod_az_name'], - '--data-center', _pod['pod']['dc_name'] - ] - verifylist = [ - ('region_name', _pod['pod']['region_name']), - ('availability_zone', _pod['pod']['az_name']), - ('pod_availability_zone', _pod['pod']['pod_az_name']), - ('data_center', _pod['pod']['dc_name']), - ] - self.pod_manager.create = mock.Mock(return_value=_pod) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(sorted(_pod['pod'].keys()), sorted(columns)) - self.assertEqual(sorted(_pod['pod'].values()), sorted(data)) - - def test_create_local_region_with_availability_zone(self): - keys = ["dc_name", "pod_az_name"] - _pod = utils.FakePod.create_single_pod({key: " " for key in keys}) - arglist = [ - '--region-name', _pod['pod']['region_name'], - '--availability-zone', _pod['pod']['az_name'] - ] - verifylist = [ - ('region_name', _pod['pod']['region_name']), - ('availability_zone', _pod['pod']['az_name']), - ] - self.pod_manager.create = mock.Mock(return_value=_pod) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(sorted(_pod['pod'].keys()), sorted(columns)) - self.assertEqual(sorted(_pod['pod'].values()), sorted(data)) - - def test_create_central_region(self): - keys = ["dc_name", "pod_az_name", "az_name"] - _pod = utils.FakePod.create_single_pod({key: " " for key in keys}) - arglist = [ - '--region-name', _pod['pod']['region_name'] - ] - verifylist = [ - ('region_name', _pod['pod']['region_name']), - ] - self.pod_manager.create = mock.Mock(return_value=_pod) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(sorted(_pod['pod'].keys()), sorted(columns)) - self.assertEqual(sorted(_pod['pod'].values()), sorted(data)) - - -class TestShowPod(_TestPodCommand, utils.TestCommandWithoutOptions): - - def setUp(self): - super(TestShowPod, self).setUp() - self.cmd = pods_cli.ShowPod(self.app, None) - - def test_show_valid_pod(self): - _pod = utils.FakePod.create_single_pod() - arglist = [ - _pod['pod']['pod_id'], - ] - verifylist = [ - ("pod", _pod['pod']['pod_id']), - ] - self.pod_manager.get = mock.Mock(return_value=_pod) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(sorted(_pod['pod'].keys()), sorted(columns)) - self.assertEqual(sorted(_pod['pod'].values()), sorted(data)) - - def test_show_valid_pod_with_empty_fields(self): - keys = ["dc_name", "pod_az_name", "az_name"] - _pod = utils.FakePod.create_single_pod({key: " " for key in keys}) - arglist = [ - _pod['pod']['pod_id'], - ] - verifylist = [ - ("pod", _pod['pod']['pod_id']), - ] - self.pod_manager.get = mock.Mock(return_value=_pod) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(sorted(_pod['pod'].keys()), sorted(columns)) - self.assertEqual(sorted(_pod['pod'].values()), sorted(data)) - - -class TestListPod(_TestPodCommand): - - columns = [ - 'ID', - 'Region Name', - ] - - def setUp(self): - super(TestListPod, self).setUp() - self.cmd = pods_cli.ListPods(self.app, None) - - def test_list(self): - _pods = utils.FakePod.create_multiple_pods() - for pod in _pods: - pod.pop('dc_name') - pod.pop('pod_az_name') - pod.pop('az_name') - self.pod_manager.list = mock.Mock( - return_value={'pods': _pods}) - parsed_args = self.check_parser(self.cmd) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(self.columns, sorted(columns)) - self.assertEqual(len(_pods), len(data)) - - -class TestDeletePod(_TestPodCommand, utils.TestCommandWithoutOptions): - - def setUp(self): - super(TestDeletePod, self).setUp() - self.cmd = pods_cli.DeletePod(self.app, None) - - def test_delete_pod(self): - arglist = [utils.FakePod.create_single_pod()['pod']['pod_id']] - verifylist = [ - ('pod', arglist), - ] - self.pod_manager.delete = mock.Mock( - return_value=None) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - result = self.cmd.take_action(parsed_args) - self.assertIsNone(result) - - def test_delete_multiple_pod(self): - arglist = [pod['pod_id'] for pod in - utils.FakePod.create_multiple_pods()] - verifylist = [ - ('pod', arglist), - ] - self.pod_manager.delete = mock.Mock(return_value=None) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - result = self.cmd.take_action(parsed_args) - self.assertIsNone(result) diff --git a/tricircleclient/tests/unit/v1/test_routings_cli.py b/tricircleclient/tests/unit/v1/test_routings_cli.py deleted file mode 100644 index acfba44..0000000 --- a/tricircleclient/tests/unit/v1/test_routings_cli.py +++ /dev/null @@ -1,232 +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. - -from unittest import mock - -from tricircleclient.tests.unit import utils -from tricircleclient.v1 import routings_cli - - -class _TestRoutingCommand(utils.TestCommand): - - def setUp(self): - super(_TestRoutingCommand, self).setUp() - self.routing_manager = \ - self.app.client_manager.multiregion_networking.routing - - -class TestCreateRouting(_TestRoutingCommand, utils.TestCommandWithoutOptions): - - def setUp(self): - super(TestCreateRouting, self).setUp() - self.cmd = routings_cli.CreateRouting(self.app, None) - - def test_create_all_options(self): - _routing = utils.FakeRouting.create_single_routing() - arglist = [ - '--top-id', _routing['routing']['top_id'], - '--bottom-id', _routing['routing']['bottom_id'], - '--pod-id', _routing['routing']['pod_id'], - '--project-id', _routing['routing']['project_id'], - '--resource-type', _routing['routing']['resource_type'], - ] - verifylist = [ - ('top_id', _routing['routing']['top_id']), - ('bottom_id', _routing['routing']['bottom_id']), - ('pod_id', _routing['routing']['pod_id']), - ('project_id', _routing['routing']['project_id']), - ('resource_type', _routing['routing']['resource_type']), - ] - self.routing_manager.create = mock.Mock(return_value=_routing) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(sorted(_routing['routing'].keys()), sorted(columns)) - self.assertEqual(sorted(_routing['routing'].values()), sorted(data)) - - -class TestShowRouting(_TestRoutingCommand, utils.TestCommandWithoutOptions): - - def setUp(self): - super(TestShowRouting, self).setUp() - self.cmd = routings_cli.ShowRouting(self.app, None) - - def test_show_valid_routing(self): - _routing = utils.FakeRouting.create_single_routing() - arglist = [ - _routing['routing']['id'], - ] - verifylist = [ - ('routing', _routing['routing']['id']), - ] - self.routing_manager.get = mock.Mock(return_value=_routing) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(sorted(_routing['routing'].keys()), sorted(columns)) - self.assertEqual(sorted(_routing['routing'].values()), sorted(data)) - - -class TestListRouting(_TestRoutingCommand): - - columns = [ - 'ID', - 'Pod', - 'Resource Type', - 'Top' - ] - - def setUp(self): - super(TestListRouting, self).setUp() - self.cmd = routings_cli.ListRoutings(self.app, None) - - def test_list(self): - _routings = utils.FakeRouting.create_multiple_routings() - - for routing in _routings: - for key in ('bottom_id', 'project_id'): - routing.pop(key) - - self.routing_manager.list = mock.Mock( - return_value={'routings': _routings}) - parsed_args = self.check_parser(self.cmd) - columns, data = (self.cmd.take_action(parsed_args)) - self.assertEqual(sorted(self.columns), sorted(columns)) - self.assertEqual(len(_routings), len(data)) - - def test_list_with_filters(self): - _routing = utils.FakeRouting.create_single_routing() - _routing = _routing['routing'] - - # we filter the routings by the following fields - # given values of _routing, then only single item _routing - # is retrieved. - arglist = [ - '--top-id', _routing['top_id'], - '--bottom-id', _routing['bottom_id'], - '--pod-id', _routing['pod_id'], - '--project-id', _routing['project_id'], - '--resource-type', _routing['resource_type'], - '--created-at', _routing['created_at'], - '--updated-at', _routing['updated_at'], - ] - verifylist = [ - ('top_id', _routing['top_id']), - ('bottom_id', _routing['bottom_id']), - ('pod_id', _routing['pod_id']), - ('project_id', _routing['project_id']), - ('resource_type', _routing['resource_type']), - ('created_at', _routing['created_at']), - ('updated_at', _routing['updated_at']), - ] - for key in ('bottom_id', 'project_id'): - _routing.pop(key) - - self.routing_manager.list = mock.Mock( - return_value={'routings': [_routing]}) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(self.columns, sorted(columns)) - self.assertEqual(1, len(data)) - - def test_throw_exception(self): - arglist = [ - '--resource-type', 'fake_resource_type', - ] - verifylist = [] - self.assertRaises(utils.ParserException, self.check_parser, - self.cmd, arglist, verifylist) - - def test_list_with_pagination(self): - _routings = utils.FakeRouting.create_multiple_routings(count=3) - arglist = [ - '--limit', '2', - '--marker', _routings[0]['id'], - ] - verifylist = [ - ('limit', 2), - ('marker', _routings[0]['id']), - ] - for routing in _routings: - for key in ('bottom_id', 'project_id'): - routing.pop(key) - - self.routing_manager.list = mock.Mock( - return_value={'routings': _routings[1:]}) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - columns, data = (self.cmd.take_action(parsed_args)) - - self.assertEqual(sorted(self.columns), sorted(columns)) - self.assertEqual(2, len(data)) - - -class TestDeleteRouting(_TestRoutingCommand, utils.TestCommandWithoutOptions): - - def setUp(self): - super(TestDeleteRouting, self).setUp() - self.cmd = routings_cli.DeleteRouting(self.app, None) - - def test_delete_routing(self): - _routings = utils.FakeRouting.create_multiple_routings(count=2) - - arglist = [ - _routings[0]['id'], - _routings[1]['id'], - ] - verifylist = [ - ('routing', [_routings[0]['id'], _routings[1]['id']]), - ] - self.routing_manager.delete = mock.Mock(return_value=None) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - result = self.cmd.take_action(parsed_args) - - self.assertIsNone(result) - - def test_delete_multiple_routing(self): - arglist = [routing['id'] for routing in - utils.FakeRouting.create_multiple_routings()] - verifylist = [ - ('routing', arglist), - ] - self.routing_manager.delete = mock.Mock(return_value=None) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - result = self.cmd.take_action(parsed_args) - - self.assertIsNone(result) - - -class TestUpdateRouting(_TestRoutingCommand, utils.TestCommandWithoutOptions): - - def setUp(self): - super(TestUpdateRouting, self).setUp() - self.cmd = routings_cli.UpdateRouting(self.app, None) - - def test_update_all_options(self): - _routing = utils.FakeRouting.create_single_routing() - arglist = [ - '--top-id', _routing['routing']['top_id'], - '--bottom-id', _routing['routing']['bottom_id'], - '--project-id', _routing['routing']['project_id'], - '--resource-type', _routing['routing']['resource_type'], - _routing['routing']['pod_id'], - ] - verifylist = [ - ('top_id', _routing['routing']['top_id']), - ('bottom_id', _routing['routing']['bottom_id']), - ('project_id', _routing['routing']['project_id']), - ('resource_type', _routing['routing']['resource_type']), - ('routing', _routing['routing']['pod_id']), - ] - self.routing_manager.update = mock.Mock(return_value=_routing) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.cmd.take_action(parsed_args) diff --git a/tricircleclient/utils.py b/tricircleclient/utils.py deleted file mode 100644 index 61a2c91..0000000 --- a/tricircleclient/utils.py +++ /dev/null @@ -1,26 +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. - - -def prepare_column_headers(columns, remap=None): - remap = remap if remap else {} - new_columns = [] - for c in columns: - new_columns.append(remap[c].replace('_', ' ')) - - return new_columns - - -def list2cols(cols, objs, headers=None): - headers = headers if headers else cols - return headers, [tuple([o[k] for k in cols]) - for o in objs] diff --git a/tricircleclient/v1/__init__.py b/tricircleclient/v1/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tricircleclient/v1/base.py b/tricircleclient/v1/base.py deleted file mode 100644 index 75038a4..0000000 --- a/tricircleclient/v1/base.py +++ /dev/null @@ -1,48 +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. - - -class Manager(object): - DEFAULT_HEADERS = { - "Accept": "application/json, */*", - } - - def __init__(self, client): - self.client = client - - def _set_default_headers(self, kwargs): - headers = kwargs.get('headers', {}) - for k, v in self.DEFAULT_HEADERS.items(): - if k not in headers: - headers[k] = v - kwargs['headers'] = headers - return kwargs - - def _get(self, *args, **kwargs): - self._set_default_headers(kwargs) - return self.client.api.get(*args, **kwargs) - - def _post(self, *args, **kwargs): - self._set_default_headers(kwargs) - return self.client.api.post(*args, **kwargs) - - def _put(self, *args, **kwargs): - self._set_default_headers(kwargs) - return self.client.api.put(*args, **kwargs) - - def _patch(self, *args, **kwargs): - self._set_default_headers(kwargs) - return self.client.api.patch(*args, **kwargs) - - def _delete(self, *args, **kwargs): - self._set_default_headers(kwargs) - return self.client.api.delete(*args, **kwargs) diff --git a/tricircleclient/v1/client.py b/tricircleclient/v1/client.py deleted file mode 100644 index c5e7477..0000000 --- a/tricircleclient/v1/client.py +++ /dev/null @@ -1,32 +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. - -from tricircleclient import client -from tricircleclient.v1 import jobs -from tricircleclient.v1 import pods -from tricircleclient.v1 import routings - - -class Client(object): - """Client for the Tricircle v1 API. - - :param string session: session - :type session: :py:class:`keystoneauth.adapter.Adapter` - """ - - def __init__(self, session=None, service_type='tricircle', **kwargs): - """Initialize a new client for the Tricircle v1 API.""" - self.api = client.SessionClient(session, service_type=service_type, - **kwargs) - self.pod = pods.PodManager(self) - self.routing = routings.RoutingManager(self) - self.job = jobs.JobManager(self) diff --git a/tricircleclient/v1/jobs.py b/tricircleclient/v1/jobs.py deleted file mode 100644 index 5a9d69b..0000000 --- a/tricircleclient/v1/jobs.py +++ /dev/null @@ -1,47 +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. - -from oslo_serialization import jsonutils - -from tricircleclient.v1 import base - - -class JobManager(base.Manager): - - def list(self, path): - """Get a list of jobs.""" - return self._get( - path, - headers={'Content-Type': "application/json"}).json() - - def create(self, job): - """Create a job.""" - return self._post( - '/jobs', headers={'Content-Type': "application/json"}, - data=jsonutils.dumps(job)).json() - - def get(self, id): - """Get information about a job.""" - return self._get( - '/jobs/%s' % id, - headers={'Content-Type': "application/json"}).json() - - def delete(self, id): - """Delete a job.""" - self._delete('/jobs/%s' % id) - - def update(self, id): - """Redo a job.""" - self._put('/jobs/%s' % id, - headers={'Content-Type': "application/json"}, - data=None).json() diff --git a/tricircleclient/v1/jobs_cli.py b/tricircleclient/v1/jobs_cli.py deleted file mode 100644 index a77fc41..0000000 --- a/tricircleclient/v1/jobs_cli.py +++ /dev/null @@ -1,260 +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. - -from osc_lib.command import command -from oslo_log import log as logging -from six.moves.urllib import parse - -from tricircleclient import constants -from tricircleclient import utils - - -def _job_from_args(parsed_args): - # necessary parameters - data = {'type': parsed_args.type, - 'project_id': parsed_args.project_id, - } - - # optional parameters vary with job type - resources = {} - for id in constants.job_resource_map[data['type']]: - resources[id] = getattr(parsed_args, id, None) - data['resource'] = resources - - return {'job': data} - - -def _add_pagination_argument(parser): - parser.add_argument( - '--limit', - dest='limit', metavar="", type=int, - help="Maximum number of jobs to return", - default=None) - - -def _add_marker_argument(parser): - parser.add_argument( - '--marker', - dest='marker', metavar="", type=str, - help="ID of last job in previous page, jobs after marker will be " - "returned. Display all jobs if not specified.", - default=None) - - -def _add_filtering_arguments(parser): - # available filtering fields: project ID, type, status - parser.add_argument( - '--project-id', - dest='project_id', metavar="", type=str, - help="ID of a project object in Keystone", - default=None) - parser.add_argument( - '--type', - dest='type', metavar="", type=str, - choices=constants.job_resource_map.keys(), - help="Job type", - default=None) - parser.add_argument( - '--status', - dest='status', metavar="", type=lambda str: str.lower(), - choices=['new', 'running', 'success', 'fail'], - help="Execution status of the job. It's case-insensitive", - default=None) - - -def _add_search_options(parsed_args): - search_opts = {} - for key in ('limit', 'marker', 'project_id', 'type', 'status'): - value = getattr(parsed_args, key, None) - if value is not None: - search_opts[key] = value - return search_opts - - -def _prepare_query_string(params): - """Convert dict params to query string""" - params = sorted(params.items(), key=lambda x: x[0]) - return '?%s' % parse.urlencode(params) if params else '' - - -def expand_job_resource(job): - # because job['resource'] is a dict value, so we should - # expand its values and let them show as other fields in the - # same level. - for id in constants.job_resource_map[job['type']]: - job[id] = job['resource'][id] - job.pop('resource') - return job - - -class ListJobs(command.Lister): - """List Jobs""" - log = logging.getLogger(__name__ + ".ListJobs") - - path = '/jobs' - - def get_parser(self, prog_name): - parser = super(ListJobs, self).get_parser(prog_name) - - _add_pagination_argument(parser) - _add_marker_argument(parser) - _add_filtering_arguments(parser) - - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - - # add pagination/marker/filter to list operation - search_opts = _add_search_options(parsed_args) - self.path += _prepare_query_string(search_opts) - - data = client.job.list(self.path) - column_headers = utils.prepare_column_headers(constants.COLUMNS, - constants.COLUMNS_REMAP) - return utils.list2cols(constants.COLUMNS, data['jobs'], column_headers) - - -class CreateJob(command.ShowOne): - """Create a Job""" - - log = logging.getLogger(__name__ + ".CreateJob") - - def get_parser(self, prog_name): - parser = super(CreateJob, self).get_parser(prog_name) - - # as resource is a compound attribute, so we expand its fields - # and list them as optional parameters. If new resources are - # provisioned, they should be added here. - parser.add_argument( - '--type', - metavar="", - required=True, - help="Job type", - ) - parser.add_argument( - '--project_id', - metavar="", - required=True, - help="ID of a project object in Keystone", - ) - parser.add_argument( - '--router_id', - metavar="", - help="ID of a router", - ) - parser.add_argument( - '--network_id', - metavar="", - help="ID of a network", - ) - parser.add_argument( - '--pod_id', - metavar="", - help="ID of a pod", - ) - parser.add_argument( - '--port_id', - metavar="", - help="ID of a port", - ) - parser.add_argument( - '--trunk_id', - metavar="", - help="ID of a trunk", - ) - parser.add_argument( - '--subnet_id', - metavar="", - help="ID of a subnet", - ) - parser.add_argument( - '--portchain_id', - metavar="", - help="ID of a port chain", - ) - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - data = client.job.create(_job_from_args(parsed_args)) - - if 'job' in data.keys(): - return self.dict2columns(expand_job_resource(data['job'])) - - -class ShowJob(command.ShowOne): - """Display Job details.""" - log = logging.getLogger(__name__ + ".ShowJob") - - def get_parser(self, prog_name): - parser = super(ShowJob, self).get_parser(prog_name) - parser.add_argument( - "job", - metavar="", - help="ID of the job to display", - ) - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - data = client.job.get(parsed_args.job) - - if 'job' in data.keys(): - return self.dict2columns(expand_job_resource(data['job'])) - - -class DeleteJob(command.Command): - """Delete a Job.""" - - log = logging.getLogger(__name__ + ".DeleteJob") - - def get_parser(self, prog_name): - parser = super(DeleteJob, self).get_parser(prog_name) - parser.add_argument( - "job", - metavar="", - nargs="+", - help="ID(s) of the job(s) to delete", - ) - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - for job_id in parsed_args.job: - client.job.delete(job_id) - - -class RedoJob(command.Command): - """Redo a Job.""" - - log = logging.getLogger(__name__ + ".RedoJob") - - def get_parser(self, prog_name): - parser = super(RedoJob, self).get_parser(prog_name) - - parser.add_argument( - 'job', - metavar="", - help="ID of the job to redo", - ) - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - client.job.update(parsed_args.job) diff --git a/tricircleclient/v1/pods.py b/tricircleclient/v1/pods.py deleted file mode 100644 index d0b5d73..0000000 --- a/tricircleclient/v1/pods.py +++ /dev/null @@ -1,41 +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. - -from oslo_serialization import jsonutils - -from tricircleclient.v1 import base - - -class PodManager(base.Manager): - - def list(self, search_opts=None): - """Get a list of Pods.""" - return self._get( - '/pods', - headers={'Content-Type': "application/json"}).json() - - def create(self, pod): - """Create a Pod.""" - return self._post( - '/pods', headers={'Content-Type': "application/json"}, - data=jsonutils.dumps(pod)).json() - - def get(self, pod): - """Get information about a Pod.""" - return self._get( - '/pods/%s' % pod, - headers={'Content-Type': "application/json"}).json() - - def delete(self, pod): - """Delete a Pod.""" - self._delete('/pods/%s' % pod) diff --git a/tricircleclient/v1/pods_cli.py b/tricircleclient/v1/pods_cli.py deleted file mode 100644 index 392be2e..0000000 --- a/tricircleclient/v1/pods_cli.py +++ /dev/null @@ -1,136 +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. - -from osc_lib.command import command -from oslo_log import log as logging - -from tricircleclient import utils - - -class ListPods(command.Lister): - """Lists pods""" - - COLS = ('pod_id', 'region_name') - - log = logging.getLogger(__name__ + ".ListPods") - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - data = client.pod.list() - remap = {'pod_id': 'ID', - 'region_name': 'Region Name', - 'az_name': 'Availability Zone', - 'dc_name': 'Data Center'} - column_headers = utils.prepare_column_headers(self.COLS, - remap) - - return utils.list2cols( - self.COLS, data['pods'], column_headers) - - -class CreatePod(command.ShowOne): - """Creates pod""" - - log = logging.getLogger(__name__ + ".CreatePod") - - @staticmethod - def _pod_from_args(parsed_args): - result = {} - result['region_name'] = parsed_args.region_name - if parsed_args.availability_zone: - result['az_name'] = parsed_args.availability_zone - if parsed_args.pod_availability_zone: - result['pod_az_name'] = parsed_args.pod_availability_zone - if parsed_args.data_center: - result['dc_name'] = parsed_args.data_center - return {'pod': result} - - def get_parser(self, prog_name): - parser = super(CreatePod, self).get_parser(prog_name) - - parser.add_argument( - '--region-name', - metavar="", - required=True, - help="Region name registered in Keystone", - ) - parser.add_argument( - '--availability-zone', - metavar="", - help="Name of the Availability Zone", - ) - parser.add_argument( - '--pod-availability-zone', - metavar="", - help="Name of the Availability Zone forwarded to local Neutron", - ) - parser.add_argument( - '--data-center', - metavar="", - help="Name of the Data Center", - ) - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - data = client.pod.create(self._pod_from_args(parsed_args)) - return self.dict2columns(data['pod']) - - -class ShowPod(command.ShowOne): - """Display pod details.""" - - log = logging.getLogger(__name__ + ".ShowPod") - - def get_parser(self, prog_name): - parser = super(ShowPod, self).get_parser(prog_name) - parser.add_argument( - "pod", - metavar="", - help="Id of the pod to display", - ) - - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - data = client.pod.get(parsed_args.pod) - - if 'pod' in data.keys(): - return self.dict2columns(data['pod']) - - -class DeletePod(command.Command): - """Deletes Pod.""" - - log = logging.getLogger(__name__ + ".DeletePod") - - def get_parser(self, prog_name): - parser = super(DeletePod, self).get_parser(prog_name) - parser.add_argument( - "pod", - metavar="", - nargs="+", - help="ID(s) of the pod(s) to delete", - ) - - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - for pod_id in parsed_args.pod: - client.pod.delete(pod_id) diff --git a/tricircleclient/v1/routings.py b/tricircleclient/v1/routings.py deleted file mode 100644 index 363d8ac..0000000 --- a/tricircleclient/v1/routings.py +++ /dev/null @@ -1,47 +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. - -from oslo_serialization import jsonutils - -from tricircleclient.v1 import base - - -class RoutingManager(base.Manager): - - def list(self, path): - """Get a list of Resource Routings.""" - return self._get( - path, - headers={'Content-Type': "application/json"}).json() - - def create(self, routing): - """Create a Resource Routing.""" - return self._post( - '/routings', headers={'Content-Type': "application/json"}, - data=jsonutils.dumps(routing)).json() - - def get(self, routing): - """Get information about a Resource Routing.""" - return self._get( - '/routings/%s' % routing, - headers={'Content-Type': "application/json"}).json() - - def delete(self, routing): - """Delete a Resource Routing.""" - self._delete('/routings/%s' % routing) - - def update(self, routing): - """Update a Resource Routing.""" - self._put('/routings/%s' % routing['routing'].pop('id'), - headers={'Content-Type': "application/json"}, - data=jsonutils.dumps(routing)).json() diff --git a/tricircleclient/v1/routings_cli.py b/tricircleclient/v1/routings_cli.py deleted file mode 100644 index 9c9e368..0000000 --- a/tricircleclient/v1/routings_cli.py +++ /dev/null @@ -1,290 +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. - -from osc_lib.command import command -from oslo_log import log as logging -from six.moves.urllib import parse - -from tricircleclient import utils - - -def _routing_from_args(parsed_args): - data = {'top_id': parsed_args.top_id, - 'bottom_id': parsed_args.bottom_id, - 'pod_id': parsed_args.pod_id, - 'project_id': parsed_args.project_id, - 'resource_type': parsed_args.resource_type, - 'id': getattr(parsed_args, 'routing', None), - } - result = {} - result.update((k, v) for k, v in data.items() if v) - return {'routing': result} - - -def _add_pagination_argument(parser): - parser.add_argument( - '--limit', - dest='limit', metavar="", type=int, - help="Maximum number of routings to return", - default=None) - - -def _add_marker_argument(parser): - parser.add_argument( - '--marker', - dest='marker', metavar="", type=str, - help="ID of last routing in previous page, routings after marker " - "will be returned. Display all routings if not specified.", - default=None) - - -def _add_filtering_arguments(parser): - parser.add_argument( - '--routing', - dest='routing', metavar="", type=int, - help="ID of a routing", - default=None) - parser.add_argument( - '--top-id', - dest='top_id', metavar="", type=str, - help="Resource id on Central Neutron", - default=None) - parser.add_argument( - '--bottom-id', - dest='bottom_id', metavar="", type=str, - help="Resource id on Local Neutron", - default=None) - parser.add_argument( - '--pod-id', - dest='pod_id', metavar="", type=str, - help="ID of a pod", - default=None) - parser.add_argument( - '--project-id', - dest='project_id', metavar="", type=str, - help="ID of a project object in Keystone", - default=None) - parser.add_argument( - '--resource-type', - dest='resource_type', metavar="", type=str, - choices=['network', 'subnet', 'port', 'router', 'security_group', - 'trunk', 'port_pair', 'port_pair_group', 'flow_classifier', - 'port_chain'], - help="Available resource types", - default=None) - parser.add_argument( - '--created-at', - dest='created_at', metavar="", type=str, - help="Create time of the resource routing", - default=None) - parser.add_argument( - '--updated-at', - dest='updated_at', metavar="", type=str, - help="Update time of the resource routing", - default=None) - - -def _add_search_options(parsed_args): - search_opts = {} - for key in ('limit', 'marker', 'id', 'top_id', 'bottom_id', 'pod_id', - 'project_id', 'resource_type', 'created_at', 'updated_at'): - value = getattr(parsed_args, key, None) - if value is not None: - search_opts[key] = value - return search_opts - - -def _prepare_query_string(params): - """Convert dict params to query string""" - params = sorted(params.items(), key=lambda x: x[0]) - return '?%s' % parse.urlencode(params) if params else '' - - -class ListRoutings(command.Lister): - """Lists Routings""" - - COLS = ('id', 'pod_id', 'resource_type', 'top_id') - path = '/routings' - - log = logging.getLogger(__name__ + ".ListRoutings") - - def get_parser(self, prog_name): - parser = super(ListRoutings, self).get_parser(prog_name) - - _add_pagination_argument(parser) - _add_marker_argument(parser) - _add_filtering_arguments(parser) - - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - - # add pagination/marker/filter to list operation - search_opts = _add_search_options(parsed_args) - self.path += _prepare_query_string(search_opts) - - data = client.routing.list(self.path) - remap = {'resource_type': 'Resource Type', - 'pod_id': 'Pod', - 'id': 'ID', - 'top_id': 'Top', - } - column_headers = utils.prepare_column_headers(self.COLS, - remap) - return utils.list2cols( - self.COLS, data['routings'], column_headers) - - -class CreateRouting(command.ShowOne): - """Creates a Resource Routing""" - - log = logging.getLogger(__name__ + ".CreateRouting") - - def get_parser(self, prog_name): - parser = super(CreateRouting, self).get_parser(prog_name) - - parser.add_argument( - '--top-id', - metavar="", - required=True, - help="Resource id on Central Neutron", - ) - parser.add_argument( - '--bottom-id', - metavar="", - required=True, - help="Resource id on Local Neutron", - ) - parser.add_argument( - '--pod-id', - metavar="", - required=True, - help="ID of a pod", - ) - parser.add_argument( - '--project-id', - metavar="", - required=True, - help="ID of a project object in Keystone", - ) - parser.add_argument( - '--resource-type', - metavar="", - choices=['network', 'subnet', 'port', 'router', 'security_group'], - required=True, - help="Available resource types", - ) - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - data = client.routing.create(_routing_from_args(parsed_args)) - - return self.dict2columns(data['routing']) - - -class ShowRouting(command.ShowOne): - """Display Routing Resource details.""" - - log = logging.getLogger(__name__ + ".ShowRouting") - - def get_parser(self, prog_name): - parser = super(ShowRouting, self).get_parser(prog_name) - parser.add_argument( - "routing", - metavar="", - help="ID of the routing resource to display", - ) - - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - data = client.routing.get(parsed_args.routing) - - if 'routing' in data.keys(): - return self.dict2columns(data['routing']) - - -class DeleteRouting(command.Command): - """Deletes Routing Resource.""" - - log = logging.getLogger(__name__ + ".DeleteRouting") - - def get_parser(self, prog_name): - parser = super(DeleteRouting, self).get_parser(prog_name) - parser.add_argument( - "routing", - metavar="", - nargs="+", - help="ID(s) of the routing resource(s) to delete", - ) - - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - for routing_id in parsed_args.routing: - client.routing.delete(routing_id) - - -class UpdateRouting(command.Command): - """Updates a Routing Resource.""" - - log = logging.getLogger(__name__ + ".UpdateRouting") - - def get_parser(self, prog_name): - parser = super(UpdateRouting, self).get_parser(prog_name) - - parser.add_argument( - '--top-id', - metavar="", - help="Resource id on Central Neutron", - ) - parser.add_argument( - '--bottom-id', - metavar="", - help="Resource id on Local Neutron", - ) - parser.add_argument( - '--pod-id', - metavar="", - help="ID of a pod", - ) - parser.add_argument( - '--project-id', - metavar="", - help="ID of a project object in Keystone", - ) - parser.add_argument( - '--resource-type', - metavar="", - choices=['network', 'subnet', 'port', 'router', 'security_group'], - help="Available resource types", - ) - parser.add_argument( - "routing", - metavar="", - help="ID of the routing resource to update", - ) - return parser - - def take_action(self, parsed_args): - self.log.debug("take_action(%s)" % parsed_args) - client = self.app.client_manager.multiregion_networking - client.routing.update(_routing_from_args(parsed_args)) diff --git a/tricircleclient/version.py b/tricircleclient/version.py deleted file mode 100644 index 0f247e3..0000000 --- a/tricircleclient/version.py +++ /dev/null @@ -1,19 +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 pbr.version - - -__version__ = pbr.version.VersionInfo( - 'python-tricircleclient').version_string()