TUN-3438: move ingress into own package, read into TunnelConfig
This commit is contained in:
		
							parent
							
								
									53a1fa46a8
								
							
						
					
					
						commit
						0eebc7cef9
					
				|  | @ -3,6 +3,7 @@ package config | ||||||
| import ( | import ( | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"io/ioutil" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"runtime" | 	"runtime" | ||||||
|  | @ -11,6 +12,7 @@ import ( | ||||||
| 	"github.com/urfave/cli/v2" | 	"github.com/urfave/cli/v2" | ||||||
| 	"gopkg.in/yaml.v2" | 	"gopkg.in/yaml.v2" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/cloudflare/cloudflared/ingress" | ||||||
| 	"github.com/cloudflare/cloudflared/validation" | 	"github.com/cloudflare/cloudflared/validation" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -193,3 +195,17 @@ func ValidateUrl(c *cli.Context, allowFromArgs bool) (string, error) { | ||||||
| 	validUrl, err := validation.ValidateUrl(url) | 	validUrl, err := validation.ValidateUrl(url) | ||||||
| 	return validUrl, err | 	return validUrl, err | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func ReadRules(c *cli.Context) ([]ingress.Rule, error) { | ||||||
|  | 	configFilePath := c.String("config") | ||||||
|  | 	if configFilePath == "" { | ||||||
|  | 		return nil, ErrNoConfigFile | ||||||
|  | 	} | ||||||
|  | 	fmt.Printf("Reading from config file %s\n", configFilePath) | ||||||
|  | 	configBytes, err := ioutil.ReadFile(configFilePath) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	rules, err := ingress.ParseIngress(configBytes) | ||||||
|  | 	return rules, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ import ( | ||||||
| 	"github.com/cloudflare/cloudflared/dbconnect" | 	"github.com/cloudflare/cloudflared/dbconnect" | ||||||
| 	"github.com/cloudflare/cloudflared/h2mux" | 	"github.com/cloudflare/cloudflared/h2mux" | ||||||
| 	"github.com/cloudflare/cloudflared/hello" | 	"github.com/cloudflare/cloudflared/hello" | ||||||
|  | 	"github.com/cloudflare/cloudflared/ingress" | ||||||
| 	"github.com/cloudflare/cloudflared/logger" | 	"github.com/cloudflare/cloudflared/logger" | ||||||
| 	"github.com/cloudflare/cloudflared/metrics" | 	"github.com/cloudflare/cloudflared/metrics" | ||||||
| 	"github.com/cloudflare/cloudflared/origin" | 	"github.com/cloudflare/cloudflared/origin" | ||||||
|  | @ -1248,3 +1249,64 @@ reconnect [delay] | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func buildValidateCommand() *cli.Command { | ||||||
|  | 	return &cli.Command{ | ||||||
|  | 		Name:        "validate", | ||||||
|  | 		Action:      cliutil.ErrorHandler(ValidateCommand), | ||||||
|  | 		Usage:       "Validate the ingress configuration ", | ||||||
|  | 		UsageText:   "cloudflared tunnel [--config FILEPATH] ingress validate", | ||||||
|  | 		Description: "Validates the configuration file, ensuring your ingress rules are OK.", | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func buildRuleCommand() *cli.Command { | ||||||
|  | 	return &cli.Command{ | ||||||
|  | 		Name:      "rule", | ||||||
|  | 		Action:    cliutil.ErrorHandler(RuleCommand), | ||||||
|  | 		Usage:     "Check which ingress rule matches a given request URL", | ||||||
|  | 		UsageText: "cloudflared tunnel [--config FILEPATH] ingress rule URL", | ||||||
|  | 		ArgsUsage: "URL", | ||||||
|  | 		Description: "Check which ingress rule matches a given request URL. " + | ||||||
|  | 			"Ingress rules match a request's hostname and path. Hostname is " + | ||||||
|  | 			"optional and is either a full hostname like `www.example.com` or a " + | ||||||
|  | 			"hostname with a `*` for its subdomains, e.g. `*.example.com`. Path " + | ||||||
|  | 			"is optional and matches a regular expression, like `/[a-zA-Z0-9_]+.html`", | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Validates the ingress rules in the cloudflared config file
 | ||||||
|  | func ValidateCommand(c *cli.Context) error { | ||||||
|  | 	_, err := config.ReadRules(c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return errors.Wrap(err, "Validation failed") | ||||||
|  | 	} | ||||||
|  | 	if c.IsSet("url") { | ||||||
|  | 		return ingress.ErrURLIncompatibleWithIngress | ||||||
|  | 	} | ||||||
|  | 	fmt.Println("OK") | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Checks which ingress rule matches the given URL.
 | ||||||
|  | func RuleCommand(c *cli.Context) error { | ||||||
|  | 	rules, err := config.ReadRules(c) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	requestArg := c.Args().First() | ||||||
|  | 	if requestArg == "" { | ||||||
|  | 		return errors.New("cloudflared tunnel rule expects a single argument, the URL to test") | ||||||
|  | 	} | ||||||
|  | 	requestURL, err := url.Parse(requestArg) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("%s is not a valid URL", requestArg) | ||||||
|  | 	} | ||||||
|  | 	if requestURL.Hostname() == "" && requestURL.Scheme == "" { | ||||||
|  | 		return fmt.Errorf("%s doesn't have a hostname, consider adding a scheme", requestArg) | ||||||
|  | 	} | ||||||
|  | 	if requestURL.Hostname() == "" { | ||||||
|  | 		return fmt.Errorf("%s doesn't have a hostname", requestArg) | ||||||
|  | 	} | ||||||
|  | 	return ingress.RuleCommand(rules, requestURL) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"github.com/cloudflare/cloudflared/cmd/cloudflared/buildinfo" | 	"github.com/cloudflare/cloudflared/cmd/cloudflared/buildinfo" | ||||||
| 	"github.com/cloudflare/cloudflared/cmd/cloudflared/config" | 	"github.com/cloudflare/cloudflared/cmd/cloudflared/config" | ||||||
|  | 	"github.com/cloudflare/cloudflared/ingress" | ||||||
| 	"github.com/cloudflare/cloudflared/logger" | 	"github.com/cloudflare/cloudflared/logger" | ||||||
| 	"github.com/cloudflare/cloudflared/origin" | 	"github.com/cloudflare/cloudflared/origin" | ||||||
| 	"github.com/cloudflare/cloudflared/tlsconfig" | 	"github.com/cloudflare/cloudflared/tlsconfig" | ||||||
|  | @ -184,12 +185,6 @@ func prepareTunnelConfig( | ||||||
| 
 | 
 | ||||||
| 	tags = append(tags, tunnelpogs.Tag{Name: "ID", Value: clientID}) | 	tags = append(tags, tunnelpogs.Tag{Name: "ID", Value: clientID}) | ||||||
| 
 | 
 | ||||||
| 	originURL, err := config.ValidateUrl(c, compatibilityMode) |  | ||||||
| 	if err != nil { |  | ||||||
| 		logger.Errorf("Error validating origin URL: %s", err) |  | ||||||
| 		return nil, errors.Wrap(err, "Error validating origin URL") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var originCert []byte | 	var originCert []byte | ||||||
| 	if !isFreeTunnel { | 	if !isFreeTunnel { | ||||||
| 		originCert, err = getOriginCert(c, logger) | 		originCert, err = getOriginCert(c, logger) | ||||||
|  | @ -224,6 +219,36 @@ func prepareTunnelConfig( | ||||||
| 	} | 	} | ||||||
| 	dialContext := dialer.DialContext | 	dialContext := dialer.DialContext | ||||||
| 
 | 
 | ||||||
|  | 	var ingressRules []ingress.Rule | ||||||
|  | 	if namedTunnel != nil { | ||||||
|  | 		clientUUID, err := uuid.NewRandom() | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, errors.Wrap(err, "can't generate clientUUID") | ||||||
|  | 		} | ||||||
|  | 		namedTunnel.Client = tunnelpogs.ClientInfo{ | ||||||
|  | 			ClientID: clientUUID[:], | ||||||
|  | 			Features: []string{origin.FeatureSerializedHeaders}, | ||||||
|  | 			Version:  version, | ||||||
|  | 			Arch:     fmt.Sprintf("%s_%s", buildInfo.GoOS, buildInfo.GoArch), | ||||||
|  | 		} | ||||||
|  | 		ingressRules, err = config.ReadRules(c) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		if c.IsSet("url") { | ||||||
|  | 			return nil, ingress.ErrURLIncompatibleWithIngress | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var originURL string | ||||||
|  | 	if len(ingressRules) == 0 { | ||||||
|  | 		originURL, err = config.ValidateUrl(c, compatibilityMode) | ||||||
|  | 		if err != nil { | ||||||
|  | 			logger.Errorf("Error validating origin URL: %s", err) | ||||||
|  | 			return nil, errors.Wrap(err, "Error validating origin URL") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if c.IsSet("unix-socket") { | 	if c.IsSet("unix-socket") { | ||||||
| 		unixSocket, err := config.ValidateUnixSocket(c) | 		unixSocket, err := config.ValidateUnixSocket(c) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  | @ -256,20 +281,6 @@ func prepareTunnelConfig( | ||||||
| 		logger.Errorf("unable to create TLS config to connect with edge: %s", err) | 		logger.Errorf("unable to create TLS config to connect with edge: %s", err) | ||||||
| 		return nil, errors.Wrap(err, "unable to create TLS config to connect with edge") | 		return nil, errors.Wrap(err, "unable to create TLS config to connect with edge") | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	if namedTunnel != nil { |  | ||||||
| 		clientUUID, err := uuid.NewRandom() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, errors.Wrap(err, "can't generate clientUUID") |  | ||||||
| 		} |  | ||||||
| 		namedTunnel.Client = tunnelpogs.ClientInfo{ |  | ||||||
| 			ClientID: clientUUID[:], |  | ||||||
| 			Features: []string{origin.FeatureSerializedHeaders}, |  | ||||||
| 			Version:  version, |  | ||||||
| 			Arch:     fmt.Sprintf("%s_%s", buildInfo.GoOS, buildInfo.GoArch), |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return &origin.TunnelConfig{ | 	return &origin.TunnelConfig{ | ||||||
| 		BuildInfo:          buildInfo, | 		BuildInfo:          buildInfo, | ||||||
| 		ClientID:           clientID, | 		ClientID:           clientID, | ||||||
|  | @ -301,6 +312,7 @@ func prepareTunnelConfig( | ||||||
| 		TlsConfig:          toEdgeTLSConfig, | 		TlsConfig:          toEdgeTLSConfig, | ||||||
| 		NamedTunnel:        namedTunnel, | 		NamedTunnel:        namedTunnel, | ||||||
| 		ReplaceExisting:    c.Bool("force"), | 		ReplaceExisting:    c.Bool("force"), | ||||||
|  | 		IngressRules:       ingressRules, | ||||||
| 		// turn off use of reconnect token and auth refresh when using named tunnels
 | 		// turn off use of reconnect token and auth refresh when using named tunnels
 | ||||||
| 		UseReconnectToken: compatibilityMode && c.Bool("use-reconnect-token"), | 		UseReconnectToken: compatibilityMode && c.Bool("use-reconnect-token"), | ||||||
| 	}, nil | 	}, nil | ||||||
|  |  | ||||||
|  | @ -1,30 +1,26 @@ | ||||||
| package tunnel | package ingress | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io/ioutil" |  | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil" |  | ||||||
| 	"github.com/cloudflare/cloudflared/cmd/cloudflared/config" |  | ||||||
| 
 |  | ||||||
| 	"github.com/pkg/errors" | 	"github.com/pkg/errors" | ||||||
| 	"github.com/urfave/cli/v2" |  | ||||||
| 	"gopkg.in/yaml.v2" | 	"gopkg.in/yaml.v2" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| 	errNoIngressRules      = errors.New("No ingress rules were specified in the config file") | 	errNoIngressRules             = errors.New("No ingress rules were specified in the config file") | ||||||
| 	errLastRuleNotCatchAll = errors.New("The last ingress rule must match all hostnames (i.e. it must be missing, or must be \"*\")") | 	errLastRuleNotCatchAll        = errors.New("The last ingress rule must match all hostnames (i.e. it must be missing, or must be \"*\")") | ||||||
| 	errBadWildcard         = errors.New("Hostname patterns can have at most one wildcard character (\"*\") and it can only be used for subdomains, e.g. \"*.example.com\"") | 	errBadWildcard                = errors.New("Hostname patterns can have at most one wildcard character (\"*\") and it can only be used for subdomains, e.g. \"*.example.com\"") | ||||||
| 	errNoIngressRulesMatch = errors.New("The URL didn't match any ingress rules") | 	errNoIngressRulesMatch        = errors.New("The URL didn't match any ingress rules") | ||||||
|  | 	ErrURLIncompatibleWithIngress = errors.New("You can't set the --url flag (or $TUNNEL_URL) when using multiple-origin ingress rules") | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Each rule route traffic from a hostname/path on the public
 | // Each rule route traffic from a hostname/path on the public
 | ||||||
| // internet to the service running on the given URL.
 | // internet to the service running on the given URL.
 | ||||||
| type rule struct { | type Rule struct { | ||||||
| 	// Requests for this hostname will be proxied to this rule's service.
 | 	// Requests for this hostname will be proxied to this rule's service.
 | ||||||
| 	Hostname string | 	Hostname string | ||||||
| 
 | 
 | ||||||
|  | @ -37,7 +33,7 @@ type rule struct { | ||||||
| 	Service *url.URL | 	Service *url.URL | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r rule) String() string { | func (r Rule) String() string { | ||||||
| 	var out strings.Builder | 	var out strings.Builder | ||||||
| 	if r.Hostname != "" { | 	if r.Hostname != "" { | ||||||
| 		out.WriteString("\thostname: ") | 		out.WriteString("\thostname: ") | ||||||
|  | @ -54,7 +50,7 @@ func (r rule) String() string { | ||||||
| 	return out.String() | 	return out.String() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r rule) matches(requestURL *url.URL) bool { | func (r Rule) matches(requestURL *url.URL) bool { | ||||||
| 	hostMatch := r.Hostname == "" || r.Hostname == "*" || matchHost(r.Hostname, requestURL.Hostname()) | 	hostMatch := r.Hostname == "" || r.Hostname == "*" || matchHost(r.Hostname, requestURL.Hostname()) | ||||||
| 	pathMatch := r.Path == nil || r.Path.MatchString(requestURL.Path) | 	pathMatch := r.Path == nil || r.Path.MatchString(requestURL.Path) | ||||||
| 	return hostMatch && pathMatch | 	return hostMatch && pathMatch | ||||||
|  | @ -81,10 +77,14 @@ type unvalidatedRule struct { | ||||||
| 
 | 
 | ||||||
| type ingress struct { | type ingress struct { | ||||||
| 	Ingress []unvalidatedRule | 	Ingress []unvalidatedRule | ||||||
|  | 	Url     string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (ing ingress) validate() ([]rule, error) { | func (ing ingress) validate() ([]Rule, error) { | ||||||
| 	rules := make([]rule, len(ing.Ingress)) | 	if ing.Url != "" { | ||||||
|  | 		return nil, ErrURLIncompatibleWithIngress | ||||||
|  | 	} | ||||||
|  | 	rules := make([]Rule, len(ing.Ingress)) | ||||||
| 	for i, r := range ing.Ingress { | 	for i, r := range ing.Ingress { | ||||||
| 		service, err := url.Parse(r.Service) | 		service, err := url.Parse(r.Service) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  | @ -119,7 +119,7 @@ func (ing ingress) validate() ([]rule, error) { | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		rules[i] = rule{ | 		rules[i] = Rule{ | ||||||
| 			Hostname: r.Hostname, | 			Hostname: r.Hostname, | ||||||
| 			Service:  service, | 			Service:  service, | ||||||
| 			Path:     pathRegex, | 			Path:     pathRegex, | ||||||
|  | @ -139,7 +139,7 @@ func (e errRuleShouldNotBeCatchAll) Error() string { | ||||||
| 		"will never be triggered.", e.i+1, e.hostname) | 		"will never be triggered.", e.i+1, e.hostname) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func parseIngress(rawYAML []byte) ([]rule, error) { | func ParseIngress(rawYAML []byte) ([]Rule, error) { | ||||||
| 	var ing ingress | 	var ing ingress | ||||||
| 	if err := yaml.Unmarshal(rawYAML, &ing); err != nil { | 	if err := yaml.Unmarshal(rawYAML, &ing); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
|  | @ -150,57 +150,10 @@ func parseIngress(rawYAML []byte) ([]rule, error) { | ||||||
| 	return ing.validate() | 	return ing.validate() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func ingressContext(c *cli.Context) ([]rule, error) { | // RuleCommand checks which ingress rule matches the given request URL.
 | ||||||
| 	configFilePath := c.String("config") | func RuleCommand(rules []Rule, requestURL *url.URL) error { | ||||||
| 	if configFilePath == "" { |  | ||||||
| 		return nil, config.ErrNoConfigFile |  | ||||||
| 	} |  | ||||||
| 	fmt.Printf("Reading from config file %s\n", configFilePath) |  | ||||||
| 	configBytes, err := ioutil.ReadFile(configFilePath) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	rules, err := parseIngress(configBytes) |  | ||||||
| 	return rules, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Validates the ingress rules in the cloudflared config file
 |  | ||||||
| func validateCommand(c *cli.Context) error { |  | ||||||
| 	_, err := ingressContext(c) |  | ||||||
| 	if err != nil { |  | ||||||
| 		fmt.Println(err.Error()) |  | ||||||
| 		return errors.New("Validation failed") |  | ||||||
| 	} |  | ||||||
| 	fmt.Println("OK") |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func buildValidateCommand() *cli.Command { |  | ||||||
| 	return &cli.Command{ |  | ||||||
| 		Name:        "validate", |  | ||||||
| 		Action:      cliutil.ErrorHandler(validateCommand), |  | ||||||
| 		Usage:       "Validate the ingress configuration ", |  | ||||||
| 		UsageText:   "cloudflared tunnel [--config FILEPATH] ingress validate", |  | ||||||
| 		Description: "Validates the configuration file, ensuring your ingress rules are OK.", |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Checks which ingress rule matches the given URL.
 |  | ||||||
| func ruleCommand(c *cli.Context) error { |  | ||||||
| 	rules, err := ingressContext(c) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	requestArg := c.Args().First() |  | ||||||
| 	if requestArg == "" { |  | ||||||
| 		return errors.New("cloudflared tunnel rule expects a single argument, the URL to test") |  | ||||||
| 	} |  | ||||||
| 	requestURL, err := url.Parse(requestArg) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("%s is not a valid URL", requestArg) |  | ||||||
| 	} |  | ||||||
| 	if requestURL.Hostname() == "" { | 	if requestURL.Hostname() == "" { | ||||||
| 		return fmt.Errorf("%s is malformed and doesn't have a hostname", requestArg) | 		return fmt.Errorf("%s is malformed and doesn't have a hostname", requestURL) | ||||||
| 	} | 	} | ||||||
| 	for i, r := range rules { | 	for i, r := range rules { | ||||||
| 		if r.matches(requestURL) { | 		if r.matches(requestURL) { | ||||||
|  | @ -211,18 +164,3 @@ func ruleCommand(c *cli.Context) error { | ||||||
| 	} | 	} | ||||||
| 	return errNoIngressRulesMatch | 	return errNoIngressRulesMatch | ||||||
| } | } | ||||||
| 
 |  | ||||||
| func buildRuleCommand() *cli.Command { |  | ||||||
| 	return &cli.Command{ |  | ||||||
| 		Name:      "rule", |  | ||||||
| 		Action:    cliutil.ErrorHandler(ruleCommand), |  | ||||||
| 		Usage:     "Check which ingress rule matches a given request URL", |  | ||||||
| 		UsageText: "cloudflared [--config CONFIGFILE] tunnel ingress rule URL", |  | ||||||
| 		ArgsUsage: "URL", |  | ||||||
| 		Description: "Check which ingress rule matches a given request URL. " + |  | ||||||
| 			"Ingress rules match a request's hostname and path. Hostname is " + |  | ||||||
| 			"optional and is either a full hostname like `www.example.com` or a " + |  | ||||||
| 			"hostname with a `*` for its subdomains, e.g. `*.example.com`. Path " + |  | ||||||
| 			"is optional and matches a regular expression, like `/[a-zA-Z0-9_]+.html`", |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| package tunnel | package ingress | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"net/url" | 	"net/url" | ||||||
|  | @ -20,7 +20,7 @@ func Test_parseIngress(t *testing.T) { | ||||||
| 	tests := []struct { | 	tests := []struct { | ||||||
| 		name    string | 		name    string | ||||||
| 		args    args | 		args    args | ||||||
| 		want    []rule | 		want    []Rule | ||||||
| 		wantErr bool | 		wantErr bool | ||||||
| 	}{ | 	}{ | ||||||
| 		{ | 		{ | ||||||
|  | @ -37,7 +37,7 @@ ingress: | ||||||
|   - hostname: "*" |   - hostname: "*" | ||||||
|     service: https://localhost:8001
 |     service: https://localhost:8001
 | ||||||
| `}, | `}, | ||||||
| 			want: []rule{ | 			want: []Rule{ | ||||||
| 				{ | 				{ | ||||||
| 					Hostname: "tunnel1.example.com", | 					Hostname: "tunnel1.example.com", | ||||||
| 					Service:  localhost8000, | 					Service:  localhost8000, | ||||||
|  | @ -56,7 +56,7 @@ ingress: | ||||||
|     service: https://localhost:8000
 |     service: https://localhost:8000
 | ||||||
| extraKey: extraValue | extraKey: extraValue | ||||||
| `}, | `}, | ||||||
| 			want: []rule{ | 			want: []Rule{ | ||||||
| 				{ | 				{ | ||||||
| 					Hostname: "*", | 					Hostname: "*", | ||||||
| 					Service:  localhost8000, | 					Service:  localhost8000, | ||||||
|  | @ -69,7 +69,7 @@ extraKey: extraValue | ||||||
| ingress: | ingress: | ||||||
|   - service: https://localhost:8000
 |   - service: https://localhost:8000
 | ||||||
| `}, | `}, | ||||||
| 			want: []rule{ | 			want: []Rule{ | ||||||
| 				{ | 				{ | ||||||
| 					Service: localhost8000, | 					Service: localhost8000, | ||||||
| 				}, | 				}, | ||||||
|  | @ -141,13 +141,13 @@ ingress: | ||||||
| 	} | 	} | ||||||
| 	for _, tt := range tests { | 	for _, tt := range tests { | ||||||
| 		t.Run(tt.name, func(t *testing.T) { | 		t.Run(tt.name, func(t *testing.T) { | ||||||
| 			got, err := parseIngress([]byte(tt.args.rawYAML)) | 			got, err := ParseIngress([]byte(tt.args.rawYAML)) | ||||||
| 			if (err != nil) != tt.wantErr { | 			if (err != nil) != tt.wantErr { | ||||||
| 				t.Errorf("parseIngress() error = %v, wantErr %v", err, tt.wantErr) | 				t.Errorf("ParseIngress() error = %v, wantErr %v", err, tt.wantErr) | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
| 			if !reflect.DeepEqual(got, tt.want) { | 			if !reflect.DeepEqual(got, tt.want) { | ||||||
| 				t.Errorf("parseIngress() = %v, want %v", got, tt.want) | 				t.Errorf("ParseIngress() = %v, want %v", got, tt.want) | ||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
|  | @ -258,7 +258,7 @@ func Test_rule_matches(t *testing.T) { | ||||||
| 	} | 	} | ||||||
| 	for _, tt := range tests { | 	for _, tt := range tests { | ||||||
| 		t.Run(tt.name, func(t *testing.T) { | 		t.Run(tt.name, func(t *testing.T) { | ||||||
| 			r := rule{ | 			r := Rule{ | ||||||
| 				Hostname: tt.fields.Hostname, | 				Hostname: tt.fields.Hostname, | ||||||
| 				Path:     tt.fields.Path, | 				Path:     tt.fields.Path, | ||||||
| 				Service:  tt.fields.Service, | 				Service:  tt.fields.Service, | ||||||
|  | @ -24,6 +24,7 @@ import ( | ||||||
| 	"github.com/cloudflare/cloudflared/cmd/cloudflared/ui" | 	"github.com/cloudflare/cloudflared/cmd/cloudflared/ui" | ||||||
| 	"github.com/cloudflare/cloudflared/connection" | 	"github.com/cloudflare/cloudflared/connection" | ||||||
| 	"github.com/cloudflare/cloudflared/h2mux" | 	"github.com/cloudflare/cloudflared/h2mux" | ||||||
|  | 	"github.com/cloudflare/cloudflared/ingress" | ||||||
| 	"github.com/cloudflare/cloudflared/logger" | 	"github.com/cloudflare/cloudflared/logger" | ||||||
| 	"github.com/cloudflare/cloudflared/signal" | 	"github.com/cloudflare/cloudflared/signal" | ||||||
| 	"github.com/cloudflare/cloudflared/tunnelrpc" | 	"github.com/cloudflare/cloudflared/tunnelrpc" | ||||||
|  | @ -92,6 +93,7 @@ type TunnelConfig struct { | ||||||
| 	NamedTunnel     *NamedTunnelConfig | 	NamedTunnel     *NamedTunnelConfig | ||||||
| 	ReplaceExisting bool | 	ReplaceExisting bool | ||||||
| 	TunnelEventChan chan<- ui.TunnelEvent | 	TunnelEventChan chan<- ui.TunnelEvent | ||||||
|  | 	IngressRules    []ingress.Rule | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type dupConnRegisterTunnelError struct{} | type dupConnRegisterTunnelError struct{} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue