mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-29 07:23:25 +08:00
* feat(api): return typed deletion outcomes with explicit missing-target semantics Implement phase 2 of #3051 across the public gateway API and first-party SDKs. Preserve asynchronous sandbox deletion and observed resource identities, reserve legacy wire fields, and document the coordinated migration. Signed-off-by: Mrunal Patel <mrunalp@gmail.com> * fix(sdk): bind deletion waits to sandbox identity Track accepted deletions by original sandbox identity in Rust and TypeScript. Preserve name-only waits and cover replacement races and lookup failures. Merge the phase-one cleanup fix and adapt its interceptor regressions to typed deletion outcomes. Refs #3051. Signed-off-by: Mrunal Patel <mrunalp@gmail.com> * test(e2e): accept asynchronous stopped sandbox deletion Allow either completed or accepted deletion output, then continue polling for actual sandbox absence. This preserves the lifecycle assertion under the phase-two deletion contract. Refs #3051. Signed-off-by: Mrunal Patel <mrunalp@gmail.com> --------- Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
59 lines
2.3 KiB
Go
59 lines
2.3 KiB
Go
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package fake
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
|
|
v1 "github.com/NVIDIA/OpenShell/sdk/go/openshell/v1"
|
|
"github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/types"
|
|
)
|
|
|
|
// fakeSSHClient implements v1.SSHInterface. All methods return
|
|
// Unimplemented because SSH session management requires a real gateway.
|
|
type fakeSSHClient struct {
|
|
closedFunc func() bool
|
|
}
|
|
|
|
// newFakeSSHClient creates a new fakeSSHClient.
|
|
func newFakeSSHClient(closedFunc func() bool) *fakeSSHClient {
|
|
return &fakeSSHClient{closedFunc: closedFunc}
|
|
}
|
|
|
|
// CreateSession returns Unimplemented.
|
|
func (c *fakeSSHClient) CreateSession(_ context.Context, _, _ string) (*types.SSHSession, error) {
|
|
if c.closedFunc() {
|
|
return nil, &types.StatusError{Code: types.ErrorUnavailable, Message: "client is closed"}
|
|
}
|
|
return nil, &types.StatusError{Code: types.ErrorUnimplemented, Message: "CreateSession is not supported by the fake client"}
|
|
}
|
|
|
|
// RevokeSession returns Unimplemented.
|
|
func (c *fakeSSHClient) RevokeSession(_ context.Context, _, _ string, _ ...v1.DeleteOptions) (*types.DeletionResult, error) {
|
|
if c.closedFunc() {
|
|
return nil, &types.StatusError{Code: types.ErrorUnavailable, Message: "client is closed"}
|
|
}
|
|
return nil, &types.StatusError{Code: types.ErrorUnimplemented, Message: "RevokeSession is not supported by the fake client"}
|
|
}
|
|
|
|
// Tunnel returns Unimplemented. Ports outside 1-65535 and empty sandbox names
|
|
// are rejected with InvalidArgument to match the real client's behavior.
|
|
func (c *fakeSSHClient) Tunnel(_ context.Context, _, sandboxName string, port uint32, _ ...v1.TunnelOption) (io.ReadWriteCloser, error) {
|
|
if c.closedFunc() {
|
|
return nil, &types.StatusError{Code: types.ErrorUnavailable, Message: "client is closed"}
|
|
}
|
|
if sandboxName == "" {
|
|
return nil, &types.StatusError{Code: types.ErrorInvalidArgument, Message: "sandbox name must not be empty"}
|
|
}
|
|
if port == 0 || port > 65535 {
|
|
return nil, &types.StatusError{Code: types.ErrorInvalidArgument, Message: fmt.Sprintf("port must be in range 1-65535, got %d", port)}
|
|
}
|
|
return nil, &types.StatusError{Code: types.ErrorUnimplemented, Message: "Tunnel is not supported by the fake client"}
|
|
}
|
|
|
|
// Compile-time check that fakeSSHClient implements v1.SSHInterface.
|
|
var _ v1.SSHInterface = (*fakeSSHClient)(nil)
|