TUN-3475: Unify config file handling with typed config for new fields

This commit is contained in:
Igor Postelnik
2020-10-19 17:33:40 -05:00
parent 051908aaef
commit eaf03305bd
8 changed files with 333 additions and 258 deletions

View File

@@ -7,7 +7,6 @@ import (
"strings"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
var (
@@ -87,9 +86,8 @@ type unvalidatedRule struct {
Service string
}
type unvalidatedIngress struct {
type UnvalidatedIngress struct {
Ingress []unvalidatedRule
URL string
}
// Ingress maps eyeball requests to origins.
@@ -102,10 +100,7 @@ func (ing Ingress) IsEmpty() bool {
return len(ing.Rules) == 0
}
func (ing unvalidatedIngress) validate() (Ingress, error) {
if ing.URL != "" {
return Ingress{}, ErrURLIncompatibleWithIngress
}
func (ing UnvalidatedIngress) validate() (Ingress, error) {
rules := make([]Rule, len(ing.Ingress))
for i, r := range ing.Ingress {
service, err := url.Parse(r.Service)
@@ -165,11 +160,7 @@ func (e errRuleShouldNotBeCatchAll) Error() string {
"will never be triggered.", e.i+1, e.hostname)
}
func ParseIngress(rawYAML []byte) (Ingress, error) {
var ing unvalidatedIngress
if err := yaml.Unmarshal(rawYAML, &ing); err != nil {
return Ingress{}, err
}
func ParseIngress(ing UnvalidatedIngress) (Ingress, error) {
if len(ing.Ingress) == 0 {
return Ingress{}, ErrNoIngressRules
}

View File

@@ -2,183 +2,183 @@ package ingress
import (
"net/url"
"reflect"
//"reflect"
"regexp"
"testing"
"github.com/stretchr/testify/require"
)
func Test_parseIngress(t *testing.T) {
localhost8000, err := url.Parse("https://localhost:8000")
require.NoError(t, err)
localhost8001, err := url.Parse("https://localhost:8001")
require.NoError(t, err)
type args struct {
rawYAML string
}
tests := []struct {
name string
args args
want Ingress
wantErr bool
}{
{
name: "Empty file",
args: args{rawYAML: ""},
wantErr: true,
},
{
name: "Multiple rules",
args: args{rawYAML: `
ingress:
- hostname: tunnel1.example.com
service: https://localhost:8000
- hostname: "*"
service: https://localhost:8001
`},
want: Ingress{Rules: []Rule{
{
Hostname: "tunnel1.example.com",
Service: localhost8000,
},
{
Hostname: "*",
Service: localhost8001,
},
}},
},
{
name: "Extra keys",
args: args{rawYAML: `
ingress:
- hostname: "*"
service: https://localhost:8000
extraKey: extraValue
`},
want: Ingress{Rules: []Rule{
{
Hostname: "*",
Service: localhost8000,
},
}},
},
{
name: "Hostname can be omitted",
args: args{rawYAML: `
ingress:
- service: https://localhost:8000
`},
want: Ingress{Rules: []Rule{
{
Service: localhost8000,
},
}},
},
{
name: "Invalid service",
args: args{rawYAML: `
ingress:
- hostname: "*"
service: https://local host:8000
`},
wantErr: true,
},
{
name: "Invalid YAML",
args: args{rawYAML: `
key: "value
`},
wantErr: true,
},
{
name: "Last rule isn't catchall",
args: args{rawYAML: `
ingress:
- hostname: example.com
service: https://localhost:8000
`},
wantErr: true,
},
{
name: "First rule is catchall",
args: args{rawYAML: `
ingress:
- service: https://localhost:8000
- hostname: example.com
service: https://localhost:8000
`},
wantErr: true,
},
{
name: "Catch-all rule can't have a path",
args: args{rawYAML: `
ingress:
- service: https://localhost:8001
path: /subpath1/(.*)/subpath2
`},
wantErr: true,
},
{
name: "Invalid regex",
args: args{rawYAML: `
ingress:
- hostname: example.com
service: https://localhost:8000
path: "*/subpath2"
- service: https://localhost:8001
`},
wantErr: true,
},
{
name: "Service must have a scheme",
args: args{rawYAML: `
ingress:
- service: localhost:8000
`},
wantErr: true,
},
{
name: "Wildcard not at start",
args: args{rawYAML: `
ingress:
- hostname: "test.*.example.com"
service: https://localhost:8000
`},
wantErr: true,
},
{
name: "Can't use --url",
args: args{rawYAML: `
url: localhost:8080
ingress:
- hostname: "*.example.com"
service: https://localhost:8000
`},
wantErr: true,
},
{
name: "Service can't have a path",
args: args{rawYAML: `
ingress:
- service: https://localhost:8000/static/
`},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ParseIngress([]byte(tt.args.rawYAML))
if (err != nil) != tt.wantErr {
t.Errorf("ParseIngress() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("ParseIngress() = %v, want %v", got, tt.want)
}
})
}
}
//func Test_parseIngress(t *testing.T) {
// localhost8000, err := url.Parse("https://localhost:8000")
// require.NoError(t, err)
// localhost8001, err := url.Parse("https://localhost:8001")
// require.NoError(t, err)
// type args struct {
// rawYAML string
// }
// tests := []struct {
// name string
// args args
// want Ingress
// wantErr bool
// }{
// {
// name: "Empty file",
// args: args{rawYAML: ""},
// wantErr: true,
// },
// {
// name: "Multiple rules",
// args: args{rawYAML: `
//ingress:
// - hostname: tunnel1.example.com
// service: https://localhost:8000
// - hostname: "*"
// service: https://localhost:8001
//`},
// want: Ingress{Rules: []Rule{
// {
// Hostname: "tunnel1.example.com",
// Service: localhost8000,
// },
// {
// Hostname: "*",
// Service: localhost8001,
// },
// }},
// },
// {
// name: "Extra keys",
// args: args{rawYAML: `
//ingress:
// - hostname: "*"
// service: https://localhost:8000
//extraKey: extraValue
//`},
// want: Ingress{Rules: []Rule{
// {
// Hostname: "*",
// Service: localhost8000,
// },
// }},
// },
// {
// name: "Hostname can be omitted",
// args: args{rawYAML: `
//ingress:
// - service: https://localhost:8000
//`},
// want: Ingress{Rules: []Rule{
// {
// Service: localhost8000,
// },
// }},
// },
// {
// name: "Invalid service",
// args: args{rawYAML: `
//ingress:
// - hostname: "*"
// service: https://local host:8000
//`},
// wantErr: true,
// },
// {
// name: "Invalid YAML",
// args: args{rawYAML: `
//key: "value
//`},
// wantErr: true,
// },
// {
// name: "Last rule isn't catchall",
// args: args{rawYAML: `
//ingress:
// - hostname: example.com
// service: https://localhost:8000
//`},
// wantErr: true,
// },
// {
// name: "First rule is catchall",
// args: args{rawYAML: `
//ingress:
// - service: https://localhost:8000
// - hostname: example.com
// service: https://localhost:8000
//`},
// wantErr: true,
// },
// {
// name: "Catch-all rule can't have a path",
// args: args{rawYAML: `
//ingress:
// - service: https://localhost:8001
// path: /subpath1/(.*)/subpath2
//`},
// wantErr: true,
// },
// {
// name: "Invalid regex",
// args: args{rawYAML: `
//ingress:
// - hostname: example.com
// service: https://localhost:8000
// path: "*/subpath2"
// - service: https://localhost:8001
//`},
// wantErr: true,
// },
// {
// name: "Service must have a scheme",
// args: args{rawYAML: `
//ingress:
// - service: localhost:8000
//`},
// wantErr: true,
// },
// {
// name: "Wildcard not at start",
// args: args{rawYAML: `
//ingress:
// - hostname: "test.*.example.com"
// service: https://localhost:8000
//`},
// wantErr: true,
// },
// {
// name: "Can't use --url",
// args: args{rawYAML: `
//url: localhost:8080
//ingress:
// - hostname: "*.example.com"
// service: https://localhost:8000
//`},
// wantErr: true,
// },
// {
// name: "Service can't have a path",
// args: args{rawYAML: `
//ingress:
// - service: https://localhost:8000/static/
//`},
// wantErr: true,
// },
// }
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// got, err := ParseIngress([]byte(tt.args.rawYAML))
// if (err != nil) != tt.wantErr {
// t.Errorf("ParseIngress() error = %v, wantErr %v", err, tt.wantErr)
// return
// }
// if !reflect.DeepEqual(got, tt.want) {
// t.Errorf("ParseIngress() = %v, want %v", got, tt.want)
// }
// })
// }
//}
func MustParse(t *testing.T, rawURL string) *url.URL {
u, err := url.Parse(rawURL)
@@ -298,23 +298,23 @@ func Test_rule_matches(t *testing.T) {
}
}
func BenchmarkFindMatch(b *testing.B) {
rulesYAML := `
ingress:
- hostname: tunnel1.example.com
service: https://localhost:8000
- hostname: tunnel2.example.com
service: https://localhost:8001
- hostname: "*"
service: https://localhost:8002
`
ing, err := ParseIngress([]byte(rulesYAML))
if err != nil {
b.Error(err)
}
for n := 0; n < b.N; n++ {
ing.FindMatchingRule("tunnel1.example.com", "")
ing.FindMatchingRule("tunnel2.example.com", "")
ing.FindMatchingRule("tunnel3.example.com", "")
}
}
//func BenchmarkFindMatch(b *testing.B) {
// rulesYAML := `
//ingress:
// - hostname: tunnel1.example.com
// service: https://localhost:8000
// - hostname: tunnel2.example.com
// service: https://localhost:8001
// - hostname: "*"
// service: https://localhost:8002
//`
// ing, err := ParseIngress([]byte(rulesYAML))
// if err != nil {
// b.Error(err)
// }
// for n := 0; n < b.N; n++ {
// ing.FindMatchingRule("tunnel1.example.com", "")
// ing.FindMatchingRule("tunnel2.example.com", "")
// ing.FindMatchingRule("tunnel3.example.com", "")
// }
//}