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