Skip to content

Allow specifying statuses for fetcher failover #96

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions atlassian_jwt_auth/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,12 @@ class HTTPSMultiRepositoryPublicKeyRetriever(BasePublicKeyRetriever):
repository locations based upon key ids.
"""

def __init__(self, key_repository_urls):
def __init__(self, key_repository_urls, failover_on=None):
if not isinstance(key_repository_urls, list):
raise TypeError('keystore_urls must be a list of urls.')
if failover_on is None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should have this "active" by default.

failover_on = (404, 500, 502, 503, 504)
self.failover_on = failover_on
self._retrievers = self._create_retrievers(key_repository_urls)

def _create_retrievers(self, key_repository_urls):
Expand All @@ -138,7 +141,8 @@ def retrieve(self, key_identifier, **requests_kwargs):
return retriever.retrieve(key_identifier, **requests_kwargs)
except (RequestException, PublicKeyRetrieverException) as e:
if isinstance(e, PublicKeyRetrieverException):
if e.status_code is None or e.status_code < 500:
if (e.status_code is None
or e.status_code not in self.failover_on):
raise
logger = logging.getLogger(__name__)
logger.warn('Unable to retrieve public key from store',
Expand Down
35 changes: 35 additions & 0 deletions atlassian_jwt_auth/tests/test_public_key_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import mock
import requests

from atlassian_jwt_auth.exceptions import PublicKeyRetrieverException
from atlassian_jwt_auth.key import (
HTTPSPublicKeyRetriever,
HTTPSMultiRepositoryPublicKeyRetriever,
Expand Down Expand Up @@ -125,6 +126,40 @@ def test_retrieve(self, mock_get_method):
retriever.retrieve('example/eg'),
self._public_key_pem)

@mock.patch.object(requests.Session, 'get')
def test_retrieve_with_400_error(self, mock_get_method):
""" tests that the retrieve method works as expected
when the first key repository returns a generic client error
response.
"""
retriever = HTTPSMultiRepositoryPublicKeyRetriever(self.keystore_urls)
_setup_mock_response_for_retriever(
mock_get_method, self._public_key_pem)
valid_response = mock_get_method.return_value
del mock_get_method.return_value
server_exception = requests.exceptions.HTTPError(
response=mock.Mock(status_code=400))
mock_get_method.side_effect = [server_exception, valid_response]
with self.assertRaises(PublicKeyRetrieverException):
retriever.retrieve('example/eg')

@mock.patch.object(requests.Session, 'get')
def test_retrieve_with_404_error(self, mock_get_method):
""" tests that the retrieve method works as expected
when the first key repository returns a not found response.
"""
retriever = HTTPSMultiRepositoryPublicKeyRetriever(self.keystore_urls)
_setup_mock_response_for_retriever(
mock_get_method, self._public_key_pem)
valid_response = mock_get_method.return_value
del mock_get_method.return_value
server_exception = requests.exceptions.HTTPError(
response=mock.Mock(status_code=404))
mock_get_method.side_effect = [server_exception, valid_response]
self.assertEqual(
retriever.retrieve('example/eg'),
self._public_key_pem)

@mock.patch.object(requests.Session, 'get')
def test_retrieve_with_500_error(self, mock_get_method):
""" tests that the retrieve method works as expected
Expand Down