Skip to content

Commit a12df3e

Browse files
authored
Merge pull request #1933 from tigrato/support-tls-server-name
Adds support for custom Server Name Indication (SNI)
2 parents a6f58bd + 68fe8ee commit a12df3e

File tree

7 files changed

+83
-5
lines changed

7 files changed

+83
-5
lines changed

kubernetes/base/config/kube_config.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,8 @@ def _load_cluster_info(self):
567567
temp_file_path=self._temp_file_path).as_file()
568568
if 'insecure-skip-tls-verify' in self._cluster:
569569
self.verify_ssl = not self._cluster['insecure-skip-tls-verify']
570+
if 'tls-server-name' in self._cluster:
571+
self.tls_server_name = self._cluster['tls-server-name']
570572

571573
def _set_config(self, client_configuration):
572574
if 'token' in self.__dict__:
@@ -578,7 +580,7 @@ def _refresh_api_key(client_configuration):
578580
self._set_config(client_configuration)
579581
client_configuration.refresh_api_key_hook = _refresh_api_key
580582
# copy these keys directly from self to configuration object
581-
keys = ['host', 'ssl_ca_cert', 'cert_file', 'key_file', 'verify_ssl']
583+
keys = ['host', 'ssl_ca_cert', 'cert_file', 'key_file', 'verify_ssl','tls_server_name']
582584
for key in keys:
583585
if key in self.__dict__:
584586
setattr(client_configuration, key, getattr(self, key))

kubernetes/base/config/kube_config_test.py

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def _raise_exception(st):
102102
TEST_CLIENT_KEY_BASE64 = _base64(TEST_CLIENT_KEY)
103103
TEST_CLIENT_CERT = "client-cert"
104104
TEST_CLIENT_CERT_BASE64 = _base64(TEST_CLIENT_CERT)
105-
105+
TEST_TLS_SERVER_NAME = "kubernetes.io"
106106

107107
TEST_OIDC_TOKEN = "test-oidc-token"
108108
TEST_OIDC_INFO = "{\"name\": \"test\"}"
@@ -592,7 +592,14 @@ class TestKubeConfigLoader(BaseTestCase):
592592
"cluster": "clustertestcmdpath",
593593
"user": "usertestcmdpathscope"
594594
}
595-
}
595+
},
596+
{
597+
"name": "tls-server-name",
598+
"context": {
599+
"cluster": "tls-server-name",
600+
"user": "ssl"
601+
}
602+
},
596603
],
597604
"clusters": [
598605
{
@@ -634,7 +641,17 @@ class TestKubeConfigLoader(BaseTestCase):
634641
{
635642
"name": "clustertestcmdpath",
636643
"cluster": {}
637-
}
644+
},
645+
{
646+
"name": "tls-server-name",
647+
"cluster": {
648+
"server": TEST_SSL_HOST,
649+
"certificate-authority-data":
650+
TEST_CERTIFICATE_AUTH_BASE64,
651+
"insecure-skip-tls-verify": False,
652+
"tls-server-name": TEST_TLS_SERVER_NAME,
653+
}
654+
},
638655
],
639656
"users": [
640657
{
@@ -1251,6 +1268,22 @@ def test_ssl_no_verification(self):
12511268
active_context="no_ssl_verification").load_and_set(actual)
12521269
self.assertEqual(expected, actual)
12531270

1271+
def test_tls_server_name(self):
1272+
expected = FakeConfig(
1273+
host=TEST_SSL_HOST,
1274+
token=BEARER_TOKEN_FORMAT % TEST_DATA_BASE64,
1275+
cert_file=self._create_temp_file(TEST_CLIENT_CERT),
1276+
key_file=self._create_temp_file(TEST_CLIENT_KEY),
1277+
ssl_ca_cert=self._create_temp_file(TEST_CERTIFICATE_AUTH),
1278+
verify_ssl=True,
1279+
tls_server_name=TEST_TLS_SERVER_NAME
1280+
)
1281+
actual = FakeConfig()
1282+
KubeConfigLoader(
1283+
config_dict=self.TEST_KUBE_CONFIG,
1284+
active_context="tls-server-name").load_and_set(actual)
1285+
self.assertEqual(expected, actual)
1286+
12541287
def test_list_contexts(self):
12551288
loader = KubeConfigLoader(
12561289
config_dict=self.TEST_KUBE_CONFIG,

kubernetes/base/stream/ws_client.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,8 @@ def create_websocket(configuration, url, headers=None):
475475
ssl_opts['certfile'] = configuration.cert_file
476476
if configuration.key_file:
477477
ssl_opts['keyfile'] = configuration.key_file
478+
if configuration.tls_server_name:
479+
ssl_opts['server_hostname'] = configuration.tls_server_name
478480

479481
websocket = WebSocket(sslopt=ssl_opts, skip_utf8_validation=False)
480482
connect_opt = {

kubernetes/client/configuration.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ def __init__(self, host="http://localhost",
144144
self.assert_hostname = None
145145
"""Set this to True/False to enable/disable SSL hostname verification.
146146
"""
147+
self.tls_server_name = None
148+
"""SSL/TLS Server Name Indication (SNI)
149+
Set this to the SNI value expected by Kubernetes API.
150+
"""
147151

148152
self.connection_pool_maxsize = multiprocessing.cpu_count() * 5
149153
"""urllib3 connection pool's maximum number of connections saved

kubernetes/client/rest.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ def __init__(self, configuration, pools_size=4, maxsize=None):
7777
if configuration.retries is not None:
7878
addition_pool_args['retries'] = configuration.retries
7979

80+
if configuration.tls_server_name:
81+
addition_pool_args['server_hostname'] = configuration.tls_server_name
82+
8083
if maxsize is None:
8184
if configuration.connection_pool_maxsize is not None:
8285
maxsize = configuration.connection_pool_maxsize

scripts/rest_sni_patch.diff

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
diff --git a/kubernetes/client/configuration.py b/kubernetes/client/configuration.py
2+
index 2b9dd96a50..ac5a18bf8a 100644
3+
--- a/kubernetes/client/configuration.py
4+
+++ b/kubernetes/client/configuration.py
5+
@@ -144,6 +144,10 @@ def __init__(self, host="http://localhost",
6+
self.assert_hostname = None
7+
"""Set this to True/False to enable/disable SSL hostname verification.
8+
"""
9+
+ self.tls_server_name = None
10+
+ """SSL/TLS Server Name Indication (SNI)
11+
+ Set this to the SNI value expected by the server.
12+
+ """
13+
14+
self.connection_pool_maxsize = multiprocessing.cpu_count() * 5
15+
"""urllib3 connection pool's maximum number of connections saved
16+
diff --git a/kubernetes/client/rest.py b/kubernetes/client/rest.py
17+
index 48cd2b7752..4f04251bbf 100644
18+
--- a/kubernetes/client/rest.py
19+
+++ b/kubernetes/client/rest.py
20+
@@ -77,6 +77,9 @@ def __init__(self, configuration, pools_size=4, maxsize=None):
21+
if configuration.retries is not None:
22+
addition_pool_args['retries'] = configuration.retries
23+
24+
+ if configuration.tls_server_name:
25+
+ addition_pool_args['server_hostname'] = configuration.tls_server_name
26+
+
27+
if maxsize is None:
28+
if configuration.connection_pool_maxsize is not None:
29+
maxsize = configuration.connection_pool_maxsize

scripts/update-client.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ else
5959
fi
6060

6161
echo ">>> Running python generator from the gen repo"
62-
"${GEN_ROOT}/openapi/python.sh" "${CLIENT_ROOT}" "${SETTING_FILE}"
62+
"${GEN_ROOT}/openapi/python.sh" "${CLIENT_ROOT}" "${SETTING_FILE}"
6363
mv "${CLIENT_ROOT}/swagger.json" "${SCRIPT_ROOT}/swagger.json"
6464

6565
echo ">>> updating version information..."
@@ -73,6 +73,11 @@ sed -i'' "s,^DEVELOPMENT_STATUS = .*,DEVELOPMENT_STATUS = \\\"${DEVELOPMENT_STAT
7373
# second, this should be ported to swagger-codegen
7474
echo ">>> patching client..."
7575
git apply "${SCRIPT_ROOT}/rest_client_patch.diff"
76+
# The fix this patch is trying to make is already in the upstream swagger-codegen
77+
# repo but it's not in the version we're using. We can remove this patch
78+
# once we upgrade to a version of swagger-codegen that includes it (version>= 6.6.0).
79+
# See https://github.com/OpenAPITools/openapi-generator/pull/15283
80+
git apply "${SCRIPT_ROOT}/rest_sni_patch.diff"
7681

7782
echo ">>> generating docs..."
7883
pushd "${DOC_ROOT}" > /dev/null

0 commit comments

Comments
 (0)