Merge branch 'cloudflare:master' into master
This commit is contained in:
		
						commit
						1afac51116
					
				| 
						 | 
					@ -163,6 +163,12 @@ func TunnelCommand(c *cli.Context) error {
 | 
				
			||||||
		return fmt.Errorf("Use `cloudflared tunnel run` to start tunnel %s", ref)
 | 
							return fmt.Errorf("Use `cloudflared tunnel run` to start tunnel %s", ref)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Unauthenticated named tunnel on <random>.<quick-tunnels-service>.com
 | 
				
			||||||
 | 
						// For now, default to legacy setup unless quick-service is specified
 | 
				
			||||||
 | 
						if c.String("hostname") == "" && c.String("quick-service") != "" {
 | 
				
			||||||
 | 
							return RunQuickTunnel(sc)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Start a classic tunnel
 | 
						// Start a classic tunnel
 | 
				
			||||||
	return runClassicTunnel(sc)
 | 
						return runClassicTunnel(sc)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -616,6 +622,11 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
 | 
				
			||||||
			Value:  false,
 | 
								Value:  false,
 | 
				
			||||||
			Hidden: shouldHide,
 | 
								Hidden: shouldHide,
 | 
				
			||||||
		}),
 | 
							}),
 | 
				
			||||||
 | 
							altsrc.NewStringFlag(&cli.StringFlag{
 | 
				
			||||||
 | 
								Name:   "quick-service",
 | 
				
			||||||
 | 
								Usage:  "URL for a service which manages unauthenticated 'quick' tunnels.",
 | 
				
			||||||
 | 
								Hidden: true,
 | 
				
			||||||
 | 
							}),
 | 
				
			||||||
		selectProtocolFlag,
 | 
							selectProtocolFlag,
 | 
				
			||||||
		overwriteDNSFlag,
 | 
							overwriteDNSFlag,
 | 
				
			||||||
	}...)
 | 
						}...)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,87 @@
 | 
				
			||||||
 | 
					package tunnel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/google/uuid"
 | 
				
			||||||
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/cloudflare/cloudflared/connection"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const httpTimeout = 15 * time.Second
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						client := http.Client{
 | 
				
			||||||
 | 
							Transport: &http.Transport{
 | 
				
			||||||
 | 
								TLSHandshakeTimeout:   httpTimeout,
 | 
				
			||||||
 | 
								ResponseHeaderTimeout: httpTimeout,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							Timeout: httpTimeout,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						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")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tunnelID, err := uuid.Parse(data.Result.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return errors.Wrap(err, "failed to parse quick tunnel ID")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						credentials := connection.Credentials{
 | 
				
			||||||
 | 
							AccountTag:   data.Result.AccountTag,
 | 
				
			||||||
 | 
							TunnelSecret: data.Result.Secret,
 | 
				
			||||||
 | 
							TunnelID:     tunnelID,
 | 
				
			||||||
 | 
							TunnelName:   data.Result.Name,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, line := range connection.AsciiBox([]string{
 | 
				
			||||||
 | 
							"Your Quick Tunnel has been created! Visit it at:",
 | 
				
			||||||
 | 
							data.Result.Hostname,
 | 
				
			||||||
 | 
						}, 2) {
 | 
				
			||||||
 | 
							sc.log.Info().Msg(line)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return StartServer(
 | 
				
			||||||
 | 
							sc.c,
 | 
				
			||||||
 | 
							version,
 | 
				
			||||||
 | 
							&connection.NamedTunnelConfig{Credentials: credentials},
 | 
				
			||||||
 | 
							sc.log,
 | 
				
			||||||
 | 
							sc.isUIEnabled,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type QuickTunnelResponse struct {
 | 
				
			||||||
 | 
						Success bool
 | 
				
			||||||
 | 
						Result  QuickTunnel
 | 
				
			||||||
 | 
						Errors  []QuickTunnelError
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type QuickTunnelError struct {
 | 
				
			||||||
 | 
						Code    int
 | 
				
			||||||
 | 
						Message string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type QuickTunnel struct {
 | 
				
			||||||
 | 
						ID         string `json:"id"`
 | 
				
			||||||
 | 
						Name       string `json:"name"`
 | 
				
			||||||
 | 
						Hostname   string `json:"hostname"`
 | 
				
			||||||
 | 
						AccountTag string `json:"account_tag"`
 | 
				
			||||||
 | 
						Secret     []byte `json:"secret"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,7 @@ func (o *Observer) logTrialHostname(registration *tunnelpogs.TunnelRegistration)
 | 
				
			||||||
	// Print out the user's trial zone URL in a nice box (if they requested and got one and UI flag is not set)
 | 
						// Print out the user's trial zone URL in a nice box (if they requested and got one and UI flag is not set)
 | 
				
			||||||
	if !o.uiEnabled {
 | 
						if !o.uiEnabled {
 | 
				
			||||||
		if registrationURL, err := url.Parse(registration.Url); err == nil {
 | 
							if registrationURL, err := url.Parse(registration.Url); err == nil {
 | 
				
			||||||
			for _, line := range asciiBox(trialZoneMsg(registrationURL.String()), 2) {
 | 
								for _, line := range AsciiBox(TrialZoneMsg(registrationURL.String()), 2) {
 | 
				
			||||||
				o.log.Info().Msg(line)
 | 
									o.log.Info().Msg(line)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,7 @@ func (o *Observer) logTrialHostname(registration *tunnelpogs.TunnelRegistration)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Print out the given lines in a nice ASCII box.
 | 
					// Print out the given lines in a nice ASCII box.
 | 
				
			||||||
func asciiBox(lines []string, padding int) (box []string) {
 | 
					func AsciiBox(lines []string, padding int) (box []string) {
 | 
				
			||||||
	maxLen := maxLen(lines)
 | 
						maxLen := maxLen(lines)
 | 
				
			||||||
	spacer := strings.Repeat(" ", padding)
 | 
						spacer := strings.Repeat(" ", padding)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,7 +94,7 @@ func maxLen(lines []string) int {
 | 
				
			||||||
	return max
 | 
						return max
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func trialZoneMsg(url string) []string {
 | 
					func TrialZoneMsg(url string) []string {
 | 
				
			||||||
	return []string{
 | 
						return []string{
 | 
				
			||||||
		"Your free tunnel has started! Visit it:",
 | 
							"Your free tunnel has started! Visit it:",
 | 
				
			||||||
		"  " + url,
 | 
							"  " + url,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue