Skip to content

Commit

Permalink
Honor REQUESTS_CA_BUNDLE env var in Endpoint class
Browse files Browse the repository at this point in the history
This allows users to set the path to a cert bundle.
The logic is:

* Any explicit value passed to get_endpoint() is used
* Otherwise use REQUESTS_CA_BUNDLE if the var exists in the env
* Otherwise, default to true.
  • Loading branch information
jamesls committed Jan 9, 2014
1 parent e9c7077 commit 4142e03
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 4 deletions.
26 changes: 22 additions & 4 deletions botocore/endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
# IN THE SOFTWARE.
#

import os
import logging
import time
import threading
Expand Down Expand Up @@ -51,12 +52,13 @@ class Endpoint(object):
:ivar session: The session object.
"""

def __init__(self, service, region_name, host, auth, proxies=None):
def __init__(self, service, region_name, host, auth, proxies=None,
verify=True):
self.service = service
self.session = self.service.session
self.region_name = region_name
self.host = host
self.verify = True
self.verify = verify
self.auth = auth
if proxies is None:
proxies = {}
Expand Down Expand Up @@ -242,7 +244,7 @@ def _get_proxies(url):
return get_environ_proxies(url)


def get_endpoint(service, region_name, endpoint_url):
def get_endpoint(service, region_name, endpoint_url, verify=None):
cls = SERVICE_TO_ENDPOINT.get(service.type)
if cls is None:
raise botocore.exceptions.UnknownServiceStyle(
Expand All @@ -256,7 +258,23 @@ def get_endpoint(service, region_name, endpoint_url):
region_name=region_name,
service_object=service)
proxies = _get_proxies(endpoint_url)
return cls(service, region_name, endpoint_url, auth=auth, proxies=proxies)
verify = _get_verify_value(verify)
return cls(service, region_name, endpoint_url, auth=auth, proxies=proxies,
verify=verify)


def _get_verify_value(verify):
# This is to account for:
# https://github.com/kennethreitz/requests/issues/1436
# where we need to honor REQUESTS_CA_BUNDLE because we're creating our
# own request objects.
# First, if verify is not None, then the user explicitly specified
# a value so this automatically wins.
if verify is not None:
return verify
# Otherwise use the value from REQUESTS_CA_BUNDLE, or default to
# True if the env var does not exist.
return os.environ.get('REQUESTS_CA_BUNDLE', True)


def _get_auth(signature_version, credentials, service_name, region_name,
Expand Down
44 changes: 44 additions & 0 deletions tests/unit/test_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ def seek(self, where):


class TestGetEndpoint(unittest.TestCase):
def setUp(self):
self.environ = {}
self.environ_patch = patch('os.environ', self.environ)
self.environ_patch.start()

def tearDown(self):
self.environ_patch.stop()

def create_mock_service(self, service_type, signature_version='v2'):
service = Mock()
service.type = service_type
Expand Down Expand Up @@ -101,6 +109,42 @@ def test_omitted_auth_handler(self):
'https://service.region.amazonaws.com')
self.assertIsNone(endpoint.auth)

def test_get_endpoint_default_verify_ssl(self):
service = self.create_mock_service('query')
endpoint = get_endpoint(service, 'us-west-2',
'https://service.region.amazonaws.com')
self.assertTrue(endpoint.verify)

def test_verify_ssl_can_be_disabled(self):
service = self.create_mock_service('query')
endpoint = get_endpoint(service, 'us-west-2',
'https://service.region.amazonaws.com',
verify=False)
self.assertFalse(endpoint.verify)

def test_verify_ssl_can_specify_cert_bundle(self):
service = self.create_mock_service('query')
endpoint = get_endpoint(service, 'us-west-2',
'https://service.region.amazonaws.com',
verify='/path/cacerts.pem')
self.assertEqual(endpoint.verify, '/path/cacerts.pem')

def test_honor_cert_bundle_env_var(self):
self.environ['REQUESTS_CA_BUNDLE'] = '/env/cacerts.pem'
service = self.create_mock_service('query')
endpoint = get_endpoint(service, 'us-west-2',
'https://service.region.amazonaws.com')
self.assertEqual(endpoint.verify, '/env/cacerts.pem')

def test_env_ignored_if_explicitly_passed(self):
self.environ['REQUESTS_CA_BUNDLE'] = '/env/cacerts.pem'
service = self.create_mock_service('query')
endpoint = get_endpoint(service, 'us-west-2',
'https://service.region.amazonaws.com',
verify='/path/cacerts.pem')
# /path/cacerts.pem wins over the value from the env var.
self.assertEqual(endpoint.verify, '/path/cacerts.pem')


class TestEndpointBase(unittest.TestCase):

Expand Down

0 comments on commit 4142e03

Please sign in to comment.