Skip to content

Commit ec5a1c5

Browse files
MEDIUM: Add support for "mode tcp"
New frontends and backends only had support for using models.FrontendModeHTTP and models.BackendModeHTTP which limited them to "mode http" only. This commit adds support for "mode tcp" using both upstream and downstream specific configuration options. It defaults to http. To use add a "config" option within an upstream similar to the below example: Sample downstream service file for Redis { "service": { "name": "redis", "port": 6379, "connect": { "sidecar_service": { "proxy" : { "config": { "protocol" : "tcp" } } } } } } Sample upstream configuration: "upstreams": [{ "destination_name": "redis", "local_bind_port": 6379, "config": { "protocol" : "tcp" } }
1 parent 556c75e commit ec5a1c5

File tree

4 files changed

+36
-7
lines changed

4 files changed

+36
-7
lines changed

consul/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type Upstream struct {
1818
Service string
1919
LocalBindAddress string
2020
LocalBindPort int
21+
Protocol string
2122

2223
TLS
2324

@@ -47,6 +48,7 @@ func (n UpstreamNode) Equal(o UpstreamNode) bool {
4748
type Downstream struct {
4849
LocalBindAddress string
4950
LocalBindPort int
51+
Protocol string
5052
TargetAddress string
5153
TargetPort int
5254

consul/watcher.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type upstream struct {
2222
LocalBindPort int
2323
Service string
2424
Datacenter string
25+
Protocol string
2526
Nodes []*api.ServiceEntry
2627

2728
done bool
@@ -30,6 +31,7 @@ type upstream struct {
3031
type downstream struct {
3132
LocalBindAddress string
3233
LocalBindPort int
34+
Protocol string
3335
TargetAddress string
3436
TargetPort int
3537
}
@@ -109,6 +111,13 @@ func (w *Watcher) handleProxyChange(first bool, srv *api.AgentService) {
109111
w.downstream.LocalBindAddress = defaultDownstreamBindAddr
110112
w.downstream.LocalBindPort = srv.Port
111113
w.downstream.TargetAddress = defaultUpstreamBindAddr
114+
115+
if srv.Proxy != nil && srv.Proxy.Config != nil {
116+
if c, ok := srv.Proxy.Config["protocol"].(string); ok {
117+
w.downstream.Protocol = c
118+
}
119+
}
120+
112121
if srv.Connect != nil && srv.Connect.Proxy != nil && srv.Connect.Proxy.Config != nil {
113122
if b, ok := srv.Connect.Proxy.Config["bind_address"].(string); ok {
114123
w.downstream.LocalBindAddress = b
@@ -153,6 +162,10 @@ func (w *Watcher) startUpstream(up api.Upstream) {
153162
Datacenter: up.Datacenter,
154163
}
155164

165+
if up.Config["protocol"] != nil {
166+
u.Protocol = up.Config["protocol"].(string)
167+
}
168+
156169
w.lock.Lock()
157170
w.upstreams[up.DestinationName] = u
158171
w.lock.Unlock()
@@ -330,7 +343,7 @@ func (w *Watcher) genCfg() Config {
330343
LocalBindPort: w.downstream.LocalBindPort,
331344
TargetAddress: w.downstream.TargetAddress,
332345
TargetPort: w.downstream.TargetPort,
333-
346+
Protocol: w.downstream.Protocol,
334347
TLS: TLS{
335348
CAs: w.certCAs,
336349
Cert: w.leaf.Cert,
@@ -344,14 +357,13 @@ func (w *Watcher) genCfg() Config {
344357
Service: up.Service,
345358
LocalBindAddress: up.LocalBindAddress,
346359
LocalBindPort: up.LocalBindPort,
347-
360+
Protocol: up.Protocol,
348361
TLS: TLS{
349362
CAs: w.certCAs,
350363
Cert: w.leaf.Cert,
351364
Key: w.leaf.Key,
352365
},
353366
}
354-
355367
for _, s := range up.Nodes {
356368
serviceInstancesTotal++
357369
host := s.Service.Address

haproxy/state/downstream.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,26 @@ import (
1010
func generateDownstream(opts Options, certStore CertificateStore, cfg consul.Downstream, state State) (State, error) {
1111
feName := "front_downstream"
1212
beName := "back_downstream"
13+
feMode := models.FrontendModeHTTP
14+
beMode := models.BackendModeHTTP
1315

1416
caPath, crtPath, err := certStore.CertsPath(cfg.TLS)
1517
if err != nil {
1618
return state, err
1719
}
1820

21+
if cfg.Protocol != "" && cfg.Protocol == "tcp" {
22+
feMode = models.FrontendModeTCP
23+
beMode = models.BackendModeTCP
24+
}
25+
1926
// Main config
2027
fe := Frontend{
2128
Frontend: models.Frontend{
2229
Name: feName,
2330
DefaultBackend: beName,
2431
ClientTimeout: &clientTimeout,
25-
Mode: models.FrontendModeHTTP,
32+
Mode: feMode,
2633
Httplog: opts.LogRequests,
2734
},
2835
Bind: models.Bind{
@@ -73,7 +80,7 @@ func generateDownstream(opts Options, certStore CertificateStore, cfg consul.Dow
7380
Name: beName,
7481
ServerTimeout: &serverTimeout,
7582
ConnectTimeout: &connectTimeout,
76-
Mode: models.BackendModeHTTP,
83+
Mode: beMode,
7784
},
7885
Servers: []models.Server{
7986
models.Server{

haproxy/state/upstream.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,22 @@ import (
1010
func generateUpstream(opts Options, certStore CertificateStore, cfg consul.Upstream, oldState, newState State) (State, error) {
1111
feName := fmt.Sprintf("front_%s", cfg.Service)
1212
beName := fmt.Sprintf("back_%s", cfg.Service)
13+
feMode := models.FrontendModeHTTP
14+
beMode := models.BackendModeHTTP
1315

1416
fePort64 := int64(cfg.LocalBindPort)
17+
18+
if cfg.Protocol != "" && cfg.Protocol == "tcp" {
19+
feMode = models.FrontendModeTCP
20+
beMode = models.BackendModeTCP
21+
}
22+
1523
fe := Frontend{
1624
Frontend: models.Frontend{
1725
Name: feName,
1826
DefaultBackend: beName,
1927
ClientTimeout: &clientTimeout,
20-
Mode: models.FrontendModeHTTP,
28+
Mode: feMode,
2129
Httplog: opts.LogRequests,
2230
},
2331
Bind: models.Bind{
@@ -45,7 +53,7 @@ func generateUpstream(opts Options, certStore CertificateStore, cfg consul.Upstr
4553
Balance: &models.Balance{
4654
Algorithm: models.BalanceAlgorithmLeastconn,
4755
},
48-
Mode: models.BackendModeHTTP,
56+
Mode: beMode,
4957
},
5058
}
5159
if opts.LogRequests && opts.LogSocket != "" {

0 commit comments

Comments
 (0)