TUN-4821: Make quick tunnels the default in cloudflared

This commit is contained in:
Rishabh Bector
2021-07-09 12:52:41 -05:00
committed by Nuno Diegues
parent 1da4fbbe0b
commit a4a9f45b0a
12 changed files with 64 additions and 89 deletions

View File

@@ -206,7 +206,7 @@ func runAdhocNamedTunnel(sc *subcommandContext, name, credentialsOutputPath stri
// runClassicTunnel creates a "classic" non-named tunnel
func runClassicTunnel(sc *subcommandContext) error {
return StartServer(sc.c, version, nil, sc.log, sc.isUIEnabled, "")
return StartServer(sc.c, version, nil, sc.log, sc.isUIEnabled)
}
func routeFromFlag(c *cli.Context) (route tunnelstore.Route, ok bool) {
@@ -225,7 +225,6 @@ func StartServer(
namedTunnel *connection.NamedTunnelConfig,
log *zerolog.Logger,
isUIEnabled bool,
quickTunnelHostname string,
) error {
_ = raven.SetDSN(sentryDSN)
var wg sync.WaitGroup
@@ -325,6 +324,15 @@ func StartServer(
observer := connection.NewObserver(log, logTransport, isUIEnabled)
// Send Quick Tunnel URL to UI if applicable
var quickTunnelURL string
if namedTunnel != nil {
quickTunnelURL = namedTunnel.QuickTunnelUrl
}
if quickTunnelURL != "" {
observer.SendURL(quickTunnelURL)
}
tunnelConfig, ingressRules, err := prepareTunnelConfig(c, buildInfo, version, log, logTransport, observer, namedTunnel)
if err != nil {
log.Err(err).Msg("Couldn't start tunnel")
@@ -342,7 +350,7 @@ func StartServer(
defer wg.Done()
readinessServer := metrics.NewReadyServer(log)
observer.RegisterSink(readinessServer)
errC <- metrics.ServeMetrics(metricsListener, ctx.Done(), readinessServer, quickTunnelHostname, log)
errC <- metrics.ServeMetrics(metricsListener, ctx.Done(), readinessServer, quickTunnelURL, log)
}()
if err := ingressRules.StartOrigins(&wg, log, ctx.Done(), errC); err != nil {
@@ -626,6 +634,7 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
altsrc.NewStringFlag(&cli.StringFlag{
Name: "quick-service",
Usage: "URL for a service which manages unauthenticated 'quick' tunnels.",
Value: "https://api.trycloudflare.com",
Hidden: true,
}),
selectProtocolFlag,

View File

@@ -161,7 +161,7 @@ func prepareTunnelConfig(
log.Err(err).Str(LogFieldHostname, configHostname).Msg("Invalid hostname")
return nil, ingress.Ingress{}, errors.Wrap(err, "Invalid hostname")
}
isFreeTunnel := hostname == ""
isQuickTunnel := hostname == ""
clientID := c.String("id")
if !c.IsSet("id") {
clientID, err = generateRandomClientID(log)
@@ -179,7 +179,7 @@ func prepareTunnelConfig(
tags = append(tags, tunnelpogs.Tag{Name: "ID", Value: clientID})
var originCert []byte
if !isFreeTunnel {
if !isQuickTunnel {
originCertPath := c.String("origincert")
originCertLog := log.With().
Str(LogFieldOriginCertPath, originCertPath).
@@ -285,7 +285,6 @@ func prepareTunnelConfig(
HAConnections: c.Int("ha-connections"),
IncidentLookup: origin.NewIncidentLookup(),
IsAutoupdated: c.Bool("is-autoupdated"),
IsFreeTunnel: isFreeTunnel,
LBPool: c.String("lb-pool"),
Tags: tags,
Log: log,

View File

@@ -15,11 +15,17 @@ import (
const httpTimeout = 15 * time.Second
const disclaimer = "Thank you for trying Cloudflare Tunnel. Doing so, without a Cloudflare account, is a quick way to" +
" experiment and try it out. However, be aware that these account-less Tunnels have no uptime guarantee. If you " +
"intend to use Tunnels in production you should use a pre-created named tunnel by following: " +
"https://developers.cloudflare.com/cloudflare-one/connections/connect-apps"
// RunQuickTunnel requests a tunnel from the specified service.
// We use this to power quick tunnels on trycloudflare.com, but the
// service is open-source and could be used by anyone.
func RunQuickTunnel(sc *subcommandContext) error {
sc.log.Info().Msg("Requesting new Quick Tunnel...")
sc.log.Info().Msg(disclaimer)
sc.log.Info().Msg("Requesting new quick Tunnel on trycloudflare.com...")
client := http.Client{
Transport: &http.Transport{
@@ -31,18 +37,18 @@ func RunQuickTunnel(sc *subcommandContext) error {
resp, err := client.Post(fmt.Sprintf("%s/tunnel", sc.c.String("quick-service")), "application/json", nil)
if err != nil {
return errors.Wrap(err, "failed to request quick tunnel")
return errors.Wrap(err, "failed to request quick Tunnel")
}
defer resp.Body.Close()
var data QuickTunnelResponse
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return errors.Wrap(err, "failed to unmarshal quick tunnel")
return errors.Wrap(err, "failed to unmarshal quick Tunnel")
}
tunnelID, err := uuid.Parse(data.Result.ID)
if err != nil {
return errors.Wrap(err, "failed to parse quick tunnel ID")
return errors.Wrap(err, "failed to parse quick Tunnel ID")
}
credentials := connection.Credentials{
@@ -57,8 +63,8 @@ func RunQuickTunnel(sc *subcommandContext) error {
url = "https://" + url
}
for _, line := range connection.AsciiBox([]string{
"Your Quick Tunnel has been created! Visit it at:",
for _, line := range AsciiBox([]string{
"Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):",
url,
}, 2) {
sc.log.Info().Msg(line)
@@ -67,10 +73,9 @@ func RunQuickTunnel(sc *subcommandContext) error {
return StartServer(
sc.c,
version,
&connection.NamedTunnelConfig{Credentials: credentials},
&connection.NamedTunnelConfig{Credentials: credentials, QuickTunnelUrl: data.Result.Hostname},
sc.log,
sc.isUIEnabled,
data.Result.Hostname,
)
}
@@ -92,3 +97,26 @@ type QuickTunnel struct {
AccountTag string `json:"account_tag"`
Secret []byte `json:"secret"`
}
// Print out the given lines in a nice ASCII box.
func AsciiBox(lines []string, padding int) (box []string) {
maxLen := maxLen(lines)
spacer := strings.Repeat(" ", padding)
border := "+" + strings.Repeat("-", maxLen+(padding*2)) + "+"
box = append(box, border)
for _, line := range lines {
box = append(box, "|"+spacer+line+strings.Repeat(" ", maxLen-len(line))+spacer+"|")
}
box = append(box, border)
return
}
func maxLen(lines []string) int {
max := 0
for _, line := range lines {
if len(line) > max {
max = len(line)
}
}
return max
}

View File

@@ -286,7 +286,6 @@ func (sc *subcommandContext) run(tunnelID uuid.UUID) error {
&connection.NamedTunnelConfig{Credentials: credentials},
sc.log,
sc.isUIEnabled,
"",
)
}