feat(sdk/go): add Go SDK foundation, types, and sandbox client (A) - #2271
Conversation
Principal Engineer Review — Go SDK foundation (A)Reviewed by checking out the branch and reading every non-generated file. Blocking1. Dead code will fail the project's own lint gate —
|
- Make scheme parsing drive transport selection: http:// uses plaintext gRPC, https:// or no scheme uses TLS. Add regression tests. - Add Resources and DriverConfig fields to SandboxTemplate and update both converter directions (SandboxFromProto/SandboxSpecToProto). - Regenerate proto bindings from current canonical proto sources to eliminate drift (SigV4/MCP fields, params matchers, reserved fields). - Run gofmt/goimports on all handwritten Go files. Signed-off-by: Roland Huß <rhuss@redhat.com>
russellb
left a comment
There was a problem hiding this comment.
[codex:gpt-5.5] Finding 1: The Go SDK still drops active sandbox policy fields from the handwritten types/converters. The synced proto includes credential_signing, signing_service, signing_region, json_rpc_max_body_bytes, mcp, and params on L7 allow/deny rules, but PolicyNetworkEndpoint, L7Allow, L7DenyRule, and the converters omit them. Since Create sends SandboxSpecToProto, Go clients cannot express current SigV4/MCP/JSON-RPC policy controls, and server-returned policies lose these fields on round-trip. Please add SDK fields and bidirectional converter coverage for every current proto policy field. Refs: sdk/go/openshell/v1/types/network_policy.go:19, sdk/go/openshell/v1/internal/converter/network_policy.go:65, proto/sandbox.proto:131, proto/sandbox.proto:211.
[codex:gpt-5.5] Finding 2: mapToStruct ignores structpb.NewStruct errors for SandboxTemplate.Resources and DriverConfig. Invalid UTF-8 keys or unsupported map[string]any values make NewStruct return nil, err, but the SDK silently sends nil, so user-provided template config can disappear without an error. Please make sandbox spec conversion fallible, validate before CreateSandbox, or expose a safer typed representation, and add tests for invalid values. Refs: sdk/go/openshell/v1/internal/converter/copy.go:60, sdk/go/openshell/v1/internal/converter/sandbox.go:170, sdk/go/openshell/v1/sandbox_client.go:28.
|
My agent's response to #2271 (comment). Most of the things are because of this artificial split to get the PRs down to something more consumable (which was also important as I hight some size limits for code agent's review when I dropped it). But thank you very much for jumping on it, I've addressed the comments (and delayed some until we get the full combo in) Thanks for the review. Here is my assessment, classifying each finding by root cause: Already addressed (in a prior fix commit
Fixed now (commit
Deferred to later PRs (expected from the A-F split):
Accepted as low-priority (not blocking):
|
Sounds good. I figured some of it would be off, but that your agent would sort it out. :) |
Move Go SDK mise configuration from standalone sdk/go/mise.toml into the project's centralized pattern: - Add Go tools (go, golangci-lint, protoc-gen-go, protoc-gen-go-grpc) to root mise.toml [tools] section - Create tasks/go.toml with all SDK tasks using go: namespace prefix and dir=sdk/go for working directory - Update sdk/go/Makefile to reference namespaced task names - Update proto:sync default path for monorepo layout Addresses review feedback from drew on PR NVIDIA#2271 regarding mise convention alignment. Signed-off-by: Roland Huß <rhuss@redhat.com>
Add a Go SDK job to branch-checks.yml that runs mise run go:ci (lint, build, test, proto-check, docs-check) on every PR. This ensures the SDK is tested in CI, not just locally. Signed-off-by: Roland Huss <rhuss@redhat.com>
#6 Fix broken godoc examples: add workspace parameter to all method calls in doc.go that were broken after workspace scoping. #7 Add Err field to Event[T]: Watch error events now carry the underlying error instead of discarding it. #8 Separate Unauthenticated from PermissionDenied: add ErrorUnauthenticated code and IsUnauthenticated() helper. gRPC Unauthenticated (401) now maps to its own code instead of collapsing into PermissionDenied (403). #9 Add Unwrap to StatusError: replace dead Details field with Cause error field. StatusError.Unwrap() returns Cause, enabling errors.Is/As unwrapping. FromGRPCError and contextError both populate Cause. Signed-off-by: Roland Huss <rhuss@redhat.com>
Add gofmt format verification to go:ci. Catches unformatted Go files before they reach the PR. Fix formatting on coverage_test.go. Signed-off-by: Roland Huss <rhuss@redhat.com>
All build, lint, test, and proto-gen tasks are already defined in tasks/go.toml and invoked via mise. The Makefile was a leftover that duplicated this and raised questions in review. Signed-off-by: Roland Huß <rhuss@redhat.com>
Regenerate Go proto bindings after rebase to pick up new CredentialHandle message and Provider.credential_handles and profile_workspace fields from upstream. Add domain types, converter support, and proto field coverage tests for Provider and CredentialHandle. Signed-off-by: Roland Huß <rhuss@redhat.com>
26aa198 to
77e65c5
Compare
|
/ok to test 77e65c5 |
Reject http:// addresses when the auth provider requires transport security instead of silently stripping the requirement. Remove the insecureAuthWrapper that overrode RequireTransportSecurity. Fix watch stream error handling: use blocking send for terminal errors so they are never silently dropped when the channel is full, and wrap mid-stream errors with converter.FromGRPCError so SDK error helpers like IsUnavailable work on watch Event.Err. Signed-off-by: Roland Huß <rhuss@redhat.com>
Head branch was pushed to by a user without write access
|
/ok to test 939ec51 |
- WaitReady now detects SandboxDeleting phase and returns immediately instead of polling indefinitely - Watch goroutine defers streamCancel() to prevent context leaks - Fix StopOnTerminal=false test to keep stream open (was wrong-reason pass due to stream ending, not StopOnTerminal logic) - Add EventDeleted test covering the Deleting phase branch - Add provider converter unit tests for CredentialHandle round-trip, nil handling, and empty maps Signed-off-by: Roland Huß <rhuss@redhat.com>
|
/ok to test 5aeb1d6 |
…g (Drop B) Add the remaining Go SDK packages to complete the OpenShell Go client library. This PR builds on the foundation from Drop A (PR NVIDIA#2271) with: - 13 domain clients: config, exec, file, health, inference, policy, profile, provider, refresh, service, ssh, tcp, workspace - Authentication: OIDC package (auth code, device code, browser flows) and gateway token management - Edge connectivity: Cloudflare tunnel and WebSocket proxy - Test infrastructure: fake client implementations with validation parity for all 14 domains - Proto extensions: inference and options proto definitions with generated Go bindings - Hardening: watch goroutine race fix, TLS config conflict detection, WaitReady helper extraction, deep-copy credential tests - API cleanup: removed unused option structs and config fields (YAGNI) - Documentation: API reference pages, getting started guide, architecture overview, error handling, and testing guides All changes target sdk/go/. CI integration follows in a subsequent PR. Ref NVIDIA#2044
Context
This is the first PR in a 6-PR decomposition of the Go SDK contribution (#2044). The decomposition was discussed in the contributor meeting on 2026-07-14 to make the review process more approachable.
The first PR is intentionally the largest because it carries the shared foundation. After this merge, the SDK is usable end-to-end for sandbox management. Each subsequent PR then incrementally adds one more resource group, and after every merge the SDK is fully working with an expanded API surface.
What's in this PR
go.mod,go.sum,Makefile,mise.tomltypes/package (14 files) covering every SDK resourceClientInterface: all 10 sub-client accessors defined upfrontUnimplementederrors linking to feat(sdk/go): Go SDK PR decomposition plan #2270. Each subsequent PR replaces stubs with real implementations.How to Review
Review zones
client.go,types/*.go,errors.go,auth*.go,sandbox.go,sandbox_client.go,internal/grpc/conn.gosandbox_client_test.go,internal/converter/sandbox.go,internal/converter/sandbox_test.gosandbox_client_test.goas the test pattern exemplar. Converter tests follow table-driven patterns.stub_clients.go,go.sum,Makefile,mise.toml,doc.go, interface-only files (exec.go,file.go, etc.)proto/*.pb.go,proto/*_grpc.pb.goKey design decisions
types/package has no proto imports, insulating consumers from wire format changesErrorUnimplementedwith a link to the tracking issue. Each follow-up PR replaces stubs with real implementations without modifyingclient.go.What to look for
ClientInterfacecovers the right API surfaceIsNotFound(), etc.)Testing
All 130 tests pass:
Resolves #2044 (with remaining PRs B-F)
Part of #2270