osc-lib 3.2.0__tar.gz → 4.0.1__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.
Files changed (136) hide show
  1. {osc-lib-3.2.0 → osc_lib-4.0.1}/.pre-commit-config.yaml +17 -2
  2. {osc-lib-3.2.0 → osc_lib-4.0.1}/ChangeLog +38 -0
  3. osc_lib-4.0.1/PKG-INFO +94 -0
  4. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/api/api.py +62 -27
  5. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/api/auth.py +36 -21
  6. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/api/utils.py +10 -5
  7. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/cli/client_config.py +53 -32
  8. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/cli/format_columns.py +19 -17
  9. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/cli/identity.py +14 -3
  10. osc_lib-4.0.1/osc_lib/cli/pagination.py +83 -0
  11. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/cli/parseractions.py +98 -20
  12. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/clientmanager.py +45 -24
  13. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/command/command.py +19 -8
  14. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/command/timing.py +11 -1
  15. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/exceptions.py +12 -2
  16. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/logs.py +17 -8
  17. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/shell.py +64 -44
  18. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/test_shell.py +4 -4
  19. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/utils/__init__.py +0 -19
  20. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/utils/test_tags.py +22 -7
  21. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/utils/test_utils.py +1 -11
  22. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/utils/__init__.py +179 -108
  23. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/utils/columns.py +15 -4
  24. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/utils/tags.py +38 -21
  25. osc_lib-4.0.1/osc_lib.egg-info/PKG-INFO +94 -0
  26. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib.egg-info/SOURCES.txt +8 -1
  27. osc_lib-4.0.1/osc_lib.egg-info/pbr.json +1 -0
  28. osc_lib-4.0.1/pyproject.toml +46 -0
  29. osc_lib-4.0.1/releasenotes/notes/deprecate-BaseAPI-09abd3cb955c2bb6.yaml +6 -0
  30. osc_lib-4.0.1/releasenotes/notes/deprecate-clientcache-38c8c9fd4ca6dcdf.yaml +4 -0
  31. osc_lib-4.0.1/releasenotes/notes/deprecated-legacy-client-helpers-53dde79bd6769d2d.yaml +7 -0
  32. osc_lib-4.0.1/releasenotes/notes/env-default-e8f2c60f1295d15f.yaml +5 -0
  33. osc_lib-4.0.1/releasenotes/notes/remove-support-for-legacy-formatters-1240317d801b4336.yaml +8 -0
  34. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/2023.1.rst +1 -1
  35. osc_lib-4.0.1/releasenotes/source/2025.1.rst +6 -0
  36. osc_lib-4.0.1/releasenotes/source/_templates/.placeholder +0 -0
  37. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/index.rst +1 -0
  38. {osc-lib-3.2.0 → osc_lib-4.0.1}/requirements.txt +1 -5
  39. {osc-lib-3.2.0 → osc_lib-4.0.1}/test-requirements.txt +0 -4
  40. {osc-lib-3.2.0 → osc_lib-4.0.1}/tox.ini +3 -3
  41. osc-lib-3.2.0/PKG-INFO +0 -87
  42. osc-lib-3.2.0/doc/Makefile +0 -130
  43. osc-lib-3.2.0/osc_lib.egg-info/PKG-INFO +0 -87
  44. osc-lib-3.2.0/osc_lib.egg-info/pbr.json +0 -1
  45. osc-lib-3.2.0/pyproject.toml +0 -9
  46. {osc-lib-3.2.0 → osc_lib-4.0.1}/.coveragerc +0 -0
  47. {osc-lib-3.2.0 → osc_lib-4.0.1}/.git-ignore-blame-revs +0 -0
  48. {osc-lib-3.2.0 → osc_lib-4.0.1}/.mailmap +0 -0
  49. {osc-lib-3.2.0 → osc_lib-4.0.1}/.stestr.conf +0 -0
  50. {osc-lib-3.2.0 → osc_lib-4.0.1}/.zuul.yaml +0 -0
  51. {osc-lib-3.2.0 → osc_lib-4.0.1}/AUTHORS +0 -0
  52. {osc-lib-3.2.0 → osc_lib-4.0.1}/HACKING.rst +0 -0
  53. {osc-lib-3.2.0 → osc_lib-4.0.1}/LICENSE +0 -0
  54. {osc-lib-3.2.0 → osc_lib-4.0.1}/README.rst +0 -0
  55. {osc-lib-3.2.0 → osc_lib-4.0.1}/doc/ext/__init__.py +0 -0
  56. {osc-lib-3.2.0 → osc_lib-4.0.1}/doc/ext/apidoc.py +0 -0
  57. {osc-lib-3.2.0 → osc_lib-4.0.1}/doc/requirements.txt +0 -0
  58. {osc-lib-3.2.0 → osc_lib-4.0.1}/doc/source/conf.py +0 -0
  59. {osc-lib-3.2.0 → osc_lib-4.0.1}/doc/source/contributor/index.rst +0 -0
  60. {osc-lib-3.2.0 → osc_lib-4.0.1}/doc/source/index.rst +0 -0
  61. {osc-lib-3.2.0 → osc_lib-4.0.1}/doc/source/reference/index.rst +0 -0
  62. {osc-lib-3.2.0 → osc_lib-4.0.1}/doc/source/user/change_log.rst +0 -0
  63. {osc-lib-3.2.0 → osc_lib-4.0.1}/doc/source/user/index.rst +0 -0
  64. {osc-lib-3.2.0 → osc_lib-4.0.1}/doc/source/user/transition.rst +0 -0
  65. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/__init__.py +0 -0
  66. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/api/__init__.py +0 -0
  67. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/cli/__init__.py +0 -0
  68. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/command/__init__.py +0 -0
  69. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/command/commandmanager.py +0 -0
  70. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/i18n.py +0 -0
  71. /osc-lib-3.2.0/osc_lib/tests/__init__.py → /osc_lib-4.0.1/osc_lib/py.typed +0 -0
  72. {osc-lib-3.2.0/osc_lib/tests/api → osc_lib-4.0.1/osc_lib/tests}/__init__.py +0 -0
  73. {osc-lib-3.2.0/osc_lib/tests/cli → osc_lib-4.0.1/osc_lib/tests/api}/__init__.py +0 -0
  74. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/api/fakes.py +0 -0
  75. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/api/test_api.py +0 -0
  76. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/api/test_utils.py +0 -0
  77. {osc-lib-3.2.0/osc_lib/tests/command → osc_lib-4.0.1/osc_lib/tests/cli}/__init__.py +0 -0
  78. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/cli/test_client_config.py +0 -0
  79. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/cli/test_format_columns.py +0 -0
  80. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/cli/test_identity.py +0 -0
  81. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/cli/test_parseractions.py +0 -0
  82. /osc-lib-3.2.0/releasenotes/notes/.placeholder → /osc_lib-4.0.1/osc_lib/tests/command/__init__.py +0 -0
  83. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/command/test_command.py +0 -0
  84. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/command/test_timing.py +0 -0
  85. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/fakes.py +0 -0
  86. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/test_clientmanager.py +0 -0
  87. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/test_logs.py +0 -0
  88. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/tests/utils/test_columns.py +0 -0
  89. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib/version.py +0 -0
  90. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib.egg-info/dependency_links.txt +0 -0
  91. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib.egg-info/not-zip-safe +0 -0
  92. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib.egg-info/requires.txt +0 -0
  93. {osc-lib-3.2.0 → osc_lib-4.0.1}/osc_lib.egg-info/top_level.txt +0 -0
  94. {osc-lib-3.2.0/releasenotes/source/_static → osc_lib-4.0.1/releasenotes/notes}/.placeholder +0 -0
  95. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/1.0-summary-47dcce446d6a512b.yaml +0 -0
  96. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/add-KeyValueAppendAction-class-f830e71152d6b91e.yaml +0 -0
  97. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/add-MultiKeyValueCommaAction-class-01dd254a287d70d2.yaml +0 -0
  98. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/add-size-column-5424c40af74688df.yaml +0 -0
  99. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/add_sdk_utils-d0c338eba682f2c8.yaml +0 -0
  100. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/arg-precedence-1ba9fd6929650830.yaml +0 -0
  101. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/auth-type-none-d96760912605f822.yaml +0 -0
  102. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/bug-1558690-1528b637f2c0a449.yaml +0 -0
  103. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/bug-1630822-mask-password-on-debug-20dcdf1c54e84fa1.yaml +0 -0
  104. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/bug-2004898-686577a07e791051.yaml +0 -0
  105. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/bug-2006480-436489d39643e76c.yaml +0 -0
  106. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/direct-openstacksdk-535a179f3c645cc0.yaml +0 -0
  107. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/drop-py2-support-60c93244107d5778.yaml +0 -0
  108. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/find-project-203bf867619c557e.yaml +0 -0
  109. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/keystone-to-keystone-9b2e55b051775322.yaml +0 -0
  110. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/none-auth-cli-48ab0e48d4852941.yaml +0 -0
  111. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/os-profile-as-environment-variable-a5e232e9ca7c5171.yaml +0 -0
  112. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/remove-babel-50abc5b548455bb2.yaml +0 -0
  113. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/remove-group-subclass-82134e6915c7c782.yaml +0 -0
  114. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/save-results-4473cb5731c0c763.yaml +0 -0
  115. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/notes/shell-argv-decode-cdc13dc0c4ec07af.yaml +0 -0
  116. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/2023.2.rst +0 -0
  117. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/2024.1.rst +0 -0
  118. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/2024.2.rst +0 -0
  119. {osc-lib-3.2.0/releasenotes/source/_templates → osc_lib-4.0.1/releasenotes/source/_static}/.placeholder +0 -0
  120. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/conf.py +0 -0
  121. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/newton.rst +0 -0
  122. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/ocata.rst +0 -0
  123. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/pike.rst +0 -0
  124. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/queens.rst +0 -0
  125. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/rocky.rst +0 -0
  126. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/stein.rst +0 -0
  127. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/train.rst +0 -0
  128. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/unreleased.rst +0 -0
  129. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/ussuri.rst +0 -0
  130. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/victoria.rst +0 -0
  131. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/wallaby.rst +0 -0
  132. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/xena.rst +0 -0
  133. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/yoga.rst +0 -0
  134. {osc-lib-3.2.0 → osc_lib-4.0.1}/releasenotes/source/zed.rst +0 -0
  135. {osc-lib-3.2.0 → osc_lib-4.0.1}/setup.cfg +0 -0
  136. {osc-lib-3.2.0 → osc_lib-4.0.1}/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: v4.6.0
7
+ rev: v5.0.0
8
8
  hooks:
9
9
  - id: trailing-whitespace
10
10
  - id: mixed-line-ending
@@ -22,7 +22,7 @@ repos:
22
22
  hooks:
23
23
  - id: doc8
24
24
  - repo: https://github.com/astral-sh/ruff-pre-commit
25
- rev: v0.6.4
25
+ rev: v0.9.6
26
26
  hooks:
27
27
  - id: ruff
28
28
  args: ['--fix', '--unsafe-fixes']
@@ -34,3 +34,18 @@ repos:
34
34
  additional_dependencies:
35
35
  - flake8-import-order~=0.18.2
36
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
+ )
@@ -1,6 +1,44 @@
1
1
  CHANGES
2
2
  =======
3
3
 
4
+ 4.0.1
5
+ -----
6
+
7
+ * Temporarily revert dependency bumps
8
+ * Use Python 3.8-style type hints
9
+ * Temporarily undrop support for Python 3.8, 3.9
10
+ * Drop support for Python 3.8, 3.9
11
+ * Replace UPPER\_CONSTRAINTS\_FILE
12
+
13
+ 4.0.0
14
+ -----
15
+
16
+ * typing: Enable disallow\_subclassing\_any
17
+ * tests: Resolve TODO
18
+ * utils: Deprecate legacy client-specific helpers
19
+ * utils: Remove support for legacy format functions
20
+ * utils: Group similar utilities together
21
+ * utils: Don't warn for partial formatter classes
22
+ * typing: Add typing to osc\_lib.utils
23
+ * typing: Add typing to osc\_lib.command
24
+ * clientmanager: Deprecate ClientCache
25
+ * typing: Add typing to osc\_lib.clientmanager
26
+ * typing: Add typing to osc\_lib.shell
27
+ * typing: Add typing to osc\_lib.logs, osc\_lib.i18n
28
+ * typing: Add typing to osc\_lib.cli
29
+ * api: Deprecate BaseAPI
30
+ * typing: Add typing to osc\_lib.api
31
+ * Remove unused docs Makefile
32
+ * typing: Add typing to osc\_lib.exceptions
33
+ * pre-commit: Enable mypy
34
+ * typing: Fix initial typing issues
35
+ * Update master for stable/2025.1
36
+ * Add pagination helpers
37
+ * pre-commit: Enable ruff S (bandit) checks
38
+ * pre-commit: Bump versions
39
+ * tests: Use consistent output widths
40
+ * reno: Update master for unmaintained/2023.1
41
+
4
42
  3.2.0
5
43
  -----
6
44
 
osc_lib-4.0.1/PKG-INFO ADDED
@@ -0,0 +1,94 @@
1
+ Metadata-Version: 2.1
2
+ Name: osc-lib
3
+ Version: 4.0.1
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>=3.2.0
23
+ Requires-Dist: keystoneauth1>=3.14.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
+
@@ -13,6 +13,9 @@
13
13
 
14
14
  """Base API Library"""
15
15
 
16
+ import typing as ty
17
+ import warnings
18
+
16
19
  from keystoneauth1 import exceptions as ksa_exceptions
17
20
  from keystoneauth1 import session as ksa_session
18
21
  import requests
@@ -42,8 +45,12 @@ class BaseAPI:
42
45
  HEADER_NAME = "OpenStack-API-Version"
43
46
 
44
47
  def __init__(
45
- self, session=None, service_type=None, endpoint=None, **kwargs
46
- ):
48
+ self,
49
+ session: ty.Optional[ksa_session.Session] = None,
50
+ service_type: ty.Optional[str] = None,
51
+ endpoint: ty.Optional[str] = None,
52
+ **kwargs: ty.Any,
53
+ ) -> None:
47
54
  """Base object that contains some common API objects and methods
48
55
 
49
56
  :param keystoneauth1.session.Session session:
@@ -58,6 +65,12 @@ class BaseAPI:
58
65
  Keyword arguments passed to keystoneauth1.session.Session().
59
66
  """
60
67
 
68
+ warnings.warn(
69
+ 'The BaseAPI class is deprecated for removal. Consider using '
70
+ 'openstacksdk instead else vendoring this code into your client',
71
+ category=DeprecationWarning,
72
+ )
73
+
61
74
  super().__init__()
62
75
 
63
76
  # Create a keystoneauth1.session.Session if one is not supplied
@@ -69,7 +82,7 @@ class BaseAPI:
69
82
  self.service_type = service_type
70
83
  self.endpoint = self._munge_endpoint(endpoint)
71
84
 
72
- def _munge_endpoint(self, endpoint):
85
+ def _munge_endpoint(self, endpoint: ty.Optional[str]) -> ty.Optional[str]:
73
86
  """Hook to allow subclasses to massage the passed-in endpoint
74
87
 
75
88
  Hook to massage passed-in endpoints from arbitrary sources,
@@ -90,7 +103,13 @@ class BaseAPI:
90
103
  else:
91
104
  return endpoint
92
105
 
93
- def _request(self, method, url, session=None, **kwargs):
106
+ def _request(
107
+ self,
108
+ method: str,
109
+ url: str,
110
+ session: ty.Optional[ksa_session.Session] = None,
111
+ **kwargs: ty.Any,
112
+ ) -> requests.Response:
94
113
  """Perform call into session
95
114
 
96
115
  All API calls are funneled through this method to provide a common
@@ -136,7 +155,13 @@ class BaseAPI:
136
155
 
137
156
  # The basic action methods all take a Session and return dict/lists
138
157
 
139
- def create(self, url, session=None, method=None, **params):
158
+ def create(
159
+ self,
160
+ url: str,
161
+ session: ty.Optional[ksa_session.Session] = None,
162
+ method: ty.Optional[str] = None,
163
+ **params: ty.Any,
164
+ ) -> ty.Union[requests.Response, ty.Any]:
140
165
  """Create a new resource
141
166
 
142
167
  :param string url:
@@ -156,7 +181,12 @@ class BaseAPI:
156
181
  except requests.JSONDecodeError:
157
182
  return ret
158
183
 
159
- def delete(self, url, session=None, **params):
184
+ def delete(
185
+ self,
186
+ url: str,
187
+ session: ty.Optional[ksa_session.Session] = None,
188
+ **params: ty.Any,
189
+ ) -> requests.Response:
160
190
  """Delete a resource
161
191
 
162
192
  :param string url:
@@ -169,13 +199,13 @@ class BaseAPI:
169
199
 
170
200
  def list(
171
201
  self,
172
- path,
173
- session=None,
174
- body=None,
175
- detailed=False,
176
- headers=None,
177
- **params,
178
- ):
202
+ path: str,
203
+ session: ty.Optional[ksa_session.Session] = None,
204
+ body: ty.Any = None,
205
+ detailed: bool = False,
206
+ headers: ty.Optional[ty.Dict[str, str]] = None,
207
+ **params: ty.Any,
208
+ ) -> ty.Union[requests.Response, ty.Any]:
179
209
  """Return a list of resources
180
210
 
181
211
  GET ${ENDPOINT}/${PATH}?${PARAMS}
@@ -226,11 +256,11 @@ class BaseAPI:
226
256
 
227
257
  def find_attr(
228
258
  self,
229
- path,
230
- value=None,
231
- attr=None,
232
- resource=None,
233
- ):
259
+ path: str,
260
+ value: ty.Optional[str] = None,
261
+ attr: ty.Optional[str] = None,
262
+ resource: ty.Optional[str] = None,
263
+ ) -> ty.Any:
234
264
  """Find a resource via attribute or ID
235
265
 
236
266
  Most APIs return a list wrapped by a dict with the resource
@@ -260,7 +290,7 @@ class BaseAPI:
260
290
  if resource is None:
261
291
  resource = path
262
292
 
263
- def getlist(kw):
293
+ def getlist(kw: ty.Dict[str, ty.Any]) -> ty.Any:
264
294
  """Do list call, unwrap resource dict if present"""
265
295
  ret = self.list(path, **kw)
266
296
  if isinstance(ret, dict) and resource in ret:
@@ -290,7 +320,12 @@ class BaseAPI:
290
320
  msg % {'resource': resource, 'attr': attr, 'value': value}
291
321
  )
292
322
 
293
- def find_bulk(self, path, headers=None, **kwargs):
323
+ def find_bulk(
324
+ self,
325
+ path: str,
326
+ headers: ty.Optional[ty.Dict[str, str]] = None,
327
+ **kwargs: ty.Any,
328
+ ) -> ty.List[ty.Any]:
294
329
  """Bulk load and filter locally
295
330
 
296
331
  :param string path:
@@ -318,7 +353,7 @@ class BaseAPI:
318
353
 
319
354
  return ret
320
355
 
321
- def find_one(self, path, **kwargs):
356
+ def find_one(self, path: str, **kwargs: ty.Any) -> ty.Any:
322
357
  """Find a resource by name or ID
323
358
 
324
359
  :param string path:
@@ -339,11 +374,11 @@ class BaseAPI:
339
374
 
340
375
  def find(
341
376
  self,
342
- path,
343
- value=None,
344
- attr=None,
345
- headers=None,
346
- ):
377
+ path: str,
378
+ value: ty.Optional[str] = None,
379
+ attr: ty.Optional[str] = None,
380
+ headers: ty.Optional[ty.Dict[str, str]] = None,
381
+ ) -> ty.Any:
347
382
  """Find a single resource by name or ID
348
383
 
349
384
  :param string path:
@@ -356,7 +391,7 @@ class BaseAPI:
356
391
  Headers dictionary to pass to requests
357
392
  """
358
393
 
359
- def raise_not_found():
394
+ def raise_not_found() -> ty.NoReturn:
360
395
  msg = _("%s not found") % value
361
396
  raise exceptions.NotFound(404, msg)
362
397
 
@@ -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: ty.Dict[str, _OptionDict] = {}
32
43
 
33
44
 
34
- def get_plugin_list():
45
+ def get_plugin_list() -> ty.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() -> ty.Dict[str, _OptionDict]:
45
56
  """Gather plugin options so the help action has them available"""
46
57
 
47
58
  global OPTIONS_LIST
@@ -65,7 +76,10 @@ def get_options_list():
65
76
  return OPTIONS_LIST
66
77
 
67
78
 
68
- def check_valid_authorization_options(options, auth_plugin_name):
79
+ def check_valid_authorization_options(
80
+ options: 'connection.Connection',
81
+ auth_plugin_name: str,
82
+ ) -> None:
69
83
  """Validate authorization options, and provide helpful error messages."""
70
84
  if (
71
85
  options.auth.get('project_id')
@@ -86,16 +100,15 @@ def check_valid_authorization_options(options, auth_plugin_name):
86
100
  )
87
101
 
88
102
 
89
- def check_valid_authentication_options(options, auth_plugin_name):
90
- """Validate authentication options, and provide helpful error messages
91
-
92
- :param required_scope: indicate whether a scoped token is required
93
-
94
- """
95
-
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."""
96
108
  # Get all the options defined within the plugin.
97
- plugin_opts = base.get_plugin_options(auth_plugin_name)
98
- plugin_opts = {opt.dest: opt for opt in plugin_opts}
109
+ plugin_opts = {
110
+ opt.dest: opt for opt in base.get_plugin_options(auth_plugin_name)
111
+ }
99
112
 
100
113
  # NOTE(aloga): this is an horrible hack. We need a way to specify the
101
114
  # required options in the plugins. Using the "required" argument for
@@ -141,7 +154,9 @@ def check_valid_authentication_options(options, auth_plugin_name):
141
154
  )
142
155
 
143
156
 
144
- def build_auth_plugins_option_parser(parser):
157
+ def build_auth_plugins_option_parser(
158
+ parser: argparse.ArgumentParser,
159
+ ) -> argparse.ArgumentParser:
145
160
  """Auth plugins options builder
146
161
 
147
162
  Builds dynamically the list of options expected by each available
@@ -206,13 +221,13 @@ def build_auth_plugins_option_parser(parser):
206
221
 
207
222
 
208
223
  def get_keystone2keystone_auth(
209
- local_auth,
210
- service_provider,
211
- project_id=None,
212
- project_name=None,
213
- project_domain_id=None,
214
- project_domain_name=None,
215
- ):
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:
216
231
  """Return Keystone 2 Keystone authentication for service provider.
217
232
 
218
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=ty.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:
@@ -14,7 +14,9 @@
14
14
  """OpenStackConfig subclass for argument compatibility"""
15
15
 
16
16
  import logging
17
+ import typing as ty
17
18
 
19
+ from keystoneauth1.loading import identity as ksa_loading
18
20
  from openstack.config import exceptions as sdk_exceptions
19
21
  from openstack.config import loader as config
20
22
  from oslo_utils import strutils
@@ -23,10 +25,12 @@ from oslo_utils import strutils
23
25
  LOG = logging.getLogger(__name__)
24
26
 
25
27
 
26
- # Sublcass OpenStackConfig in order to munge config values
28
+ # Subclass OpenStackConfig in order to munge config values
27
29
  # before auth plugins are loaded
28
- class OSC_Config(config.OpenStackConfig):
29
- def _auth_select_default_plugin(self, config):
30
+ class OSC_Config(config.OpenStackConfig): # type: ignore
31
+ def _auth_select_default_plugin(
32
+ self, config: ty.Dict[str, ty.Any]
33
+ ) -> ty.Dict[str, ty.Any]:
30
34
  """Select a default plugin based on supplied arguments
31
35
 
32
36
  Migrated from auth.select_auth_plugin()
@@ -59,7 +63,9 @@ class OSC_Config(config.OpenStackConfig):
59
63
  LOG.debug("Auth plugin {} selected".format(config['auth_type']))
60
64
  return config
61
65
 
62
- def _auth_v2_arguments(self, config):
66
+ def _auth_v2_arguments(
67
+ self, config: ty.Dict[str, ty.Any]
68
+ ) -> ty.Dict[str, ty.Any]:
63
69
  """Set up v2-required arguments from v3 info
64
70
 
65
71
  Migrated from auth.build_auth_params()
@@ -72,41 +78,49 @@ class OSC_Config(config.OpenStackConfig):
72
78
  config['auth']['tenant_name'] = config['auth']['project_name']
73
79
  return config
74
80
 
75
- def _auth_v2_ignore_v3(self, config):
81
+ def _auth_v2_ignore_v3(
82
+ self, config: ty.Dict[str, ty.Any]
83
+ ) -> ty.Dict[str, ty.Any]:
76
84
  """Remove v3 arguments if present for v2 plugin
77
85
 
78
86
  Migrated from clientmanager.setup_auth()
79
87
  """
80
-
81
88
  # NOTE(hieulq): If USER_DOMAIN_NAME, USER_DOMAIN_ID, PROJECT_DOMAIN_ID
82
89
  # or PROJECT_DOMAIN_NAME is present and API_VERSION is 2.0, then
83
90
  # ignore all domain related configs.
84
- if str(config.get('identity_api_version', '')).startswith(
85
- '2'
86
- ) and config.get('auth_type').endswith('password'):
87
- domain_props = [
88
- 'project_domain_id',
89
- 'project_domain_name',
90
- 'user_domain_id',
91
- 'user_domain_name',
92
- ]
93
- for prop in domain_props:
94
- if config['auth'].pop(prop, None) is not None:
95
- if config.get('cloud'):
96
- LOG.warning(
97
- "Ignoring domain related config {} for {}"
98
- "because identity API version is 2.0".format(
99
- prop, config['cloud']
100
- )
101
- )
102
- else:
103
- LOG.warning(
104
- f"Ignoring domain related config {prop} because"
105
- " identity API version is 2.0"
91
+ if not str(config.get('identity_api_version', '')).startswith('2'):
92
+ return config
93
+
94
+ if not config.get('auth_type') or not config['auth_type'].endswith(
95
+ 'password'
96
+ ):
97
+ return config
98
+
99
+ domain_props = [
100
+ 'project_domain_id',
101
+ 'project_domain_name',
102
+ 'user_domain_id',
103
+ 'user_domain_name',
104
+ ]
105
+ for prop in domain_props:
106
+ if config['auth'].pop(prop, None) is not None:
107
+ if config.get('cloud'):
108
+ LOG.warning(
109
+ "Ignoring domain related config {} for {}"
110
+ "because identity API version is 2.0".format(
111
+ prop, config['cloud']
106
112
  )
113
+ )
114
+ else:
115
+ LOG.warning(
116
+ f"Ignoring domain related config {prop} because"
117
+ " identity API version is 2.0"
118
+ )
107
119
  return config
108
120
 
109
- def _auth_default_domain(self, config):
121
+ def _auth_default_domain(
122
+ self, config: ty.Dict[str, ty.Any]
123
+ ) -> ty.Dict[str, ty.Any]:
110
124
  """Set a default domain from available arguments
111
125
 
112
126
  Migrated from clientmanager.setup_auth()
@@ -147,7 +161,9 @@ class OSC_Config(config.OpenStackConfig):
147
161
  config['auth']['user_domain_id'] = default_domain
148
162
  return config
149
163
 
150
- def auth_config_hook(self, config):
164
+ def auth_config_hook(
165
+ self, config: ty.Dict[str, ty.Any]
166
+ ) -> ty.Dict[str, ty.Any]:
151
167
  """Allow examination of config values before loading auth plugin
152
168
 
153
169
  OpenStackClient will override this to perform additional checks
@@ -165,7 +181,11 @@ class OSC_Config(config.OpenStackConfig):
165
181
  )
166
182
  return config
167
183
 
168
- def _validate_auth(self, config, loader, fixed_argparse=None):
184
+ def _validate_auth(
185
+ self,
186
+ config: ty.Dict[str, ty.Any],
187
+ loader: ksa_loading.BaseIdentityLoader, # type: ignore
188
+ ) -> ty.Dict[str, ty.Any]:
169
189
  """Validate auth plugin arguments"""
170
190
  # May throw a keystoneauth1.exceptions.NoMatchingPlugin
171
191
 
@@ -229,7 +249,8 @@ class OSC_Config(config.OpenStackConfig):
229
249
 
230
250
  return config
231
251
 
232
- def load_auth_plugin(self, config):
252
+ # TODO(stephenfin): Add type once we have typing for SDK
253
+ def load_auth_plugin(self, config: ty.Dict[str, ty.Any]) -> ty.Any:
233
254
  """Get auth plugin and validate args"""
234
255
 
235
256
  loader = self._get_auth_loader(config)