TLS integration for latest pythonk8sclient

swagger_client uses PoolManager from urllib3. PoolManager keeps the
connection_pool_kw passed during the init time and uses the same later
while initiating HTTPSConnection. Existing implementation instantiates
RESTClientObject() at import time, without giving an option to pass
the security parameters, viz. key_file, ca_certs etc. So we needed to
change the way instantiation/initialization was happening.

Change-Id: I3b490bbb47eb5f961951708dabe6c1abfbcece4e
Partially-Implements: bp tls-pythonk8sclient
Closes-bug: #1499560
This commit is contained in:
Surojit Pathak
2015-09-24 23:22:29 +00:00
parent 669d2c81cc
commit 6cf871f44f
2 changed files with 58 additions and 56 deletions

View File

@@ -65,7 +65,8 @@ class ApiClient(object):
:param header_value: a header value to pass when making calls to the API. :param header_value: a header value to pass when making calls to the API.
""" """
def __init__(self, host=Configuration().host, def __init__(self, host=Configuration().host,
header_name=None, header_value=None, cookie=None): header_name=None, header_value=None, cookie=None,
key_file=None, cert_file=None, ca_certs=None):
""" """
Constructor of the class. Constructor of the class.
@@ -77,6 +78,9 @@ class ApiClient(object):
self.cookie = cookie self.cookie = cookie
# Set default User-Agent. # Set default User-Agent.
self.user_agent = 'Python-Swagger' self.user_agent = 'Python-Swagger'
self.RESTClient = RESTClient(key_file=key_file,
cert_file=cert_file,
ca_certs=ca_certs)
@property @property
def user_agent(self): def user_agent(self):
@@ -328,38 +332,38 @@ class ApiClient(object):
def request(self, method, url, query_params=None, headers=None, def request(self, method, url, query_params=None, headers=None,
post_params=None, body=None): post_params=None, body=None):
""" """
Makes the HTTP request using RESTClient. Makes the HTTP request using instance of rest client.
""" """
if method == "GET": if method == "GET":
return RESTClient.GET(url, return self.RESTClient.GET(url,
query_params=query_params, query_params=query_params,
headers=headers) headers=headers)
elif method == "HEAD": elif method == "HEAD":
return RESTClient.HEAD(url, return self.RESTClient.HEAD(url,
query_params=query_params, query_params=query_params,
headers=headers) headers=headers)
elif method == "POST": elif method == "POST":
return RESTClient.POST(url, return self.RESTClient.POST(url,
query_params=query_params, query_params=query_params,
headers=headers, headers=headers,
post_params=post_params, post_params=post_params,
body=body) body=body)
elif method == "PUT": elif method == "PUT":
return RESTClient.PUT(url, return self.RESTClient.PUT(url,
query_params=query_params, query_params=query_params,
headers=headers, headers=headers,
post_params=post_params, post_params=post_params,
body=body) body=body)
elif method == "PATCH": elif method == "PATCH":
return RESTClient.PATCH(url, return self.RESTClient.PATCH(url,
query_params=query_params, query_params=query_params,
headers=headers, headers=headers,
post_params=post_params, post_params=post_params,
body=body) body=body)
elif method == "DELETE": elif method == "DELETE":
return RESTClient.DELETE(url, return self.RESTClient.DELETE(url,
query_params=query_params, query_params=query_params,
headers=headers) headers=headers)
else: else:
raise ValueError( raise ValueError(
"http method must be `GET`, `HEAD`," "http method must be `GET`, `HEAD`,"

View File

@@ -67,20 +67,22 @@ class RESTResponse(io.IOBase):
class RESTClientObject(object): class RESTClientObject(object):
def __init__(self, pools_size=4): def __init__(self, pools_size=4,
key_file=None, cert_file=None, ca_certs=None):
# http pool manager # http pool manager
self.pool_manager = urllib3.PoolManager( self.pool_manager = urllib3.PoolManager(
num_pools=pools_size num_pools=pools_size
) )
# https pool manager # Note(suro-patz): Changing the behavior to accept security param
# certificates validated using Mozillas root certificates if ca_certs is None:
# TODO(hongbin): fix the hard-coded ca_certs path ca_certs = '/etc/ssl/certs/ca-certificates.crt'
self.ssl_pool_manager = urllib3.PoolManager( self.ssl_pool_manager = urllib3.PoolManager(
num_pools=pools_size, num_pools=pools_size,
key_file=key_file,
cert_file=cert_file,
cert_reqs=ssl.CERT_REQUIRED, cert_reqs=ssl.CERT_REQUIRED,
ca_certs='/etc/ssl/certs/ca-certificates.crt' ca_certs=ca_certs)
)
def agent(self, url): def agent(self, url):
""" """
@@ -229,56 +231,52 @@ class ApiException(Exception):
class RESTClient(object): class RESTClient(object):
""" """
A class with all class methods to perform JSON requests. A class with methods to perform JSON requests.
""" """
IMPL = RESTClientObject() def __init__(self, key_file=None, cert_file=None, ca_certs=None):
self.IMPL = RESTClientObject(key_file=key_file,
cert_file=cert_file,
ca_certs=ca_certs)
@classmethod def request(self, *n, **kw):
def request(cls, *n, **kw):
""" """
Perform a REST request and parse the response. Perform a REST request and parse the response.
""" """
return cls.IMPL.request(*n, **kw) return self.IMPL.request(*n, **kw)
@classmethod def GET(self, *n, **kw):
def GET(cls, *n, **kw):
""" """
Perform a GET request using `RESTClient.request()`. Perform a GET request using `RESTClient.request()`.
""" """
return cls.IMPL.GET(*n, **kw) return self.IMPL.GET(*n, **kw)
@classmethod def HEAD(self, *n, **kw):
def HEAD(cls, *n, **kw):
""" """
Perform a HEAD request using `RESTClient.request()`. Perform a HEAD request using `RESTClient.request()`.
""" """
return cls.IMPL.GET(*n, **kw) return self.IMPL.GET(*n, **kw)
@classmethod def POST(self, *n, **kw):
def POST(cls, *n, **kw):
""" """
Perform a POST request using `RESTClient.request()` Perform a POST request using `RESTClient.request()`
""" """
return cls.IMPL.POST(*n, **kw) return self.IMPL.POST(*n, **kw)
@classmethod def PUT(self, *n, **kw):
def PUT(cls, *n, **kw):
""" """
Perform a PUT request using `RESTClient.request()` Perform a PUT request using `RESTClient.request()`
""" """
return cls.IMPL.PUT(*n, **kw) return self.IMPL.PUT(*n, **kw)
@classmethod def PATCH(self, *n, **kw):
def PATCH(cls, *n, **kw):
""" """
Perform a PATCH request using `RESTClient.request()` Perform a PATCH request using `RESTClient.request()`
""" """
return cls.IMPL.PATCH(*n, **kw) return self.IMPL.PATCH(*n, **kw)
@classmethod def DELETE(self, *n, **kw):
def DELETE(cls, *n, **kw):
""" """
Perform a DELETE request using `RESTClient.request()` Perform a DELETE request using `RESTClient.request()`
""" """
return cls.IMPL.DELETE(*n, **kw) return self.IMPL.DELETE(*n, **kw)