mirror of https://github.com/docker/docker-py.git
* Merge branch 'tls' of github.com:momer/docker-py into momer-tls
* Exported TLS configuration in tls.TLSConfig * Merged exceptions packagee into pre-existing errors module * Flake8 fixes * Bug fixes
This commit is contained in:
commit
116d1370af
|
@ -24,8 +24,10 @@ import six
|
|||
|
||||
from .auth import auth
|
||||
from .unixconn import unixconn
|
||||
from .ssladapter import ssladapter
|
||||
from .utils import utils
|
||||
from . import errors
|
||||
from .tls import TLSConfig
|
||||
|
||||
if not six.PY3:
|
||||
import websocket
|
||||
|
@ -37,10 +39,15 @@ STREAM_HEADER_SIZE_BYTES = 8
|
|||
|
||||
class Client(requests.Session):
|
||||
def __init__(self, base_url=None, version=DEFAULT_DOCKER_API_VERSION,
|
||||
timeout=DEFAULT_TIMEOUT_SECONDS):
|
||||
timeout=DEFAULT_TIMEOUT_SECONDS, tls=False):
|
||||
super(Client, self).__init__()
|
||||
|
||||
if base_url is None:
|
||||
base_url = "http+unix://var/run/docker.sock"
|
||||
if tls and not base_url.startswith('https://'):
|
||||
raise errors.TLSParameterError(
|
||||
'If using TLS, the base_url argument must begin with '
|
||||
'"https://".')
|
||||
if 'unix:///' in base_url:
|
||||
base_url = base_url.replace('unix:/', 'unix:')
|
||||
if base_url.startswith('unix:'):
|
||||
|
@ -54,7 +61,13 @@ class Client(requests.Session):
|
|||
self._timeout = timeout
|
||||
self._auth_configs = auth.load_config()
|
||||
|
||||
self.mount('http+unix://', unixconn.UnixAdapter(base_url, timeout))
|
||||
""" Use SSLAdapter for the ability to specify SSL version """
|
||||
if isinstance(tls, TLSConfig):
|
||||
tls.configure_client(self)
|
||||
elif tls:
|
||||
self.mount('https://', ssladapter.SSLAdapter(self.ssl_version))
|
||||
else:
|
||||
self.mount('http+unix://', unixconn.UnixAdapter(base_url, timeout))
|
||||
|
||||
def _set_request_timeout(self, kwargs):
|
||||
"""Prepare the kwargs for an HTTP request by inserting the timeout
|
||||
|
|
|
@ -63,3 +63,14 @@ class InvalidConfigFile(DockerException):
|
|||
|
||||
class DeprecatedMethod(DockerException):
|
||||
pass
|
||||
|
||||
|
||||
class TLSParameterError(DockerException):
|
||||
def __init__(self, msg):
|
||||
self.msg = msg
|
||||
|
||||
def __str__(self):
|
||||
return self.msg + (". TLS configurations should map the Docker CLI "
|
||||
"client configurations. See "
|
||||
"http://docs.docker.com/examples/https/ for "
|
||||
"API details.")
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
from .ssladapter import SSLAdapter # flake8: noqa
|
|
@ -0,0 +1,22 @@
|
|||
""" Resolves OpenSSL issues in some servers:
|
||||
https://lukasa.co.uk/2013/01/Choosing_SSL_Version_In_Requests/
|
||||
https://github.com/kennethreitz/requests/pull/799
|
||||
"""
|
||||
from requests.adapters import HTTPAdapter
|
||||
try:
|
||||
from requests.packages.urllib3.poolmanager import PoolManager
|
||||
except ImportError:
|
||||
from urllib3.poolmanager import PoolManager
|
||||
|
||||
|
||||
class SSLAdapter(HTTPAdapter):
|
||||
'''An HTTPS Transport Adapter that uses an arbitrary SSL version.'''
|
||||
def __init__(self, ssl_version=None, **kwargs):
|
||||
self.ssl_version = ssl_version
|
||||
super(SSLAdapter, self).__init__(**kwargs)
|
||||
|
||||
def init_poolmanager(self, connections, maxsize, block=False):
|
||||
self.poolmanager = PoolManager(num_pools=connections,
|
||||
maxsize=maxsize,
|
||||
block=block,
|
||||
ssl_version=self.ssl_version)
|
|
@ -0,0 +1,51 @@
|
|||
import os
|
||||
|
||||
from . import errors
|
||||
from .ssladapter import ssladapter
|
||||
|
||||
|
||||
class TLSConfig(object):
|
||||
def __init__(self, tls, tls_cert=None, tls_key=None, tls_verify=False,
|
||||
tls_ca_cert=None, ssl_version=None):
|
||||
# Argument compatibility/mapping with
|
||||
# http://docs.docker.com/examples/https/
|
||||
# This diverges from the Docker CLI in that users can specify 'tls'
|
||||
# here, but also disable any public/default CA pool verification by
|
||||
# leaving tls_verify=False
|
||||
|
||||
# urllib3 sets a default ssl_version if ssl_version is None
|
||||
# http://tinyurl.com/kxga8hb
|
||||
self.ssl_version = ssl_version
|
||||
|
||||
# "tls" and "tls_verify" must have both or neither cert/key files
|
||||
# In either case, Alert the user when both are expected, but any are
|
||||
# missing.
|
||||
|
||||
if tls_cert or tls_key:
|
||||
if not (tls_cert and tls_key) or (not os.path.isfile(tls_cert) or
|
||||
not os.path.isfile(tls_key)):
|
||||
raise errors.TLSParameterError(
|
||||
'You must provide either both "tls_cert"/"tls_key" files, '
|
||||
'or neither, in order to use TLS.')
|
||||
self.cert = (tls_cert, tls_key)
|
||||
|
||||
# Either set tls_verify to True (public/default CA checks) or to the
|
||||
# path of a CA Cert file.
|
||||
if tls_verify:
|
||||
if not tls_ca_cert:
|
||||
self.verify = True
|
||||
elif os.path.isfile(tls_ca_cert):
|
||||
self.verify = tls_ca_cert
|
||||
else:
|
||||
raise errors.TLSParameterError(
|
||||
'If "tls_verify" is set, then "tls_ca_cert" must be blank'
|
||||
' (to check public CA list) OR a path to a Cert File.'
|
||||
)
|
||||
else:
|
||||
self.verify = False
|
||||
|
||||
def configure_client(self, client):
|
||||
client.verify = self.verify
|
||||
client.ssl_version = self.ssl_version
|
||||
client.cert = self.cert
|
||||
self.mount('https://', ssladapter.SSLAdapter(self.ssl_version))
|
3
setup.py
3
setup.py
|
@ -22,7 +22,8 @@ setup(
|
|||
name="docker-py",
|
||||
version=version,
|
||||
description="Python client for Docker.",
|
||||
packages=['docker', 'docker.auth', 'docker.unixconn', 'docker.utils'],
|
||||
packages=['docker', 'docker.auth', 'docker.unixconn', 'docker.utils',
|
||||
'docker.ssladapter'],
|
||||
install_requires=requirements + test_requirements,
|
||||
zip_safe=False,
|
||||
test_suite='tests',
|
||||
|
|
Loading…
Reference in New Issue