Open
Conversation
Signed-off-by: Daniil Antoshin <daniil.antoshin@flant.com>
Signed-off-by: Daniil Antoshin <daniil.antoshin@flant.com>
Signed-off-by: Daniil Antoshin <daniil.antoshin@flant.com>
yaroslavborbat
requested changes
Apr 22, 2026
Comment on lines
+137
to
+145
| if err != nil { | ||
| t.Fatalf("Run returned error: %v", err) | ||
| } | ||
| if connectCalls != 2 { | ||
| t.Fatalf("expected 2 connect attempts, got %d", connectCalls) | ||
| } | ||
| if clientCalls != 2 { | ||
| t.Fatalf("expected client to be refreshed before each reconnect, got %d calls", clientCalls) | ||
| } |
Comment on lines
+37
to
+87
| func (f *fakeKubeclient) ClusterVirtualImages() virtualizationv1alpha2.ClusterVirtualImageInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachines(namespace string) virtualizationv1alpha2.VirtualMachineInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualImages(namespace string) virtualizationv1alpha2.VirtualImageInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualDisks(namespace string) virtualizationv1alpha2.VirtualDiskInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineBlockDeviceAttachments(namespace string) virtualizationv1alpha2.VirtualMachineBlockDeviceAttachmentInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineIPAddresses(namespace string) virtualizationv1alpha2.VirtualMachineIPAddressInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineIPAddressLeases() virtualizationv1alpha2.VirtualMachineIPAddressLeaseInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineOperations(namespace string) virtualizationv1alpha2.VirtualMachineOperationInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineClasses() virtualizationv1alpha2.VirtualMachineClassInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineMACAddresses(namespace string) virtualizationv1alpha2.VirtualMachineMACAddressInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineMACAddressLeases() virtualizationv1alpha2.VirtualMachineMACAddressLeaseInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) NodeUSBDevices() virtualizationv1alpha2.NodeUSBDeviceInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) USBDevices(namespace string) virtualizationv1alpha2.USBDeviceInterface { | ||
| return nil | ||
| } |
Member
There was a problem hiding this comment.
Don’t we have a generated fake client?
Comment on lines
+116
to
+124
| if ln == nil { | ||
| t.Fatal("listener must not be nil") | ||
| } | ||
| if namespace != "default" { | ||
| t.Fatalf("unexpected namespace: %s", namespace) | ||
| } | ||
| if vmName != "test-vm" { | ||
| t.Fatalf("unexpected vm name: %s", vmName) | ||
| } |
Comment on lines
+138
to
+146
| if err != nil { | ||
| t.Fatalf("Run returned error: %v", err) | ||
| } | ||
| if connectCalls != 2 { | ||
| t.Fatalf("expected 2 connect attempts, got %d", connectCalls) | ||
| } | ||
| if clientCalls != 2 { | ||
| t.Fatalf("expected client to be refreshed before each reconnect, got %d calls", clientCalls) | ||
| } |
Comment on lines
+38
to
+88
| func (f *fakeKubeclient) ClusterVirtualImages() virtualizationv1alpha2.ClusterVirtualImageInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachines(namespace string) virtualizationv1alpha2.VirtualMachineInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualImages(namespace string) virtualizationv1alpha2.VirtualImageInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualDisks(namespace string) virtualizationv1alpha2.VirtualDiskInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineBlockDeviceAttachments(namespace string) virtualizationv1alpha2.VirtualMachineBlockDeviceAttachmentInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineIPAddresses(namespace string) virtualizationv1alpha2.VirtualMachineIPAddressInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineIPAddressLeases() virtualizationv1alpha2.VirtualMachineIPAddressLeaseInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineOperations(namespace string) virtualizationv1alpha2.VirtualMachineOperationInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineClasses() virtualizationv1alpha2.VirtualMachineClassInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineMACAddresses(namespace string) virtualizationv1alpha2.VirtualMachineMACAddressInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) VirtualMachineMACAddressLeases() virtualizationv1alpha2.VirtualMachineMACAddressLeaseInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) NodeUSBDevices() virtualizationv1alpha2.NodeUSBDeviceInterface { | ||
| return nil | ||
| } | ||
|
|
||
| func (f *fakeKubeclient) USBDevices(namespace string) virtualizationv1alpha2.USBDeviceInterface { | ||
| return nil | ||
| } |
Member
There was a problem hiding this comment.
Don’t we have a generated fake client?
Comment on lines
+101
to
+103
| if err != nil { | ||
| t.Fatalf("create stdin pipe: %v", err) | ||
| } |
Comment on lines
+117
to
+122
| if namespace != "default" { | ||
| t.Fatalf("unexpected namespace: %s", namespace) | ||
| } | ||
| if name != "test-vm" { | ||
| t.Fatalf("unexpected vm name: %s", name) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Refresh CLI client config before reconnecting long-lived VM access sessions.
This PR updates
d8 v vncandd8 v consoleso they recreate the Kubernetes client from the current context before each reconnect attempt instead of reusing the client created at command start.Also adds unit tests covering reconnect behavior for both commands.
Why do we need it, and what problem does it solve?
When
d8 v vncord8 v consolestays alive for a long time, the process keeps the old in-memory OIDC config. If the ID token expires and another client (kubectl, anotherd8, Lens, k9s, IDE) refreshes the token first, Dex rotates the refresh token and the old CLI process can no longer use its stale refresh token on reconnect.As a result, after VNC/console reconnect scenarios the command may fail with an error like:
This change makes reconnect logic reread kubeconfig/client config before each new connection attempt, so the command uses the latest valid tokens.
What is the expected result?
Reproduction steps for the original problem:
user-authn/ Dex.user-authn.settings.idTokenTTL, for example to1m.d8 v vnc <vm> -n <ns>, ord8 v console <vm> -n <ns>.kubectl get nsto refresh tokens and rotate the refresh token.Expected result after this PR:
d8 v vncreconnects successfully.d8 v consolereconnects successfully.Checklist
Changelog entries