Skip to content

Commit e2a8302

Browse files
committed
TUN-5869: Add configuration endpoint in metrics server
1 parent 6eeaf4b commit e2a8302

File tree

13 files changed

+275
-96
lines changed

13 files changed

+275
-96
lines changed

cmd/cloudflared/proxydns/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func Run(c *cli.Context) error {
7373
log.Fatal().Err(err).Msg("Failed to open the metrics listener")
7474
}
7575

76-
go metrics.ServeMetrics(metricsListener, nil, nil, "", log)
76+
go metrics.ServeMetrics(metricsListener, nil, nil, "", nil, log)
7777

7878
listener, err := tunneldns.CreateListener(
7979
c.String("address"),

cmd/cloudflared/tunnel/cmd.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,11 @@ func StartServer(
340340
return err
341341
}
342342

343+
orchestrator, err := orchestration.NewOrchestrator(ctx, dynamicConfig, tunnelConfig.Tags, tunnelConfig.Log)
344+
if err != nil {
345+
return err
346+
}
347+
343348
metricsListener, err := listeners.Listen("tcp", c.String("metrics"))
344349
if err != nil {
345350
log.Err(err).Msg("Error opening metrics server listener")
@@ -351,14 +356,9 @@ func StartServer(
351356
defer wg.Done()
352357
readinessServer := metrics.NewReadyServer(log)
353358
observer.RegisterSink(readinessServer)
354-
errC <- metrics.ServeMetrics(metricsListener, ctx.Done(), readinessServer, quickTunnelURL, log)
359+
errC <- metrics.ServeMetrics(metricsListener, ctx.Done(), readinessServer, quickTunnelURL, orchestrator, log)
355360
}()
356361

357-
orchestrator, err := orchestration.NewOrchestrator(ctx, dynamicConfig, tunnelConfig.Tags, tunnelConfig.Log)
358-
if err != nil {
359-
return err
360-
}
361-
362362
reconnectCh := make(chan supervisor.ReconnectSignal, 1)
363363
if c.IsSet("stdin-control") {
364364
log.Info().Msg("Enabling control through stdin")

config/configuration.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ type CustomDuration struct {
411411
time.Duration
412412
}
413413

414-
func (s *CustomDuration) MarshalJSON() ([]byte, error) {
414+
func (s CustomDuration) MarshalJSON() ([]byte, error) {
415415
return json.Marshal(s.Duration.Seconds())
416416
}
417417

ingress/config.go

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ import (
1111
"github.com/cloudflare/cloudflared/tlsconfig"
1212
)
1313

14-
const (
15-
defaultConnectTimeout = 30 * time.Second
16-
defaultTLSTimeout = 10 * time.Second
17-
defaultTCPKeepAlive = 30 * time.Second
18-
defaultKeepAliveConnections = 100
19-
defaultKeepAliveTimeout = 90 * time.Second
20-
defaultProxyAddress = "127.0.0.1"
14+
var (
15+
defaultConnectTimeout = config.CustomDuration{Duration: 30 * time.Second}
16+
defaultTLSTimeout = config.CustomDuration{Duration: 10 * time.Second}
17+
defaultTCPKeepAlive = config.CustomDuration{Duration: 30 * time.Second}
18+
defaultKeepAliveTimeout = config.CustomDuration{Duration: 90 * time.Second}
19+
)
2120

21+
const (
22+
defaultProxyAddress = "127.0.0.1"
23+
defaultKeepAliveConnections = 100
2224
SSHServerFlag = "ssh-server"
2325
Socks5Flag = "socks5"
2426
ProxyConnectTimeoutFlag = "proxy-connect-timeout"
@@ -68,12 +70,12 @@ func (rc *RemoteConfig) UnmarshalJSON(b []byte) error {
6870
}
6971

7072
func originRequestFromSingeRule(c *cli.Context) OriginRequestConfig {
71-
var connectTimeout time.Duration = defaultConnectTimeout
72-
var tlsTimeout time.Duration = defaultTLSTimeout
73-
var tcpKeepAlive time.Duration = defaultTCPKeepAlive
73+
var connectTimeout config.CustomDuration = defaultConnectTimeout
74+
var tlsTimeout config.CustomDuration = defaultTLSTimeout
75+
var tcpKeepAlive config.CustomDuration = defaultTCPKeepAlive
7476
var noHappyEyeballs bool
7577
var keepAliveConnections int = defaultKeepAliveConnections
76-
var keepAliveTimeout time.Duration = defaultKeepAliveTimeout
78+
var keepAliveTimeout config.CustomDuration = defaultKeepAliveTimeout
7779
var httpHostHeader string
7880
var originServerName string
7981
var caPool string
@@ -84,13 +86,13 @@ func originRequestFromSingeRule(c *cli.Context) OriginRequestConfig {
8486
var proxyPort uint
8587
var proxyType string
8688
if flag := ProxyConnectTimeoutFlag; c.IsSet(flag) {
87-
connectTimeout = c.Duration(flag)
89+
connectTimeout = config.CustomDuration{Duration: c.Duration(flag)}
8890
}
8991
if flag := ProxyTLSTimeoutFlag; c.IsSet(flag) {
90-
tlsTimeout = c.Duration(flag)
92+
tlsTimeout = config.CustomDuration{Duration: c.Duration(flag)}
9193
}
9294
if flag := ProxyTCPKeepAliveFlag; c.IsSet(flag) {
93-
tcpKeepAlive = c.Duration(flag)
95+
tcpKeepAlive = config.CustomDuration{Duration: c.Duration(flag)}
9496
}
9597
if flag := ProxyNoHappyEyeballsFlag; c.IsSet(flag) {
9698
noHappyEyeballs = c.Bool(flag)
@@ -99,7 +101,7 @@ func originRequestFromSingeRule(c *cli.Context) OriginRequestConfig {
99101
keepAliveConnections = c.Int(flag)
100102
}
101103
if flag := ProxyKeepAliveTimeoutFlag; c.IsSet(flag) {
102-
keepAliveTimeout = c.Duration(flag)
104+
keepAliveTimeout = config.CustomDuration{Duration: c.Duration(flag)}
103105
}
104106
if flag := HTTPHostHeaderFlag; c.IsSet(flag) {
105107
httpHostHeader = c.String(flag)
@@ -158,13 +160,13 @@ func originRequestFromConfig(c config.OriginRequestConfig) OriginRequestConfig {
158160
ProxyAddress: defaultProxyAddress,
159161
}
160162
if c.ConnectTimeout != nil {
161-
out.ConnectTimeout = c.ConnectTimeout.Duration
163+
out.ConnectTimeout = *c.ConnectTimeout
162164
}
163165
if c.TLSTimeout != nil {
164-
out.TLSTimeout = c.TLSTimeout.Duration
166+
out.TLSTimeout = *c.TLSTimeout
165167
}
166168
if c.TCPKeepAlive != nil {
167-
out.TCPKeepAlive = c.TCPKeepAlive.Duration
169+
out.TCPKeepAlive = *c.TCPKeepAlive
168170
}
169171
if c.NoHappyEyeballs != nil {
170172
out.NoHappyEyeballs = *c.NoHappyEyeballs
@@ -173,7 +175,7 @@ func originRequestFromConfig(c config.OriginRequestConfig) OriginRequestConfig {
173175
out.KeepAliveConnections = *c.KeepAliveConnections
174176
}
175177
if c.KeepAliveTimeout != nil {
176-
out.KeepAliveTimeout = c.KeepAliveTimeout.Duration
178+
out.KeepAliveTimeout = *c.KeepAliveTimeout
177179
}
178180
if c.HTTPHostHeader != nil {
179181
out.HTTPHostHeader = *c.HTTPHostHeader
@@ -218,52 +220,52 @@ func originRequestFromConfig(c config.OriginRequestConfig) OriginRequestConfig {
218220
// Note: To specify a time.Duration in go-yaml, use e.g. "3s" or "24h".
219221
type OriginRequestConfig struct {
220222
// HTTP proxy timeout for establishing a new connection
221-
ConnectTimeout time.Duration `yaml:"connectTimeout"`
223+
ConnectTimeout config.CustomDuration `yaml:"connectTimeout" json:"connectTimeout"`
222224
// HTTP proxy timeout for completing a TLS handshake
223-
TLSTimeout time.Duration `yaml:"tlsTimeout"`
225+
TLSTimeout config.CustomDuration `yaml:"tlsTimeout" json:"tlsTimeout"`
224226
// HTTP proxy TCP keepalive duration
225-
TCPKeepAlive time.Duration `yaml:"tcpKeepAlive"`
227+
TCPKeepAlive config.CustomDuration `yaml:"tcpKeepAlive" json:"tcpKeepAlive"`
226228
// HTTP proxy should disable "happy eyeballs" for IPv4/v6 fallback
227-
NoHappyEyeballs bool `yaml:"noHappyEyeballs"`
229+
NoHappyEyeballs bool `yaml:"noHappyEyeballs" json:"noHappyEyeballs"`
228230
// HTTP proxy timeout for closing an idle connection
229-
KeepAliveTimeout time.Duration `yaml:"keepAliveTimeout"`
231+
KeepAliveTimeout config.CustomDuration `yaml:"keepAliveTimeout" json:"keepAliveTimeout"`
230232
// HTTP proxy maximum keepalive connection pool size
231-
KeepAliveConnections int `yaml:"keepAliveConnections"`
233+
KeepAliveConnections int `yaml:"keepAliveConnections" json:"keepAliveConnections"`
232234
// Sets the HTTP Host header for the local webserver.
233-
HTTPHostHeader string `yaml:"httpHostHeader"`
235+
HTTPHostHeader string `yaml:"httpHostHeader" json:"httpHostHeader"`
234236
// Hostname on the origin server certificate.
235-
OriginServerName string `yaml:"originServerName"`
237+
OriginServerName string `yaml:"originServerName" json:"originServerName"`
236238
// Path to the CA for the certificate of your origin.
237239
// This option should be used only if your certificate is not signed by Cloudflare.
238-
CAPool string `yaml:"caPool"`
240+
CAPool string `yaml:"caPool" json:"caPool"`
239241
// Disables TLS verification of the certificate presented by your origin.
240242
// Will allow any certificate from the origin to be accepted.
241243
// Note: The connection from your machine to Cloudflare's Edge is still encrypted.
242-
NoTLSVerify bool `yaml:"noTLSVerify"`
244+
NoTLSVerify bool `yaml:"noTLSVerify" json:"noTLSVerify"`
243245
// Disables chunked transfer encoding.
244246
// Useful if you are running a WSGI server.
245-
DisableChunkedEncoding bool `yaml:"disableChunkedEncoding"`
247+
DisableChunkedEncoding bool `yaml:"disableChunkedEncoding" json:"disableChunkedEncoding"`
246248
// Runs as jump host
247-
BastionMode bool `yaml:"bastionMode"`
249+
BastionMode bool `yaml:"bastionMode" json:"bastionMode"`
248250
// Listen address for the proxy.
249-
ProxyAddress string `yaml:"proxyAddress"`
251+
ProxyAddress string `yaml:"proxyAddress" json:"proxyAddress"`
250252
// Listen port for the proxy.
251-
ProxyPort uint `yaml:"proxyPort"`
253+
ProxyPort uint `yaml:"proxyPort" json:"proxyPort"`
252254
// What sort of proxy should be started
253-
ProxyType string `yaml:"proxyType"`
255+
ProxyType string `yaml:"proxyType" json:"proxyType"`
254256
// IP rules for the proxy service
255-
IPRules []ipaccess.Rule `yaml:"ipRules"`
257+
IPRules []ipaccess.Rule `yaml:"ipRules" json:"ipRules"`
256258
}
257259

258260
func (defaults *OriginRequestConfig) setConnectTimeout(overrides config.OriginRequestConfig) {
259261
if val := overrides.ConnectTimeout; val != nil {
260-
defaults.ConnectTimeout = val.Duration
262+
defaults.ConnectTimeout = *val
261263
}
262264
}
263265

264266
func (defaults *OriginRequestConfig) setTLSTimeout(overrides config.OriginRequestConfig) {
265267
if val := overrides.TLSTimeout; val != nil {
266-
defaults.TLSTimeout = val.Duration
268+
defaults.TLSTimeout = *val
267269
}
268270
}
269271

@@ -281,13 +283,13 @@ func (defaults *OriginRequestConfig) setKeepAliveConnections(overrides config.Or
281283

282284
func (defaults *OriginRequestConfig) setKeepAliveTimeout(overrides config.OriginRequestConfig) {
283285
if val := overrides.KeepAliveTimeout; val != nil {
284-
defaults.KeepAliveTimeout = val.Duration
286+
defaults.KeepAliveTimeout = *val
285287
}
286288
}
287289

288290
func (defaults *OriginRequestConfig) setTCPKeepAlive(overrides config.OriginRequestConfig) {
289291
if val := overrides.TCPKeepAlive; val != nil {
290-
defaults.TCPKeepAlive = val.Duration
292+
defaults.TCPKeepAlive = *val
291293
}
292294
}
293295

ingress/config_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func TestUnmarshalRemoteConfigOverridesGlobal(t *testing.T) {
6565
err := json.Unmarshal(rawConfig, &remoteConfig)
6666
require.NoError(t, err)
6767
require.True(t, remoteConfig.Ingress.Rules[0].Config.NoTLSVerify)
68-
require.True(t, remoteConfig.Ingress.defaults.NoHappyEyeballs)
68+
require.True(t, remoteConfig.Ingress.Defaults.NoHappyEyeballs)
6969
}
7070

7171
func TestOriginRequestConfigOverrides(t *testing.T) {
@@ -74,11 +74,11 @@ func TestOriginRequestConfigOverrides(t *testing.T) {
7474
// root-level configuration.
7575
actual0 := ing.Rules[0].Config
7676
expected0 := OriginRequestConfig{
77-
ConnectTimeout: 1 * time.Minute,
78-
TLSTimeout: 1 * time.Second,
79-
TCPKeepAlive: 1 * time.Second,
77+
ConnectTimeout: config.CustomDuration{Duration: 1 * time.Minute},
78+
TLSTimeout: config.CustomDuration{Duration: 1 * time.Second},
79+
TCPKeepAlive: config.CustomDuration{Duration: 1 * time.Second},
8080
NoHappyEyeballs: true,
81-
KeepAliveTimeout: 1 * time.Second,
81+
KeepAliveTimeout: config.CustomDuration{Duration: 1 * time.Second},
8282
KeepAliveConnections: 1,
8383
HTTPHostHeader: "abc",
8484
OriginServerName: "a1",
@@ -99,11 +99,11 @@ func TestOriginRequestConfigOverrides(t *testing.T) {
9999
// Rule 1 overrode all the root-level config.
100100
actual1 := ing.Rules[1].Config
101101
expected1 := OriginRequestConfig{
102-
ConnectTimeout: 2 * time.Minute,
103-
TLSTimeout: 2 * time.Second,
104-
TCPKeepAlive: 2 * time.Second,
102+
ConnectTimeout: config.CustomDuration{Duration: 2 * time.Minute},
103+
TLSTimeout: config.CustomDuration{Duration: 2 * time.Second},
104+
TCPKeepAlive: config.CustomDuration{Duration: 2 * time.Second},
105105
NoHappyEyeballs: false,
106-
KeepAliveTimeout: 2 * time.Second,
106+
KeepAliveTimeout: config.CustomDuration{Duration: 2 * time.Second},
107107
KeepAliveConnections: 2,
108108
HTTPHostHeader: "def",
109109
OriginServerName: "b2",
@@ -286,11 +286,11 @@ func TestOriginRequestConfigDefaults(t *testing.T) {
286286
// Rule 1 overrode all defaults.
287287
actual1 := ing.Rules[1].Config
288288
expected1 := OriginRequestConfig{
289-
ConnectTimeout: 2 * time.Minute,
290-
TLSTimeout: 2 * time.Second,
291-
TCPKeepAlive: 2 * time.Second,
289+
ConnectTimeout: config.CustomDuration{Duration: 2 * time.Minute},
290+
TLSTimeout: config.CustomDuration{Duration: 2 * time.Second},
291+
TCPKeepAlive: config.CustomDuration{Duration: 2 * time.Second},
292292
NoHappyEyeballs: false,
293-
KeepAliveTimeout: 2 * time.Second,
293+
KeepAliveTimeout: config.CustomDuration{Duration: 2 * time.Second},
294294
KeepAliveConnections: 2,
295295
HTTPHostHeader: "def",
296296
OriginServerName: "b2",

ingress/ingress.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ func matchHost(ruleHost, reqHost string) bool {
6464

6565
// Ingress maps eyeball requests to origins.
6666
type Ingress struct {
67-
Rules []Rule
68-
defaults OriginRequestConfig
67+
Rules []Rule `json:"ingress"`
68+
Defaults OriginRequestConfig `json:"originRequest"`
6969
}
7070

7171
// NewSingleOrigin constructs an Ingress set with only one rule, constructed from
@@ -86,7 +86,7 @@ func NewSingleOrigin(c *cli.Context, allowURLFromArgs bool) (Ingress, error) {
8686
Config: setConfig(defaults, config.OriginRequestConfig{}),
8787
},
8888
},
89-
defaults: defaults,
89+
Defaults: defaults,
9090
}
9191
return ing, err
9292
}
@@ -180,7 +180,7 @@ func validateIngress(ingress []config.UnvalidatedIngressRule, defaults OriginReq
180180
}
181181
srv := newStatusCode(status)
182182
service = &srv
183-
} else if r.Service == "hello_world" || r.Service == "hello-world" || r.Service == "helloworld" {
183+
} else if r.Service == HelloWorldService || r.Service == "hello-world" || r.Service == "helloworld" {
184184
service = new(helloWorld)
185185
} else if r.Service == ServiceSocksProxy {
186186
rules := make([]ipaccess.Rule, len(r.OriginRequest.IPRules))
@@ -230,23 +230,24 @@ func validateIngress(ingress []config.UnvalidatedIngressRule, defaults OriginReq
230230
return Ingress{}, err
231231
}
232232

233-
var pathRegex *regexp.Regexp
233+
var pathRegexp *Regexp
234234
if r.Path != "" {
235235
var err error
236-
pathRegex, err = regexp.Compile(r.Path)
236+
regex, err := regexp.Compile(r.Path)
237237
if err != nil {
238238
return Ingress{}, errors.Wrapf(err, "Rule #%d has an invalid regex", i+1)
239239
}
240+
pathRegexp = &Regexp{Regexp: regex}
240241
}
241242

242243
rules[i] = Rule{
243244
Hostname: r.Hostname,
244245
Service: service,
245-
Path: pathRegex,
246+
Path: pathRegexp,
246247
Config: cfg,
247248
}
248249
}
249-
return Ingress{Rules: rules, defaults: defaults}, nil
250+
return Ingress{Rules: rules, Defaults: defaults}, nil
250251
}
251252

252253
func validateHostname(r config.UnvalidatedIngressRule, ruleIndex, totalRules int) error {

ingress/ingress_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -482,12 +482,12 @@ func TestSingleOriginSetsConfig(t *testing.T) {
482482
ingress, err := NewSingleOrigin(cliCtx, allowURLFromArgs)
483483
require.NoError(t, err)
484484

485-
assert.Equal(t, time.Second, ingress.Rules[0].Config.ConnectTimeout)
486-
assert.Equal(t, time.Second, ingress.Rules[0].Config.TLSTimeout)
487-
assert.Equal(t, time.Second, ingress.Rules[0].Config.TCPKeepAlive)
485+
assert.Equal(t, config.CustomDuration{Duration: time.Second}, ingress.Rules[0].Config.ConnectTimeout)
486+
assert.Equal(t, config.CustomDuration{Duration: time.Second}, ingress.Rules[0].Config.TLSTimeout)
487+
assert.Equal(t, config.CustomDuration{Duration: time.Second}, ingress.Rules[0].Config.TCPKeepAlive)
488488
assert.True(t, ingress.Rules[0].Config.NoHappyEyeballs)
489489
assert.Equal(t, 10, ingress.Rules[0].Config.KeepAliveConnections)
490-
assert.Equal(t, time.Second, ingress.Rules[0].Config.KeepAliveTimeout)
490+
assert.Equal(t, config.CustomDuration{Duration: time.Second}, ingress.Rules[0].Config.KeepAliveTimeout)
491491
assert.Equal(t, "example.com:8080", ingress.Rules[0].Config.HTTPHostHeader)
492492
assert.Equal(t, "example.com", ingress.Rules[0].Config.OriginServerName)
493493
assert.Equal(t, "/etc/certs/ca.pem", ingress.Rules[0].Config.CAPool)
@@ -508,7 +508,7 @@ func TestFindMatchingRule(t *testing.T) {
508508
},
509509
{
510510
Hostname: "tunnel-b.example.com",
511-
Path: mustParsePath(t, "/health"),
511+
Path: MustParsePath(t, "/health"),
512512
},
513513
{
514514
Hostname: "*",
@@ -591,10 +591,10 @@ func TestIsHTTPService(t *testing.T) {
591591
}
592592
}
593593

594-
func mustParsePath(t *testing.T, path string) *regexp.Regexp {
594+
func MustParsePath(t *testing.T, path string) *Regexp {
595595
regexp, err := regexp.Compile(path)
596596
assert.NoError(t, err)
597-
return regexp
597+
return &Regexp{Regexp: regexp}
598598
}
599599

600600
func MustParseURL(t *testing.T, rawURL string) *url.URL {

0 commit comments

Comments
 (0)