Skip to content

Commit 3be9543

Browse files
Igor DrozdovVasilii Iakliushinvglafirov
authored andcommitted
Merge branch 'vg/fix-topology-classify-claims-chain' into 'main'
Send Classify claims via the claims chain See merge request https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/1541 Merged-by: Igor Drozdov <idrozdov@gitlab.com> Approved-by: Igor Drozdov <idrozdov@gitlab.com> Co-authored-by: Vasilii Iakliushin <viakliushin@gitlab.com> Co-authored-by: Vladimir Glafirov <vglafirov@gitlab.com>
2 parents ee60225 + 27d9848 commit 3be9543

8 files changed

Lines changed: 65 additions & 19 deletions

File tree

‎go.mod‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ require (
1717
github.com/pires/go-proxyproto v0.14.0
1818
github.com/prometheus/client_golang v1.23.2
1919
github.com/stretchr/testify v1.11.1
20-
gitlab.com/gitlab-org/cells/topology-service v0.0.0-20260522095121-2c761c2e9850
20+
gitlab.com/gitlab-org/cells/topology-service v0.0.0-20260827174901-e70472732254
2121
gitlab.com/gitlab-org/gitaly/v18 v18.9.0-rc4
2222
gitlab.com/gitlab-org/labkit v1.64.11
2323
gitlab.com/gitlab-org/labkit/v2 v2.35.0

‎go.sum‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,8 +516,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
516516
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
517517
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
518518
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
519-
gitlab.com/gitlab-org/cells/topology-service v0.0.0-20260522095121-2c761c2e9850 h1:ooD76K9Xy1IFB6840t808xPzT4sBx3OGoH6Uz37wCYw=
520-
gitlab.com/gitlab-org/cells/topology-service v0.0.0-20260522095121-2c761c2e9850/go.mod h1:3cPQOfQvgI26owOpGzADzB3IJJQ3pTYuLQaurpp1k/A=
519+
gitlab.com/gitlab-org/cells/topology-service v0.0.0-20260827174901-e70472732254 h1:omotGPkyvMHt473hG3xtaZehAeHRm3W1U5UJxg5OXMk=
520+
gitlab.com/gitlab-org/cells/topology-service v0.0.0-20260827174901-e70472732254/go.mod h1:xOxWBmF9zM1HaoAEfjoSb54FpXqIzG0qyD1oBTOQSQw=
521521
gitlab.com/gitlab-org/gitaly/v18 v18.9.0-rc4 h1:2PQlCQF5ioVdmcjY6Ut8zxwFY2TIgHWnl5ekT4IJEKQ=
522522
gitlab.com/gitlab-org/gitaly/v18 v18.9.0-rc4/go.mod h1:ijDPC9GyV3UdmrZG4LiBQJyMjOuzLcbH5AuQ8GpSSIk=
523523
gitlab.com/gitlab-org/go/reopen v1.0.0 h1:6BujZ0lkkjGIejTUJdNO1w56mN1SI10qcVQyQlOPM+8=

‎internal/gitlabnet/authorizedcerts/client_test.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func TestGetByKeyWithTopologyService(t *testing.T) {
163163
require.True(t, cellReceived, "request should have been sent to the cell server")
164164
require.False(t, defaultReceived, "request should NOT have been sent to the default server")
165165

166-
require.Equal(t, "fingerprint-value", mock.LastRequest.GetClaim().GetSshKeyFingerprint())
166+
require.Equal(t, "fingerprint-value", mock.LastClaim(t).GetSshKeyFingerprint())
167167
})
168168

169169
t.Run("falls back to default", func(t *testing.T) {

‎internal/gitlabnet/authorizedkeys/client_test.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ func TestGetByKeyWithTopologyService(t *testing.T) {
169169
require.True(t, cellReceived, "request should have been sent to the cell server")
170170
require.False(t, defaultReceived, "request should NOT have been sent to the default server")
171171

172-
require.Equal(t, expectedFingerprint, mock.LastRequest.GetClaim().GetSshKeyFingerprint())
172+
require.Equal(t, expectedFingerprint, mock.LastClaim(t).GetSshKeyFingerprint())
173173
})
174174

175175
t.Run("falls back to default", func(t *testing.T) {

‎internal/topology/client.go‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,9 @@ func (c *Client) Classify(ctx context.Context, claim *types_proto.Claim) (resp *
9898
ctx, cancel := context.WithTimeout(ctx, c.config.Timeout)
9999
defer cancel()
100100

101+
// GitLab Shell resolves one claim per lookup.
101102
req := &pb.ClassifyRequest{
102-
ClassificationKey: &pb.ClassifyRequest_Claim{
103-
Claim: claim,
104-
},
103+
Claims: []*types_proto.Claim{claim},
105104
}
106105

107106
resp, err = client.Classify(ctx, req)

‎internal/topology/client_test.go‎

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ import (
1414
"github.com/prometheus/client_golang/prometheus/testutil"
1515
"github.com/stretchr/testify/require"
1616
pb "gitlab.com/gitlab-org/cells/topology-service/clients/go/proto"
17+
types_proto "gitlab.com/gitlab-org/cells/topology-service/clients/go/proto/types/v1"
1718
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics"
1819
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper"
1920
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/topology/topologytest"
2021
"gitlab.com/gitlab-org/labkit/correlation"
2122
"google.golang.org/grpc"
23+
"google.golang.org/protobuf/proto"
2224
)
2325

2426
const localhostAddr = "localhost:9090"
@@ -128,11 +130,7 @@ func TestClient_Classify(t *testing.T) {
128130
require.Equal(t, pb.ClassifyAction_PROXY, result.GetAction())
129131
require.Equal(t, "cell-1.gitlab.com:443", result.GetProxy().GetAddress())
130132

131-
// Verify the request was constructed correctly
132-
require.NotNil(t, mock.LastRequest.GetClassificationKey())
133-
require.Equal(t, "my-group/my-project", mock.LastRequest.GetClaim().GetRoute())
134-
require.Equal(t, pb.ClassifyType_UNSPECIFIED, mock.LastRequest.GetType())
135-
require.Empty(t, mock.LastRequest.GetValue())
133+
require.Equal(t, "my-group/my-project", mock.LastClaim(t).GetRoute())
136134
})
137135

138136
t.Run("successful SSH key claim returns proxy info", func(t *testing.T) {
@@ -152,7 +150,7 @@ func TestClient_Classify(t *testing.T) {
152150

153151
require.NoError(t, err)
154152
require.Equal(t, pb.ClassifyAction_PROXY, result.GetAction())
155-
require.Equal(t, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ", mock.LastRequest.GetClaim().GetSshKey())
153+
require.Equal(t, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ", mock.LastClaim(t).GetSshKey())
156154
})
157155

158156
t.Run("successful project ID claim returns proxy info", func(t *testing.T) {
@@ -172,7 +170,46 @@ func TestClient_Classify(t *testing.T) {
172170

173171
require.NoError(t, err)
174172
require.Equal(t, pb.ClassifyAction_PROXY, result.GetAction())
175-
require.Equal(t, int64(42), mock.LastRequest.GetClaim().GetProjectId())
173+
require.Equal(t, int64(42), mock.LastClaim(t).GetProjectId())
174+
})
175+
176+
t.Run("sends the claim via the claims chain, not type/value", func(t *testing.T) {
177+
mock := &topologytest.MockClassifyServer{}
178+
addr, stop := topologytest.StartMockServer(t, mock)
179+
defer stop()
180+
181+
client := NewClient(&Config{
182+
Enabled: true,
183+
Address: addr,
184+
Timeout: 5 * time.Second,
185+
})
186+
defer client.Close()
187+
188+
tests := []struct {
189+
name string
190+
claim *types_proto.Claim
191+
}{
192+
{name: "route", claim: RouteClaim("my-group")},
193+
{name: "ssh_key", claim: SSHKeyClaim("ssh-rsa AAAAB3")},
194+
{name: "ssh_fingerprint", claim: SSHFingerprintClaim("W3THTJOKxMaZp0VIOrjVSBVDnFjyzVSMFGMLmSPcaGo")},
195+
{name: "project_id", claim: ProjectIDClaim(42)},
196+
{name: "username", claim: UsernameClaim("jane.doe")},
197+
}
198+
199+
for _, tt := range tests {
200+
t.Run(tt.name, func(t *testing.T) {
201+
_, err := client.Classify(ctx, tt.claim)
202+
require.NoError(t, err)
203+
204+
claims := mock.LastRequest.GetClaims()
205+
require.Len(t, claims, 1)
206+
require.True(t, proto.Equal(tt.claim, claims[0]),
207+
"claim must be sent unmodified in the claims chain")
208+
209+
require.Equal(t, pb.ClassifyType_UNSPECIFIED, mock.LastRequest.GetType())
210+
require.Empty(t, mock.LastRequest.GetValue())
211+
})
212+
}
176213
})
177214

178215
t.Run("server error is propagated", func(t *testing.T) {

‎internal/topology/resolver_test.go‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ func TestResolveByRoute(t *testing.T) {
320320
require.Equal(t, "http://cell-1:8080", result)
321321

322322
// Verify the claim sent to the server used just the top-level namespace
323-
require.Equal(t, groupNamespace, mock.LastRequest.GetClaim().GetRoute())
323+
require.Equal(t, groupNamespace, mock.LastClaim(t).GetRoute())
324324
})
325325

326326
t.Run("empty repo path returns empty string", func(t *testing.T) {
@@ -497,7 +497,7 @@ func TestResolveBySSHKey(t *testing.T) {
497497
require.Equal(t, "http://cell-2:8080", result)
498498

499499
// Verify the claim sent to the server used the SSH key
500-
require.Equal(t, "ssh-rsa AAAAB3...", mock.LastRequest.GetClaim().GetSshKey())
500+
require.Equal(t, "ssh-rsa AAAAB3...", mock.LastClaim(t).GetSshKey())
501501
})
502502

503503
t.Run("empty key returns empty string", func(t *testing.T) {
@@ -557,7 +557,7 @@ func TestResolveBySSHFingerprint(t *testing.T) {
557557
result := resolver.resolveBySSHFingerprint(context.Background(), "W3THTJOKxMaZp0VIOrjVSBVDnFjyzVSMFGMLmSPcaGo")
558558
require.Equal(t, "http://cell-2:8080", result)
559559

560-
require.Equal(t, "W3THTJOKxMaZp0VIOrjVSBVDnFjyzVSMFGMLmSPcaGo", mock.LastRequest.GetClaim().GetSshKeyFingerprint())
560+
require.Equal(t, "W3THTJOKxMaZp0VIOrjVSBVDnFjyzVSMFGMLmSPcaGo", mock.LastClaim(t).GetSshKeyFingerprint())
561561
})
562562

563563
t.Run("empty fingerprint returns empty string", func(t *testing.T) {
@@ -618,7 +618,7 @@ func TestResolveByUserArgs(t *testing.T) {
618618
require.Equal(t, "http://cell-2:8080", result)
619619

620620
// Verify the claim sent to the server used the username
621-
require.Equal(t, janeDoe, mock.LastRequest.GetClaim().GetUsername())
621+
require.Equal(t, janeDoe, mock.LastClaim(t).GetUsername())
622622
})
623623

624624
fallbackTests := []struct {

‎internal/topology/topologytest/mock_server.go‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/stretchr/testify/require"
1414
pb "gitlab.com/gitlab-org/cells/topology-service/clients/go/proto"
15+
types_proto "gitlab.com/gitlab-org/cells/topology-service/clients/go/proto/types/v1"
1516
"google.golang.org/grpc"
1617
)
1718

@@ -34,6 +35,15 @@ type MockClassifyServer struct {
3435
ErrUntilAttempt int
3536
}
3637

38+
// LastClaim returns the first claim from the most recent request.
39+
func (m *MockClassifyServer) LastClaim(t *testing.T) *types_proto.Claim {
40+
t.Helper()
41+
require.NotNil(t, m.LastRequest)
42+
require.NotEmpty(t, m.LastRequest.GetClaims())
43+
44+
return m.LastRequest.GetClaims()[0]
45+
}
46+
3747
// Classify implements the ClassifyService RPC.
3848
func (m *MockClassifyServer) Classify(_ context.Context, req *pb.ClassifyRequest) (*pb.ClassifyResponse, error) {
3949
m.CallCount++

0 commit comments

Comments
 (0)