Skip to content

Commit 4aa32dc

Browse files
wlwilliamxlidezhu
authored andcommitted
server: propagate TLS flags to tiflow options (#4083)
close #4082
1 parent 34d3c1a commit 4aa32dc

File tree

2 files changed

+53
-44
lines changed

2 files changed

+53
-44
lines changed

cmd/cdc/server/server.go

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -312,30 +312,48 @@ func isNewArchEnabled(o *options) bool {
312312
return newarch
313313
}
314314

315-
func runTiFlowServer(o *options, cmd *cobra.Command) error {
315+
func buildTiFlowServerOptions(o *options) (*tiflowServer.Options, error) {
316316
// Populate security credentials from CLI flags before marshaling to JSON.
317-
// In old architecture mode, complete() is not called, so we need to transfer
318-
// TLS credentials (--ca, --cert, --key) to serverConfig.Security here.
319-
// Without this, the Security struct is empty and tiflow uses HTTP instead of HTTPS.
317+
//
318+
// NOTE: When TiCDC runs in old architecture mode, it delegates to
319+
// `github.com/pingcap/tiflow/pkg/cmd/server` but *reuses TiCDC's cobra.Command*.
320+
// That means cobra flags are bound to TiCDC's `options` fields, not tiflow's.
321+
//
322+
// tiflow's `Options.complete()` treats TLS flags as "visited" and then reads
323+
// the values from `tiflowServer.Options.CaPath/CertPath/KeyPath`. If we don't
324+
// copy the TLS flag values into those fields, tiflow will see the TLS flags
325+
// as set but with empty values, overwrite `ServerConfig.Security` with empty,
326+
// and fail https PD endpoint validation.
320327
o.serverConfig.Security = o.getCredential()
321328

322329
cfgData, err := json.Marshal(o.serverConfig)
323330
if err != nil {
324-
return errors.Trace(err)
331+
return nil, errors.Trace(err)
325332
}
326333

327334
var oldCfg tiflowConfig.ServerConfig
328335
err = json.Unmarshal(cfgData, &oldCfg)
329336
if err != nil {
330-
return errors.Trace(err)
337+
return nil, errors.Trace(err)
331338
}
332339

333-
var oldOptions tiflowServer.Options
334-
oldOptions.ServerConfig = &oldCfg
335-
oldOptions.ServerPdAddr = strings.Join(o.pdEndpoints, ",")
336-
oldOptions.ServerConfigFilePath = o.serverConfigFilePath
340+
return &tiflowServer.Options{
341+
ServerConfig: &oldCfg,
342+
ServerPdAddr: strings.Join(o.pdEndpoints, ","),
343+
ServerConfigFilePath: o.serverConfigFilePath,
344+
CaPath: o.caPath,
345+
CertPath: o.certPath,
346+
KeyPath: o.keyPath,
347+
AllowedCertCN: o.allowedCertCN,
348+
}, nil
349+
}
337350

338-
return tiflowServer.Run(&oldOptions, cmd)
351+
func runTiFlowServer(o *options, cmd *cobra.Command) error {
352+
oldOptions, err := buildTiFlowServerOptions(o)
353+
if err != nil {
354+
return err
355+
}
356+
return tiflowServer.Run(oldOptions, cmd)
339357
}
340358

341359
// NewCmdServer creates the `server` command.

cmd/cdc/server/server_test.go

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,52 +14,43 @@
1414
package server
1515

1616
import (
17-
"encoding/json"
17+
"strings"
1818
"testing"
1919

20-
tiflowConfig "github.com/pingcap/tiflow/pkg/config"
2120
"github.com/stretchr/testify/require"
2221
)
2322

24-
func TestRunTiFlowServerPopulatesSecurityConfig(t *testing.T) {
25-
// This test verifies that TLS credentials from CLI flags are properly
26-
// transferred to serverConfig.Security before being passed to tiflow.
27-
// See https://github.com/pingcap/ticdc/issues/3718
28-
23+
func TestBuildTiFlowServerOptionsPropagatesTLSFlags(t *testing.T) {
24+
// Scenario: TiCDC runs in old architecture mode and delegates to tiflow's
25+
// server command, but reuses TiCDC's cobra.Command (flags are bound to TiCDC's
26+
// options, not tiflow's). If we don't copy TLS flags to tiflowServer.Options,
27+
// tiflow will see TLS flags as visited but with empty values, clear the
28+
// security config, and fail when PD endpoints are https.
2929
o := newOptions()
3030
o.caPath = "/path/to/ca.crt"
3131
o.certPath = "/path/to/server.crt"
3232
o.keyPath = "/path/to/server.key"
3333
o.allowedCertCN = "cn1,cn2"
34+
o.pdEndpoints = []string{"https://127.0.0.1:2379"}
3435

35-
// Verify that before calling getCredential, serverConfig.Security is empty
36-
require.Empty(t, o.serverConfig.Security.CAPath)
37-
require.Empty(t, o.serverConfig.Security.CertPath)
38-
require.Empty(t, o.serverConfig.Security.KeyPath)
39-
40-
// Simulate what runTiFlowServer does: populate Security from CLI flags
41-
o.serverConfig.Security = o.getCredential()
42-
43-
// Verify Security is now populated
44-
require.Equal(t, "/path/to/ca.crt", o.serverConfig.Security.CAPath)
45-
require.Equal(t, "/path/to/server.crt", o.serverConfig.Security.CertPath)
46-
require.Equal(t, "/path/to/server.key", o.serverConfig.Security.KeyPath)
47-
require.Equal(t, []string{"cn1", "cn2"}, o.serverConfig.Security.CertAllowedCN)
48-
49-
// Verify that JSON marshaling preserves the Security config
50-
cfgData, err := json.Marshal(o.serverConfig)
51-
require.NoError(t, err)
52-
53-
var oldCfg tiflowConfig.ServerConfig
54-
err = json.Unmarshal(cfgData, &oldCfg)
36+
oldOptions, err := buildTiFlowServerOptions(o)
5537
require.NoError(t, err)
5638

57-
// This is the critical assertion: tiflow's ServerConfig.Security
58-
// should have the TLS credentials after unmarshaling
59-
require.Equal(t, "/path/to/ca.crt", oldCfg.Security.CAPath)
60-
require.Equal(t, "/path/to/server.crt", oldCfg.Security.CertPath)
61-
require.Equal(t, "/path/to/server.key", oldCfg.Security.KeyPath)
62-
require.Equal(t, []string{"cn1", "cn2"}, oldCfg.Security.CertAllowedCN)
39+
// Ensure tiflow options carry TLS flags, so tiflow can rebuild credentials
40+
// regardless of cobra flag binding.
41+
require.Equal(t, "/path/to/ca.crt", oldOptions.CaPath)
42+
require.Equal(t, "/path/to/server.crt", oldOptions.CertPath)
43+
require.Equal(t, "/path/to/server.key", oldOptions.KeyPath)
44+
require.Equal(t, "cn1,cn2", oldOptions.AllowedCertCN)
45+
46+
// Ensure the converted tiflow ServerConfig also contains the TLS credential,
47+
// which is used for logging and downstream config consumers.
48+
require.Equal(t, "/path/to/ca.crt", oldOptions.ServerConfig.Security.CAPath)
49+
require.Equal(t, "/path/to/server.crt", oldOptions.ServerConfig.Security.CertPath)
50+
require.Equal(t, "/path/to/server.key", oldOptions.ServerConfig.Security.KeyPath)
51+
require.Equal(t, []string{"cn1", "cn2"}, oldOptions.ServerConfig.Security.CertAllowedCN)
52+
53+
require.Equal(t, strings.Join(o.pdEndpoints, ","), oldOptions.ServerPdAddr)
6354
}
6455

6556
func TestGetCredential(t *testing.T) {

0 commit comments

Comments
 (0)