Skip to content

Commit 3543703

Browse files
committed
connect reverse_proxy transport to global node config
allow specifying a node name when configuring the tailscale transport, which is used to lookup config values from the global tailscale app. Also rename to just "Transport" and do some cleanup and simplification. Signed-off-by: Will Norris <will@tailscale.com>
1 parent 27fad94 commit 3543703

File tree

2 files changed

+51
-41
lines changed

2 files changed

+51
-41
lines changed

module.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
func init() {
2222
caddy.RegisterNetwork("tailscale", getPlainListener)
2323
caddy.RegisterNetwork("tailscale+tls", getTLSListener)
24-
caddy.RegisterModule(&TailscaleCaddyTransport{})
2524
}
2625

2726
func getPlainListener(c context.Context, _ string, addr string, _ net.ListenConfig) (any, error) {
@@ -211,8 +210,8 @@ func (t *tsnetServerListener) Close() error {
211210
return err
212211
}
213212

214-
// Decrement usage count of server for this hostname.
215-
// If usage reaches zero, then the server is actually shutdown.
213+
// Decrement usage count of this node.
214+
// If usage reaches zero, then the node is actually shutdown.
216215
_, err := nodes.Delete(t.name)
217216
return err
218217
}

transport.go

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,77 @@
11
package tscaddy
22

3-
// transport.go contains the TailscaleCaddyTransport module.
3+
// transport.go contains the Transport module.
44

55
import (
6-
"fmt"
76
"net/http"
87

98
"github.com/caddyserver/caddy/v2"
109
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
11-
"go.uber.org/zap"
1210
)
1311

14-
// TailscaleCaddyTransport is a caddy transport that uses a tailscale node to make requests.
15-
type TailscaleCaddyTransport struct {
16-
logger *zap.Logger
17-
node *tailscaleNode
12+
func init() {
13+
caddy.RegisterModule(&Transport{})
1814
}
1915

20-
func (t *TailscaleCaddyTransport) CaddyModule() caddy.ModuleInfo {
21-
return caddy.ModuleInfo{
22-
ID: "http.reverse_proxy.transport.tailscale",
23-
New: func() caddy.Module {
24-
return new(TailscaleCaddyTransport)
25-
},
26-
}
27-
}
16+
// Transport is a caddy transport that uses a tailscale node to make requests.
17+
type Transport struct {
18+
Name string `json:"name,omitempty"`
2819

29-
func (t *TailscaleCaddyTransport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
30-
return nil
20+
node *tailscaleNode
3121
}
3222

33-
func (t *TailscaleCaddyTransport) Provision(ctx caddy.Context) error {
34-
t.logger = ctx.Logger()
35-
36-
// TODO(will): allow users to specify a node name used to lookup that node's config in TSApp.
37-
s, err := getNode(ctx, "caddy-tsnet-client")
38-
if err != nil {
39-
return err
23+
func (t *Transport) CaddyModule() caddy.ModuleInfo {
24+
return caddy.ModuleInfo{
25+
ID: "http.reverse_proxy.transport.tailscale",
26+
New: func() caddy.Module { return new(Transport) },
4027
}
28+
}
4129

42-
s.Ephemeral = true
43-
s.Logf = func(format string, args ...any) {
44-
t.logger.Debug(fmt.Sprintf(format, args))
45-
}
30+
// UnmarshalCaddyfile populates a Transport config from a caddyfile.
31+
//
32+
// We only support a single token identifying the name of a node in the TSApp config.
33+
// For example:
34+
//
35+
// reverse_proxy {
36+
// transport tailscale my-node
37+
// }
38+
//
39+
// If a node name is not specified, a default name is used.
40+
func (t *Transport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
41+
const defaultNodeName = "caddy-proxy"
4642

47-
if err := s.Start(); err != nil {
48-
return err
43+
d.Next() // skip transport name
44+
if d.NextArg() {
45+
t.Name = d.Val()
46+
} else {
47+
t.Name = defaultNodeName
4948
}
50-
t.node = s
5149

5250
return nil
5351
}
5452

55-
func (t *TailscaleCaddyTransport) RoundTrip(request *http.Request) (*http.Response, error) {
56-
if request.URL.Scheme == "" {
57-
request.URL.Scheme = "http"
53+
func (t *Transport) Provision(ctx caddy.Context) error {
54+
var err error
55+
t.node, err = getNode(ctx, t.Name)
56+
return err
57+
}
58+
59+
func (t *Transport) Cleanup() error {
60+
// Decrement usage count of this node.
61+
_, err := nodes.Delete(t.Name)
62+
return err
63+
}
64+
65+
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
66+
if req.URL.Scheme == "" {
67+
req.URL.Scheme = "http"
5868
}
59-
return t.node.HTTPClient().Transport.RoundTrip(request)
69+
return t.node.HTTPClient().Transport.RoundTrip(req)
6070
}
6171

6272
var (
63-
_ http.RoundTripper = (*TailscaleCaddyTransport)(nil)
64-
_ caddy.Provisioner = (*TailscaleCaddyTransport)(nil)
65-
_ caddyfile.Unmarshaler = (*TailscaleCaddyTransport)(nil)
73+
_ http.RoundTripper = (*Transport)(nil)
74+
_ caddy.Provisioner = (*Transport)(nil)
75+
_ caddy.CleanerUpper = (*Transport)(nil)
76+
_ caddyfile.Unmarshaler = (*Transport)(nil)
6677
)

0 commit comments

Comments
 (0)