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)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 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
 | 
			
		||||
	return runClassicTunnel(sc)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -616,6 +622,11 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
 | 
			
		|||
			Value:  false,
 | 
			
		||||
			Hidden: shouldHide,
 | 
			
		||||
		}),
 | 
			
		||||
		altsrc.NewStringFlag(&cli.StringFlag{
 | 
			
		||||
			Name:   "quick-service",
 | 
			
		||||
			Usage:  "URL for a service which manages unauthenticated 'quick' tunnels.",
 | 
			
		||||
			Hidden: true,
 | 
			
		||||
		}),
 | 
			
		||||
		selectProtocolFlag,
 | 
			
		||||
		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)
 | 
			
		||||
	if !o.uiEnabled {
 | 
			
		||||
		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)
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -70,7 +70,7 @@ func (o *Observer) logTrialHostname(registration *tunnelpogs.TunnelRegistration)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// 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)
 | 
			
		||||
	spacer := strings.Repeat(" ", padding)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ func maxLen(lines []string) int {
 | 
			
		|||
	return max
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func trialZoneMsg(url string) []string {
 | 
			
		||||
func TrialZoneMsg(url string) []string {
 | 
			
		||||
	return []string{
 | 
			
		||||
		"Your free tunnel has started! Visit it:",
 | 
			
		||||
		"  " + url,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue