TUN-4521: Modify cloudflared to use zoneless-tunnels-worker for free tunnels
This commit is contained in:
		
							parent
							
								
									8d99e92852
								
							
						
					
					
						commit
						3eb9efd9f0
					
				|  | @ -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