From f6e436ea5fc6cefb49aa8169f48a6aa3a5a2eb15 Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Mon, 17 Apr 2017 21:17:47 +0200 Subject: [PATCH] Retire repo This repo was created by accident, use deb-python-saharaclient instead. Depends-On: I2c2e6218cce314225ba956db4a21f1494212c8d3 Needed-By: I1ac1a06931c8b6dd7c2e73620a0302c29e605f03 Change-Id: I81894aea69b9d09b0977039623c26781093a397a --- .coveragerc | 13 - .gitignore | 40 - .gitreview | 4 - .testr.conf | 7 - CONTRIBUTING.rst | 21 - HACKING.rst | 12 - LICENSE | 176 --- MANIFEST.in | 9 - README.rst | 41 - README.txt | 13 + doc/ext/__init__.py | 0 doc/ext/cli.py | 90 -- doc/ext/ext.py | 386 ------- doc/ext/parser.py | 138 --- doc/source/_templates/sidebarlinks.html | 11 - doc/source/_theme_rtd/layout.html | 4 - doc/source/_theme_rtd/theme.conf | 4 - doc/source/api.rst | 167 --- doc/source/cli.rst | 64 -- doc/source/conf.py | 271 ----- doc/source/how_to_participate.rst | 68 -- doc/source/index.rst | 42 - doc/source/shell.rst | 64 -- openstack-common.conf | 7 - releasenotes/notes/.placeholder | 0 ...togenerated-api-docs-3bc8513e63bfe610.yaml | 4 - ...togenerated-cli-docs-c1e89ec6ea66c4a9.yaml | 4 - .../cli-deprecation-da0e7b6dfe77af52.yaml | 4 - ...esignate-integration-16c59a6b57dbcfa4.yaml | 4 - .../notes/event-logs-c6d286e25dc7d9b1.yaml | 4 - .../notes/fields-unset-068db4c3e680c37d.yaml | 5 - ...implement-pagination-2ba52769d240a3ce.yaml | 4 - ...nary-create-optional-bc0f9ee6426c5659.yaml | 6 - .../job-create-optional-034307a6b5db2cf2.yaml | 6 - ...tion-create-optional-1014a403e5ffa7ac.yaml | 6 - .../notes/new-cli-6119bf8a4fb24ab6.yaml | 4 - .../notes/plugin-api-f650c26a030b7df8.yaml | 4 - ...ove-functional-tests-c4b9d43c2c32d121.yaml | 4 - .../notes/remove-py26-dad75fc8d602b3c5.yaml | 5 - .../notes/remove-py33-8364cb4805391750.yaml | 5 - ...on_to_plugin-version-20cfe17530446391.yaml | 10 - .../notes/shares-update-d6f7e28acd27aa7f.yaml | 4 - .../start-using-reno-1f3418c11785c9ab.yaml | 4 - .../notes/tags-update-c794416bcc035cb8.yaml | 5 - ...pdate-image-optional-f83c5746d88507cd.yaml | 5 - .../volume-mount-prefix-b6ef396a357cddd0.yaml | 6 - releasenotes/source/_static/.placeholder | 0 releasenotes/source/_templates/.placeholder | 0 releasenotes/source/conf.py | 219 ---- releasenotes/source/index.rst | 9 - releasenotes/source/mitaka.rst | 6 - releasenotes/source/unreleased.rst | 5 - requirements.txt | 18 - run_tests.sh | 164 --- saharaclient/__init__.py | 0 saharaclient/api/__init__.py | 0 saharaclient/api/base.py | 281 ----- saharaclient/api/client.py | 188 --- saharaclient/api/cluster_templates.py | 99 -- saharaclient/api/clusters.py | 138 --- saharaclient/api/data_sources.py | 80 -- saharaclient/api/helpers.py | 76 -- saharaclient/api/images.py | 72 -- saharaclient/api/job_binaries.py | 79 -- saharaclient/api/job_binary_internals.py | 63 - saharaclient/api/job_executions.py | 65 -- saharaclient/api/job_types.py | 29 - saharaclient/api/jobs.py | 69 -- saharaclient/api/node_group_templates.py | 129 --- saharaclient/api/parameters.py | 26 - saharaclient/api/plugins.py | 75 -- saharaclient/api/shell.py | 1012 ----------------- saharaclient/client.py | 47 - saharaclient/openstack/__init__.py | 0 saharaclient/openstack/common/__init__.py | 0 saharaclient/openstack/common/_i18n.py | 45 - .../openstack/common/apiclient/__init__.py | 0 .../openstack/common/apiclient/auth.py | 234 ---- .../openstack/common/apiclient/exceptions.py | 479 -------- saharaclient/openstack/common/cliutils.py | 272 ----- saharaclient/osc/__init__.py | 0 saharaclient/osc/plugin.py | 67 -- saharaclient/osc/v1/__init__.py | 0 saharaclient/osc/v1/cluster_templates.py | 508 --------- saharaclient/osc/v1/clusters.py | 663 ----------- saharaclient/osc/v1/data_sources.py | 303 ----- saharaclient/osc/v1/images.py | 309 ----- saharaclient/osc/v1/job_binaries.py | 429 ------- saharaclient/osc/v1/job_templates.py | 327 ------ saharaclient/osc/v1/job_types.py | 133 --- saharaclient/osc/v1/jobs.py | 379 ------ saharaclient/osc/v1/node_group_templates.py | 691 ----------- saharaclient/osc/v1/plugins.py | 218 ---- saharaclient/osc/v1/utils.py | 102 -- saharaclient/shell.py | 732 ------------ saharaclient/tests/__init__.py | 0 saharaclient/tests/unit/__init__.py | 0 saharaclient/tests/unit/base.py | 47 - saharaclient/tests/unit/nova/__init__.py | 0 saharaclient/tests/unit/nova/test_shell.py | 366 ------ saharaclient/tests/unit/nova/utils.py | 57 - saharaclient/tests/unit/osc/__init__.py | 0 saharaclient/tests/unit/osc/test_plugin.py | 42 - saharaclient/tests/unit/osc/v1/__init__.py | 0 saharaclient/tests/unit/osc/v1/fakes.py | 28 - .../unit/osc/v1/test_cluster_templates.py | 335 ------ .../tests/unit/osc/v1/test_clusters.py | 548 --------- .../tests/unit/osc/v1/test_data_sources.py | 307 ----- saharaclient/tests/unit/osc/v1/test_images.py | 367 ------ .../tests/unit/osc/v1/test_job_binaries.py | 324 ------ .../tests/unit/osc/v1/test_job_templates.py | 290 ----- .../tests/unit/osc/v1/test_job_types.py | 147 --- saharaclient/tests/unit/osc/v1/test_jobs.py | 322 ------ .../unit/osc/v1/test_node_group_templates.py | 406 ------- .../tests/unit/osc/v1/test_plugins.py | 232 ---- saharaclient/tests/unit/osc/v1/test_utils.py | 90 -- saharaclient/tests/unit/test_base.py | 28 - .../tests/unit/test_cluster_templates.py | 144 --- saharaclient/tests/unit/test_clusters.py | 214 ---- saharaclient/tests/unit/test_data_sources.py | 94 -- saharaclient/tests/unit/test_images.py | 85 -- saharaclient/tests/unit/test_job_binaries.py | 99 -- .../tests/unit/test_job_binary_internals.py | 99 -- .../tests/unit/test_job_executions.py | 127 --- saharaclient/tests/unit/test_job_types.py | 51 - saharaclient/tests/unit/test_jobs.py | 123 -- saharaclient/tests/unit/test_manager.py | 50 - .../tests/unit/test_node_group_templates.py | 147 --- saharaclient/tests/unit/test_plugins.py | 69 -- saharaclient/tests/unit/test_resource.py | 63 - saharaclient/version.py | 18 - setup.cfg | 104 -- setup.py | 29 - test-requirements.txt | 15 - tools/install_venv.py | 75 -- tools/install_venv_common.py | 212 ---- tools/with_venv.sh | 4 - tox.ini | 68 -- 138 files changed, 13 insertions(+), 16408 deletions(-) delete mode 100644 .coveragerc delete mode 100644 .gitignore delete mode 100644 .gitreview delete mode 100755 .testr.conf delete mode 100644 CONTRIBUTING.rst delete mode 100644 HACKING.rst delete mode 100644 LICENSE delete mode 100644 MANIFEST.in delete mode 100644 README.rst create mode 100644 README.txt delete mode 100644 doc/ext/__init__.py delete mode 100644 doc/ext/cli.py delete mode 100644 doc/ext/ext.py delete mode 100644 doc/ext/parser.py delete mode 100644 doc/source/_templates/sidebarlinks.html delete mode 100644 doc/source/_theme_rtd/layout.html delete mode 100644 doc/source/_theme_rtd/theme.conf delete mode 100644 doc/source/api.rst delete mode 100644 doc/source/cli.rst delete mode 100644 doc/source/conf.py delete mode 100644 doc/source/how_to_participate.rst delete mode 100644 doc/source/index.rst delete mode 100644 doc/source/shell.rst delete mode 100644 openstack-common.conf delete mode 100644 releasenotes/notes/.placeholder delete mode 100644 releasenotes/notes/autogenerated-api-docs-3bc8513e63bfe610.yaml delete mode 100644 releasenotes/notes/autogenerated-cli-docs-c1e89ec6ea66c4a9.yaml delete mode 100644 releasenotes/notes/cli-deprecation-da0e7b6dfe77af52.yaml delete mode 100644 releasenotes/notes/designate-integration-16c59a6b57dbcfa4.yaml delete mode 100644 releasenotes/notes/event-logs-c6d286e25dc7d9b1.yaml delete mode 100644 releasenotes/notes/fields-unset-068db4c3e680c37d.yaml delete mode 100644 releasenotes/notes/implement-pagination-2ba52769d240a3ce.yaml delete mode 100644 releasenotes/notes/job-binary-create-optional-bc0f9ee6426c5659.yaml delete mode 100644 releasenotes/notes/job-create-optional-034307a6b5db2cf2.yaml delete mode 100644 releasenotes/notes/job-execution-create-optional-1014a403e5ffa7ac.yaml delete mode 100644 releasenotes/notes/new-cli-6119bf8a4fb24ab6.yaml delete mode 100644 releasenotes/notes/plugin-api-f650c26a030b7df8.yaml delete mode 100644 releasenotes/notes/remove-functional-tests-c4b9d43c2c32d121.yaml delete mode 100644 releasenotes/notes/remove-py26-dad75fc8d602b3c5.yaml delete mode 100644 releasenotes/notes/remove-py33-8364cb4805391750.yaml delete mode 100644 releasenotes/notes/rename_version_to_plugin-version-20cfe17530446391.yaml delete mode 100644 releasenotes/notes/shares-update-d6f7e28acd27aa7f.yaml delete mode 100644 releasenotes/notes/start-using-reno-1f3418c11785c9ab.yaml delete mode 100644 releasenotes/notes/tags-update-c794416bcc035cb8.yaml delete mode 100644 releasenotes/notes/update-image-optional-f83c5746d88507cd.yaml delete mode 100644 releasenotes/notes/volume-mount-prefix-b6ef396a357cddd0.yaml delete mode 100644 releasenotes/source/_static/.placeholder delete mode 100644 releasenotes/source/_templates/.placeholder delete mode 100644 releasenotes/source/conf.py delete mode 100644 releasenotes/source/index.rst delete mode 100644 releasenotes/source/mitaka.rst delete mode 100644 releasenotes/source/unreleased.rst delete mode 100644 requirements.txt delete mode 100755 run_tests.sh delete mode 100644 saharaclient/__init__.py delete mode 100644 saharaclient/api/__init__.py delete mode 100644 saharaclient/api/base.py delete mode 100644 saharaclient/api/client.py delete mode 100644 saharaclient/api/cluster_templates.py delete mode 100644 saharaclient/api/clusters.py delete mode 100644 saharaclient/api/data_sources.py delete mode 100644 saharaclient/api/helpers.py delete mode 100644 saharaclient/api/images.py delete mode 100644 saharaclient/api/job_binaries.py delete mode 100644 saharaclient/api/job_binary_internals.py delete mode 100644 saharaclient/api/job_executions.py delete mode 100644 saharaclient/api/job_types.py delete mode 100644 saharaclient/api/jobs.py delete mode 100644 saharaclient/api/node_group_templates.py delete mode 100644 saharaclient/api/parameters.py delete mode 100644 saharaclient/api/plugins.py delete mode 100644 saharaclient/api/shell.py delete mode 100644 saharaclient/client.py delete mode 100644 saharaclient/openstack/__init__.py delete mode 100644 saharaclient/openstack/common/__init__.py delete mode 100644 saharaclient/openstack/common/_i18n.py delete mode 100644 saharaclient/openstack/common/apiclient/__init__.py delete mode 100644 saharaclient/openstack/common/apiclient/auth.py delete mode 100644 saharaclient/openstack/common/apiclient/exceptions.py delete mode 100644 saharaclient/openstack/common/cliutils.py delete mode 100644 saharaclient/osc/__init__.py delete mode 100644 saharaclient/osc/plugin.py delete mode 100644 saharaclient/osc/v1/__init__.py delete mode 100644 saharaclient/osc/v1/cluster_templates.py delete mode 100644 saharaclient/osc/v1/clusters.py delete mode 100644 saharaclient/osc/v1/data_sources.py delete mode 100644 saharaclient/osc/v1/images.py delete mode 100644 saharaclient/osc/v1/job_binaries.py delete mode 100644 saharaclient/osc/v1/job_templates.py delete mode 100644 saharaclient/osc/v1/job_types.py delete mode 100644 saharaclient/osc/v1/jobs.py delete mode 100644 saharaclient/osc/v1/node_group_templates.py delete mode 100644 saharaclient/osc/v1/plugins.py delete mode 100644 saharaclient/osc/v1/utils.py delete mode 100644 saharaclient/shell.py delete mode 100644 saharaclient/tests/__init__.py delete mode 100644 saharaclient/tests/unit/__init__.py delete mode 100644 saharaclient/tests/unit/base.py delete mode 100644 saharaclient/tests/unit/nova/__init__.py delete mode 100644 saharaclient/tests/unit/nova/test_shell.py delete mode 100644 saharaclient/tests/unit/nova/utils.py delete mode 100644 saharaclient/tests/unit/osc/__init__.py delete mode 100644 saharaclient/tests/unit/osc/test_plugin.py delete mode 100644 saharaclient/tests/unit/osc/v1/__init__.py delete mode 100644 saharaclient/tests/unit/osc/v1/fakes.py delete mode 100644 saharaclient/tests/unit/osc/v1/test_cluster_templates.py delete mode 100644 saharaclient/tests/unit/osc/v1/test_clusters.py delete mode 100644 saharaclient/tests/unit/osc/v1/test_data_sources.py delete mode 100644 saharaclient/tests/unit/osc/v1/test_images.py delete mode 100644 saharaclient/tests/unit/osc/v1/test_job_binaries.py delete mode 100644 saharaclient/tests/unit/osc/v1/test_job_templates.py delete mode 100644 saharaclient/tests/unit/osc/v1/test_job_types.py delete mode 100644 saharaclient/tests/unit/osc/v1/test_jobs.py delete mode 100644 saharaclient/tests/unit/osc/v1/test_node_group_templates.py delete mode 100644 saharaclient/tests/unit/osc/v1/test_plugins.py delete mode 100644 saharaclient/tests/unit/osc/v1/test_utils.py delete mode 100644 saharaclient/tests/unit/test_base.py delete mode 100644 saharaclient/tests/unit/test_cluster_templates.py delete mode 100644 saharaclient/tests/unit/test_clusters.py delete mode 100644 saharaclient/tests/unit/test_data_sources.py delete mode 100644 saharaclient/tests/unit/test_images.py delete mode 100644 saharaclient/tests/unit/test_job_binaries.py delete mode 100644 saharaclient/tests/unit/test_job_binary_internals.py delete mode 100644 saharaclient/tests/unit/test_job_executions.py delete mode 100644 saharaclient/tests/unit/test_job_types.py delete mode 100644 saharaclient/tests/unit/test_jobs.py delete mode 100644 saharaclient/tests/unit/test_manager.py delete mode 100644 saharaclient/tests/unit/test_node_group_templates.py delete mode 100644 saharaclient/tests/unit/test_plugins.py delete mode 100644 saharaclient/tests/unit/test_resource.py delete mode 100644 saharaclient/version.py delete mode 100644 setup.cfg delete mode 100644 setup.py delete mode 100644 test-requirements.txt delete mode 100644 tools/install_venv.py delete mode 100644 tools/install_venv_common.py delete mode 100755 tools/with_venv.sh delete mode 100644 tox.ini diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 2b789e1..0000000 --- a/.coveragerc +++ /dev/null @@ -1,13 +0,0 @@ -[run] -branch = True -source = saharaclient -omit = - */openstack/common/* - .tox/* - saharaclient/tests/* - -[paths] -source = saharaclient - -[report] -ignore_errors = True diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 393b55d..0000000 --- a/.gitignore +++ /dev/null @@ -1,40 +0,0 @@ -*.py[co] -*.egg -*.egg-info -dist -build -eggs -parts -var -sdist -develop-eggs -.installed.cfg -pip-log.txt -.tox -*.mo -.mr.developer.cfg -.DS_Store -Thumbs.db -.venv -.idea -out -target -*.iml -*.ipr -*.iws -*.db -.coverage -nosetests.xml -pylint-report.txt -ChangeLog -cscope.out -.testrepository -AUTHORS -cover -doc/html -doc/source/apidoc -doc/source/api -doc/build -*.log -# Files created by releasenotes build -releasenotes/build diff --git a/.gitreview b/.gitreview deleted file mode 100644 index 0593a6d..0000000 --- a/.gitreview +++ /dev/null @@ -1,4 +0,0 @@ -[gerrit] -host=review.openstack.org -port=29418 -project=openstack/python-saharaclient.git diff --git a/.testr.conf b/.testr.conf deleted file mode 100755 index 4da4d7d..0000000 --- a/.testr.conf +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] -test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ - OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ - OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \ - ${PYTHON:-python} -m subunit.run discover $DISCOVER_DIRECTORY $LISTOPT $IDOPTION -test_id_option=--load-list $IDFILE -test_list_option=--list diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst deleted file mode 100644 index a04c76b..0000000 --- a/CONTRIBUTING.rst +++ /dev/null @@ -1,21 +0,0 @@ -If you would like to contribute to the development of OpenStack, -you must follow the steps in the "If you're a developer" -section of this page: - - http://wiki.openstack.org/HowToContribute - -You can find more Sahara-specific info in our How To Participate guide: - - http://docs.openstack.org/developer/python-saharaclient/devref/how_to_participate.html - -Once those steps have been completed, changes to OpenStack -should be submitted for review via the Gerrit tool, following -the workflow documented at: - - http://wiki.openstack.org/GerritWorkflow - -Pull requests submitted through GitHub will be ignored. - -Bugs should be filed on Launchpad, not GitHub: - - https://bugs.launchpad.net/python-saharaclient diff --git a/HACKING.rst b/HACKING.rst deleted file mode 100644 index 6568acd..0000000 --- a/HACKING.rst +++ /dev/null @@ -1,12 +0,0 @@ -Sahara Style Commandments -========================= - -- Step 1: Read the OpenStack Style Commandments - http://docs.openstack.org/developer/hacking/ -- Step 2: Read on - -Sahara Specific Commandments ----------------------------- - -None so far - 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/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index f1c38fb..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,9 +0,0 @@ -include AUTHORS -include README.rst -include ChangeLog -include LICENSE - -exclude .gitignore -exclude .gitreview - -global-exclude *.pyc diff --git a/README.rst b/README.rst deleted file mode 100644 index 06a2134..0000000 --- a/README.rst +++ /dev/null @@ -1,41 +0,0 @@ -Python bindings to the OpenStack Sahara API -=========================================== - -.. image:: https://img.shields.io/pypi/v/python-saharaclient.svg - :target: https://pypi.python.org/pypi/python-saharaclient/ - :alt: Latest Version - -.. image:: https://img.shields.io/pypi/dm/python-saharaclient.svg - :target: https://pypi.python.org/pypi/python-saharaclient/ - :alt: Downloads - -This is a client for the OpenStack Sahara API. There's a Python API (the -``saharaclient`` module), and a command-line script (``sahara``). Each -implements the OpenStack Sahara API. You can find documentation for both -Python bindings and CLI in `Docs`_. - -Development takes place via the usual OpenStack processes as outlined -in the `developer guide -`_. - -.. _Docs: http://docs.openstack.org/developer/python-saharaclient/ - -* License: Apache License, Version 2.0 -* `PyPi`_ - package installation -* `Online Documentation`_ -* `Launchpad project`_ - release management -* `Blueprints`_ - feature specifications -* `Bugs`_ - issue tracking -* `Source`_ -* `Specs`_ -* `How to Contribute`_ - -.. _PyPi: https://pypi.python.org/pypi/python-saharaclient -.. _Online Documentation: http://docs.openstack.org/developer/python-saharaclient -.. _Launchpad project: https://launchpad.net/python-saharaclient -.. _Blueprints: https://blueprints.launchpad.net/python-saharaclient -.. _Bugs: https://bugs.launchpad.net/python-saharaclient -.. _Source: https://git.openstack.org/cgit/openstack/python-saharaclient -.. _How to Contribute: http://docs.openstack.org/infra/manual/developers.html -.. _Specs: http://specs.openstack.org/openstack/sahara-specs/ - diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..07a04ab --- /dev/null +++ b/README.txt @@ -0,0 +1,13 @@ +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". + +Use instead the project deb-python-saharaclient at +http://git.openstack.org/cgit/openstack/deb-python-saharaclient . + +For any further questions, please email +openstack-dev@lists.openstack.org or join #openstack-dev on +Freenode. diff --git a/doc/ext/__init__.py b/doc/ext/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/doc/ext/cli.py b/doc/ext/cli.py deleted file mode 100644 index feb28d7..0000000 --- a/doc/ext/cli.py +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright (c) 2015 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -import inspect -import os -import sys - -from docutils import nodes -from . import ext - - -def _get_command(classes): - """Associates each command class with command depending on setup.cfg - """ - commands = {} - setup_file = os.path.join( - os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')), - 'setup.cfg') - for line in open(setup_file, 'r'): - for cl in classes: - if cl in line: - commands[cl] = line.split(' = ')[0].strip().replace('_', ' ') - - return commands - - -class ArgParseDirectiveOSC(ext.ArgParseDirective): - """Sphinx extension that automatically documents commands and options - of the module that contains OpenstackClient/cliff command objects - - Usage example: - - .. cli:: - :module: saharaclient.osc.v1.clusters - - """ - def run(self): - module_name = self.options['module'] - - mod = __import__(module_name, globals(), locals()) - - classes = inspect.getmembers(sys.modules[module_name], inspect.isclass) - classes_names = [cl[0] for cl in classes] - commands = _get_command(classes_names) - - items = [] - - for cl in classes: - parser = cl[1](None, None).get_parser(None) - parser.prog = commands[cl[0]] - items.append(nodes.subtitle(text=commands[cl[0]])) - result = ext.parse_parser( - parser, skip_default_values='nodefault' in self.options) - result = ext.parser_navigate(result, '') - nested_content = ext.nodes.paragraph() - self.state.nested_parse( - self.content, self.content_offset, nested_content) - nested_content = nested_content.children - - for item in nested_content: - if not isinstance(item, ext.nodes.definition_list): - items.append(item) - if 'description' in result: - items.append(self._nested_parse_paragraph(result['description'])) - items.append(ext.nodes.literal_block(text=result['usage'])) - items.append(ext.print_command_args_and_opts( - ext.print_arg_list(result, nested_content), - ext.print_opt_list(result, nested_content), - ext.print_subcommand_list(result, nested_content) - )) - if 'epilog' in result: - items.append(self._nested_parse_paragraph(result['epilog'])) - return items - - -def setup(app): - app.add_directive('cli', ArgParseDirectiveOSC) diff --git a/doc/ext/ext.py b/doc/ext/ext.py deleted file mode 100644 index 9b07ab1..0000000 --- a/doc/ext/ext.py +++ /dev/null @@ -1,386 +0,0 @@ -# Copyright (c) 2013 Alex Rudakov -# -# 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 argparse import ArgumentParser -import os - -from docutils import nodes -from docutils.statemachine import StringList -from docutils.parsers.rst.directives import flag, unchanged -from sphinx.util.compat import Directive -from sphinx.util.nodes import nested_parse_with_titles - -from .parser import parse_parser, parser_navigate - - -def map_nested_definitions(nested_content): - if nested_content is None: - raise Exception('Nested content should be iterable, not null') - # build definition dictionary - definitions = {} - for item in nested_content: - if not isinstance(item, nodes.definition_list): - continue - for subitem in item: - if not isinstance(subitem, nodes.definition_list_item): - continue - if not len(subitem.children) > 0: - continue - classifier = '@after' - idx = subitem.first_child_matching_class(nodes.classifier) - if idx is not None: - ci = subitem[idx] - if len(ci.children) > 0: - classifier = ci.children[0].astext() - if classifier is not None and classifier not in ( - '@replace', '@before', '@after'): - raise Exception('Unknown classifier: %s' % classifier) - idx = subitem.first_child_matching_class(nodes.term) - if idx is not None: - ch = subitem[idx] - if len(ch.children) > 0: - term = ch.children[0].astext() - idx = subitem.first_child_matching_class(nodes.definition) - if idx is not None: - def_node = subitem[idx] - def_node.attributes['classifier'] = classifier - definitions[term] = def_node - return definitions - - -def print_arg_list(data, nested_content): - definitions = map_nested_definitions(nested_content) - items = [] - if 'args' in data: - for arg in data['args']: - my_def = [nodes.paragraph(text=arg['help'])] if arg['help'] else [] - name = arg['name'] - my_def = apply_definition(definitions, my_def, name) - if len(my_def) == 0: - my_def.append(nodes.paragraph(text='Undocumented')) - if 'choices' in arg: - my_def.append(nodes.paragraph( - text=('Possible choices: %s' % ', '.join([str(c) for c in arg['choices']])))) - items.append( - nodes.option_list_item( - '', nodes.option_group('', nodes.option_string(text=name)), - nodes.description('', *my_def))) - return nodes.option_list('', *items) if items else None - - -def print_opt_list(data, nested_content): - definitions = map_nested_definitions(nested_content) - items = [] - if 'options' in data: - for opt in data['options']: - names = [] - my_def = [nodes.paragraph(text=opt['help'])] if opt['help'] else [] - for name in opt['name']: - option_declaration = [nodes.option_string(text=name)] - if opt['default'] is not None \ - and opt['default'] != '==SUPPRESS==': - option_declaration += nodes.option_argument( - '', text='=' + str(opt['default'])) - names.append(nodes.option('', *option_declaration)) - my_def = apply_definition(definitions, my_def, name) - if len(my_def) == 0: - my_def.append(nodes.paragraph(text='Undocumented')) - if 'choices' in opt: - my_def.append(nodes.paragraph( - text=('Possible choices: %s' % ', '.join([str(c) for c in opt['choices']])))) - items.append( - nodes.option_list_item( - '', nodes.option_group('', *names), - nodes.description('', *my_def))) - return nodes.option_list('', *items) if items else None - - -def print_command_args_and_opts(arg_list, opt_list, sub_list=None): - items = [] - if arg_list: - items.append(nodes.definition_list_item( - '', nodes.term(text='Positional arguments:'), - nodes.definition('', arg_list))) - if opt_list: - items.append(nodes.definition_list_item( - '', nodes.term(text='Options:'), - nodes.definition('', opt_list))) - if sub_list and len(sub_list): - items.append(nodes.definition_list_item( - '', nodes.term(text='Sub-commands:'), - nodes.definition('', sub_list))) - return nodes.definition_list('', *items) - - -def apply_definition(definitions, my_def, name): - if name in definitions: - definition = definitions[name] - classifier = definition['classifier'] - if classifier == '@replace': - return definition.children - if classifier == '@after': - return my_def + definition.children - if classifier == '@before': - return definition.children + my_def - raise Exception('Unknown classifier: %s' % classifier) - return my_def - - -def print_subcommand_list(data, nested_content): - definitions = map_nested_definitions(nested_content) - items = [] - if 'children' in data: - for child in data['children']: - my_def = [nodes.paragraph( - text=child['help'])] if child['help'] else [] - name = child['name'] - my_def = apply_definition(definitions, my_def, name) - if len(my_def) == 0: - my_def.append(nodes.paragraph(text='Undocumented')) - if 'description' in child: - my_def.append(nodes.paragraph(text=child['description'])) - my_def.append(nodes.literal_block(text=child['usage'])) - my_def.append(print_command_args_and_opts( - print_arg_list(child, nested_content), - print_opt_list(child, nested_content), - print_subcommand_list(child, nested_content) - )) - items.append( - nodes.definition_list_item( - '', - nodes.term('', '', nodes.strong(text=name)), - nodes.definition('', *my_def) - ) - ) - return nodes.definition_list('', *items) - - -class ArgParseDirective(Directive): - has_content = True - option_spec = dict(module=unchanged, func=unchanged, ref=unchanged, - prog=unchanged, path=unchanged, nodefault=flag, - manpage=unchanged, nosubcommands=unchanged, passparser=flag) - - def _construct_manpage_specific_structure(self, parser_info): - """ - Construct a typical man page consisting of the following elements: - NAME (automatically generated, out of our control) - SYNOPSIS - DESCRIPTION - OPTIONS - FILES - SEE ALSO - BUGS - """ - # SYNOPSIS section - synopsis_section = nodes.section( - '', - nodes.title(text='Synopsis'), - nodes.literal_block(text=parser_info["bare_usage"]), - ids=['synopsis-section']) - # DESCRIPTION section - description_section = nodes.section( - '', - nodes.title(text='Description'), - nodes.paragraph(text=parser_info.get( - 'description', parser_info.get( - 'help', "undocumented").capitalize())), - ids=['description-section']) - nested_parse_with_titles( - self.state, self.content, description_section) - if parser_info.get('epilog'): - # TODO: do whatever sphinx does to understand ReST inside - # docstrings magically imported from other places. The nested - # parse method invoked above seem to be able to do this but - # I haven't found a way to do it for arbitrary text - description_section += nodes.paragraph( - text=parser_info['epilog']) - # OPTIONS section - options_section = nodes.section( - '', - nodes.title(text='Options'), - ids=['options-section']) - if 'args' in parser_info: - options_section += nodes.paragraph() - options_section += nodes.subtitle(text='Positional arguments:') - options_section += self._format_positional_arguments(parser_info) - if 'options' in parser_info: - options_section += nodes.paragraph() - options_section += nodes.subtitle(text='Optional arguments:') - options_section += self._format_optional_arguments(parser_info) - items = [ - # NOTE: we cannot generate NAME ourselves. It is generated by - # docutils.writers.manpage - synopsis_section, - description_section, - # TODO: files - # TODO: see also - # TODO: bugs - ] - if len(options_section.children) > 1: - items.append(options_section) - if 'nosubcommands' not in self.options: - # SUBCOMMANDS section (non-standard) - subcommands_section = nodes.section( - '', - nodes.title(text='Sub-Commands'), - ids=['subcommands-section']) - if 'children' in parser_info: - subcommands_section += self._format_subcommands(parser_info) - if len(subcommands_section) > 1: - items.append(subcommands_section) - if os.getenv("INCLUDE_DEBUG_SECTION"): - import json - # DEBUG section (non-standard) - debug_section = nodes.section( - '', - nodes.title(text="Argparse + Sphinx Debugging"), - nodes.literal_block(text=json.dumps(parser_info, indent=' ')), - ids=['debug-section']) - items.append(debug_section) - return items - - def _format_positional_arguments(self, parser_info): - assert 'args' in parser_info - items = [] - for arg in parser_info['args']: - arg_items = [] - if arg['help']: - arg_items.append(nodes.paragraph(text=arg['help'])) - else: - arg_items.append(nodes.paragraph(text='Undocumented')) - if 'choices' in arg: - arg_items.append( - nodes.paragraph( - text='Possible choices: ' + ', '.join(arg['choices']))) - items.append( - nodes.option_list_item( - '', - nodes.option_group( - '', nodes.option( - '', nodes.option_string(text=arg['metavar']) - ) - ), - nodes.description('', *arg_items))) - return nodes.option_list('', *items) - - def _format_optional_arguments(self, parser_info): - assert 'options' in parser_info - items = [] - for opt in parser_info['options']: - names = [] - opt_items = [] - for name in opt['name']: - option_declaration = [nodes.option_string(text=name)] - if opt['default'] is not None \ - and opt['default'] != '==SUPPRESS==': - option_declaration += nodes.option_argument( - '', text='=' + str(opt['default'])) - names.append(nodes.option('', *option_declaration)) - if opt['help']: - opt_items.append(nodes.paragraph(text=opt['help'])) - else: - opt_items.append(nodes.paragraph(text='Undocumented')) - if 'choices' in opt: - opt_items.append( - nodes.paragraph( - text='Possible choices: ' + ', '.join(opt['choices']))) - items.append( - nodes.option_list_item( - '', nodes.option_group('', *names), - nodes.description('', *opt_items))) - return nodes.option_list('', *items) - - def _format_subcommands(self, parser_info): - assert 'children' in parser_info - items = [] - for subcmd in parser_info['children']: - subcmd_items = [] - if subcmd['help']: - subcmd_items.append(nodes.paragraph(text=subcmd['help'])) - else: - subcmd_items.append(nodes.paragraph(text='Undocumented')) - items.append( - nodes.definition_list_item( - '', - nodes.term('', '', nodes.strong( - text=subcmd['bare_usage'])), - nodes.definition('', *subcmd_items))) - return nodes.definition_list('', *items) - - def _nested_parse_paragraph(self, text): - content = nodes.paragraph() - self.state.nested_parse(StringList(text.split("\n")), 0, content) - return content - - def run(self): - if 'module' in self.options and 'func' in self.options: - module_name = self.options['module'] - attr_name = self.options['func'] - elif 'ref' in self.options: - _parts = self.options['ref'].split('.') - module_name = '.'.join(_parts[0:-1]) - attr_name = _parts[-1] - else: - raise self.error( - ':module: and :func: should be specified, or :ref:') - mod = __import__(module_name, globals(), locals(), [attr_name]) - if not hasattr(mod, attr_name): - raise self.error(( - 'Module "%s" has no attribute "%s"\n' - 'Incorrect argparse :module: or :func: values?' - ) % (module_name, attr_name)) - func = getattr(mod, attr_name) - if isinstance(func, ArgumentParser): - parser = func - elif 'passparser' in self.options: - parser = ArgumentParser() - func(parser) - else: - parser = func() - if 'path' not in self.options: - self.options['path'] = '' - path = str(self.options['path']) - if 'prog' in self.options: - parser.prog = self.options['prog'] - result = parse_parser( - parser, skip_default_values='nodefault' in self.options) - result = parser_navigate(result, path) - if 'manpage' in self.options: - return self._construct_manpage_specific_structure(result) - nested_content = nodes.paragraph() - self.state.nested_parse( - self.content, self.content_offset, nested_content) - nested_content = nested_content.children - items = [] - # add common content between - for item in nested_content: - if not isinstance(item, nodes.definition_list): - items.append(item) - if 'description' in result: - items.append(self._nested_parse_paragraph(result['description'])) - items.append(nodes.literal_block(text=result['usage'])) - items.append(print_command_args_and_opts( - print_arg_list(result, nested_content), - print_opt_list(result, nested_content), - print_subcommand_list(result, nested_content) - )) - if 'epilog' in result: - items.append(self._nested_parse_paragraph(result['epilog'])) - return items - - -def setup(app): - app.add_directive('argparse', ArgParseDirective) \ No newline at end of file diff --git a/doc/ext/parser.py b/doc/ext/parser.py deleted file mode 100644 index fbb8feb..0000000 --- a/doc/ext/parser.py +++ /dev/null @@ -1,138 +0,0 @@ -# Copyright (c) 2013 Alex Rudakov -# -# 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 argparse import _HelpAction, _SubParsersAction -import re - - -class NavigationException(Exception): - pass - - -def parser_navigate(parser_result, path, current_path=None): - if isinstance(path, str): - if path == '': - return parser_result - path = re.split('\s+', path) - current_path = current_path or [] - if len(path) == 0: - return parser_result - if 'children' not in parser_result: - raise NavigationException( - 'Current parser have no children elements. (path: %s)' % - ' '.join(current_path)) - next_hop = path.pop(0) - for child in parser_result['children']: - if child['name'] == next_hop: - current_path.append(next_hop) - return parser_navigate(child, path, current_path) - raise NavigationException( - 'Current parser have no children element with name: %s (path: %s)' % ( - next_hop, ' '.join(current_path))) - - -def _try_add_parser_attribute(data, parser, attribname): - attribval = getattr(parser, attribname, None) - if attribval is None: - return - if not isinstance(attribval, str): - return - if len(attribval) > 0: - data[attribname] = attribval - - -def _format_usage_without_prefix(parser): - """ - Use private argparse APIs to get the usage string without - the 'usage: ' prefix. - """ - fmt = parser._get_formatter() - fmt.add_usage(parser.usage, parser._actions, - parser._mutually_exclusive_groups, prefix='') - return fmt.format_help().strip() - - -def parse_parser(parser, data=None, **kwargs): - if data is None: - data = { - 'name': '', - 'usage': parser.format_usage().strip(), - 'bare_usage': _format_usage_without_prefix(parser), - 'prog': parser.prog, - } - _try_add_parser_attribute(data, parser, 'description') - _try_add_parser_attribute(data, parser, 'epilog') - for action in parser._get_positional_actions(): - if isinstance(action, _HelpAction): - continue - if isinstance(action, _SubParsersAction): - helps = {} - for item in action._choices_actions: - helps[item.dest] = item.help - - # commands which share an existing parser are an alias, - # don't duplicate docs - subsection_alias = {} - subsection_alias_names = set() - for name, subaction in action._name_parser_map.items(): - if subaction not in subsection_alias: - subsection_alias[subaction] = [] - else: - subsection_alias[subaction].append(name) - subsection_alias_names.add(name) - - for name, subaction in action._name_parser_map.items(): - if name in subsection_alias_names: - continue - subalias = subsection_alias[subaction] - subaction.prog = '%s %s' % (parser.prog, name) - subdata = { - 'name': name if not subalias else - '%s (%s)' % (name, ', '.join(subalias)), - 'help': helps.get(name, ''), - 'usage': subaction.format_usage().strip(), - 'bare_usage': _format_usage_without_prefix(subaction), - } - parse_parser(subaction, subdata, **kwargs) - data.setdefault('children', []).append(subdata) - continue - if 'args' not in data: - data['args'] = [] - arg = { - 'name': action.dest, - 'help': action.help or '', - 'metavar': action.metavar - } - if action.choices: - arg['choices'] = action.choices - data['args'].append(arg) - show_defaults = ( - ('skip_default_values' not in kwargs) - or (kwargs['skip_default_values'] is False)) - for action in parser._get_optional_actions(): - if isinstance(action, _HelpAction): - continue - if 'options' not in data: - data['options'] = [] - option = { - 'name': action.option_strings, - 'default': action.default if show_defaults else '==SUPPRESS==', - 'help': action.help or '' - } - if action.choices: - option['choices'] = action.choices - if "==SUPPRESS==" not in option['help']: - data['options'].append(option) - return data diff --git a/doc/source/_templates/sidebarlinks.html b/doc/source/_templates/sidebarlinks.html deleted file mode 100644 index af88d86..0000000 --- a/doc/source/_templates/sidebarlinks.html +++ /dev/null @@ -1,11 +0,0 @@ -

Useful Links

- - -{% if READTHEDOCS %} - -{% endif %} diff --git a/doc/source/_theme_rtd/layout.html b/doc/source/_theme_rtd/layout.html deleted file mode 100644 index cd7ade1..0000000 --- a/doc/source/_theme_rtd/layout.html +++ /dev/null @@ -1,4 +0,0 @@ -{% extends "basic/layout.html" %} -{% set css_files = css_files + ['_static/tweaks.css'] %} - -{% block relbar1 %}{% endblock relbar1 %} \ No newline at end of file diff --git a/doc/source/_theme_rtd/theme.conf b/doc/source/_theme_rtd/theme.conf deleted file mode 100644 index 8c44b0c..0000000 --- a/doc/source/_theme_rtd/theme.conf +++ /dev/null @@ -1,4 +0,0 @@ -[theme] -inherit = nature -stylesheet = nature.css -pygments_style = tango \ No newline at end of file diff --git a/doc/source/api.rst b/doc/source/api.rst deleted file mode 100644 index f49e663..0000000 --- a/doc/source/api.rst +++ /dev/null @@ -1,167 +0,0 @@ -Sahara Client -============= - -Overview --------- - -Sahara Client provides a list of Python interfaces to communicate with the -Sahara REST API. Sahara Client enables users to perform most of the existing -operations like retrieving template lists, creating Clusters, submitting EDP -Jobs, etc. - - -Instantiating a Client ----------------------- - -To start using the Sahara Client users have to create an instance of the -`Client` class. The client constructor has a list of parameters to authenticate -and locate Sahara endpoint. - -.. autoclass:: saharaclient.api.client.Client - :members: - -**Important!** - It is not a mandatory rule to provide all of the parameters above. The minimum - number should be enough to determine Sahara endpoint, check user - authentication and tenant to operate in. - -Authentication check -~~~~~~~~~~~~~~~~~~~~ - -Passing authentication parameters to Sahara Client is deprecated. Keystone -Session object should be used for this purpose. For example: - -.. sourcecode:: python - - from keystoneauth1.identity import v2 - from keystoneauth1 import session - from saharaclient import client - - auth = v2.Password(auth_url=AUTH_URL, - username=USERNAME, - password=PASSWORD, - tenant_name=PROJECT_ID) - - ses = session.Session(auth=auth) - - sahara = client.Client('1.1', session=ses) -.. - -For more information about Keystone Sessions, see `Using Sessions`_. - -.. _Using Sessions: http://docs.openstack.org/developer/python-keystoneclient/using-sessions.html - -Sahara endpoint discovery -~~~~~~~~~~~~~~~~~~~~~~~~~ - -If user has a direct URL pointing to Sahara REST API, it may be specified as -`sahara_url`. If this parameter is missing, Sahara client will use Keystone -Service Catalog to find the endpoint. There are two parameters: `service_type` -and `endpoint_type` to configure endpoint search. Both parameters have -default values. - -.. sourcecode:: python - - from keystoneauth1.identity import v2 - from keystoneauth1 import session - from saharaclient import client - - auth = v2.Password(auth_url=AUTH_URL, - username=USERNAME, - password=PASSWORD, - tenant_name=PROJECT_ID) - - ses = session.Session(auth=auth) - - sahara = client.Client('1.1', session=ses, - service_type="non-default-service-type", - endpoint_type="internalURL") -.. - -Object managers ---------------- -Sahara Client has a list of fields to operate with: - - * plugins - * clusters - * cluster_templates - * node_group_templates - * images - * data_sources - * job_binaries - * job_binary_internals - * job_executions - * job_types - -Each of this fields is a reference to a Manager for a corresponding group of -REST calls. - - -Supported operations --------------------- - -Plugin ops -~~~~~~~~~~ - -.. autoclass:: saharaclient.api.plugins.PluginManager - :members: - -Image Registry ops -~~~~~~~~~~~~~~~~~~ - -.. autoclass:: saharaclient.api.images.ImageManager - :members: - -Node Group Template ops -~~~~~~~~~~~~~~~~~~~~~~~ - -.. autoclass:: saharaclient.api.node_group_templates.NodeGroupTemplateManager - :members: - -Cluster Template ops -~~~~~~~~~~~~~~~~~~~~ - -.. autoclass:: saharaclient.api.cluster_templates.ClusterTemplateManager - :members: - -Cluster ops -~~~~~~~~~~~ - -.. autoclass:: saharaclient.api.clusters.ClusterManager - :members: - -Data Source ops -~~~~~~~~~~~~~~~ - -.. autoclass:: saharaclient.api.data_sources.DataSourceManager - :members: - -Job Binary Internal ops -~~~~~~~~~~~~~~~~~~~~~~~ - -.. autoclass:: saharaclient.api.job_binary_internals.JobBinaryInternalsManager - :members: create, update - -Job Binary ops -~~~~~~~~~~~~~~ - -.. autoclass:: saharaclient.api.job_binaries.JobBinariesManager - :members: - -Job ops -~~~~~~~ - -.. autoclass:: saharaclient.api.jobs.JobsManager - :members: - -Job Execution ops -~~~~~~~~~~~~~~~~~ - -.. autoclass:: saharaclient.api.job_executions.JobExecutionsManager - :members: - -Job Types ops -~~~~~~~~~~~~~ - -.. autoclass:: saharaclient.api.job_types.JobTypesManager - :members: diff --git a/doc/source/cli.rst b/doc/source/cli.rst deleted file mode 100644 index 62637f0..0000000 --- a/doc/source/cli.rst +++ /dev/null @@ -1,64 +0,0 @@ -Sahara CLI Commands -=================== - -The following commands are currently supported by the Sahara CLI: - -Plugins -------- - -.. cli:: - :module: saharaclient.osc.v1.plugins - -Images ------- - -.. cli:: - :module: saharaclient.osc.v1.images - -Node Group Templates --------------------- - -.. cli:: - :module: saharaclient.osc.v1.node_group_templates - -Cluster Templates ------------------ - -.. cli:: - :module: saharaclient.osc.v1.cluster_templates - -Clusters --------- - -.. cli:: - :module: saharaclient.osc.v1.clusters - -Data Sources ------------- - -.. cli:: - :module: saharaclient.osc.v1.data_sources - -Job Binaries ------------- - -.. cli:: - :module: saharaclient.osc.v1.job_binaries - -Job Types ---------- - -.. cli:: - :module: saharaclient.osc.v1.job_types - -Job Templates -------------- - -.. cli:: - :module: saharaclient.osc.v1.job_templates - -Jobs ----- - -.. cli:: - :module: saharaclient.osc.v1.jobs diff --git a/doc/source/conf.py b/doc/source/conf.py deleted file mode 100644 index fd50871..0000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,271 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import subprocess -import sys - -import os - -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) -sys.path.insert(0, os.path.abspath('../../saharaclient')) -sys.path.append(os.path.abspath('..')) -sys.path.append(os.path.abspath('../bin')) - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.viewcode', 'ext.cli'] - -if not on_rtd: - extensions.append('oslosphinx') - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'Sahara Client' -copyright = u'2013, OpenStack Foundation' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# Version info -from saharaclient.version import version_info as saharaclient_version -release = saharaclient_version.release_string() -# The short X.Y version. -version = saharaclient_version.version_string() - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. - -if on_rtd: - html_theme_path = ['.'] - html_theme = '_theme_rtd' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -html_title = 'Sahara Client' - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' -git_cmd = ["git", "log", "--pretty=format:'%ad, commit %h'", "--date=local", - "-n1"] -html_last_updated_fmt = subprocess.Popen( - git_cmd, stdout=subprocess.PIPE).communicate()[0] - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -html_sidebars = { - 'index': ['sidebarlinks.html', 'localtoc.html', 'searchbox.html', 'sourcelink.html'], - '**': ['localtoc.html', 'relations.html', - 'searchbox.html', 'sourcelink.html'] -} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'SaharaClientDoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - #'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - #'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - #'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'saharaclientdoc.tex', u'Sahara Client', - u'OpenStack Foundation', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'saharaclient', u'Sahara Client', - [u'OpenStack Foundation'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------------ - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'Sahara Client', u'Sahara Client', - u'OpenStack Foundation', 'Sahara Client', 'Sahara Client', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' diff --git a/doc/source/how_to_participate.rst b/doc/source/how_to_participate.rst deleted file mode 100644 index 14c1ee0..0000000 --- a/doc/source/how_to_participate.rst +++ /dev/null @@ -1,68 +0,0 @@ -How to Participate -================== - -Getting started ---------------- - -* Create account on `Github `_ - (if you don't have one) - - * Make sure that your local git is properly configured by executing - ``git config --list``. If not, configure ``user.name``, ``user.email`` - -* Create account on `Launchpad `_ - (if you don't have one) - -* Subscribe to `OpenStack general mail-list `_ - -* Subscribe to `OpenStack development mail-list `_ - -* Create `OpenStack profile `_ - -* Login to `OpenStack Gerrit `_ with your - Launchpad id - - * Sign `OpenStack Individual Contributor License Agreement `_ - * Make sure that your email is listed in `identities `_ - -* Subscribe to code-reviews. Go to your settings on http://review.openstack.org - - * Go to ``watched projects`` - * Add ``openstack/sahara``, ``openstack/sahara-dashboard``, - ``openstack/sahara-extra``, ``openstack/python-saharaclient``, - ``openstack/sahara-image-elements``, ``openstack/horizon`` - - -How to stay in touch with the community? ----------------------------------------- - -* If you have something to discuss use - `OpenStack development mail-list `_. - Prefix mail subject with ``[Sahara]`` - -* Join ``#openstack-sahara`` IRC channel on `freenode `_ - -* Join public weekly meetings on *Thursdays at 18:00 UTC* on - ``#openstack-meeting-alt`` IRC channel -* Join public weekly meetings on *Thursdays at 14:00 UTC* on - ``#openstack-meeting-3`` IRC channel - - -How to send your first patch on review? ---------------------------------------- - -* Checkout Sahara code from `Github `_ - -* Carefully read https://wiki.openstack.org/wiki/Gerrit_Workflow - - * Pay special attention to https://wiki.openstack.org/wiki/Gerrit_Workflow#Committing_Changes - -* Apply and commit your changes - -* Make sure that your code passes ``PEP8`` checks and unit-tests - -* Send your patch on review - -* Monitor status of your patch review on https://review.openstack.org/#/ - - diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100644 index 50a3d08..0000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,42 +0,0 @@ -Python bindings to the OpenStack Sahara API -=========================================== - -This is a client for OpenStack Sahara API. There's :doc:`a Python API -` (the :mod:`saharaclient` module), and a :doc:`command-line utility -` (installed as an OpenStackClient plugin). Each implements the entire -OpenStack Sahara API. - -You'll need credentials for an OpenStack cloud that implements the -Data Processing API, in order to use the sahara client. - -You may want to read the `OpenStack Sahara Docs`__ -- the overview, at -least -- to get an idea of the concepts. By understanding the concepts -this library should make more sense. - - __ http://docs.openstack.org/developer/sahara/ - -Contents: - -.. toctree:: - :maxdepth: 2 - - api - shell - cli - how_to_participate - -Contributing -============ - -Code is hosted in `review.o.o`_ and mirrored to `github`_ and `git.o.o`_ . -Submit bugs to the Sahara project on `launchpad`_ and to the Sahara client on -`launchpad_client`_. Submit code to the openstack/python-saharaclient project -using `gerrit`_. - -.. _review.o.o: https://review.openstack.org -.. _github: https://github.com/openstack/python-saharaclient -.. _git.o.o: http://git.openstack.org/cgit/openstack/python-saharaclient -.. _launchpad: https://launchpad.net/sahara -.. _launchpad_client: https://launchpad.net/python-saharaclient -.. _gerrit: http://docs.openstack.org/infra/manual/developers.html#development-workflow - diff --git a/doc/source/shell.rst b/doc/source/shell.rst deleted file mode 100644 index 6c6249e..0000000 --- a/doc/source/shell.rst +++ /dev/null @@ -1,64 +0,0 @@ -Sahara CLI -========== - -The Sahara shell utility now is part of the OpenStackClient, so all -shell commands take the following form: - -.. code-block:: bash - - $ openstack dataprocessing [arguments...] - -To get a list of all possible commands you can run: - -.. code-block:: bash - - $ openstack help dataprocessing - -To get detailed help for the command you can run: - -.. code-block:: bash - - $ openstack help dataprocessing - -For more information about commands and their parameters you can refer to -:doc:`the Sahara CLI commands `. - -For more information about abilities and features of OpenStackClient CLI you -can refer to `OpenStackClient documentation `_ - -Configuration -------------- - -The CLI is configured via environment variables and command-line options which -are described in http://docs.openstack.org/developer/python-openstackclient/authentication.html. - -Authentication using username/password is most commonly used and can be -provided with environment variables: - -.. code-block:: bash - - export OS_AUTH_URL= - export OS_PROJECT_NAME= - export OS_USERNAME= - export OS_PASSWORD= # (optional) - -or command-line options: - -.. code-block:: bash - - --os-auth-url - --os-project-name - --os-username - [--os-password ] - -Additionally :program:`sahara` API url can be configured with parameter: - -.. code-block:: bash - - --os-data-processing-url - -or with environment variable: - -.. code-block:: bash - - export OS_DATA_PROCESSING_URL= diff --git a/openstack-common.conf b/openstack-common.conf deleted file mode 100644 index 0b4ad3f..0000000 --- a/openstack-common.conf +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] -base=saharaclient - -module=apiclient.auth -module=apiclient.exceptions -module=cliutils -module=_i18n diff --git a/releasenotes/notes/.placeholder b/releasenotes/notes/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/releasenotes/notes/autogenerated-api-docs-3bc8513e63bfe610.yaml b/releasenotes/notes/autogenerated-api-docs-3bc8513e63bfe610.yaml deleted file mode 100644 index 471c98c..0000000 --- a/releasenotes/notes/autogenerated-api-docs-3bc8513e63bfe610.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -features: - - > - Automatically generated documentation for saharaclient API was added. diff --git a/releasenotes/notes/autogenerated-cli-docs-c1e89ec6ea66c4a9.yaml b/releasenotes/notes/autogenerated-cli-docs-c1e89ec6ea66c4a9.yaml deleted file mode 100644 index 6044f5e..0000000 --- a/releasenotes/notes/autogenerated-cli-docs-c1e89ec6ea66c4a9.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -features: - - > - Automatically generated documentation for saharaclient CLI was added. diff --git a/releasenotes/notes/cli-deprecation-da0e7b6dfe77af52.yaml b/releasenotes/notes/cli-deprecation-da0e7b6dfe77af52.yaml deleted file mode 100644 index e5b7f34..0000000 --- a/releasenotes/notes/cli-deprecation-da0e7b6dfe77af52.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -deprecations: - - > - Old CLI is deprecated and will not be maintained. diff --git a/releasenotes/notes/designate-integration-16c59a6b57dbcfa4.yaml b/releasenotes/notes/designate-integration-16c59a6b57dbcfa4.yaml deleted file mode 100644 index 3cb06fe..0000000 --- a/releasenotes/notes/designate-integration-16c59a6b57dbcfa4.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -features: - - Added integration of Designate for hostname resolution through dns - servers diff --git a/releasenotes/notes/event-logs-c6d286e25dc7d9b1.yaml b/releasenotes/notes/event-logs-c6d286e25dc7d9b1.yaml deleted file mode 100644 index 45449b4..0000000 --- a/releasenotes/notes/event-logs-c6d286e25dc7d9b1.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -features: - - Providing ability to make dump of event logs for clusters. - Also displaying shorten version of event logs by option. diff --git a/releasenotes/notes/fields-unset-068db4c3e680c37d.yaml b/releasenotes/notes/fields-unset-068db4c3e680c37d.yaml deleted file mode 100644 index 435b06d..0000000 --- a/releasenotes/notes/fields-unset-068db4c3e680c37d.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -fixes: - - > - [`bug 1534050 `_] - Now object's fields can be unset with ``update`` calls. diff --git a/releasenotes/notes/implement-pagination-2ba52769d240a3ce.yaml b/releasenotes/notes/implement-pagination-2ba52769d240a3ce.yaml deleted file mode 100644 index 178f7a0..0000000 --- a/releasenotes/notes/implement-pagination-2ba52769d240a3ce.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -features: - - > - Pagination for list operations is implemented. diff --git a/releasenotes/notes/job-binary-create-optional-bc0f9ee6426c5659.yaml b/releasenotes/notes/job-binary-create-optional-bc0f9ee6426c5659.yaml deleted file mode 100644 index 79b2749..0000000 --- a/releasenotes/notes/job-binary-create-optional-bc0f9ee6426c5659.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -fixes: - - > - [`bug 1508406 `_] - Now ``description`` and ``extra`` parameters of jobs ``create`` method - are optional. diff --git a/releasenotes/notes/job-create-optional-034307a6b5db2cf2.yaml b/releasenotes/notes/job-create-optional-034307a6b5db2cf2.yaml deleted file mode 100644 index 7a603cc..0000000 --- a/releasenotes/notes/job-create-optional-034307a6b5db2cf2.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -fixes: - - > - [`bug 1506448 `_] - Now ``mains``, ``libs`` and ``description`` parameters of jobs ``create`` - method are optional. diff --git a/releasenotes/notes/job-execution-create-optional-1014a403e5ffa7ac.yaml b/releasenotes/notes/job-execution-create-optional-1014a403e5ffa7ac.yaml deleted file mode 100644 index 2b48e97..0000000 --- a/releasenotes/notes/job-execution-create-optional-1014a403e5ffa7ac.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -fixes: - - > - [`bug 1507966 `_] - Now input_id, output_id, configs parameters of job executions create - method are optional. diff --git a/releasenotes/notes/new-cli-6119bf8a4fb24ab6.yaml b/releasenotes/notes/new-cli-6119bf8a4fb24ab6.yaml deleted file mode 100644 index 0a7fdb7..0000000 --- a/releasenotes/notes/new-cli-6119bf8a4fb24ab6.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -features: - - > - New CLI as part of the openstackclient was implemented. diff --git a/releasenotes/notes/plugin-api-f650c26a030b7df8.yaml b/releasenotes/notes/plugin-api-f650c26a030b7df8.yaml deleted file mode 100644 index 20dbc4c..0000000 --- a/releasenotes/notes/plugin-api-f650c26a030b7df8.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -features: - - Plugins updates are supported now in saharaclient. Also - information about plugin labels is available for users. diff --git a/releasenotes/notes/remove-functional-tests-c4b9d43c2c32d121.yaml b/releasenotes/notes/remove-functional-tests-c4b9d43c2c32d121.yaml deleted file mode 100644 index 3475261..0000000 --- a/releasenotes/notes/remove-functional-tests-c4b9d43c2c32d121.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -prelude: > - Functional tests were replaced to sahara-tests repository. Please refer to - README of sahara-tests about how to run these tests now. diff --git a/releasenotes/notes/remove-py26-dad75fc8d602b3c5.yaml b/releasenotes/notes/remove-py26-dad75fc8d602b3c5.yaml deleted file mode 100644 index cf8f520..0000000 --- a/releasenotes/notes/remove-py26-dad75fc8d602b3c5.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -deprecations: - - > - [`bug 1519510 `_] - Support of python 2.6 was dropped. diff --git a/releasenotes/notes/remove-py33-8364cb4805391750.yaml b/releasenotes/notes/remove-py33-8364cb4805391750.yaml deleted file mode 100644 index ff68223..0000000 --- a/releasenotes/notes/remove-py33-8364cb4805391750.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -deprecations: - - > - [`bug 1526170 `_] - Support of python 3.3 was dropped. diff --git a/releasenotes/notes/rename_version_to_plugin-version-20cfe17530446391.yaml b/releasenotes/notes/rename_version_to_plugin-version-20cfe17530446391.yaml deleted file mode 100644 index d8967fd..0000000 --- a/releasenotes/notes/rename_version_to_plugin-version-20cfe17530446391.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -upgrade: - - Option 'version' is replaced by 'plugin-version' option. -fixes: - - Option 'version' is a global option, which is used for getting - the client version. So there were problems with the OpenStack client, - when we specified 'version' of the plugin, but OSC treated - that as a request for getting the current client version. Hence, to fix - this problem, 'version' is replaced by 'plugin-version'. - Related bug 1565775. diff --git a/releasenotes/notes/shares-update-d6f7e28acd27aa7f.yaml b/releasenotes/notes/shares-update-d6f7e28acd27aa7f.yaml deleted file mode 100644 index 59ab850..0000000 --- a/releasenotes/notes/shares-update-d6f7e28acd27aa7f.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -features: - - > - Now shares can be edited on an existing cluster. diff --git a/releasenotes/notes/start-using-reno-1f3418c11785c9ab.yaml b/releasenotes/notes/start-using-reno-1f3418c11785c9ab.yaml deleted file mode 100644 index 67726d9..0000000 --- a/releasenotes/notes/start-using-reno-1f3418c11785c9ab.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -other: - - > - Start using reno to manage release notes. diff --git a/releasenotes/notes/tags-update-c794416bcc035cb8.yaml b/releasenotes/notes/tags-update-c794416bcc035cb8.yaml deleted file mode 100644 index 5c35b13..0000000 --- a/releasenotes/notes/tags-update-c794416bcc035cb8.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -fixes: - - > - [`bug 1500790 `_] - Now tags can be added and removed simultaneously in one call. diff --git a/releasenotes/notes/update-image-optional-f83c5746d88507cd.yaml b/releasenotes/notes/update-image-optional-f83c5746d88507cd.yaml deleted file mode 100644 index 1211fcb..0000000 --- a/releasenotes/notes/update-image-optional-f83c5746d88507cd.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -fixes: - - > - [`bug 1510470 `_] - Now ``desc`` parameter of ``update_image`` is optional. diff --git a/releasenotes/notes/volume-mount-prefix-b6ef396a357cddd0.yaml b/releasenotes/notes/volume-mount-prefix-b6ef396a357cddd0.yaml deleted file mode 100644 index dc78b82..0000000 --- a/releasenotes/notes/volume-mount-prefix-b6ef396a357cddd0.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -fixes: - - > - [`bug 1499697 `_] - Now node group templates can be created and updated with - ``volume_mount_prefix`` parameter. diff --git a/releasenotes/source/_static/.placeholder b/releasenotes/source/_static/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/releasenotes/source/_templates/.placeholder b/releasenotes/source/_templates/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py deleted file mode 100644 index 8cb5d9e..0000000 --- a/releasenotes/source/conf.py +++ /dev/null @@ -1,219 +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. - -# Sahara Client Release Notes documentation build configuration file - -extensions = [ - 'oslosphinx', - 'reno.sphinxext', -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'Saharaclient Release Notes' -copyright = u'2015, Sahara Developers' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -from saharaclient.version import version_info as saharaclient_version -# The full version, including alpha/beta/rc tags. -release = saharaclient_version.version_string_with_vcs() -# The short X.Y version. -version = saharaclient_version.canonical_version_string() - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [] - -# 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. See the documentation for -# a list of builtin themes. -html_theme = 'default' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -# html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -# html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# html_additional_pages = {} - -# If false, no module index is generated. -# html_domain_indices = True - -# If false, no index is generated. -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'SaharaClientReleaseNotesdoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # 'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ('index', 'SaharaClientReleaseNotes.tex', - u'Sahara Client Release Notes Documentation', - u'Sahara Client Developers', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# latex_use_parts = False - -# If true, show page references after internal links. -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# latex_appendices = [] - -# If false, no module index is generated. -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'saharaclientreleasenotes', - u'Sahara Client Release Notes Documentation', - [u'Sahara Developers'], 1) -] - -# If true, show URL addresses after external links. -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'SaharaClientReleaseNotes', - u'Sahara Client Release Notes Documentation', - u'Sahara Developers', 'SaharaClientReleaseNotes', - 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -# texinfo_appendices = [] - -# If false, no module index is generated. -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# texinfo_no_detailmenu = False diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst deleted file mode 100644 index 2ab1f9d..0000000 --- a/releasenotes/source/index.rst +++ /dev/null @@ -1,9 +0,0 @@ -=========================== - Saharaclient Release Notes -=========================== - -.. toctree:: - :maxdepth: 1 - - unreleased - mitaka diff --git a/releasenotes/source/mitaka.rst b/releasenotes/source/mitaka.rst deleted file mode 100644 index e545609..0000000 --- a/releasenotes/source/mitaka.rst +++ /dev/null @@ -1,6 +0,0 @@ -=================================== - Mitaka Series Release Notes -=================================== - -.. release-notes:: - :branch: origin/stable/mitaka diff --git a/releasenotes/source/unreleased.rst b/releasenotes/source/unreleased.rst deleted file mode 100644 index cd22aab..0000000 --- a/releasenotes/source/unreleased.rst +++ /dev/null @@ -1,5 +0,0 @@ -============================== - Current Series Release Notes -============================== - -.. release-notes:: diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index c22783b..0000000 --- a/requirements.txt +++ /dev/null @@ -1,18 +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>=1.6 # Apache-2.0 - -Babel>=2.3.4 # BSD -keystoneauth1>=2.10.0 # Apache-2.0 -osc-lib>=0.4.0 # Apache-2.0 -oslo.log>=1.14.0 # Apache-2.0 -oslo.serialization>=1.10.0 # Apache-2.0 -oslo.i18n>=2.1.0 # Apache-2.0 -oslo.utils>=3.16.0 # Apache-2.0 -python-keystoneclient!=1.8.0,!=2.1.0,>=1.7.0 # Apache-2.0 -python-openstackclient>=2.1.0 # Apache-2.0 -requests>=2.10.0 # Apache-2.0 -six>=1.9.0 # MIT -PrettyTable<0.8,>=0.7 # BSD diff --git a/run_tests.sh b/run_tests.sh deleted file mode 100755 index f5ebe5b..0000000 --- a/run_tests.sh +++ /dev/null @@ -1,164 +0,0 @@ -#!/bin/bash - -set -eu - -function usage { - echo "Usage: $0 [OPTION]..." - echo "Run python-saharaclient test suite" - echo "" - echo " -V, --virtual-env Always use virtualenv. Install automatically if not present" - echo " -N, --no-virtual-env Don't use virtualenv. Run tests in local environment" - echo " -s, --no-site-packages Isolate the virtualenv from the global Python environment" - echo " -x, --stop Stop running tests after the first error or failure." - echo " -f, --force Force a clean re-build of the virtual environment. Useful when dependencies have been added." - echo " -p, --pep8 Just run pep8" - echo " -P, --no-pep8 Don't run pep8" - echo " -c, --coverage Generate coverage report" - echo " -h, --help Print this usage message" - echo " --hide-elapsed Don't print the elapsed time for each test along with slow test list" - echo "" - echo "Note: with no options specified, the script will try to run the tests in a virtual environment," - echo " If no virtualenv is found, the script will ask if you would like to create one. If you " - echo " prefer to run tests NOT in a virtual environment, simply pass the -N option." - exit -} - -function process_option { - case "$1" in - -h|--help) usage;; - -V|--virtual-env) always_venv=1; never_venv=0;; - -N|--no-virtual-env) always_venv=0; never_venv=1;; - -s|--no-site-packages) no_site_packages=1;; - -f|--force) force=1;; - -p|--pep8) just_pep8=1;; - -P|--no-pep8) no_pep8=1;; - -c|--coverage) coverage=1;; - -*) testropts="$testropts $1";; - *) testrargs="$testrargs $1" - esac -} - -venv=.venv -with_venv=tools/with_venv.sh -always_venv=0 -never_venv=0 -force=0 -no_site_packages=0 -installvenvopts= -testrargs= -testropts= -wrapper="" -just_pep8=0 -no_pep8=0 -coverage=0 - -LANG=en_US.UTF-8 -LANGUAGE=en_US:en -LC_ALL=C - -for arg in "$@"; do - process_option $arg -done - -if [ $no_site_packages -eq 1 ]; then - installvenvopts="--no-site-packages" -fi - -function init_testr { - if [ ! -d .testrepository ]; then - ${wrapper} testr init - fi -} - -function run_tests { - # Cleanup *pyc - ${wrapper} find . -type f -name "*.pyc" -delete - - if [ $coverage -eq 1 ]; then - # Do not test test_coverage_ext when gathering coverage. - if [ "x$testrargs" = "x" ]; then - testrargs="^(?!.*test_coverage_ext).*$" - fi - export PYTHON="${wrapper} coverage run --source saharaclient --parallel-mode" - fi - # Just run the test suites in current environment - set +e - TESTRTESTS="$TESTRTESTS $testrargs" - echo "Running \`${wrapper} $TESTRTESTS\`" - ${wrapper} $TESTRTESTS - RESULT=$? - set -e - - copy_subunit_log - - return $RESULT -} - -function copy_subunit_log { - LOGNAME=`cat .testrepository/next-stream` - LOGNAME=$(($LOGNAME - 1)) - LOGNAME=".testrepository/${LOGNAME}" - cp $LOGNAME subunit.log -} - -function run_pep8 { - echo "Running flake8 ..." - ${wrapper} flake8 -} - -TESTRTESTS="testr run --parallel $testropts" - -if [ $never_venv -eq 0 ] -then - # Remove the virtual environment if --force used - if [ $force -eq 1 ]; then - echo "Cleaning virtualenv..." - rm -rf ${venv} - fi - if [ -e ${venv} ]; then - wrapper="${with_venv}" - else - if [ $always_venv -eq 1 ]; then - # Automatically install the virtualenv - python tools/install_venv.py $installvenvopts - wrapper="${with_venv}" - else - echo -e "No virtual environment found...create one? (Y/n) \c" - read use_ve - if [ "x$use_ve" = "xY" -o "x$use_ve" = "x" -o "x$use_ve" = "xy" ]; then - # Install the virtualenv and run the test suite in it - python tools/install_venv.py $installvenvopts - wrapper=${with_venv} - fi - fi - fi -fi - -# Delete old coverage data from previous runs -if [ $coverage -eq 1 ]; then - ${wrapper} coverage erase -fi - -if [ $just_pep8 -eq 1 ]; then - run_pep8 - exit -fi - -init_testr -run_tests - -# NOTE(sirp): we only want to run pep8 when we're running the full-test suite, -# not when we're running tests individually. To handle this, we need to -# distinguish between options (noseopts), which begin with a '-', and -# arguments (testrargs). -if [ -z "$testrargs" ]; then - if [ $no_pep8 -eq 0 ]; then - run_pep8 - fi -fi - -if [ $coverage -eq 1 ]; then - echo "Generating coverage report in covhtml/" - ${wrapper} coverage combine - ${wrapper} coverage html --include='saharaclient/*' --omit='saharaclient/openstack/common/*' -d covhtml -i -fi diff --git a/saharaclient/__init__.py b/saharaclient/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/saharaclient/api/__init__.py b/saharaclient/api/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/saharaclient/api/base.py b/saharaclient/api/base.py deleted file mode 100644 index 36c9e45..0000000 --- a/saharaclient/api/base.py +++ /dev/null @@ -1,281 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import copy -import json -import logging - -import six -from six.moves.urllib import parse - -from saharaclient.openstack.common._i18n import _ - -LOG = logging.getLogger(__name__) - - -class Resource(object): - resource_name = 'Something' - defaults = {} - - def __init__(self, manager, info): - self.manager = manager - info = info.copy() - self._info = info - self._set_defaults(info) - self._add_details(info) - - def _set_defaults(self, info): - for name, value in six.iteritems(self.defaults): - if name not in info: - info[name] = value - - def _add_details(self, info): - for (k, v) in six.iteritems(info): - try: - setattr(self, k, v) - self._info[k] = v - except AttributeError: - # In this case we already defined the attribute on the class - pass - - def to_dict(self): - return copy.deepcopy(self._info) - - def __str__(self): - return '%s %s' % (self.resource_name, str(self._info)) - - -def _check_items(obj, searches): - try: - return all(getattr(obj, attr) == value for (attr, value) in searches) - except AttributeError: - return False - - -class NotUpdated(object): - """A sentinel class to signal that parameter should not be updated.""" - def __repr__(self): - return 'NotUpdated' - - -class ResourceManager(object): - resource_class = None - - def __init__(self, api): - self.api = api - - def find(self, **kwargs): - return [i for i in self.list() if _check_items(i, kwargs.items())] - - def find_unique(self, **kwargs): - found = self.find(**kwargs) - if not found: - raise APIException(error_code=404, - error_message=_("No matches found.")) - if len(found) > 1: - raise APIException(error_code=409, - error_message=_("Multiple matches found.")) - return found[0] - - def _copy_if_defined(self, data, **kwargs): - for var_name, var_value in six.iteritems(kwargs): - if var_value is not None: - data[var_name] = var_value - - def _copy_if_updated(self, data, **kwargs): - for var_name, var_value in six.iteritems(kwargs): - if not isinstance(var_value, NotUpdated): - data[var_name] = var_value - - def _create(self, url, data, response_key=None, dump_json=True): - if dump_json: - kwargs = {'json': data} - else: - kwargs = {'data': data} - - resp = self.api.post(url, **kwargs) - - if resp.status_code != 202: - self._raise_api_exception(resp) - - if response_key is not None: - data = get_json(resp)[response_key] - else: - data = get_json(resp) - return self.resource_class(self, data) - - def _update(self, url, data, response_key=None, dump_json=True): - if dump_json: - kwargs = {'json': data} - else: - kwargs = {'data': data} - - resp = self.api.put(url, **kwargs) - - if resp.status_code != 202: - self._raise_api_exception(resp) - if response_key is not None: - data = get_json(resp)[response_key] - else: - data = get_json(resp) - - return self.resource_class(self, data) - - def _patch(self, url, data, response_key=None, dump_json=True): - if dump_json: - kwargs = {'json': data} - else: - kwargs = {'data': data} - - resp = self.api.patch(url, **kwargs) - - if resp.status_code != 202: - self._raise_api_exception(resp) - if response_key is not None: - data = get_json(resp)[response_key] - else: - data = get_json(resp) - - return self.resource_class(self, data) - - def _post(self, url, data, response_key=None, dump_json=True): - if dump_json: - kwargs = {'json': data} - else: - kwargs = {'data': data} - - resp = self.api.post(url, **kwargs) - - if resp.status_code != 202: - self._raise_api_exception(resp) - - if response_key is not None: - data = get_json(resp)[response_key] - else: - data = get_json(resp) - - return self.resource_class(self, data) - - def _list(self, url, response_key): - resp = self.api.get(url) - if resp.status_code == 200: - data = get_json(resp)[response_key] - - return [self.resource_class(self, res) - for res in data] - else: - self._raise_api_exception(resp) - - def _page(self, url, response_key, limit=None): - resp = self.api.get(url) - if resp.status_code == 200: - result = get_json(resp) - data = result[response_key] - meta = result.get('markers') - - next, prev = None, None - - if meta: - prev = meta.get('prev') - next = meta.get('next') - - l = [self.resource_class(self, res) - for res in data] - - return Page(l, prev, next, limit) - else: - self._raise_api_exception(resp) - - def _get(self, url, response_key=None): - resp = self.api.get(url) - - if resp.status_code == 200: - if response_key is not None: - data = get_json(resp)[response_key] - else: - data = get_json(resp) - return self.resource_class(self, data) - else: - self._raise_api_exception(resp) - - def _delete(self, url): - resp = self.api.delete(url) - - if resp.status_code != 204: - self._raise_api_exception(resp) - - def _plurify_resource_name(self): - return self.resource_class.resource_name + 's' - - def _raise_api_exception(self, resp): - try: - error_data = get_json(resp) - except Exception: - msg = _("Failed to parse response from Sahara: %s") % resp.reason - raise APIException( - error_code=resp.status_code, - error_message=msg) - - raise APIException(error_code=error_data.get("error_code"), - error_name=error_data.get("error_name"), - error_message=error_data.get("error_message")) - - -def get_json(response): - """Provide backward compatibility with old versions of requests library.""" - - json_field_or_function = getattr(response, 'json', None) - if callable(json_field_or_function): - return response.json() - else: - return json.loads(response.content) - - -class APIException(Exception): - def __init__(self, error_code=None, error_name=None, error_message=None): - super(APIException, self).__init__(error_message) - self.error_code = error_code - self.error_name = error_name - self.error_message = error_message - - -def get_query_string(search_opts, limit=None, marker=None, sort_by=None, - reverse=None): - opts = {} - if marker is not None: - opts['marker'] = marker - if limit is not None: - opts['limit'] = limit - if sort_by is not None: - if reverse: - opts['sort_by'] = "-%s" % sort_by - else: - opts['sort_by'] = sort_by - if search_opts is not None: - opts.update(search_opts) - if opts: - qparams = sorted(opts.items(), key=lambda x: x[0]) - query_string = "?%s" % parse.urlencode(qparams, doseq=True) - else: - query_string = "" - return query_string - - -class Page(list): - def __init__(self, l, prev, next, limit): - super(Page, self).__init__(l) - self.prev = prev - self.next = next - self.limit = limit diff --git a/saharaclient/api/client.py b/saharaclient/api/client.py deleted file mode 100644 index 1fd7602..0000000 --- a/saharaclient/api/client.py +++ /dev/null @@ -1,188 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import warnings - -from keystoneauth1 import adapter -from keystoneauth1 import exceptions -from keystoneauth1.identity import v2 -from keystoneauth1.identity import v3 -from keystoneauth1 import session as keystone_session -from keystoneauth1 import token_endpoint - -from saharaclient.api import cluster_templates -from saharaclient.api import clusters -from saharaclient.api import data_sources -from saharaclient.api import images -from saharaclient.api import job_binaries -from saharaclient.api import job_binary_internals -from saharaclient.api import job_executions -from saharaclient.api import job_types -from saharaclient.api import jobs -from saharaclient.api import node_group_templates -from saharaclient.api import plugins - - -USER_AGENT = 'python-saharaclient' - - -class HTTPClient(adapter.Adapter): - - def request(self, *args, **kwargs): - kwargs.setdefault('raise_exc', False) - return super(HTTPClient, self).request(*args, **kwargs) - - -class Client(object): - """Client for the OpenStack Data Processing v1 API. - - :param str username: Username for Keystone authentication. - :param str api_key: Password for Keystone authentication. - :param str project_id: Keystone Tenant id. - :param str project_name: Keystone Tenant name. - :param str auth_url: Keystone URL that will be used for authentication. - :param str sahara_url: Sahara REST API URL to communicate with. - :param str endpoint_type: Desired Sahara endpoint type. - :param str service_type: Sahara service name in Keystone catalog. - :param str input_auth_token: Keystone authorization token. - :param session: Keystone Session object. - :param auth: Keystone Authentication Plugin object. - :param boolean insecure: Allow insecure. - :param string cacert: Path to the Privacy Enhanced Mail (PEM) file - which contains certificates needed to establish - SSL connection with the identity service. - :param string region_name: Name of a region to select when choosing an - endpoint from the service catalog. - """ - def __init__(self, username=None, api_key=None, project_id=None, - project_name=None, auth_url=None, sahara_url=None, - endpoint_type='publicURL', service_type='data-processing', - input_auth_token=None, session=None, auth=None, - insecure=False, cacert=None, region_name=None, **kwargs): - - if not session: - warnings.simplefilter('once', category=DeprecationWarning) - warnings.warn('Passing authentication parameters to saharaclient ' - 'is deprecated. Please construct and pass an ' - 'authenticated session object directly.', - DeprecationWarning) - warnings.resetwarnings() - - if input_auth_token: - auth = token_endpoint.Token(sahara_url, input_auth_token) - - else: - auth = self._get_keystone_auth(auth_url=auth_url, - username=username, - api_key=api_key, - project_id=project_id, - project_name=project_name) - - verify = True - if insecure: - verify = False - elif cacert: - verify = cacert - - session = keystone_session.Session(verify=verify) - - if not auth: - auth = session.auth - - # NOTE(Toan): bug #1512801. If sahara_url is provided, it does not - # matter if service_type is orthographically correct or not. - # Only find Sahara service_type and endpoint in Keystone catalog - # if sahara_url is not provided. - if not sahara_url: - service_type = self._determine_service_type(session, - auth, - service_type, - endpoint_type) - - kwargs['user_agent'] = USER_AGENT - kwargs.setdefault('interface', endpoint_type) - kwargs.setdefault('endpoint_override', sahara_url) - - client = HTTPClient(session=session, - auth=auth, - service_type=service_type, - region_name=region_name, - **kwargs) - - self.clusters = clusters.ClusterManager(client) - self.cluster_templates = ( - cluster_templates.ClusterTemplateManager(client) - ) - self.node_group_templates = ( - node_group_templates.NodeGroupTemplateManager(client) - ) - self.plugins = plugins.PluginManager(client) - self.images = images.ImageManager(client) - - self.data_sources = data_sources.DataSourceManager(client) - self.jobs = jobs.JobsManager(client) - self.job_executions = job_executions.JobExecutionsManager(client) - self.job_binaries = job_binaries.JobBinariesManager(client) - self.job_binary_internals = ( - job_binary_internals.JobBinaryInternalsManager(client) - ) - self.job_types = job_types.JobTypesManager(client) - - def _get_keystone_auth(self, username=None, api_key=None, auth_url=None, - project_id=None, project_name=None): - if not auth_url: - raise RuntimeError("No auth url specified") - - if 'v2.0' in auth_url: - return v2.Password(auth_url=auth_url, - username=username, - password=api_key, - tenant_id=project_id, - tenant_name=project_name) - else: - # NOTE(jamielennox): Setting these to default is what - # keystoneclient does in the event they are not passed. - return v3.Password(auth_url=auth_url, - username=username, - password=api_key, - user_domain_id='default', - project_id=project_id, - project_name=project_name, - project_domain_id='default') - - @staticmethod - def _determine_service_type(session, auth, service_type, interface): - """Check a catalog for data-processing or data_processing""" - - # NOTE(jamielennox): calling get_endpoint forces an auth on - # initialization which is required for backwards compatibility. It - # also allows us to reset the service type if not in the catalog. - for st in (service_type, service_type.replace('-', '_')): - try: - url = auth.get_endpoint(session, - service_type=st, - interface=interface) - except exceptions.Unauthorized: - raise RuntimeError("Not Authorized") - except exceptions.EndpointNotFound: - # NOTE(jamielennox): bug #1428447. This should not be - # raised, instead None should be returned. Handle in case - # it changes in the future - url = None - - if url: - return st - - raise RuntimeError("Could not find Sahara endpoint in catalog") diff --git a/saharaclient/api/cluster_templates.py b/saharaclient/api/cluster_templates.py deleted file mode 100644 index 9c7bd43..0000000 --- a/saharaclient/api/cluster_templates.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from saharaclient.api import base - - -class ClusterTemplate(base.Resource): - resource_name = 'Cluster Template' - - -class ClusterTemplateManager(base.ResourceManager): - resource_class = ClusterTemplate - NotUpdated = base.NotUpdated() - - def create(self, name, plugin_name, hadoop_version, description=None, - cluster_configs=None, node_groups=None, anti_affinity=None, - net_id=None, default_image_id=None, use_autoconfig=None, - shares=None, is_public=None, is_protected=None, - domain_name=None): - """Create a Cluster Template.""" - - data = { - 'name': name, - 'plugin_name': plugin_name, - 'hadoop_version': hadoop_version, - } - - self._copy_if_defined(data, - description=description, - cluster_configs=cluster_configs, - node_groups=node_groups, - anti_affinity=anti_affinity, - neutron_management_network=net_id, - default_image_id=default_image_id, - use_autoconfig=use_autoconfig, - shares=shares, - is_public=is_public, - is_protected=is_protected, - domain_name=domain_name) - - return self._create('/cluster-templates', data, 'cluster_template') - - def update(self, cluster_template_id, name=NotUpdated, - plugin_name=NotUpdated, hadoop_version=NotUpdated, - description=NotUpdated, cluster_configs=NotUpdated, - node_groups=NotUpdated, anti_affinity=NotUpdated, - net_id=NotUpdated, default_image_id=NotUpdated, - use_autoconfig=NotUpdated, shares=NotUpdated, - is_public=NotUpdated, is_protected=NotUpdated, - domain_name=NotUpdated): - """Update a Cluster Template.""" - - data = {} - self._copy_if_updated(data, name=name, - plugin_name=plugin_name, - hadoop_version=hadoop_version, - description=description, - cluster_configs=cluster_configs, - node_groups=node_groups, - anti_affinity=anti_affinity, - neutron_management_network=net_id, - default_image_id=default_image_id, - use_autoconfig=use_autoconfig, - shares=shares, - is_public=is_public, - is_protected=is_protected, - domain_name=domain_name) - - return self._update('/cluster-templates/%s' % cluster_template_id, - data, 'cluster_template') - - def list(self, search_opts=None, marker=None, - limit=None, sort_by=None, reverse=None): - """Get list of Cluster Templates.""" - query = base.get_query_string(search_opts, marker=marker, limit=limit, - sort_by=sort_by, reverse=reverse) - url = "/cluster-templates%s" % query - return self._page(url, 'cluster_templates', limit) - - def get(self, cluster_template_id): - """Get information about a Cluster Template.""" - return self._get('/cluster-templates/%s' % cluster_template_id, - 'cluster_template') - - def delete(self, cluster_template_id): - """Delete a Cluster Template.""" - self._delete('/cluster-templates/%s' % cluster_template_id) diff --git a/saharaclient/api/clusters.py b/saharaclient/api/clusters.py deleted file mode 100644 index fde5916..0000000 --- a/saharaclient/api/clusters.py +++ /dev/null @@ -1,138 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from six.moves.urllib import parse - -from saharaclient.api import base - - -class Cluster(base.Resource): - resource_name = 'Cluster' - - -class ClusterManager(base.ResourceManager): - resource_class = Cluster - NotUpdated = base.NotUpdated() - - def create(self, name, plugin_name, hadoop_version, - cluster_template_id=None, default_image_id=None, - is_transient=None, description=None, cluster_configs=None, - node_groups=None, user_keypair_id=None, - anti_affinity=None, net_id=None, count=None, - use_autoconfig=None, shares=None, - is_public=None, is_protected=None): - """Launch a Cluster.""" - - data = { - 'name': name, - 'plugin_name': plugin_name, - 'hadoop_version': hadoop_version, - } - - # Checking if count is greater than 1, otherwise we set it to None - # so the created dict in the _copy_if_defined method does not contain - # the count parameter. - if count and count <= 1: - count = None - - self._copy_if_defined(data, - cluster_template_id=cluster_template_id, - is_transient=is_transient, - default_image_id=default_image_id, - description=description, - cluster_configs=cluster_configs, - node_groups=node_groups, - user_keypair_id=user_keypair_id, - anti_affinity=anti_affinity, - neutron_management_network=net_id, - count=count, - use_autoconfig=use_autoconfig, - shares=shares, - is_public=is_public, - is_protected=is_protected) - - if count: - return self._create('/clusters/multiple', data) - - return self._create('/clusters', data, 'cluster') - - def scale(self, cluster_id, scale_object): - """Scale an existing Cluster. - - :param scale_object: dict that describes scaling operation - - :Example: - - The following `scale_object` can be used to change the number of - instances in the node group and add instances of new node group to - existing cluster: - - .. sourcecode:: json - - { - "add_node_groups": [ - { - "count": 3, - "name": "new_ng", - "node_group_template_id": "ngt_id" - } - ], - "resize_node_groups": [ - { - "count": 2, - "name": "old_ng" - } - ] - } - - """ - return self._update('/clusters/%s' % cluster_id, scale_object) - - def list(self, search_opts=None, limit=None, marker=None, - sort_by=None, reverse=None): - """Get a list of Clusters.""" - query = base.get_query_string(search_opts, limit=limit, marker=marker, - sort_by=sort_by, reverse=reverse) - url = "/clusters%s" % query - return self._page(url, 'clusters', limit) - - def get(self, cluster_id, show_progress=False): - """Get information about a Cluster.""" - url = ('/clusters/%(cluster_id)s?%(params)s' % - {"cluster_id": cluster_id, - "params": parse.urlencode({"show_progress": show_progress})}) - - return self._get(url, 'cluster') - - def delete(self, cluster_id): - """Delete a Cluster.""" - self._delete('/clusters/%s' % cluster_id) - - def update(self, cluster_id, name=NotUpdated, description=NotUpdated, - is_public=NotUpdated, is_protected=NotUpdated, - shares=NotUpdated): - """Update a Cluster.""" - - data = {} - self._copy_if_updated(data, name=name, description=description, - is_public=is_public, is_protected=is_protected, - shares=shares) - - return self._patch('/clusters/%s' % cluster_id, data) - - def verification_update(self, cluster_id, status): - """Start a verification for a Cluster.""" - data = {'verification': {'status': status}} - return self._patch("/clusters/%s" % cluster_id, data) diff --git a/saharaclient/api/data_sources.py b/saharaclient/api/data_sources.py deleted file mode 100644 index 112cca5..0000000 --- a/saharaclient/api/data_sources.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from saharaclient.api import base - - -class DataSources(base.Resource): - resource_name = 'Data Source' - - -class DataSourceManager(base.ResourceManager): - resource_class = DataSources - - def create(self, name, description, data_source_type, - url, credential_user=None, credential_pass=None, - is_public=None, is_protected=None): - """Create a Data Source.""" - - data = { - 'name': name, - 'description': description, - 'type': data_source_type, - 'url': url, - 'credentials': {} - } - self._copy_if_defined(data['credentials'], - user=credential_user, - password=credential_pass) - - self._copy_if_defined(data, is_public=is_public, - is_protected=is_protected) - - return self._create('/data-sources', data, 'data_source') - - def list(self, search_opts=None, limit=None, marker=None, - sort_by=None, reverse=None): - """Get a list of Data Sources.""" - query = base.get_query_string(search_opts, limit=limit, marker=marker, - sort_by=sort_by, reverse=reverse) - url = "/data-sources%s" % query - return self._page(url, 'data_sources', limit) - - def get(self, data_source_id): - """Get information about a Data Source.""" - return self._get('/data-sources/%s' % data_source_id, 'data_source') - - def delete(self, data_source_id): - """Delete a Data Source.""" - self._delete('/data-sources/%s' % data_source_id) - - def update(self, data_source_id, update_data): - """Update a Data Source. - - :param dict update_data: dict that contains fields that should be - updated with new values. - - Fields that can be updated: - - * name - * description - * type - * url - * is_public - * is_protected - * credentials - dict with `user` and `password` keyword arguments - """ - return self._update('/data-sources/%s' % data_source_id, - update_data) diff --git a/saharaclient/api/helpers.py b/saharaclient/api/helpers.py deleted file mode 100644 index 6633c92..0000000 --- a/saharaclient/api/helpers.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from saharaclient.api import parameters as params - - -class Helpers(object): - def __init__(self, sahara_client): - self.sahara = sahara_client - self.plugins = self.sahara.plugins - - def _get_node_processes(self, plugin): - processes = [] - for proc_lst in plugin.node_processes.values(): - processes += proc_lst - - return [(proc_name, proc_name) for proc_name in processes] - - def get_node_processes(self, plugin_name, hadoop_version): - plugin = self.plugins.get_version_details(plugin_name, hadoop_version) - - return self._get_node_processes(plugin) - - def _extract_parameters(self, configs, scope, applicable_target): - parameters = [] - for config in configs: - if (config['scope'] == scope and - config['applicable_target'] == applicable_target): - - parameters.append(params.Parameter(config)) - - return parameters - - def get_cluster_general_configs(self, plugin_name, hadoop_version): - plugin = self.plugins.get_version_details(plugin_name, hadoop_version) - - return self._extract_parameters(plugin.configs, 'cluster', "general") - - def get_general_node_group_configs(self, plugin_name, hadoop_version): - plugin = self.plugins.get_version_details(plugin_name, hadoop_version) - - return self._extract_parameters(plugin.configs, 'node', 'general') - - def get_targeted_node_group_configs(self, plugin_name, hadoop_version): - plugin = self.plugins.get_version_details(plugin_name, hadoop_version) - - parameters = dict() - - for service in plugin.node_processes.keys(): - parameters[service] = self._extract_parameters(plugin.configs, - 'node', service) - - return parameters - - def get_targeted_cluster_configs(self, plugin_name, hadoop_version): - plugin = self.plugins.get_version_details(plugin_name, hadoop_version) - - parameters = dict() - - for service in plugin.node_processes.keys(): - parameters[service] = self._extract_parameters(plugin.configs, - 'cluster', service) - - return parameters diff --git a/saharaclient/api/images.py b/saharaclient/api/images.py deleted file mode 100644 index c10033b..0000000 --- a/saharaclient/api/images.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from saharaclient.api import base - - -class Image(base.Resource): - resource_name = 'Image' - defaults = {'description': ''} - - -class ImageManager(base.ResourceManager): - resource_class = Image - - def list(self, search_opts=None): - """Get a list of registered images.""" - query = base.get_query_string(search_opts) - return self._list('/images%s' % query, 'images') - - def get(self, id): - """Get information about an image""" - return self._get('/images/%s' % id, 'image') - - def unregister_image(self, image_id): - """Remove an Image from Sahara Image Registry.""" - self._delete('/images/%s' % image_id) - - def update_image(self, image_id, user_name, desc=None): - """Create or update an Image in Image Registry.""" - desc = desc if desc else '' - data = {"username": user_name, - "description": desc} - - return self._post('/images/%s' % image_id, data) - - def update_tags(self, image_id, new_tags): - """Update an Image tags. - - :param list new_tags: list of tags that will replace currently - assigned tags - """ - old_image = self.get(image_id) - - old_tags = frozenset(old_image.tags) - new_tags = frozenset(new_tags) - - to_add = list(new_tags - old_tags) - to_remove = list(old_tags - new_tags) - - add_response, remove_response = None, None - - if to_add: - add_response = self._post('/images/%s/tag' % image_id, - {'tags': to_add}, 'image') - - if to_remove: - remove_response = self._post('/images/%s/untag' % image_id, - {'tags': to_remove}, 'image') - - return remove_response or add_response or self.get(image_id) diff --git a/saharaclient/api/job_binaries.py b/saharaclient/api/job_binaries.py deleted file mode 100644 index 38637e3..0000000 --- a/saharaclient/api/job_binaries.py +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from saharaclient.api import base - - -class JobBinaries(base.Resource): - resource_name = 'Job Binary' - - -class JobBinariesManager(base.ResourceManager): - resource_class = JobBinaries - - def create(self, name, url, description=None, extra=None, is_public=None, - is_protected=None): - """Create a Job Binary.""" - data = { - "name": name, - "url": url - } - - self._copy_if_defined(data, description=description, extra=extra, - is_public=is_public, is_protected=is_protected) - - return self._create('/job-binaries', data, 'job_binary') - - def list(self, search_opts=None, limit=None, marker=None, - sort_by=None, reverse=None): - """Get a list of Job Binaries.""" - query = base.get_query_string(search_opts, limit=limit, marker=marker, - sort_by=sort_by, reverse=reverse) - url = "/job-binaries%s" % query - return self._page(url, 'binaries', limit) - - def get(self, job_binary_id): - """Get information about a Job Binary.""" - return self._get('/job-binaries/%s' % job_binary_id, 'job_binary') - - def delete(self, job_binary_id): - """Delete a Job Binary.""" - self._delete('/job-binaries/%s' % job_binary_id) - - def get_file(self, job_binary_id): - """Download a Job Binary.""" - resp = self.api.get('/job-binaries/%s/data' % job_binary_id) - - if resp.status_code != 200: - self._raise_api_exception(resp) - return resp.content - - def update(self, job_binary_id, data): - """Update Job Binary. - - :param dict data: dict that contains fields that should be updated - with new values. - - Fields that can be updated: - - * name - * description - * url - * is_public - * is_protected - * extra - dict with `user` and `password` keyword arguments - """ - return self._update( - '/job-binaries/%s' % job_binary_id, data, 'job_binary') diff --git a/saharaclient/api/job_binary_internals.py b/saharaclient/api/job_binary_internals.py deleted file mode 100644 index 9c7b139..0000000 --- a/saharaclient/api/job_binary_internals.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from six.moves.urllib import parse as urlparse - -from saharaclient.api import base - - -class JobBinaryInternal(base.Resource): - resource_name = 'JobBinaryInternal' - - -class JobBinaryInternalsManager(base.ResourceManager): - resource_class = JobBinaryInternal - NotUpdated = base.NotUpdated() - - def create(self, name, data): - """Create a Job Binary Internal. - - :param str data: raw data ot script text - """ - return self._update('/job-binary-internals/%s' % - urlparse.quote(name.encode('utf-8')), data, - 'job_binary_internal', dump_json=False) - - def list(self, search_opts=None, limit=None, marker=None, - sort_by=None, reverse=None): - """Get a list of Job Binary Internals.""" - query = base.get_query_string(search_opts, limit=limit, marker=marker, - sort_by=sort_by, reverse=reverse) - url = "/job-binary-internals%s" % query - return self._page(url, 'binaries', limit) - - def get(self, job_binary_id): - """Get information about a Job Binary Internal.""" - return self._get('/job-binary-internals/%s' % job_binary_id, - 'job_binary_internal') - - def delete(self, job_binary_id): - """Delete a Job Binary Internal.""" - self._delete('/job-binary-internals/%s' % job_binary_id) - - def update(self, job_binary_id, name=NotUpdated, is_public=NotUpdated, - is_protected=NotUpdated): - """Update a Job Binary Internal.""" - - data = {} - self._copy_if_updated(data, name=name, is_public=is_public, - is_protected=is_protected) - - return self._patch('/job-binary-internals/%s' % job_binary_id, data) diff --git a/saharaclient/api/job_executions.py b/saharaclient/api/job_executions.py deleted file mode 100644 index a76597a..0000000 --- a/saharaclient/api/job_executions.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from saharaclient.api import base - - -class JobExecution(base.Resource): - resource_name = 'JobExecution' - - -class JobExecutionsManager(base.ResourceManager): - resource_class = JobExecution - NotUpdated = base.NotUpdated() - - def list(self, search_opts=None, marker=None, limit=None, - sort_by=None, reverse=None): - """Get a list of Job Executions.""" - query = base.get_query_string(search_opts, limit=limit, marker=marker, - sort_by=sort_by, reverse=reverse) - url = "/job-executions%s" % query - return self._page(url, 'job_executions', limit) - - def get(self, obj_id): - """Get information about a Job Execution.""" - return self._get('/job-executions/%s' % obj_id, 'job_execution') - - def delete(self, obj_id): - """Delete a Job Execution.""" - self._delete('/job-executions/%s' % obj_id) - - def create(self, job_id, cluster_id, input_id=None, - output_id=None, configs=None, interface=None, is_public=None, - is_protected=None): - """Launch a Job.""" - - url = "/jobs/%s/execute" % job_id - data = { - "cluster_id": cluster_id, - } - - self._copy_if_defined(data, input_id=input_id, output_id=output_id, - job_configs=configs, interface=interface, - is_public=is_public, is_protected=is_protected) - - return self._create(url, data, 'job_execution') - - def update(self, obj_id, is_public=NotUpdated, is_protected=NotUpdated): - """Update a Job Execution.""" - - data = {} - self._copy_if_updated(data, is_public=is_public, - is_protected=is_protected) - return self._patch('/job-executions/%s' % obj_id, data) diff --git a/saharaclient/api/job_types.py b/saharaclient/api/job_types.py deleted file mode 100644 index 25eed81..0000000 --- a/saharaclient/api/job_types.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2015 Red Hat Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from saharaclient.api import base - - -class JobType(base.Resource): - resource_name = 'JobType' - - -class JobTypesManager(base.ResourceManager): - resource_class = JobType - - def list(self, search_opts=None): - """Get a list of job types supported by plugins.""" - query = base.get_query_string(search_opts) - return self._list('/job-types%s' % query, 'job_types') diff --git a/saharaclient/api/jobs.py b/saharaclient/api/jobs.py deleted file mode 100644 index 8fdde51..0000000 --- a/saharaclient/api/jobs.py +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from saharaclient.api import base - - -class Job(base.Resource): - resource_name = 'Job' - - -class JobsManager(base.ResourceManager): - resource_class = Job - NotUpdated = base.NotUpdated() - - def create(self, name, type, mains=None, libs=None, description=None, - interface=None, is_public=None, is_protected=None): - """Create a Job.""" - data = { - 'name': name, - 'type': type - } - - self._copy_if_defined(data, description=description, mains=mains, - libs=libs, interface=interface, - is_public=is_public, is_protected=is_protected) - - return self._create('/jobs', data, 'job') - - def list(self, search_opts=None, limit=None, - marker=None, sort_by=None, reverse=None): - """Get a list of Jobs.""" - query = base.get_query_string(search_opts, limit=limit, marker=marker, - sort_by=sort_by, reverse=reverse) - url = "/jobs%s" % query - return self._page(url, 'jobs', limit) - - def get(self, job_id): - """Get information about a Job""" - return self._get('/jobs/%s' % job_id, 'job') - - def get_configs(self, job_type): - """Get config hints for a specified Job type.""" - return self._get('/jobs/config-hints/%s' % job_type) - - def delete(self, job_id): - """Delete a Job""" - self._delete('/jobs/%s' % job_id) - - def update(self, job_id, name=NotUpdated, description=NotUpdated, - is_public=NotUpdated, is_protected=NotUpdated): - """Update a Job.""" - - data = {} - self._copy_if_updated(data, name=name, description=description, - is_public=is_public, is_protected=is_protected) - - return self._patch('/jobs/%s' % job_id, data) diff --git a/saharaclient/api/node_group_templates.py b/saharaclient/api/node_group_templates.py deleted file mode 100644 index 90c1b4d..0000000 --- a/saharaclient/api/node_group_templates.py +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from saharaclient.api import base - - -class NodeGroupTemplate(base.Resource): - resource_name = 'Node Group Template' - - -class NodeGroupTemplateManager(base.ResourceManager): - resource_class = NodeGroupTemplate - NotUpdated = base.NotUpdated() - - def create(self, name, plugin_name, hadoop_version, flavor_id, - description=None, volumes_per_node=None, volumes_size=None, - node_processes=None, node_configs=None, floating_ip_pool=None, - security_groups=None, auto_security_group=None, - availability_zone=None, volumes_availability_zone=None, - volume_type=None, image_id=None, is_proxy_gateway=None, - volume_local_to_instance=None, use_autoconfig=None, - shares=None, is_public=None, is_protected=None, - volume_mount_prefix=None): - """Create a Node Group Template.""" - - data = { - 'name': name, - 'plugin_name': plugin_name, - 'hadoop_version': hadoop_version, - 'flavor_id': flavor_id, - 'node_processes': node_processes - } - - self._copy_if_defined(data, - description=description, - node_configs=node_configs, - floating_ip_pool=floating_ip_pool, - security_groups=security_groups, - auto_security_group=auto_security_group, - availability_zone=availability_zone, - image_id=image_id, - is_proxy_gateway=is_proxy_gateway, - use_autoconfig=use_autoconfig, - shares=shares, - is_public=is_public, - is_protected=is_protected - ) - - if volumes_per_node: - data.update({"volumes_per_node": volumes_per_node, - "volumes_size": volumes_size}) - if volumes_availability_zone: - data.update({"volumes_availability_zone": - volumes_availability_zone}) - if volume_type: - data.update({"volume_type": volume_type}) - if volume_local_to_instance: - data.update( - {"volume_local_to_instance": volume_local_to_instance}) - if volume_mount_prefix: - data.update({"volume_mount_prefix": volume_mount_prefix}) - - return self._create('/node-group-templates', data, - 'node_group_template') - - def update(self, ng_template_id, name=NotUpdated, plugin_name=NotUpdated, - hadoop_version=NotUpdated, flavor_id=NotUpdated, - description=NotUpdated, volumes_per_node=NotUpdated, - volumes_size=NotUpdated, node_processes=NotUpdated, - node_configs=NotUpdated, floating_ip_pool=NotUpdated, - security_groups=NotUpdated, auto_security_group=NotUpdated, - availability_zone=NotUpdated, - volumes_availability_zone=NotUpdated, volume_type=NotUpdated, - image_id=NotUpdated, is_proxy_gateway=NotUpdated, - volume_local_to_instance=NotUpdated, use_autoconfig=NotUpdated, - shares=NotUpdated, is_public=NotUpdated, - is_protected=NotUpdated, volume_mount_prefix=NotUpdated): - """Update a Node Group Template.""" - - data = {} - self._copy_if_updated( - data, name=name, plugin_name=plugin_name, - hadoop_version=hadoop_version, flavor_id=flavor_id, - description=description, volumes_per_node=volumes_per_node, - volumes_size=volumes_size, node_processes=node_processes, - node_configs=node_configs, floating_ip_pool=floating_ip_pool, - security_groups=security_groups, - auto_security_group=auto_security_group, - availability_zone=availability_zone, - volumes_availability_zone=volumes_availability_zone, - volume_type=volume_type, image_id=image_id, - is_proxy_gateway=is_proxy_gateway, - volume_local_to_instance=volume_local_to_instance, - use_autoconfig=use_autoconfig, shares=shares, - is_public=is_public, is_protected=is_protected, - volume_mount_prefix=volume_mount_prefix - ) - - return self._update('/node-group-templates/%s' % ng_template_id, data, - 'node_group_template') - - def list(self, search_opts=None, marker=None, - limit=None, sort_by=None, reverse=None): - """Get a list of Node Group Templates.""" - query = base.get_query_string(search_opts, limit=limit, marker=marker, - sort_by=sort_by, reverse=reverse) - url = "/node-group-templates%s" % query - return self._page(url, 'node_group_templates', limit) - - def get(self, ng_template_id): - """Get information about a Node Group Template.""" - return self._get('/node-group-templates/%s' % ng_template_id, - 'node_group_template') - - def delete(self, ng_template_id): - """Delete a Node Group Template.""" - self._delete('/node-group-templates/%s' % ng_template_id) diff --git a/saharaclient/api/parameters.py b/saharaclient/api/parameters.py deleted file mode 100644 index 4575b56..0000000 --- a/saharaclient/api/parameters.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -class Parameter(object): - """This bean is used for building config entries.""" - def __init__(self, config): - self.name = config['name'] - self.description = config.get('description', "No description") - self.required = not config['is_optional'] - self.default_value = config.get('default_value', None) - self.initial_value = self.default_value - self.param_type = config['config_type'] - self.priority = int(config.get('priority', 2)) diff --git a/saharaclient/api/plugins.py b/saharaclient/api/plugins.py deleted file mode 100644 index 21156cf..0000000 --- a/saharaclient/api/plugins.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from six.moves.urllib import parse as urlparse - -from saharaclient.api import base - - -class Plugin(base.Resource): - resource_name = 'Plugin' - - def __init__(self, manager, info): - base.Resource.__init__(self, manager, info) - - # Horizon requires each object in table to have an id - self.id = self.name - - -class PluginManager(base.ResourceManager): - resource_class = Plugin - - def list(self, search_opts=None): - """Get a list of Plugins.""" - query = base.get_query_string(search_opts) - return self._list('/plugins%s' % query, 'plugins') - - def get(self, plugin_name): - """Get information about a Plugin.""" - return self._get('/plugins/%s' % plugin_name, 'plugin') - - def get_version_details(self, plugin_name, hadoop_version): - """Get version details - - Get the list of Services and Service Parameters for a specified - Plugin and Plugin Version. - """ - return self._get('/plugins/%s/%s' % (plugin_name, hadoop_version), - 'plugin') - - def update(self, plugin_name, values): - """Update plugin and then return updated result to user - - """ - return self._patch("/plugins/%s" % plugin_name, values, 'plugin') - - def convert_to_cluster_template(self, plugin_name, hadoop_version, - template_name, filecontent): - """Convert to cluster template - - Create Cluster Template directly, avoiding Cluster Template - mechanism. - """ - resp = self.api.post('/plugins/%s/%s/convert-config/%s' % - (plugin_name, - hadoop_version, - urlparse.quote(template_name)), - data=filecontent) - if resp.status_code != 202: - raise RuntimeError('Failed to upload template file for plugin "%s"' - ' and version "%s"' % - (plugin_name, hadoop_version)) - else: - return base.get_json(resp)['cluster_template'] diff --git a/saharaclient/api/shell.py b/saharaclient/api/shell.py deleted file mode 100644 index 40c339c..0000000 --- a/saharaclient/api/shell.py +++ /dev/null @@ -1,1012 +0,0 @@ -# Copyright 2013 Red Hat, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import argparse -import datetime -import inspect -import json -import os.path -import sys - -from saharaclient.openstack.common.apiclient import exceptions -from saharaclient.openstack.common import cliutils as utils - - -def _print_list_field(field): - return lambda obj: ', '.join(getattr(obj, field)) - - -def _filter_call_args(args, func, remap={}): - """Filter args according to func's parameter list. - - Take three arguments: - * args - a dictionary - * func - a function - * remap - a dictionary - Remove from dct all the keys which are not among the parameters - of func. Before filtering, remap the keys in the args dict - according to remap dict. - """ - - for name, new_name in remap.items(): - if name in args: - args[new_name] = args[name] - del args[name] - - valid_args = inspect.getargspec(func).args - for name in args.keys(): - if name not in valid_args: - print('WARNING: "%s" is not a valid parameter and will be ' - 'discarded from the request' % name) - del args[name] - - -def _print_node_group_field(cluster): - return ', '.join(map(lambda x: ': '.join(x), - [(node_group['name'], - str(node_group['count'])) - for node_group in cluster.node_groups])) - - -def _show_node_group_template(template): - template._info['node_processes'] = ( - ', '.join(template._info['node_processes']) - ) - utils.print_dict(template._info) - - -def _show_cluster_template(template): - template._info['node_groups'] = _print_node_group_field(template) - utils.print_dict(template._info) - - -def _show_cluster(cluster): - # TODO(mattf): Make this pretty, e.g format node_groups and info urls - # Forcing wrap=47 allows for clean display on a terminal of width 80 - utils.print_dict(cluster._info, wrap=47) - - -def _show_job_binary_data(data): - columns = ('id', 'name') - utils.print_list(data, columns) - - -def _show_data_source(source): - # TODO(mattf): why are we passing credentials around like this? - if 'credentials' in source._info: - del source._info['credentials'] - utils.print_dict(source._info) - - -def _show_job_binary(binary): - # TODO(mattf): why are we passing credentials around like this? - if 'extra' in binary._info: - del binary._info['extra'] - utils.print_dict(binary._info) - - -def _show_job_template(template): - # TODO(mattf): Make "mains" property pretty - # TODO(mattf): handle/remove "extra" creds - utils.print_dict(template._info) - - -def _show_job(job): - # TODO(mattf): make display of info pretty, until then - # extract the important status information - job._info['status'] = job._info['info']['status'] - del job._info['info'] - utils.print_dict(job._info) - - -def _get_by_id_or_name(manager, id=None, name=None, **kwargs): - if not (name or id): - raise exceptions.CommandError("either NAME or ID is required") - if id: - return manager.get(id, **kwargs) - ls = manager.find(name=name) - if len(ls) == 0: - raise exceptions.CommandError("%s '%s' not found" % - (manager.resource_class.resource_name, - name)) - elif len(ls) > 1: - raise exceptions.CommandError("%s '%s' not unique, try by ID" % - (manager.resource_class.resource_name, - name)) - return manager.get(ls[0].id, **kwargs) - - -# -# Plugins -# ~~~~~~~ -# plugin-list -# -# plugin-show --name [--version ] -# - -def do_plugin_list(cs, args): - """Print a list of available plugins.""" - plugins = cs.plugins.list() - columns = ('name', 'versions', 'title') - utils.print_list(plugins, columns, - {'versions': _print_list_field('versions')}) - - -@utils.arg('--name', - metavar='', - required=True, - help='Name of the plugin.') -# TODO(mattf) - saharaclient does not support query w/ version -# @utils.arg('--version', -# metavar='', -# help='Optional version') -def do_plugin_show(cs, args): - """Show details of a plugin.""" - plugin = cs.plugins.get(args.name) - plugin._info['versions'] = ', '.join(plugin._info['versions']) - utils.print_dict(plugin._info) - - -# -# Image Registry -# ~~~~~~~~~~~~~~ -# image-list [--tag ]* -# -# image-show --name |--id -# -# image-register --name |--id -# [--username ] [--description ] -# -# image-unregister --name |--id -# -# image-add-tag --name |--id --tag + -# -# image-remove-tag --name |--id --tag + -# - -# TODO(mattf): [--tag ]* -def do_image_list(cs, args): - """Print a list of available images.""" - images = cs.images.list() - columns = ('name', 'id', 'username', 'tags', 'description') - utils.print_list(images, columns, {'tags': _print_list_field('tags')}) - - -@utils.arg('--name', - help='Name of the image.') -@utils.arg('--id', - metavar='', - help='ID of the image.') -def do_image_show(cs, args): - """Show details of an image.""" - image = _get_by_id_or_name(cs.images, args.id, args.name) - del image._info['metadata'] - image._info['tags'] = ', '.join(image._info['tags']) - utils.print_dict(image._info) - - -# TODO(mattf): Add --name, must lookup in glance index -@utils.arg('--id', - metavar='', - required=True, - help='ID of image, run "glance image-list" to see all IDs.') -@utils.arg('--username', - default='root', - metavar='', - help='Username of privileged user in the image.') -@utils.arg('--description', - default='', - metavar='', - help='Description of the image.') -def do_image_register(cs, args): - """Register an image from the Image index.""" - # TODO(mattf): image register should not be through update - cs.images.update_image(args.id, args.username, args.description) - # TODO(mattf): No indication of result, expect image details - - -@utils.arg('--name', - help='Name of the image.') -@utils.arg('--id', - metavar='', - help='ID of image to unregister.') -def do_image_unregister(cs, args): - """Unregister an image.""" - cs.images.unregister_image( - args.id or _get_by_id_or_name(cs.images, name=args.name).id - ) - # TODO(mattf): No indication of result, expect result to display - - -@utils.arg('--name', - help='Name of the image.') -@utils.arg('--id', - metavar='', - help='ID of image to tag.') -# TODO(mattf): Change --tag to --tag+ -@utils.arg('--tag', - metavar='', - required=True, - help='Tag to add.') -def do_image_add_tag(cs, args): - """Add a tag to an image.""" - # TODO(mattf): Need proper add_tag API call - id = args.id or _get_by_id_or_name(cs.images, name=args.name).id - cs.images.update_tags(id, cs.images.get(id).tags + [args.tag, ]) - # TODO(mattf): No indication of result, expect image details - - -@utils.arg('--name', - help='Name of the image.') -@utils.arg('--id', - metavar='', - help='Image to tag.') -# TODO(mattf): Change --tag to --tag+ -@utils.arg('--tag', - metavar='', - required=True, - help='Tag to remove.') -def do_image_remove_tag(cs, args): - """Remove a tag from an image.""" - # TODO(mattf): Need proper remove_tag API call - id = args.id or _get_by_id_or_name(cs.images, name=args.name).id - cs.images.update_tags(id, - filter(lambda x: x != args.tag, - cs.images.get(id).tags)) - # TODO(mattf): No indication of result, expect image details - - -# -# Clusters -# ~~~~~~~~ -# cluster-list -# -# cluster-show --name |--id [--json] [--show-progress] -# -# cluster-create [--json ] -# -# cluster-scale --name |--id [--json ] -# -# cluster-delete --name |--id -# - -def do_cluster_list(cs, args): - """Print a list of available clusters.""" - clusters = cs.clusters.list() - for cluster in clusters: - cluster.node_count = sum(map(lambda g: g['count'], - cluster.node_groups)) - columns = ('name', 'id', 'status', 'node_count') - utils.print_list(clusters, columns) - - -@utils.arg('--name', - help='Name of the cluster.') -@utils.arg('--id', - metavar='', - help='ID of the cluster to show.') -@utils.arg('--show-progress', - help='Show provision progress events of the cluster.') -@utils.arg('--json', - action='store_true', - default=False, - help='Print JSON representation of the cluster.') -def do_cluster_show(cs, args): - """Show details of a cluster.""" - cluster = _get_by_id_or_name(cs.clusters, args.id, args.name, - show_progress=args.show_progress) - if args.json: - print(json.dumps(cluster._info)) - else: - _show_cluster(cluster) - - -@utils.arg('--json', - default=sys.stdin, - type=argparse.FileType('r'), - help='JSON representation of cluster.') -@utils.arg('--count', - default=1, - type=int, - help='Number of clusters to create.') -def do_cluster_create(cs, args): - """Create a cluster.""" - # TODO(mattf): improve template validation, e.g. template w/o name key - template = json.loads(args.json.read()) - # The neutron_management_network parameter to clusters.create is - # called net_id. Therefore, we must translate before invoking - # create w/ **template. It may be desirable to simple change - # clusters.create in the future. - remap = {'neutron_management_network': 'net_id'} - template['count'] = args.count - _filter_call_args(template, cs.clusters.create, remap) - - _show_cluster(cs.clusters.create(**template)) - - -@utils.arg('--name', - help='Name of the cluster.') -@utils.arg('--id', - metavar='', - help='ID of the cluster.') -@utils.arg('--json', - default=sys.stdin, - type=argparse.FileType('r'), - help='JSON representation of cluster scale.') -def do_cluster_scale(cs, args): - """Scale a cluster.""" - cluster_id = args.id or _get_by_id_or_name(cs.clusters, name=args.name).id - scale_template = json.loads(args.json.read()) - _show_cluster(cs.clusters.scale(cluster_id, **scale_template)) - - -@utils.arg('--name', - help='Name of the cluster.') -@utils.arg('--id', - metavar='', - help='ID of the cluster to delete.') -def do_cluster_delete(cs, args): - """Delete a cluster.""" - cs.clusters.delete( - args.id or _get_by_id_or_name(cs.clusters, name=args.name).id - ) - # TODO(mattf): No indication of result - - -# -# Node Group Templates -# ~~~~~~~~~~~~~~~~~~~~ -# node-group-template-list -# -# node-group-template-show --name