kubernetes-client / kubernetes-client/java
Unable to interact with cluster through Teleport
- Dominant language
- Java
- Stars
- 4k
- Forks
- 2.1k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 16
Description
**Describe the bug**
Using a cluster with authn via Teleport, it is not possible to interact with the cluster.
This is working fine with `kubectl` and after testing with the Python client it works too. This seems to only happen with the Java client (I didn’t test other clients though).
**Client Version**
20
**Kubernetes Version**
1.28.6
**Java Version**
17
**To Reproduce**
- configure your cluster with Teleport
- generate a kubeconfig through `tsh`
Edit the `KubeConfigFileClientExample`:
```diff
diff --git a/examples/examples-release-20/src/main/java/io/kubernetes/client/examples/KubeConfigFileClientExample.java b/examples/examples-release-20/src/main/java/io/kubernetes/client/examples/KubeConfigFileClientExample.java
index 7a0ba4dcf..99a7cc75e 100644
--- a/examples/examples-release-20/src/main/java/io/kubernetes/client/examples/KubeConfigFileClientExample.java
+++ b/examples/examples-release-20/src/main/java/io/kubernetes/client/examples/KubeConfigFileClientExample.java
@@ -16,12 +16,13 @@ import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.Configuration;
import io.kubernetes.client.openapi.apis.CoreV1Api;
-import io.kubernetes.client.openapi.models.V1Pod;
-import io.kubernetes.client.openapi.models.V1PodList;
+import io.kubernetes.client.openapi.models.V1Namespace;
+import io.kubernetes.client.openapi.models.V1ObjectMeta;
import io.kubernetes.client.util.ClientBuilder;
import io.kubernetes.client.util.KubeConfig;
import java.io.FileReader;
import java.io.IOException;
+import java.nio.file.Paths;
/**
* A simple example of how to use the Java API from an application outside a kubernetes cluster
@@ -37,10 +38,12 @@ public class KubeConfigFileClientExample {
// file path to your KubeConfig
String kubeConfigPath = System.getenv("HOME") + "/.kube/config";
+ KubeConfig kubeconfig = KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath));
+ kubeconfig.setFile(Paths.get(kubeConfigPath).toFile());
// loading the out-of-cluster config, a kubeconfig from file-system
ApiClient client =
- ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))).build();
+ ClientBuilder.kubeconfig(kubeconfig).build();
// set the global default api-client to the in-cluster one from above
Configuration.setDefaultApiClient(client);
@@ -48,11 +51,11 @@ public class KubeConfigFileClientExample {
// the CoreV1Api loads default api-client from global configuration.
CoreV1Api api = new CoreV1Api();
- // invokes the CoreV1Api client
- V1PodList list =
- api.listPodForAllNamespaces().execute();
- for (V1Pod item : list.getItems()) {
- System.out.println(item.getMetadata().getName());
- }
+ V1Namespace ns = new V1Namespace();
+ V1ObjectMeta meta = new V1ObjectMeta();
+ meta.setName("test");
+ ns.setMetadata(meta);
+ V1Namespace result = api.createNamespace(ns).pretty("true").execute();
+ System.out.println(result.getMetadata().getName());
}
}
```
Run the example:
```
cd examples/examples-release-20
mvn -X clean install exec:java -Dexec.mainClass="io.kubernetes.client.examples.KubeConfigFileClientExample"
```
**Expected behavior**
The namespace is created.
**KubeConfig**
```yaml
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: REDACTED
server: REDACTED
tls-server-name: REDACTED
name: REDACTED
contexts:
- context:
cluster: REDACTED
extensions:
- extension: sandbox
name: teleport.kube.name
user: REDACTED
name: REDACTED
current-context: REDACTED
kind: Config
preferences: {}
users:
- name: REDACTED
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- kube
- credentials
- --kube-cluster=sandbox
- --teleport-cluster=REDACTED
- --proxy=REDACTED
command: tsh
env: null
provideClusterInfo: false
```
**Server (please complete the following information):**
- OS: Linux
- Environment: system
- Cloud: Azure/Teleport
**Additional context**
My user has limited permissions, but I should be able to create a namespace:
```
$ kubectl auth can-i --list
Resources Non-Resource URLs Resource Names Verbs
selfsubjectreviews.authentication.k8s.io [] [] [create]
selfsubjectaccessreviews.authorization.k8s.io [] [] [create]
selfsubjectrulesreviews.authorization.k8s.io [] [] [create]
namespaces.* [] [] [get list watch create delete]
nodes [] [] [get list watch]
[/api/*] [] [get]
[/api] [] [get]
[/apis/*] [] [get]
[/apis] [] [get]
[/healthz] [] [get]
[/healthz] [] [get]
[/livez] [] [get]
[/livez] [] [get]
[/openapi/*] [] [get]
[/openapi] [] [get]
[/readyz] [] [get]
[/readyz] [] [get]
[/version/] [] [get]
[/version/] [] [get]
[/version] [] [get]
[/version] [] [get]
```
Contributor guide
Research direction
Start with examples/examples-release-20/src/main/java/io/kubernetes/client/examples/KubeConfigFileClientExample.java and the KubeConfig.loadKubeConfig and ClientBuilder.kubeconfig entry points. Run the provided Maven command with the tsh-generated kubeconfig, then trace how the Java client handles its exec configuration and file path. Done means the example creates and prints the test namespace through Teleport.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, authentication
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100