Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting error "src" is null when browsing tree #726

Closed
deejonz opened this issue Mar 18, 2024 · 65 comments
Closed

Getting error "src" is null when browsing tree #726

deejonz opened this issue Mar 18, 2024 · 65 comments
Assignees
Labels
kind/bug Something isn't working severity/critical
Milestone

Comments

@deejonz
Copy link

deejonz commented Mar 18, 2024

I get the following stacktrace when browsing the kubernates tree in many places, I can see the pods item well BTW:

2024-03-18 15:05:59,803 [ 255348]   WARN - #com.redhat.devtools.intellij.kubernetes.tree.TreeStructure - Cannot invoke "String.getBytes(java.nio.charset.Charset)" because "src" is null
java.lang.NullPointerException: Cannot invoke "String.getBytes(java.nio.charset.Charset)" because "src" is null
	at java.base/java.util.Base64$Decoder.decode(Base64.java:589)
	at io.fabric8.kubernetes.client.utils.OpenIDConnectionUtils.getDefaultHttpClientWithPemCert(OpenIDConnectionUtils.java:292)
	at io.fabric8.kubernetes.client.utils.OpenIDConnectionUtils.getOIDCProviderTokenEndpointAndRefreshToken(OpenIDConnectionUtils.java:330)
	at io.fabric8.kubernetes.client.utils.OpenIDConnectionUtils.resolveOIDCTokenFromAuthConfig(OpenIDConnectionUtils.java:86)
	at io.fabric8.kubernetes.client.utils.TokenRefreshInterceptor.extractNewAccessTokenFrom(TokenRefreshInterceptor.java:83)
	at io.fabric8.kubernetes.client.utils.TokenRefreshInterceptor.refreshToken(TokenRefreshInterceptor.java:76)
	at io.fabric8.kubernetes.client.utils.TokenRefreshInterceptor.before(TokenRefreshInterceptor.java:58)
	at io.fabric8.kubernetes.client.http.StandardHttpClient.consumeBytes(StandardHttpClient.java:65)
	at io.fabric8.kubernetes.client.http.SendAsyncUtils.bytes(SendAsyncUtils.java:51)
	at io.fabric8.kubernetes.client.http.HttpResponse$SupportedResponses.sendAsync(HttpResponse.java:105)
	at io.fabric8.kubernetes.client.http.StandardHttpClient.sendAsync(StandardHttpClient.java:52)
	at io.fabric8.kubernetes.client.dsl.internal.OperationSupport.retryWithExponentialBackoff(OperationSupport.java:604)
	at io.fabric8.kubernetes.client.dsl.internal.OperationSupport.handleResponse(OperationSupport.java:581)
	at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.submitList(BaseOperation.java:414)
	at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.list(BaseOperation.java:427)
	at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.list(BaseOperation.java:392)
	at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.list(BaseOperation.java:93)
	at com.redhat.devtools.intellij.kubernetes.model.resource.NamespacedResourceOperator.loadAllResources(NamespacedResourceOperator.kt:68)
	at com.redhat.devtools.intellij.kubernetes.model.resource.NamespacedResourceOperator.getAllResources(NamespacedResourceOperator.kt:54)
	at com.redhat.devtools.intellij.kubernetes.model.resource.NamespacedResourceOperator.getAllResources(NamespacedResourceOperator.kt:36)
	at com.redhat.devtools.intellij.kubernetes.model.context.ActiveContext.getAllResources(ActiveContext.kt:148)
	at com.redhat.devtools.intellij.kubernetes.model.ResourceModel.getAllResources(ResourceModel.kt:122)
	at com.redhat.devtools.intellij.kubernetes.model.ListableResources.list(ResourceModelQuery.kt:39)
	at com.redhat.devtools.intellij.kubernetes.tree.KubernetesStructure$createWorkloadElements$3$3.invoke(KubernetesStructure.kt:193)
	at com.redhat.devtools.intellij.kubernetes.tree.KubernetesStructure$createWorkloadElements$3$3.invoke(KubernetesStructure.kt:189)
	at com.redhat.devtools.intellij.kubernetes.tree.AbstractTreeStructureContribution$ElementNode.getChildElements(AbstractTreeStructureContribution.kt:97)
	at com.redhat.devtools.intellij.kubernetes.tree.AbstractTreeStructureContribution.getChildElements(AbstractTreeStructureContribution.kt:28)
	at com.redhat.devtools.intellij.kubernetes.tree.TreeStructure.getChildElements(TreeStructure.kt:71)
	at com.redhat.devtools.intellij.kubernetes.tree.TreeStructure.getChildElements(TreeStructure.kt:64)
	at com.intellij.ui.tree.StructureTreeModel.getValidChildren(StructureTreeModel.java:411)
	at com.intellij.ui.tree.StructureTreeModel.validateChildren(StructureTreeModel.java:329)
	at com.intellij.ui.tree.StructureTreeModel.getNode(StructureTreeModel.java:323)
	at com.intellij.ui.tree.StructureTreeModel.getChildren(StructureTreeModel.java:343)
	at com.intellij.ui.tree.AsyncTreeModel$CmdGetChildren.computeNode(AsyncTreeModel.java:613)
	at com.intellij.ui.tree.AsyncTreeModel$Command.computeNode(AsyncTreeModel.java:489)
	at com.intellij.util.concurrency.Invoker$Task.run(Invoker.java:381)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$1(CoreProgressManager.java:192)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeProcessUnderProgress$12(CoreProgressManager.java:610)
	at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:685)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:641)
	at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:609)
	at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:78)
	at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:179)
	at com.intellij.util.concurrency.Invoker.startTask(Invoker.java:236)
	at com.intellij.util.concurrency.Invoker.invokeSafely(Invoker.java:194)
	at com.intellij.util.concurrency.Invoker.lambda$offerSafely$0(Invoker.java:177)
	at com.intellij.util.concurrency.Invoker$Background.lambda$offer$0(Invoker.java:508)
	at com.intellij.util.concurrency.BoundedTaskExecutor.doRun(BoundedTaskExecutor.java:244)
	at com.intellij.util.concurrency.BoundedTaskExecutor.access$200(BoundedTaskExecutor.java:30)
	at com.intellij.util.concurrency.BoundedTaskExecutor$1.executeFirstTaskAndHelpQueue(BoundedTaskExecutor.java:222)
	at com.intellij.util.ConcurrencyUtil.runUnderThreadName(ConcurrencyUtil.java:218)
	at com.intellij.util.concurrency.BoundedTaskExecutor$1.run(BoundedTaskExecutor.java:210)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:702)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:699)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:699)
	at java.base/java.lang.Thread.run(Thread.java:840)
2024-03-18 15:06:17,456 [ 273001]   INFO - #c.i.w.i.i.j.s.JpsGlobalModelSynchronizerImpl - Saving global entities to files
image
@adietish
Copy link
Collaborator

copied over from #717 (comment)

I tried three times and I can reproduce everytime. It seems that error is not coming with a specific element, but only after opening a certain amount of items.

@adietish
Copy link
Collaborator

copied over from #717 (comment)

this last time 47 clicks, including opening items (like expanding pods one by one), I tried another time and it was 48.. very similar.

@adietish
Copy link
Collaborator

@deejonz: would it be possible for you to provide a redacted version of your configs in kube config so that we can try to reproduce this? It looks as if there's a problem with the OIDC authentication. The bug occurrs when the client library tries to refresh the token. We'd love to try to replicate this 😃

@deejonz
Copy link
Author

deejonz commented Mar 19, 2024

@adietish sure, this is my config file, I hope this is what you were looking for:

---
apiVersion: "v1"
kind: "Config"
clusters:
- cluster:
    certificate-authority: "certs/xxxxx-id/k8s-ca.crt"
    server: "https://api.a-central-1.aws.xxxx.com"
  name: "xxxxx-id"
contexts:
- context:
    cluster: "xxxxx-id"
    namespace: "id-stag"
    user: "stefano-xxxxx-id"
  name: "xxxxx-id"

current-context: "xxxxx-id"
preferences: {}
users:
- name: "stefano-xxxxx-id"
  user:
    auth-provider:
      config:
        client-id: "de-k8s-authenticator"
        client-secret: "pUBnBOY8[...]ijwadxreNGQok"
        id-token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IjRjZmRiYjcx[...]eiuhedeaZmQifQ.eyJpc3MiOiJodHRwczovL2RleC5pZC5hd3MuY3[...]6IkNpUXhZV1l5TlRnd05TMWtZ[...]aGVudGljYXRvciIsImV4cCI6MTcxMDgxMzc3NSwiaWF0IjoxNzEwNzcwNTc1LCJhdF9oYXNoIjoiVHAwenM1RFBNRjI2WnNpOEI1cmdyUSIsImVtYWlsIjoic3RlZmFuby5icnVzYUB2b"
        idp-issuer-url: "https://de.id.aws.xxxxx.com"
        refresh-token: "Chl4eG0zZmhzd2aeiuhE[...]kaHRhN3h6bXlqZmtoYXdrY2Zt"
      name: "oidc"

@adietish
Copy link
Collaborator

@deejonz thanks for that snippet. According to @rohanKanojia this is related to your local certificates. Here's his question to you:

KubernetesClient seems to expect cluster certificate info either in idp-certificate-authority-data field in auth-provider config or cluster caCertData in OpenIDConnectionUtils. Probably in user's case both of them are null. How are certificates configured for the cluster?

@deejonz
Copy link
Author

deejonz commented Mar 19, 2024

sorry but I don't know how this is configured in the organization.

@adietish
Copy link
Collaborator

@deejonz I think that @rohanKanojia is talking about the certificates that you have locally. I think that he's guessing from the stacktrace that the certificates is null and he is thus wondering if you can confirm/refute that the local certificates are all ok. If those weren't you should fail to talk to the cluster using kubectl once the token is out of validity and should be refreshed.

@deejonz
Copy link
Author

deejonz commented Mar 19, 2024

if I do kubectl get po -n id-stag it returns the details as expected. Even when I'm getting the error on the intellij plugin, kubectl commandline works fine.

@rohanKanojia
Copy link

@deejonz : Could you please open an issue on Fabric8 Kubernetes Client (with the ~/.kube/config and location of certificate file)

@adietish
Copy link
Collaborator

I'm doing the issue

@rohanKanojia
Copy link

@deejonz : I see that your certificate file is a relative path certs/xxxxx-id/k8s-ca.crt . Am I right? What happens if you change it to absolute path?

@adietish
Copy link
Collaborator

@adietish
Copy link
Collaborator

adietish commented Mar 19, 2024

If confirmed that fabric8io/kubernetes-client#4960 was the same problem then the fix would be as simple as upgrading our client-library 6.4.0 to >= 6.5.1, crossing fingers 😃

@adietish
Copy link
Collaborator

@deejonz I could try to make a binary build for you that you can test if you'd agree? Would take a bit longer though because of API breakages this bump may imply.

@adietish adietish moved this to 🏗 In progress in IDE Cloudaptors Mar 19, 2024
@deejonz
Copy link
Author

deejonz commented Mar 19, 2024

sure @adietish, I can test that np.

@rohanKanojia
Copy link

@deejonz : Is it possible for you to run this reproducer project on your machine?

In fabric8io/kubernetes-client#4960 we default to currentConfig.getCaCertData() if idp-certificate-authority-data is not provided. If

Could you please run mvn clean install after extracting the reproducer project to see if the certificate gets loaded into KubernetesClient config? If not, which attributes are loaded (I've added a print statement for Config in the test)
fabric8-oidc-config-certdata-reproducer.zip

@deejonz
Copy link
Author

deejonz commented Mar 19, 2024

[ERROR] io.fabric8.reproducer.ConfigReadsCertTest.configLoadsCertData  Time elapsed: 0.4 s  <<< FAILURE!
org.opentest4j.AssertionFailedError: expected: not <null>
	at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:152)
	at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
	at org.junit.jupiter.api.AssertNotNull.failNull(AssertNotNull.java:49)
	at org.junit.jupiter.api.AssertNotNull.assertNotNull(AssertNotNull.java:35)
	at org.junit.jupiter.api.AssertNotNull.assertNotNull(AssertNotNull.java:30)
	at org.junit.jupiter.api.Assertions.assertNotNull(Assertions.java:304)
	at io.fabric8.reproducer.ConfigReadsCertTest.configLoadsCertData(ConfigReadsCertTest.java:20)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at java.util.ArrayList.forEach(ArrayList.java:1259)

@deejonz
Copy link
Author

deejonz commented Mar 19, 2024

probably you needed this:

{"authProvider":{"config":{"client-id":"de-k8s-authenticator","client-secret":"pUBnBOY8[...]Y2xreNGQok","id-token":"eyJhbGciOiJSUzI1Ni[...]4cCI6MTcxMDg5OTg0MiwiaWF0IjoxNzEwODU2NjQyLCJhdF9oYXNoIjoiczZZVUxCazhGV0VxdmE4WVpTWlg2dyIsImVtYWlsI[...]Aj3NUExIYKwTsGcEZGiPLnNdyb5WUNbNgotnw","idp-issuer-url":"https://de.id.aws.xxxxx.com","refresh-token":"Chl4eG0zZ[...]pmcm5hZG8yeWZqYTN5"},"name":"oidc"},"maxConcurrentRequests":64,"maxConcurrentRequestsPerHost":5,"requestConfig":{"impersonateUsername":null,"impersonateGroups":[""],"impersonateExtras":{},"watchReconnectInterval":1000,"watchReconnectLimit":-1,"uploadRequestTimeout":120000,"requestRetryBackoffLimit":10,"requestRetryBackoffInterval":100,"requestTimeout":10000,"scaleTimeout":600000,"loggingInterval":20000},"contexts":[{"context":{"cluster":"xxxxx-id","namespace":"id-stag","user":"stefano-xxxxx-id"},"name":"xxxxx-id"},{"context":{"cluster":"docker-desktop","user":"docker-desktop"},"name":"docker-desktop"}],"currentContext":{"context":{"cluster":"xxxxx-id","namespace":"id-stag","user":"stefano.xxxxx-id"},"name":"xxxxx-id"},"onlyHttpWatches":false,"autoConfigure":true,"file":"/Users/deej/.kube/config","trustCerts":false,"disableHostnameVerification":false,"masterUrl":"https://api.k8s.eu-central-1.aws.xxxxx.com/","apiVersion":"v1","namespace":"id-stag","defaultNamespace":true,"caCertFile":"/Users/deej/.kube/certs/xxxxx-id/k8s-ca.crt","clientKeyPassphrase":"meeeee","websocketPingInterval":30000,"connectionTimeout":10000,"watchReconnectInterval":1000,"watchReconnectLimit":-1,"uploadRequestTimeout":120000,"requestRetryBackoffLimit":10,"requestRetryBackoffInterval":100,"requestTimeout":10000,"scaleTimeout":600000,"loggingInterval":20000,"impersonateGroups":[""],"impersonateExtras":{},"http2Disable":false,"noProxy":[],"userAgent":"fabric8-kubernetes-client/6.10.0","tlsVersions":["TLS_1_3","TLS_1_2"],"errorMessages":{}}

@rohanKanojia
Copy link

@deejonz : oh, I see in your case caCertFile is set instead of caCertData.

I think we should update OpenIDConnectionUtils to consider both caCertData and caCertFile.

@rohanKanojia
Copy link

rohanKanojia commented Mar 19, 2024

@deejonz : I have created a PR that might fix this issue. Is it possible for you to try it out and confirm if you still get NPE?

  1. Clone this repository git clone https://github.com/rohanKanojia/kubernetes-client.git -b pr/openid-cert-data-or-file
  2. Build project mvn clean install -DskipTests
  3. Download the updated reproducer project attached in this comment fabric8-oidc-config-certdata-reproducer.zip
  4. Change fabric8.version property to point to SNAPSHOT in reproducer project
<fabric8.version>6.11-SNAPSHOT</fabric8.version>
  1. Run mvn clean install in reproducer project, the test just invokes OIDC refresh method. Do you still get the NPE? Or is it a different error?

@deejonz
Copy link
Author

deejonz commented Mar 19, 2024

@rohanKanojia

[ERROR] Errors:
[ERROR]   OIDCTokenRefreshTest.resolveOIDCTokenFromAuthConfig:20 » IllegalArgument Illegal base64 character 2d

@rohanKanojia
Copy link

@deejonz : Okay, so we're getting past NPE. I wasn't encoding the read cert file contents, this seems to throw exception when pemString is decoded later.

I've pushed an update to my branch. Is it possible for you to give it a try again 🙏 ?

@deejonz
Copy link
Author

deejonz commented Mar 19, 2024

sure, there you go:

[ERROR] Failures:
[ERROR]   OIDCTokenRefreshTest.resolveOIDCTokenFromAuthConfig:23 expected: <true> but was: <false>

@rohanKanojia
Copy link

rohanKanojia commented Mar 20, 2024

@deejonz : Hmm, now we don't seem to get any exception but maybe token isn't getting refreshed 🤔 . Not sure whether it's due to some misconfiguration from our side or we still need to update something in KubernetesClient.

Load the reproducer project in IntelliJ as a maven project. Is it possible for you to set a breakpoint in OpenIDConnectionUtils#resolveOIDCTokenFromAuthConfig and observe what's happening?

@adietish
Copy link
Collaborator

adietish commented Mar 28, 2024

@deejonz: I "kinda" can replicate it. I have an EKS cluster with keycloak OIDC (@sabre1041 set it up for me, kudos!). I created some deployment, fiddled around an had all the tree items erroring after a few minuntes:

java.lang.NullPointerException
	at java.base/java.util.Base64$Decoder.decode(Base64.java:561)
	at io.fabric8.kubernetes.client.utils.OpenIDConnectionUtils.getDefaultHttpClientWithPemCert(OpenIDConnectionUtils.java:292)
	at io.fabric8.kubernetes.client.utils.OpenIDConnectionUtils.getOIDCProviderTokenEndpointAndRefreshToken(OpenIDConnectionUtils.java:330)
	at io.fabric8.kubernetes.client.utils.OpenIDConnectionUtils.resolveOIDCTokenFromAuthConfig(OpenIDConnectionUtils.java:86)
	at io.fabric8.kubernetes.client.utils.TokenRefreshInterceptor.extractNewAccessTokenFrom(TokenRefreshInterceptor.java:83)
	at io.fabric8.kubernetes.client.utils.TokenRefreshInterceptor.refreshToken(TokenRefreshInterceptor.java:76)
	at io.fabric8.kubernetes.client.utils.TokenRefreshInterceptor.before(TokenRefreshInterceptor.java:58)
	at io.fabric8.kubernetes.client.http.StandardHttpClient.consumeBytes(StandardHttpClient.java:65)
	at io.fabric8.kubernetes.client.http.SendAsyncUtils.bytes(SendAsyncUtils.java:51)
	at io.fabric8.kubernetes.client.http.HttpResponse$SupportedResponses.sendAsync(HttpResponse.java:105)
	at io.fabric8.kubernetes.client.http.StandardHttpClient.sendAsync(StandardHttpClient.java:52)
	at io.fabric8.kubernetes.client.dsl.internal.OperationSupport.retryWithExponentialBackoff(OperationSupport.java:604)
	at io.fabric8.kubernetes.client.dsl.internal.OperationSupport.handleResponse(OperationSupport.java:581)
	at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.submitList(BaseOperation.java:414)
	at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.list(BaseOperation.java:427)
	at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.list(BaseOperation.java:392)
	at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.list(BaseOperation.java:93)
	at com.redhat.devtools.intellij.kubernetes.model.resource.NamespacedResourceOperator.loadAllResources(NamespacedResourceOperator.kt:68)
	at com.redhat.devtools.intellij.kubernetes.model.resource.NamespacedResourceOperator.getAllResources(NamespacedResourceOperator.kt:54)
	at com.redhat.devtools.intellij.kubernetes.model.resource.NamespacedResourceOperator.getAllResources(NamespacedResourceOperator.kt:36)
	at com.redhat.devtools.intellij.kubernetes.model.context.ActiveContext.getAllResources(ActiveContext.kt:148)
	at com.redhat.devtools.intellij.kubernetes.model.ResourceModel.getAllResources(ResourceModel.kt:122)
	at com.redhat.devtools.intellij.kubernetes.model.ResourceModel.getAllResources$default(ResourceModel.kt:121)
	at com.redhat.devtools.intellij.kubernetes.model.FilterableResources.list(ResourceModelQuery.kt:63)
	at com.redhat.devtools.intellij.kubernetes.tree.KubernetesStructure$createWorkloadElements$14$3.invoke(KubernetesStructure.kt:307)
	at com.redhat.devtools.intellij.kubernetes.tree.KubernetesStructure$createWorkloadElements$14$3.invoke(KubernetesStructure.kt:304)
	at com.redhat.devtools.intellij.kubernetes.tree.AbstractTreeStructureContribution$ElementNode.getChildElements(AbstractTreeStructureContribution.kt:97)
	at com.redhat.devtools.intellij.kubernetes.tree.AbstractTreeStructureContribution.getChildElements(AbstractTreeStructureContribution.kt:28)
	at com.redhat.devtools.intellij.kubernetes.tree.TreeStructure.getChildElements(TreeStructure.kt:71)
	at com.redhat.devtools.intellij.kubernetes.tree.TreeStructure.getChildElements(TreeStructure.kt:64)
	at com.intellij.ui.tree.StructureTreeModel.getValidChildren(StructureTreeModel.java:383)
	at com.intellij.ui.tree.StructureTreeModel.validateChildren(StructureTreeModel.java:299)
	at com.intellij.ui.tree.StructureTreeModel.getNode(StructureTreeModel.java:293)
	at com.intellij.ui.tree.StructureTreeModel.getChildren(StructureTreeModel.java:313)
	at com.intellij.ui.tree.AsyncTreeModel$CmdGetChildren.getNode(AsyncTreeModel.java:545)
	at com.intellij.ui.tree.AsyncTreeModel$Command.get(AsyncTreeModel.java:440)
	at com.intellij.ui.tree.AsyncTreeModel$Command.get(AsyncTreeModel.java:406)
	at com.intellij.util.concurrency.Invoker$Task.run(Invoker.java:314)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:189)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeProcessUnderProgress$12(CoreProgressManager.java:608)
	at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:683)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:639)
	at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:607)
	at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:60)
	at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:176)
	at com.intellij.util.concurrency.Invoker.invokeSafely(Invoker.java:201)
	at com.intellij.util.concurrency.Invoker.lambda$offerSafely$0(Invoker.java:181)
	at com.intellij.util.concurrency.Invoker$Background.lambda$offer$0(Invoker.java:481)
	at com.intellij.util.concurrency.BoundedTaskExecutor.doRun(BoundedTaskExecutor.java:241)
	at com.intellij.util.concurrency.BoundedTaskExecutor.access$200(BoundedTaskExecutor.java:31)
	at com.intellij.util.concurrency.BoundedTaskExecutor$1.execute(BoundedTaskExecutor.java:214)
	at com.intellij.util.ConcurrencyUtil.runUnderThreadName(ConcurrencyUtil.java:212)
	at com.intellij.util.concurrency.BoundedTaskExecutor$1.run(BoundedTaskExecutor.java:203)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:668)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:665)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:665)
	at java.base/java.lang.Thread.run(Thread.java:829)

I'll now try with the updated client that i should build manually.

@adietish
Copy link
Collaborator

adietish commented Mar 28, 2024

@deejonz: Using the fixed client mentioned in #726 (comment) I dont face the issue any more. What about me making you a binary build of the plugin and kindly asking you to test it?

ps. I found other non-related issues though. Refresh causes the plugin to break. Changing the current namespace also breaks it. Will file those.

@deejonz
Copy link
Author

deejonz commented Mar 28, 2024

sure np I can do it, but after tuesday. Thanks for your effort.

@adietish
Copy link
Collaborator

@deejonz awesomeness. Thanks for reporting and testing, highly appreciated.

@adietish
Copy link
Collaborator

adietish commented Mar 28, 2024

for my own documentation, here's how to set up the whole thing:

  1. ASSERT: Have a keycloak service running.
  2. EXEC: add it as OIDC identity provider in your EKS cluster
image image
  1. EXEC: in bash, query keycloak for refresh-token and id-token:
curl \
  -d "grant_type=password" \
  -d "scope=openid" \
  -d "client_id=kubernetes" \
  -d "client_secret=<shared secret> \
  -d "username=<myuser>" \
  -d "password=<mypassword>" \
https://<keycloak-host>/auth/realms/eks/protocol/openid-connect/token | jq .

you get the following output:

{
  "access_token": "eyJhbGciOiJSUzI1...0zojav4wbx3gg",
  "expires_in": 300,
  "refresh_expires_in": 1800,
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAi...P2W0Gy6VTiQHD1fLRJSDDmHm0",
  "token_type": "Bearer",
  "id_token": "eyJhbGciOiJSUzI1NiIsInR5...DxDnqo31mVmmBMhn11w",
  "not-before-policy": 0,
  "session_state": "44d1f4...bb3ffaa7",
  "scope": "openid email profile"
}
  1. EXEC: using kubectl issue the following command using refresh_token and id_token given in the former output to update the kube config (creates/updates an 'eks' context):
kubectl config set-credentials eks \
"--auth-provider=oidc" \
"--auth-provider-arg=idp-issuer-url=https://<keycloak-host>/auth/realms/eks" \
"--auth-provider-arg=client-id=kubernetes" \
"--auth-provider-arg=client-secret=<same shared-secret>" \
"--auth-provider-arg=refresh-token=<refresh-token>" \
"--auth-provider-arg=id-token=<id-token>"

@deejonz
Copy link
Author

deejonz commented Apr 2, 2024

Good morning @adietish can I have the binary build to try?

@adietish
Copy link
Collaborator

adietish commented Apr 2, 2024

Hi @deejonz, sure, sorry for being late. Here it is: https://drive.google.com/file/d/190iiADA7SEmbchyXq2PihYEAc_wVy1ZC/view?usp=sharing

ps. you'd have to uninstall the other custom build with the same version first. I now have a EKS cluster with external OIDC authentication. Still, I'm not using the AWS OIDC service but keycloack running on our infrastructure. It is close, not identical. Crossing fingers it's close enough.

@deejonz
Copy link
Author

deejonz commented Apr 2, 2024

it looks much better now 👍
thanks.

@mohitsuman mohitsuman added this to the 1.3.0 milestone Apr 3, 2024
@mohitsuman mohitsuman moved this from 🏗 In progress to 👀 In review in IDE Cloudaptors Apr 3, 2024
@adietish adietish mentioned this issue Apr 3, 2024
@deejonz
Copy link
Author

deejonz commented Apr 4, 2024

Good morning @adietish same problem this morning with updated plugin:
Screenshot 2024-04-04 at 09 35 47
Screenshot 2024-04-04 at 09 35 26

and after clicking refresh:
Screenshot 2024-04-03 at 09 36 18

then I've restarted intellij and I've got this:
image
clicked refresh, nothing happened.
If I do: "get po" then it works fine.

@rohanKanojia
Copy link

@deejonz : I'm not sure whether somehow IntelliJ is reverting to stable build of plugin or whether it's actually a problem in KubernetesClient. Is it possible for you to run the BasicPodListTest in the reproducer project I had shared tomorrow morning when your token expires fabric8io/kubernetes-client#5817 (comment)?

@deejonz
Copy link
Author

deejonz commented Apr 4, 2024

the plugin version is still 6.11-SNAPSHOT in the plugin folder..

@adietish
Copy link
Collaborator

adietish commented Apr 4, 2024

@deejonz: @rohanKanojia could replicate it with the binary build while showing that the client library by itself didnt have the issue. I'm digging into it to see what is happensing here

@deejonz
Copy link
Author

deejonz commented Apr 5, 2024

@adietish hello, same issue this morning, so I run the unit test and it passed. After that the plugin automatically refreshed and it started to work so no need to restart intellij to make it working.

@rohanKanojia
Copy link

@deejonz : When you ran the test, KubernetesClient refreshed the token and persisted it in kubeconfig. Plugin picked up that updated token and started working.

@adietish
Copy link
Collaborator

adietish commented Apr 8, 2024

Hi @deejonz,
thanks for reporting this latest behaviour. I think that we found what was causing it.
I have a new build for you to test if you want: https://drive.google.com/file/d/1eZge8aacPOUbh2vjU2GKCBO5uMm09bsW/view?usp=sharing

@deejonz
Copy link
Author

deejonz commented Apr 8, 2024

Hi @adietish sure I will test it, thanks for the update.

@adietish
Copy link
Collaborator

adietish commented Apr 8, 2024

For my own documentation, our code was preventing the OIDC token from being refreshed:

In https://github.com/fabric8io/kubernetes-client/blob/a400d760fc966f660cd687d8d773dc1be04bbb85/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/TokenRefreshInterceptor.java#L138 a refresh of the token is only attempted if the kube config has an OIDC auth provider.

  protected boolean useRemoteRefresh(Config newestConfig) {
    // TODO: in a hard failure scenario, should we skip the expired check
    return isAuthProviderOidc(newestConfig) && OpenIDConnectionUtils.idTokenExpired(newestConfig);
  }
  private static boolean isAuthProviderOidc(Config newestConfig) {
    return newestConfig.getAuthProvider() != null && newestConfig.getAuthProvider().getName().equalsIgnoreCase("oidc");
  }

Our code was erroneously thinking that the cluster was an OpenShift cluster. The config in the OpenShift client hides the auth provider (that exists in the Kubernetes client) and thus prevents tokens from being refreshed. Correcting redhat-developer/intellij-common#216 therefore causes tokens to be refreshed if the kube config is configured with an OIDC auth provider.

@deejonz
Copy link
Author

deejonz commented Apr 9, 2024

Good, this morning it is working fine! Thanks for the fix!

@adietish
Copy link
Collaborator

adietish commented Apr 9, 2024

@deejonz wohoo, great news. Very happy that all this work came to fruition 🕺 Thanks a lot for all the testing!

@adietish
Copy link
Collaborator

The PR for this can be reviewed and merged once we have a new release of kubernetes-client. fabric8/kubernetes-client is planning one for very soon. Once merged we'll release a 1.3 of our plugin.

@adietish
Copy link
Collaborator

fixed by #713. Closing.

@github-project-automation github-project-automation bot moved this from 👀 In review to ✅ Done in IDE Cloudaptors Apr 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Something isn't working severity/critical
Projects
Status: ✅ Done
Development

No branches or pull requests

4 participants