From d04e09d8846f81b40d9e60141e7ce71f762a75de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Gro=C3=9Fmann?= Date: Mon, 19 Jan 2026 16:52:58 +0100 Subject: [PATCH] feat: engine should not depend on client module --- client/client.go | 42 +++++------------------------ cmd/engine/go.sum | 2 -- engine/.gomodguard.yaml | 4 +-- engine/engine_test.go | 16 ++++------- engine/go.mod | 1 - engine/integration_runtimes_test.go | 24 ++++++++++++----- x/api/resolver/resolver.go | 42 +++++++++++++++++++++++++++++ 7 files changed, 73 insertions(+), 58 deletions(-) diff --git a/client/client.go b/client/client.go index 35acecf3..96351763 100644 --- a/client/client.go +++ b/client/client.go @@ -8,9 +8,9 @@ import ( "time" "connectrpc.com/connect" - "google.golang.org/protobuf/proto" "github.com/docker/secrets-engine/x/api" + "github.com/docker/secrets-engine/x/api/resolver" v1 "github.com/docker/secrets-engine/x/api/resolver/v1" "github.com/docker/secrets-engine/x/api/resolver/v1/resolverv1connect" "github.com/docker/secrets-engine/x/secrets" @@ -74,10 +74,14 @@ type config struct { } type client struct { - resolverClient resolverv1connect.ResolverServiceClient + resolverClient secrets.Resolver listClient resolverv1connect.ListServiceClient } +func (c client) GetSecrets(ctx context.Context, pattern secrets.Pattern) ([]secrets.Envelope, error) { + return c.resolverClient.GetSecrets(ctx, pattern) +} + type Client interface { secrets.Resolver @@ -118,43 +122,11 @@ func New(options ...Option) (Client, error) { Timeout: cfg.requestTimeout, } return &client{ - resolverClient: resolverv1connect.NewResolverServiceClient(c, "http://unix"), + resolverClient: resolver.NewResolverClient(c), listClient: resolverv1connect.NewListServiceClient(c, "http://unix"), }, nil } -func (c client) GetSecrets(ctx context.Context, pattern secrets.Pattern) ([]secrets.Envelope, error) { - req := connect.NewRequest(v1.GetSecretsRequest_builder{ - Pattern: proto.String(pattern.String()), - }.Build()) - resp, err := c.resolverClient.GetSecrets(ctx, req) - if err != nil { - if connect.CodeOf(err) == connect.CodeNotFound { - err = secrets.ErrNotFound - } - return nil, err - } - - var envelopes []secrets.Envelope - for _, item := range resp.Msg.GetEnvelopes() { - id, err := secrets.ParseID(item.GetId()) - if err != nil { - continue - } - envelopes = append(envelopes, secrets.Envelope{ - ID: id, - Value: item.GetValue(), - Metadata: item.GetMetadata(), - Provider: item.GetProvider(), - Version: item.GetVersion(), - CreatedAt: item.GetCreatedAt().AsTime(), - ResolvedAt: item.GetResolvedAt().AsTime(), - ExpiresAt: item.GetExpiresAt().AsTime(), - }) - } - return envelopes, nil -} - func (c client) ListPlugins(ctx context.Context) ([]PluginInfo, error) { req := connect.NewRequest(v1.ListPluginsRequest_builder{}.Build()) resp, err := c.listClient.ListPlugins(ctx, req) diff --git a/cmd/engine/go.sum b/cmd/engine/go.sum index 4264dad1..4a457462 100644 --- a/cmd/engine/go.sum +++ b/cmd/engine/go.sum @@ -11,8 +11,6 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/docker-credential-helpers v0.9.4 h1:76ItO69/AP/V4yT9V4uuuItG0B1N8hvt0T0c0NN/DzI= github.com/docker/docker-credential-helpers v0.9.4/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= -github.com/docker/secrets-engine/client v0.0.16 h1:x6IeuuJXE7E9zfK0ZZzOBTJhtgli/abRX2qWUV6wLDc= -github.com/docker/secrets-engine/client v0.0.16/go.mod h1:0/DJvZvZKVwxum7gGKbP44v3vHr4y03skTBrD0Asn2k= github.com/docker/secrets-engine/plugin v0.0.19 h1:MZpwFIpDJXdlb+jS7GMaH2FUTshxlSQ77XYyu/OVsyc= github.com/docker/secrets-engine/plugin v0.0.19/go.mod h1:5smOpW84QwwIcuXrIN4IfyI3QJ4T8gDErycstYWjHZE= github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE= diff --git a/engine/.gomodguard.yaml b/engine/.gomodguard.yaml index 2323c7c9..92cf8327 100644 --- a/engine/.gomodguard.yaml +++ b/engine/.gomodguard.yaml @@ -1,8 +1,8 @@ --- blocked: modules: -# - github.com/docker/secrets-engine/client: -# reason: "Forbidden dependency" + - github.com/docker/secrets-engine/client: + reason: "Forbidden dependency" - github.com/docker/secrets-engine/injector: reason: "Forbidden dependency" - github.com/docker/secrets-engine/plugins/pass: diff --git a/engine/engine_test.go b/engine/engine_test.go index 34356194..20e408eb 100644 --- a/engine/engine_test.go +++ b/engine/engine_test.go @@ -14,7 +14,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/docker/secrets-engine/client" "github.com/docker/secrets-engine/engine/internal/mocks" "github.com/docker/secrets-engine/engine/internal/plugin" "github.com/docker/secrets-engine/engine/internal/registry" @@ -215,8 +214,7 @@ func Test_newEngine(t *testing.T) { e, err := newEngine(testhelper.TestLoggerCtx(t), cfg) require.NoError(t, err) t.Cleanup(func() { assert.NoError(t, e.Close()) }) - c, err := client.New(client.WithSocketPath(socketPath)) - require.NoError(t, err) + c := newMockClient(socketPath) foo, err := c.GetSecrets(t.Context(), secrets.MustParsePattern("foo")) require.NoError(t, err) require.NotEmpty(t, foo) @@ -240,8 +238,7 @@ func Test_newEngine(t *testing.T) { assert.EventuallyWithT(t, func(collect *assert.CollectT) { assert.ElementsMatch(collect, e.Plugins(), []string{"plugin-bar"}) }, 2*time.Second, 100*time.Millisecond) - c, err := client.New(client.WithSocketPath(socketPath)) - require.NoError(t, err) + c := newMockClient(socketPath) bar, err := c.GetSecrets(t.Context(), secrets.MustParsePattern("bar")) require.NoError(t, err) require.NotEmpty(t, bar) @@ -285,8 +282,7 @@ func Test_newEngine(t *testing.T) { assert.EventuallyWithT(t, func(collect *assert.CollectT) { assert.ElementsMatch(collect, e.Plugins(), []string{"my-builtin"}) }, 2*time.Second, 100*time.Millisecond) - c, err := client.New(client.WithSocketPath(socketPath)) - require.NoError(t, err) + c := newMockClient(socketPath) mySecret, err := c.GetSecrets(t.Context(), secrets.MustParsePattern("my-secret")) require.NoError(t, err) require.NotEmpty(t, mySecret) @@ -312,8 +308,7 @@ func Test_newEngine(t *testing.T) { e, err := newEngine(testhelper.TestLoggerCtx(t), cfg) require.NoError(t, err) t.Cleanup(func() { assert.NoError(t, e.Close()) }) - c, err := client.New(client.WithSocketPath(socketPath)) - require.NoError(t, err) + c := newMockClient(socketPath) _, err = c.GetSecrets(t.Context(), secrets.MustParsePattern("bar")) require.NoError(t, err) killAllPlugins(t, getRegistry(t, e)) @@ -355,8 +350,7 @@ func Test_newEngine(t *testing.T) { e, err := newEngine(testhelper.TestLoggerCtx(t), cfg) require.NoError(t, err) t.Cleanup(func() { assert.NoError(t, e.Close()) }) - c, err := client.New(client.WithSocketPath(socketPath)) - require.NoError(t, err) + c := newMockClient(socketPath) assert.EventuallyWithT(t, func(collect *assert.CollectT) { assert.ElementsMatch(collect, e.Plugins(), []string{"my-builtin"}) }, 2*time.Second, 100*time.Millisecond) diff --git a/engine/go.mod b/engine/go.mod index d7cd3af8..e329b64e 100644 --- a/engine/go.mod +++ b/engine/go.mod @@ -16,7 +16,6 @@ replace github.com/docker/secrets-engine/x => ../x require ( connectrpc.com/connect v1.18.1 github.com/cenkalti/backoff/v5 v5.0.3 - github.com/docker/secrets-engine/client v0.0.16 github.com/docker/secrets-engine/plugin v0.0.19 github.com/docker/secrets-engine/x v0.0.12-do.not.use github.com/go-chi/chi/v5 v5.2.3 diff --git a/engine/integration_runtimes_test.go b/engine/integration_runtimes_test.go index 8d641ffe..3c1c6087 100644 --- a/engine/integration_runtimes_test.go +++ b/engine/integration_runtimes_test.go @@ -4,6 +4,7 @@ import ( "context" "errors" "net" + "net/http" "path/filepath" "syscall" "testing" @@ -15,12 +16,12 @@ import ( "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/sdk/trace" - "github.com/docker/secrets-engine/client" "github.com/docker/secrets-engine/engine/internal/mocks" "github.com/docker/secrets-engine/engine/internal/plugin" "github.com/docker/secrets-engine/engine/internal/testdummy" p "github.com/docker/secrets-engine/plugin" "github.com/docker/secrets-engine/x/api" + "github.com/docker/secrets-engine/x/api/resolver" "github.com/docker/secrets-engine/x/secrets" "github.com/docker/secrets-engine/x/testhelper" ) @@ -51,9 +52,19 @@ func testEngine(t *testing.T) (secrets.Resolver, string) { {"my-builtin", mockValidVersion, mockPatternAny}: &mocks.MockInternalPlugin{Secrets: map[secrets.ID]string{secrets.MustParseID("my-secret"): "some-value"}}, }), ) - c, err := client.New(client.WithSocketPath(socketPath)) - require.NoError(t, err) - return c, socketPath + return newMockClient(socketPath), socketPath +} + +func newMockClient(socketPath string) secrets.Resolver { + c := &http.Client{ + Transport: &http.Transport{ + DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) { + d := &net.Dialer{} + return d.DialContext(ctx, "unix", socketPath) + }, + }, + } + return resolver.NewResolverClient(c) } func Test_SecretsEngine(t *testing.T) { @@ -190,9 +201,8 @@ func TestWithEnginePluginsDisabled(t *testing.T) { options = append(options, test.extraOption) } runEngineAsync(t, "test-engine", "test-version", options...) - c, err := client.New(client.WithSocketPath(socketPath)) - require.NoError(t, err) - _, err = c.GetSecrets(t.Context(), secrets.MustParsePattern("foo")) + c := newMockClient(socketPath) + _, err := c.GetSecrets(t.Context(), secrets.MustParsePattern("foo")) if test.shouldGetSecretFromExternalPlugin { assert.NoError(t, err) } else { diff --git a/x/api/resolver/resolver.go b/x/api/resolver/resolver.go index db7339fb..d8484b2c 100644 --- a/x/api/resolver/resolver.go +++ b/x/api/resolver/resolver.go @@ -59,3 +59,45 @@ func (r resolverService) GetSecrets(ctx context.Context, c *connect.Request[reso Envelopes: items, }.Build()), nil } + +var _ secrets.Resolver = &resolverClient{} + +type resolverClient struct { + resolverClient resolverv1connect.ResolverServiceClient +} + +func NewResolverClient(httpClient connect.HTTPClient) secrets.Resolver { + return &resolverClient{resolverClient: resolverv1connect.NewResolverServiceClient(httpClient, "http://unix")} +} + +func (r resolverClient) GetSecrets(ctx context.Context, pattern secrets.Pattern) ([]secrets.Envelope, error) { + req := connect.NewRequest(resolverv1.GetSecretsRequest_builder{ + Pattern: proto.String(pattern.String()), + }.Build()) + resp, err := r.resolverClient.GetSecrets(ctx, req) + if err != nil { + if connect.CodeOf(err) == connect.CodeNotFound { + err = secrets.ErrNotFound + } + return nil, err + } + + var envelopes []secrets.Envelope + for _, item := range resp.Msg.GetEnvelopes() { + id, err := secrets.ParseID(item.GetId()) + if err != nil { + continue + } + envelopes = append(envelopes, secrets.Envelope{ + ID: id, + Value: item.GetValue(), + Metadata: item.GetMetadata(), + Provider: item.GetProvider(), + Version: item.GetVersion(), + CreatedAt: item.GetCreatedAt().AsTime(), + ResolvedAt: item.GetResolvedAt().AsTime(), + ExpiresAt: item.GetExpiresAt().AsTime(), + }) + } + return envelopes, nil +}