Skip to content

Conversation

@arikalon1
Copy link
Contributor

Summary

Adds support for the tls-server-name field from kubeconfig, fixing SSL certificate verification failures when connecting to Kubernetes clusters through Teleport proxy.

Problem

When using Teleport to access Kubernetes clusters, the kubeconfig contains a tls-server-name field that specifies the SNI (Server Name Indication) to use during TLS negotiation. Without this, the SSL certificate verification fails because the CA is valid for the SNI hostname, not the server URL hostname.

Error users see:

SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: 
unable to get local issuer certificate (_ssl.c:1006)'))

Solution

This fix follows the exact same pattern already used for proxy-url support:

  1. Load tls-server-name from cluster config in _load_cluster_info()
  2. Pass it to the client configuration in _set_config()
  3. Add tls_server_name parameter to the Configuration class

Testing

Users with Teleport-proxied Kubernetes clusters can test by:

  1. Ensuring their kubeconfig has tls-server-name set (Teleport generates this automatically)
  2. Running krr simple -p <prometheus-url>
  3. Verifying Kubernetes API calls succeed without SSL errors

Fixes #495

This patch adds support for the `tls-server-name` field from kubeconfig,
which is required when connecting to Kubernetes clusters through
Teleport proxy or similar services that use TLS SNI for routing.

The fix follows the same pattern already used for `proxy-url` support,
loading the tls-server-name from cluster config and passing it to the
kubernetes client configuration.

Fixes #495
@coderabbitai
Copy link

coderabbitai bot commented Jan 14, 2026

Walkthrough

Adds support for the tls_server_name Kubernetes configuration field to enable proper TLS Server Name Indication (SNI) handling. The parameter is read from the cluster config, stored in the Configuration class, and propagated to the client configuration.

Changes

Cohort / File(s) Summary
TLS Server Name Configuration Support
robusta_krr/core/integrations/kubernetes/config_patch.py
Added tls_server_name parameter handling in Configuration class __init__ method and extended config loading/setting logic to read tls-server-name from cluster config and propagate it to the Kubernetes client configuration alongside proxy settings.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: Add tls-server-name support for Teleport proxy' accurately and clearly describes the main change in the pull request.
Description check ✅ Passed The pull request description is well-detailed and directly related to the changeset, explaining the problem, solution, and testing approach for the tls-server-name support.
Linked Issues check ✅ Passed The pull request implementation fully addresses the objectives from issue #495 by adding tls-server-name support following the proxy-url pattern to enable Teleport proxy connectivity.
Out of Scope Changes check ✅ Passed All changes are focused on adding tls-server-name support as required by issue #495; no out-of-scope modifications were introduced.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/issue-495-tls-server-name-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@robusta_krr/core/integrations/kubernetes/config_patch.py`:
- Around line 32-42: The patch adds a tls_server_name attribute to the
Configuration class (Configuration.__init__, proxy and tls_server_name) but
kubernetes-client v26.1.0 does not honor that field; either update the
kubernetes-client dependency to 28.1.0+ so the library will use tls_server_name
for TLS/SNI, or remove reliance on that attribute and implement a compatible
workaround (for example configure SNI via the HTTP client adapter or SSLContext
used by the client) in the Configuration wrapper so the behavior works on
v26.1.0; update packaging/requirements to pin >=28.1.0 if choosing the upgrade
path or implement and document the alternative adapter/SSLContext approach if
staying on older clients.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3acc116 and a3e91a4.

📒 Files selected for processing (1)
  • robusta_krr/core/integrations/kubernetes/config_patch.py
🔇 Additional comments (2)
robusta_krr/core/integrations/kubernetes/config_patch.py (2)

19-22: LGTM!

Clean implementation that follows the existing pattern for proxy-url. The comment with the issue reference provides good context for future maintainers.


27-29: LGTM!

Good refactoring to DRY up the attribute propagation. Using self.__dict__ correctly ensures only explicitly-set attributes are propagated.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines 32 to +42
class Configuration(configuration.Configuration):
def __init__(
self,
proxy: Optional[str] = None,
tls_server_name: Optional[str] = None,
**kwargs,
):
super().__init__(**kwargs)

self.proxy = proxy
self.tls_server_name = tls_server_name
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if kubernetes-client 26.1.0's ApiClient or REST layer uses tls_server_name

# First, find where tls_server_name might be used in the kubernetes client
pip install kubernetes==26.1.0 -q 2>&1 | grep -v "already satisfied"
python3 -c "
import inspect
from kubernetes.client import ApiClient, Configuration

# Check if Configuration has tls_server_name property/attribute defined
print('=== Configuration class attributes ===')
config = Configuration()
print('Has tls_server_name attr:', hasattr(config, 'tls_server_name'))

# Check ApiClient's rest_client setup for tls_server_name usage
print('\n=== Searching for tls_server_name in ApiClient ===')
source = inspect.getsource(ApiClient)
if 'tls_server_name' in source:
    print('Found tls_server_name in ApiClient')
else:
    print('tls_server_name NOT found in ApiClient')

# Check the REST client
from kubernetes.client import rest
print('\n=== Searching for tls_server_name in REST client ===')
source = inspect.getsource(rest)
if 'tls_server_name' in source:
    print('Found tls_server_name in REST client')
else:
    print('tls_server_name NOT found in REST client')

# Try to check urllib3 pool manager configuration
print('\n=== Checking REST client SSL context setup ===')
import re
# Look for ssl_context or ca_certs setup in rest module
if 'ssl_context' in source:
    print('Found ssl_context references in REST client')
    # Find the lines that mention ssl_context
    for i, line in enumerate(source.split('\n')):
        if 'ssl_context' in line and 'tls_server_name' in source[max(0, source.find(line)-500):source.find(line)+500]:
            print(f'  Line {i}: {line.strip()}')
"

Repository: robusta-dev/krr

Length of output: 868


🏁 Script executed:

pip install kubernetes==28.0.0 -q 2>&1 | grep -v "already satisfied" || true
python3 -c "
from kubernetes.client import Configuration
import inspect

# Check if v28.0.0 has tls_server_name
config = Configuration()
print('v28.0.0 Configuration has tls_server_name:', hasattr(config, 'tls_server_name'))

# Also check the REST client in v28
from kubernetes.client import rest
source = inspect.getsource(rest)
print('v28.0.0 REST client uses tls_server_name:', 'tls_server_name' in source)
"

Repository: robusta-dev/krr

Length of output: 1293


🏁 Script executed:

#!/bin/bash
# Check latest kubernetes versions
pip install 'kubernetes==28.1.0' -q 2>&1 | grep -v "WARNING" | grep -v "already satisfied"
python3 << 'EOF'
from kubernetes.client import Configuration
config = Configuration()
print('kubernetes 28.1.0 Configuration has tls_server_name:', hasattr(config, 'tls_server_name'))
EOF

# Also check the actual latest stable version
pip install 'kubernetes>=30,<31' -q 2>&1 | grep -v "WARNING" | tail -1
python3 << 'EOF'
from kubernetes.client import Configuration
config = Configuration()
print('kubernetes 30.x Configuration has tls_server_name:', hasattr(config, 'tls_server_name'))
EOF

# Try to find release notes or check source
python3 << 'EOF'
import subprocess
result = subprocess.run(['pip', 'show', 'kubernetes'], capture_output=True, text=True)
print(result.stdout)
EOF

Repository: robusta-dev/krr

Length of output: 833


🏁 Script executed:

python3 << 'EOF'
pip_output = """Requires: certifi, google-auth, oauthlib, python-dateutil, pyyaml, requests, requests-oauthlib, six, urllib3, websocket-client"""

# The key finding: 26.1.0 doesn't have tls_server_name, but 28.1.0 does
# Let's verify 27.2.0 (between the two) to narrow down where it was added
import subprocess
subprocess.run(['pip', 'install', '-q', 'kubernetes==27.2.0'], capture_output=True)

from kubernetes.client import Configuration
config = Configuration()
print('kubernetes 27.2.0 Configuration has tls_server_name:', hasattr(config, 'tls_server_name'))
EOF

Repository: robusta-dev/krr

Length of output: 117


This patch will not work with kubernetes-client 26.1.0—upgrade to 28.1.0+ required.

The tls_server_name attribute is not supported in kubernetes-client v26.1.0. While the code correctly stores the attribute on the Configuration object, the kubernetes-client library won't read or use it for TLS/SNI configuration. Support for tls_server_name was introduced in kubernetes-client 28.1.0+. Either upgrade the kubernetes-client dependency to 28.1.0 or later, or implement a different approach compatible with v26.1.0.

🤖 Prompt for AI Agents
In `@robusta_krr/core/integrations/kubernetes/config_patch.py` around lines 32 -
42, The patch adds a tls_server_name attribute to the Configuration class
(Configuration.__init__, proxy and tls_server_name) but kubernetes-client
v26.1.0 does not honor that field; either update the kubernetes-client
dependency to 28.1.0+ so the library will use tls_server_name for TLS/SNI, or
remove reliance on that attribute and implement a compatible workaround (for
example configure SNI via the HTTP client adapter or SSLContext used by the
client) in the Configuration wrapper so the behavior works on v26.1.0; update
packaging/requirements to pin >=28.1.0 if choosing the upgrade path or implement
and document the alternative adapter/SSLContext approach if staying on older
clients.

@arikalon1 arikalon1 closed this Jan 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SSL certificate verification fails when using Teleport Kubernetes proxy

2 participants