Skip to content

Commit

Permalink
Issue #179: TCP Proxy Support
Browse files Browse the repository at this point in the history
Changes for 1.4beta2

* Advertise routes with 'tcp://' URL
* Update integration test for 'tcp://' URLs
* Filter urlprefix- tags from generated route commands
* Allow demo server to register additional tags
* Update UI to show TCP and HTTP routes correctly
* Update UI to limit weights to two decimal points
  • Loading branch information
magiconair committed Mar 25, 2017
1 parent a4d7342 commit 08261e4
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 15 deletions.
8 changes: 3 additions & 5 deletions admin/ui/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ $(function(){
var tbl = '<thead><tr>';
tbl += '<th>#</th>';
tbl += '<th>Service</th>';
tbl += '<th>Host</th>';
tbl += '<th>Path</th>';
tbl += '<th>Source</th>';
tbl += '<th>Dest</th>';
tbl += '<th>Weight</th>';
tbl += '</tr></thead><tbody>'
Expand All @@ -86,10 +85,9 @@ $(function(){
tbl += '<tr>';
tbl += '<td>' + (i+1) + '</td>';
tbl += '<td>' + r.service + '</td>';
tbl += '<td>' + r.host + '</td>';
tbl += '<td>' + r.path + '</td>';
tbl += '<td>' + r.src + '</td>';
tbl += '<td>' + r.dst + '</td>';
tbl += '<td>' + r.weight * 100 + '%</td>';
tbl += '<td>' + (r.weight * 100).toFixed(2) + '%</td>';
tbl += '</tr>';
}
tbl += '</tbody>';
Expand Down
7 changes: 4 additions & 3 deletions demo/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,15 @@ func (s *TCPServer) Tags() []string {
}

func main() {
var addr, consul, name, prefix, proto, token string
var addr, consul, name, prefix, proto, token, rawtags string
var certFile, keyFile string
var status int
flag.StringVar(&addr, "addr", "127.0.0.1:5000", "host:port of the service")
flag.StringVar(&consul, "consul", "127.0.0.1:8500", "host:port of the consul agent")
flag.StringVar(&name, "name", filepath.Base(os.Args[0]), "name of the service")
flag.StringVar(&prefix, "prefix", "", "comma-sep list of 'host/path' or ':port' prefixes to register")
flag.StringVar(&proto, "proto", "http", "protocol for endpoints: http, ws or tcp")
flag.StringVar(&rawtags, "tags", "", "additional tags to register in consul")
flag.StringVar(&token, "token", "", "consul ACL token")
flag.StringVar(&certFile, "cert", "", "path to cert file")
flag.StringVar(&keyFile, "key", "", "path to key file")
Expand All @@ -118,7 +119,7 @@ func main() {
log.Printf("%s -> 404", r.URL)
})

var tags []string
tags := strings.Split(rawtags, ",")
for _, p := range strings.Split(prefix, ",") {
tags = append(tags, "urlprefix-"+p)
switch proto {
Expand All @@ -141,7 +142,7 @@ func main() {
srv = &HTTPServer{&http.Server{Addr: addr, Handler: mux}, tags, check}

case "tcp":
var tags []string
tags := strings.Split(rawtags, ",")
for _, p := range strings.Split(prefix, ",") {
tags = append(tags, "urlprefix-"+p+" proto=tcp")
}
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import (
// It is also set by the linker when fabio
// is built via the Makefile or the build/docker.sh
// script to ensure the correct version nubmer
var version = "1.4beta1"
var version = "1.4beta2"

var shuttingDown int32

Expand Down
7 changes: 6 additions & 1 deletion proxy/tcp_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/eBay/fabio/proxy/internal"
"github.com/eBay/fabio/proxy/tcp"
"github.com/eBay/fabio/proxy/tcp/tcptest"
"github.com/eBay/fabio/route"
)

var echoHandler tcp.HandlerFunc = func(c net.Conn) error {
Expand All @@ -33,7 +34,11 @@ func TestTCPProxy(t *testing.T) {
proxyAddr := "127.0.0.1:57778"
go func() {
h := &tcp.Proxy{
Lookup: func(string) string { return srv.Addr },
Lookup: func(h string) string {
tbl, _ := route.NewTable("route add srv :57778 tcp://" + srv.Addr)
t := tbl.LookupHost(h, route.Picker["rr"])
return t.URL.Host
},
}
l := config.Listen{Addr: proxyAddr}
if err := ListenAndServeTCP(l, h); err != nil {
Expand Down
23 changes: 20 additions & 3 deletions registry/consul/service.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package consul

import (
"fmt"
"log"
"net"
"runtime"
Expand Down Expand Up @@ -89,6 +88,15 @@ func serviceConfig(client *api.Client, name string, passing map[string]bool, tag
continue
}

// get all tags which do not have the tag prefix
var svctags []string
for _, tag := range svc.ServiceTags {
if !strings.HasPrefix(tag, tagPrefix) {
svctags = append(svctags, tag)
}
}

// generate route commands
for _, tag := range svc.ServiceTags {
if route, opts, ok := parseURLPrefixTag(tag, tagPrefix, env); ok {
name, addr, port := svc.ServiceName, svc.ServiceAddress, svc.ServicePort
Expand All @@ -103,11 +111,20 @@ func serviceConfig(client *api.Client, name string, passing map[string]bool, tag
addr += ".local"
}

// build route command
addr = net.JoinHostPort(addr, strconv.Itoa(port))
dst := "http://" + addr + "/"
if strings.Contains(opts, "proto=tcp") {
dst = "tcp://" + addr
}
tags := strings.Join(svctags, ",")

cfg := fmt.Sprintf("route add %s %s http://%s/ tags %q", name, route, addr, strings.Join(svc.ServiceTags, ","))
cfg := "route add " + name + " " + route + " " + dst
if tags != "" {
cfg += " tags " + strconv.Quote(tags)
}
if opts != "" {
cfg += ` opts "` + opts + `"`
cfg += " opts " + strconv.Quote(opts)
}
config = append(config, cfg)
}
Expand Down
15 changes: 15 additions & 0 deletions route/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ func TestParse(t *testing.T) {
in: `route add svc /prefix http://1.2.3.4/`,
out: []*RouteDef{{Cmd: RouteAddCmd, Service: "svc", Src: "/prefix", Dst: "http://1.2.3.4/"}},
},
{
desc: "RouteAddTCPService",
in: `route add svc :1234 tcp://1.2.3.4:5678`,
out: []*RouteDef{{Cmd: RouteAddCmd, Service: "svc", Src: ":1234", Dst: "tcp://1.2.3.4:5678"}},
},
{
desc: "RouteAddServiceWeight",
in: `route add svc /prefix http://1.2.3.4/ weight 1.2`,
Expand Down Expand Up @@ -96,11 +101,21 @@ func TestParse(t *testing.T) {
in: `route del svc /prefix`,
out: []*RouteDef{{Cmd: RouteDelCmd, Service: "svc", Src: "/prefix"}},
},
{
desc: "RouteDelTCPServiceSrc",
in: `route del svc :1234`,
out: []*RouteDef{{Cmd: RouteDelCmd, Service: "svc", Src: ":1234"}},
},
{
desc: "RouteDelServiceSrcDst",
in: `route del svc /prefix http://1.2.3.4/`,
out: []*RouteDef{{Cmd: RouteDelCmd, Service: "svc", Src: "/prefix", Dst: "http://1.2.3.4/"}},
},
{
desc: "RouteDelTCPServiceSrcDst",
in: `route del svc :1234 tcp://1.2.3.4:5678`,
out: []*RouteDef{{Cmd: RouteDelCmd, Service: "svc", Src: ":1234", Dst: "tcp://1.2.3.4:5678"}},
},
{
desc: "RouteDelServiceSrcDstMoreSpaces",
in: ` route del svc /prefix http://1.2.3.4/ `,
Expand Down
9 changes: 7 additions & 2 deletions route/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,14 @@ func syncRegistry(t Table) {
// by sorting the routes in reverse order by path.
type Table map[string]Routes

// hostpath splits a host/path prefix into a host and a path.
// The path always starts with a slash
// hostpath splits a 'host/path' prefix into 'host' and '/path' or it returns a
// ':port' prefix as ':port' and '' since there is no path component for TCP
// connections.
func hostpath(prefix string) (host string, path string) {
if strings.HasPrefix(prefix, ":") {
return prefix, ""
}

p := strings.SplitN(prefix, "/", 2)
host, path = p[0], ""
if len(p) == 1 {
Expand Down

0 comments on commit 08261e4

Please sign in to comment.