Skip to content

Commit 4dd7652

Browse files
committed
Pass flags, add tests, cleanup and polish
1 parent dc8c349 commit 4dd7652

File tree

14 files changed

+777
-113
lines changed

14 files changed

+777
-113
lines changed

cmd/consul-dataplane/main.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ var (
3232
adminBindPort int
3333
readyBindAddr string
3434
readyBindPort int
35+
36+
xdsBindAddr string
37+
xdsBindPort int
3538
)
3639

3740
func init() {
@@ -63,6 +66,9 @@ func init() {
6366
flag.IntVar(&adminBindPort, "envoy-admin-bind-port", 19000, "The port on which the Envoy admin server will be available.")
6467
flag.StringVar(&readyBindAddr, "envoy-ready-bind-address", "", "The address on which Envoy's readiness probe will be available.")
6568
flag.IntVar(&readyBindPort, "envoy-ready-bind-port", 0, "The port on which Envoy's readiness probe will be available.")
69+
70+
flag.StringVar(&xdsBindAddr, "xds-bind-addr", "127.0.0.1", "The address on which the envoy xDS server will be available.")
71+
flag.IntVar(&xdsBindPort, "xds-bind-port", 0, "The port on which the envoy xDS server will be available.")
6672
}
6773

6874
// validateFlags performs semantic validation of the flag values
@@ -111,6 +117,10 @@ func main() {
111117
ReadyBindAddress: readyBindAddr,
112118
ReadyBindPort: readyBindPort,
113119
},
120+
XDSServer: &consuldp.XDSServer{
121+
BindAddress: xdsBindAddr,
122+
BindPort: xdsBindPort,
123+
},
114124
}
115125
consuldpInstance, err := consuldp.NewConsulDP(consuldpCfg)
116126
if err != nil {

pkg/consuldp/bootstrap.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ const (
2525

2626
// bootstrapConfig generates the Envoy bootstrap config in JSON format.
2727
func (cdp *ConsulDataplane) bootstrapConfig(ctx context.Context) ([]byte, error) {
28-
cdpGRPCFullAddr := strings.Split(cdp.gRPCServer.listener.Addr().String(), ":")
29-
cdpGRPCAddr := cdpGRPCFullAddr[0]
30-
cdpGRPCPort := cdpGRPCFullAddr[1]
3128
svc := cdp.cfg.Service
3229
envoy := cdp.cfg.Envoy
3330

@@ -54,8 +51,8 @@ func (cdp *ConsulDataplane) bootstrapConfig(ctx context.Context) ([]byte, error)
5451

5552
args := &bootstrap.BootstrapTplArgs{
5653
GRPC: bootstrap.GRPC{
57-
AgentAddress: cdpGRPCAddr,
58-
AgentPort: cdpGRPCPort,
54+
AgentAddress: cdp.cfg.XDSServer.BindAddress,
55+
AgentPort: strconv.Itoa(cdp.cfg.XDSServer.BindPort),
5956
AgentTLS: false,
6057
},
6158
ProxyCluster: rsp.Service,
@@ -66,11 +63,19 @@ func (cdp *ConsulDataplane) bootstrapConfig(ctx context.Context) ([]byte, error)
6663
AdminBindAddress: envoy.AdminBindAddress,
6764
AdminBindPort: strconv.Itoa(envoy.AdminBindPort),
6865
LocalAgentClusterName: localClusterName,
69-
// TODO(NET-148): Support login via an ACL auth-method.
70-
Token: cdp.cfg.Consul.Credentials.Static.Token,
71-
Namespace: rsp.Namespace,
72-
Partition: rsp.Partition,
73-
Datacenter: rsp.Datacenter,
66+
Namespace: rsp.Namespace,
67+
Partition: rsp.Partition,
68+
Datacenter: rsp.Datacenter,
69+
}
70+
71+
if cdp.localXDSServer != nil && cdp.localXDSServer.enabled {
72+
if cdp.localXDSServer.listenerNetwork == "unix" {
73+
args.GRPC.AgentSocket = cdp.localXDSServer.listenerAddress
74+
} else {
75+
xdsServerFullAddr := strings.Split(cdp.localXDSServer.listenerAddress, ":")
76+
args.GRPC.AgentAddress = xdsServerFullAddr[0]
77+
args.GRPC.AgentPort = xdsServerFullAddr[1]
78+
}
7479
}
7580

7681
var bootstrapConfig bootstrap.BootstrapConfig

pkg/consuldp/bootstrap_test.go

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import (
44
"bytes"
55
"context"
66
"flag"
7-
"net"
7+
"fmt"
88
"os"
99
"os/exec"
1010
"path/filepath"
11+
"strings"
1112
"testing"
1213

1314
"github.com/stretchr/testify/mock"
@@ -24,8 +25,9 @@ var (
2425

2526
func TestBootstrapConfig(t *testing.T) {
2627
const (
27-
serverAddr = "1.2.3.4"
28-
nodeName = "agentless-node"
28+
nodeName = "agentless-node"
29+
xdsBindPort = 1234
30+
socketPath = "/var/run/xds.sock"
2931
)
3032

3133
makeStruct := func(kv map[string]any) *structpb.Struct {
@@ -42,11 +44,6 @@ func TestBootstrapConfig(t *testing.T) {
4244
&Config{
4345
Consul: &ConsulConfig{
4446
GRPCPort: 1234,
45-
Credentials: &CredentialsConfig{
46-
Static: &StaticCredentialsConfig{
47-
Token: "some-acl-token",
48-
},
49-
},
5047
},
5148
Service: &ServiceConfig{
5249
ServiceID: "web-proxy",
@@ -59,6 +56,7 @@ func TestBootstrapConfig(t *testing.T) {
5956
Telemetry: &TelemetryConfig{
6057
UseCentralConfig: false,
6158
},
59+
XDSServer: &XDSServer{BindAddress: "1.2.3.4", BindPort: xdsBindPort},
6260
},
6361
&pbdataplane.GetEnvoyBootstrapParamsResponse{
6462
Service: "web",
@@ -72,11 +70,6 @@ func TestBootstrapConfig(t *testing.T) {
7270
&Config{
7371
Consul: &ConsulConfig{
7472
GRPCPort: 1234,
75-
Credentials: &CredentialsConfig{
76-
Static: &StaticCredentialsConfig{
77-
Token: "some-acl-token",
78-
},
79-
},
8073
},
8174
Service: &ServiceConfig{
8275
ServiceID: "web-proxy",
@@ -89,6 +82,7 @@ func TestBootstrapConfig(t *testing.T) {
8982
Telemetry: &TelemetryConfig{
9083
UseCentralConfig: true,
9184
},
85+
XDSServer: &XDSServer{BindAddress: "1.2.3.4", BindPort: xdsBindPort},
9286
},
9387
&pbdataplane.GetEnvoyBootstrapParamsResponse{
9488
Service: "web",
@@ -102,11 +96,6 @@ func TestBootstrapConfig(t *testing.T) {
10296
&Config{
10397
Consul: &ConsulConfig{
10498
GRPCPort: 1234,
105-
Credentials: &CredentialsConfig{
106-
Static: &StaticCredentialsConfig{
107-
Token: "some-acl-token",
108-
},
109-
},
11099
},
111100
Service: &ServiceConfig{
112101
ServiceID: "web-proxy",
@@ -121,12 +110,65 @@ func TestBootstrapConfig(t *testing.T) {
121110
Telemetry: &TelemetryConfig{
122111
UseCentralConfig: false,
123112
},
113+
XDSServer: &XDSServer{BindAddress: "1.2.3.4", BindPort: xdsBindPort},
124114
},
125115
&pbdataplane.GetEnvoyBootstrapParamsResponse{
126116
Service: "web",
127117
NodeName: nodeName,
128118
},
129119
},
120+
"local-xds-server": {
121+
&Config{
122+
Consul: &ConsulConfig{
123+
GRPCPort: 1234,
124+
},
125+
Service: &ServiceConfig{
126+
ServiceID: "web-proxy",
127+
NodeName: nodeName,
128+
},
129+
Envoy: &EnvoyConfig{
130+
AdminBindAddress: "127.0.0.1",
131+
AdminBindPort: 19000,
132+
},
133+
Telemetry: &TelemetryConfig{
134+
UseCentralConfig: false,
135+
},
136+
XDSServer: &XDSServer{BindAddress: "127.0.0.1", BindPort: xdsBindPort},
137+
},
138+
&pbdataplane.GetEnvoyBootstrapParamsResponse{
139+
Service: "web",
140+
NodeName: nodeName,
141+
Config: makeStruct(map[string]any{
142+
"envoy_dogstatsd_url": "this-should-not-appear-in-generated-config",
143+
}),
144+
},
145+
},
146+
"local-unix-socket-xds-server": {
147+
&Config{
148+
Consul: &ConsulConfig{
149+
GRPCPort: 1234,
150+
},
151+
Service: &ServiceConfig{
152+
ServiceID: "web-proxy",
153+
NodeName: nodeName,
154+
},
155+
Envoy: &EnvoyConfig{
156+
AdminBindAddress: "127.0.0.1",
157+
AdminBindPort: 19000,
158+
},
159+
Telemetry: &TelemetryConfig{
160+
UseCentralConfig: false,
161+
},
162+
XDSServer: &XDSServer{BindAddress: fmt.Sprintf("unix://%s", socketPath)},
163+
},
164+
&pbdataplane.GetEnvoyBootstrapParamsResponse{
165+
Service: "web",
166+
NodeName: nodeName,
167+
Config: makeStruct(map[string]any{
168+
"envoy_dogstatsd_url": "this-should-not-appear-in-generated-config",
169+
}),
170+
},
171+
},
130172
}
131173
for desc, tc := range testCases {
132174
t.Run(desc, func(t *testing.T) {
@@ -144,7 +186,14 @@ func TestBootstrapConfig(t *testing.T) {
144186
dp := &ConsulDataplane{
145187
cfg: tc.cfg,
146188
dpServiceClient: client,
147-
consulServer: &consulServer{address: net.IPAddr{IP: net.ParseIP(serverAddr)}},
189+
}
190+
191+
if checkLocalXDSServer(tc.cfg.XDSServer.BindAddress) {
192+
if strings.HasPrefix(tc.cfg.XDSServer.BindAddress, "unix://") {
193+
dp.localXDSServer = &localXDSServer{enabled: true, listenerAddress: socketPath, listenerNetwork: "unix"}
194+
} else {
195+
dp.localXDSServer = &localXDSServer{enabled: true, listenerAddress: fmt.Sprintf("127.0.0.1:%d", xdsBindPort)}
196+
}
148197
}
149198

150199
bsCfg, err := dp.bootstrapConfig(ctx)

pkg/consuldp/config.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ type EnvoyConfig struct {
7676
ReadyBindPort int
7777
}
7878

79+
//
80+
type XDSServer struct {
81+
// BindAddress is the address on which the Envoy xDS server will be available.
82+
BindAddress string
83+
// BindPort is the address on which the Envoy xDS port will be available.
84+
BindPort int
85+
}
86+
7987
// Config is the configuration used by consul-dataplane, consolidated
8088
// from various sources - CLI flags, env vars, config file settings.
8189
type Config struct {
@@ -84,4 +92,5 @@ type Config struct {
8492
Logging *LoggingConfig
8593
Telemetry *TelemetryConfig
8694
Envoy *EnvoyConfig
95+
XDSServer *XDSServer
8796
}

pkg/consuldp/consul_dataplane.go

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"math/rand"
88
"net"
9+
"strings"
910
"time"
1011

1112
"github.com/hashicorp/go-hclog"
@@ -29,10 +30,13 @@ type consulServer struct {
2930
grpcClientConn *grpc.ClientConn
3031
}
3132

32-
type gRPCServer struct {
33-
listener net.Listener
34-
server *grpc.Server
35-
exitedCh chan struct{}
33+
type localXDSServer struct {
34+
enabled bool
35+
listener net.Listener
36+
listenerAddress string
37+
listenerNetwork string
38+
gRPCServer *grpc.Server
39+
exitedCh chan struct{}
3640
}
3741

3842
// ConsulDataplane represents the consul-dataplane process
@@ -41,7 +45,7 @@ type ConsulDataplane struct {
4145
cfg *Config
4246
consulServer *consulServer
4347
dpServiceClient pbdataplane.DataplaneServiceClient
44-
gRPCServer *gRPCServer
48+
localXDSServer *localXDSServer
4549
}
4650

4751
// NewConsulDP creates a new instance of ConsulDataplane
@@ -61,8 +65,9 @@ func NewConsulDP(cfg *Config) (*ConsulDataplane, error) {
6165
})
6266

6367
return &ConsulDataplane{
64-
logger: logger,
65-
cfg: cfg,
68+
logger: logger,
69+
cfg: cfg,
70+
localXDSServer: &localXDSServer{enabled: false},
6671
}, nil
6772
}
6873

@@ -86,6 +91,10 @@ func validateConfig(cfg *Config) error {
8691
return errors.New("envoy admin bind port not specified")
8792
case cfg.Logging == nil:
8893
return errors.New("logging settings not specified")
94+
case cfg.XDSServer.BindAddress == "":
95+
return errors.New("envoy xDS bind address not specified")
96+
case cfg.XDSServer.BindPort == 0 && !checkLocalXDSServer(cfg.XDSServer.BindAddress):
97+
return errors.New("envoy xDS bind port not specified")
8998
}
9099
return nil
91100
}
@@ -124,6 +133,28 @@ func (cdp *ConsulDataplane) setConsulServerSupportedFeatures(ctx context.Context
124133
return nil
125134
}
126135

136+
// checkLocalXDSServer checks if the specified xds bind address is local.
137+
func checkLocalXDSServer(xdsBindAddr string) bool {
138+
if strings.HasPrefix(xdsBindAddr, "unix://") || xdsBindAddr == "127.0.0.1" || xdsBindAddr == "localhost" {
139+
return true
140+
}
141+
return false
142+
}
143+
144+
// checkAndEnableLocalXDSServer checks if the specified xds bind address is local.
145+
// If local, it enables the flag to configure consul-dataplane (later on in the setup process)
146+
// with a gRPC server to serve envoy xDS requests.
147+
// If not local, the flag remains turned off and it is assumed the xDS requests will be served
148+
// by a remote gRPC server.
149+
// Potential TODO: Explicitly allow specifying an option (xds.disable?) to disable configuring
150+
// consul-dataplane as the xDS server in case xDS requests can be served on another port locally
151+
// (example: consul server process on localhost).
152+
func (cdp *ConsulDataplane) checkAndEnableLocalXDSServer() {
153+
if checkLocalXDSServer(cdp.cfg.XDSServer.BindAddress) {
154+
cdp.localXDSServer.enabled = true
155+
}
156+
}
157+
127158
func (cdp *ConsulDataplane) Run(ctx context.Context) error {
128159
cdp.logger.Info("started consul-dataplane process")
129160

@@ -156,11 +187,16 @@ func (cdp *ConsulDataplane) Run(ctx context.Context) error {
156187
return fmt.Errorf("failed to set supported features: %w", err)
157188
}
158189

159-
err = cdp.setupGRPCServer()
160-
if err != nil {
161-
return err
190+
cdp.checkAndEnableLocalXDSServer()
191+
192+
if cdp.localXDSServer.enabled {
193+
err = cdp.setupXDSServer()
194+
if err != nil {
195+
return err
196+
}
197+
go cdp.startXDSServer()
198+
defer cdp.stopXDSServer()
162199
}
163-
go cdp.startGRPCServer()
164200

165201
cfg, err := cdp.bootstrapConfig(ctx)
166202
if err != nil {
@@ -190,16 +226,14 @@ func (cdp *ConsulDataplane) Run(ctx context.Context) error {
190226
if err := proxy.Stop(); err != nil {
191227
cdp.logger.Error("failed to stop proxy", "error", err)
192228
}
193-
cdp.stopGRPCServer()
194229
doneCh <- nil
195230
case <-proxy.Exited():
196-
cdp.stopGRPCServer()
197231
doneCh <- errors.New("envoy proxy exited unexpectedly")
198-
case <-cdp.gRPCServerExited():
232+
case <-cdp.xdsServerExited():
199233
if err := proxy.Stop(); err != nil {
200234
cdp.logger.Error("failed to stop proxy", "error", err)
201235
}
202-
doneCh <- errors.New("gRPC server exited unexpectedly")
236+
doneCh <- errors.New("xDS server exited unexpectedly")
203237
}
204238
}()
205239
return <-doneCh

0 commit comments

Comments
 (0)