osc-lib 3.1.0__tar.gz → 4.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {osc-lib-3.1.0 → osc_lib-4.0.0}/.coveragerc +1 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/.pre-commit-config.yaml +26 -14
- {osc-lib-3.1.0 → osc_lib-4.0.0}/AUTHORS +1 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/ChangeLog +40 -0
- osc_lib-4.0.0/PKG-INFO +94 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/doc/source/conf.py +0 -1
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/api/api.py +67 -30
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/api/auth.py +39 -25
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/api/utils.py +10 -5
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/cli/client_config.py +55 -35
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/cli/format_columns.py +19 -17
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/cli/identity.py +14 -3
- osc_lib-4.0.0/osc_lib/cli/pagination.py +83 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/cli/parseractions.py +116 -37
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/clientmanager.py +49 -28
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/command/command.py +20 -9
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/command/timing.py +11 -1
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/exceptions.py +13 -3
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/logs.py +19 -9
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/shell.py +73 -56
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/api/fakes.py +1 -1
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/api/test_api.py +5 -5
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/api/test_utils.py +1 -1
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/cli/test_client_config.py +1 -1
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/cli/test_format_columns.py +1 -1
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/cli/test_parseractions.py +48 -100
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/command/test_timing.py +2 -2
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/fakes.py +10 -10
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/test_clientmanager.py +1 -1
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/test_logs.py +2 -2
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/test_shell.py +10 -10
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/utils/__init__.py +6 -25
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/utils/test_tags.py +22 -7
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/utils/test_utils.py +4 -14
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/utils/__init__.py +183 -111
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/utils/columns.py +25 -11
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/utils/tags.py +39 -21
- osc_lib-4.0.0/osc_lib.egg-info/PKG-INFO +94 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib.egg-info/SOURCES.txt +10 -1
- osc_lib-4.0.0/osc_lib.egg-info/pbr.json +1 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib.egg-info/requires.txt +2 -2
- osc_lib-4.0.0/pyproject.toml +45 -0
- osc_lib-4.0.0/releasenotes/notes/deprecate-BaseAPI-09abd3cb955c2bb6.yaml +6 -0
- osc_lib-4.0.0/releasenotes/notes/deprecate-clientcache-38c8c9fd4ca6dcdf.yaml +4 -0
- osc_lib-4.0.0/releasenotes/notes/deprecated-legacy-client-helpers-53dde79bd6769d2d.yaml +7 -0
- osc_lib-4.0.0/releasenotes/notes/env-default-e8f2c60f1295d15f.yaml +5 -0
- osc_lib-4.0.0/releasenotes/notes/remove-support-for-legacy-formatters-1240317d801b4336.yaml +8 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/2023.1.rst +1 -1
- osc_lib-4.0.0/releasenotes/source/2024.2.rst +6 -0
- osc_lib-4.0.0/releasenotes/source/2025.1.rst +6 -0
- osc_lib-4.0.0/releasenotes/source/_templates/.placeholder +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/conf.py +0 -1
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/index.rst +2 -0
- osc_lib-4.0.0/requirements.txt +8 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/test-requirements.txt +0 -4
- {osc-lib-3.1.0 → osc_lib-4.0.0}/tox.ini +5 -12
- osc-lib-3.1.0/PKG-INFO +0 -87
- osc-lib-3.1.0/doc/Makefile +0 -130
- osc-lib-3.1.0/osc_lib.egg-info/PKG-INFO +0 -87
- osc-lib-3.1.0/osc_lib.egg-info/pbr.json +0 -1
- osc-lib-3.1.0/requirements.txt +0 -12
- {osc-lib-3.1.0 → osc_lib-4.0.0}/.git-ignore-blame-revs +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/.mailmap +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/.stestr.conf +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/.zuul.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/HACKING.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/LICENSE +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/README.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/doc/ext/__init__.py +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/doc/ext/apidoc.py +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/doc/requirements.txt +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/doc/source/contributor/index.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/doc/source/index.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/doc/source/reference/index.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/doc/source/user/change_log.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/doc/source/user/index.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/doc/source/user/transition.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/__init__.py +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/api/__init__.py +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/cli/__init__.py +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/command/__init__.py +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/command/commandmanager.py +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/i18n.py +0 -0
- /osc-lib-3.1.0/osc_lib/tests/__init__.py → /osc_lib-4.0.0/osc_lib/py.typed +0 -0
- {osc-lib-3.1.0/osc_lib/tests/api → osc_lib-4.0.0/osc_lib/tests}/__init__.py +0 -0
- {osc-lib-3.1.0/osc_lib/tests/cli → osc_lib-4.0.0/osc_lib/tests/api}/__init__.py +0 -0
- {osc-lib-3.1.0/osc_lib/tests/command → osc_lib-4.0.0/osc_lib/tests/cli}/__init__.py +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/cli/test_identity.py +0 -0
- /osc-lib-3.1.0/releasenotes/notes/.placeholder → /osc_lib-4.0.0/osc_lib/tests/command/__init__.py +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/command/test_command.py +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/tests/utils/test_columns.py +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib/version.py +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib.egg-info/dependency_links.txt +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib.egg-info/not-zip-safe +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/osc_lib.egg-info/top_level.txt +0 -0
- {osc-lib-3.1.0/releasenotes/source/_static → osc_lib-4.0.0/releasenotes/notes}/.placeholder +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/1.0-summary-47dcce446d6a512b.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/add-KeyValueAppendAction-class-f830e71152d6b91e.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/add-MultiKeyValueCommaAction-class-01dd254a287d70d2.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/add-size-column-5424c40af74688df.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/add_sdk_utils-d0c338eba682f2c8.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/arg-precedence-1ba9fd6929650830.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/auth-type-none-d96760912605f822.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/bug-1558690-1528b637f2c0a449.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/bug-1630822-mask-password-on-debug-20dcdf1c54e84fa1.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/bug-2004898-686577a07e791051.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/bug-2006480-436489d39643e76c.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/direct-openstacksdk-535a179f3c645cc0.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/drop-py2-support-60c93244107d5778.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/find-project-203bf867619c557e.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/keystone-to-keystone-9b2e55b051775322.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/none-auth-cli-48ab0e48d4852941.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/os-profile-as-environment-variable-a5e232e9ca7c5171.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/remove-babel-50abc5b548455bb2.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/remove-group-subclass-82134e6915c7c782.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/save-results-4473cb5731c0c763.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/notes/shell-argv-decode-cdc13dc0c4ec07af.yaml +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/2023.2.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/2024.1.rst +0 -0
- {osc-lib-3.1.0/releasenotes/source/_templates → osc_lib-4.0.0/releasenotes/source/_static}/.placeholder +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/newton.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/ocata.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/pike.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/queens.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/rocky.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/stein.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/train.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/unreleased.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/ussuri.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/victoria.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/wallaby.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/xena.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/yoga.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/releasenotes/source/zed.rst +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/setup.cfg +0 -0
- {osc-lib-3.1.0 → osc_lib-4.0.0}/setup.py +0 -0
@@ -4,7 +4,7 @@ default_language_version:
|
|
4
4
|
python: python3
|
5
5
|
repos:
|
6
6
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
7
|
-
rev:
|
7
|
+
rev: v5.0.0
|
8
8
|
hooks:
|
9
9
|
- id: trailing-whitespace
|
10
10
|
- id: mixed-line-ending
|
@@ -18,22 +18,34 @@ repos:
|
|
18
18
|
files: .*\.(yaml|yml)$
|
19
19
|
exclude: '^zuul.d/.*$'
|
20
20
|
- repo: https://github.com/PyCQA/doc8
|
21
|
-
rev: v1.1.
|
21
|
+
rev: v1.1.2
|
22
22
|
hooks:
|
23
23
|
- id: doc8
|
24
|
-
- repo: https://github.com/
|
25
|
-
rev:
|
24
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
25
|
+
rev: v0.9.6
|
26
26
|
hooks:
|
27
|
-
- id:
|
28
|
-
args: ['
|
29
|
-
|
27
|
+
- id: ruff
|
28
|
+
args: ['--fix', '--unsafe-fixes']
|
29
|
+
- id: ruff-format
|
30
|
+
- repo: https://opendev.org/openstack/hacking
|
31
|
+
rev: 7.0.0
|
30
32
|
hooks:
|
31
|
-
- id:
|
32
|
-
name: flake8
|
33
|
+
- id: hacking
|
33
34
|
additional_dependencies:
|
34
|
-
-
|
35
|
-
- flake8-import-order>=0.18.2,<0.19.0
|
36
|
-
language: python
|
37
|
-
entry: flake8
|
38
|
-
files: '^.*\.py$'
|
35
|
+
- flake8-import-order~=0.18.2
|
39
36
|
exclude: '^(doc|releasenotes|tools)/.*$'
|
37
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
38
|
+
rev: v1.13.0
|
39
|
+
hooks:
|
40
|
+
- id: mypy
|
41
|
+
additional_dependencies:
|
42
|
+
- cliff
|
43
|
+
- keystoneauth1
|
44
|
+
- types-requests
|
45
|
+
# keep this in-sync with '[mypy] exclude' in 'setup.cfg'
|
46
|
+
exclude: |
|
47
|
+
(?x)(
|
48
|
+
doc/.*
|
49
|
+
| examples/.*
|
50
|
+
| releasenotes/.*
|
51
|
+
)
|
@@ -107,6 +107,7 @@ OpenStack Release Bot <infra-root@openstack.org>
|
|
107
107
|
Paul Belanger <paul.belanger@polybeacon.com>
|
108
108
|
Qiu Yu <qiuyu@ebaysf.com>
|
109
109
|
Rabi Mishra <ramishra@redhat.com>
|
110
|
+
Radoslaw Smigielski <rsmigiel@redhat.com>
|
110
111
|
Reedip <reedip14@gmail.com>
|
111
112
|
Riccardo Pittau <elfosardo@gmail.com>
|
112
113
|
Richard Theis <rtheis@us.ibm.com>
|
@@ -1,11 +1,51 @@
|
|
1
1
|
CHANGES
|
2
2
|
=======
|
3
3
|
|
4
|
+
4.0.0
|
5
|
+
-----
|
6
|
+
|
7
|
+
* typing: Enable disallow\_subclassing\_any
|
8
|
+
* tests: Resolve TODO
|
9
|
+
* utils: Deprecate legacy client-specific helpers
|
10
|
+
* utils: Remove support for legacy format functions
|
11
|
+
* utils: Group similar utilities together
|
12
|
+
* utils: Don't warn for partial formatter classes
|
13
|
+
* typing: Add typing to osc\_lib.utils
|
14
|
+
* typing: Add typing to osc\_lib.command
|
15
|
+
* clientmanager: Deprecate ClientCache
|
16
|
+
* typing: Add typing to osc\_lib.clientmanager
|
17
|
+
* typing: Add typing to osc\_lib.shell
|
18
|
+
* typing: Add typing to osc\_lib.logs, osc\_lib.i18n
|
19
|
+
* typing: Add typing to osc\_lib.cli
|
20
|
+
* api: Deprecate BaseAPI
|
21
|
+
* typing: Add typing to osc\_lib.api
|
22
|
+
* Remove unused docs Makefile
|
23
|
+
* typing: Add typing to osc\_lib.exceptions
|
24
|
+
* pre-commit: Enable mypy
|
25
|
+
* typing: Fix initial typing issues
|
26
|
+
* Update master for stable/2025.1
|
27
|
+
* Add pagination helpers
|
28
|
+
* pre-commit: Enable ruff S (bandit) checks
|
29
|
+
* pre-commit: Bump versions
|
30
|
+
* tests: Use consistent output widths
|
31
|
+
* reno: Update master for unmaintained/2023.1
|
32
|
+
|
33
|
+
3.2.0
|
34
|
+
-----
|
35
|
+
|
36
|
+
* ruff: Enable pyupgrade rules
|
37
|
+
* pre-commit: Migrate from black to ruff format
|
38
|
+
* pre-commit: Migrate from flake8 to ruff
|
39
|
+
* parseactions: Use ArgumentError, not ArgumentTypeError
|
40
|
+
* Update master for stable/2024.2
|
41
|
+
* Exclude tests directory from coverage calculation
|
42
|
+
|
4
43
|
3.1.0
|
5
44
|
-----
|
6
45
|
|
7
46
|
* Drop dependency on simplejson
|
8
47
|
* reno: Update master for unmaintained/zed
|
48
|
+
* Fix log level, remove unnecessary debug
|
9
49
|
* Update master for stable/2024.1
|
10
50
|
* reno: Update master for unmaintained/xena
|
11
51
|
* reno: Update master for unmaintained/wallaby
|
osc_lib-4.0.0/PKG-INFO
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: osc-lib
|
3
|
+
Version: 4.0.0
|
4
|
+
Summary: OpenStackClient Library
|
5
|
+
Home-page: https://docs.openstack.org/osc-lib/latest/
|
6
|
+
Author: OpenStack
|
7
|
+
Author-email: openstack-discuss@lists.openstack.org
|
8
|
+
Project-URL: Bug Tracker, https://storyboard.openstack.org/#!/project/openstack/osc-lib
|
9
|
+
Project-URL: Documentation, https://docs.openstack.org/osc-lib/latest/
|
10
|
+
Project-URL: Source Code, https://opendev.org/openstack/osc-lib/
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
12
|
+
Classifier: Environment :: OpenStack
|
13
|
+
Classifier: Intended Audience :: Information Technology
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
15
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
17
|
+
Classifier: Programming Language :: Python
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
20
|
+
Requires-Python: >=3.8
|
21
|
+
License-File: LICENSE
|
22
|
+
Requires-Dist: cliff>=4.9.0
|
23
|
+
Requires-Dist: keystoneauth1>=5.10.0
|
24
|
+
Requires-Dist: openstacksdk>=0.15.0
|
25
|
+
Requires-Dist: oslo.i18n>=3.15.3
|
26
|
+
Requires-Dist: oslo.utils>=3.33.0
|
27
|
+
Requires-Dist: pbr!=2.1.0,>=2.0.0
|
28
|
+
Requires-Dist: requests>=2.14.2
|
29
|
+
Requires-Dist: stevedore>=1.20.0
|
30
|
+
|
31
|
+
=======
|
32
|
+
osc-lib
|
33
|
+
=======
|
34
|
+
|
35
|
+
.. image:: https://img.shields.io/pypi/v/osc-lib.svg
|
36
|
+
:target: https://pypi.org/project/osc-lib/
|
37
|
+
:alt: Latest Version
|
38
|
+
|
39
|
+
OpenStackClient (aka OSC) is a command-line client for OpenStack. osc-lib
|
40
|
+
is a package of common support modules for writing OSC plugins.
|
41
|
+
|
42
|
+
* `PyPi`_ - package installation
|
43
|
+
* `Online Documentation`_
|
44
|
+
* `Launchpad project`_ - part of OpenStackClient
|
45
|
+
* `Bugs`_ - issue tracking
|
46
|
+
* `Source`_
|
47
|
+
* `Developer` - getting started as a developer
|
48
|
+
* `Contributing` - contributing code
|
49
|
+
* `Testing` - testing code
|
50
|
+
* IRC: #openstack-sdks on OFTC (irc.oftc.net)
|
51
|
+
* License: Apache 2.0
|
52
|
+
|
53
|
+
.. _PyPi: https://pypi.org/project/osc-lib
|
54
|
+
.. _Online Documentation: http://docs.openstack.org/osc-lib/latest/
|
55
|
+
.. _Launchpad project: https://launchpad.net/python-openstackclient
|
56
|
+
.. _Bugs: https://storyboard.openstack.org/#!/project_group/80
|
57
|
+
.. _Source: https://opendev.org/openstack/osc-lib
|
58
|
+
.. _Developer: http://docs.openstack.org/project-team-guide/project-setup/python.html
|
59
|
+
.. _Contributing: http://docs.openstack.org/infra/manual/developers.html
|
60
|
+
.. _Testing: http://docs.openstack.org/osc-lib/latest/contributor/#testing
|
61
|
+
.. _Release Notes: https://docs.openstack.org/releasenotes/osc-lib
|
62
|
+
|
63
|
+
Getting Started
|
64
|
+
===============
|
65
|
+
|
66
|
+
osc-lib can be installed from PyPI using pip::
|
67
|
+
|
68
|
+
pip install osc-lib
|
69
|
+
|
70
|
+
Transition From OpenStackclient
|
71
|
+
===============================
|
72
|
+
|
73
|
+
This library was extracted from the main OSC repo after the OSC 2.4.0 release.
|
74
|
+
The following are the changes to imports that will cover the majority of
|
75
|
+
transition to using osc-lib:
|
76
|
+
|
77
|
+
* openstackclient.api.api -> osc_lib.api.api
|
78
|
+
* openstackclient.api.auth -> osc_lib.api.auth
|
79
|
+
* openstackclient.api.utils -> osc_lib.api.utils
|
80
|
+
* openstackclient.common.command -> osc_lib.command.command
|
81
|
+
* openstackclient.common.commandmanager -> osc_lib.command.commandmanager
|
82
|
+
* openstackclient.common.exceptions -> osc_lib.exceptions
|
83
|
+
* openstackclient.common.logs -> osc_lib.logs
|
84
|
+
* openstackclient.common.parseractions -> osc_lib.cli.parseractions
|
85
|
+
* openstackclient.common.session -> osc_lib.session
|
86
|
+
* openstackclient.common.utils -> osc_lib.utils
|
87
|
+
* openstackclient.i18n -> osc_lib.i18n
|
88
|
+
* openstackclient.shell -> osc_lib.shell
|
89
|
+
|
90
|
+
Also, some of the test fixtures and modules may be used:
|
91
|
+
|
92
|
+
* openstackclient.tests.fakes -> osc_lib.tests.fakes
|
93
|
+
* openstackclient.tests.utils -> osc_lib.tests.utils
|
94
|
+
|
@@ -12,6 +12,11 @@
|
|
12
12
|
#
|
13
13
|
|
14
14
|
"""Base API Library"""
|
15
|
+
|
16
|
+
import builtins
|
17
|
+
import typing as ty
|
18
|
+
import warnings
|
19
|
+
|
15
20
|
from keystoneauth1 import exceptions as ksa_exceptions
|
16
21
|
from keystoneauth1 import session as ksa_session
|
17
22
|
import requests
|
@@ -20,7 +25,7 @@ from osc_lib import exceptions
|
|
20
25
|
from osc_lib.i18n import _
|
21
26
|
|
22
27
|
|
23
|
-
class BaseAPI
|
28
|
+
class BaseAPI:
|
24
29
|
"""Base API wrapper for keystoneauth1.session.Session
|
25
30
|
|
26
31
|
Encapsulate the translation between keystoneauth1.session.Session
|
@@ -41,8 +46,12 @@ class BaseAPI(object):
|
|
41
46
|
HEADER_NAME = "OpenStack-API-Version"
|
42
47
|
|
43
48
|
def __init__(
|
44
|
-
self,
|
45
|
-
|
49
|
+
self,
|
50
|
+
session: ty.Optional[ksa_session.Session] = None,
|
51
|
+
service_type: ty.Optional[str] = None,
|
52
|
+
endpoint: ty.Optional[str] = None,
|
53
|
+
**kwargs: ty.Any,
|
54
|
+
) -> None:
|
46
55
|
"""Base object that contains some common API objects and methods
|
47
56
|
|
48
57
|
:param keystoneauth1.session.Session session:
|
@@ -57,7 +66,13 @@ class BaseAPI(object):
|
|
57
66
|
Keyword arguments passed to keystoneauth1.session.Session().
|
58
67
|
"""
|
59
68
|
|
60
|
-
|
69
|
+
warnings.warn(
|
70
|
+
'The BaseAPI class is deprecated for removal. Consider using '
|
71
|
+
'openstacksdk instead else vendoring this code into your client',
|
72
|
+
category=DeprecationWarning,
|
73
|
+
)
|
74
|
+
|
75
|
+
super().__init__()
|
61
76
|
|
62
77
|
# Create a keystoneauth1.session.Session if one is not supplied
|
63
78
|
if not session:
|
@@ -68,7 +83,7 @@ class BaseAPI(object):
|
|
68
83
|
self.service_type = service_type
|
69
84
|
self.endpoint = self._munge_endpoint(endpoint)
|
70
85
|
|
71
|
-
def _munge_endpoint(self, endpoint):
|
86
|
+
def _munge_endpoint(self, endpoint: ty.Optional[str]) -> ty.Optional[str]:
|
72
87
|
"""Hook to allow subclasses to massage the passed-in endpoint
|
73
88
|
|
74
89
|
Hook to massage passed-in endpoints from arbitrary sources,
|
@@ -89,7 +104,13 @@ class BaseAPI(object):
|
|
89
104
|
else:
|
90
105
|
return endpoint
|
91
106
|
|
92
|
-
def _request(
|
107
|
+
def _request(
|
108
|
+
self,
|
109
|
+
method: str,
|
110
|
+
url: str,
|
111
|
+
session: ty.Optional[ksa_session.Session] = None,
|
112
|
+
**kwargs: ty.Any,
|
113
|
+
) -> requests.Response:
|
93
114
|
"""Perform call into session
|
94
115
|
|
95
116
|
All API calls are funneled through this method to provide a common
|
@@ -135,7 +156,13 @@ class BaseAPI(object):
|
|
135
156
|
|
136
157
|
# The basic action methods all take a Session and return dict/lists
|
137
158
|
|
138
|
-
def create(
|
159
|
+
def create(
|
160
|
+
self,
|
161
|
+
url: str,
|
162
|
+
session: ty.Optional[ksa_session.Session] = None,
|
163
|
+
method: ty.Optional[str] = None,
|
164
|
+
**params: ty.Any,
|
165
|
+
) -> ty.Union[requests.Response, ty.Any]:
|
139
166
|
"""Create a new resource
|
140
167
|
|
141
168
|
:param string url:
|
@@ -155,7 +182,12 @@ class BaseAPI(object):
|
|
155
182
|
except requests.JSONDecodeError:
|
156
183
|
return ret
|
157
184
|
|
158
|
-
def delete(
|
185
|
+
def delete(
|
186
|
+
self,
|
187
|
+
url: str,
|
188
|
+
session: ty.Optional[ksa_session.Session] = None,
|
189
|
+
**params: ty.Any,
|
190
|
+
) -> requests.Response:
|
159
191
|
"""Delete a resource
|
160
192
|
|
161
193
|
:param string url:
|
@@ -168,13 +200,13 @@ class BaseAPI(object):
|
|
168
200
|
|
169
201
|
def list(
|
170
202
|
self,
|
171
|
-
path,
|
172
|
-
session=None,
|
173
|
-
body=None,
|
174
|
-
detailed=False,
|
175
|
-
headers=None,
|
176
|
-
**params
|
177
|
-
):
|
203
|
+
path: str,
|
204
|
+
session: ty.Optional[ksa_session.Session] = None,
|
205
|
+
body: ty.Any = None,
|
206
|
+
detailed: bool = False,
|
207
|
+
headers: ty.Optional[dict[str, str]] = None,
|
208
|
+
**params: ty.Any,
|
209
|
+
) -> ty.Union[requests.Response, ty.Any]:
|
178
210
|
"""Return a list of resources
|
179
211
|
|
180
212
|
GET ${ENDPOINT}/${PATH}?${PARAMS}
|
@@ -225,11 +257,11 @@ class BaseAPI(object):
|
|
225
257
|
|
226
258
|
def find_attr(
|
227
259
|
self,
|
228
|
-
path,
|
229
|
-
value=None,
|
230
|
-
attr=None,
|
231
|
-
resource=None,
|
232
|
-
):
|
260
|
+
path: str,
|
261
|
+
value: ty.Optional[str] = None,
|
262
|
+
attr: ty.Optional[str] = None,
|
263
|
+
resource: ty.Optional[str] = None,
|
264
|
+
) -> ty.Any:
|
233
265
|
"""Find a resource via attribute or ID
|
234
266
|
|
235
267
|
Most APIs return a list wrapped by a dict with the resource
|
@@ -259,7 +291,7 @@ class BaseAPI(object):
|
|
259
291
|
if resource is None:
|
260
292
|
resource = path
|
261
293
|
|
262
|
-
def getlist(kw):
|
294
|
+
def getlist(kw: dict[str, ty.Any]) -> ty.Any:
|
263
295
|
"""Do list call, unwrap resource dict if present"""
|
264
296
|
ret = self.list(path, **kw)
|
265
297
|
if isinstance(ret, dict) and resource in ret:
|
@@ -289,7 +321,12 @@ class BaseAPI(object):
|
|
289
321
|
msg % {'resource': resource, 'attr': attr, 'value': value}
|
290
322
|
)
|
291
323
|
|
292
|
-
def find_bulk(
|
324
|
+
def find_bulk(
|
325
|
+
self,
|
326
|
+
path: str,
|
327
|
+
headers: ty.Optional[dict[str, str]] = None,
|
328
|
+
**kwargs: ty.Any,
|
329
|
+
) -> builtins.list[ty.Any]:
|
293
330
|
"""Bulk load and filter locally
|
294
331
|
|
295
332
|
:param string path:
|
@@ -317,7 +354,7 @@ class BaseAPI(object):
|
|
317
354
|
|
318
355
|
return ret
|
319
356
|
|
320
|
-
def find_one(self, path, **kwargs):
|
357
|
+
def find_one(self, path: str, **kwargs: ty.Any) -> ty.Any:
|
321
358
|
"""Find a resource by name or ID
|
322
359
|
|
323
360
|
:param string path:
|
@@ -338,11 +375,11 @@ class BaseAPI(object):
|
|
338
375
|
|
339
376
|
def find(
|
340
377
|
self,
|
341
|
-
path,
|
342
|
-
value=None,
|
343
|
-
attr=None,
|
344
|
-
headers=None,
|
345
|
-
):
|
378
|
+
path: str,
|
379
|
+
value: ty.Optional[str] = None,
|
380
|
+
attr: ty.Optional[str] = None,
|
381
|
+
headers: ty.Optional[dict[str, str]] = None,
|
382
|
+
) -> ty.Any:
|
346
383
|
"""Find a single resource by name or ID
|
347
384
|
|
348
385
|
:param string path:
|
@@ -355,14 +392,14 @@ class BaseAPI(object):
|
|
355
392
|
Headers dictionary to pass to requests
|
356
393
|
"""
|
357
394
|
|
358
|
-
def raise_not_found():
|
395
|
+
def raise_not_found() -> ty.NoReturn:
|
359
396
|
msg = _("%s not found") % value
|
360
397
|
raise exceptions.NotFound(404, msg)
|
361
398
|
|
362
399
|
try:
|
363
400
|
ret = self._request(
|
364
401
|
'GET',
|
365
|
-
"
|
402
|
+
f"/{path}/{value}",
|
366
403
|
headers=headers,
|
367
404
|
).json()
|
368
405
|
if isinstance(ret, dict):
|
@@ -14,7 +14,9 @@
|
|
14
14
|
"""Authentication Library"""
|
15
15
|
|
16
16
|
import argparse
|
17
|
+
import typing as ty
|
17
18
|
|
19
|
+
from keystoneauth1.identity import base as identity_base
|
18
20
|
from keystoneauth1.identity.v3 import k2k
|
19
21
|
from keystoneauth1.loading import base
|
20
22
|
|
@@ -22,16 +24,25 @@ from osc_lib import exceptions as exc
|
|
22
24
|
from osc_lib.i18n import _
|
23
25
|
from osc_lib import utils
|
24
26
|
|
27
|
+
if ty.TYPE_CHECKING:
|
28
|
+
from openstack import connection
|
29
|
+
|
25
30
|
|
26
31
|
# Initialize the list of Authentication plugins early in order
|
27
32
|
# to get the command-line options
|
28
33
|
PLUGIN_LIST = None
|
29
34
|
|
35
|
+
|
36
|
+
class _OptionDict(ty.TypedDict):
|
37
|
+
env: str
|
38
|
+
help: str
|
39
|
+
|
40
|
+
|
30
41
|
# List of plugin command line options
|
31
|
-
OPTIONS_LIST = {}
|
42
|
+
OPTIONS_LIST: dict[str, _OptionDict] = {}
|
32
43
|
|
33
44
|
|
34
|
-
def get_plugin_list():
|
45
|
+
def get_plugin_list() -> frozenset[str]:
|
35
46
|
"""Gather plugin list and cache it"""
|
36
47
|
|
37
48
|
global PLUGIN_LIST
|
@@ -41,7 +52,7 @@ def get_plugin_list():
|
|
41
52
|
return PLUGIN_LIST
|
42
53
|
|
43
54
|
|
44
|
-
def get_options_list():
|
55
|
+
def get_options_list() -> dict[str, _OptionDict]:
|
45
56
|
"""Gather plugin options so the help action has them available"""
|
46
57
|
|
47
58
|
global OPTIONS_LIST
|
@@ -59,14 +70,16 @@ def get_options_list():
|
|
59
70
|
# TODO(mhu) simplistic approach, would be better to only add
|
60
71
|
# help texts if they vary from one auth plugin to another
|
61
72
|
# also the text rendering is ugly in the CLI ...
|
62
|
-
OPTIONS_LIST[os_name]['help'] +=
|
63
|
-
plugin_name
|
64
|
-
o.help,
|
73
|
+
OPTIONS_LIST[os_name]['help'] += (
|
74
|
+
f'With {plugin_name}: {o.help}\n'
|
65
75
|
)
|
66
76
|
return OPTIONS_LIST
|
67
77
|
|
68
78
|
|
69
|
-
def check_valid_authorization_options(
|
79
|
+
def check_valid_authorization_options(
|
80
|
+
options: 'connection.Connection',
|
81
|
+
auth_plugin_name: str,
|
82
|
+
) -> None:
|
70
83
|
"""Validate authorization options, and provide helpful error messages."""
|
71
84
|
if (
|
72
85
|
options.auth.get('project_id')
|
@@ -87,16 +100,15 @@ def check_valid_authorization_options(options, auth_plugin_name):
|
|
87
100
|
)
|
88
101
|
|
89
102
|
|
90
|
-
def check_valid_authentication_options(
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
"""
|
96
|
-
|
103
|
+
def check_valid_authentication_options(
|
104
|
+
options: 'connection.Connection',
|
105
|
+
auth_plugin_name: str,
|
106
|
+
) -> None:
|
107
|
+
"""Validate authentication options, and provide helpful error messages."""
|
97
108
|
# Get all the options defined within the plugin.
|
98
|
-
plugin_opts =
|
99
|
-
|
109
|
+
plugin_opts = {
|
110
|
+
opt.dest: opt for opt in base.get_plugin_options(auth_plugin_name)
|
111
|
+
}
|
100
112
|
|
101
113
|
# NOTE(aloga): this is an horrible hack. We need a way to specify the
|
102
114
|
# required options in the plugins. Using the "required" argument for
|
@@ -142,7 +154,9 @@ def check_valid_authentication_options(options, auth_plugin_name):
|
|
142
154
|
)
|
143
155
|
|
144
156
|
|
145
|
-
def build_auth_plugins_option_parser(
|
157
|
+
def build_auth_plugins_option_parser(
|
158
|
+
parser: argparse.ArgumentParser,
|
159
|
+
) -> argparse.ArgumentParser:
|
146
160
|
"""Auth plugins options builder
|
147
161
|
|
148
162
|
Builds dynamically the list of options expected by each available
|
@@ -177,7 +191,7 @@ def build_auth_plugins_option_parser(parser):
|
|
177
191
|
if 'tenant' not in o:
|
178
192
|
parser.add_argument(
|
179
193
|
'--os-' + o,
|
180
|
-
metavar='<auth
|
194
|
+
metavar=f'<auth-{o}>',
|
181
195
|
dest=o.replace('-', '_'),
|
182
196
|
default=envs.get(
|
183
197
|
OPTIONS_LIST[o]['env'],
|
@@ -207,13 +221,13 @@ def build_auth_plugins_option_parser(parser):
|
|
207
221
|
|
208
222
|
|
209
223
|
def get_keystone2keystone_auth(
|
210
|
-
local_auth,
|
211
|
-
service_provider,
|
212
|
-
project_id=None,
|
213
|
-
project_name=None,
|
214
|
-
project_domain_id=None,
|
215
|
-
project_domain_name=None,
|
216
|
-
):
|
224
|
+
local_auth: identity_base.BaseIdentityPlugin,
|
225
|
+
service_provider: str,
|
226
|
+
project_id: ty.Optional[str] = None,
|
227
|
+
project_name: ty.Optional[str] = None,
|
228
|
+
project_domain_id: ty.Optional[str] = None,
|
229
|
+
project_domain_name: ty.Optional[str] = None,
|
230
|
+
) -> k2k.Keystone2Keystone:
|
217
231
|
"""Return Keystone 2 Keystone authentication for service provider.
|
218
232
|
|
219
233
|
:param local_auth: authentication to use with the local Keystone
|
@@ -13,13 +13,18 @@
|
|
13
13
|
|
14
14
|
"""API Utilities Library"""
|
15
15
|
|
16
|
+
import typing as ty
|
17
|
+
|
18
|
+
|
19
|
+
_T = ty.TypeVar('_T', bound=list[ty.Any])
|
20
|
+
|
16
21
|
|
17
22
|
def simple_filter(
|
18
|
-
data=None,
|
19
|
-
attr=None,
|
20
|
-
value=None,
|
21
|
-
property_field=None,
|
22
|
-
):
|
23
|
+
data: ty.Optional[_T] = None,
|
24
|
+
attr: ty.Optional[str] = None,
|
25
|
+
value: ty.Optional[str] = None,
|
26
|
+
property_field: ty.Optional[str] = None,
|
27
|
+
) -> ty.Optional[_T]:
|
23
28
|
"""Filter a list of dicts
|
24
29
|
|
25
30
|
:param list data:
|