Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-keystoneauth1 for
openSUSE:Factory checked in at 2023-03-21 17:40:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-keystoneauth1 (Old)
and /work/SRC/openSUSE:Factory/.python-keystoneauth1.new.31432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-keystoneauth1"
Tue Mar 21 17:40:51 2023 rev:17 rq:1073019 version:5.1.2
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-keystoneauth1/python-keystoneauth1.changes
2022-08-11 18:31:57.202210444 +0200
+++
/work/SRC/openSUSE:Factory/.python-keystoneauth1.new.31432/python-keystoneauth1.changes
2023-03-21 17:40:52.477642751 +0100
@@ -1,0 +2,11 @@
+Mon Mar 6 15:53:59 UTC 2023 - [email protected]
+
+- update to version 5.1.2
+ - OAuth2.0 Client Credentials Grant Flow Support
+ - Update python testing as per zed cycle teting runtime
+ - Enforce scope mutual exclusion for system
+ - Allow passing of version header
+ - Fix docs build for tox4
+ - Fix linters and bindep on jammy
+
+-------------------------------------------------------------------
Old:
----
keystoneauth1-4.6.0.tar.gz
New:
----
keystoneauth1-5.1.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-keystoneauth1.spec ++++++
--- /var/tmp/diff_new_pack.Fu9YtP/_old 2023-03-21 17:40:53.133645889 +0100
+++ /var/tmp/diff_new_pack.Fu9YtP/_new 2023-03-21 17:40:53.141645927 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-keystoneauth1
#
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,13 +17,13 @@
Name: python-keystoneauth1
-Version: 4.6.0
+Version: 5.1.2
Release: 0
Summary: OpenStack authenticating tools
License: Apache-2.0
Group: Development/Languages/Python
URL: https://docs.openstack.org/keystoneauth
-Source0:
https://files.pythonhosted.org/packages/source/k/keystoneauth1/keystoneauth1-4.6.0.tar.gz
+Source0:
https://files.pythonhosted.org/packages/source/k/keystoneauth1/keystoneauth1-5.1.2.tar.gz
BuildRequires: openstack-macros
BuildRequires: python3-PyYAML
BuildRequires: python3-betamax
@@ -100,7 +100,7 @@
%check
rm -v keystoneauth1/tests/unit/test_hacking_checks.py
-python3 -m stestr.cli run
+%{openstack_stestr_run}
%files -n python3-keystoneauth1
%license LICENSE
++++++ keystoneauth1-4.6.0.tar.gz -> keystoneauth1-5.1.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/keystoneauth1-4.6.0/.zuul.yaml
new/keystoneauth1-5.1.2/.zuul.yaml
--- old/keystoneauth1-4.6.0/.zuul.yaml 2022-05-20 14:26:02.000000000 +0200
+++ new/keystoneauth1-5.1.2/.zuul.yaml 2023-02-13 16:48:53.000000000 +0100
@@ -2,7 +2,7 @@
templates:
- check-requirements
- lib-forward-testing-python3
- - openstack-python3-ussuri-jobs
+ - openstack-python3-zed-jobs
- openstacksdk-functional-tips
- openstacksdk-tox-tips
- osc-tox-unit-tips
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/keystoneauth1-4.6.0/AUTHORS
new/keystoneauth1-5.1.2/AUTHORS
--- old/keystoneauth1-4.6.0/AUTHORS 2022-05-20 14:26:32.000000000 +0200
+++ new/keystoneauth1-5.1.2/AUTHORS 2023-02-13 16:49:31.000000000 +0100
@@ -75,6 +75,7 @@
Guang Yee <[email protected]>
Haiwei Xu <[email protected]>
Henry Nash <[email protected]>
+Hervé Beraud <[email protected]>
Ian Cordasco <[email protected]>
Ian Cordasco <[email protected]>
Ihar Hrachyshka <[email protected]>
@@ -179,6 +180,7 @@
XiaojueGuan <[email protected]>
YangLei <[email protected]>
Yatin Kumbhare <[email protected]>
+Yi Feng <[email protected]>
Yolanda Robla <[email protected]>
Zhenguo Niu <[email protected]>
ZhiQiang Fan <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/keystoneauth1-4.6.0/ChangeLog
new/keystoneauth1-5.1.2/ChangeLog
--- old/keystoneauth1-4.6.0/ChangeLog 2022-05-20 14:26:32.000000000 +0200
+++ new/keystoneauth1-5.1.2/ChangeLog 2023-02-13 16:49:31.000000000 +0100
@@ -1,6 +1,28 @@
CHANGES
=======
+5.1.2
+-----
+
+* Fix docs build for tox4
+
+5.1.1
+-----
+
+* Allow passing of version header
+* Enforce scope mutual exclusion for system
+* Fix linters and bindep on jammy
+
+5.1.0
+-----
+
+* OAuth2.0 Client Credentials Grant Flow Support
+
+5.0.0
+-----
+
+* Update python testing as per zed cycle teting runtime
+
4.6.0
-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/keystoneauth1-4.6.0/PKG-INFO
new/keystoneauth1-5.1.2/PKG-INFO
--- old/keystoneauth1-4.6.0/PKG-INFO 2022-05-20 14:26:32.638197700 +0200
+++ new/keystoneauth1-5.1.2/PKG-INFO 2023-02-13 16:49:32.015777300 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: keystoneauth1
-Version: 4.6.0
+Version: 5.1.2
Summary: Authentication Library for OpenStack Identity
Home-page: https://docs.openstack.org/keystoneauth/latest/
Author: OpenStack
@@ -54,9 +54,8 @@
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
Provides-Extra: betamax
Provides-Extra: kerberos
Provides-Extra: oauth1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/keystoneauth1-4.6.0/bindep.txt
new/keystoneauth1-5.1.2/bindep.txt
--- old/keystoneauth1-4.6.0/bindep.txt 2022-05-20 14:26:02.000000000 +0200
+++ new/keystoneauth1-5.1.2/bindep.txt 2023-02-13 16:48:53.000000000 +0100
@@ -2,7 +2,7 @@
# see https://docs.openstack.org/infra/bindep/ for additional information.
build-essential [platform:dpkg test]
-python-dev [platform:dpkg test]
+python3-dev [platform:dpkg test]
python3-devel [platform:rpm test]
libkrb5-dev [platform:dpkg test]
krb5-devel [platform:rpm test]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/keystoneauth1-4.6.0/keystoneauth1/discover.py
new/keystoneauth1-5.1.2/keystoneauth1/discover.py
--- old/keystoneauth1-4.6.0/keystoneauth1/discover.py 2022-05-20
14:26:02.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1/discover.py 2023-02-13
16:48:53.000000000 +0100
@@ -58,7 +58,7 @@
return LATEST if val == 'latest' or val == LATEST else int(val)
-def get_version_data(session, url, authenticated=None):
+def get_version_data(session, url, authenticated=None, version_header=None):
"""Retrieve raw version data from a url.
The return is a list of dicts of the form::
@@ -93,10 +93,15 @@
:param string url: Endpoint or discovery URL from which to retrieve data.
:param bool authenticated: Include a token in the discovery call.
(optional) Defaults to None.
+ :param string version_header: provide the OpenStack-API-Version header
+ for services which don't return version information without it, for
+ backward compatibility.
:return: A list of dicts containing version information.
:rtype: list(dict)
"""
headers = {'Accept': 'application/json'}
+ if version_header:
+ headers['OpenStack-API-Version'] = version_header
try:
resp = session.get(url, headers=headers, authenticated=authenticated)
@@ -197,7 +202,7 @@
Examples: (1,), [1, 2], ('12', '34', '56'), (LATEST,), (2, 'latest')
:return: A tuple of len >= 2 comprising integers and/or LATEST.
:raises TypeError: If the input version cannot be interpreted.
- """
+ """ # noqa: D412
# Copy the input var so the error presents the original value
ver = version
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/keystoneauth1/identity/__init__.py
new/keystoneauth1-5.1.2/keystoneauth1/identity/__init__.py
--- old/keystoneauth1-4.6.0/keystoneauth1/identity/__init__.py 2022-05-20
14:26:02.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1/identity/__init__.py 2023-02-13
16:48:53.000000000 +0100
@@ -61,6 +61,9 @@
V3MultiFactor = v3.MultiFactor
"""See :class:`keystoneauth1.identity.v3.MultiFactor`"""
+V3OAuth2ClientCredential = v3.OAuth2ClientCredential
+"""See :class:`keystoneauth1.identity.v3.OAuth2ClientCredential`"""
+
__all__ = ('BaseIdentityPlugin',
'Password',
'Token',
@@ -74,4 +77,5 @@
'V3TOTP',
'V3TokenlessAuth',
'V3ApplicationCredential',
- 'V3MultiFactor')
+ 'V3MultiFactor',
+ 'V3OAuth2ClientCredential')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/keystoneauth1/identity/v3/__init__.py
new/keystoneauth1-5.1.2/keystoneauth1/identity/v3/__init__.py
--- old/keystoneauth1-4.6.0/keystoneauth1/identity/v3/__init__.py
2022-05-20 14:26:02.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1/identity/v3/__init__.py
2023-02-13 16:48:53.000000000 +0100
@@ -23,6 +23,7 @@
from keystoneauth1.identity.v3.token import * # noqa
from keystoneauth1.identity.v3.totp import * # noqa
from keystoneauth1.identity.v3.tokenless_auth import * # noqa
+from keystoneauth1.identity.v3.oauth2_client_credential import * # noqa
__all__ = ('ApplicationCredential',
@@ -55,4 +56,7 @@
'ReceiptMethod',
- 'MultiFactor', )
+ 'MultiFactor',
+
+ 'OAuth2ClientCredential',
+ 'OAuth2ClientCredentialMethod',)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/keystoneauth1/identity/v3/base.py
new/keystoneauth1-5.1.2/keystoneauth1/identity/v3/base.py
--- old/keystoneauth1-4.6.0/keystoneauth1/identity/v3/base.py 2022-05-20
14:26:02.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1/identity/v3/base.py 2023-02-13
16:48:53.000000000 +0100
@@ -137,13 +137,14 @@
mutual_exclusion = [bool(self.domain_id or self.domain_name),
bool(self.project_id or self.project_name),
bool(self.trust_id),
+ bool(self.system_scope),
bool(self.unscoped)]
if sum(mutual_exclusion) > 1:
raise exceptions.AuthorizationFailure(
message='Authentication cannot be scoped to multiple'
' targets. Pick one of: project, domain, '
- 'trust or unscoped')
+ 'trust, system or unscoped')
if self.domain_id:
body['auth']['scope'] = {'domain': {'id': self.domain_id}}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/keystoneauth1/identity/v3/oauth2_client_credential.py
new/keystoneauth1-5.1.2/keystoneauth1/identity/v3/oauth2_client_credential.py
---
old/keystoneauth1-4.6.0/keystoneauth1/identity/v3/oauth2_client_credential.py
1970-01-01 01:00:00.000000000 +0100
+++
new/keystoneauth1-5.1.2/keystoneauth1/identity/v3/oauth2_client_credential.py
2023-02-13 16:48:53.000000000 +0100
@@ -0,0 +1,127 @@
+# Copyright 2022 OpenStack Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import requests.auth
+
+from keystoneauth1.exceptions import ClientException
+from keystoneauth1.identity.v3 import base
+
+__all__ = ('OAuth2ClientCredentialMethod', 'OAuth2ClientCredential')
+
+
+class OAuth2ClientCredentialMethod(base.AuthMethod):
+ """An auth method to fetch a token via an OAuth2.0 client credential.
+
+ :param string oauth2_endpoint: OAuth2.0 endpoint.
+ :param string oauth2_client_id: OAuth2.0 client credential id.
+ :param string oauth2_client_secret: OAuth2.0 client credential secret.
+ """
+
+ _method_parameters = [
+ 'oauth2_endpoint',
+ 'oauth2_client_id',
+ 'oauth2_client_secret'
+ ]
+
+ def get_auth_data(self, session, auth, headers, **kwargs):
+ """Return the authentication section of an auth plugin.
+
+ :param session: The communication session.
+ :type session: keystoneauth1.session.Session
+ :param base.Auth auth: The auth plugin calling the method.
+ :param dict headers: The headers that will be sent with the auth
+ request if a plugin needs to add to them.
+ :return: The identifier of this plugin and a dict of authentication
+ data for the auth type.
+ :rtype: tuple(string, dict)
+ """
+ auth_data = {
+ 'id': self.oauth2_client_id,
+ 'secret': self.oauth2_client_secret
+ }
+ return 'application_credential', auth_data
+
+ def get_cache_id_elements(self):
+ """Get the elements for this auth method that make it unique.
+
+ These elements will be used as part of the
+ :py:meth:`keystoneauth1.plugin.BaseIdentityPlugin.get_cache_id` to
+ allow caching of the auth plugin.
+
+ Plugins should override this if they want to allow caching of their
+ state.
+
+ To avoid collision or overrides the keys of the returned dictionary
+ should be prefixed with the plugin identifier. For example the password
+ plugin returns its username value as 'password_username'.
+ """
+ return dict(('oauth2_client_credential_%s' % p, getattr(self, p))
+ for p in self._method_parameters)
+
+
+class OAuth2ClientCredential(base.AuthConstructor):
+ """A plugin for authenticating via an OAuth2.0 client credential.
+
+ :param string auth_url: Identity service endpoint for authentication.
+ :param string oauth2_endpoint: OAuth2.0 endpoint.
+ :param string oauth2_client_id: OAuth2.0 client credential id.
+ :param string oauth2_client_secret: OAuth2.0 client credential secret.
+ """
+
+ _auth_method_class = OAuth2ClientCredentialMethod
+
+ def __init__(self, auth_url, *args, **kwargs):
+ super(OAuth2ClientCredential, self).__init__(auth_url, *args, **kwargs)
+ self._oauth2_endpoint = kwargs['oauth2_endpoint']
+ self._oauth2_client_id = kwargs['oauth2_client_id']
+ self._oauth2_client_secret = kwargs['oauth2_client_secret']
+
+ def get_headers(self, session, **kwargs):
+ """Fetch authentication headers for message.
+
+ :param session: The session object that the auth_plugin belongs to.
+ :type session: keystoneauth1.session.Session
+
+ :returns: Headers that are set to authenticate a message or None for
+ failure. Note that when checking this value that the empty
+ dict is a valid, non-failure response.
+ :rtype: dict
+ """
+ # get headers for X-Auth-Token
+ headers = super(OAuth2ClientCredential, self).get_headers(
+ session, **kwargs)
+
+ # Get OAuth2.0 access token and add the field 'Authorization'
+ data = {"grant_type": "client_credentials"}
+ auth = requests.auth.HTTPBasicAuth(self._oauth2_client_id,
+ self._oauth2_client_secret)
+ resp = session.request(self._oauth2_endpoint,
+ "POST",
+ authenticated=False,
+ raise_exc=False,
+ data=data,
+ requests_auth=auth)
+ if resp.status_code == 200:
+ oauth2 = resp.json()
+ oauth2_token = oauth2["access_token"]
+ if headers:
+ headers['Authorization'] = f'Bearer {oauth2_token}'
+ else:
+ headers = {'Authorization': f'Bearer {oauth2_token}'}
+ else:
+ error = resp.json()
+ msg = error.get("error_description")
+ raise ClientException(msg)
+
+ return headers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/keystoneauth1/identity/v3/oidc.py
new/keystoneauth1-5.1.2/keystoneauth1/identity/v3/oidc.py
--- old/keystoneauth1-4.6.0/keystoneauth1/identity/v3/oidc.py 2022-05-20
14:26:02.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1/identity/v3/oidc.py 2023-02-13
16:48:53.000000000 +0100
@@ -452,7 +452,7 @@
self.access_token = access_token
def get_payload(self, session):
- """OidcAccessToken does not require a payload."""
+ """OidcAccessToken does not require a payload.""" # noqa: D403
return {}
def get_unscoped_auth_ref(self, session):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/keystoneauth1/loading/_plugins/identity/v3.py
new/keystoneauth1-5.1.2/keystoneauth1/loading/_plugins/identity/v3.py
--- old/keystoneauth1-4.6.0/keystoneauth1/loading/_plugins/identity/v3.py
2022-05-20 14:26:02.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1/loading/_plugins/identity/v3.py
2023-02-13 16:48:53.000000000 +0100
@@ -338,3 +338,44 @@
self._methods = kwargs['auth_methods']
return super(MultiFactor, self).load_from_options(**kwargs)
+
+
+class OAuth2ClientCredential(loading.BaseV3Loader):
+
+ @property
+ def plugin_class(self):
+ return identity.V3OAuth2ClientCredential
+
+ def get_options(self):
+ options = super(OAuth2ClientCredential, self).get_options()
+ options.extend([
+ loading.Opt('oauth2_endpoint',
+ required=True,
+ help='Endpoint for OAuth2.0'),
+ ]),
+ options.extend([
+ loading.Opt('oauth2_client_id',
+ required=True,
+ help='Client id for OAuth2.0'),
+ ]),
+ options.extend([
+ loading.Opt('oauth2_client_secret',
+ secret=True,
+ required=True,
+ help='Client secret for OAuth2.0'),
+ ])
+
+ return options
+
+ def load_from_options(self, **kwargs):
+ if not kwargs.get('oauth2_endpoint'):
+ m = 'You must provide an OAuth2.0 endpoint.'
+ raise exceptions.OptionError(m)
+ if not kwargs.get('oauth2_client_id'):
+ m = 'You must provide an OAuth2.0 client credential ID.'
+ raise exceptions.OptionError(m)
+ if not kwargs.get('oauth2_client_secret'):
+ m = 'You must provide an OAuth2.0 client credential auth secret.'
+ raise exceptions.OptionError(m)
+
+ return super(OAuth2ClientCredential, self).load_from_options(**kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/keystoneauth1/tests/unit/identity/test_identity_v3.py
new/keystoneauth1-5.1.2/keystoneauth1/tests/unit/identity/test_identity_v3.py
---
old/keystoneauth1-4.6.0/keystoneauth1/tests/unit/identity/test_identity_v3.py
2022-05-20 14:26:02.000000000 +0200
+++
new/keystoneauth1-5.1.2/keystoneauth1/tests/unit/identity/test_identity_v3.py
2023-02-13 16:48:53.000000000 +0100
@@ -13,11 +13,13 @@
import copy
import json
import time
+import unittest
import uuid
from keystoneauth1 import _utils as ksa_utils
from keystoneauth1 import access
from keystoneauth1 import exceptions
+from keystoneauth1.exceptions import ClientException
from keystoneauth1 import fixture
from keystoneauth1.identity import v3
from keystoneauth1.identity.v3 import base as v3_base
@@ -37,6 +39,9 @@
TEST_APP_CRED_ID = 'appcredid'
TEST_APP_CRED_SECRET = 'secret'
+ TEST_CLIENT_CRED_ID = 'clientcredid'
+ TEST_CLIENT_CRED_SECRET = 'secret'
+
TEST_SERVICE_CATALOG = [{
"endpoints": [{
"url": "http://cdn.admin-nets.local:8774/v1.0/",
@@ -822,3 +827,261 @@
self.assertRequestHeaderEqual('Content-Type', 'application/json')
self.assertRequestHeaderEqual('Accept', 'application/json')
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
+
+ def test_oauth2_client_credential_method_http(self):
+ base_http = self.TEST_URL
+ oauth2_endpoint = f'{self.TEST_URL}/oauth_token'
+ oauth2_token = 'HW9bB6oYWJywz6mAN_KyIBXlof15Pk'
+ self.stub_auth(json=self.TEST_APP_CRED_TOKEN_RESPONSE)
+ client_cre = v3.OAuth2ClientCredential(
+ base_http,
+ oauth2_endpoint=oauth2_endpoint,
+ oauth2_client_id=self.TEST_CLIENT_CRED_ID,
+ oauth2_client_secret=self.TEST_CLIENT_CRED_SECRET
+ )
+ oauth2_resp = {
+ 'status_code': 200,
+ 'json': {
+ 'access_token': oauth2_token,
+ 'expires_in': 3600,
+ 'token_type': 'Bearer'
+ }
+ }
+ self.requests_mock.post(oauth2_endpoint,
+ [oauth2_resp])
+
+ sess = session.Session(auth=client_cre)
+ initial_cache_id = client_cre.get_cache_id()
+
+ auth_head = sess.get_auth_headers()
+ self.assertEqual(self.TEST_TOKEN, auth_head['X-Auth-Token'])
+ self.assertEqual(f'Bearer {oauth2_token}', auth_head['Authorization'])
+
+ self.assertEqual(sess.auth.auth_ref.auth_token, self.TEST_TOKEN)
+ self.assertEqual(initial_cache_id, client_cre.get_cache_id())
+
+ resp_ok = {
+ 'status_code': 200
+ }
+ self.requests_mock.post(f'{base_http}/test_api',
+ [resp_ok])
+ resp = sess.post(f'{base_http}/test_api', authenticated=True)
+ self.assertRequestHeaderEqual('Authorization',
+ f'Bearer {oauth2_token}')
+ self.assertRequestHeaderEqual('X-Auth-Token', self.TEST_TOKEN)
+ self.assertEqual(200, resp.status_code)
+
+ def test_oauth2_client_credential_method_https(self):
+ self.TEST_URL = self.TEST_URL.replace('http:', 'https:')
+ base_https = self.TEST_URL
+ oauth2_endpoint = f'{base_https}/oauth_token'
+ oauth2_token = 'HW9bB6oYWJywz6mAN_KyIBXlof15Pk'
+ self.stub_auth(json=self.TEST_APP_CRED_TOKEN_RESPONSE)
+ client_cre = v3.OAuth2ClientCredential(
+ base_https,
+ oauth2_endpoint=oauth2_endpoint,
+ oauth2_client_id=self.TEST_CLIENT_CRED_ID,
+ oauth2_client_secret=self.TEST_CLIENT_CRED_SECRET
+ )
+ oauth2_resp = {
+ 'status_code': 200,
+ 'json': {
+ 'access_token': oauth2_token,
+ 'expires_in': 3600,
+ 'token_type': 'Bearer'
+ }
+ }
+ self.requests_mock.post(oauth2_endpoint,
+ [oauth2_resp])
+
+ sess = session.Session(auth=client_cre)
+ initial_cache_id = client_cre.get_cache_id()
+
+ auth_head = sess.get_auth_headers()
+ self.assertEqual(self.TEST_TOKEN, auth_head['X-Auth-Token'])
+ self.assertEqual(f'Bearer {oauth2_token}', auth_head['Authorization'])
+
+ self.assertEqual(sess.auth.auth_ref.auth_token, self.TEST_TOKEN)
+ self.assertEqual(initial_cache_id, client_cre.get_cache_id())
+
+ resp_ok = {
+ 'status_code': 200
+ }
+ self.requests_mock.post(f'{base_https}/test_api',
+ [resp_ok])
+ resp = sess.post(f'{base_https}/test_api', authenticated=True)
+ self.assertRequestHeaderEqual('Authorization',
+ f'Bearer {oauth2_token}')
+ self.assertRequestHeaderEqual('X-Auth-Token', self.TEST_TOKEN)
+ self.assertEqual(200, resp.status_code)
+
+ def test_oauth2_client_credential_method_base_header_none(self):
+ base_https = self.TEST_URL.replace('http:', 'https:')
+ oauth2_endpoint = f'{base_https}/oauth_token'
+ oauth2_token = 'HW9bB6oYWJywz6mAN_KyIBXlof15Pk'
+ with unittest.mock.patch(
+ 'keystoneauth1.plugin.BaseAuthPlugin.'
+ 'get_headers') as co_mock:
+ co_mock.return_value = None
+ client_cre = v3.OAuth2ClientCredential(
+ base_https,
+ oauth2_endpoint=oauth2_endpoint,
+ oauth2_client_id=self.TEST_CLIENT_CRED_ID,
+ oauth2_client_secret=self.TEST_CLIENT_CRED_SECRET
+ )
+ oauth2_resp = {
+ 'status_code': 200,
+ 'json': {
+ 'access_token': oauth2_token,
+ 'expires_in': 3600,
+ 'token_type': 'Bearer'
+ }
+ }
+ self.requests_mock.post(oauth2_endpoint,
+ [oauth2_resp])
+
+ sess = session.Session(auth=client_cre)
+ auth_head = sess.get_auth_headers()
+ self.assertNotIn('X-Auth-Token', auth_head)
+ self.assertEqual(f'Bearer {oauth2_token}',
+ auth_head['Authorization'])
+
+ def test_oauth2_client_credential_method_rm_auth(self):
+ base_https = self.TEST_URL.replace('http:', 'https:')
+ base_http = self.TEST_URL
+ oauth2_endpoint = f'{base_https}/oauth_token'
+ oauth2_token = 'HW9bB6oYWJywz6mAN_KyIBXlof15Pk'
+ self.stub_auth(json=self.TEST_APP_CRED_TOKEN_RESPONSE)
+ client_cre = v3.OAuth2ClientCredential(
+ base_http,
+ oauth2_endpoint=oauth2_endpoint,
+ oauth2_client_id=self.TEST_CLIENT_CRED_ID,
+ oauth2_client_secret=self.TEST_CLIENT_CRED_SECRET
+ )
+ oauth2_resp = {
+ 'status_code': 200,
+ 'json': {
+ 'access_token': oauth2_token,
+ 'expires_in': 3600,
+ 'token_type': 'Bearer'
+ }
+ }
+ self.requests_mock.post(oauth2_endpoint,
+ [oauth2_resp])
+
+ sess = session.Session(auth=client_cre)
+ initial_cache_id = client_cre.get_cache_id()
+
+ auth_head = sess.get_auth_headers()
+ self.assertEqual(self.TEST_TOKEN, auth_head['X-Auth-Token'])
+ self.assertEqual(f'Bearer {oauth2_token}', auth_head['Authorization'])
+
+ self.assertEqual(sess.auth.auth_ref.auth_token, self.TEST_TOKEN)
+ self.assertEqual(initial_cache_id, client_cre.get_cache_id())
+
+ resp_ok = {
+ 'status_code': 200
+ }
+ self.requests_mock.post(f'{base_http}/test_api',
+ [resp_ok])
+ resp = sess.post(f'{base_http}/test_api', authenticated=True)
+ self.assertRequestHeaderEqual('Authorization',
+ f'Bearer {oauth2_token}')
+ self.assertRequestHeaderEqual('X-Auth-Token', self.TEST_TOKEN)
+ self.assertEqual(200, resp.status_code)
+
+ def test_oauth2_client_credential_method_other_not_rm_auth(self):
+ base_https = self.TEST_URL.replace('http:', 'https:')
+ other_auth_token = 'HW9bB6oYWJywz6mAN_KyIBXlof15Pk'
+ self.stub_auth(json=self.TEST_APP_CRED_TOKEN_RESPONSE)
+ with unittest.mock.patch(
+ 'keystoneauth1.identity.v3.Password.get_headers') as co_mock:
+ co_mock.return_value = {
+ 'X-Auth-Token': self.TEST_TOKEN,
+ 'Authorization': other_auth_token
+ }
+ pass_auth = v3.Password(base_https,
+ username=self.TEST_USER,
+ password=self.TEST_PASS,
+ include_catalog=False)
+ sess = session.Session(auth=pass_auth)
+
+ resp_ok = {
+ 'status_code': 200
+ }
+ self.requests_mock.post(f'{base_https}/test_api',
+ [resp_ok])
+ resp = sess.post(f'{base_https}/test_api', authenticated=True)
+ self.assertRequestHeaderEqual('Authorization', other_auth_token)
+ self.assertRequestHeaderEqual('X-Auth-Token', self.TEST_TOKEN)
+ self.assertEqual(200, resp.status_code)
+
+ def test_oauth2_client_credential_method_500(self):
+ self.TEST_URL = self.TEST_URL.replace('http:', 'https:')
+ base_https = self.TEST_URL
+ oauth2_endpoint = f'{base_https}/oauth_token'
+ self.stub_auth(json=self.TEST_APP_CRED_TOKEN_RESPONSE)
+ client_cre = v3.OAuth2ClientCredential(
+ base_https,
+ oauth2_endpoint=oauth2_endpoint,
+ oauth2_client_id=self.TEST_CLIENT_CRED_ID,
+ oauth2_client_secret=self.TEST_CLIENT_CRED_SECRET
+ )
+ oauth2_resp = {
+ 'status_code': 500,
+ 'json': {
+ 'error': 'other_error',
+ 'error_description':
+ 'Unknown error is occur.'
+ }
+ }
+ self.requests_mock.post(oauth2_endpoint,
+ [oauth2_resp])
+
+ sess = session.Session(auth=client_cre)
+ err = self.assertRaises(ClientException, sess.get_auth_headers)
+ self.assertEqual('Unknown error is occur.',
+ str(err))
+
+ def test_oauth2_client_credential_reauth_called_https(self):
+ base_https = self.TEST_URL.replace('http:', 'https:')
+ oauth2_endpoint = f'{base_https}/oauth_token'
+ oauth2_token = 'HW9bB6oYWJywz6mAN_KyIBXlof15Pk'
+ auth = v3.OAuth2ClientCredential(
+ base_https,
+ oauth2_endpoint=oauth2_endpoint,
+ oauth2_client_id='clientcredid',
+ oauth2_client_secret='secret'
+ )
+ oauth2_resp = {
+ 'status_code': 200,
+ 'json': {
+ 'access_token': oauth2_token,
+ 'expires_in': 3600,
+ 'token_type': 'Bearer'
+ }
+ }
+ self.requests_mock.post(oauth2_endpoint,
+ [oauth2_resp])
+
+ sess = session.Session(auth=auth)
+
+ resp_text = json.dumps(self.TEST_APP_CRED_TOKEN_RESPONSE)
+ resp_ok = {
+ 'status_code': 200,
+ 'headers': {
+ 'Content-Type': 'application/json',
+ 'x-subject-token': self.TEST_TOKEN
+ },
+ 'text': resp_text
+ }
+ self.requests_mock.post(f'{base_https}/auth/tokens',
+ [resp_ok,
+ {'text': 'Failed', 'status_code': 401},
+ resp_ok])
+
+ resp = sess.post(f'{base_https}/auth/tokens', authenticated=True)
+ self.assertRequestHeaderEqual('Authorization',
+ f'Bearer {oauth2_token}')
+ self.assertEqual(200, resp.status_code)
+ self.assertEqual(resp_text, resp.text)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/keystoneauth1/tests/unit/loading/test_v3.py
new/keystoneauth1-5.1.2/keystoneauth1/tests/unit/loading/test_v3.py
--- old/keystoneauth1-4.6.0/keystoneauth1/tests/unit/loading/test_v3.py
2022-05-20 14:26:02.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1/tests/unit/loading/test_v3.py
2023-02-13 16:48:53.000000000 +0100
@@ -486,3 +486,56 @@
username=uuid.uuid4().hex,
project_name=uuid.uuid4().hex,
project_domain_id=uuid.uuid4().hex)
+
+
+class V3Oauth2ClientCredentialTests(utils.TestCase):
+
+ def setUp(self):
+ super(V3Oauth2ClientCredentialTests, self).setUp()
+
+ self.auth_url = uuid.uuid4().hex
+
+ def create(self, **kwargs):
+ kwargs.setdefault('auth_url', self.auth_url)
+ loader = loading.get_plugin_loader('v3oauth2clientcredential')
+ return loader.load_from_options(**kwargs)
+
+ def test_basic(self):
+ id = uuid.uuid4().hex
+ secret = uuid.uuid4().hex
+ oauth2_endpoint = "https://localhost/token"
+
+ client_cred = self.create(oauth2_endpoint=oauth2_endpoint,
+ oauth2_client_id=id,
+ oauth2_client_secret=secret)
+
+ client_method = client_cred.auth_methods[0]
+ self.assertEqual(id, client_method.oauth2_client_id)
+ self.assertEqual(secret, client_method.oauth2_client_secret)
+ self.assertEqual(oauth2_endpoint, client_method.oauth2_endpoint)
+
+ self.assertEqual(id, client_cred._oauth2_client_id)
+ self.assertEqual(secret, client_cred._oauth2_client_secret)
+ self.assertEqual(oauth2_endpoint, client_cred._oauth2_endpoint)
+
+ def test_without_oauth2_endpoint(self):
+ id = uuid.uuid4().hex
+ secret = uuid.uuid4().hex
+ self.assertRaises(exceptions.OptionError,
+ self.create,
+ oauth2_client_id=id,
+ oauth2_client_secret=secret)
+
+ def test_without_client_id(self):
+ oauth2_endpoint = "https://localhost/token"
+ self.assertRaises(exceptions.OptionError,
+ self.create,
+ oauth2_endpoint=oauth2_endpoint,
+ oauth2_client_secret=uuid.uuid4().hex)
+
+ def test_without_secret(self):
+ oauth2_endpoint = "https://localhost/token"
+ self.assertRaises(exceptions.OptionError,
+ self.create,
+ oauth2_endpoint=oauth2_endpoint,
+ oauth2_client_id=uuid.uuid4().hex)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/keystoneauth1/tests/unit/test_discovery.py
new/keystoneauth1-5.1.2/keystoneauth1/tests/unit/test_discovery.py
--- old/keystoneauth1-4.6.0/keystoneauth1/tests/unit/test_discovery.py
2022-05-20 14:26:02.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1/tests/unit/test_discovery.py
2023-02-13 16:48:53.000000000 +0100
@@ -1321,7 +1321,8 @@
def test_run_discovery_auth(self):
url = 'https://example.com'
- headers = {'Accept': 'application/json'}
+ headers = {'Accept': 'application/json',
+ 'OpenStack-API-Version': 'version header test'}
session = mock.Mock()
session.get.side_effect = [
@@ -1332,7 +1333,8 @@
]
try:
- discover.get_version_data(session, url)
+ discover.get_version_data(
+ session, url, version_header='version header test')
except exceptions.BadRequest:
pass
# Only one call with 'url'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/keystoneauth1-4.6.0/keystoneauth1.egg-info/PKG-INFO
new/keystoneauth1-5.1.2/keystoneauth1.egg-info/PKG-INFO
--- old/keystoneauth1-4.6.0/keystoneauth1.egg-info/PKG-INFO 2022-05-20
14:26:32.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1.egg-info/PKG-INFO 2023-02-13
16:49:31.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: keystoneauth1
-Version: 4.6.0
+Version: 5.1.2
Summary: Authentication Library for OpenStack Identity
Home-page: https://docs.openstack.org/keystoneauth/latest/
Author: OpenStack
@@ -54,9 +54,8 @@
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
Provides-Extra: betamax
Provides-Extra: kerberos
Provides-Extra: oauth1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/keystoneauth1.egg-info/SOURCES.txt
new/keystoneauth1-5.1.2/keystoneauth1.egg-info/SOURCES.txt
--- old/keystoneauth1-4.6.0/keystoneauth1.egg-info/SOURCES.txt 2022-05-20
14:26:32.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1.egg-info/SOURCES.txt 2023-02-13
16:49:31.000000000 +0100
@@ -99,6 +99,7 @@
keystoneauth1/identity/v3/federation.py
keystoneauth1/identity/v3/k2k.py
keystoneauth1/identity/v3/multi_factor.py
+keystoneauth1/identity/v3/oauth2_client_credential.py
keystoneauth1/identity/v3/oidc.py
keystoneauth1/identity/v3/password.py
keystoneauth1/identity/v3/receipt.py
@@ -213,6 +214,7 @@
releasenotes/notes/api-sig-error-guideline-handler.yaml
releasenotes/notes/basic-http-auth-45bea4298209df75.yaml
releasenotes/notes/bp-application-credentials-416a1f8bb2311e04.yaml
+releasenotes/notes/bp-oauth2-client-credentials-ext-06271700d4f33a7e.yaml
releasenotes/notes/bp-system-scope-29e9c597039ddb1e.yaml
releasenotes/notes/bug-1582774-49af731b6dfc6f2f.yaml
releasenotes/notes/bug-1614688-c4a1bd54f4ba5644.yaml
@@ -229,6 +231,7 @@
releasenotes/notes/client-side-rate-limiting-dec43fc9b54f5b70.yaml
releasenotes/notes/collect-timing-85f007f0d86c8b26.yaml
releasenotes/notes/drop-py-2-7-f90c67a5db0dfeb8.yaml
+releasenotes/notes/drop-python-3-6-and-3-7-c407d5898c5eafec.yaml
releasenotes/notes/drop-python-3.5-362bb9d47f830353.yaml
releasenotes/notes/expose-endpoint-status-6195a6b76d8a8de8.yaml
releasenotes/notes/filter-versions-service-type-763af68092344b7a.yaml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/keystoneauth1.egg-info/entry_points.txt
new/keystoneauth1-5.1.2/keystoneauth1.egg-info/entry_points.txt
--- old/keystoneauth1-4.6.0/keystoneauth1.egg-info/entry_points.txt
2022-05-20 14:26:32.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1.egg-info/entry_points.txt
2023-02-13 16:49:31.000000000 +0100
@@ -12,6 +12,7 @@
v3kerberos = keystoneauth1.extras.kerberos._loading:Kerberos
v3multifactor = keystoneauth1.loading._plugins.identity.v3:MultiFactor
v3oauth1 = keystoneauth1.extras.oauth1._loading:V3OAuth1
+v3oauth2clientcredential =
keystoneauth1.loading._plugins.identity.v3:OAuth2ClientCredential
v3oidcaccesstoken =
keystoneauth1.loading._plugins.identity.v3:OpenIDConnectAccessToken
v3oidcauthcode =
keystoneauth1.loading._plugins.identity.v3:OpenIDConnectAuthorizationCode
v3oidcclientcredentials =
keystoneauth1.loading._plugins.identity.v3:OpenIDConnectClientCredentials
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/keystoneauth1-4.6.0/keystoneauth1.egg-info/pbr.json
new/keystoneauth1-5.1.2/keystoneauth1.egg-info/pbr.json
--- old/keystoneauth1-4.6.0/keystoneauth1.egg-info/pbr.json 2022-05-20
14:26:32.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1.egg-info/pbr.json 2023-02-13
16:49:31.000000000 +0100
@@ -1 +1 @@
-{"git_version": "f194e6a", "is_release": true}
\ No newline at end of file
+{"git_version": "6ee21bd", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/keystoneauth1.egg-info/requires.txt
new/keystoneauth1-5.1.2/keystoneauth1.egg-info/requires.txt
--- old/keystoneauth1-4.6.0/keystoneauth1.egg-info/requires.txt 2022-05-20
14:26:32.000000000 +0200
+++ new/keystoneauth1-5.1.2/keystoneauth1.egg-info/requires.txt 2023-02-13
16:49:31.000000000 +0100
@@ -25,15 +25,14 @@
betamax>=0.7.0
coverage!=4.4,>=4.0
fixtures>=3.0.0
-flake8-docstrings==0.2.1.post1
+flake8-docstrings~=1.6.0
flake8-import-order>=0.17.1
-hacking<3.1.0,>=3.0.1
+hacking~=4.1.0
lxml>=4.2.0
oauthlib>=0.6.2
oslo.config>=5.2.0
oslo.utils>=3.33.0
oslotest>=3.2.0
-pycodestyle<2.6.0,>=2.0.0
reno>=3.1.0
requests-kerberos>=0.8.0
requests-mock>=1.2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/releasenotes/notes/bp-oauth2-client-credentials-ext-06271700d4f33a7e.yaml
new/keystoneauth1-5.1.2/releasenotes/notes/bp-oauth2-client-credentials-ext-06271700d4f33a7e.yaml
---
old/keystoneauth1-4.6.0/releasenotes/notes/bp-oauth2-client-credentials-ext-06271700d4f33a7e.yaml
1970-01-01 01:00:00.000000000 +0100
+++
new/keystoneauth1-5.1.2/releasenotes/notes/bp-oauth2-client-credentials-ext-06271700d4f33a7e.yaml
2023-02-13 16:48:53.000000000 +0100
@@ -0,0 +1,10 @@
+---
+features:
+ - |
+ [`blueprint oauth2-client-credentials-ext
<https://blueprints.launchpad.net/keystone/+spec/oauth2-client-credentials-ext>`_]
+ Added a new OAuth2ClientCredential plugin, accessible via the
+ 'v3oauth2clientcredential' entry point, making possible to authenticate
+ using an application credentials as an OAuth2.0 client credentials.
+ Keystoneauth can now be used to access the OpenStack APIs that use the
+ keystone middleware to support OAuth2.0 client credentials authentication
+ through the keystone identity server.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/keystoneauth1-4.6.0/releasenotes/notes/drop-python-3-6-and-3-7-c407d5898c5eafec.yaml
new/keystoneauth1-5.1.2/releasenotes/notes/drop-python-3-6-and-3-7-c407d5898c5eafec.yaml
---
old/keystoneauth1-4.6.0/releasenotes/notes/drop-python-3-6-and-3-7-c407d5898c5eafec.yaml
1970-01-01 01:00:00.000000000 +0100
+++
new/keystoneauth1-5.1.2/releasenotes/notes/drop-python-3-6-and-3-7-c407d5898c5eafec.yaml
2023-02-13 16:48:53.000000000 +0100
@@ -0,0 +1,5 @@
+---
+upgrade:
+ - |
+ Python 3.6 & 3.7 support has been dropped. The minimum version of Python
+ now supported is Python 3.8.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/keystoneauth1-4.6.0/setup.cfg
new/keystoneauth1-5.1.2/setup.cfg
--- old/keystoneauth1-4.6.0/setup.cfg 2022-05-20 14:26:32.638197700 +0200
+++ new/keystoneauth1-5.1.2/setup.cfg 2023-02-13 16:49:32.015777300 +0100
@@ -6,7 +6,7 @@
author = OpenStack
author_email = [email protected]
home_page = https://docs.openstack.org/keystoneauth/latest/
-python_equires = >=3.6
+python_equires = >=3.8
classifier =
Environment :: OpenStack
Intended Audience :: Information Technology
@@ -17,9 +17,8 @@
Programming Language :: Python :: Implementation :: CPython
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3
- Programming Language :: Python :: 3.6
- Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
+ Programming Language :: Python :: 3.9
[files]
packages =
@@ -61,6 +60,7 @@
v3samlpassword = keystoneauth1.extras._saml2._loading:Saml2Password
v3applicationcredential =
keystoneauth1.loading._plugins.identity.v3:ApplicationCredential
v3multifactor = keystoneauth1.loading._plugins.identity.v3:MultiFactor
+ v3oauth2clientcredential =
keystoneauth1.loading._plugins.identity.v3:OAuth2ClientCredential
[egg_info]
tag_build =
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/keystoneauth1-4.6.0/test-requirements.txt
new/keystoneauth1-5.1.2/test-requirements.txt
--- old/keystoneauth1-4.6.0/test-requirements.txt 2022-05-20
14:26:02.000000000 +0200
+++ new/keystoneauth1-5.1.2/test-requirements.txt 2023-02-13
16:48:53.000000000 +0100
@@ -2,10 +2,9 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-hacking>=3.0.1,<3.1.0 # Apache-2.0
-flake8-docstrings==0.2.1.post1 # MIT
+hacking~=4.1.0 # Apache-2.0
+flake8-docstrings~=1.6.0 # MIT
flake8-import-order>=0.17.1 #LGPLv3
-pycodestyle>=2.0.0,<2.6.0 # MIT
bandit<1.6.0,>=1.1.0 # Apache-2.0
coverage!=4.4,>=4.0 # Apache-2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/keystoneauth1-4.6.0/tox.ini
new/keystoneauth1-5.1.2/tox.ini
--- old/keystoneauth1-4.6.0/tox.ini 2022-05-20 14:26:02.000000000 +0200
+++ new/keystoneauth1-5.1.2/tox.ini 2023-02-13 16:48:53.000000000 +0100
@@ -1,7 +1,6 @@
[tox]
minversion = 3.1.1
-skipsdist = True
-envlist = py38,pep8,releasenotes
+envlist = py3,pep8,releasenotes
ignore_basepython_conflict = True
[testenv]
@@ -14,7 +13,7 @@
-r{toxinidir}/test-requirements.txt
-r{toxinidir}/requirements.txt
commands = stestr run {posargs}
-whitelist_externals =
+allowlist_externals =
bash
basepython = python3
@@ -53,10 +52,12 @@
# D102: Missing docstring in public method
# D103: Missing docstring in public function
# D104: Missing docstring in public package
+# D107: Missing docstring in __init__
# D203: 1 blank line required before class docstring (deprecated in pep257)
+# D401: First line should be in imperative mood; try rephrasing
# W503 line break before binary operator
# W504 line break after binary operator
-ignore = D100,D101,D102,D103,D104,D203,W503,W504
+ignore = D100,D101,D102,D103,D104,D107,D203,D401,W503,W504
# H106: Donât put vim configuration in source files
# H203: Use assertIs(Not)None to check for None
enable-extensions=H106,H203
@@ -83,7 +84,7 @@
SPHINX_APIDOC_OPTIONS=noindex,members,undoc-members,show-inheritance
envdir = {toxworkdir}/docs
deps = {[testenv:docs]deps}
-whitelist_externals =
+allowlist_externals =
make
rm
commands =